Put each error code long explanation into their own markdown file
This commit is contained in:
parent
3302190b67
commit
cd274632f8
File diff suppressed because it is too large
Load Diff
24
src/librustc_error_codes/error_codes/E0001.md
Normal file
24
src/librustc_error_codes/error_codes/E0001.md
Normal file
@ -0,0 +1,24 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
This error suggests that the expression arm corresponding to the noted pattern
|
||||
will never be reached as for all possible values of the expression being
|
||||
matched, one of the preceding patterns will match.
|
||||
|
||||
This means that perhaps some of the preceding patterns are too general, this
|
||||
one is too specific or the ordering is incorrect.
|
||||
|
||||
For example, the following `match` block has too many arms:
|
||||
|
||||
```
|
||||
match Some(0) {
|
||||
Some(bar) => {/* ... */}
|
||||
x => {/* ... */} // This handles the `None` case
|
||||
_ => {/* ... */} // All possible cases have already been handled
|
||||
}
|
||||
```
|
||||
|
||||
`match` blocks have their patterns matched in order, so, for example, putting
|
||||
a wildcard arm above a more specific arm will make the latter arm irrelevant.
|
||||
|
||||
Ensure the ordering of the match arm is correct and remove any superfluous
|
||||
arms.
|
29
src/librustc_error_codes/error_codes/E0002.md
Normal file
29
src/librustc_error_codes/error_codes/E0002.md
Normal file
@ -0,0 +1,29 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
This error indicates that an empty match expression is invalid because the type
|
||||
it is matching on is non-empty (there exist values of this type). In safe code
|
||||
it is impossible to create an instance of an empty type, so empty match
|
||||
expressions are almost never desired. This error is typically fixed by adding
|
||||
one or more cases to the match expression.
|
||||
|
||||
An example of an empty type is `enum Empty { }`. So, the following will work:
|
||||
|
||||
```
|
||||
enum Empty {}
|
||||
|
||||
fn foo(x: Empty) {
|
||||
match x {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
However, this won't:
|
||||
|
||||
```compile_fail
|
||||
fn foo(x: Option<String>) {
|
||||
match x {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
```
|
46
src/librustc_error_codes/error_codes/E0004.md
Normal file
46
src/librustc_error_codes/error_codes/E0004.md
Normal file
@ -0,0 +1,46 @@
|
||||
This error indicates that the compiler cannot guarantee a matching pattern for
|
||||
one or more possible inputs to a match expression. Guaranteed matches are
|
||||
required in order to assign values to match expressions, or alternatively,
|
||||
determine the flow of execution.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0004
|
||||
enum Terminator {
|
||||
HastaLaVistaBaby,
|
||||
TalkToMyHand,
|
||||
}
|
||||
|
||||
let x = Terminator::HastaLaVistaBaby;
|
||||
|
||||
match x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered
|
||||
Terminator::TalkToMyHand => {}
|
||||
}
|
||||
```
|
||||
|
||||
If you encounter this error you must alter your patterns so that every possible
|
||||
value of the input type is matched. For types with a small number of variants
|
||||
(like enums) you should probably cover all cases explicitly. Alternatively, the
|
||||
underscore `_` wildcard pattern can be added after all other patterns to match
|
||||
"anything else". Example:
|
||||
|
||||
```
|
||||
enum Terminator {
|
||||
HastaLaVistaBaby,
|
||||
TalkToMyHand,
|
||||
}
|
||||
|
||||
let x = Terminator::HastaLaVistaBaby;
|
||||
|
||||
match x {
|
||||
Terminator::TalkToMyHand => {}
|
||||
Terminator::HastaLaVistaBaby => {}
|
||||
}
|
||||
|
||||
// or:
|
||||
|
||||
match x {
|
||||
Terminator::TalkToMyHand => {}
|
||||
_ => {}
|
||||
}
|
||||
```
|
30
src/librustc_error_codes/error_codes/E0005.md
Normal file
30
src/librustc_error_codes/error_codes/E0005.md
Normal file
@ -0,0 +1,30 @@
|
||||
Patterns used to bind names must be irrefutable, that is, they must guarantee
|
||||
that a name will be extracted in all cases.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0005
|
||||
let x = Some(1);
|
||||
let Some(y) = x;
|
||||
// error: refutable pattern in local binding: `None` not covered
|
||||
```
|
||||
|
||||
If you encounter this error you probably need to use a `match` or `if let` to
|
||||
deal with the possibility of failure. Example:
|
||||
|
||||
```
|
||||
let x = Some(1);
|
||||
|
||||
match x {
|
||||
Some(y) => {
|
||||
// do something
|
||||
},
|
||||
None => {}
|
||||
}
|
||||
|
||||
// or:
|
||||
|
||||
if let Some(y) = x {
|
||||
// do something
|
||||
}
|
||||
```
|
18
src/librustc_error_codes/error_codes/E0007.md
Normal file
18
src/librustc_error_codes/error_codes/E0007.md
Normal file
@ -0,0 +1,18 @@
|
||||
This error indicates that the bindings in a match arm would require a value to
|
||||
be moved into more than one location, thus violating unique ownership. Code
|
||||
like the following is invalid as it requires the entire `Option<String>` to be
|
||||
moved into a variable called `op_string` while simultaneously requiring the
|
||||
inner `String` to be moved into a variable called `s`.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0007
|
||||
let x = Some("s".to_string());
|
||||
|
||||
match x {
|
||||
op_string @ Some(s) => {}, // error: cannot bind by-move with sub-bindings
|
||||
None => {},
|
||||
}
|
||||
```
|
||||
|
||||
See also the error E0303.
|
48
src/librustc_error_codes/error_codes/E0009.md
Normal file
48
src/librustc_error_codes/error_codes/E0009.md
Normal file
@ -0,0 +1,48 @@
|
||||
In a pattern, all values that don't implement the `Copy` trait have to be bound
|
||||
the same way. The goal here is to avoid binding simultaneously by-move and
|
||||
by-ref.
|
||||
|
||||
This limitation may be removed in a future version of Rust.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0009
|
||||
struct X { x: (), }
|
||||
|
||||
let x = Some((X { x: () }, X { x: () }));
|
||||
match x {
|
||||
Some((y, ref z)) => {}, // error: cannot bind by-move and by-ref in the
|
||||
// same pattern
|
||||
None => panic!()
|
||||
}
|
||||
```
|
||||
|
||||
You have two solutions:
|
||||
|
||||
Solution #1: Bind the pattern's values the same way.
|
||||
|
||||
```
|
||||
struct X { x: (), }
|
||||
|
||||
let x = Some((X { x: () }, X { x: () }));
|
||||
match x {
|
||||
Some((ref y, ref z)) => {},
|
||||
// or Some((y, z)) => {}
|
||||
None => panic!()
|
||||
}
|
||||
```
|
||||
|
||||
Solution #2: Implement the `Copy` trait for the `X` structure.
|
||||
|
||||
However, please keep in mind that the first solution should be preferred.
|
||||
|
||||
```
|
||||
#[derive(Clone, Copy)]
|
||||
struct X { x: (), }
|
||||
|
||||
let x = Some((X { x: () }, X { x: () }));
|
||||
match x {
|
||||
Some((y, ref z)) => {},
|
||||
None => panic!()
|
||||
}
|
||||
```
|
11
src/librustc_error_codes/error_codes/E0010.md
Normal file
11
src/librustc_error_codes/error_codes/E0010.md
Normal file
@ -0,0 +1,11 @@
|
||||
The value of statics and constants must be known at compile time, and they live
|
||||
for the entire lifetime of a program. Creating a boxed value allocates memory on
|
||||
the heap at runtime, and therefore cannot be done at compile time.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0010
|
||||
#![feature(box_syntax)]
|
||||
|
||||
const CON : Box<i32> = box 0;
|
||||
```
|
18
src/librustc_error_codes/error_codes/E0013.md
Normal file
18
src/librustc_error_codes/error_codes/E0013.md
Normal file
@ -0,0 +1,18 @@
|
||||
Static and const variables can refer to other const variables. But a const
|
||||
variable cannot refer to a static variable.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0013
|
||||
static X: i32 = 42;
|
||||
const Y: i32 = X;
|
||||
```
|
||||
|
||||
In this example, `Y` cannot refer to `X` here. To fix this, the value can be
|
||||
extracted as a const and then used:
|
||||
|
||||
```
|
||||
const A: i32 = 42;
|
||||
static X: i32 = A;
|
||||
const Y: i32 = A;
|
||||
```
|
20
src/librustc_error_codes/error_codes/E0014.md
Normal file
20
src/librustc_error_codes/error_codes/E0014.md
Normal file
@ -0,0 +1,20 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
Constants can only be initialized by a constant value or, in a future
|
||||
version of Rust, a call to a const function. This error indicates the use
|
||||
of a path (like a::b, or x) denoting something other than one of these
|
||||
allowed items.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```
|
||||
const FOO: i32 = { let x = 0; x }; // 'x' isn't a constant nor a function!
|
||||
```
|
||||
|
||||
To avoid it, you have to replace the non-constant value:
|
||||
|
||||
```
|
||||
const FOO: i32 = { const X : i32 = 0; X };
|
||||
// or even:
|
||||
const FOO2: i32 = { 0 }; // but brackets are useless here
|
||||
```
|
14
src/librustc_error_codes/error_codes/E0015.md
Normal file
14
src/librustc_error_codes/error_codes/E0015.md
Normal file
@ -0,0 +1,14 @@
|
||||
The only functions that can be called in static or constant expressions are
|
||||
`const` functions, and struct/enum constructors. `const` functions are only
|
||||
available on a nightly compiler. Rust currently does not support more general
|
||||
compile-time function execution.
|
||||
|
||||
```
|
||||
const FOO: Option<u8> = Some(1); // enum constructor
|
||||
struct Bar {x: u8}
|
||||
const BAR: Bar = Bar {x: 1}; // struct constructor
|
||||
```
|
||||
|
||||
See [RFC 911] for more details on the design of `const fn`s.
|
||||
|
||||
[RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md
|
20
src/librustc_error_codes/error_codes/E0017.md
Normal file
20
src/librustc_error_codes/error_codes/E0017.md
Normal file
@ -0,0 +1,20 @@
|
||||
References in statics and constants may only refer to immutable values.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0017
|
||||
static X: i32 = 1;
|
||||
const C: i32 = 2;
|
||||
|
||||
// these three are not allowed:
|
||||
const CR: &mut i32 = &mut C;
|
||||
static STATIC_REF: &'static mut i32 = &mut X;
|
||||
static CONST_REF: &'static mut i32 = &mut C;
|
||||
```
|
||||
|
||||
Statics are shared everywhere, and if they refer to mutable data one might
|
||||
violate memory safety since holding multiple mutable references to shared data
|
||||
is not allowed.
|
||||
|
||||
If you really want global mutable state, try using `static mut` or a global
|
||||
`UnsafeCell`.
|
36
src/librustc_error_codes/error_codes/E0019.md
Normal file
36
src/librustc_error_codes/error_codes/E0019.md
Normal file
@ -0,0 +1,36 @@
|
||||
A function call isn't allowed in the const's initialization expression
|
||||
because the expression's value must be known at compile-time.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0019
|
||||
#![feature(box_syntax)]
|
||||
|
||||
fn main() {
|
||||
struct MyOwned;
|
||||
|
||||
static STATIC11: Box<MyOwned> = box MyOwned; // error!
|
||||
}
|
||||
```
|
||||
|
||||
Remember: you can't use a function call inside a const's initialization
|
||||
expression! However, you can totally use it anywhere else:
|
||||
|
||||
```
|
||||
enum Test {
|
||||
V1
|
||||
}
|
||||
|
||||
impl Test {
|
||||
fn func(&self) -> i32 {
|
||||
12
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
const FOO: Test = Test::V1;
|
||||
|
||||
FOO.func(); // here is good
|
||||
let x = FOO.func(); // or even here!
|
||||
}
|
||||
```
|
47
src/librustc_error_codes/error_codes/E0023.md
Normal file
47
src/librustc_error_codes/error_codes/E0023.md
Normal file
@ -0,0 +1,47 @@
|
||||
A pattern used to match against an enum variant must provide a sub-pattern for
|
||||
each field of the enum variant. This error indicates that a pattern attempted to
|
||||
extract an incorrect number of fields from a variant.
|
||||
|
||||
```
|
||||
enum Fruit {
|
||||
Apple(String, String),
|
||||
Pear(u32),
|
||||
}
|
||||
```
|
||||
|
||||
Here the `Apple` variant has two fields, and should be matched against like so:
|
||||
|
||||
```
|
||||
enum Fruit {
|
||||
Apple(String, String),
|
||||
Pear(u32),
|
||||
}
|
||||
|
||||
let x = Fruit::Apple(String::new(), String::new());
|
||||
|
||||
// Correct.
|
||||
match x {
|
||||
Fruit::Apple(a, b) => {},
|
||||
_ => {}
|
||||
}
|
||||
```
|
||||
|
||||
Matching with the wrong number of fields has no sensible interpretation:
|
||||
|
||||
```compile_fail,E0023
|
||||
enum Fruit {
|
||||
Apple(String, String),
|
||||
Pear(u32),
|
||||
}
|
||||
|
||||
let x = Fruit::Apple(String::new(), String::new());
|
||||
|
||||
// Incorrect.
|
||||
match x {
|
||||
Fruit::Apple(a) => {},
|
||||
Fruit::Apple(a, b, c) => {},
|
||||
}
|
||||
```
|
||||
|
||||
Check how many fields the enum was declared with and ensure that your pattern
|
||||
uses the same number.
|
33
src/librustc_error_codes/error_codes/E0025.md
Normal file
33
src/librustc_error_codes/error_codes/E0025.md
Normal file
@ -0,0 +1,33 @@
|
||||
Each field of a struct can only be bound once in a pattern. Erroneous code
|
||||
example:
|
||||
|
||||
```compile_fail,E0025
|
||||
struct Foo {
|
||||
a: u8,
|
||||
b: u8,
|
||||
}
|
||||
|
||||
fn main(){
|
||||
let x = Foo { a:1, b:2 };
|
||||
|
||||
let Foo { a: x, a: y } = x;
|
||||
// error: field `a` bound multiple times in the pattern
|
||||
}
|
||||
```
|
||||
|
||||
Each occurrence of a field name binds the value of that field, so to fix this
|
||||
error you will have to remove or alter the duplicate uses of the field name.
|
||||
Perhaps you misspelled another field name? Example:
|
||||
|
||||
```
|
||||
struct Foo {
|
||||
a: u8,
|
||||
b: u8,
|
||||
}
|
||||
|
||||
fn main(){
|
||||
let x = Foo { a:1, b:2 };
|
||||
|
||||
let Foo { a: x, b: y } = x; // ok!
|
||||
}
|
||||
```
|
51
src/librustc_error_codes/error_codes/E0026.md
Normal file
51
src/librustc_error_codes/error_codes/E0026.md
Normal file
@ -0,0 +1,51 @@
|
||||
This error indicates that a struct pattern attempted to extract a non-existent
|
||||
field from a struct. Struct fields are identified by the name used before the
|
||||
colon `:` so struct patterns should resemble the declaration of the struct type
|
||||
being matched.
|
||||
|
||||
```
|
||||
// Correct matching.
|
||||
struct Thing {
|
||||
x: u32,
|
||||
y: u32
|
||||
}
|
||||
|
||||
let thing = Thing { x: 1, y: 2 };
|
||||
|
||||
match thing {
|
||||
Thing { x: xfield, y: yfield } => {}
|
||||
}
|
||||
```
|
||||
|
||||
If you are using shorthand field patterns but want to refer to the struct field
|
||||
by a different name, you should rename it explicitly.
|
||||
|
||||
Change this:
|
||||
|
||||
```compile_fail,E0026
|
||||
struct Thing {
|
||||
x: u32,
|
||||
y: u32
|
||||
}
|
||||
|
||||
let thing = Thing { x: 0, y: 0 };
|
||||
|
||||
match thing {
|
||||
Thing { x, z } => {}
|
||||
}
|
||||
```
|
||||
|
||||
To this:
|
||||
|
||||
```
|
||||
struct Thing {
|
||||
x: u32,
|
||||
y: u32
|
||||
}
|
||||
|
||||
let thing = Thing { x: 0, y: 0 };
|
||||
|
||||
match thing {
|
||||
Thing { x, y: z } => {}
|
||||
}
|
||||
```
|
39
src/librustc_error_codes/error_codes/E0027.md
Normal file
39
src/librustc_error_codes/error_codes/E0027.md
Normal file
@ -0,0 +1,39 @@
|
||||
This error indicates that a pattern for a struct fails to specify a sub-pattern
|
||||
for every one of the struct's fields. Ensure that each field from the struct's
|
||||
definition is mentioned in the pattern, or use `..` to ignore unwanted fields.
|
||||
|
||||
For example:
|
||||
|
||||
```compile_fail,E0027
|
||||
struct Dog {
|
||||
name: String,
|
||||
age: u32,
|
||||
}
|
||||
|
||||
let d = Dog { name: "Rusty".to_string(), age: 8 };
|
||||
|
||||
// This is incorrect.
|
||||
match d {
|
||||
Dog { age: x } => {}
|
||||
}
|
||||
```
|
||||
|
||||
This is correct (explicit):
|
||||
|
||||
```
|
||||
struct Dog {
|
||||
name: String,
|
||||
age: u32,
|
||||
}
|
||||
|
||||
let d = Dog { name: "Rusty".to_string(), age: 8 };
|
||||
|
||||
match d {
|
||||
Dog { name: ref n, age: x } => {}
|
||||
}
|
||||
|
||||
// This is also correct (ignore unused fields).
|
||||
match d {
|
||||
Dog { age: x, .. } => {}
|
||||
}
|
||||
```
|
22
src/librustc_error_codes/error_codes/E0029.md
Normal file
22
src/librustc_error_codes/error_codes/E0029.md
Normal file
@ -0,0 +1,22 @@
|
||||
In a match expression, only numbers and characters can be matched against a
|
||||
range. This is because the compiler checks that the range is non-empty at
|
||||
compile-time, and is unable to evaluate arbitrary comparison functions. If you
|
||||
want to capture values of an orderable type between two end-points, you can use
|
||||
a guard.
|
||||
|
||||
```compile_fail,E0029
|
||||
let string = "salutations !";
|
||||
|
||||
// The ordering relation for strings cannot be evaluated at compile time,
|
||||
// so this doesn't work:
|
||||
match string {
|
||||
"hello" ..= "world" => {}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// This is a more general version, using a guard:
|
||||
match string {
|
||||
s if s >= "hello" && s <= "world" => {}
|
||||
_ => {}
|
||||
}
|
||||
```
|
15
src/librustc_error_codes/error_codes/E0030.md
Normal file
15
src/librustc_error_codes/error_codes/E0030.md
Normal file
@ -0,0 +1,15 @@
|
||||
When matching against a range, the compiler verifies that the range is
|
||||
non-empty. Range patterns include both end-points, so this is equivalent to
|
||||
requiring the start of the range to be less than or equal to the end of the
|
||||
range.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0030
|
||||
match 5u32 {
|
||||
// This range is ok, albeit pointless.
|
||||
1 ..= 1 => {}
|
||||
// This range is empty, and the compiler can tell.
|
||||
1000 ..= 5 => {}
|
||||
}
|
||||
```
|
23
src/librustc_error_codes/error_codes/E0033.md
Normal file
23
src/librustc_error_codes/error_codes/E0033.md
Normal file
@ -0,0 +1,23 @@
|
||||
This error indicates that a pointer to a trait type cannot be implicitly
|
||||
dereferenced by a pattern. Every trait defines a type, but because the
|
||||
size of trait implementers isn't fixed, this type has no compile-time size.
|
||||
Therefore, all accesses to trait types must be through pointers. If you
|
||||
encounter this error you should try to avoid dereferencing the pointer.
|
||||
|
||||
```compile_fail,E0033
|
||||
# trait SomeTrait { fn method_one(&self){} fn method_two(&self){} }
|
||||
# impl<T> SomeTrait for T {}
|
||||
let trait_obj: &SomeTrait = &"some_value";
|
||||
|
||||
// This tries to implicitly dereference to create an unsized local variable.
|
||||
let &invalid = trait_obj;
|
||||
|
||||
// You can call methods without binding to the value being pointed at.
|
||||
trait_obj.method_one();
|
||||
trait_obj.method_two();
|
||||
```
|
||||
|
||||
You can read more about trait objects in the [Trait Objects] section of the
|
||||
Reference.
|
||||
|
||||
[Trait Objects]: https://doc.rust-lang.org/reference/types.html#trait-objects
|
84
src/librustc_error_codes/error_codes/E0034.md
Normal file
84
src/librustc_error_codes/error_codes/E0034.md
Normal file
@ -0,0 +1,84 @@
|
||||
The compiler doesn't know what method to call because more than one method
|
||||
has the same prototype. Erroneous code example:
|
||||
|
||||
```compile_fail,E0034
|
||||
struct Test;
|
||||
|
||||
trait Trait1 {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
trait Trait2 {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
impl Trait1 for Test { fn foo() {} }
|
||||
impl Trait2 for Test { fn foo() {} }
|
||||
|
||||
fn main() {
|
||||
Test::foo() // error, which foo() to call?
|
||||
}
|
||||
```
|
||||
|
||||
To avoid this error, you have to keep only one of them and remove the others.
|
||||
So let's take our example and fix it:
|
||||
|
||||
```
|
||||
struct Test;
|
||||
|
||||
trait Trait1 {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
impl Trait1 for Test { fn foo() {} }
|
||||
|
||||
fn main() {
|
||||
Test::foo() // and now that's good!
|
||||
}
|
||||
```
|
||||
|
||||
However, a better solution would be using fully explicit naming of type and
|
||||
trait:
|
||||
|
||||
```
|
||||
struct Test;
|
||||
|
||||
trait Trait1 {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
trait Trait2 {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
impl Trait1 for Test { fn foo() {} }
|
||||
impl Trait2 for Test { fn foo() {} }
|
||||
|
||||
fn main() {
|
||||
<Test as Trait1>::foo()
|
||||
}
|
||||
```
|
||||
|
||||
One last example:
|
||||
|
||||
```
|
||||
trait F {
|
||||
fn m(&self);
|
||||
}
|
||||
|
||||
trait G {
|
||||
fn m(&self);
|
||||
}
|
||||
|
||||
struct X;
|
||||
|
||||
impl F for X { fn m(&self) { println!("I am F"); } }
|
||||
impl G for X { fn m(&self) { println!("I am G"); } }
|
||||
|
||||
fn main() {
|
||||
let f = X;
|
||||
|
||||
F::m(&f); // it displays "I am F"
|
||||
G::m(&f); // it displays "I am G"
|
||||
}
|
||||
```
|
291
src/librustc_error_codes/error_codes/E0038.md
Normal file
291
src/librustc_error_codes/error_codes/E0038.md
Normal file
@ -0,0 +1,291 @@
|
||||
Trait objects like `Box<Trait>` can only be constructed when certain
|
||||
requirements are satisfied by the trait in question.
|
||||
|
||||
Trait objects are a form of dynamic dispatch and use a dynamically sized type
|
||||
for the inner type. So, for a given trait `Trait`, when `Trait` is treated as a
|
||||
type, as in `Box<Trait>`, the inner type is 'unsized'. In such cases the boxed
|
||||
pointer is a 'fat pointer' that contains an extra pointer to a table of methods
|
||||
(among other things) for dynamic dispatch. This design mandates some
|
||||
restrictions on the types of traits that are allowed to be used in trait
|
||||
objects, which are collectively termed as 'object safety' rules.
|
||||
|
||||
Attempting to create a trait object for a non object-safe trait will trigger
|
||||
this error.
|
||||
|
||||
There are various rules:
|
||||
|
||||
### The trait cannot require `Self: Sized`
|
||||
|
||||
When `Trait` is treated as a type, the type does not implement the special
|
||||
`Sized` trait, because the type does not have a known size at compile time and
|
||||
can only be accessed behind a pointer. Thus, if we have a trait like the
|
||||
following:
|
||||
|
||||
```
|
||||
trait Foo where Self: Sized {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
We cannot create an object of type `Box<Foo>` or `&Foo` since in this case
|
||||
`Self` would not be `Sized`.
|
||||
|
||||
Generally, `Self: Sized` is used to indicate that the trait should not be used
|
||||
as a trait object. If the trait comes from your own crate, consider removing
|
||||
this restriction.
|
||||
|
||||
### Method references the `Self` type in its parameters or return type
|
||||
|
||||
This happens when a trait has a method like the following:
|
||||
|
||||
```
|
||||
trait Trait {
|
||||
fn foo(&self) -> Self;
|
||||
}
|
||||
|
||||
impl Trait for String {
|
||||
fn foo(&self) -> Self {
|
||||
"hi".to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait for u8 {
|
||||
fn foo(&self) -> Self {
|
||||
1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
(Note that `&self` and `&mut self` are okay, it's additional `Self` types which
|
||||
cause this problem.)
|
||||
|
||||
In such a case, the compiler cannot predict the return type of `foo()` in a
|
||||
situation like the following:
|
||||
|
||||
```compile_fail
|
||||
trait Trait {
|
||||
fn foo(&self) -> Self;
|
||||
}
|
||||
|
||||
fn call_foo(x: Box<Trait>) {
|
||||
let y = x.foo(); // What type is y?
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
If only some methods aren't object-safe, you can add a `where Self: Sized` bound
|
||||
on them to mark them as explicitly unavailable to trait objects. The
|
||||
functionality will still be available to all other implementers, including
|
||||
`Box<Trait>` which is itself sized (assuming you `impl Trait for Box<Trait>`).
|
||||
|
||||
```
|
||||
trait Trait {
|
||||
fn foo(&self) -> Self where Self: Sized;
|
||||
// more functions
|
||||
}
|
||||
```
|
||||
|
||||
Now, `foo()` can no longer be called on a trait object, but you will now be
|
||||
allowed to make a trait object, and that will be able to call any object-safe
|
||||
methods. With such a bound, one can still call `foo()` on types implementing
|
||||
that trait that aren't behind trait objects.
|
||||
|
||||
### Method has generic type parameters
|
||||
|
||||
As mentioned before, trait objects contain pointers to method tables. So, if we
|
||||
have:
|
||||
|
||||
```
|
||||
trait Trait {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
impl Trait for String {
|
||||
fn foo(&self) {
|
||||
// implementation 1
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait for u8 {
|
||||
fn foo(&self) {
|
||||
// implementation 2
|
||||
}
|
||||
}
|
||||
// ...
|
||||
```
|
||||
|
||||
At compile time each implementation of `Trait` will produce a table containing
|
||||
the various methods (and other items) related to the implementation.
|
||||
|
||||
This works fine, but when the method gains generic parameters, we can have a
|
||||
problem.
|
||||
|
||||
Usually, generic parameters get _monomorphized_. For example, if I have
|
||||
|
||||
```
|
||||
fn foo<T>(x: T) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The machine code for `foo::<u8>()`, `foo::<bool>()`, `foo::<String>()`, or any
|
||||
other type substitution is different. Hence the compiler generates the
|
||||
implementation on-demand. If you call `foo()` with a `bool` parameter, the
|
||||
compiler will only generate code for `foo::<bool>()`. When we have additional
|
||||
type parameters, the number of monomorphized implementations the compiler
|
||||
generates does not grow drastically, since the compiler will only generate an
|
||||
implementation if the function is called with unparametrized substitutions
|
||||
(i.e., substitutions where none of the substituted types are themselves
|
||||
parametrized).
|
||||
|
||||
However, with trait objects we have to make a table containing _every_ object
|
||||
that implements the trait. Now, if it has type parameters, we need to add
|
||||
implementations for every type that implements the trait, and there could
|
||||
theoretically be an infinite number of types.
|
||||
|
||||
For example, with:
|
||||
|
||||
```
|
||||
trait Trait {
|
||||
fn foo<T>(&self, on: T);
|
||||
// more methods
|
||||
}
|
||||
|
||||
impl Trait for String {
|
||||
fn foo<T>(&self, on: T) {
|
||||
// implementation 1
|
||||
}
|
||||
}
|
||||
|
||||
impl Trait for u8 {
|
||||
fn foo<T>(&self, on: T) {
|
||||
// implementation 2
|
||||
}
|
||||
}
|
||||
|
||||
// 8 more implementations
|
||||
```
|
||||
|
||||
Now, if we have the following code:
|
||||
|
||||
```compile_fail,E0038
|
||||
# trait Trait { fn foo<T>(&self, on: T); }
|
||||
# impl Trait for String { fn foo<T>(&self, on: T) {} }
|
||||
# impl Trait for u8 { fn foo<T>(&self, on: T) {} }
|
||||
# impl Trait for bool { fn foo<T>(&self, on: T) {} }
|
||||
# // etc.
|
||||
fn call_foo(thing: Box<Trait>) {
|
||||
thing.foo(true); // this could be any one of the 8 types above
|
||||
thing.foo(1);
|
||||
thing.foo("hello");
|
||||
}
|
||||
```
|
||||
|
||||
We don't just need to create a table of all implementations of all methods of
|
||||
`Trait`, we need to create such a table, for each different type fed to
|
||||
`foo()`. In this case this turns out to be (10 types implementing `Trait`)*(3
|
||||
types being fed to `foo()`) = 30 implementations!
|
||||
|
||||
With real world traits these numbers can grow drastically.
|
||||
|
||||
To fix this, it is suggested to use a `where Self: Sized` bound similar to the
|
||||
fix for the sub-error above if you do not intend to call the method with type
|
||||
parameters:
|
||||
|
||||
```
|
||||
trait Trait {
|
||||
fn foo<T>(&self, on: T) where Self: Sized;
|
||||
// more methods
|
||||
}
|
||||
```
|
||||
|
||||
If this is not an option, consider replacing the type parameter with another
|
||||
trait object (e.g., if `T: OtherTrait`, use `on: Box<OtherTrait>`). If the
|
||||
number of types you intend to feed to this method is limited, consider manually
|
||||
listing out the methods of different types.
|
||||
|
||||
### Method has no receiver
|
||||
|
||||
Methods that do not take a `self` parameter can't be called since there won't be
|
||||
a way to get a pointer to the method table for them.
|
||||
|
||||
```
|
||||
trait Foo {
|
||||
fn foo() -> u8;
|
||||
}
|
||||
```
|
||||
|
||||
This could be called as `<Foo as Foo>::foo()`, which would not be able to pick
|
||||
an implementation.
|
||||
|
||||
Adding a `Self: Sized` bound to these methods will generally make this compile.
|
||||
|
||||
```
|
||||
trait Foo {
|
||||
fn foo() -> u8 where Self: Sized;
|
||||
}
|
||||
```
|
||||
|
||||
### The trait cannot contain associated constants
|
||||
|
||||
Just like static functions, associated constants aren't stored on the method
|
||||
table. If the trait or any subtrait contain an associated constant, they cannot
|
||||
be made into an object.
|
||||
|
||||
```compile_fail,E0038
|
||||
trait Foo {
|
||||
const X: i32;
|
||||
}
|
||||
|
||||
impl Foo {}
|
||||
```
|
||||
|
||||
A simple workaround is to use a helper method instead:
|
||||
|
||||
```
|
||||
trait Foo {
|
||||
fn x(&self) -> i32;
|
||||
}
|
||||
```
|
||||
|
||||
### The trait cannot use `Self` as a type parameter in the supertrait listing
|
||||
|
||||
This is similar to the second sub-error, but subtler. It happens in situations
|
||||
like the following:
|
||||
|
||||
```compile_fail,E0038
|
||||
trait Super<A: ?Sized> {}
|
||||
|
||||
trait Trait: Super<Self> {
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Super<Foo> for Foo{}
|
||||
|
||||
impl Trait for Foo {}
|
||||
|
||||
fn main() {
|
||||
let x: Box<dyn Trait>;
|
||||
}
|
||||
```
|
||||
|
||||
Here, the supertrait might have methods as follows:
|
||||
|
||||
```
|
||||
trait Super<A: ?Sized> {
|
||||
fn get_a(&self) -> &A; // note that this is object safe!
|
||||
}
|
||||
```
|
||||
|
||||
If the trait `Trait` was deriving from something like `Super<String>` or
|
||||
`Super<T>` (where `Foo` itself is `Foo<T>`), this is okay, because given a type
|
||||
`get_a()` will definitely return an object of that type.
|
||||
|
||||
However, if it derives from `Super<Self>`, even though `Super` is object safe,
|
||||
the method `get_a()` would return an object of unknown type when called on the
|
||||
function. `Self` type parameters let us make object safe traits no longer safe,
|
||||
so they are forbidden when specifying supertraits.
|
||||
|
||||
There's no easy fix for this, generally code will need to be refactored so that
|
||||
you no longer need to derive from `Super<Self>`.
|
22
src/librustc_error_codes/error_codes/E0040.md
Normal file
22
src/librustc_error_codes/error_codes/E0040.md
Normal file
@ -0,0 +1,22 @@
|
||||
It is not allowed to manually call destructors in Rust. It is also not
|
||||
necessary to do this since `drop` is called automatically whenever a value goes
|
||||
out of scope.
|
||||
|
||||
Here's an example of this error:
|
||||
|
||||
```compile_fail,E0040
|
||||
struct Foo {
|
||||
x: i32,
|
||||
}
|
||||
|
||||
impl Drop for Foo {
|
||||
fn drop(&mut self) {
|
||||
println!("kaboom");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut x = Foo { x: -7 };
|
||||
x.drop(); // error: explicit use of destructor method
|
||||
}
|
||||
```
|
14
src/librustc_error_codes/error_codes/E0044.md
Normal file
14
src/librustc_error_codes/error_codes/E0044.md
Normal file
@ -0,0 +1,14 @@
|
||||
You cannot use type or const parameters on foreign items.
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0044
|
||||
extern { fn some_func<T>(x: T); }
|
||||
```
|
||||
|
||||
To fix this, replace the generic parameter with the specializations that you
|
||||
need:
|
||||
|
||||
```
|
||||
extern { fn some_func_i32(x: i32); }
|
||||
extern { fn some_func_i64(x: i64); }
|
||||
```
|
21
src/librustc_error_codes/error_codes/E0045.md
Normal file
21
src/librustc_error_codes/error_codes/E0045.md
Normal file
@ -0,0 +1,21 @@
|
||||
Rust only supports variadic parameters for interoperability with C code in its
|
||||
FFI. As such, variadic parameters can only be used with functions which are
|
||||
using the C ABI. Examples of erroneous code:
|
||||
|
||||
```compile_fail
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
extern "rust-call" { fn foo(x: u8, ...); }
|
||||
|
||||
// or
|
||||
|
||||
fn foo(x: u8, ...) {}
|
||||
```
|
||||
|
||||
To fix such code, put them in an extern "C" block:
|
||||
|
||||
```
|
||||
extern "C" {
|
||||
fn foo (x: u8, ...);
|
||||
}
|
||||
```
|
29
src/librustc_error_codes/error_codes/E0046.md
Normal file
29
src/librustc_error_codes/error_codes/E0046.md
Normal file
@ -0,0 +1,29 @@
|
||||
Items are missing in a trait implementation. Erroneous code example:
|
||||
|
||||
```compile_fail,E0046
|
||||
trait Foo {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl Foo for Bar {}
|
||||
// error: not all trait items implemented, missing: `foo`
|
||||
```
|
||||
|
||||
When trying to make some type implement a trait `Foo`, you must, at minimum,
|
||||
provide implementations for all of `Foo`'s required methods (meaning the
|
||||
methods that do not have default implementations), as well as any required
|
||||
trait items like associated types or constants. Example:
|
||||
|
||||
```
|
||||
trait Foo {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl Foo for Bar {
|
||||
fn foo() {} // ok!
|
||||
}
|
||||
```
|
19
src/librustc_error_codes/error_codes/E0049.md
Normal file
19
src/librustc_error_codes/error_codes/E0049.md
Normal file
@ -0,0 +1,19 @@
|
||||
This error indicates that an attempted implementation of a trait method
|
||||
has the wrong number of type or const parameters.
|
||||
|
||||
For example, the trait below has a method `foo` with a type parameter `T`,
|
||||
but the implementation of `foo` for the type `Bar` is missing this parameter:
|
||||
|
||||
```compile_fail,E0049
|
||||
trait Foo {
|
||||
fn foo<T: Default>(x: T) -> Self;
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
// error: method `foo` has 0 type parameters but its trait declaration has 1
|
||||
// type parameter
|
||||
impl Foo for Bar {
|
||||
fn foo(x: bool) -> Self { Bar }
|
||||
}
|
||||
```
|
20
src/librustc_error_codes/error_codes/E0050.md
Normal file
20
src/librustc_error_codes/error_codes/E0050.md
Normal file
@ -0,0 +1,20 @@
|
||||
This error indicates that an attempted implementation of a trait method
|
||||
has the wrong number of function parameters.
|
||||
|
||||
For example, the trait below has a method `foo` with two function parameters
|
||||
(`&self` and `u8`), but the implementation of `foo` for the type `Bar` omits
|
||||
the `u8` parameter:
|
||||
|
||||
```compile_fail,E0050
|
||||
trait Foo {
|
||||
fn foo(&self, x: u8) -> bool;
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
// error: method `foo` has 1 parameter but the declaration in trait `Foo::foo`
|
||||
// has 2
|
||||
impl Foo for Bar {
|
||||
fn foo(&self) -> bool { true }
|
||||
}
|
||||
```
|
21
src/librustc_error_codes/error_codes/E0053.md
Normal file
21
src/librustc_error_codes/error_codes/E0053.md
Normal file
@ -0,0 +1,21 @@
|
||||
The parameters of any trait method must match between a trait implementation
|
||||
and the trait definition.
|
||||
|
||||
Here are a couple examples of this error:
|
||||
|
||||
```compile_fail,E0053
|
||||
trait Foo {
|
||||
fn foo(x: u16);
|
||||
fn bar(&self);
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl Foo for Bar {
|
||||
// error, expected u16, found i16
|
||||
fn foo(x: i16) { }
|
||||
|
||||
// error, types differ in mutability
|
||||
fn bar(&mut self) { }
|
||||
}
|
||||
```
|
16
src/librustc_error_codes/error_codes/E0054.md
Normal file
16
src/librustc_error_codes/error_codes/E0054.md
Normal file
@ -0,0 +1,16 @@
|
||||
It is not allowed to cast to a bool. If you are trying to cast a numeric type
|
||||
to a bool, you can compare it with zero instead:
|
||||
|
||||
```compile_fail,E0054
|
||||
let x = 5;
|
||||
|
||||
// Not allowed, won't compile
|
||||
let x_is_nonzero = x as bool;
|
||||
```
|
||||
|
||||
```
|
||||
let x = 5;
|
||||
|
||||
// Ok
|
||||
let x_is_nonzero = x != 0;
|
||||
```
|
28
src/librustc_error_codes/error_codes/E0055.md
Normal file
28
src/librustc_error_codes/error_codes/E0055.md
Normal file
@ -0,0 +1,28 @@
|
||||
During a method call, a value is automatically dereferenced as many times as
|
||||
needed to make the value's type match the method's receiver. The catch is that
|
||||
the compiler will only attempt to dereference a number of times up to the
|
||||
recursion limit (which can be set via the `recursion_limit` attribute).
|
||||
|
||||
For a somewhat artificial example:
|
||||
|
||||
```compile_fail,E0055
|
||||
#![recursion_limit="5"]
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
fn foo(&self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let foo = Foo;
|
||||
let ref_foo = &&&&&Foo;
|
||||
|
||||
// error, reached the recursion limit while auto-dereferencing `&&&&&Foo`
|
||||
ref_foo.foo();
|
||||
}
|
||||
```
|
||||
|
||||
One fix may be to increase the recursion limit. Note that it is possible to
|
||||
create an infinite recursion of dereferencing, in which case the only fix is to
|
||||
somehow break the recursion.
|
20
src/librustc_error_codes/error_codes/E0057.md
Normal file
20
src/librustc_error_codes/error_codes/E0057.md
Normal file
@ -0,0 +1,20 @@
|
||||
When invoking closures or other implementations of the function traits `Fn`,
|
||||
`FnMut` or `FnOnce` using call notation, the number of parameters passed to the
|
||||
function must match its definition.
|
||||
|
||||
An example using a closure:
|
||||
|
||||
```compile_fail,E0057
|
||||
let f = |x| x * 3;
|
||||
let a = f(); // invalid, too few parameters
|
||||
let b = f(4); // this works!
|
||||
let c = f(2, 3); // invalid, too many parameters
|
||||
```
|
||||
|
||||
A generic function must be treated similarly:
|
||||
|
||||
```
|
||||
fn foo<F: Fn()>(f: F) {
|
||||
f(); // this is valid, but f(3) would not work
|
||||
}
|
||||
```
|
25
src/librustc_error_codes/error_codes/E0059.md
Normal file
25
src/librustc_error_codes/error_codes/E0059.md
Normal file
@ -0,0 +1,25 @@
|
||||
The built-in function traits are generic over a tuple of the function arguments.
|
||||
If one uses angle-bracket notation (`Fn<(T,), Output=U>`) instead of parentheses
|
||||
(`Fn(T) -> U`) to denote the function trait, the type parameter should be a
|
||||
tuple. Otherwise function call notation cannot be used and the trait will not be
|
||||
implemented by closures.
|
||||
|
||||
The most likely source of this error is using angle-bracket notation without
|
||||
wrapping the function argument type into a tuple, for example:
|
||||
|
||||
```compile_fail,E0059
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) }
|
||||
```
|
||||
|
||||
It can be fixed by adjusting the trait bound like this:
|
||||
|
||||
```
|
||||
#![feature(unboxed_closures)]
|
||||
|
||||
fn foo<F: Fn<(i32,)>>(f: F) -> F::Output { f(3) }
|
||||
```
|
||||
|
||||
Note that `(T,)` always denotes the type of a 1-tuple containing an element of
|
||||
type `T`. The comma is necessary for syntactic disambiguation.
|
36
src/librustc_error_codes/error_codes/E0060.md
Normal file
36
src/librustc_error_codes/error_codes/E0060.md
Normal file
@ -0,0 +1,36 @@
|
||||
External C functions are allowed to be variadic. However, a variadic function
|
||||
takes a minimum number of arguments. For example, consider C's variadic `printf`
|
||||
function:
|
||||
|
||||
```
|
||||
use std::os::raw::{c_char, c_int};
|
||||
|
||||
extern "C" {
|
||||
fn printf(_: *const c_char, ...) -> c_int;
|
||||
}
|
||||
```
|
||||
|
||||
Using this declaration, it must be called with at least one argument, so
|
||||
simply calling `printf()` is invalid. But the following uses are allowed:
|
||||
|
||||
```
|
||||
# #![feature(static_nobundle)]
|
||||
# use std::os::raw::{c_char, c_int};
|
||||
# #[cfg_attr(all(windows, target_env = "msvc"),
|
||||
# link(name = "legacy_stdio_definitions", kind = "static-nobundle"))]
|
||||
# extern "C" { fn printf(_: *const c_char, ...) -> c_int; }
|
||||
# fn main() {
|
||||
unsafe {
|
||||
use std::ffi::CString;
|
||||
|
||||
let fmt = CString::new("test\n").unwrap();
|
||||
printf(fmt.as_ptr());
|
||||
|
||||
let fmt = CString::new("number = %d\n").unwrap();
|
||||
printf(fmt.as_ptr(), 3);
|
||||
|
||||
let fmt = CString::new("%d, %d\n").unwrap();
|
||||
printf(fmt.as_ptr(), 10, 5);
|
||||
}
|
||||
# }
|
||||
```
|
13
src/librustc_error_codes/error_codes/E0061.md
Normal file
13
src/librustc_error_codes/error_codes/E0061.md
Normal file
@ -0,0 +1,13 @@
|
||||
The number of arguments passed to a function must match the number of arguments
|
||||
specified in the function signature.
|
||||
|
||||
For example, a function like:
|
||||
|
||||
```
|
||||
fn f(a: u16, b: &str) {}
|
||||
```
|
||||
|
||||
Must always be called with exactly two arguments, e.g., `f(2, "test")`.
|
||||
|
||||
Note that Rust does not have a notion of optional function arguments or
|
||||
variadic functions (except for its C-FFI).
|
28
src/librustc_error_codes/error_codes/E0062.md
Normal file
28
src/librustc_error_codes/error_codes/E0062.md
Normal file
@ -0,0 +1,28 @@
|
||||
This error indicates that during an attempt to build a struct or struct-like
|
||||
enum variant, one of the fields was specified more than once. Erroneous code
|
||||
example:
|
||||
|
||||
```compile_fail,E0062
|
||||
struct Foo {
|
||||
x: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Foo {
|
||||
x: 0,
|
||||
x: 0, // error: field `x` specified more than once
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Each field should be specified exactly one time. Example:
|
||||
|
||||
```
|
||||
struct Foo {
|
||||
x: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Foo { x: 0 }; // ok!
|
||||
}
|
||||
```
|
26
src/librustc_error_codes/error_codes/E0063.md
Normal file
26
src/librustc_error_codes/error_codes/E0063.md
Normal file
@ -0,0 +1,26 @@
|
||||
This error indicates that during an attempt to build a struct or struct-like
|
||||
enum variant, one of the fields was not provided. Erroneous code example:
|
||||
|
||||
```compile_fail,E0063
|
||||
struct Foo {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Foo { x: 0 }; // error: missing field: `y`
|
||||
}
|
||||
```
|
||||
|
||||
Each field should be specified exactly once. Example:
|
||||
|
||||
```
|
||||
struct Foo {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = Foo { x: 0, y: 0 }; // ok!
|
||||
}
|
||||
```
|
33
src/librustc_error_codes/error_codes/E0067.md
Normal file
33
src/librustc_error_codes/error_codes/E0067.md
Normal file
@ -0,0 +1,33 @@
|
||||
The left-hand side of a compound assignment expression must be a place
|
||||
expression. A place expression represents a memory location and includes
|
||||
item paths (ie, namespaced variables), dereferences, indexing expressions,
|
||||
and field references.
|
||||
|
||||
Let's start with some erroneous code examples:
|
||||
|
||||
```compile_fail,E0067
|
||||
use std::collections::LinkedList;
|
||||
|
||||
// Bad: assignment to non-place expression
|
||||
LinkedList::new() += 1;
|
||||
|
||||
// ...
|
||||
|
||||
fn some_func(i: &mut i32) {
|
||||
i += 12; // Error : '+=' operation cannot be applied on a reference !
|
||||
}
|
||||
```
|
||||
|
||||
And now some working examples:
|
||||
|
||||
```
|
||||
let mut i : i32 = 0;
|
||||
|
||||
i += 12; // Good !
|
||||
|
||||
// ...
|
||||
|
||||
fn some_func(i: &mut i32) {
|
||||
*i += 12; // Good !
|
||||
}
|
||||
```
|
12
src/librustc_error_codes/error_codes/E0069.md
Normal file
12
src/librustc_error_codes/error_codes/E0069.md
Normal file
@ -0,0 +1,12 @@
|
||||
The compiler found a function whose body contains a `return;` statement but
|
||||
whose return type is not `()`. An example of this is:
|
||||
|
||||
```compile_fail,E0069
|
||||
// error
|
||||
fn foo() -> u8 {
|
||||
return;
|
||||
}
|
||||
```
|
||||
|
||||
Since `return;` is just like `return ();`, there is a mismatch between the
|
||||
function's return type and the value being returned.
|
47
src/librustc_error_codes/error_codes/E0070.md
Normal file
47
src/librustc_error_codes/error_codes/E0070.md
Normal file
@ -0,0 +1,47 @@
|
||||
The left-hand side of an assignment operator must be a place expression. A
|
||||
place expression represents a memory location and can be a variable (with
|
||||
optional namespacing), a dereference, an indexing expression or a field
|
||||
reference.
|
||||
|
||||
More details can be found in the [Expressions] section of the Reference.
|
||||
|
||||
[Expressions]: https://doc.rust-lang.org/reference/expressions.html#places-rvalues-and-temporaries
|
||||
|
||||
Now, we can go further. Here are some erroneous code examples:
|
||||
|
||||
```compile_fail,E0070
|
||||
struct SomeStruct {
|
||||
x: i32,
|
||||
y: i32
|
||||
}
|
||||
|
||||
const SOME_CONST : i32 = 12;
|
||||
|
||||
fn some_other_func() {}
|
||||
|
||||
fn some_function() {
|
||||
SOME_CONST = 14; // error : a constant value cannot be changed!
|
||||
1 = 3; // error : 1 isn't a valid place!
|
||||
some_other_func() = 4; // error : we cannot assign value to a function!
|
||||
SomeStruct.x = 12; // error : SomeStruct a structure name but it is used
|
||||
// like a variable!
|
||||
}
|
||||
```
|
||||
|
||||
And now let's give working examples:
|
||||
|
||||
```
|
||||
struct SomeStruct {
|
||||
x: i32,
|
||||
y: i32
|
||||
}
|
||||
let mut s = SomeStruct {x: 0, y: 0};
|
||||
|
||||
s.x = 3; // that's good !
|
||||
|
||||
// ...
|
||||
|
||||
fn some_func(x: &mut i32) {
|
||||
*x = 12; // that's good !
|
||||
}
|
||||
```
|
27
src/librustc_error_codes/error_codes/E0071.md
Normal file
27
src/librustc_error_codes/error_codes/E0071.md
Normal file
@ -0,0 +1,27 @@
|
||||
You tried to use structure-literal syntax to create an item that is
|
||||
not a structure or enum variant.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0071
|
||||
type U32 = u32;
|
||||
let t = U32 { value: 4 }; // error: expected struct, variant or union type,
|
||||
// found builtin type `u32`
|
||||
```
|
||||
|
||||
To fix this, ensure that the name was correctly spelled, and that
|
||||
the correct form of initializer was used.
|
||||
|
||||
For example, the code above can be fixed to:
|
||||
|
||||
```
|
||||
enum Foo {
|
||||
FirstValue(i32)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let u = Foo::FirstValue(0i32);
|
||||
|
||||
let t = 4;
|
||||
}
|
||||
```
|
34
src/librustc_error_codes/error_codes/E0072.md
Normal file
34
src/librustc_error_codes/error_codes/E0072.md
Normal file
@ -0,0 +1,34 @@
|
||||
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:
|
||||
|
||||
```compile_fail,E0072
|
||||
// error, invalid 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,
|
||||
|
||||
```plain
|
||||
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.
|
19
src/librustc_error_codes/error_codes/E0073.md
Normal file
19
src/librustc_error_codes/error_codes/E0073.md
Normal file
@ -0,0 +1,19 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
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 }`.
|
24
src/librustc_error_codes/error_codes/E0074.md
Normal file
24
src/librustc_error_codes/error_codes/E0074.md
Normal file
@ -0,0 +1,24 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
When using the `#[simd]` attribute on a tuple struct, the components of the
|
||||
tuple struct must all be of a concrete, nongeneric type so the compiler can
|
||||
reason about how to use SIMD with them. This error will occur if the types
|
||||
are generic.
|
||||
|
||||
This will cause an error:
|
||||
|
||||
```
|
||||
#![feature(repr_simd)]
|
||||
|
||||
#[repr(simd)]
|
||||
struct Bad<T>(T, T, T);
|
||||
```
|
||||
|
||||
This will not:
|
||||
|
||||
```
|
||||
#![feature(repr_simd)]
|
||||
|
||||
#[repr(simd)]
|
||||
struct Good(u32, u32, u32);
|
||||
```
|
21
src/librustc_error_codes/error_codes/E0075.md
Normal file
21
src/librustc_error_codes/error_codes/E0075.md
Normal file
@ -0,0 +1,21 @@
|
||||
The `#[simd]` attribute can only be applied to non empty tuple structs, because
|
||||
it doesn't make sense to try to use SIMD operations when there are no values to
|
||||
operate on.
|
||||
|
||||
This will cause an error:
|
||||
|
||||
```compile_fail,E0075
|
||||
#![feature(repr_simd)]
|
||||
|
||||
#[repr(simd)]
|
||||
struct Bad;
|
||||
```
|
||||
|
||||
This will not:
|
||||
|
||||
```
|
||||
#![feature(repr_simd)]
|
||||
|
||||
#[repr(simd)]
|
||||
struct Good(u32);
|
||||
```
|
21
src/librustc_error_codes/error_codes/E0076.md
Normal file
21
src/librustc_error_codes/error_codes/E0076.md
Normal file
@ -0,0 +1,21 @@
|
||||
When using the `#[simd]` attribute to automatically use SIMD operations in tuple
|
||||
struct, the types in the struct must all be of the same type, or the compiler
|
||||
will trigger this error.
|
||||
|
||||
This will cause an error:
|
||||
|
||||
```compile_fail,E0076
|
||||
#![feature(repr_simd)]
|
||||
|
||||
#[repr(simd)]
|
||||
struct Bad(u16, u32, u32);
|
||||
```
|
||||
|
||||
This will not:
|
||||
|
||||
```
|
||||
#![feature(repr_simd)]
|
||||
|
||||
#[repr(simd)]
|
||||
struct Good(u32, u32, u32);
|
||||
```
|
20
src/librustc_error_codes/error_codes/E0077.md
Normal file
20
src/librustc_error_codes/error_codes/E0077.md
Normal file
@ -0,0 +1,20 @@
|
||||
When using the `#[simd]` attribute on a tuple struct, the elements in the tuple
|
||||
must be machine types so SIMD operations can be applied to them.
|
||||
|
||||
This will cause an error:
|
||||
|
||||
```compile_fail,E0077
|
||||
#![feature(repr_simd)]
|
||||
|
||||
#[repr(simd)]
|
||||
struct Bad(String);
|
||||
```
|
||||
|
||||
This will not:
|
||||
|
||||
```
|
||||
#![feature(repr_simd)]
|
||||
|
||||
#[repr(simd)]
|
||||
struct Good(u32, u32, u32);
|
||||
```
|
16
src/librustc_error_codes/error_codes/E0080.md
Normal file
16
src/librustc_error_codes/error_codes/E0080.md
Normal file
@ -0,0 +1,16 @@
|
||||
This error indicates that the compiler was unable to sensibly evaluate a
|
||||
constant expression that had to be evaluated. Attempting to divide by 0
|
||||
or causing integer overflow are two ways to induce this error. For example:
|
||||
|
||||
```compile_fail,E0080
|
||||
enum Enum {
|
||||
X = (1 << 500),
|
||||
Y = (1 / 0)
|
||||
}
|
||||
```
|
||||
|
||||
Ensure that the expressions given can be evaluated as the desired integer type.
|
||||
See the FFI section of the Reference for more information about using a custom
|
||||
integer type:
|
||||
|
||||
https://doc.rust-lang.org/reference.html#ffi-attributes
|
35
src/librustc_error_codes/error_codes/E0081.md
Normal file
35
src/librustc_error_codes/error_codes/E0081.md
Normal file
@ -0,0 +1,35 @@
|
||||
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,
|
||||
making them impossible to tell apart.
|
||||
|
||||
```compile_fail,E0081
|
||||
// Bad.
|
||||
enum Enum {
|
||||
P = 3,
|
||||
X = 3,
|
||||
Y = 5,
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
// Good.
|
||||
enum Enum {
|
||||
P,
|
||||
X = 3,
|
||||
Y = 5,
|
||||
}
|
||||
```
|
||||
|
||||
Note that variants without a manually specified discriminant are numbered from
|
||||
top to bottom starting from 0, so clashes can occur with seemingly unrelated
|
||||
variants.
|
||||
|
||||
```compile_fail,E0081
|
||||
enum Bad {
|
||||
X,
|
||||
Y = 0
|
||||
}
|
||||
```
|
||||
|
||||
Here `X` will have already been specified the discriminant 0 by the time `Y` is
|
||||
encountered, so a conflict occurs.
|
27
src/librustc_error_codes/error_codes/E0084.md
Normal file
27
src/librustc_error_codes/error_codes/E0084.md
Normal file
@ -0,0 +1,27 @@
|
||||
An unsupported representation was attempted on a zero-variant enum.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0084
|
||||
#[repr(i32)]
|
||||
enum NightsWatch {} // error: unsupported representation for zero-variant enum
|
||||
```
|
||||
|
||||
It is impossible to define an integer type to be used to represent zero-variant
|
||||
enum values because there are no zero-variant enum values. There is no way to
|
||||
construct an instance of the following type using only safe code. So you have
|
||||
two solutions. Either you add variants in your enum:
|
||||
|
||||
```
|
||||
#[repr(i32)]
|
||||
enum NightsWatch {
|
||||
JonSnow,
|
||||
Commander,
|
||||
}
|
||||
```
|
||||
|
||||
or you remove the integer represention of your enum:
|
||||
|
||||
```
|
||||
enum NightsWatch {}
|
||||
```
|
15
src/librustc_error_codes/error_codes/E0087.md
Normal file
15
src/librustc_error_codes/error_codes/E0087.md
Normal file
@ -0,0 +1,15 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
Too many type arguments were supplied for a function. For example:
|
||||
|
||||
```compile_fail,E0107
|
||||
fn foo<T>() {}
|
||||
|
||||
fn main() {
|
||||
foo::<f64, bool>(); // error: wrong number of type arguments:
|
||||
// expected 1, found 2
|
||||
}
|
||||
```
|
||||
|
||||
The number of supplied arguments must exactly match the number of defined type
|
||||
parameters.
|
45
src/librustc_error_codes/error_codes/E0088.md
Normal file
45
src/librustc_error_codes/error_codes/E0088.md
Normal file
@ -0,0 +1,45 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
You gave too many lifetime arguments. Erroneous code example:
|
||||
|
||||
```compile_fail,E0107
|
||||
fn f() {}
|
||||
|
||||
fn main() {
|
||||
f::<'static>() // error: wrong number of lifetime arguments:
|
||||
// expected 0, found 1
|
||||
}
|
||||
```
|
||||
|
||||
Please check you give the right number of lifetime arguments. Example:
|
||||
|
||||
```
|
||||
fn f() {}
|
||||
|
||||
fn main() {
|
||||
f() // ok!
|
||||
}
|
||||
```
|
||||
|
||||
It's also important to note that the Rust compiler can generally
|
||||
determine the lifetime by itself. Example:
|
||||
|
||||
```
|
||||
struct Foo {
|
||||
value: String
|
||||
}
|
||||
|
||||
impl Foo {
|
||||
// it can be written like this
|
||||
fn get_value<'a>(&'a self) -> &'a str { &self.value }
|
||||
// but the compiler works fine with this too:
|
||||
fn without_lifetime(&self) -> &str { &self.value }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let f = Foo { value: "hello".to_owned() };
|
||||
|
||||
println!("{}", f.get_value());
|
||||
println!("{}", f.without_lifetime());
|
||||
}
|
||||
```
|
25
src/librustc_error_codes/error_codes/E0089.md
Normal file
25
src/librustc_error_codes/error_codes/E0089.md
Normal file
@ -0,0 +1,25 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
Too few type arguments were supplied for a function. For example:
|
||||
|
||||
```compile_fail,E0107
|
||||
fn foo<T, U>() {}
|
||||
|
||||
fn main() {
|
||||
foo::<f64>(); // error: wrong number of type arguments: expected 2, found 1
|
||||
}
|
||||
```
|
||||
|
||||
Note that if a function takes multiple type arguments but you want the compiler
|
||||
to infer some of them, you can use type placeholders:
|
||||
|
||||
```compile_fail,E0107
|
||||
fn foo<T, U>(x: T) {}
|
||||
|
||||
fn main() {
|
||||
let x: bool = true;
|
||||
foo::<f64>(x); // error: wrong number of type arguments:
|
||||
// expected 2, found 1
|
||||
foo::<_, f64>(x); // same as `foo::<bool, f64>(x)`
|
||||
}
|
||||
```
|
22
src/librustc_error_codes/error_codes/E0090.md
Normal file
22
src/librustc_error_codes/error_codes/E0090.md
Normal file
@ -0,0 +1,22 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
You gave too few lifetime arguments. Example:
|
||||
|
||||
```compile_fail,E0107
|
||||
fn foo<'a: 'b, 'b: 'a>() {}
|
||||
|
||||
fn main() {
|
||||
foo::<'static>(); // error: wrong number of lifetime arguments:
|
||||
// expected 2, found 1
|
||||
}
|
||||
```
|
||||
|
||||
Please check you give the right number of lifetime arguments. Example:
|
||||
|
||||
```
|
||||
fn foo<'a: 'b, 'b: 'a>() {}
|
||||
|
||||
fn main() {
|
||||
foo::<'static, 'static>();
|
||||
}
|
||||
```
|
15
src/librustc_error_codes/error_codes/E0091.md
Normal file
15
src/librustc_error_codes/error_codes/E0091.md
Normal file
@ -0,0 +1,15 @@
|
||||
You gave an unnecessary type or const parameter in a type alias. Erroneous
|
||||
code example:
|
||||
|
||||
```compile_fail,E0091
|
||||
type Foo<T> = u32; // error: type parameter `T` is unused
|
||||
// or:
|
||||
type Foo<A,B> = Box<A>; // error: type parameter `B` is unused
|
||||
```
|
||||
|
||||
Please check you didn't write too many parameters. Example:
|
||||
|
||||
```
|
||||
type Foo = u32; // ok!
|
||||
type Foo2<A> = Box<A>; // ok!
|
||||
```
|
23
src/librustc_error_codes/error_codes/E0092.md
Normal file
23
src/librustc_error_codes/error_codes/E0092.md
Normal file
@ -0,0 +1,23 @@
|
||||
You tried to declare an undefined atomic operation function.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0092
|
||||
#![feature(intrinsics)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
fn atomic_foo(); // error: unrecognized atomic operation
|
||||
// function
|
||||
}
|
||||
```
|
||||
|
||||
Please check you didn't make a mistake in the function's name. All intrinsic
|
||||
functions are defined in librustc_codegen_llvm/intrinsic.rs and in
|
||||
libcore/intrinsics.rs in the Rust source code. Example:
|
||||
|
||||
```
|
||||
#![feature(intrinsics)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
fn atomic_fence(); // ok!
|
||||
}
|
||||
```
|
33
src/librustc_error_codes/error_codes/E0093.md
Normal file
33
src/librustc_error_codes/error_codes/E0093.md
Normal file
@ -0,0 +1,33 @@
|
||||
You declared an unknown intrinsic function. Erroneous code example:
|
||||
|
||||
```compile_fail,E0093
|
||||
#![feature(intrinsics)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
fn foo(); // error: unrecognized intrinsic function: `foo`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Please check you didn't make a mistake in the function's name. All intrinsic
|
||||
functions are defined in librustc_codegen_llvm/intrinsic.rs and in
|
||||
libcore/intrinsics.rs in the Rust source code. Example:
|
||||
|
||||
```
|
||||
#![feature(intrinsics)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
fn atomic_fence(); // ok!
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
atomic_fence();
|
||||
}
|
||||
}
|
||||
```
|
23
src/librustc_error_codes/error_codes/E0094.md
Normal file
23
src/librustc_error_codes/error_codes/E0094.md
Normal file
@ -0,0 +1,23 @@
|
||||
You gave an invalid number of type parameters to an intrinsic function.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0094
|
||||
#![feature(intrinsics)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
fn size_of<T, U>() -> usize; // error: intrinsic has wrong number
|
||||
// of type parameters
|
||||
}
|
||||
```
|
||||
|
||||
Please check that you provided the right number of type parameters
|
||||
and verify with the function declaration in the Rust source code.
|
||||
Example:
|
||||
|
||||
```
|
||||
#![feature(intrinsics)]
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
fn size_of<T>() -> usize; // ok!
|
||||
}
|
||||
```
|
53
src/librustc_error_codes/error_codes/E0106.md
Normal file
53
src/librustc_error_codes/error_codes/E0106.md
Normal file
@ -0,0 +1,53 @@
|
||||
This error indicates that a lifetime is missing from a type. If it is an error
|
||||
inside a function signature, the problem may be with failing to adhere to the
|
||||
lifetime elision rules (see below).
|
||||
|
||||
Here are some simple examples of where you'll run into this error:
|
||||
|
||||
```compile_fail,E0106
|
||||
struct Foo1 { x: &bool }
|
||||
// ^ expected lifetime parameter
|
||||
struct Foo2<'a> { x: &'a bool } // correct
|
||||
|
||||
struct Bar1 { x: Foo2 }
|
||||
// ^^^^ expected lifetime parameter
|
||||
struct Bar2<'a> { x: Foo2<'a> } // correct
|
||||
|
||||
enum Baz1 { A(u8), B(&bool), }
|
||||
// ^ expected lifetime parameter
|
||||
enum Baz2<'a> { A(u8), B(&'a bool), } // correct
|
||||
|
||||
type MyStr1 = &str;
|
||||
// ^ expected lifetime parameter
|
||||
type MyStr2<'a> = &'a str; // correct
|
||||
```
|
||||
|
||||
Lifetime elision is a special, limited kind of inference for lifetimes in
|
||||
function signatures which allows you to leave out lifetimes in certain cases.
|
||||
For more background on lifetime elision see [the book][book-le].
|
||||
|
||||
The lifetime elision rules require that any function signature with an elided
|
||||
output lifetime must either have
|
||||
|
||||
- exactly one input lifetime
|
||||
- or, multiple input lifetimes, but the function must also be a method with a
|
||||
`&self` or `&mut self` receiver
|
||||
|
||||
In the first case, the output lifetime is inferred to be the same as the unique
|
||||
input lifetime. In the second case, the lifetime is instead inferred to be the
|
||||
same as the lifetime on `&self` or `&mut self`.
|
||||
|
||||
Here are some examples of elision errors:
|
||||
|
||||
```compile_fail,E0106
|
||||
// error, no input lifetimes
|
||||
fn foo() -> &str { }
|
||||
|
||||
// error, `x` and `y` have distinct lifetimes inferred
|
||||
fn bar(x: &str, y: &str) -> &str { }
|
||||
|
||||
// error, `y`'s lifetime is inferred to be distinct from `x`'s
|
||||
fn baz<'a>(x: &'a str, y: &str) -> &str { }
|
||||
```
|
||||
|
||||
[book-le]: https://doc.rust-lang.org/book/ch10-03-lifetime-syntax.html#lifetime-elision
|
28
src/librustc_error_codes/error_codes/E0107.md
Normal file
28
src/librustc_error_codes/error_codes/E0107.md
Normal file
@ -0,0 +1,28 @@
|
||||
This error means that an incorrect number of generic arguments were provided:
|
||||
|
||||
```compile_fail,E0107
|
||||
struct Foo<T> { x: T }
|
||||
|
||||
struct Bar { x: Foo } // error: wrong number of type arguments:
|
||||
// expected 1, found 0
|
||||
struct Baz<S, T> { x: Foo<S, T> } // error: wrong number of type arguments:
|
||||
// expected 1, found 2
|
||||
|
||||
fn foo<T, U>(x: T, y: U) {}
|
||||
|
||||
fn main() {
|
||||
let x: bool = true;
|
||||
foo::<bool>(x); // error: wrong number of type arguments:
|
||||
// expected 2, found 1
|
||||
foo::<bool, i32, i32>(x, 2, 4); // error: wrong number of type arguments:
|
||||
// expected 2, found 3
|
||||
}
|
||||
|
||||
fn f() {}
|
||||
|
||||
fn main() {
|
||||
f::<'static>(); // error: wrong number of lifetime arguments:
|
||||
// expected 0, found 1
|
||||
}
|
||||
```
|
||||
|
21
src/librustc_error_codes/error_codes/E0109.md
Normal file
21
src/librustc_error_codes/error_codes/E0109.md
Normal file
@ -0,0 +1,21 @@
|
||||
You tried to provide a generic argument to a type which doesn't need it.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0109
|
||||
type X = u32<i32>; // error: type arguments are not allowed for this type
|
||||
type Y = bool<'static>; // error: lifetime parameters are not allowed on
|
||||
// this type
|
||||
```
|
||||
|
||||
Check that you used the correct argument and that the definition is correct.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
type X = u32; // ok!
|
||||
type Y = bool; // ok!
|
||||
```
|
||||
|
||||
Note that generic arguments for enum variant constructors go after the variant,
|
||||
not after the enum. For example, you would write `Option::None::<u32>`,
|
||||
rather than `Option::<u32>::None`.
|
4
src/librustc_error_codes/error_codes/E0110.md
Normal file
4
src/librustc_error_codes/error_codes/E0110.md
Normal file
@ -0,0 +1,4 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
You tried to provide a lifetime to a type which doesn't need it.
|
||||
See `E0109` for more details.
|
23
src/librustc_error_codes/error_codes/E0116.md
Normal file
23
src/librustc_error_codes/error_codes/E0116.md
Normal file
@ -0,0 +1,23 @@
|
||||
You can only define an inherent implementation for a type in the same crate
|
||||
where the type was defined. For example, an `impl` block as below is not allowed
|
||||
since `Vec` is defined in the standard library:
|
||||
|
||||
```compile_fail,E0116
|
||||
impl Vec<u8> { } // error
|
||||
```
|
||||
|
||||
To fix this problem, you can do either of these things:
|
||||
|
||||
- define a trait that has the desired associated functions/types/constants and
|
||||
implement the trait for the type in question
|
||||
- define a new type wrapping the type and define an implementation on the new
|
||||
type
|
||||
|
||||
Note that using the `type` keyword does not work here because `type` only
|
||||
introduces a type alias:
|
||||
|
||||
```compile_fail,E0116
|
||||
type Bytes = Vec<u8>;
|
||||
|
||||
impl Bytes { } // error, same as above
|
||||
```
|
48
src/librustc_error_codes/error_codes/E0117.md
Normal file
48
src/librustc_error_codes/error_codes/E0117.md
Normal file
@ -0,0 +1,48 @@
|
||||
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:
|
||||
|
||||
```compile_fail,E0117
|
||||
impl Drop for u32 {}
|
||||
```
|
||||
|
||||
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
|
||||
|
||||
impl Drop for Foo { // and you can implement the trait on it!
|
||||
// code of trait implementation here
|
||||
# fn drop(&mut self) { }
|
||||
}
|
||||
|
||||
impl From<Foo> for i32 { // or you use a type from your crate as
|
||||
// a type parameter
|
||||
fn from(i: Foo) -> i32 {
|
||||
0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
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/blob/master/text/1023-rebalancing-coherence.md
|
41
src/librustc_error_codes/error_codes/E0118.md
Normal file
41
src/librustc_error_codes/error_codes/E0118.md
Normal file
@ -0,0 +1,41 @@
|
||||
You're trying to write an inherent implementation for something which isn't a
|
||||
struct nor an enum. Erroneous code example:
|
||||
|
||||
```compile_fail,E0118
|
||||
impl (u8, u8) { // error: no base type found for inherent implementation
|
||||
fn get_state(&self) -> String {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To fix this error, please implement a trait on the type or wrap it in a struct.
|
||||
Example:
|
||||
|
||||
```
|
||||
// we create a trait here
|
||||
trait LiveLongAndProsper {
|
||||
fn get_state(&self) -> String;
|
||||
}
|
||||
|
||||
// and now you can implement it on (u8, u8)
|
||||
impl LiveLongAndProsper for (u8, u8) {
|
||||
fn get_state(&self) -> String {
|
||||
"He's dead, Jim!".to_owned()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, you can create a newtype. A newtype is a wrapping tuple-struct.
|
||||
For example, `NewType` is a newtype over `Foo` in `struct NewType(Foo)`.
|
||||
Example:
|
||||
|
||||
```
|
||||
struct TypeWrapper((u8, u8));
|
||||
|
||||
impl TypeWrapper {
|
||||
fn get_state(&self) -> String {
|
||||
"Fascinating!".to_owned()
|
||||
}
|
||||
}
|
||||
```
|
58
src/librustc_error_codes/error_codes/E0119.md
Normal file
58
src/librustc_error_codes/error_codes/E0119.md
Normal file
@ -0,0 +1,58 @@
|
||||
There are conflicting trait implementations for the same type.
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0119
|
||||
trait MyTrait {
|
||||
fn get(&self) -> usize;
|
||||
}
|
||||
|
||||
impl<T> MyTrait for T {
|
||||
fn get(&self) -> usize { 0 }
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
value: usize
|
||||
}
|
||||
|
||||
impl MyTrait for Foo { // error: conflicting implementations of trait
|
||||
// `MyTrait` for type `Foo`
|
||||
fn get(&self) -> usize { self.value }
|
||||
}
|
||||
```
|
||||
|
||||
When looking for the implementation for the trait, the compiler finds
|
||||
both the `impl<T> 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:
|
||||
|
||||
```
|
||||
trait MyTrait {
|
||||
fn get(&self) -> usize;
|
||||
}
|
||||
|
||||
impl<T> MyTrait for T {
|
||||
fn get(&self) -> usize { 0 }
|
||||
}
|
||||
```
|
||||
|
||||
This makes the trait implemented on all types in the scope. So if you
|
||||
try to implement it on another one after that, the implementations will
|
||||
conflict. Example:
|
||||
|
||||
```
|
||||
trait MyTrait {
|
||||
fn get(&self) -> usize;
|
||||
}
|
||||
|
||||
impl<T> MyTrait for T {
|
||||
fn get(&self) -> usize { 0 }
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
|
||||
fn main() {
|
||||
let f = Foo;
|
||||
|
||||
f.get(); // the trait is implemented so we can use it
|
||||
}
|
||||
```
|
36
src/librustc_error_codes/error_codes/E0120.md
Normal file
36
src/librustc_error_codes/error_codes/E0120.md
Normal file
@ -0,0 +1,36 @@
|
||||
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:
|
||||
|
||||
```compile_fail,E0120
|
||||
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<T: MyTrait> { foo: T }
|
||||
|
||||
impl <T: MyTrait> Drop for MyWrapper<T> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Alternatively, wrapping trait objects requires something like the following:
|
||||
|
||||
```
|
||||
trait MyTrait {}
|
||||
|
||||
//or Box<MyTrait>, if you wanted an owned trait object
|
||||
struct MyWrapper<'a> { foo: &'a MyTrait }
|
||||
|
||||
impl <'a> Drop for MyWrapper<'a> {
|
||||
fn drop(&mut self) {}
|
||||
}
|
||||
```
|
10
src/librustc_error_codes/error_codes/E0121.md
Normal file
10
src/librustc_error_codes/error_codes/E0121.md
Normal file
@ -0,0 +1,10 @@
|
||||
In order to be consistent with Rust's lack of global type inference,
|
||||
type and const placeholders are disallowed by design in item signatures.
|
||||
|
||||
Examples of this error include:
|
||||
|
||||
```compile_fail,E0121
|
||||
fn foo() -> _ { 5 } // error, explicitly write out the return type instead
|
||||
|
||||
static BAR: _ = "test"; // error, explicitly write out the type instead
|
||||
```
|
18
src/librustc_error_codes/error_codes/E0124.md
Normal file
18
src/librustc_error_codes/error_codes/E0124.md
Normal file
@ -0,0 +1,18 @@
|
||||
You declared two fields of a struct with the same name. Erroneous code
|
||||
example:
|
||||
|
||||
```compile_fail,E0124
|
||||
struct Foo {
|
||||
field1: i32,
|
||||
field1: i32, // error: field is already declared
|
||||
}
|
||||
```
|
||||
|
||||
Please verify that the field names have been correctly spelled. Example:
|
||||
|
||||
```
|
||||
struct Foo {
|
||||
field1: i32,
|
||||
field2: i32, // ok!
|
||||
}
|
||||
```
|
24
src/librustc_error_codes/error_codes/E0128.md
Normal file
24
src/librustc_error_codes/error_codes/E0128.md
Normal file
@ -0,0 +1,24 @@
|
||||
Type parameter defaults can only use parameters that occur before them.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0128
|
||||
struct Foo<T = U, U = ()> {
|
||||
field1: T,
|
||||
field2: U,
|
||||
}
|
||||
// error: type parameters with a default cannot use forward declared
|
||||
// identifiers
|
||||
```
|
||||
|
||||
Since type parameters are evaluated in-order, you may be able to fix this issue
|
||||
by doing:
|
||||
|
||||
```
|
||||
struct Foo<U = (), T = U> {
|
||||
field1: T,
|
||||
field2: U,
|
||||
}
|
||||
```
|
||||
|
||||
Please also verify that this wasn't because of a name-clash and rename the type
|
||||
parameter if so.
|
31
src/librustc_error_codes/error_codes/E0130.md
Normal file
31
src/librustc_error_codes/error_codes/E0130.md
Normal file
@ -0,0 +1,31 @@
|
||||
You declared a pattern as an argument in a foreign function declaration.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail
|
||||
extern {
|
||||
fn foo((a, b): (u32, u32)); // error: patterns aren't allowed in foreign
|
||||
// function declarations
|
||||
}
|
||||
```
|
||||
|
||||
Please replace the pattern argument with a regular one. Example:
|
||||
|
||||
```
|
||||
struct SomeStruct {
|
||||
a: u32,
|
||||
b: u32,
|
||||
}
|
||||
|
||||
extern {
|
||||
fn foo(s: SomeStruct); // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Or:
|
||||
|
||||
```
|
||||
extern {
|
||||
fn foo(a: (u32, u32)); // ok!
|
||||
}
|
||||
```
|
8
src/librustc_error_codes/error_codes/E0131.md
Normal file
8
src/librustc_error_codes/error_codes/E0131.md
Normal file
@ -0,0 +1,8 @@
|
||||
It is not possible to define `main` with generic parameters.
|
||||
When `main` is present, it must take no arguments and return `()`.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0131
|
||||
fn main<T>() { // error: main function is not allowed to have generic parameters
|
||||
}
|
||||
```
|
32
src/librustc_error_codes/error_codes/E0132.md
Normal file
32
src/librustc_error_codes/error_codes/E0132.md
Normal file
@ -0,0 +1,32 @@
|
||||
A function with the `start` attribute was declared with type parameters.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0132
|
||||
#![feature(start)]
|
||||
|
||||
#[start]
|
||||
fn f<T>() {}
|
||||
```
|
||||
|
||||
It is not possible to declare type parameters on a function that has the `start`
|
||||
attribute. Such a function must have the following type signature (for more
|
||||
information, view [the unstable book][1]):
|
||||
|
||||
[1]: https://doc.rust-lang.org/unstable-book/language-features/lang-items.html#writing-an-executable-without-stdlib
|
||||
|
||||
```
|
||||
# let _:
|
||||
fn(isize, *const *const u8) -> isize;
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
#![feature(start)]
|
||||
|
||||
#[start]
|
||||
fn my_start(argc: isize, argv: *const *const u8) -> isize {
|
||||
0
|
||||
}
|
||||
```
|
31
src/librustc_error_codes/error_codes/E0133.md
Normal file
31
src/librustc_error_codes/error_codes/E0133.md
Normal file
@ -0,0 +1,31 @@
|
||||
Unsafe code was used outside of an unsafe function or block.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0133
|
||||
unsafe fn f() { return; } // This is the unsafe code
|
||||
|
||||
fn main() {
|
||||
f(); // error: call to unsafe function requires unsafe function or block
|
||||
}
|
||||
```
|
||||
|
||||
Using unsafe functionality is potentially dangerous and disallowed by safety
|
||||
checks. Examples:
|
||||
|
||||
* Dereferencing raw pointers
|
||||
* Calling functions via FFI
|
||||
* Calling functions marked unsafe
|
||||
|
||||
These safety checks can be relaxed for a section of the code by wrapping the
|
||||
unsafe instructions with an `unsafe` block. For instance:
|
||||
|
||||
```
|
||||
unsafe fn f() { return; }
|
||||
|
||||
fn main() {
|
||||
unsafe { f(); } // ok!
|
||||
}
|
||||
```
|
||||
|
||||
See also https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html
|
16
src/librustc_error_codes/error_codes/E0136.md
Normal file
16
src/librustc_error_codes/error_codes/E0136.md
Normal file
@ -0,0 +1,16 @@
|
||||
A binary can only have one entry point, and by default that entry point is the
|
||||
function `main()`. If there are multiple such functions, please rename one.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0136
|
||||
fn main() {
|
||||
// ...
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
fn main() { // error!
|
||||
// ...
|
||||
}
|
||||
```
|
24
src/librustc_error_codes/error_codes/E0137.md
Normal file
24
src/librustc_error_codes/error_codes/E0137.md
Normal file
@ -0,0 +1,24 @@
|
||||
More than one function was declared with the `#[main]` attribute.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0137
|
||||
#![feature(main)]
|
||||
|
||||
#[main]
|
||||
fn foo() {}
|
||||
|
||||
#[main]
|
||||
fn f() {} // error: multiple functions with a `#[main]` attribute
|
||||
```
|
||||
|
||||
This error indicates that the compiler found multiple functions with the
|
||||
`#[main]` attribute. This is an error because there must be a unique entry
|
||||
point into a Rust program. Example:
|
||||
|
||||
```
|
||||
#![feature(main)]
|
||||
|
||||
#[main]
|
||||
fn f() {} // ok!
|
||||
```
|
25
src/librustc_error_codes/error_codes/E0138.md
Normal file
25
src/librustc_error_codes/error_codes/E0138.md
Normal file
@ -0,0 +1,25 @@
|
||||
More than one function was declared with the `#[start]` attribute.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0138
|
||||
#![feature(start)]
|
||||
|
||||
#[start]
|
||||
fn foo(argc: isize, argv: *const *const u8) -> isize {}
|
||||
|
||||
#[start]
|
||||
fn f(argc: isize, argv: *const *const u8) -> isize {}
|
||||
// error: multiple 'start' functions
|
||||
```
|
||||
|
||||
This error indicates that the compiler found multiple functions with the
|
||||
`#[start]` attribute. This is an error because there must be a unique entry
|
||||
point into a Rust program. Example:
|
||||
|
||||
```
|
||||
#![feature(start)]
|
||||
|
||||
#[start]
|
||||
fn foo(argc: isize, argv: *const *const u8) -> isize { 0 } // ok!
|
||||
```
|
84
src/librustc_error_codes/error_codes/E0139.md
Normal file
84
src/librustc_error_codes/error_codes/E0139.md
Normal file
@ -0,0 +1,84 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
There are various restrictions on transmuting between types in Rust; for example
|
||||
types being transmuted must have the same size. To apply all these restrictions,
|
||||
the compiler must know the exact types that may be transmuted. When type
|
||||
parameters are involved, this cannot always be done.
|
||||
|
||||
So, for example, the following is not allowed:
|
||||
|
||||
```
|
||||
use std::mem::transmute;
|
||||
|
||||
struct Foo<T>(Vec<T>);
|
||||
|
||||
fn foo<T>(x: Vec<T>) {
|
||||
// we are transmuting between Vec<T> and Foo<F> here
|
||||
let y: Foo<T> = unsafe { transmute(x) };
|
||||
// do something with y
|
||||
}
|
||||
```
|
||||
|
||||
In this specific case there's a good chance that the transmute is harmless (but
|
||||
this is not guaranteed by Rust). However, when alignment and enum optimizations
|
||||
come into the picture, it's quite likely that the sizes may or may not match
|
||||
with different type parameter substitutions. It's not possible to check this for
|
||||
_all_ possible types, so `transmute()` simply only accepts types without any
|
||||
unsubstituted type parameters.
|
||||
|
||||
If you need this, there's a good chance you're doing something wrong. Keep in
|
||||
mind that Rust doesn't guarantee much about the layout of different structs
|
||||
(even two structs with identical declarations may have different layouts). If
|
||||
there is a solution that avoids the transmute entirely, try it instead.
|
||||
|
||||
If it's possible, hand-monomorphize the code by writing the function for each
|
||||
possible type substitution. It's possible to use traits to do this cleanly,
|
||||
for example:
|
||||
|
||||
```
|
||||
use std::mem::transmute;
|
||||
|
||||
struct Foo<T>(Vec<T>);
|
||||
|
||||
trait MyTransmutableType: Sized {
|
||||
fn transmute(_: Vec<Self>) -> Foo<Self>;
|
||||
}
|
||||
|
||||
impl MyTransmutableType for u8 {
|
||||
fn transmute(x: Vec<u8>) -> Foo<u8> {
|
||||
unsafe { transmute(x) }
|
||||
}
|
||||
}
|
||||
|
||||
impl MyTransmutableType for String {
|
||||
fn transmute(x: Vec<String>) -> Foo<String> {
|
||||
unsafe { transmute(x) }
|
||||
}
|
||||
}
|
||||
|
||||
// ... more impls for the types you intend to transmute
|
||||
|
||||
fn foo<T: MyTransmutableType>(x: Vec<T>) {
|
||||
let y: Foo<T> = <T as MyTransmutableType>::transmute(x);
|
||||
// do something with y
|
||||
}
|
||||
```
|
||||
|
||||
Each impl will be checked for a size match in the transmute as usual, and since
|
||||
there are no unbound type parameters involved, this should compile unless there
|
||||
is a size mismatch in one of the impls.
|
||||
|
||||
It is also possible to manually transmute:
|
||||
|
||||
```
|
||||
# use std::ptr;
|
||||
# let v = Some("value");
|
||||
# type SomeType = &'static [u8];
|
||||
unsafe {
|
||||
ptr::read(&v as *const _ as *const SomeType) // `v` transmuted to `SomeType`
|
||||
}
|
||||
# ;
|
||||
```
|
||||
|
||||
Note that this does not move `v` (unlike `transmute`), and may need a
|
||||
call to `mem::forget(v)` in case you want to avoid destructors being called.
|
25
src/librustc_error_codes/error_codes/E0152.md
Normal file
25
src/librustc_error_codes/error_codes/E0152.md
Normal file
@ -0,0 +1,25 @@
|
||||
A lang item was redefined.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0152
|
||||
#![feature(lang_items)]
|
||||
|
||||
#[lang = "arc"]
|
||||
struct Foo; // error: duplicate lang item found: `arc`
|
||||
```
|
||||
|
||||
Lang items are already implemented in the standard library. Unless you are
|
||||
writing a free-standing application (e.g., a kernel), you do not need to provide
|
||||
them yourself.
|
||||
|
||||
You can build a free-standing crate by adding `#![no_std]` to the crate
|
||||
attributes:
|
||||
|
||||
```ignore (only-for-syntax-highlight)
|
||||
#![no_std]
|
||||
```
|
||||
|
||||
See also the [unstable book][1].
|
||||
|
||||
[1]: https://doc.rust-lang.org/unstable-book/language-features/lang-items.html#writing-an-executable-without-stdlib
|
33
src/librustc_error_codes/error_codes/E0154.md
Normal file
33
src/librustc_error_codes/error_codes/E0154.md
Normal file
@ -0,0 +1,33 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
Imports (`use` statements) are not allowed after non-item statements, such as
|
||||
variable declarations and expression statements.
|
||||
|
||||
Here is an example that demonstrates the error:
|
||||
|
||||
```
|
||||
fn f() {
|
||||
// Variable declaration before import
|
||||
let x = 0;
|
||||
use std::io::Read;
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The solution is to declare the imports at the top of the block, function, or
|
||||
file.
|
||||
|
||||
Here is the previous example again, with the correct order:
|
||||
|
||||
```
|
||||
fn f() {
|
||||
use std::io::Read;
|
||||
let x = 0;
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
See the Declaration Statements section of the reference for more information
|
||||
about what constitutes an Item declaration and what does not:
|
||||
|
||||
https://doc.rust-lang.org/reference.html#statements
|
38
src/librustc_error_codes/error_codes/E0158.md
Normal file
38
src/librustc_error_codes/error_codes/E0158.md
Normal file
@ -0,0 +1,38 @@
|
||||
An associated const has been referenced in a pattern.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0158
|
||||
enum EFoo { A, B, C, D }
|
||||
|
||||
trait Foo {
|
||||
const X: EFoo;
|
||||
}
|
||||
|
||||
fn test<A: Foo>(arg: EFoo) {
|
||||
match arg {
|
||||
A::X => { // error!
|
||||
println!("A::X");
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`const` and `static` mean different things. A `const` is a compile-time
|
||||
constant, an alias for a literal value. This property means you can match it
|
||||
directly within a pattern.
|
||||
|
||||
The `static` keyword, on the other hand, guarantees a fixed location in memory.
|
||||
This does not always mean that the value is constant. For example, a global
|
||||
mutex can be declared `static` as well.
|
||||
|
||||
If you want to match against a `static`, consider using a guard instead:
|
||||
|
||||
```
|
||||
static FORTY_TWO: i32 = 42;
|
||||
|
||||
match Some(42) {
|
||||
Some(x) if x == FORTY_TWO => {}
|
||||
_ => {}
|
||||
}
|
||||
```
|
30
src/librustc_error_codes/error_codes/E0161.md
Normal file
30
src/librustc_error_codes/error_codes/E0161.md
Normal file
@ -0,0 +1,30 @@
|
||||
A value was moved. However, its size was not known at compile time, and only
|
||||
values of a known size can be moved.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0161
|
||||
#![feature(box_syntax)]
|
||||
|
||||
fn main() {
|
||||
let array: &[isize] = &[1, 2, 3];
|
||||
let _x: Box<[isize]> = box *array;
|
||||
// error: cannot move a value of type [isize]: the size of [isize] cannot
|
||||
// be statically determined
|
||||
}
|
||||
```
|
||||
|
||||
In Rust, you can only move a value when its size is known at compile time.
|
||||
|
||||
To work around this restriction, consider "hiding" the value behind a reference:
|
||||
either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move
|
||||
it around as usual. Example:
|
||||
|
||||
```
|
||||
#![feature(box_syntax)]
|
||||
|
||||
fn main() {
|
||||
let array: &[isize] = &[1, 2, 3];
|
||||
let _x: Box<&[isize]> = box array; // ok!
|
||||
}
|
||||
```
|
26
src/librustc_error_codes/error_codes/E0162.md
Normal file
26
src/librustc_error_codes/error_codes/E0162.md
Normal file
@ -0,0 +1,26 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
An if-let pattern attempts to match the pattern, and enters the body if the
|
||||
match was successful. If the match is irrefutable (when it cannot fail to
|
||||
match), use a regular `let`-binding instead. For instance:
|
||||
|
||||
```
|
||||
struct Irrefutable(i32);
|
||||
let irr = Irrefutable(0);
|
||||
|
||||
// This fails to compile because the match is irrefutable.
|
||||
if let Irrefutable(x) = irr {
|
||||
// This body will always be executed.
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Try this instead:
|
||||
|
||||
```
|
||||
struct Irrefutable(i32);
|
||||
let irr = Irrefutable(0);
|
||||
|
||||
let Irrefutable(x) = irr;
|
||||
println!("{}", x);
|
||||
```
|
24
src/librustc_error_codes/error_codes/E0164.md
Normal file
24
src/librustc_error_codes/error_codes/E0164.md
Normal file
@ -0,0 +1,24 @@
|
||||
This error means that an attempt was made to match a struct type enum
|
||||
variant as a non-struct type:
|
||||
|
||||
```compile_fail,E0164
|
||||
enum Foo { B { i: u32 } }
|
||||
|
||||
fn bar(foo: Foo) -> u32 {
|
||||
match foo {
|
||||
Foo::B(i) => i, // error E0164
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Try using `{}` instead:
|
||||
|
||||
```
|
||||
enum Foo { B { i: u32 } }
|
||||
|
||||
fn bar(foo: Foo) -> u32 {
|
||||
match foo {
|
||||
Foo::B{i} => i,
|
||||
}
|
||||
}
|
||||
```
|
27
src/librustc_error_codes/error_codes/E0165.md
Normal file
27
src/librustc_error_codes/error_codes/E0165.md
Normal file
@ -0,0 +1,27 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
A while-let pattern attempts to match the pattern, and enters the body if the
|
||||
match was successful. If the match is irrefutable (when it cannot fail to
|
||||
match), use a regular `let`-binding inside a `loop` instead. For instance:
|
||||
|
||||
```no_run
|
||||
struct Irrefutable(i32);
|
||||
let irr = Irrefutable(0);
|
||||
|
||||
// This fails to compile because the match is irrefutable.
|
||||
while let Irrefutable(x) = irr {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Try this instead:
|
||||
|
||||
```no_run
|
||||
struct Irrefutable(i32);
|
||||
let irr = Irrefutable(0);
|
||||
|
||||
loop {
|
||||
let Irrefutable(x) = irr;
|
||||
// ...
|
||||
}
|
||||
```
|
46
src/librustc_error_codes/error_codes/E0170.md
Normal file
46
src/librustc_error_codes/error_codes/E0170.md
Normal file
@ -0,0 +1,46 @@
|
||||
Enum variants are qualified by default. For example, given this type:
|
||||
|
||||
```
|
||||
enum Method {
|
||||
GET,
|
||||
POST,
|
||||
}
|
||||
```
|
||||
|
||||
You would match it using:
|
||||
|
||||
```
|
||||
enum Method {
|
||||
GET,
|
||||
POST,
|
||||
}
|
||||
|
||||
let m = Method::GET;
|
||||
|
||||
match m {
|
||||
Method::GET => {},
|
||||
Method::POST => {},
|
||||
}
|
||||
```
|
||||
|
||||
If you don't qualify the names, the code will bind new variables named "GET" and
|
||||
"POST" instead. This behavior is likely not what you want, so `rustc` warns when
|
||||
that happens.
|
||||
|
||||
Qualified names are good practice, and most code works well with them. But if
|
||||
you prefer them unqualified, you can import the variants into scope:
|
||||
|
||||
```
|
||||
use Method::*;
|
||||
enum Method { GET, POST }
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
If you want others to be able to import variants from your module directly, use
|
||||
`pub use`:
|
||||
|
||||
```
|
||||
pub use Method::*;
|
||||
pub enum Method { GET, POST }
|
||||
# fn main() {}
|
||||
```
|
19
src/librustc_error_codes/error_codes/E0178.md
Normal file
19
src/librustc_error_codes/error_codes/E0178.md
Normal file
@ -0,0 +1,19 @@
|
||||
In types, the `+` type operator has low precedence, so it is often necessary
|
||||
to use parentheses.
|
||||
|
||||
For example:
|
||||
|
||||
```compile_fail,E0178
|
||||
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
|
6
src/librustc_error_codes/error_codes/E0184.md
Normal file
6
src/librustc_error_codes/error_codes/E0184.md
Normal file
@ -0,0 +1,6 @@
|
||||
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
|
||||
incorrect and can lead to memory unsafety (see [issue #20126][iss20126]), so
|
||||
it has been disabled for now.
|
||||
|
||||
[iss20126]: https://github.com/rust-lang/rust/issues/20126
|
19
src/librustc_error_codes/error_codes/E0185.md
Normal file
19
src/librustc_error_codes/error_codes/E0185.md
Normal file
@ -0,0 +1,19 @@
|
||||
An associated function for a trait was defined to be static, but an
|
||||
implementation of the trait declared the same function to be a method (i.e., to
|
||||
take a `self` parameter).
|
||||
|
||||
Here's an example of this error:
|
||||
|
||||
```compile_fail,E0185
|
||||
trait Foo {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl Foo for Bar {
|
||||
// error, method `foo` has a `&self` declaration in the impl, but not in
|
||||
// the trait
|
||||
fn foo(&self) {}
|
||||
}
|
||||
```
|
19
src/librustc_error_codes/error_codes/E0186.md
Normal file
19
src/librustc_error_codes/error_codes/E0186.md
Normal file
@ -0,0 +1,19 @@
|
||||
An associated function for a trait was defined to be a method (i.e., to take a
|
||||
`self` parameter), but an implementation of the trait declared the same function
|
||||
to be static.
|
||||
|
||||
Here's an example of this error:
|
||||
|
||||
```compile_fail,E0186
|
||||
trait Foo {
|
||||
fn foo(&self);
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl Foo for Bar {
|
||||
// error, method `foo` has a `&self` declaration in the trait, but not in
|
||||
// the impl
|
||||
fn foo() {}
|
||||
}
|
||||
```
|
22
src/librustc_error_codes/error_codes/E0191.md
Normal file
22
src/librustc_error_codes/error_codes/E0191.md
Normal file
@ -0,0 +1,22 @@
|
||||
Trait objects need to have all associated types specified. Erroneous code
|
||||
example:
|
||||
|
||||
```compile_fail,E0191
|
||||
trait Trait {
|
||||
type Bar;
|
||||
}
|
||||
|
||||
type Foo = Trait; // error: the value of the associated type `Bar` (from
|
||||
// the trait `Trait`) must be specified
|
||||
```
|
||||
|
||||
Please verify you specified all associated types of the trait and that you
|
||||
used the right trait. Example:
|
||||
|
||||
```
|
||||
trait Trait {
|
||||
type Bar;
|
||||
}
|
||||
|
||||
type Foo = Trait<Bar=i32>; // ok!
|
||||
```
|
4
src/librustc_error_codes/error_codes/E0192.md
Normal file
4
src/librustc_error_codes/error_codes/E0192.md
Normal file
@ -0,0 +1,4 @@
|
||||
Negative impls are only allowed for auto traits. For more
|
||||
information see the [opt-in builtin traits RFC][RFC 19].
|
||||
|
||||
[RFC 19]: https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md
|
44
src/librustc_error_codes/error_codes/E0193.md
Normal file
44
src/librustc_error_codes/error_codes/E0193.md
Normal file
@ -0,0 +1,44 @@
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
`where` clauses must use generic type parameters: it does not make sense to use
|
||||
them otherwise. An example causing this error:
|
||||
|
||||
```
|
||||
trait Foo {
|
||||
fn bar(&self);
|
||||
}
|
||||
|
||||
#[derive(Copy,Clone)]
|
||||
struct Wrapper<T> {
|
||||
Wrapped: T
|
||||
}
|
||||
|
||||
impl Foo for Wrapper<u32> where Wrapper<u32>: Clone {
|
||||
fn bar(&self) { }
|
||||
}
|
||||
```
|
||||
|
||||
This use of a `where` clause is strange - a more common usage would look
|
||||
something like the following:
|
||||
|
||||
```
|
||||
trait Foo {
|
||||
fn bar(&self);
|
||||
}
|
||||
|
||||
#[derive(Copy,Clone)]
|
||||
struct Wrapper<T> {
|
||||
Wrapped: T
|
||||
}
|
||||
impl <T> Foo for Wrapper<T> where Wrapper<T>: Clone {
|
||||
fn bar(&self) { }
|
||||
}
|
||||
```
|
||||
|
||||
Here, we're saying that the implementation exists on Wrapper only when the
|
||||
wrapped type `T` implements `Clone`. The `where` clause is important because
|
||||
some types will not implement `Clone`, and thus will not get this method.
|
||||
|
||||
In our erroneous example, however, we're referencing a single concrete type.
|
||||
Since we know for certain that `Wrapper<u32>` implements `Clone`, there's no
|
||||
reason to also specify it in a `where` clause.
|
34
src/librustc_error_codes/error_codes/E0195.md
Normal file
34
src/librustc_error_codes/error_codes/E0195.md
Normal file
@ -0,0 +1,34 @@
|
||||
Your method's lifetime parameters do not match the trait declaration.
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0195
|
||||
trait Trait {
|
||||
fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Trait for Foo {
|
||||
fn bar<'a,'b>(x: &'a str, y: &'b str) {
|
||||
// error: lifetime parameters or bounds on method `bar`
|
||||
// do not match the trait declaration
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
```
|
||||
trait Trait {
|
||||
fn t<'a,'b:'a>(x: &'a str, y: &'b str);
|
||||
}
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Trait for Foo {
|
||||
fn t<'a,'b:'a>(x: &'a str, y: &'b str) { // ok!
|
||||
}
|
||||
}
|
||||
```
|
13
src/librustc_error_codes/error_codes/E0197.md
Normal file
13
src/librustc_error_codes/error_codes/E0197.md
Normal file
@ -0,0 +1,13 @@
|
||||
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 { }
|
||||
```
|
27
src/librustc_error_codes/error_codes/E0198.md
Normal file
27
src/librustc_error_codes/error_codes/E0198.md
Normal file
@ -0,0 +1,27 @@
|
||||
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.
|
||||
|
||||
```compile_fail
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
// unsafe is unnecessary
|
||||
unsafe impl !Clone for Foo { }
|
||||
```
|
||||
|
||||
This will compile:
|
||||
|
||||
```ignore (ignore auto_trait future compatibility warning)
|
||||
#![feature(optin_builtin_traits)]
|
||||
|
||||
struct Foo;
|
||||
|
||||
auto trait Enterprise {}
|
||||
|
||||
impl !Enterprise for Foo { }
|
||||
```
|
||||
|
||||
Please note that negative impls are only allowed for auto traits.
|
14
src/librustc_error_codes/error_codes/E0199.md
Normal file
14
src/librustc_error_codes/error_codes/E0199.md
Normal file
@ -0,0 +1,14 @@
|
||||
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.
|
||||
|
||||
```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 { }
|
||||
```
|
14
src/librustc_error_codes/error_codes/E0200.md
Normal file
14
src/librustc_error_codes/error_codes/E0200.md
Normal file
@ -0,0 +1,14 @@
|
||||
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 { }
|
||||
```
|
45
src/librustc_error_codes/error_codes/E0201.md
Normal file
45
src/librustc_error_codes/error_codes/E0201.md
Normal file
@ -0,0 +1,45 @@
|
||||
It is an error to define two associated items (like methods, associated types,
|
||||
associated functions, etc.) with the same identifier.
|
||||
|
||||
For example:
|
||||
|
||||
```compile_fail,E0201
|
||||
struct Foo(u8);
|
||||
|
||||
impl Foo {
|
||||
fn bar(&self) -> bool { self.0 > 5 }
|
||||
fn bar() {} // error: duplicate associated function
|
||||
}
|
||||
|
||||
trait Baz {
|
||||
type Quux;
|
||||
fn baz(&self) -> bool;
|
||||
}
|
||||
|
||||
impl Baz for Foo {
|
||||
type Quux = u32;
|
||||
|
||||
fn baz(&self) -> bool { true }
|
||||
|
||||
// error: duplicate method
|
||||
fn baz(&self) -> bool { self.0 > 5 }
|
||||
|
||||
// error: duplicate associated type
|
||||
type Quux = u32;
|
||||
}
|
||||
```
|
||||
|
||||
Note, however, that items with the same name are allowed for inherent `impl`
|
||||
blocks that don't overlap:
|
||||
|
||||
```
|
||||
struct Foo<T>(T);
|
||||
|
||||
impl Foo<u8> {
|
||||
fn bar(&self) -> bool { self.0 > 5 }
|
||||
}
|
||||
|
||||
impl Foo<bool> {
|
||||
fn bar(&self) -> bool { self.0 }
|
||||
}
|
||||
```
|
5
src/librustc_error_codes/error_codes/E0202.md
Normal file
5
src/librustc_error_codes/error_codes/E0202.md
Normal file
@ -0,0 +1,5 @@
|
||||
Inherent associated types were part of [RFC 195] but are not yet implemented.
|
||||
See [the tracking issue][iss8995] for the status of this implementation.
|
||||
|
||||
[RFC 195]: https://github.com/rust-lang/rfcs/blob/master/text/0195-associated-items.md
|
||||
[iss8995]: https://github.com/rust-lang/rust/issues/8995
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user