X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_typeck%2Fdiagnostics.rs;h=77256d5b34ef96f3d25ec44558329502667a2513;hb=21dd5e62a225f90e4d7a182d8029af5d54222212;hp=40ea63e3cf9b4ee289435b97c3f2360c469b3d24;hpb=89c0be547e1c381317db56982757704ea597967a;p=rust.git diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 40ea63e3cf9..77256d5b34e 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -584,7 +584,7 @@ fn foo>(f: F) -> F::Output { f(3) } ``` Using this declaration, it must be called with at least one argument, so -simply calling `printf()` is illegal. But the following uses are allowed: +simply calling `printf()` is invalid. But the following uses are allowed: ``` unsafe { @@ -1227,16 +1227,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 kind of error, ensure that at least one local type is referenced +by the `impl`: ``` pub struct Foo; // you define your type in your crate @@ -1245,14 +1251,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 for i32 { // or you use a type from your crate as // a type parameter fn from(i: Foo) -> i32 { @@ -1260,6 +1258,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##" @@ -1889,6 +1903,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 ForeignTrait for T { ... } // error +``` + +To work around this, it can be covered with a local type, `MyType`: + +``` +struct MyType(T); +impl ForeignTrait for MyType { ... } // 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 ForeignTrait2> 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 ForeignTrait2, T> for MyType2 { ... } // Ok +``` + +This only differs from the previous `impl` in that the parameters `T` and +`MyType` 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 ForeignTrait 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: @@ -2335,18 +2414,17 @@ struct Foo<'a, T: 'a> { // 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 - E0215, // angle-bracket notation is not stable with `Fn` - E0216, // parenthetical notation is only stable with `Fn` +// E0215, // angle-bracket notation is not stable with `Fn` +// E0216, // parenthetical notation is only stable with `Fn` E0217, // ambiguous associated type, defined in multiple supertraits E0218, // no associated type defined E0219, // associated type defined in higher-ranked supertrait E0221, // ambiguous associated type in bounds - //E0222, // Error code E0045 (variadic function must have C calling - // convention) duplicate +// E0222, // Error code E0045 (variadic function must have C calling + // convention) duplicate E0224, // at least one non-builtin train is required for an object type E0226, // only a single explicit lifetime bound is permitted E0227, // ambiguous lifetime bound, explicit lifetime bound required