]> git.proxmox.com Git - rustc.git/blob - compiler/rustc_error_codes/src/error_codes/E0210.md
New upstream version 1.48.0~beta.8+dfsg1
[rustc.git] / compiler / rustc_error_codes / src / error_codes / E0210.md
1 This error indicates a violation of one of Rust's orphan rules for trait
2 implementations. The rule concerns the use of type parameters in an
3 implementation of a foreign trait (a trait defined in another crate), and
4 states that type parameters must be "covered" by a local type.
5
6 When implementing a foreign trait for a foreign type,
7 the trait must have one or more type parameters.
8 A type local to your crate must appear before any use of any type parameters.
9
10 To understand what this means, it is perhaps easier to consider a few examples.
11
12 If `ForeignTrait` is a trait defined in some external crate `foo`, then the
13 following trait `impl` is an error:
14
15 ```compile_fail,E0210
16 # #[cfg(for_demonstration_only)]
17 extern crate foo;
18 # #[cfg(for_demonstration_only)]
19 use foo::ForeignTrait;
20 # use std::panic::UnwindSafe as ForeignTrait;
21
22 impl<T> ForeignTrait for T { } // error
23 # fn main() {}
24 ```
25
26 To work around this, it can be covered with a local type, `MyType`:
27
28 ```
29 # use std::panic::UnwindSafe as ForeignTrait;
30 struct MyType<T>(T);
31 impl<T> ForeignTrait for MyType<T> { } // Ok
32 ```
33
34 Please note that a type alias is not sufficient.
35
36 For another example of an error, suppose there's another trait defined in `foo`
37 named `ForeignTrait2` that takes two type parameters. Then this `impl` results
38 in the same rule violation:
39
40 ```ignore (cannot-doctest-multicrate-project)
41 struct MyType2;
42 impl<T> ForeignTrait2<T, MyType<T>> for MyType2 { } // error
43 ```
44
45 The reason for this is that there are two appearances of type parameter `T` in
46 the `impl` header, both as parameters for `ForeignTrait2`. The first appearance
47 is uncovered, and so runs afoul of the orphan rule.
48
49 Consider one more example:
50
51 ```ignore (cannot-doctest-multicrate-project)
52 impl<T> ForeignTrait2<MyType<T>, T> for MyType2 { } // Ok
53 ```
54
55 This only differs from the previous `impl` in that the parameters `T` and
56 `MyType<T>` for `ForeignTrait2` have been swapped. This example does *not*
57 violate the orphan rule; it is permitted.
58
59 To see why that last example was allowed, you need to understand the general
60 rule. Unfortunately this rule is a bit tricky to state. Consider an `impl`:
61
62 ```ignore (only-for-syntax-highlight)
63 impl<P1, ..., Pm> ForeignTrait<T1, ..., Tn> for T0 { ... }
64 ```
65
66 where `P1, ..., Pm` are the type parameters of the `impl` and `T0, ..., Tn`
67 are types. One of the types `T0, ..., Tn` must be a local type (this is another
68 orphan rule, see the explanation for E0117).
69
70 Both of the following must be true:
71 1. At least one of the types `T0..=Tn` must be a local type.
72 Let `Ti` be the first such type.
73 2. No uncovered type parameters `P1..=Pm` may appear in `T0..Ti`
74 (excluding `Ti`).
75
76 For information on the design of the orphan rules,
77 see [RFC 2451] and [RFC 1023].
78
79 For information on the design of the orphan rules, see [RFC 1023].
80
81 [RFC 2451]: https://rust-lang.github.io/rfcs/2451-re-rebalancing-coherence.html
82 [RFC 1023]: https://github.com/rust-lang/rfcs/blob/master/text/1023-rebalancing-coherence.md