| This error indicates a violation of one of Rust's orphan rules for trait |
| implementations. The rule concerns the use of type parameters in an |
| implementation of a foreign trait (a trait defined in another crate), and |
| states that type parameters must be "covered" by a local type. |
| |
| When implementing a foreign trait for a foreign type, |
| the trait must have one or more type parameters. |
| A type local to your crate must appear before any use of any type parameters. |
| |
| To understand what this means, it is perhaps easier to consider a few examples. |
| |
| If `ForeignTrait` is a trait defined in some external crate `foo`, then the |
| following trait `impl` is an error: |
| |
| ```compile_fail,E0210 |
| # #[cfg(for_demonstration_only)] |
| extern crate foo; |
| # #[cfg(for_demonstration_only)] |
| use foo::ForeignTrait; |
| # use std::panic::UnwindSafe as ForeignTrait; |
| |
| impl<T> ForeignTrait for T { } // error |
| # fn main() {} |
| ``` |
| |
| To work around this, it can be covered with a local type, `MyType`: |
| |
| ``` |
| # use std::panic::UnwindSafe as ForeignTrait; |
| struct MyType<T>(T); |
| impl<T> ForeignTrait for MyType<T> { } // Ok |
| ``` |
| |
| Please note that a type alias is not sufficient. |
| |
| For another example of an error, suppose there's another trait defined in `foo` |
| named `ForeignTrait2` that takes two type parameters. Then this `impl` results |
| in the same rule violation: |
| |
| ```ignore (cannot-doctest-multicrate-project) |
| struct MyType2; |
| impl<T> ForeignTrait2<T, MyType<T>> for MyType2 { } // error |
| ``` |
| |
| The reason for this is that there are two appearances of type parameter `T` in |
| the `impl` header, both as parameters for `ForeignTrait2`. The first appearance |
| is uncovered, and so runs afoul of the orphan rule. |
| |
| Consider one more example: |
| |
| ```ignore (cannot-doctest-multicrate-project) |
| impl<T> ForeignTrait2<MyType<T>, T> for MyType2 { } // Ok |
| ``` |
| |
| This only differs from the previous `impl` in that the parameters `T` and |
| `MyType<T>` for `ForeignTrait2` have been swapped. This example does *not* |
| violate the orphan rule; it is permitted. |
| |
| To see why that last example was allowed, you need to understand the general |
| rule. Unfortunately this rule is a bit tricky to state. Consider an `impl`: |
| |
| ```ignore (only-for-syntax-highlight) |
| impl<P1, ..., Pm> ForeignTrait<T1, ..., Tn> for T0 { ... } |
| ``` |
| |
| where `P1, ..., Pm` are the type parameters of the `impl` and `T0, ..., Tn` |
| are types. One of the types `T0, ..., Tn` must be a local type (this is another |
| orphan rule, see the explanation for E0117). |
| |
| Both of the following must be true: |
| 1. At least one of the types `T0..=Tn` must be a local type. |
| Let `Ti` be the first such type. |
| 2. No uncovered type parameters `P1..=Pm` may appear in `T0..Ti` |
| (excluding `Ti`). |
| |
| For information on the design of the orphan rules, |
| see [RFC 2451] and [RFC 1023]. |
| |
| [RFC 2451]: https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html |
| [RFC 1023]: https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md |