Add error explanations for E0072, E0073, E0121, E0178, E0371, E0372.
This commit is contained in:
parent
8b7c17db22
commit
c69a152018
@ -170,6 +170,63 @@ fn foo() -> u8 {
|
||||
function's return type and the value being returned.
|
||||
"##,
|
||||
|
||||
E0072: r##"
|
||||
When defining a recursive struct or enum, any use of the type being defined
|
||||
from inside the definition must occur behind a pointer (like `Box` or `&`).
|
||||
This is because structs and enums must have a well-defined size, and without
|
||||
the pointer the size of the type would need to be unbounded.
|
||||
|
||||
Consider the following erroneous definition of a type for a list of bytes:
|
||||
|
||||
```
|
||||
// error, illegal recursive struct type
|
||||
struct ListNode {
|
||||
head: u8,
|
||||
tail: Option<ListNode>,
|
||||
}
|
||||
```
|
||||
|
||||
This type cannot have a well-defined size, because it needs to be arbitrarily
|
||||
large (since we would be able to nest `ListNode`s to any depth). Specifically,
|
||||
|
||||
```
|
||||
size of ListNode = 1 byte for head
|
||||
+ 1 byte for the discriminant of the Option
|
||||
+ size of ListNode
|
||||
```
|
||||
|
||||
One way to fix this is by wrapping `ListNode` in a `Box`, like so:
|
||||
|
||||
```
|
||||
struct ListNode {
|
||||
head: u8,
|
||||
tail: Option<Box<ListNode>>,
|
||||
}
|
||||
```
|
||||
|
||||
This works because `Box` is a pointer, so its size is well-known.
|
||||
"##,
|
||||
|
||||
E0073: r##"
|
||||
You cannot define a struct (or enum) `Foo` that requires an instance of `Foo`
|
||||
in order to make a new `Foo` value. This is because there would be no way a
|
||||
first instance of `Foo` could be made to initialize another instance!
|
||||
|
||||
Here's an example of a struct that has this problem:
|
||||
|
||||
```
|
||||
struct Foo { x: Box<Foo> } // error
|
||||
```
|
||||
|
||||
One fix is to use `Option`, like so:
|
||||
|
||||
```
|
||||
struct Foo { x: Option<Box<Foo>> }
|
||||
```
|
||||
|
||||
Now it's possible to create at least one instance of `Foo`: `Foo { x: None }`.
|
||||
"##,
|
||||
|
||||
E0081: r##"
|
||||
Enum discriminants are used to differentiate enum variants stored in memory.
|
||||
This error indicates that the same value was used for two or more variants,
|
||||
@ -327,6 +384,19 @@ impl Quux for Foo { } // error: expected 1, found 0
|
||||
[iss15872]: https://github.com/rust-lang/rust/issues/15872
|
||||
"##,
|
||||
|
||||
E0121: r##"
|
||||
In order to be consistent with Rust's lack of global type inference, type
|
||||
placeholders are disallowed by design in item signatures.
|
||||
|
||||
Examples of this error include:
|
||||
|
||||
```
|
||||
fn foo() -> _ { 5 } // error, explicitly write out the return type instead
|
||||
|
||||
static BAR: _ = "test"; // error, explicitly write out the type instead
|
||||
```
|
||||
"##,
|
||||
|
||||
E0131: r##"
|
||||
It is not possible to define `main` with type parameters, or even with function
|
||||
parameters. When `main` is present, it must take no arguments and return `()`.
|
||||
@ -355,6 +425,28 @@ impl Quux for Foo { } // error: expected 1, found 0
|
||||
diverging function (such as `panic!()`).
|
||||
"##,
|
||||
|
||||
E0178: r##"
|
||||
In types, the `+` type operator has low precedence, so it is often necessary
|
||||
to use parentheses.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
trait Foo {}
|
||||
|
||||
struct Bar<'a> {
|
||||
w: &'a Foo + Copy, // error, use &'a (Foo + Copy)
|
||||
x: &'a Foo + 'a, // error, use &'a (Foo + 'a)
|
||||
y: &'a mut Foo + 'a, // error, use &'a mut (Foo + 'a)
|
||||
z: fn() -> Foo + 'a, // error, use fn() -> (Foo + 'a)
|
||||
}
|
||||
```
|
||||
|
||||
More details can be found in [RFC 438].
|
||||
|
||||
[RFC 438]: https://github.com/rust-lang/rfcs/pull/438
|
||||
"##,
|
||||
|
||||
E0184: r##"
|
||||
Explicitly implementing both Drop and Copy for a type is currently disallowed.
|
||||
This feature can make some sense in theory, but the current implementation is
|
||||
@ -632,6 +724,35 @@ fn main() {
|
||||
to change this.
|
||||
|
||||
[RFC 953]: https://github.com/rust-lang/rfcs/pull/953
|
||||
"##,
|
||||
|
||||
E0371: r##"
|
||||
When `Trait2` is a subtrait of `Trait1` (for example, when `Trait2` has a
|
||||
definition like `trait Trait2: Trait1 { ... }`), it is not allowed to implement
|
||||
`Trait1` for `Trait2`. This is because `Trait2` already implements `Trait1` by
|
||||
definition, so it is not useful to do this.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
trait Foo { fn foo(&self) { } }
|
||||
trait Bar: Foo { }
|
||||
trait Baz: Bar { }
|
||||
|
||||
impl Bar for Baz { } // error, `Baz` implements `Bar` by definition
|
||||
impl Foo for Baz { } // error, `Baz` implements `Bar` which implements `Foo`
|
||||
impl Baz for Baz { } // error, `Baz` (trivially) implements `Baz`
|
||||
impl Baz for Bar { } // Note: This is OK
|
||||
```
|
||||
"##,
|
||||
|
||||
E0372: r##"
|
||||
Trying to implement a trait for a trait object (as in `impl Trait1 for
|
||||
Trait2 { ... }`) does not work if the trait is not object-safe. Please see the
|
||||
[RFC 255] for more details on object safety rules.
|
||||
|
||||
[RFC 255]:https://github.com/rust-lang/rfcs/blob/master/text/0255-object-\
|
||||
safety.md
|
||||
"##
|
||||
|
||||
}
|
||||
@ -660,8 +781,6 @@ fn main() {
|
||||
E0068,
|
||||
E0070,
|
||||
E0071,
|
||||
E0072,
|
||||
E0073,
|
||||
E0074,
|
||||
E0075,
|
||||
E0076,
|
||||
@ -685,7 +804,6 @@ fn main() {
|
||||
E0118,
|
||||
E0119,
|
||||
E0120,
|
||||
E0121,
|
||||
E0122,
|
||||
E0123,
|
||||
E0124,
|
||||
@ -702,7 +820,6 @@ fn main() {
|
||||
E0172,
|
||||
E0173, // manual implementations of unboxed closure traits are experimental
|
||||
E0174, // explicit use of unboxed closure methods are experimental
|
||||
E0178,
|
||||
E0182,
|
||||
E0183,
|
||||
E0185,
|
||||
@ -774,8 +891,6 @@ fn main() {
|
||||
E0366, // dropck forbid specialization to concrete type or region
|
||||
E0367, // dropck forbid specialization to predicate not in struct/enum
|
||||
E0369, // binary operation `<op>` cannot be applied to types
|
||||
E0371, // impl Trait for Trait is illegal
|
||||
E0372, // impl Trait for Trait where Trait is not object safe
|
||||
E0374, // the trait `CoerceUnsized` may only be implemented for a coercion
|
||||
// between structures with one field being coerced, none found
|
||||
E0375, // the trait `CoerceUnsized` may only be implemented for a coercion
|
||||
|
@ -15,14 +15,14 @@ trait Foo { fn dummy(&self) { } }
|
||||
trait Bar: Foo { }
|
||||
trait Baz: Bar { }
|
||||
|
||||
// Subtraits of Baz are not legal:
|
||||
// Supertraits of Baz are not legal:
|
||||
impl Foo for Baz { } //~ ERROR E0371
|
||||
impl Bar for Baz { } //~ ERROR E0371
|
||||
impl Baz for Baz { } //~ ERROR E0371
|
||||
|
||||
// But other random traits are:
|
||||
trait Other { }
|
||||
impl Other for Baz { } // OK, Bar not a subtrait of Baz
|
||||
impl Other for Baz { } // OK, Other not a supertrait of Baz
|
||||
|
||||
// If the trait is not object-safe, we give a more tailored message
|
||||
// because we're such schnuckels:
|
||||
|
Loading…
Reference in New Issue
Block a user