Put each error code long explanation into their own markdown file

This commit is contained in:
Guillaume Gomez 2019-11-12 11:45:21 +01:00
parent 3302190b67
commit cd274632f8
397 changed files with 12609 additions and 13403 deletions

File diff suppressed because it is too large Load Diff

View 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.

View 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
}
}
```

View 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 => {}
_ => {}
}
```

View 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
}
```

View 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.

View 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!()
}
```

View 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;
```

View 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;
```

View 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
```

View 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

View 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`.

View 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!
}
```

View 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.

View 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!
}
```

View 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 } => {}
}
```

View 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, .. } => {}
}
```

View 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" => {}
_ => {}
}
```

View 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 => {}
}
```

View 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

View 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"
}
```

View 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>`.

View 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
}
```

View 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); }
```

View 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, ...);
}
```

View 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!
}
```

View 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 }
}
```

View 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 }
}
```

View 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) { }
}
```

View 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;
```

View 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.

View 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
}
```

View 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.

View 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);
}
# }
```

View 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).

View 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!
}
```

View 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!
}
```

View 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 !
}
```

View 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.

View 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 !
}
```

View 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;
}
```

View 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.

View 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 }`.

View 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);
```

View 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);
```

View 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);
```

View 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);
```

View 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

View 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.

View 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 {}
```

View 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.

View 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());
}
```

View 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)`
}
```

View 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>();
}
```

View 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!
```

View 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!
}
```

View 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();
}
}
```

View 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!
}
```

View 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

View 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
}
```

View 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`.

View 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.

View 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
```

View 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

View 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()
}
}
```

View 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
}
```

View 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) {}
}
```

View 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
```

View 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!
}
```

View 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.

View 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!
}
```

View 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
}
```

View 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
}
```

View 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

View 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!
// ...
}
```

View 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!
```

View 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!
```

View 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.

View 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

View 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

View 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 => {}
_ => {}
}
```

View 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!
}
```

View 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);
```

View 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,
}
}
```

View 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;
// ...
}
```

View 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() {}
```

View 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

View 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

View 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) {}
}
```

View 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() {}
}
```

View 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!
```

View 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

View 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.

View 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!
}
}
```

View 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 { }
```

View 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.

View 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 { }
```

View 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 { }
```

View 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 }
}
```

View 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