In Rust, implementing a trait for a type is allowed only if:
These conditions are called the orphan rule. This protects against conflicts in the case of independent implementations of the same trait for the same type in different crates.
If you want to implement an external trait for an external type — this is not possible directly. Typically, a "newtype" pattern is used: wrap the type in your own structure within the crate, and then implement the trait for your own type.
Example:
// External type and external trait (not in our crate) // struct ExternalType; trait ExternalTrait { ... } struct MyWrapper(ExternalType); impl ExternalTrait for MyWrapper { /* ... */ } // Now we work through the wrapper
Question: Can you implement an external trait for an external type if both are public, through use and impl?
Incorrect answer: Yes, it’s enough to simply declare impl in your crate, and everything will work.
Correct answer: No, the compiler will not allow that. You can only implement a trait if either the trait or the type is declared in the current crate. Otherwise — orphan rule error.
Example of an error:
// extern crate other; // impl Display for other::ExternalType { ... } // Orphan rule error
Story
The team needed support for an external logger through impl of an external trait. Attempting to implement it for a third-party type led to an orphan rule error and lengthy debates about the reasons. Ultimately, they had to redesign the architecture to use newtype.
Story
In an open-source project, they attempted to implement Debug for a structure from another library, which was blocked by orphan rule. As a result, users had to deal with awkward workarounds and write their own wrappers.
Story
A serious bug: when trying to implement FromStr for an external enum to parse from a string, the compiler blocked it due to orphan rule. The developer "solved" the problem via unsafe memory conversions, which caused UB in production.