@@ -1227,16 +1227,22 @@ impl Bytes { ... } // error, same as above
1227
1227
"## ,
1228
1228
1229
1229
E0117 : r##"
1230
- You got this error because because you tried to implement a foreign
1231
- trait for a foreign type (with maybe a foreign type parameter). Erroneous
1232
- code example:
1230
+ This error indicates a violation of one of Rust's orphan rules for trait
1231
+ implementations. The rule prohibits any implementation of a foreign trait (a
1232
+ trait defined in another crate) where
1233
+
1234
+ - the type that is implementing the trait is foreign
1235
+ - all of the parameters being passed to the trait (if there are any) are also
1236
+ foreign.
1237
+
1238
+ Here's one example of this error:
1233
1239
1234
1240
```
1235
1241
impl Drop for u32 {}
1236
1242
```
1237
1243
1238
- The type, trait or the type parameter (or all of them) has to be defined
1239
- in your crate. Example :
1244
+ To avoid this kind of error, ensure that at least one local type is referenced
1245
+ by the `impl` :
1240
1246
1241
1247
```
1242
1248
pub struct Foo; // you define your type in your crate
@@ -1245,21 +1251,29 @@ impl Drop for Foo { // and you can implement the trait on it!
1245
1251
// code of trait implementation here
1246
1252
}
1247
1253
1248
- trait Bar { // or define your trait in your crate
1249
- fn get(&self) -> usize;
1250
- }
1251
-
1252
- impl Bar for u32 { // and then you implement it on a foreign type
1253
- fn get(&self) -> usize { 0 }
1254
- }
1255
-
1256
1254
impl From<Foo> for i32 { // or you use a type from your crate as
1257
1255
// a type parameter
1258
1256
fn from(i: Foo) -> i32 {
1259
1257
0
1260
1258
}
1261
1259
}
1262
1260
```
1261
+
1262
+ Alternatively, define a trait locally and implement that instead:
1263
+
1264
+ ```
1265
+ trait Bar {
1266
+ fn get(&self) -> usize;
1267
+ }
1268
+
1269
+ impl Bar for u32 {
1270
+ fn get(&self) -> usize { 0 }
1271
+ }
1272
+ ```
1273
+
1274
+ For information on the design of the orphan rules, see [RFC 1023].
1275
+
1276
+ [RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
1263
1277
"## ,
1264
1278
1265
1279
E0119 : r##"
@@ -1889,6 +1903,71 @@ impl MyTrait for Foo {
1889
1903
```
1890
1904
"## ,
1891
1905
1906
+ E0210 : r##"
1907
+ This error indicates a violation of one of Rust's orphan rules for trait
1908
+ implementations. The rule concerns the use of type parameters in an
1909
+ implementation of a foreign trait (a trait defined in another crate), and
1910
+ states that type parameters must be "covered" by a local type. To understand
1911
+ what this means, it is perhaps easiest to consider a few examples.
1912
+
1913
+ If `ForeignTrait` is a trait defined in some external crate `foo`, then the
1914
+ following trait `impl` is an error:
1915
+
1916
+ ```
1917
+ extern crate foo;
1918
+ use foo::ForeignTrait;
1919
+
1920
+ impl<T> ForeignTrait for T { ... } // error
1921
+ ```
1922
+
1923
+ To work around this, it can be covered with a local type, `MyType`:
1924
+
1925
+ ```
1926
+ struct MyType<T>(T);
1927
+ impl<T> ForeignTrait for MyType<T> { ... } // Ok
1928
+ ```
1929
+
1930
+ For another example of an error, suppose there's another trait defined in `foo`
1931
+ named `ForeignTrait2` that takes two type parameters. Then this `impl` results
1932
+ in the same rule violation:
1933
+
1934
+ ```
1935
+ struct MyType2;
1936
+ impl<T> ForeignTrait2<T, MyType<T>> for MyType2 { ... } // error
1937
+ ```
1938
+
1939
+ The reason for this is that there are two appearances of type parameter `T` in
1940
+ the `impl` header, both as parameters for `ForeignTrait2`. The first appearance
1941
+ is uncovered, and so runs afoul of the orphan rule.
1942
+
1943
+ Consider one more example:
1944
+
1945
+ ```
1946
+ impl<T> ForeignTrait2<MyType<T>, T> for MyType2 { ... } // Ok
1947
+ ```
1948
+
1949
+ This only differs from the previous `impl` in that the parameters `T` and
1950
+ `MyType<T>` for `ForeignTrait2` have been swapped. This example does *not*
1951
+ violate the orphan rule; it is permitted.
1952
+
1953
+ To see why that last example was allowed, you need to understand the general
1954
+ rule. Unfortunately this rule is a bit tricky to state. Consider an `impl`:
1955
+
1956
+ ```
1957
+ impl<P1, ..., Pm> ForeignTrait<T1, ..., Tn> for T0 { ... }
1958
+ ```
1959
+
1960
+ where `P1, ..., Pm` are the type parameters of the `impl` and `T0, ..., Tn`
1961
+ are types. One of the types `T0, ..., Tn` must be a local type (this is another
1962
+ orphan rule, see the explanation for E0117). Let `i` be the smallest integer
1963
+ such that `Ti` is a local type. Then no type parameter can appear in any of the
1964
+ `Tj` for `j < i`.
1965
+
1966
+ For information on the design of the orphan rules, see [RFC 1023].
1967
+
1968
+ [RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
1969
+ "## ,
1970
+
1892
1971
E0211 : r##"
1893
1972
You used an intrinsic function which doesn't correspond to its
1894
1973
definition. Erroneous code example:
@@ -2335,7 +2414,6 @@ register_diagnostics! {
2335
2414
// and only one is supported
2336
2415
E0208 ,
2337
2416
E0209 , // builtin traits can only be implemented on structs or enums
2338
- E0210 , // type parameter is not constrained by any local type
2339
2417
E0212 , // cannot extract an associated type from a higher-ranked trait bound
2340
2418
E0213 , // associated types are not accepted in this context
2341
2419
E0214 , // parenthesized parameters may only be used with a trait
0 commit comments