diff options
| author | Jorge Aparicio <jorge.aparicio@ferrous-systems.com> | 2020-01-20 07:50:32 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-20 07:50:32 +0000 |
| commit | a3a077610028c773bffc7a74e6a15faa10d2360d (patch) | |
| tree | 819cf353c019f421d80d9545aa18583841c34348 /src/librustc_error_codes/error_codes | |
| parent | 470cdf54ac9acee20ab8da46ef7899bae9f58f29 (diff) | |
| parent | 29b854fb741809c29764e33fc17c32ba9c6523ba (diff) | |
| download | rust-a3a077610028c773bffc7a74e6a15faa10d2360d.tar.gz rust-a3a077610028c773bffc7a74e6a15faa10d2360d.zip | |
Merge branch 'master' into bare-metal-cortex-a
Diffstat (limited to 'src/librustc_error_codes/error_codes')
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0170.md | 21 | ||||
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0195.md | 5 | ||||
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0197.md | 17 | ||||
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0198.md | 17 | ||||
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0199.md | 21 | ||||
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0200.md | 19 | ||||
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0527.md | 2 | ||||
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0528.md | 4 | ||||
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0730.md | 2 | ||||
| -rw-r--r-- | src/librustc_error_codes/error_codes/E0746.md | 138 |
10 files changed, 212 insertions, 34 deletions
diff --git a/src/librustc_error_codes/error_codes/E0170.md b/src/librustc_error_codes/error_codes/E0170.md index 4b870dbf221..9678cd173b7 100644 --- a/src/librustc_error_codes/error_codes/E0170.md +++ b/src/librustc_error_codes/error_codes/E0170.md @@ -1,3 +1,24 @@ +A pattern binding is using the same name as one of the variants of a type. + +Erroneous code example: + +```compile_fail,E0170 +# #![deny(warnings)] +enum Method { + GET, + POST, +} + +fn is_empty(s: Method) -> bool { + match s { + GET => true, + _ => false + } +} + +fn main() {} +``` + Enum variants are qualified by default. For example, given this type: ``` diff --git a/src/librustc_error_codes/error_codes/E0195.md b/src/librustc_error_codes/error_codes/E0195.md index 3606521020a..b8c313d412e 100644 --- a/src/librustc_error_codes/error_codes/E0195.md +++ b/src/librustc_error_codes/error_codes/E0195.md @@ -1,4 +1,5 @@ -Your method's lifetime parameters do not match the trait declaration. +The lifetime parameters of the method do not match the trait declaration. + Erroneous code example: ```compile_fail,E0195 @@ -16,7 +17,7 @@ impl Trait for Foo { } ``` -The lifetime constraint `'b` for bar() implementation does not match the +The lifetime constraint `'b` for `bar()` implementation does not match the trait declaration. Ensure lifetime declarations match exactly in both trait declaration and implementation. Example: diff --git a/src/librustc_error_codes/error_codes/E0197.md b/src/librustc_error_codes/error_codes/E0197.md index 0d91157e572..c142b8f3664 100644 --- a/src/librustc_error_codes/error_codes/E0197.md +++ b/src/librustc_error_codes/error_codes/E0197.md @@ -1,13 +1,20 @@ +An inherent implementation was marked unsafe. + +Erroneous code example: + +```compile_fail,E0197 +struct Foo; + +unsafe impl Foo { } // error! +``` + Inherent implementations (one that do not implement a trait but provide methods associated with a type) are always safe because they are not implementing an unsafe trait. Removing the `unsafe` keyword from the inherent implementation will resolve this error. -```compile_fail,E0197 +``` struct Foo; -// this will cause this error -unsafe impl Foo { } -// converting it to this will fix it -impl Foo { } +impl Foo { } // ok! ``` diff --git a/src/librustc_error_codes/error_codes/E0198.md b/src/librustc_error_codes/error_codes/E0198.md index 6504d60dbd1..687214a2050 100644 --- a/src/librustc_error_codes/error_codes/E0198.md +++ b/src/librustc_error_codes/error_codes/E0198.md @@ -1,17 +1,18 @@ -A negative implementation is one that excludes a type from implementing a -particular trait. Not being able to use a trait is always a safe operation, -so negative implementations are always safe and never need to be marked as -unsafe. +A negative implementation was marked as unsafe. -```compile_fail -#![feature(optin_builtin_traits)] +Erroneous code example: +```compile_fail struct Foo; -// unsafe is unnecessary -unsafe impl !Clone for Foo { } +unsafe impl !Clone for Foo { } // error! ``` +A negative implementation is one that excludes a type from implementing a +particular trait. Not being able to use a trait is always a safe operation, +so negative implementations are always safe and never need to be marked as +unsafe. + This will compile: ```ignore (ignore auto_trait future compatibility warning) diff --git a/src/librustc_error_codes/error_codes/E0199.md b/src/librustc_error_codes/error_codes/E0199.md index d0c12dc6f17..88130e8e5e5 100644 --- a/src/librustc_error_codes/error_codes/E0199.md +++ b/src/librustc_error_codes/error_codes/E0199.md @@ -1,14 +1,23 @@ +A trait implementation was marked as unsafe while the trait is safe. + +Erroneous code example: + +```compile_fail,E0199 +struct Foo; + +trait Bar { } + +unsafe impl Bar for Foo { } // error! +``` + Safe traits should not have unsafe implementations, therefore marking an implementation for a safe trait unsafe will cause a compiler error. Removing -the unsafe marker on the trait noted in the error will resolve this problem. +the unsafe marker on the trait noted in the error will resolve this problem: -```compile_fail,E0199 +``` struct Foo; trait Bar { } -// this won't compile because Bar is safe -unsafe impl Bar for Foo { } -// this will compile -impl Bar for Foo { } +impl Bar for Foo { } // ok! ``` diff --git a/src/librustc_error_codes/error_codes/E0200.md b/src/librustc_error_codes/error_codes/E0200.md index 865e91430ac..7245bb59ce5 100644 --- a/src/librustc_error_codes/error_codes/E0200.md +++ b/src/librustc_error_codes/error_codes/E0200.md @@ -1,14 +1,23 @@ +An unsafe trait was implemented without an unsafe implementation. + +Erroneous code example: + +```compile_fail,E0200 +struct Foo; + +unsafe trait Bar { } + +impl Bar for Foo { } // error! +``` + Unsafe traits must have unsafe implementations. This error occurs when an implementation for an unsafe trait isn't marked as unsafe. This may be resolved by marking the unsafe implementation as unsafe. -```compile_fail,E0200 +``` struct Foo; unsafe trait Bar { } -// this won't compile because Bar is unsafe and impl isn't unsafe -impl Bar for Foo { } -// this will compile -unsafe impl Bar for Foo { } +unsafe impl Bar for Foo { } // ok! ``` diff --git a/src/librustc_error_codes/error_codes/E0527.md b/src/librustc_error_codes/error_codes/E0527.md index 4bff39dc770..97ea3126938 100644 --- a/src/librustc_error_codes/error_codes/E0527.md +++ b/src/librustc_error_codes/error_codes/E0527.md @@ -17,8 +17,6 @@ Ensure that the pattern is consistent with the size of the matched array. Additional elements can be matched with `..`: ``` -#![feature(slice_patterns)] - let r = &[1, 2, 3, 4]; match r { &[a, b, ..] => { // ok! diff --git a/src/librustc_error_codes/error_codes/E0528.md b/src/librustc_error_codes/error_codes/E0528.md index 4b6ea246991..54c2c4d4e9d 100644 --- a/src/librustc_error_codes/error_codes/E0528.md +++ b/src/librustc_error_codes/error_codes/E0528.md @@ -4,8 +4,6 @@ matched array. Example of erroneous code: ```compile_fail,E0528 -#![feature(slice_patterns)] - let r = &[1, 2]; match r { &[a, b, c, rest @ ..] => { // error: pattern requires at least 3 @@ -19,8 +17,6 @@ Ensure that the matched array has at least as many elements as the pattern requires. You can match an arbitrary number of remaining elements with `..`: ``` -#![feature(slice_patterns)] - let r = &[1, 2, 3, 4, 5]; match r { &[a, b, c, rest @ ..] => { // ok! diff --git a/src/librustc_error_codes/error_codes/E0730.md b/src/librustc_error_codes/error_codes/E0730.md index 803a2514865..bf1f72be325 100644 --- a/src/librustc_error_codes/error_codes/E0730.md +++ b/src/librustc_error_codes/error_codes/E0730.md @@ -18,8 +18,6 @@ Ensure that the pattern is consistent with the size of the matched array. Additional elements can be matched with `..`: ``` -#![feature(slice_patterns)] - let r = &[1, 2, 3, 4]; match r { &[a, b, ..] => { // ok! diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md new file mode 100644 index 00000000000..16b2722f0ea --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -0,0 +1,138 @@ +Return types cannot be `dyn Trait`s as they must be `Sized`. + +Erroneous code example: + +```compile_fail,E0277 +# // FIXME: after E0746 is in beta, change the above +trait T { + fn bar(&self); +} +struct S(usize); +impl T for S { + fn bar(&self) {} +} + +// Having the trait `T` as return type is invalid because +// unboxed trait objects do not have a statically known size: +fn foo() -> dyn T { + S(42) +} +``` + +To avoid the error there are a couple of options. + +If there is a single type involved, you can use [`impl Trait`]: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +// The compiler will select `S(usize)` as the materialized return type of this +// function, but callers will only know that the return type implements `T`. +fn foo() -> impl T { + S(42) +} +``` + +If there are multiple types involved, the only way you care to interact with +them is through the trait's interface, and having to rely on dynamic dispatch +is acceptable, then you can use [trait objects] with `Box`, or other container +types like `Rc` or `Arc`: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +struct O(&'static str); +impl T for O { + fn bar(&self) {} +} + +// This now returns a "trait object" and callers are only be able to access +// associated items from `T`. +fn foo(x: bool) -> Box<dyn T> { + if x { + Box::new(S(42)) + } else { + Box::new(O("val")) + } +} +``` + +Finally, if you wish to still be able to access the original type, you can +create a new `enum` with a variant for each type: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +# struct O(&'static str); +# impl T for O { +# fn bar(&self) {} +# } +enum E { + S(S), + O(O), +} + +// The caller can access the original types directly, but it needs to match on +// the returned `enum E`. +fn foo(x: bool) -> E { + if x { + E::S(S(42)) + } else { + E::O(O("val")) + } +} +``` + +You can even implement the `trait` on the returned `enum` so the callers +*don't* have to match on the returned value to invoke the associated items: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +# struct O(&'static str); +# impl T for O { +# fn bar(&self) {} +# } +# enum E { +# S(S), +# O(O), +# } +impl T for E { + fn bar(&self) { + match self { + E::S(s) => s.bar(), + E::O(o) => o.bar(), + } + } +} +``` + +If you decide to use trait objects, be aware that these rely on +[dynamic dispatch], which has performance implications, as the compiler needs +to emit code that will figure out which method to call *at runtime* instead of +during compilation. Using trait objects we are trading flexibility for +performance. + +[`impl Trait`]: https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits +[trait objects]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types +[dynamic dispatch]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch |
