Add explanation for E0210 and revise E0117.

This commit is contained in:
Nick Hamann 2015-07-11 19:48:42 -05:00
parent 1b28ffa521
commit 5559d2ba04

View File

@ -1245,16 +1245,22 @@ impl Bytes { ... } // error, same as above
"##,
E0117: r##"
You got this error because because you tried to implement a foreign
trait for a foreign type (with maybe a foreign type parameter). Erroneous
code example:
This error indicates a violation of one of Rust's orphan rules for trait
implementations. The rule prohibits any implementation of a foreign trait (a
trait defined in another crate) where
- the type that is implementing the trait is foreign
- all of the parameters being passed to the trait (if there are any) are also
foreign.
Here's one example of this error:
```
impl Drop for u32 {}
```
The type, trait or the type parameter (or all of them) has to be defined
in your crate. Example:
To avoid this error, ensure that at least one local type is referenced by
the `impl`:
```
pub struct Foo; // you define your type in your crate
@ -1263,14 +1269,6 @@ impl Drop for Foo { // and you can implement the trait on it!
// code of trait implementation here
}
trait Bar { // or define your trait in your crate
fn get(&self) -> usize;
}
impl Bar for u32 { // and then you implement it on a foreign type
fn get(&self) -> usize { 0 }
}
impl From<Foo> for i32 { // or you use a type from your crate as
// a type parameter
fn from(i: Foo) -> i32 {
@ -1278,6 +1276,22 @@ fn from(i: Foo) -> i32 {
}
}
```
Alternatively, define a trait locally and implement that instead:
```
trait Bar {
fn get(&self) -> usize;
}
impl Bar for u32 {
fn get(&self) -> usize { 0 }
}
```
For information on the design of the orphan rules, see [RFC 1023].
[RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
"##,
E0119: r##"
@ -1833,6 +1847,71 @@ fn get(&self) -> usize {
```
"##,
E0210: r##"
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. To understand
what this means, it is perhaps easiest to consider a few examples.
If `ForeignTrait` is a trait defined in some external crate `foo`, then the
following trait `impl` is an error:
```
extern crate foo;
use foo::ForeignTrait;
impl<T> ForeignTrait for T { ... } // error
```
To work around this, it can be covered with a local type, `MyType`:
```
struct MyType<T>(T);
impl<T> ForeignTrait for MyType<T> { ... } // Ok
```
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:
```
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:
```
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`:
```
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). Let `i` be the smallest integer
such that `Ti` is a local type. Then no type parameter can appear in any of the
`Tj` for `j < i`.
For information on the design of the orphan rules, see [RFC 1023].
[RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
"##,
E0211: r##"
You used an intrinsic function which doesn't correspond to its
definition. Erroneous code example:
@ -2148,7 +2227,6 @@ impl Baz for Bar { } // Note: This is OK
// and only one is supported
E0208,
E0209, // builtin traits can only be implemented on structs or enums
E0210, // type parameter is not constrained by any local type
E0212, // cannot extract an associated type from a higher-ranked trait bound
E0213, // associated types are not accepted in this context
E0214, // parenthesized parameters may only be used with a trait