X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_typeck%2Fdiagnostics.rs;h=77256d5b34ef96f3d25ec44558329502667a2513;hb=21dd5e62a225f90e4d7a182d8029af5d54222212;hp=b151ae677d93fa35e48ef0d4c146b1da42d44539;hpb=fafb1fa82357e89759fb5698bac3252f852208f0;p=rust.git diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index b151ae677d9..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 { @@ -778,7 +778,7 @@ fn main() { Consider the following erroneous definition of a type for a list of bytes: ``` -// error, illegal recursive struct type +// error, invalid recursive struct type struct ListNode { head: u8, tail: Option, @@ -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,11 +1258,27 @@ 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##" There are conflicting trait implementations for the same type. -Erroneous code example: +Example of erroneous code: ``` trait MyTrait { @@ -1285,7 +1299,10 @@ fn get(&self) -> usize { self.value } } ``` -When you write: +When looking for the implementation for the trait, the compiler finds +both the `impl MyTrait for T` where T is all types and the `impl +MyTrait for Foo`. Since a trait cannot be implemented multiple times, +this is an error. So, when you write: ``` impl MyTrait for T { @@ -1316,6 +1333,45 @@ fn main() { ``` "##, +E0120: r##" +An attempt was made to implement Drop on a trait, which is not allowed: only +structs and enums can implement Drop. An example causing this error: + +``` +trait MyTrait {} + +impl Drop for MyTrait { + fn drop(&mut self) {} +} +``` + +A workaround for this problem is to wrap the trait up in a struct, and implement +Drop on that. An example is shown below: + +``` +trait MyTrait {} +struct MyWrapper { foo: T } + +impl Drop for MyWrapper { + fn drop(&mut self) {} +} + +``` + +Alternatively, wrapping trait objects requires something like the following: + +``` +trait MyTrait {} + +//or Box, if you wanted an owned trait object +struct MyWrapper<'a> { foo: &'a MyTrait } + +impl <'a> Drop for MyWrapper<'a> { + fn drop(&mut self) {} +} +``` +"##, + E0121: r##" In order to be consistent with Rust's lack of global type inference, type placeholders are disallowed by design in item signatures. @@ -1847,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: @@ -2176,6 +2297,23 @@ impl Baz for Bar { } // Note: This is OK -lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md). "##, +E0391: r##" +This error indicates that some types or traits depend on each other +and therefore cannot be constructed. + +The following example contains a circular dependency between two traits: + +``` +trait FirstTrait : SecondTrait { + +} + +trait SecondTrait : FirstTrait { + +} +``` +"##, + E0392: r##" This error indicates that a type or lifetime parameter has been declared but not actually used. Here is an example that demonstrates the error: @@ -2251,7 +2389,6 @@ struct Foo<'a, T: 'a> { E0103, E0104, E0118, - E0120, E0122, E0123, E0127, @@ -2277,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 @@ -2307,7 +2443,7 @@ struct Foo<'a, T: 'a> { E0241, E0242, // internal error looking up a definition E0245, // not a trait - E0246, // illegal recursive type + E0246, // invalid recursive type E0247, // found module name used as a type E0248, // found value name used as a type E0319, // trait impls for defaulted traits allowed just for structs/enums @@ -2332,7 +2468,6 @@ struct Foo<'a, T: 'a> { // between structures with the same definition E0390, // only a single inherent implementation marked with // `#[lang = \"{}\"]` is allowed for the `{}` primitive - E0391, // unsupported cyclic reference between types/traits detected E0393, // the type parameter `{}` must be explicitly specified in an object // type because its default value `{}` references the type `Self`" E0399, // trait items need to be implemented because the associated