2630 lines
60 KiB
Rust
2630 lines
60 KiB
Rust
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
// file at the top-level directory of this distribution and at
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
#![allow(non_snake_case)]
|
|
|
|
register_long_diagnostics! {
|
|
|
|
E0023: r##"
|
|
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:
|
|
|
|
```
|
|
// Correct.
|
|
match x {
|
|
Apple(a, b) => ...
|
|
}
|
|
```
|
|
|
|
Matching with the wrong number of fields has no sensible interpretation:
|
|
|
|
```
|
|
// Incorrect.
|
|
match x {
|
|
Apple(a) => ...,
|
|
Apple(a, b, c) => ...
|
|
}
|
|
```
|
|
|
|
Check how many fields the enum was declared with and ensure that your pattern
|
|
uses the same number.
|
|
"##,
|
|
|
|
E0024: r##"
|
|
This error indicates that a pattern attempted to extract the fields of an enum
|
|
variant with no fields. Here's a tiny example of this error:
|
|
|
|
```
|
|
// This enum has two variants.
|
|
enum Number {
|
|
// This variant has no fields.
|
|
Zero,
|
|
// This variant has one field.
|
|
One(u32)
|
|
}
|
|
|
|
// Assuming x is a Number we can pattern match on its contents.
|
|
match x {
|
|
Zero(inside) => ...,
|
|
One(inside) => ...
|
|
}
|
|
```
|
|
|
|
The pattern match `Zero(inside)` is incorrect because the `Zero` variant
|
|
contains no fields, yet the `inside` name attempts to bind the first field of
|
|
the enum.
|
|
"##,
|
|
|
|
E0025: r##"
|
|
Each field of a struct can only be bound once in a 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 misspelt
|
|
another field name?
|
|
"##,
|
|
|
|
E0026: r##"
|
|
This error indicates that a struct pattern attempted to extract a non-existant
|
|
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:
|
|
match thing {
|
|
Thing { x, z } => ...
|
|
}
|
|
|
|
// To this:
|
|
match thing {
|
|
Thing { x, y: z } => ...
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0027: r##"
|
|
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:
|
|
|
|
```
|
|
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).
|
|
match d {
|
|
Dog { name: n, age: x } => ...
|
|
}
|
|
|
|
// This is also correct (ignore unused fields).
|
|
match d {
|
|
Dog { age: x, .. } => ...
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0029: r##"
|
|
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.
|
|
|
|
```
|
|
// The ordering relation for strings can't 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" => ...
|
|
_ => ...
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0033: r##"
|
|
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 implementors 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.
|
|
|
|
```
|
|
let trait_obj: &SomeTrait = ...;
|
|
|
|
// 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 Object section of the
|
|
Reference:
|
|
|
|
https://doc.rust-lang.org/reference.html#trait-objects
|
|
"##,
|
|
|
|
E0034: r##"
|
|
The compiler doesn't know what method to call because more than one method
|
|
has the same prototype. Example:
|
|
|
|
```
|
|
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()
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0035: r##"
|
|
You tried to give a type parameter where it wasn't needed. Bad example:
|
|
|
|
```
|
|
struct Test;
|
|
|
|
impl Test {
|
|
fn method(&self) {}
|
|
}
|
|
|
|
fn main() {
|
|
let x = Test;
|
|
|
|
x.method::<i32>(); // Error: Test::method doesn't need type parameter!
|
|
}
|
|
```
|
|
|
|
To fix this error, just remove the type parameter:
|
|
|
|
```
|
|
struct Test;
|
|
|
|
impl Test {
|
|
fn method(&self) {}
|
|
}
|
|
|
|
fn main() {
|
|
let x = Test;
|
|
|
|
x.method(); // OK, we're good!
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0036: r##"
|
|
This error occurrs when you pass too many or not enough type parameters to
|
|
a method. Example:
|
|
|
|
```
|
|
struct Test;
|
|
|
|
impl Test {
|
|
fn method<T>(&self, v: &[T]) -> usize {
|
|
v.len()
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let x = Test;
|
|
let v = &[0i32];
|
|
|
|
x.method::<i32, i32>(v); // error: only one type parameter is expected!
|
|
}
|
|
```
|
|
|
|
To fix it, just specify a correct number of type parameters:
|
|
|
|
```
|
|
struct Test;
|
|
|
|
impl Test {
|
|
fn method<T>(&self, v: &[T]) -> usize {
|
|
v.len()
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let x = Test;
|
|
let v = &[0i32];
|
|
|
|
x.method::<i32>(v); // OK, we're good!
|
|
}
|
|
```
|
|
|
|
Please note on the last example that we could have called `method` like this:
|
|
|
|
```
|
|
x.method(v);
|
|
```
|
|
"##,
|
|
|
|
E0040: r##"
|
|
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:
|
|
|
|
```
|
|
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
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0044: r##"
|
|
You can't use type parameters on foreign items. Example of erroneous code:
|
|
|
|
```
|
|
extern { fn some_func<T>(x: T); }
|
|
```
|
|
|
|
To fix this, replace the type parameter with the specializations that you
|
|
need:
|
|
|
|
```
|
|
extern { fn some_func_i32(x: i32); }
|
|
extern { fn some_func_i64(x: i64); }
|
|
```
|
|
"##,
|
|
|
|
E0045: r##"
|
|
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:
|
|
|
|
```
|
|
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, ...);
|
|
// or:
|
|
extern "C" {
|
|
fn foo (x: u8, ...);
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0046: r##"
|
|
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.
|
|
"##,
|
|
|
|
E0049: r##"
|
|
This error indicates that an attempted implementation of a trait method
|
|
has the wrong number of type 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:
|
|
|
|
```
|
|
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 }
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0050: r##"
|
|
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:
|
|
|
|
```
|
|
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 }
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0053: r##"
|
|
The parameters of any trait method must match between a trait implementation
|
|
and the trait definition.
|
|
|
|
Here are a couple examples of this error:
|
|
|
|
```
|
|
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, values differ in mutability
|
|
fn bar(&mut self) { }
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0054: r##"
|
|
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:
|
|
|
|
```
|
|
let x = 5;
|
|
|
|
// Ok
|
|
let x_is_nonzero = x != 0;
|
|
|
|
// Not allowed, won't compile
|
|
let x_is_nonzero = x as bool;
|
|
```
|
|
"##,
|
|
|
|
E0055: r##"
|
|
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:
|
|
|
|
```
|
|
#![recursion_limit="2"]
|
|
|
|
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.
|
|
"##,
|
|
|
|
E0057: r##"
|
|
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:
|
|
|
|
```
|
|
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
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0059: r##"
|
|
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:
|
|
|
|
```
|
|
fn foo<F: Fn<i32>>(f: F) -> F::Output { f(3) }
|
|
```
|
|
|
|
It can be fixed by adjusting the trait bound like this:
|
|
|
|
```
|
|
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.
|
|
"##,
|
|
|
|
E0060: r##"
|
|
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:
|
|
|
|
```
|
|
extern crate libc;
|
|
use libc::{ 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:
|
|
|
|
```
|
|
unsafe {
|
|
use std::ffi::CString;
|
|
|
|
printf(CString::new("test\n").unwrap().as_ptr());
|
|
printf(CString::new("number = %d\n").unwrap().as_ptr(), 3);
|
|
printf(CString::new("%d, %d\n").unwrap().as_ptr(), 10, 5);
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0061: r##"
|
|
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).
|
|
"##,
|
|
|
|
E0062: r##"
|
|
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. Each field should
|
|
be specified exactly one time.
|
|
"##,
|
|
|
|
E0063: r##"
|
|
This error indicates that during an attempt to build a struct or struct-like
|
|
enum variant, one of the fields was not provided. Each field should be
|
|
specified exactly once.
|
|
"##,
|
|
|
|
E0066: r##"
|
|
Box placement expressions (like C++'s "placement new") do not yet support any
|
|
place expression except the exchange heap (i.e. `std::boxed::HEAP`).
|
|
Furthermore, the syntax is changing to use `in` instead of `box`. See [RFC 470]
|
|
and [RFC 809] for more details.
|
|
|
|
[RFC 470]: https://github.com/rust-lang/rfcs/pull/470
|
|
[RFC 809]: https://github.com/rust-lang/rfcs/pull/809
|
|
"##,
|
|
|
|
E0067: r##"
|
|
The left-hand side of a compound assignment expression must be an lvalue
|
|
expression. An lvalue expression represents a memory location and includes
|
|
item paths (ie, namespaced variables), dereferences, indexing expressions,
|
|
and field references.
|
|
|
|
Let's start with some bad examples:
|
|
```
|
|
use std::collections::LinkedList;
|
|
|
|
// Bad: assignment to non-lvalue expression
|
|
LinkedList::new() += 1;
|
|
|
|
// ...
|
|
|
|
fn some_func(i: &mut i32) {
|
|
i += 12; // Error : '+=' operation cannot be applied on a reference !
|
|
}
|
|
|
|
And now some good examples:
|
|
```
|
|
let mut i : i32 = 0;
|
|
|
|
i += 12; // Good !
|
|
|
|
// ...
|
|
|
|
fn some_func(i: &mut i32) {
|
|
*i += 12; // Good !
|
|
}
|
|
|
|
```
|
|
"##,
|
|
|
|
E0069: r##"
|
|
The compiler found a function whose body contains a `return;` statement but
|
|
whose return type is not `()`. An example of this is:
|
|
|
|
```
|
|
// 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.
|
|
"##,
|
|
|
|
E0070: r##"
|
|
The left-hand side of an assignment operator must be an lvalue expression. An
|
|
lvalue 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 here:
|
|
https://doc.rust-lang.org/reference.html#lvalues,-rvalues-and-temporaries
|
|
|
|
Now, we can go further. Here are some bad examples:
|
|
```
|
|
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 lvalue!
|
|
some_other_func() = 4; // error : we can't 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 good 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 !
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0071: r##"
|
|
You tried to use a structure initialization with a non-structure type.
|
|
Example of erroneous code:
|
|
|
|
```
|
|
enum Foo { FirstValue };
|
|
|
|
let u = Foo::FirstValue { value: 0i32 }; // error: Foo::FirstValue
|
|
// isn't a structure!
|
|
// or even simpler, if the structure wasn't defined at all:
|
|
let u = RandomName { random_field: 0i32 }; // error: RandomName
|
|
// isn't a structure!
|
|
```
|
|
|
|
To fix this, please check:
|
|
* Did you spell it right?
|
|
* Did you accidentaly used an enum as a struct?
|
|
* Did you accidentaly make an enum when you intended to use a struct?
|
|
|
|
Here is the previous code with all missing information:
|
|
|
|
```
|
|
struct Inner {
|
|
value: i32
|
|
}
|
|
|
|
enum Foo {
|
|
FirstValue(Inner)
|
|
}
|
|
|
|
fn main() {
|
|
let u = Foo::FirstValue(Inner { value: 0i32 });
|
|
|
|
let t = Inner { value: 0i32 };
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0072: r##"
|
|
When defining a recursive struct or enum, any use of the type being defined
|
|
from inside the definition must occur behind a pointer (like `Box` or `&`).
|
|
This is because structs and enums must have a well-defined size, and without
|
|
the pointer the size of the type would need to be unbounded.
|
|
|
|
Consider the following erroneous definition of a type for a list of bytes:
|
|
|
|
```
|
|
// error, 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.
|
|
"##,
|
|
|
|
E0073: r##"
|
|
You cannot define a struct (or enum) `Foo` that requires an instance of `Foo`
|
|
in order to make a new `Foo` value. This is because there would be no way a
|
|
first instance of `Foo` could be made to initialize another instance!
|
|
|
|
Here's an example of a struct that has this problem:
|
|
|
|
```
|
|
struct Foo { x: Box<Foo> } // error
|
|
```
|
|
|
|
One fix is to use `Option`, like so:
|
|
|
|
```
|
|
struct Foo { x: Option<Box<Foo>> }
|
|
```
|
|
|
|
Now it's possible to create at least one instance of `Foo`: `Foo { x: None }`.
|
|
"##,
|
|
|
|
E0074: r##"
|
|
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.
|
|
|
|
```
|
|
#[simd]
|
|
struct Bad<T>(T, T, T); // This will cause an error
|
|
|
|
#[simd]
|
|
struct Good(u32, u32, u32); // This will not
|
|
```
|
|
"##,
|
|
|
|
E0075: r##"
|
|
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.
|
|
|
|
```
|
|
#[simd]
|
|
struct Bad; // This will cause an error
|
|
|
|
#[simd]
|
|
struct Good(u32); // This will not
|
|
```
|
|
"##,
|
|
|
|
E0076: r##"
|
|
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.
|
|
|
|
```
|
|
#[simd]
|
|
struct Bad(u16, u32, u32); // This will cause an error
|
|
|
|
#[simd]
|
|
struct Good(u32, u32, u32); // This will not
|
|
```
|
|
|
|
"##,
|
|
|
|
E0077: r##"
|
|
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.
|
|
|
|
```
|
|
#[simd]
|
|
struct Bad(String); // This will cause an error
|
|
|
|
#[simd]
|
|
struct Good(u32, u32, u32); // This will not
|
|
```
|
|
"##,
|
|
|
|
E0079: r##"
|
|
Enum variants which contain no data can be given a custom integer
|
|
representation. This error indicates that the value provided is not an integer
|
|
literal and is therefore invalid.
|
|
|
|
For example, in the following code,
|
|
|
|
```
|
|
enum Foo {
|
|
Q = "32"
|
|
}
|
|
```
|
|
|
|
we try to set the representation to a string.
|
|
|
|
There's no general fix for this; if you can work with an integer then just set
|
|
it to one:
|
|
|
|
```
|
|
enum Foo {
|
|
Q = 32
|
|
}
|
|
```
|
|
|
|
however if you actually wanted a mapping between variants and non-integer
|
|
objects, it may be preferable to use a method with a match instead:
|
|
|
|
```
|
|
enum Foo { Q }
|
|
impl Foo {
|
|
fn get_str(&self) -> &'static str {
|
|
match *self {
|
|
Foo::Q => "32",
|
|
}
|
|
}
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0080: r##"
|
|
This error indicates that the compiler was unable to sensibly evaluate an
|
|
integer expression provided as an enum discriminant. Attempting to divide by 0
|
|
or causing integer overflow are two ways to induce this error. For example:
|
|
|
|
```
|
|
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
|
|
"##,
|
|
|
|
E0081: r##"
|
|
Enum discriminants are used to differentiate enum variants stored in memory.
|
|
This error indicates that the same value was used for two or more variants,
|
|
making them impossible to tell apart.
|
|
|
|
```
|
|
// Good.
|
|
enum Enum {
|
|
P,
|
|
X = 3,
|
|
Y = 5
|
|
}
|
|
|
|
// Bad.
|
|
enum Enum {
|
|
P = 3,
|
|
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.
|
|
|
|
```
|
|
enum Bad {
|
|
X,
|
|
Y = 0
|
|
}
|
|
```
|
|
|
|
Here `X` will have already been assigned the discriminant 0 by the time `Y` is
|
|
encountered, so a conflict occurs.
|
|
"##,
|
|
|
|
E0082: r##"
|
|
The default type for enum discriminants is `isize`, but it can be adjusted by
|
|
adding the `repr` attribute to the enum declaration. This error indicates that
|
|
an integer literal given as a discriminant is not a member of the discriminant
|
|
type. For example:
|
|
|
|
```
|
|
#[repr(u8)]
|
|
enum Thing {
|
|
A = 1024,
|
|
B = 5
|
|
}
|
|
```
|
|
|
|
Here, 1024 lies outside the valid range for `u8`, so the discriminant for `A` is
|
|
invalid. You may want to change representation types to fix this, or else change
|
|
invalid discriminant values so that they fit within the existing type.
|
|
|
|
Note also that without a representation manually defined, the compiler will
|
|
optimize by using the smallest integer type possible.
|
|
"##,
|
|
|
|
E0083: r##"
|
|
At present, it's not possible to define a custom representation for an enum with
|
|
a single variant. As a workaround you can add a `Dummy` variant.
|
|
|
|
See: https://github.com/rust-lang/rust/issues/10292
|
|
"##,
|
|
|
|
E0084: r##"
|
|
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:
|
|
|
|
```
|
|
enum Empty {}
|
|
```
|
|
"##,
|
|
|
|
E0087: r##"
|
|
Too many type parameters were supplied for a function. For example:
|
|
|
|
```
|
|
fn foo<T>() {}
|
|
|
|
fn main() {
|
|
foo::<f64, bool>(); // error, expected 1 parameter, found 2 parameters
|
|
}
|
|
```
|
|
|
|
The number of supplied parameters much exactly match the number of defined type
|
|
parameters.
|
|
"##,
|
|
|
|
E0088: r##"
|
|
You gave too many lifetime parameters. Erroneous code example:
|
|
|
|
```
|
|
fn f() {}
|
|
|
|
fn main() {
|
|
f::<'static>() // error: too many lifetime parameters provided
|
|
}
|
|
```
|
|
|
|
Please check you give the right number of lifetime parameters. 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());
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0089: r##"
|
|
Not enough type parameters were supplied for a function. For example:
|
|
|
|
```
|
|
fn foo<T, U>() {}
|
|
|
|
fn main() {
|
|
foo::<f64>(); // error, expected 2 parameters, found 1 parameter
|
|
}
|
|
```
|
|
|
|
Note that if a function takes multiple type parameters but you want the compiler
|
|
to infer some of them, you can use type placeholders:
|
|
|
|
```
|
|
fn foo<T, U>(x: T) {}
|
|
|
|
fn main() {
|
|
let x: bool = true;
|
|
foo::<f64>(x); // error, expected 2 parameters, found 1 parameter
|
|
foo::<_, f64>(x); // same as `foo::<bool, f64>(x)`
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0091: r##"
|
|
You gave an unnecessary type parameter in a type alias. Erroneous code
|
|
example:
|
|
|
|
```
|
|
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 type parameters. Example:
|
|
|
|
```
|
|
type Foo = u32; // ok!
|
|
type Foo<A> = Box<A>; // ok!
|
|
```
|
|
"##,
|
|
|
|
E0092: r##"
|
|
You tried to declare an undefined atomic operation function.
|
|
Erroneous code example:
|
|
|
|
```
|
|
#![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_trans/trans/intrinsic.rs and in
|
|
libcore/intrinsics.rs in the Rust source code. Example:
|
|
|
|
```
|
|
#![feature(intrinsics)]
|
|
|
|
extern "rust-intrinsic" {
|
|
fn atomic_fence(); // ok!
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0093: r##"
|
|
You declared an unknown intrinsic function. Erroneous code example:
|
|
|
|
```
|
|
#![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_trans/trans/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();
|
|
}
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0094: r##"
|
|
You gave an invalid number of type parameters to an intrinsic function.
|
|
Erroneous code example:
|
|
|
|
```
|
|
#![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 lifetime parameters
|
|
and verify with the function declaration in the Rust source code.
|
|
Example:
|
|
|
|
```
|
|
#![feature(intrinsics)]
|
|
|
|
extern "rust-intrinsic" {
|
|
fn size_of<T>() -> usize; // ok!
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0101: r##"
|
|
You hit this error because the compiler the compiler lacks information
|
|
to determine a type for this expression. Erroneous code example:
|
|
|
|
```
|
|
fn main() {
|
|
let x = |_| {}; // error: cannot determine a type for this expression
|
|
}
|
|
```
|
|
|
|
You have two possibilities to solve this situation:
|
|
* Give an explicit definition of the expression
|
|
* Infer the expression
|
|
|
|
Examples:
|
|
|
|
```
|
|
fn main() {
|
|
let x = |_ : u32| {}; // ok!
|
|
// or:
|
|
let x = |_| {};
|
|
x(0u32);
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0102: r##"
|
|
You hit this error because the compiler lacks information to
|
|
determine a type for this variable. Erroneous code example:
|
|
|
|
```
|
|
fn demo(devil: fn () -> !) {
|
|
let x: &_ = devil();
|
|
// error: cannot determine a type for this local variable
|
|
}
|
|
|
|
fn oh_no() -> ! { panic!("the devil is in the details") }
|
|
|
|
fn main() {
|
|
demo(oh_no);
|
|
}
|
|
```
|
|
|
|
To solve this situation, constrain the type of the variable.
|
|
Examples:
|
|
|
|
```
|
|
fn some_func(x: &u32) {
|
|
// some code
|
|
}
|
|
|
|
fn demo(devil: fn () -> !) {
|
|
let x: &u32 = devil();
|
|
// Here we defined the type at the variable creation
|
|
|
|
let x: &_ = devil();
|
|
some_func(x);
|
|
// Here, the type is determined by the function argument type
|
|
}
|
|
|
|
fn oh_no() -> ! { panic!("the devil is in the details") }
|
|
|
|
fn main() {
|
|
demo(oh_no);
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0106: r##"
|
|
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:
|
|
|
|
```
|
|
struct Foo { x: &bool } // error
|
|
struct Foo<'a> { x: &'a bool } // correct
|
|
|
|
enum Bar { A(u8), B(&bool), } // error
|
|
enum Bar<'a> { A(u8), B(&'a bool), } // correct
|
|
|
|
type MyStr = &str; // error
|
|
type MyStr<'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:
|
|
|
|
```
|
|
// 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/nightly/book/lifetimes.html#lifetime-elision
|
|
"##,
|
|
|
|
E0107: r##"
|
|
This error means that an incorrect number of lifetime parameters were provided
|
|
for a type (like a struct or enum) or trait.
|
|
|
|
Some basic examples include:
|
|
|
|
```
|
|
struct Foo<'a>(&'a str);
|
|
enum Bar { A, B, C }
|
|
|
|
struct Baz<'a> {
|
|
foo: Foo, // error: expected 1, found 0
|
|
bar: Bar<'a>, // error: expected 0, found 1
|
|
}
|
|
```
|
|
|
|
Here's an example that is currently an error, but may work in a future version
|
|
of Rust:
|
|
|
|
```
|
|
struct Foo<'a>(&'a str);
|
|
|
|
trait Quux { }
|
|
impl Quux for Foo { } // error: expected 1, found 0
|
|
```
|
|
|
|
Lifetime elision in implementation headers was part of the lifetime elision
|
|
RFC. It is, however, [currently unimplemented][iss15872].
|
|
|
|
[iss15872]: https://github.com/rust-lang/rust/issues/15872
|
|
"##,
|
|
|
|
E0116: r##"
|
|
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:
|
|
|
|
```
|
|
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:
|
|
|
|
```
|
|
type Bytes = Vec<u8>;
|
|
|
|
impl Bytes { ... } // error, same as above
|
|
```
|
|
"##,
|
|
|
|
E0117: r##"
|
|
This error indicates a violation of one of Rust's orphan rules for trait
|
|
implementations. The rule prohibits any implementation of a foreign trait (a
|
|
trait defined in another crate) where
|
|
|
|
- the type that is implementing the trait is foreign
|
|
- all of the parameters being passed to the trait (if there are any) are also
|
|
foreign.
|
|
|
|
Here's one example of this error:
|
|
|
|
```
|
|
impl Drop for u32 {}
|
|
```
|
|
|
|
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
|
|
}
|
|
|
|
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/pull/1023
|
|
"##,
|
|
|
|
E0119: r##"
|
|
There are conflicting trait implementations for the same type.
|
|
Example of erroneous code:
|
|
|
|
```
|
|
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 for trait
|
|
// `MyTrait`
|
|
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:
|
|
|
|
```
|
|
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
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0120: r##"
|
|
An attempt was made to implement Drop on a trait, which is not allowed: only
|
|
structs and enums can implement Drop. An example causing this error:
|
|
|
|
```
|
|
trait MyTrait {}
|
|
|
|
impl Drop for MyTrait {
|
|
fn drop(&mut self) {}
|
|
}
|
|
```
|
|
|
|
A workaround for this problem is to wrap the trait up in a struct, and implement
|
|
Drop on that. An example is shown below:
|
|
|
|
```
|
|
trait MyTrait {}
|
|
struct MyWrapper<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) {}
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0121: r##"
|
|
In order to be consistent with Rust's lack of global type inference, type
|
|
placeholders are disallowed by design in item signatures.
|
|
|
|
Examples of this error include:
|
|
|
|
```
|
|
fn foo() -> _ { 5 } // error, explicitly write out the return type instead
|
|
|
|
static BAR: _ = "test"; // error, explicitly write out the type instead
|
|
```
|
|
"##,
|
|
|
|
E0124: r##"
|
|
You declared two fields of a struct with the same name. Erroneous code
|
|
example:
|
|
|
|
```
|
|
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!
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0128: r##"
|
|
Type parameter defaults can only use parameters that occur before them.
|
|
Erroneous code example:
|
|
|
|
```
|
|
pub struct Foo<T=U, U=()> {
|
|
field1: T,
|
|
filed2: 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:
|
|
|
|
```
|
|
pub struct Foo<U=(), T=U> {
|
|
field1: T,
|
|
filed2: U,
|
|
}
|
|
```
|
|
|
|
Please also verify that this wasn't because of a name-clash and rename the type
|
|
parameter if so.
|
|
"##,
|
|
|
|
E0130: r##"
|
|
You declared a pattern as an argument in a foreign function declaration.
|
|
Erroneous code example:
|
|
|
|
```
|
|
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!
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0131: r##"
|
|
It is not possible to define `main` with type parameters, or even with function
|
|
parameters. When `main` is present, it must take no arguments and return `()`.
|
|
"##,
|
|
|
|
E0132: r##"
|
|
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:
|
|
|
|
```
|
|
fn(isize, *const *const u8) -> isize
|
|
```
|
|
"##,
|
|
|
|
E0159: r##"
|
|
You tried to use a trait as a struct constructor. Erroneous code example:
|
|
|
|
```
|
|
trait TraitNotAStruct {}
|
|
|
|
TraitNotAStruct{ value: 0 }; // error: use of trait `TraitNotAStruct` as a
|
|
// struct constructor
|
|
```
|
|
|
|
Please verify you used the correct type name or please implement the trait
|
|
on a struct and use this struct constructor. Example:
|
|
|
|
```
|
|
trait TraitNotAStruct {}
|
|
|
|
struct Foo {
|
|
value: i32
|
|
}
|
|
|
|
Foo{ value: 0 }; // ok!
|
|
```
|
|
"##,
|
|
|
|
E0166: r##"
|
|
This error means that the compiler found a return expression in a function
|
|
marked as diverging. A function diverges if it has `!` in the place of the
|
|
return type in its signature. For example:
|
|
|
|
```
|
|
fn foo() -> ! { return; } // error
|
|
```
|
|
|
|
For a function that diverges, every control path in the function must never
|
|
return, for example with a `loop` that never breaks or a call to another
|
|
diverging function (such as `panic!()`).
|
|
"##,
|
|
|
|
E0172: r##"
|
|
This error means that an attempt was made to specify the type of a variable with
|
|
a combination of a concrete type and a trait. Consider the following example:
|
|
|
|
```
|
|
fn foo(bar: i32+std::fmt::Display) {}
|
|
```
|
|
|
|
The code is trying to specify that we want to receive a signed 32-bit integer
|
|
which also implements `Display`. This doesn't make sense: when we pass `i32`, a
|
|
concrete type, it implicitly includes all of the traits that it implements.
|
|
This includes `Display`, `Debug`, `Clone`, and a host of others.
|
|
|
|
If `i32` implements the trait we desire, there's no need to specify the trait
|
|
separately. If it does not, then we need to `impl` the trait for `i32` before
|
|
passing it into `foo`. Either way, a fixed definition for `foo` will look like
|
|
the following:
|
|
|
|
```
|
|
fn foo(bar: i32) {}
|
|
```
|
|
|
|
To learn more about traits, take a look at the Book:
|
|
|
|
https://doc.rust-lang.org/book/traits.html
|
|
"##,
|
|
|
|
E0178: r##"
|
|
In types, the `+` type operator has low precedence, so it is often necessary
|
|
to use parentheses.
|
|
|
|
For example:
|
|
|
|
```
|
|
trait Foo {}
|
|
|
|
struct Bar<'a> {
|
|
w: &'a Foo + Copy, // error, use &'a (Foo + Copy)
|
|
x: &'a Foo + 'a, // error, use &'a (Foo + 'a)
|
|
y: &'a mut Foo + 'a, // error, use &'a mut (Foo + 'a)
|
|
z: fn() -> Foo + 'a, // error, use fn() -> (Foo + 'a)
|
|
}
|
|
```
|
|
|
|
More details can be found in [RFC 438].
|
|
|
|
[RFC 438]: https://github.com/rust-lang/rfcs/pull/438
|
|
"##,
|
|
|
|
E0184: r##"
|
|
Explicitly implementing both Drop and Copy for a type is currently disallowed.
|
|
This feature can make some sense in theory, but the current implementation is
|
|
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
|
|
"##,
|
|
|
|
E0185: r##"
|
|
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:
|
|
|
|
```
|
|
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) {}
|
|
}
|
|
"##,
|
|
|
|
E0186: r##"
|
|
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:
|
|
|
|
```
|
|
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() {}
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0191: r##"
|
|
Trait objects need to have all associated types specified. Erroneous code
|
|
example:
|
|
|
|
```
|
|
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!
|
|
```
|
|
"##,
|
|
|
|
E0192: r##"
|
|
Negative impls are only allowed for traits with default impls. For more
|
|
information see the [opt-in builtin traits RFC](https://github.com/rust-lang/
|
|
rfcs/blob/master/text/0019-opt-in-builtin-traits.md).
|
|
"##,
|
|
|
|
E0195: r##"
|
|
Your method's lifetime parameters do not match the trait declaration.
|
|
Erroneous code example:
|
|
|
|
```
|
|
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!
|
|
}
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0197: r##"
|
|
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.
|
|
|
|
```
|
|
struct Foo;
|
|
|
|
// this will cause this error
|
|
unsafe impl Foo { }
|
|
// converting it to this will fix it
|
|
impl Foo { }
|
|
```
|
|
|
|
"##,
|
|
|
|
E0198: r##"
|
|
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.
|
|
|
|
```
|
|
struct Foo;
|
|
|
|
// unsafe is unnecessary
|
|
unsafe impl !Clone for Foo { }
|
|
// this will compile
|
|
impl !Clone for Foo { }
|
|
```
|
|
|
|
"##,
|
|
|
|
E0199: r##"
|
|
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.
|
|
|
|
```
|
|
struct Foo;
|
|
|
|
trait Bar { }
|
|
|
|
// this won't compile because Bar is safe
|
|
unsafe impl Bar for Foo { }
|
|
// this will compile
|
|
impl Bar for Foo { }
|
|
```
|
|
|
|
"##,
|
|
|
|
E0200: r##"
|
|
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.
|
|
|
|
```
|
|
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 { }
|
|
```
|
|
|
|
"##,
|
|
|
|
E0201: r##"
|
|
It is an error to define two associated items (like methods, associated types,
|
|
associated functions, etc.) with the same identifier.
|
|
|
|
For example:
|
|
|
|
```
|
|
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;
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0202: r##"
|
|
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/pull/195
|
|
[iss8995]: https://github.com/rust-lang/rust/issues/8995
|
|
"##,
|
|
|
|
E0204: r##"
|
|
An attempt to implement the `Copy` trait for a struct failed because one of the
|
|
fields does not implement `Copy`. To fix this, you must implement `Copy` for the
|
|
mentioned field. Note that this may not be possible, as in the example of
|
|
|
|
```
|
|
struct Foo {
|
|
foo : Vec<u32>,
|
|
}
|
|
|
|
impl Copy for Foo { }
|
|
```
|
|
|
|
This fails because `Vec<T>` does not implement `Copy` for any `T`.
|
|
|
|
Here's another example that will fail:
|
|
|
|
```
|
|
#[derive(Copy)]
|
|
struct Foo<'a> {
|
|
ty: &'a mut bool,
|
|
}
|
|
```
|
|
|
|
This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this
|
|
differs from the behavior for `&T`, which is always `Copy`).
|
|
"##,
|
|
|
|
E0205: r##"
|
|
An attempt to implement the `Copy` trait for an enum failed because one of the
|
|
variants does not implement `Copy`. To fix this, you must implement `Copy` for
|
|
the mentioned variant. Note that this may not be possible, as in the example of
|
|
|
|
```
|
|
enum Foo {
|
|
Bar(Vec<u32>),
|
|
Baz,
|
|
}
|
|
|
|
impl Copy for Foo { }
|
|
```
|
|
|
|
This fails because `Vec<T>` does not implement `Copy` for any `T`.
|
|
|
|
Here's another example that will fail:
|
|
|
|
```
|
|
#[derive(Copy)]
|
|
enum Foo<'a> {
|
|
Bar(&'a mut bool),
|
|
Baz
|
|
}
|
|
```
|
|
|
|
This fails because `&mut T` is not `Copy`, even when `T` is `Copy` (this
|
|
differs from the behavior for `&T`, which is always `Copy`).
|
|
"##,
|
|
|
|
E0206: r##"
|
|
You can only implement `Copy` for a struct or enum. Both of the following
|
|
examples will fail, because neither `i32` (primitive type) nor `&'static Bar`
|
|
(reference to `Bar`) is a struct or enum:
|
|
|
|
```
|
|
type Foo = i32;
|
|
impl Copy for Foo { } // error
|
|
|
|
#[derive(Copy, Clone)]
|
|
struct Bar;
|
|
impl Copy for &'static Bar { } // error
|
|
```
|
|
"##,
|
|
|
|
E0207: r##"
|
|
You declared an unused type parameter when implementing a trait on an object.
|
|
Erroneous code example:
|
|
|
|
```
|
|
trait MyTrait {
|
|
fn get(&self) -> usize;
|
|
}
|
|
|
|
struct Foo;
|
|
|
|
impl<T> MyTrait for Foo {
|
|
fn get(&self) -> usize {
|
|
0
|
|
}
|
|
}
|
|
```
|
|
|
|
Please check your object definition and remove unused type
|
|
parameter(s). Example:
|
|
|
|
```
|
|
trait MyTrait {
|
|
fn get(&self) -> usize;
|
|
}
|
|
|
|
struct Foo;
|
|
|
|
impl MyTrait for Foo {
|
|
fn get(&self) -> usize {
|
|
0
|
|
}
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0210: r##"
|
|
This error indicates a violation of one of Rust's orphan rules for trait
|
|
implementations. The rule concerns the use of type parameters in an
|
|
implementation of a foreign trait (a trait defined in another crate), and
|
|
states that type parameters must be "covered" by a local type. To understand
|
|
what this means, it is perhaps easiest to consider a few examples.
|
|
|
|
If `ForeignTrait` is a trait defined in some external crate `foo`, then the
|
|
following trait `impl` is an error:
|
|
|
|
```
|
|
extern crate foo;
|
|
use foo::ForeignTrait;
|
|
|
|
impl<T> ForeignTrait for T { ... } // error
|
|
```
|
|
|
|
To work around this, it can be covered with a local type, `MyType`:
|
|
|
|
```
|
|
struct MyType<T>(T);
|
|
impl<T> ForeignTrait for MyType<T> { ... } // Ok
|
|
```
|
|
|
|
For another example of an error, suppose there's another trait defined in `foo`
|
|
named `ForeignTrait2` that takes two type parameters. Then this `impl` results
|
|
in the same rule violation:
|
|
|
|
```
|
|
struct MyType2;
|
|
impl<T> ForeignTrait2<T, MyType<T>> for MyType2 { ... } // error
|
|
```
|
|
|
|
The reason for this is that there are two appearances of type parameter `T` in
|
|
the `impl` header, both as parameters for `ForeignTrait2`. The first appearance
|
|
is uncovered, and so runs afoul of the orphan rule.
|
|
|
|
Consider one more example:
|
|
|
|
```
|
|
impl<T> ForeignTrait2<MyType<T>, T> for MyType2 { ... } // Ok
|
|
```
|
|
|
|
This only differs from the previous `impl` in that the parameters `T` and
|
|
`MyType<T>` for `ForeignTrait2` have been swapped. This example does *not*
|
|
violate the orphan rule; it is permitted.
|
|
|
|
To see why that last example was allowed, you need to understand the general
|
|
rule. Unfortunately this rule is a bit tricky to state. Consider an `impl`:
|
|
|
|
```
|
|
impl<P1, ..., Pm> ForeignTrait<T1, ..., Tn> for T0 { ... }
|
|
```
|
|
|
|
where `P1, ..., Pm` are the type parameters of the `impl` and `T0, ..., Tn`
|
|
are types. One of the types `T0, ..., Tn` must be a local type (this is another
|
|
orphan rule, see the explanation for E0117). Let `i` be the smallest integer
|
|
such that `Ti` is a local type. Then no type parameter can appear in any of the
|
|
`Tj` for `j < i`.
|
|
|
|
For information on the design of the orphan rules, see [RFC 1023].
|
|
|
|
[RFC 1023]: https://github.com/rust-lang/rfcs/pull/1023
|
|
"##,
|
|
|
|
E0211: r##"
|
|
You used an intrinsic function which doesn't correspond to its
|
|
definition. Erroneous code example:
|
|
|
|
```
|
|
#![feature(intrinsics)]
|
|
|
|
extern "rust-intrinsic" {
|
|
fn size_of<T>(); // error: intrinsic has wrong type
|
|
}
|
|
```
|
|
|
|
Please check the function definition. Example:
|
|
|
|
```
|
|
#![feature(intrinsics)]
|
|
|
|
extern "rust-intrinsic" {
|
|
fn size_of<T>() -> usize;
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0220: r##"
|
|
You used an associated type which isn't defined in the trait.
|
|
Erroneous code example:
|
|
|
|
```
|
|
trait Trait {
|
|
type Bar;
|
|
}
|
|
|
|
type Foo = Trait<F=i32>; // error: associated type `F` not found for
|
|
// `Trait`
|
|
```
|
|
|
|
Please verify you used the right trait or you didn't misspell the
|
|
associated type name. Example:
|
|
|
|
```
|
|
trait Trait {
|
|
type Bar;
|
|
}
|
|
|
|
type Foo = Trait<Bar=i32>; // ok!
|
|
```
|
|
"##,
|
|
|
|
E0223: r##"
|
|
An attempt was made to retrieve an associated type, but the type was ambiguous.
|
|
For example:
|
|
|
|
```
|
|
trait MyTrait {type X; }
|
|
|
|
fn main() {
|
|
let foo: MyTrait::X;
|
|
}
|
|
```
|
|
|
|
The problem here is that we're attempting to take the type of X from MyTrait.
|
|
Unfortunately, the type of X is not defined, because it's only made concrete in
|
|
implementations of the trait. A working version of this code might look like:
|
|
|
|
```
|
|
trait MyTrait {type X; }
|
|
struct MyStruct;
|
|
|
|
impl MyTrait for MyStruct {
|
|
type X = u32;
|
|
}
|
|
|
|
fn main() {
|
|
let foo: <MyStruct as MyTrait>::X;
|
|
}
|
|
```
|
|
|
|
This syntax specifies that we want the X type from MyTrait, as made concrete in
|
|
MyStruct. The reason that we cannot simply use `MyStruct::X` is that MyStruct
|
|
might implement two different traits with identically-named associated types.
|
|
This syntax allows disambiguation between the two.
|
|
"##,
|
|
|
|
E0225: r##"
|
|
You attempted to use multiple types as bounds for a closure or trait object.
|
|
Rust does not currently support this. A simple example that causes this error:
|
|
|
|
```
|
|
fn main() {
|
|
let _: Box<std::io::Read+std::io::Write>;
|
|
}
|
|
```
|
|
|
|
Builtin traits are an exception to this rule: it's possible to have bounds of
|
|
one non-builtin type, plus any number of builtin types. For example, the
|
|
following compiles correctly:
|
|
|
|
```
|
|
fn main() {
|
|
let _: Box<std::io::Read+Copy+Sync>;
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0232: r##"
|
|
The attribute must have a value. Erroneous code example:
|
|
|
|
```
|
|
#[rustc_on_unimplemented] // error: this attribute must have a value
|
|
trait Bar {}
|
|
```
|
|
|
|
Please supply the missing value of the attribute. Example:
|
|
|
|
```
|
|
#[rustc_on_unimplemented = "foo"] // ok!
|
|
trait Bar {}
|
|
```
|
|
"##,
|
|
|
|
E0243: r##"
|
|
This error indicates that not enough type parameters were found in a type or
|
|
trait.
|
|
|
|
For example, the `Foo` struct below is defined to be generic in `T`, but the
|
|
type parameter is missing in the definition of `Bar`:
|
|
|
|
```
|
|
struct Foo<T> { x: T }
|
|
|
|
struct Bar { x: Foo }
|
|
```
|
|
"##,
|
|
|
|
E0244: r##"
|
|
This error indicates that too many type parameters were found in a type or
|
|
trait.
|
|
|
|
For example, the `Foo` struct below has no type parameters, but is supplied
|
|
with two in the definition of `Bar`:
|
|
|
|
```
|
|
struct Foo { x: bool }
|
|
|
|
struct Bar<S, T> { x: Foo<S, T> }
|
|
```
|
|
"##,
|
|
|
|
E0249: r##"
|
|
This error indicates a constant expression for the array length was found, but
|
|
it was not an integer (signed or unsigned) expression.
|
|
|
|
Some examples of code that produces this error are:
|
|
|
|
```
|
|
const A: [u32; "hello"] = []; // error
|
|
const B: [u32; true] = []; // error
|
|
const C: [u32; 0.0] = []; // error
|
|
"##,
|
|
|
|
E0250: r##"
|
|
There was an error while evaluating the expression for the length of a fixed-
|
|
size array type.
|
|
|
|
Some examples of this error are:
|
|
|
|
```
|
|
// divide by zero in the length expression
|
|
const A: [u32; 1/0] = [];
|
|
|
|
// Rust currently will not evaluate the function `foo` at compile time
|
|
fn foo() -> usize { 12 }
|
|
const B: [u32; foo()] = [];
|
|
|
|
// it is an error to try to add `u8` and `f64`
|
|
use std::{f64, u8};
|
|
const C: [u32; u8::MAX + f64::EPSILON] = [];
|
|
```
|
|
"##,
|
|
|
|
E0318: r##"
|
|
Default impls for a trait must be located in the same crate where the trait was
|
|
defined. For more information see the [opt-in builtin traits RFC](https://github
|
|
.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md).
|
|
"##,
|
|
|
|
E0322: r##"
|
|
The `Sized` trait is a special trait built-in to the compiler for types with a
|
|
constant size known at compile-time. This trait is automatically implemented
|
|
for types as needed by the compiler, and it is currently disallowed to
|
|
explicitly implement it for a type.
|
|
"##,
|
|
|
|
E0326: r##"
|
|
The types of any associated constants in a trait implementation must match the
|
|
types in the trait definition. This error indicates that there was a mismatch.
|
|
|
|
Here's an example of this error:
|
|
|
|
```
|
|
trait Foo {
|
|
const BAR: bool;
|
|
}
|
|
|
|
struct Bar;
|
|
|
|
impl Foo for Bar {
|
|
const BAR: u32 = 5; // error, expected bool, found u32
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0327: r##"
|
|
You cannot use associated items other than constant items as patterns. This
|
|
includes method items. Example of erroneous code:
|
|
|
|
```
|
|
enum B {}
|
|
|
|
impl B {
|
|
fn bb() -> i32 { 0 }
|
|
}
|
|
|
|
fn main() {
|
|
match 0 {
|
|
B::bb => {} // error: associated items in match patterns must
|
|
// be constants
|
|
}
|
|
}
|
|
```
|
|
|
|
Please check that you're not using a method as a pattern. Example:
|
|
|
|
```
|
|
enum B {
|
|
ba,
|
|
bb
|
|
}
|
|
|
|
fn main() {
|
|
match B::ba {
|
|
B::bb => {} // ok!
|
|
_ => {}
|
|
}
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0368: r##"
|
|
This error indicates that a binary assignment operator like `+=` or `^=` was
|
|
applied to the wrong types. For example:
|
|
|
|
```
|
|
let mut x: u16 = 5;
|
|
x ^= true; // error, `^=` cannot be applied to types `u16` and `bool`
|
|
x += (); // error, `+=` cannot be applied to types `u16` and `()`
|
|
```
|
|
|
|
Another problem you might be facing is this: suppose you've overloaded the `+`
|
|
operator for some type `Foo` by implementing the `std::ops::Add` trait for
|
|
`Foo`, but you find that using `+=` does not work, as in this example:
|
|
|
|
```
|
|
use std::ops::Add;
|
|
|
|
struct Foo(u32);
|
|
|
|
impl Add for Foo {
|
|
type Output = Foo;
|
|
|
|
fn add(self, rhs: Foo) -> Foo {
|
|
Foo(self.0 + rhs.0)
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let mut x: Foo = Foo(5);
|
|
x += Foo(7); // error, `+= cannot be applied to types `Foo` and `Foo`
|
|
}
|
|
```
|
|
|
|
This is because the binary assignment operators currently do not work off of
|
|
traits, so it is not possible to overload them. See [RFC 953] for a proposal
|
|
to change this.
|
|
|
|
[RFC 953]: https://github.com/rust-lang/rfcs/pull/953
|
|
"##,
|
|
|
|
E0371: r##"
|
|
When `Trait2` is a subtrait of `Trait1` (for example, when `Trait2` has a
|
|
definition like `trait Trait2: Trait1 { ... }`), it is not allowed to implement
|
|
`Trait1` for `Trait2`. This is because `Trait2` already implements `Trait1` by
|
|
definition, so it is not useful to do this.
|
|
|
|
Example:
|
|
|
|
```
|
|
trait Foo { fn foo(&self) { } }
|
|
trait Bar: Foo { }
|
|
trait Baz: Bar { }
|
|
|
|
impl Bar for Baz { } // error, `Baz` implements `Bar` by definition
|
|
impl Foo for Baz { } // error, `Baz` implements `Bar` which implements `Foo`
|
|
impl Baz for Baz { } // error, `Baz` (trivially) implements `Baz`
|
|
impl Baz for Bar { } // Note: This is OK
|
|
```
|
|
"##,
|
|
|
|
E0372: r##"
|
|
Trying to implement a trait for a trait object (as in `impl Trait1 for
|
|
Trait2 { ... }`) does not work if the trait is not object-safe. Please see the
|
|
[RFC 255] for more details on object safety rules.
|
|
|
|
[RFC 255]: https://github.com/rust-lang/rfcs/pull/255
|
|
"##,
|
|
|
|
E0379: r##"
|
|
Trait methods cannot be declared `const` by design. For more information, see
|
|
[RFC 911].
|
|
|
|
[RFC 911]: https://github.com/rust-lang/rfcs/pull/911
|
|
"##,
|
|
|
|
E0380: r##"
|
|
Default impls are only allowed for traits with no methods or associated items.
|
|
For more information see the [opt-in builtin traits RFC](https://github.com/rust
|
|
-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md).
|
|
"##,
|
|
|
|
E0391: r##"
|
|
This error indicates that some types or traits depend on each other
|
|
and therefore cannot be constructed.
|
|
|
|
The following example contains a circular dependency between two traits:
|
|
|
|
```
|
|
trait FirstTrait : SecondTrait {
|
|
|
|
}
|
|
|
|
trait SecondTrait : FirstTrait {
|
|
|
|
}
|
|
```
|
|
"##,
|
|
|
|
E0392: r##"
|
|
This error indicates that a type or lifetime parameter has been declared
|
|
but not actually used. Here is an example that demonstrates the error:
|
|
|
|
```
|
|
enum Foo<T> {
|
|
Bar
|
|
}
|
|
```
|
|
|
|
If the type parameter was included by mistake, this error can be fixed
|
|
by simply removing the type parameter, as shown below:
|
|
|
|
```
|
|
enum Foo {
|
|
Bar
|
|
}
|
|
```
|
|
|
|
Alternatively, if the type parameter was intentionally inserted, it must be
|
|
used. A simple fix is shown below:
|
|
|
|
```
|
|
enum Foo<T> {
|
|
Bar(T)
|
|
}
|
|
```
|
|
|
|
This error may also commonly be found when working with unsafe code. For
|
|
example, when using raw pointers one may wish to specify the lifetime for
|
|
which the pointed-at data is valid. An initial attempt (below) causes this
|
|
error:
|
|
|
|
```
|
|
struct Foo<'a, T> {
|
|
x: *const T
|
|
}
|
|
```
|
|
|
|
We want to express the constraint that Foo should not outlive `'a`, because
|
|
the data pointed to by `T` is only valid for that lifetime. The problem is
|
|
that there are no actual uses of `'a`. It's possible to work around this
|
|
by adding a PhantomData type to the struct, using it to tell the compiler
|
|
to act as if the struct contained a borrowed reference `&'a T`:
|
|
|
|
```
|
|
use std::marker::PhantomData;
|
|
|
|
struct Foo<'a, T: 'a> {
|
|
x: *const T,
|
|
phantom: PhantomData<&'a T>
|
|
}
|
|
```
|
|
|
|
PhantomData can also be used to express information about unused type
|
|
parameters. You can read more about it in the API documentation:
|
|
|
|
https://doc.rust-lang.org/std/marker/struct.PhantomData.html
|
|
"##
|
|
|
|
}
|
|
|
|
register_diagnostics! {
|
|
E0068,
|
|
E0085,
|
|
E0086,
|
|
E0090,
|
|
E0103,
|
|
E0104,
|
|
E0118,
|
|
E0122,
|
|
E0123,
|
|
E0127,
|
|
E0129,
|
|
E0141,
|
|
E0163,
|
|
E0164,
|
|
E0167,
|
|
E0168,
|
|
E0173, // manual implementations of unboxed closure traits are experimental
|
|
E0174, // explicit use of unboxed closure methods are experimental
|
|
E0182,
|
|
E0183,
|
|
E0187, // can't infer the kind of the closure
|
|
E0188, // can not cast a immutable reference to a mutable pointer
|
|
E0189, // deprecated: can only cast a boxed pointer to a boxed object
|
|
E0190, // deprecated: can only cast a &-pointer to an &-object
|
|
E0193, // cannot bound type where clause bounds may only be attached to types
|
|
// involving type parameters
|
|
E0194,
|
|
E0196, // cannot determine a type for this closure
|
|
E0203, // type parameter has more than one relaxed default bound,
|
|
// and only one is supported
|
|
E0208,
|
|
E0209, // builtin traits can only be implemented on structs or enums
|
|
E0212, // cannot extract an associated type from a higher-ranked trait bound
|
|
E0213, // associated types are not accepted in this context
|
|
E0214, // parenthesized parameters may only be used with a trait
|
|
// E0215, // angle-bracket notation is not stable with `Fn`
|
|
// E0216, // parenthetical notation is only stable with `Fn`
|
|
E0217, // ambiguous associated type, defined in multiple supertraits
|
|
E0218, // no associated type defined
|
|
E0219, // associated type defined in higher-ranked supertrait
|
|
E0221, // ambiguous associated type in bounds
|
|
// E0222, // Error code E0045 (variadic function must have C calling
|
|
// convention) duplicate
|
|
E0224, // at least one non-builtin train is required for an object type
|
|
E0226, // only a single explicit lifetime bound is permitted
|
|
E0227, // ambiguous lifetime bound, explicit lifetime bound required
|
|
E0228, // explicit lifetime bound required
|
|
E0229, // associated type bindings are not allowed here
|
|
E0230, // there is no type parameter on trait
|
|
E0231, // only named substitution parameters are allowed
|
|
E0233,
|
|
E0234,
|
|
E0235, // structure constructor specifies a structure of type but
|
|
E0236, // no lang item for range syntax
|
|
E0237, // no lang item for range syntax
|
|
E0238, // parenthesized parameters may only be used with a trait
|
|
E0239, // `next` method of `Iterator` trait has unexpected type
|
|
E0240,
|
|
E0241,
|
|
E0242, // internal error looking up a definition
|
|
E0245, // not a trait
|
|
E0246, // invalid recursive type
|
|
E0247, // found module name used as a type
|
|
E0248, // found value name used as a type
|
|
E0319, // trait impls for defaulted traits allowed just for structs/enums
|
|
E0320, // recursive overflow during dropck
|
|
E0321, // extended coherence rules for defaulted traits violated
|
|
E0323, // implemented an associated const when another trait item expected
|
|
E0324, // implemented a method when another trait item expected
|
|
E0325, // implemented an associated type when another trait item expected
|
|
E0328, // cannot implement Unsize explicitly
|
|
E0329, // associated const depends on type parameter or Self.
|
|
E0366, // dropck forbid specialization to concrete type or region
|
|
E0367, // dropck forbid specialization to predicate not in struct/enum
|
|
E0369, // binary operation `<op>` cannot be applied to types
|
|
E0370, // discriminant overflow
|
|
E0374, // the trait `CoerceUnsized` may only be implemented for a coercion
|
|
// between structures with one field being coerced, none found
|
|
E0375, // the trait `CoerceUnsized` may only be implemented for a coercion
|
|
// between structures with one field being coerced, but multiple
|
|
// fields need coercions
|
|
E0376, // the trait `CoerceUnsized` may only be implemented for a coercion
|
|
// between structures
|
|
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
|
|
// between structures with the same definition
|
|
E0390, // only a single inherent implementation marked with
|
|
// `#[lang = \"{}\"]` is allowed for the `{}` primitive
|
|
E0393, // the type parameter `{}` must be explicitly specified in an object
|
|
// type because its default value `{}` references the type `Self`"
|
|
E0399, // trait items need to be implemented because the associated
|
|
// type `{}` was overridden
|
|
E0436 // functional record update requires a struct
|
|
}
|