mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-02 00:07:42 +03:00
Auto merge of #66314 - GuillaumeGomez:move-error-codes, r=Centril
Move error codes Works towards #66210. r? @Centril Oh btw, for the ones interested, I used this python script to get all error codes content sorted into one final file: <details> ```python from os import listdir from os.path import isdir, isfile, join def get_error_codes(error_codes, f_path): with open(f_path) as f: short_mode = False lines = f.read().split("\n") i = 0 while i < len(lines): line = lines[i] if not short_mode and line.startswith("E0") and line.endswith(": r##\""): error = line error += "\n" i += 1 while i < len(lines): line = lines[i] error += line if line.endswith("\"##,"): break error += "\n" i += 1 error_codes["long"].append(error) elif line == ';': short_mode = True elif short_mode is True and len(line) > 0 and line != "}": error_codes["short"].append(line) while i + 1 < len(lines): line = lines[i + 1].strip() if not line.startswith("//"): break parts = line.split("//") if len(parts) < 2: break if parts[1].strip().startswith("E0"): break error_codes["short"][-1] += "\n" error_codes["short"][-1] += lines[i + 1] i += 1 i += 1 def loop_dirs(error_codes, cur_dir): for entry in listdir(cur_dir): f = join(cur_dir, entry) if isfile(f) and entry == "error_codes.rs": get_error_codes(error_codes, f) elif isdir(f) and not entry.startswith("librustc_error_codes"): loop_dirs(error_codes, f) def get_error_code(err): x = err.split(",") if len(x) < 2: return err x = x[0] if x.strip().startswith("//"): x = x.split("//")[1].strip() return x.strip() def write_into_file(error_codes, f_path): with open(f_path, "w") as f: f.write("// Error messages for EXXXX errors. Each message should start and end with a\n") f.write("// new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and\n") f.write("// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.\n\n") f.write("syntax::register_diagnostics! {\n\n") error_codes["long"].sort() for i in error_codes["long"]: f.write(i) f.write("\n\n") f.write(";\n") error_codes["short"] = sorted(error_codes["short"], key=lambda err: get_error_code(err)) for i in error_codes["short"]: f.write(i) f.write("\n") f.write("}\n") error_codes = { "long": [], "short": [] } loop_dirs(error_codes, "src") write_into_file(error_codes, "src/librustc_error_codes/src/error_codes.rs") ``` </details> And to move the error codes into their own files: <details> ```python import os try: os.mkdir("src/librustc_error_codes/error_codes") except OSError: print("Seems like folder already exist, moving on!") data = '' with open("src/librustc_error_codes/error_codes.rs") as f: x = f.read().split('\n') i = 0 short_part = False while i < len(x): line = x[i] if short_part is False and line.startswith('E0') and line.endswith(': r##"'): err_code = line.split(':')[0] i += 1 content = '' while i < len(x): if x[i] == '"##,': break content += x[i] content += '\n' i += 1 f_path = "src/librustc_error_codes/error_codes/{}.md".format(err_code) with open(f_path, "w") as ff: ff.write(content) data += '{}: include_str!("./error_codes/{}.md"),'.format(err_code, err_code) elif short_part is False and line == ';': short_part is True data += ';\n' else: data += line data += '\n' i += 1 with open("src/librustc_error_codes/error_codes.rs", "w") as f: f.write(data) ``` </details>
This commit is contained in:
+19
@@ -3120,6 +3120,7 @@ dependencies = [
|
||||
"graphviz",
|
||||
"jobserver",
|
||||
"log",
|
||||
"measureme",
|
||||
"num_cpus",
|
||||
"parking_lot 0.9.0",
|
||||
"polonius-engine",
|
||||
@@ -3127,6 +3128,7 @@ dependencies = [
|
||||
"rustc-rayon-core 0.3.0",
|
||||
"rustc_apfloat",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_fs_util",
|
||||
"rustc_index",
|
||||
@@ -3439,6 +3441,7 @@ dependencies = [
|
||||
"rustc_apfloat",
|
||||
"rustc_codegen_utils",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_fs_util",
|
||||
"rustc_incremental",
|
||||
@@ -3516,6 +3519,10 @@ dependencies = [
|
||||
"syntax_pos",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_error_codes"
|
||||
version = "0.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_errors"
|
||||
version = "0.0.0"
|
||||
@@ -3569,6 +3576,7 @@ dependencies = [
|
||||
"rustc_codegen_ssa",
|
||||
"rustc_codegen_utils",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_incremental",
|
||||
"rustc_lint",
|
||||
@@ -3605,6 +3613,7 @@ dependencies = [
|
||||
"log",
|
||||
"rustc",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_index",
|
||||
"rustc_target",
|
||||
"syntax",
|
||||
@@ -3650,6 +3659,7 @@ dependencies = [
|
||||
"memmap",
|
||||
"rustc",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_index",
|
||||
"rustc_parse",
|
||||
@@ -3675,6 +3685,7 @@ dependencies = [
|
||||
"rustc",
|
||||
"rustc_apfloat",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_index",
|
||||
"rustc_lexer",
|
||||
@@ -3703,6 +3714,7 @@ dependencies = [
|
||||
"bitflags",
|
||||
"log",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_lexer",
|
||||
"rustc_target",
|
||||
@@ -3718,6 +3730,7 @@ dependencies = [
|
||||
"log",
|
||||
"rustc",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_index",
|
||||
"rustc_parse",
|
||||
@@ -3738,6 +3751,7 @@ name = "rustc_plugin_impl"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc",
|
||||
"rustc_error_codes",
|
||||
"rustc_metadata",
|
||||
"syntax",
|
||||
"syntax_expand",
|
||||
@@ -3751,6 +3765,7 @@ dependencies = [
|
||||
"log",
|
||||
"rustc",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_typeck",
|
||||
"syntax",
|
||||
"syntax_pos",
|
||||
@@ -3765,6 +3780,7 @@ dependencies = [
|
||||
"log",
|
||||
"rustc",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_metadata",
|
||||
"smallvec 1.0.0",
|
||||
@@ -3844,6 +3860,7 @@ dependencies = [
|
||||
"log",
|
||||
"rustc",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_index",
|
||||
"rustc_target",
|
||||
@@ -4380,6 +4397,7 @@ dependencies = [
|
||||
"lazy_static 1.3.0",
|
||||
"log",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_index",
|
||||
"rustc_lexer",
|
||||
@@ -4411,6 +4429,7 @@ dependencies = [
|
||||
"fmt_macros",
|
||||
"log",
|
||||
"rustc_data_structures",
|
||||
"rustc_error_codes",
|
||||
"rustc_errors",
|
||||
"rustc_parse",
|
||||
"rustc_target",
|
||||
|
||||
@@ -40,3 +40,5 @@ byteorder = { version = "1.3" }
|
||||
chalk-engine = { version = "0.9.0", default-features=false }
|
||||
rustc_fs_util = { path = "../librustc_fs_util" }
|
||||
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
|
||||
measureme = "0.4"
|
||||
rustc_error_codes = { path = "../librustc_error_codes" }
|
||||
|
||||
@@ -1,2394 +0,0 @@
|
||||
// Error messages for EXXXX errors.
|
||||
// Each message should start and end with a new line, and be wrapped to 80
|
||||
// characters. In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use
|
||||
// `:set tw=0` to disable.
|
||||
syntax::register_diagnostics! {
|
||||
E0038: r##"
|
||||
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>`.
|
||||
"##,
|
||||
|
||||
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:
|
||||
|
||||
```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.
|
||||
"##,
|
||||
|
||||
E0080: r##"
|
||||
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
|
||||
"##,
|
||||
|
||||
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:
|
||||
|
||||
```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
|
||||
"##,
|
||||
|
||||
E0119: r##"
|
||||
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
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0139: r##"
|
||||
#### 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.
|
||||
"##,
|
||||
|
||||
E0152: r##"
|
||||
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
|
||||
"##,
|
||||
|
||||
E0214: r##"
|
||||
A generic type was described using parentheses rather than angle brackets.
|
||||
For example:
|
||||
|
||||
```compile_fail,E0214
|
||||
fn main() {
|
||||
let v: Vec(&str) = vec!["foo"];
|
||||
}
|
||||
```
|
||||
|
||||
This is not currently supported: `v` should be defined as `Vec<&str>`.
|
||||
Parentheses are currently only used with generic types when defining parameters
|
||||
for `Fn`-family traits.
|
||||
"##,
|
||||
|
||||
E0230: r##"
|
||||
The `#[rustc_on_unimplemented]` attribute lets you specify a custom error
|
||||
message for when a particular trait isn't implemented on a type placed in a
|
||||
position that needs that trait. For example, when the following code is
|
||||
compiled:
|
||||
|
||||
```compile_fail
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
fn foo<T: Index<u8>>(x: T){}
|
||||
|
||||
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
|
||||
trait Index<Idx> { /* ... */ }
|
||||
|
||||
foo(true); // `bool` does not implement `Index<u8>`
|
||||
```
|
||||
|
||||
There will be an error about `bool` not implementing `Index<u8>`, followed by a
|
||||
note saying "the type `bool` cannot be indexed by `u8`".
|
||||
|
||||
As you can see, you can specify type parameters in curly braces for
|
||||
substitution with the actual types (using the regular format string syntax) in
|
||||
a given situation. Furthermore, `{Self}` will substitute to the type (in this
|
||||
case, `bool`) that we tried to use.
|
||||
|
||||
This error appears when the curly braces contain an identifier which doesn't
|
||||
match with any of the type parameters or the string `Self`. This might happen
|
||||
if you misspelled a type parameter, or if you intended to use literal curly
|
||||
braces. If it is the latter, escape the curly braces with a second curly brace
|
||||
of the same type; e.g., a literal `{` is `{{`.
|
||||
"##,
|
||||
|
||||
E0231: r##"
|
||||
The `#[rustc_on_unimplemented]` attribute lets you specify a custom error
|
||||
message for when a particular trait isn't implemented on a type placed in a
|
||||
position that needs that trait. For example, when the following code is
|
||||
compiled:
|
||||
|
||||
```compile_fail
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
fn foo<T: Index<u8>>(x: T){}
|
||||
|
||||
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
|
||||
trait Index<Idx> { /* ... */ }
|
||||
|
||||
foo(true); // `bool` does not implement `Index<u8>`
|
||||
```
|
||||
|
||||
there will be an error about `bool` not implementing `Index<u8>`, followed by a
|
||||
note saying "the type `bool` cannot be indexed by `u8`".
|
||||
|
||||
As you can see, you can specify type parameters in curly braces for
|
||||
substitution with the actual types (using the regular format string syntax) in
|
||||
a given situation. Furthermore, `{Self}` will substitute to the type (in this
|
||||
case, `bool`) that we tried to use.
|
||||
|
||||
This error appears when the curly braces do not contain an identifier. Please
|
||||
add one of the same name as a type parameter. If you intended to use literal
|
||||
braces, use `{{` and `}}` to escape them.
|
||||
"##,
|
||||
|
||||
E0232: r##"
|
||||
The `#[rustc_on_unimplemented]` attribute lets you specify a custom error
|
||||
message for when a particular trait isn't implemented on a type placed in a
|
||||
position that needs that trait. For example, when the following code is
|
||||
compiled:
|
||||
|
||||
```compile_fail
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
fn foo<T: Index<u8>>(x: T){}
|
||||
|
||||
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
|
||||
trait Index<Idx> { /* ... */ }
|
||||
|
||||
foo(true); // `bool` does not implement `Index<u8>`
|
||||
```
|
||||
|
||||
there will be an error about `bool` not implementing `Index<u8>`, followed by a
|
||||
note saying "the type `bool` cannot be indexed by `u8`".
|
||||
|
||||
For this to work, some note must be specified. An empty attribute will not do
|
||||
anything, please remove the attribute or add some helpful note for users of the
|
||||
trait.
|
||||
"##,
|
||||
|
||||
E0261: r##"
|
||||
When using a lifetime like `'a` in a type, it must be declared before being
|
||||
used.
|
||||
|
||||
These two examples illustrate the problem:
|
||||
|
||||
```compile_fail,E0261
|
||||
// error, use of undeclared lifetime name `'a`
|
||||
fn foo(x: &'a str) { }
|
||||
|
||||
struct Foo {
|
||||
// error, use of undeclared lifetime name `'a`
|
||||
x: &'a str,
|
||||
}
|
||||
```
|
||||
|
||||
These can be fixed by declaring lifetime parameters:
|
||||
|
||||
```
|
||||
struct Foo<'a> {
|
||||
x: &'a str,
|
||||
}
|
||||
|
||||
fn foo<'a>(x: &'a str) {}
|
||||
```
|
||||
|
||||
Impl blocks declare lifetime parameters separately. You need to add lifetime
|
||||
parameters to an impl block if you're implementing a type that has a lifetime
|
||||
parameter of its own.
|
||||
For example:
|
||||
|
||||
```compile_fail,E0261
|
||||
struct Foo<'a> {
|
||||
x: &'a str,
|
||||
}
|
||||
|
||||
// error, use of undeclared lifetime name `'a`
|
||||
impl Foo<'a> {
|
||||
fn foo<'a>(x: &'a str) {}
|
||||
}
|
||||
```
|
||||
|
||||
This is fixed by declaring the impl block like this:
|
||||
|
||||
```
|
||||
struct Foo<'a> {
|
||||
x: &'a str,
|
||||
}
|
||||
|
||||
// correct
|
||||
impl<'a> Foo<'a> {
|
||||
fn foo(x: &'a str) {}
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0262: r##"
|
||||
Declaring certain lifetime names in parameters is disallowed. For example,
|
||||
because the `'static` lifetime is a special built-in lifetime name denoting
|
||||
the lifetime of the entire program, this is an error:
|
||||
|
||||
```compile_fail,E0262
|
||||
// error, invalid lifetime parameter name `'static`
|
||||
fn foo<'static>(x: &'static str) { }
|
||||
```
|
||||
"##,
|
||||
|
||||
E0263: r##"
|
||||
A lifetime name cannot be declared more than once in the same scope. For
|
||||
example:
|
||||
|
||||
```compile_fail,E0263
|
||||
// error, lifetime name `'a` declared twice in the same scope
|
||||
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { }
|
||||
```
|
||||
"##,
|
||||
|
||||
E0264: r##"
|
||||
An unknown external lang item was used. Erroneous code example:
|
||||
|
||||
```compile_fail,E0264
|
||||
#![feature(lang_items)]
|
||||
|
||||
extern "C" {
|
||||
#[lang = "cake"] // error: unknown external lang item: `cake`
|
||||
fn cake();
|
||||
}
|
||||
```
|
||||
|
||||
A list of available external lang items is available in
|
||||
`src/librustc/middle/weak_lang_items.rs`. Example:
|
||||
|
||||
```
|
||||
#![feature(lang_items)]
|
||||
|
||||
extern "C" {
|
||||
#[lang = "panic_impl"] // ok!
|
||||
fn cake();
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0271: r##"
|
||||
This is because of a type mismatch between the associated type of some
|
||||
trait (e.g., `T::Bar`, where `T` implements `trait Quux { type Bar; }`)
|
||||
and another type `U` that is required to be equal to `T::Bar`, but is not.
|
||||
Examples follow.
|
||||
|
||||
Here is a basic example:
|
||||
|
||||
```compile_fail,E0271
|
||||
trait Trait { type AssociatedType; }
|
||||
|
||||
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
|
||||
println!("in foo");
|
||||
}
|
||||
|
||||
impl Trait for i8 { type AssociatedType = &'static str; }
|
||||
|
||||
foo(3_i8);
|
||||
```
|
||||
|
||||
Here is that same example again, with some explanatory comments:
|
||||
|
||||
```compile_fail,E0271
|
||||
trait Trait { type AssociatedType; }
|
||||
|
||||
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
|
||||
// ~~~~~~~~ ~~~~~~~~~~~~~~~~~~
|
||||
// | |
|
||||
// This says `foo` can |
|
||||
// only be used with |
|
||||
// some type that |
|
||||
// implements `Trait`. |
|
||||
// |
|
||||
// This says not only must
|
||||
// `T` be an impl of `Trait`
|
||||
// but also that the impl
|
||||
// must assign the type `u32`
|
||||
// to the associated type.
|
||||
println!("in foo");
|
||||
}
|
||||
|
||||
impl Trait for i8 { type AssociatedType = &'static str; }
|
||||
//~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// | |
|
||||
// `i8` does have |
|
||||
// implementation |
|
||||
// of `Trait`... |
|
||||
// ... but it is an implementation
|
||||
// that assigns `&'static str` to
|
||||
// the associated type.
|
||||
|
||||
foo(3_i8);
|
||||
// Here, we invoke `foo` with an `i8`, which does not satisfy
|
||||
// the constraint `<i8 as Trait>::AssociatedType=u32`, and
|
||||
// therefore the type-checker complains with this error code.
|
||||
```
|
||||
|
||||
To avoid those issues, you have to make the types match correctly.
|
||||
So we can fix the previous examples like this:
|
||||
|
||||
```
|
||||
// Basic Example:
|
||||
trait Trait { type AssociatedType; }
|
||||
|
||||
fn foo<T>(t: T) where T: Trait<AssociatedType = &'static str> {
|
||||
println!("in foo");
|
||||
}
|
||||
|
||||
impl Trait for i8 { type AssociatedType = &'static str; }
|
||||
|
||||
foo(3_i8);
|
||||
|
||||
// For-Loop Example:
|
||||
let vs = vec![1, 2, 3, 4];
|
||||
for v in &vs {
|
||||
match v {
|
||||
&1 => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
|
||||
E0275: r##"
|
||||
This error occurs when there was a recursive trait requirement that overflowed
|
||||
before it could be evaluated. Often this means that there is unbounded
|
||||
recursion in resolving some type bounds.
|
||||
|
||||
For example, in the following code:
|
||||
|
||||
```compile_fail,E0275
|
||||
trait Foo {}
|
||||
|
||||
struct Bar<T>(T);
|
||||
|
||||
impl<T> Foo for T where Bar<T>: Foo {}
|
||||
```
|
||||
|
||||
To determine if a `T` is `Foo`, we need to check if `Bar<T>` is `Foo`. However,
|
||||
to do this check, we need to determine that `Bar<Bar<T>>` is `Foo`. To
|
||||
determine this, we check if `Bar<Bar<Bar<T>>>` is `Foo`, and so on. This is
|
||||
clearly a recursive requirement that can't be resolved directly.
|
||||
|
||||
Consider changing your trait bounds so that they're less self-referential.
|
||||
"##,
|
||||
|
||||
E0276: r##"
|
||||
This error occurs when a bound in an implementation of a trait does not match
|
||||
the bounds specified in the original trait. For example:
|
||||
|
||||
```compile_fail,E0276
|
||||
trait Foo {
|
||||
fn foo<T>(x: T);
|
||||
}
|
||||
|
||||
impl Foo for bool {
|
||||
fn foo<T>(x: T) where T: Copy {}
|
||||
}
|
||||
```
|
||||
|
||||
Here, all types implementing `Foo` must have a method `foo<T>(x: T)` which can
|
||||
take any type `T`. However, in the `impl` for `bool`, we have added an extra
|
||||
bound that `T` is `Copy`, which isn't compatible with the original trait.
|
||||
|
||||
Consider removing the bound from the method or adding the bound to the original
|
||||
method definition in the trait.
|
||||
"##,
|
||||
|
||||
E0277: r##"
|
||||
You tried to use a type which doesn't implement some trait in a place which
|
||||
expected that trait. Erroneous code example:
|
||||
|
||||
```compile_fail,E0277
|
||||
// here we declare the Foo trait with a bar method
|
||||
trait Foo {
|
||||
fn bar(&self);
|
||||
}
|
||||
|
||||
// we now declare a function which takes an object implementing the Foo trait
|
||||
fn some_func<T: Foo>(foo: T) {
|
||||
foo.bar();
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// we now call the method with the i32 type, which doesn't implement
|
||||
// the Foo trait
|
||||
some_func(5i32); // error: the trait bound `i32 : Foo` is not satisfied
|
||||
}
|
||||
```
|
||||
|
||||
In order to fix this error, verify that the type you're using does implement
|
||||
the trait. Example:
|
||||
|
||||
```
|
||||
trait Foo {
|
||||
fn bar(&self);
|
||||
}
|
||||
|
||||
fn some_func<T: Foo>(foo: T) {
|
||||
foo.bar(); // we can now use this method since i32 implements the
|
||||
// Foo trait
|
||||
}
|
||||
|
||||
// we implement the trait on the i32 type
|
||||
impl Foo for i32 {
|
||||
fn bar(&self) {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
some_func(5i32); // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Or in a generic context, an erroneous code example would look like:
|
||||
|
||||
```compile_fail,E0277
|
||||
fn some_func<T>(foo: T) {
|
||||
println!("{:?}", foo); // error: the trait `core::fmt::Debug` is not
|
||||
// implemented for the type `T`
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// We now call the method with the i32 type,
|
||||
// which *does* implement the Debug trait.
|
||||
some_func(5i32);
|
||||
}
|
||||
```
|
||||
|
||||
Note that the error here is in the definition of the generic function: Although
|
||||
we only call it with a parameter that does implement `Debug`, the compiler
|
||||
still rejects the function: It must work with all possible input types. In
|
||||
order to make this example compile, we need to restrict the generic type we're
|
||||
accepting:
|
||||
|
||||
```
|
||||
use std::fmt;
|
||||
|
||||
// Restrict the input type to types that implement Debug.
|
||||
fn some_func<T: fmt::Debug>(foo: T) {
|
||||
println!("{:?}", foo);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Calling the method is still fine, as i32 implements Debug.
|
||||
some_func(5i32);
|
||||
|
||||
// This would fail to compile now:
|
||||
// struct WithoutDebug;
|
||||
// some_func(WithoutDebug);
|
||||
}
|
||||
```
|
||||
|
||||
Rust only looks at the signature of the called function, as such it must
|
||||
already specify all requirements that will be used for every type parameter.
|
||||
"##,
|
||||
|
||||
E0281: r##"
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
You tried to supply a type which doesn't implement some trait in a location
|
||||
which expected that trait. This error typically occurs when working with
|
||||
`Fn`-based types. Erroneous code example:
|
||||
|
||||
```compile-fail
|
||||
fn foo<F: Fn(usize)>(x: F) { }
|
||||
|
||||
fn main() {
|
||||
// type mismatch: ... implements the trait `core::ops::Fn<(String,)>`,
|
||||
// but the trait `core::ops::Fn<(usize,)>` is required
|
||||
// [E0281]
|
||||
foo(|y: String| { });
|
||||
}
|
||||
```
|
||||
|
||||
The issue in this case is that `foo` is defined as accepting a `Fn` with one
|
||||
argument of type `String`, but the closure we attempted to pass to it requires
|
||||
one arguments of type `usize`.
|
||||
"##,
|
||||
|
||||
E0282: r##"
|
||||
This error indicates that type inference did not result in one unique possible
|
||||
type, and extra information is required. In most cases this can be provided
|
||||
by adding a type annotation. Sometimes you need to specify a generic type
|
||||
parameter manually.
|
||||
|
||||
A common example is the `collect` method on `Iterator`. It has a generic type
|
||||
parameter with a `FromIterator` bound, which for a `char` iterator is
|
||||
implemented by `Vec` and `String` among others. Consider the following snippet
|
||||
that reverses the characters of a string:
|
||||
|
||||
```compile_fail,E0282
|
||||
let x = "hello".chars().rev().collect();
|
||||
```
|
||||
|
||||
In this case, the compiler cannot infer what the type of `x` should be:
|
||||
`Vec<char>` and `String` are both suitable candidates. To specify which type to
|
||||
use, you can use a type annotation on `x`:
|
||||
|
||||
```
|
||||
let x: Vec<char> = "hello".chars().rev().collect();
|
||||
```
|
||||
|
||||
It is not necessary to annotate the full type. Once the ambiguity is resolved,
|
||||
the compiler can infer the rest:
|
||||
|
||||
```
|
||||
let x: Vec<_> = "hello".chars().rev().collect();
|
||||
```
|
||||
|
||||
Another way to provide the compiler with enough information, is to specify the
|
||||
generic type parameter:
|
||||
|
||||
```
|
||||
let x = "hello".chars().rev().collect::<Vec<char>>();
|
||||
```
|
||||
|
||||
Again, you need not specify the full type if the compiler can infer it:
|
||||
|
||||
```
|
||||
let x = "hello".chars().rev().collect::<Vec<_>>();
|
||||
```
|
||||
|
||||
Apart from a method or function with a generic type parameter, this error can
|
||||
occur when a type parameter of a struct or trait cannot be inferred. In that
|
||||
case it is not always possible to use a type annotation, because all candidates
|
||||
have the same return type. For instance:
|
||||
|
||||
```compile_fail,E0282
|
||||
struct Foo<T> {
|
||||
num: T,
|
||||
}
|
||||
|
||||
impl<T> Foo<T> {
|
||||
fn bar() -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
fn baz() {
|
||||
let number = Foo::bar();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This will fail because the compiler does not know which instance of `Foo` to
|
||||
call `bar` on. Change `Foo::bar()` to `Foo::<T>::bar()` to resolve the error.
|
||||
"##,
|
||||
|
||||
E0283: r##"
|
||||
This error occurs when the compiler doesn't have enough information
|
||||
to unambiguously choose an implementation.
|
||||
|
||||
For example:
|
||||
|
||||
```compile_fail,E0283
|
||||
trait Generator {
|
||||
fn create() -> u32;
|
||||
}
|
||||
|
||||
struct Impl;
|
||||
|
||||
impl Generator for Impl {
|
||||
fn create() -> u32 { 1 }
|
||||
}
|
||||
|
||||
struct AnotherImpl;
|
||||
|
||||
impl Generator for AnotherImpl {
|
||||
fn create() -> u32 { 2 }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let cont: u32 = Generator::create();
|
||||
// error, impossible to choose one of Generator trait implementation
|
||||
// Should it be Impl or AnotherImpl, maybe something else?
|
||||
}
|
||||
```
|
||||
|
||||
To resolve this error use the concrete type:
|
||||
|
||||
```
|
||||
trait Generator {
|
||||
fn create() -> u32;
|
||||
}
|
||||
|
||||
struct AnotherImpl;
|
||||
|
||||
impl Generator for AnotherImpl {
|
||||
fn create() -> u32 { 2 }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let gen1 = AnotherImpl::create();
|
||||
|
||||
// if there are multiple methods with same name (different traits)
|
||||
let gen2 = <AnotherImpl as Generator>::create();
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0284: r##"
|
||||
This error occurs when the compiler is unable to unambiguously infer the
|
||||
return type of a function or method which is generic on return type, such
|
||||
as the `collect` method for `Iterator`s.
|
||||
|
||||
For example:
|
||||
|
||||
```compile_fail,E0284
|
||||
fn foo() -> Result<bool, ()> {
|
||||
let results = [Ok(true), Ok(false), Err(())].iter().cloned();
|
||||
let v: Vec<bool> = results.collect()?;
|
||||
// Do things with v...
|
||||
Ok(true)
|
||||
}
|
||||
```
|
||||
|
||||
Here we have an iterator `results` over `Result<bool, ()>`.
|
||||
Hence, `results.collect()` can return any type implementing
|
||||
`FromIterator<Result<bool, ()>>`. On the other hand, the
|
||||
`?` operator can accept any type implementing `Try`.
|
||||
|
||||
The author of this code probably wants `collect()` to return a
|
||||
`Result<Vec<bool>, ()>`, but the compiler can't be sure
|
||||
that there isn't another type `T` implementing both `Try` and
|
||||
`FromIterator<Result<bool, ()>>` in scope such that
|
||||
`T::Ok == Vec<bool>`. Hence, this code is ambiguous and an error
|
||||
is returned.
|
||||
|
||||
To resolve this error, use a concrete type for the intermediate expression:
|
||||
|
||||
```
|
||||
fn foo() -> Result<bool, ()> {
|
||||
let results = [Ok(true), Ok(false), Err(())].iter().cloned();
|
||||
let v = {
|
||||
let temp: Result<Vec<bool>, ()> = results.collect();
|
||||
temp?
|
||||
};
|
||||
// Do things with v...
|
||||
Ok(true)
|
||||
}
|
||||
```
|
||||
|
||||
Note that the type of `v` can now be inferred from the type of `temp`.
|
||||
"##,
|
||||
|
||||
E0308: r##"
|
||||
This error occurs when the compiler was unable to infer the concrete type of a
|
||||
variable. It can occur for several cases, the most common of which is a
|
||||
mismatch in the expected type that the compiler inferred for a variable's
|
||||
initializing expression, and the actual type explicitly assigned to the
|
||||
variable.
|
||||
|
||||
For example:
|
||||
|
||||
```compile_fail,E0308
|
||||
let x: i32 = "I am not a number!";
|
||||
// ~~~ ~~~~~~~~~~~~~~~~~~~~
|
||||
// | |
|
||||
// | initializing expression;
|
||||
// | compiler infers type `&str`
|
||||
// |
|
||||
// type `i32` assigned to variable `x`
|
||||
```
|
||||
"##,
|
||||
|
||||
E0309: r##"
|
||||
The type definition contains some field whose type
|
||||
requires an outlives annotation. Outlives annotations
|
||||
(e.g., `T: 'a`) are used to guarantee that all the data in T is valid
|
||||
for at least the lifetime `'a`. This scenario most commonly
|
||||
arises when the type contains an associated type reference
|
||||
like `<T as SomeTrait<'a>>::Output`, as shown in this example:
|
||||
|
||||
```compile_fail,E0309
|
||||
// This won't compile because the applicable impl of
|
||||
// `SomeTrait` (below) requires that `T: 'a`, but the struct does
|
||||
// not have a matching where-clause.
|
||||
struct Foo<'a, T> {
|
||||
foo: <T as SomeTrait<'a>>::Output,
|
||||
}
|
||||
|
||||
trait SomeTrait<'a> {
|
||||
type Output;
|
||||
}
|
||||
|
||||
impl<'a, T> SomeTrait<'a> for T
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
type Output = u32;
|
||||
}
|
||||
```
|
||||
|
||||
Here, the where clause `T: 'a` that appears on the impl is not known to be
|
||||
satisfied on the struct. To make this example compile, you have to add
|
||||
a where-clause like `T: 'a` to the struct definition:
|
||||
|
||||
```
|
||||
struct Foo<'a, T>
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
foo: <T as SomeTrait<'a>>::Output
|
||||
}
|
||||
|
||||
trait SomeTrait<'a> {
|
||||
type Output;
|
||||
}
|
||||
|
||||
impl<'a, T> SomeTrait<'a> for T
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
type Output = u32;
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0310: r##"
|
||||
Types in type definitions have lifetimes associated with them that represent
|
||||
how long the data stored within them is guaranteed to be live. This lifetime
|
||||
must be as long as the data needs to be alive, and missing the constraint that
|
||||
denotes this will cause this error.
|
||||
|
||||
```compile_fail,E0310
|
||||
// This won't compile because T is not constrained to the static lifetime
|
||||
// the reference needs
|
||||
struct Foo<T> {
|
||||
foo: &'static T
|
||||
}
|
||||
```
|
||||
|
||||
This will compile, because it has the constraint on the type parameter:
|
||||
|
||||
```
|
||||
struct Foo<T: 'static> {
|
||||
foo: &'static T
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0312: r##"
|
||||
Reference's lifetime of borrowed content doesn't match the expected lifetime.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0312
|
||||
pub fn opt_str<'a>(maybestr: &'a Option<String>) -> &'static str {
|
||||
if maybestr.is_none() {
|
||||
"(none)"
|
||||
} else {
|
||||
let s: &'a str = maybestr.as_ref().unwrap();
|
||||
s // Invalid lifetime!
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To fix this error, either lessen the expected lifetime or find a way to not have
|
||||
to use this reference outside of its current scope (by running the code directly
|
||||
in the same block for example?):
|
||||
|
||||
```
|
||||
// In this case, we can fix the issue by switching from "static" lifetime to 'a
|
||||
pub fn opt_str<'a>(maybestr: &'a Option<String>) -> &'a str {
|
||||
if maybestr.is_none() {
|
||||
"(none)"
|
||||
} else {
|
||||
let s: &'a str = maybestr.as_ref().unwrap();
|
||||
s // Ok!
|
||||
}
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0317: r##"
|
||||
This error occurs when an `if` expression without an `else` block is used in a
|
||||
context where a type other than `()` is expected, for example a `let`
|
||||
expression:
|
||||
|
||||
```compile_fail,E0317
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let a = if x == 5 { 1 };
|
||||
}
|
||||
```
|
||||
|
||||
An `if` expression without an `else` block has the type `()`, so this is a type
|
||||
error. To resolve it, add an `else` block having the same type as the `if`
|
||||
block.
|
||||
"##,
|
||||
|
||||
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:
|
||||
|
||||
```compile_fail,E0391
|
||||
trait FirstTrait : SecondTrait {
|
||||
|
||||
}
|
||||
|
||||
trait SecondTrait : FirstTrait {
|
||||
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0398: r##"
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
In Rust 1.3, the default object lifetime bounds are expected to change, as
|
||||
described in [RFC 1156]. You are getting a warning because the compiler
|
||||
thinks it is possible that this change will cause a compilation error in your
|
||||
code. It is possible, though unlikely, that this is a false alarm.
|
||||
|
||||
The heart of the change is that where `&'a Box<SomeTrait>` used to default to
|
||||
`&'a Box<SomeTrait+'a>`, it now defaults to `&'a Box<SomeTrait+'static>` (here,
|
||||
`SomeTrait` is the name of some trait type). Note that the only types which are
|
||||
affected are references to boxes, like `&Box<SomeTrait>` or
|
||||
`&[Box<SomeTrait>]`. More common types like `&SomeTrait` or `Box<SomeTrait>`
|
||||
are unaffected.
|
||||
|
||||
To silence this warning, edit your code to use an explicit bound. Most of the
|
||||
time, this means that you will want to change the signature of a function that
|
||||
you are calling. For example, if the error is reported on a call like `foo(x)`,
|
||||
and `foo` is defined as follows:
|
||||
|
||||
```
|
||||
# trait SomeTrait {}
|
||||
fn foo(arg: &Box<SomeTrait>) { /* ... */ }
|
||||
```
|
||||
|
||||
You might change it to:
|
||||
|
||||
```
|
||||
# trait SomeTrait {}
|
||||
fn foo<'a>(arg: &'a Box<SomeTrait+'a>) { /* ... */ }
|
||||
```
|
||||
|
||||
This explicitly states that you expect the trait object `SomeTrait` to contain
|
||||
references (with a maximum lifetime of `'a`).
|
||||
|
||||
[RFC 1156]: https://github.com/rust-lang/rfcs/blob/master/text/1156-adjust-default-object-bounds.md
|
||||
"##,
|
||||
|
||||
E0452: r##"
|
||||
An invalid lint attribute has been given. Erroneous code example:
|
||||
|
||||
```compile_fail,E0452
|
||||
#![allow(foo = "")] // error: malformed lint attribute
|
||||
```
|
||||
|
||||
Lint attributes only accept a list of identifiers (where each identifier is a
|
||||
lint name). Ensure the attribute is of this form:
|
||||
|
||||
```
|
||||
#![allow(foo)] // ok!
|
||||
// or:
|
||||
#![allow(foo, foo2)] // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0453: r##"
|
||||
A lint check attribute was overruled by a `forbid` directive set as an
|
||||
attribute on an enclosing scope, or on the command line with the `-F` option.
|
||||
|
||||
Example of erroneous code:
|
||||
|
||||
```compile_fail,E0453
|
||||
#![forbid(non_snake_case)]
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn main() {
|
||||
let MyNumber = 2; // error: allow(non_snake_case) overruled by outer
|
||||
// forbid(non_snake_case)
|
||||
}
|
||||
```
|
||||
|
||||
The `forbid` lint setting, like `deny`, turns the corresponding compiler
|
||||
warning into a hard error. Unlike `deny`, `forbid` prevents itself from being
|
||||
overridden by inner attributes.
|
||||
|
||||
If you're sure you want to override the lint check, you can change `forbid` to
|
||||
`deny` (or use `-D` instead of `-F` if the `forbid` setting was given as a
|
||||
command-line option) to allow the inner lint check attribute:
|
||||
|
||||
```
|
||||
#![deny(non_snake_case)]
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
fn main() {
|
||||
let MyNumber = 2; // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Otherwise, edit the code to pass the lint check, and remove the overruled
|
||||
attribute:
|
||||
|
||||
```
|
||||
#![forbid(non_snake_case)]
|
||||
|
||||
fn main() {
|
||||
let my_number = 2;
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0478: r##"
|
||||
A lifetime bound was not satisfied.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0478
|
||||
// Check that the explicit lifetime bound (`'SnowWhite`, in this example) must
|
||||
// outlive all the superbounds from the trait (`'kiss`, in this example).
|
||||
|
||||
trait Wedding<'t>: 't { }
|
||||
|
||||
struct Prince<'kiss, 'SnowWhite> {
|
||||
child: Box<Wedding<'kiss> + 'SnowWhite>,
|
||||
// error: lifetime bound not satisfied
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the `'SnowWhite` lifetime is supposed to outlive the `'kiss`
|
||||
lifetime but the declaration of the `Prince` struct doesn't enforce it. To fix
|
||||
this issue, you need to specify it:
|
||||
|
||||
```
|
||||
trait Wedding<'t>: 't { }
|
||||
|
||||
struct Prince<'kiss, 'SnowWhite: 'kiss> { // You say here that 'kiss must live
|
||||
// longer than 'SnowWhite.
|
||||
child: Box<Wedding<'kiss> + 'SnowWhite>, // And now it's all good!
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0491: r##"
|
||||
A reference has a longer lifetime than the data it references.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0491
|
||||
trait SomeTrait<'a> {
|
||||
type Output;
|
||||
}
|
||||
|
||||
impl<'a, T> SomeTrait<'a> for T {
|
||||
type Output = &'a T; // compile error E0491
|
||||
}
|
||||
```
|
||||
|
||||
Here, the problem is that a reference type like `&'a T` is only valid
|
||||
if all the data in T outlives the lifetime `'a`. But this impl as written
|
||||
is applicable to any lifetime `'a` and any type `T` -- we have no guarantee
|
||||
that `T` outlives `'a`. To fix this, you can add a where clause like
|
||||
`where T: 'a`.
|
||||
|
||||
```
|
||||
trait SomeTrait<'a> {
|
||||
type Output;
|
||||
}
|
||||
|
||||
impl<'a, T> SomeTrait<'a> for T
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
type Output = &'a T; // compile error E0491
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0495: r##"
|
||||
A lifetime cannot be determined in the given situation.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0495
|
||||
fn transmute_lifetime<'a, 'b, T>(t: &'a (T,)) -> &'b T {
|
||||
match (&t,) { // error!
|
||||
((u,),) => u,
|
||||
}
|
||||
}
|
||||
|
||||
let y = Box::new((42,));
|
||||
let x = transmute_lifetime(&y);
|
||||
```
|
||||
|
||||
In this code, you have two ways to solve this issue:
|
||||
1. Enforce that `'a` lives at least as long as `'b`.
|
||||
2. Use the same lifetime requirement for both input and output values.
|
||||
|
||||
So for the first solution, you can do it by replacing `'a` with `'a: 'b`:
|
||||
|
||||
```
|
||||
fn transmute_lifetime<'a: 'b, 'b, T>(t: &'a (T,)) -> &'b T {
|
||||
match (&t,) { // ok!
|
||||
((u,),) => u,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the second you can do it by simply removing `'b` so they both use `'a`:
|
||||
|
||||
```
|
||||
fn transmute_lifetime<'a, T>(t: &'a (T,)) -> &'a T {
|
||||
match (&t,) { // ok!
|
||||
((u,),) => u,
|
||||
}
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0496: r##"
|
||||
A lifetime name is shadowing another lifetime name.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0496
|
||||
struct Foo<'a> {
|
||||
a: &'a i32,
|
||||
}
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
fn f<'a>(x: &'a i32) { // error: lifetime name `'a` shadows a lifetime
|
||||
// name that is already in scope
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Please change the name of one of the lifetimes to remove this error. Example:
|
||||
|
||||
```
|
||||
struct Foo<'a> {
|
||||
a: &'a i32,
|
||||
}
|
||||
|
||||
impl<'a> Foo<'a> {
|
||||
fn f<'b>(x: &'b i32) { // ok!
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0497: r##"
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
A stability attribute was used outside of the standard library.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail
|
||||
#[stable] // error: stability attributes may not be used outside of the
|
||||
// standard library
|
||||
fn foo() {}
|
||||
```
|
||||
|
||||
It is not possible to use stability attributes outside of the standard library.
|
||||
Also, for now, it is not possible to write deprecation messages either.
|
||||
"##,
|
||||
|
||||
E0517: r##"
|
||||
This error indicates that a `#[repr(..)]` attribute was placed on an
|
||||
unsupported item.
|
||||
|
||||
Examples of erroneous code:
|
||||
|
||||
```compile_fail,E0517
|
||||
#[repr(C)]
|
||||
type Foo = u8;
|
||||
|
||||
#[repr(packed)]
|
||||
enum Foo {Bar, Baz}
|
||||
|
||||
#[repr(u8)]
|
||||
struct Foo {bar: bool, baz: bool}
|
||||
|
||||
#[repr(C)]
|
||||
impl Foo {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
* The `#[repr(C)]` attribute can only be placed on structs and enums.
|
||||
* The `#[repr(packed)]` and `#[repr(simd)]` attributes only work on structs.
|
||||
* The `#[repr(u8)]`, `#[repr(i16)]`, etc attributes only work on enums.
|
||||
|
||||
These attributes do not work on typedefs, since typedefs are just aliases.
|
||||
|
||||
Representations like `#[repr(u8)]`, `#[repr(i64)]` are for selecting the
|
||||
discriminant size for enums with no data fields on any of the variants, e.g.
|
||||
`enum Color {Red, Blue, Green}`, effectively setting the size of the enum to
|
||||
the size of the provided type. Such an enum can be cast to a value of the same
|
||||
type as well. In short, `#[repr(u8)]` makes the enum behave like an integer
|
||||
with a constrained set of allowed values.
|
||||
|
||||
Only field-less enums can be cast to numerical primitives, so this attribute
|
||||
will not apply to structs.
|
||||
|
||||
`#[repr(packed)]` reduces padding to make the struct size smaller. The
|
||||
representation of enums isn't strictly defined in Rust, and this attribute
|
||||
won't work on enums.
|
||||
|
||||
`#[repr(simd)]` will give a struct consisting of a homogeneous series of machine
|
||||
types (i.e., `u8`, `i32`, etc) a representation that permits vectorization via
|
||||
SIMD. This doesn't make much sense for enums since they don't consist of a
|
||||
single list of data.
|
||||
"##,
|
||||
|
||||
E0518: r##"
|
||||
This error indicates that an `#[inline(..)]` attribute was incorrectly placed
|
||||
on something other than a function or method.
|
||||
|
||||
Examples of erroneous code:
|
||||
|
||||
```compile_fail,E0518
|
||||
#[inline(always)]
|
||||
struct Foo;
|
||||
|
||||
#[inline(never)]
|
||||
impl Foo {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
`#[inline]` hints the compiler whether or not to attempt to inline a method or
|
||||
function. By default, the compiler does a pretty good job of figuring this out
|
||||
itself, but if you feel the need for annotations, `#[inline(always)]` and
|
||||
`#[inline(never)]` can override or force the compiler's decision.
|
||||
|
||||
If you wish to apply this attribute to all methods in an impl, manually annotate
|
||||
each method; it is not possible to annotate the entire impl with an `#[inline]`
|
||||
attribute.
|
||||
"##,
|
||||
|
||||
E0522: r##"
|
||||
The lang attribute is intended for marking special items that are built-in to
|
||||
Rust itself. This includes special traits (like `Copy` and `Sized`) that affect
|
||||
how the compiler behaves, as well as special functions that may be automatically
|
||||
invoked (such as the handler for out-of-bounds accesses when indexing a slice).
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0522
|
||||
#![feature(lang_items)]
|
||||
|
||||
#[lang = "cookie"]
|
||||
fn cookie() -> ! { // error: definition of an unknown language item: `cookie`
|
||||
loop {}
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0525: r##"
|
||||
A closure was used but didn't implement the expected trait.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0525
|
||||
struct X;
|
||||
|
||||
fn foo<T>(_: T) {}
|
||||
fn bar<T: Fn(u32)>(_: T) {}
|
||||
|
||||
fn main() {
|
||||
let x = X;
|
||||
let closure = |_| foo(x); // error: expected a closure that implements
|
||||
// the `Fn` trait, but this closure only
|
||||
// implements `FnOnce`
|
||||
bar(closure);
|
||||
}
|
||||
```
|
||||
|
||||
In the example above, `closure` is an `FnOnce` closure whereas the `bar`
|
||||
function expected an `Fn` closure. In this case, it's simple to fix the issue,
|
||||
you just have to implement `Copy` and `Clone` traits on `struct X` and it'll
|
||||
be ok:
|
||||
|
||||
```
|
||||
#[derive(Clone, Copy)] // We implement `Clone` and `Copy` traits.
|
||||
struct X;
|
||||
|
||||
fn foo<T>(_: T) {}
|
||||
fn bar<T: Fn(u32)>(_: T) {}
|
||||
|
||||
fn main() {
|
||||
let x = X;
|
||||
let closure = |_| foo(x);
|
||||
bar(closure); // ok!
|
||||
}
|
||||
```
|
||||
|
||||
To understand better how closures work in Rust, read:
|
||||
https://doc.rust-lang.org/book/ch13-01-closures.html
|
||||
"##,
|
||||
|
||||
E0566: r##"
|
||||
Conflicting representation hints have been used on a same item.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```
|
||||
#[repr(u32, u64)] // warning!
|
||||
enum Repr { A }
|
||||
```
|
||||
|
||||
In most cases (if not all), using just one representation hint is more than
|
||||
enough. If you want to have a representation hint depending on the current
|
||||
architecture, use `cfg_attr`. Example:
|
||||
|
||||
```
|
||||
#[cfg_attr(linux, repr(u32))]
|
||||
#[cfg_attr(not(linux), repr(u64))]
|
||||
enum Repr { A }
|
||||
```
|
||||
"##,
|
||||
|
||||
E0580: r##"
|
||||
The `main` function was incorrectly declared.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0580
|
||||
fn main(x: i32) { // error: main function has wrong type
|
||||
println!("{}", x);
|
||||
}
|
||||
```
|
||||
|
||||
The `main` function prototype should never take arguments.
|
||||
Example:
|
||||
|
||||
```
|
||||
fn main() {
|
||||
// your code
|
||||
}
|
||||
```
|
||||
|
||||
If you want to get command-line arguments, use `std::env::args`. To exit with a
|
||||
specified exit code, use `std::process::exit`.
|
||||
"##,
|
||||
|
||||
E0562: r##"
|
||||
Abstract return types (written `impl Trait` for some trait `Trait`) are only
|
||||
allowed as function and inherent impl return types.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0562
|
||||
fn main() {
|
||||
let count_to_ten: impl Iterator<Item=usize> = 0..10;
|
||||
// error: `impl Trait` not allowed outside of function and inherent method
|
||||
// return types
|
||||
for i in count_to_ten {
|
||||
println!("{}", i);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Make sure `impl Trait` only appears in return-type position.
|
||||
|
||||
```
|
||||
fn count_to_n(n: usize) -> impl Iterator<Item=usize> {
|
||||
0..n
|
||||
}
|
||||
|
||||
fn main() {
|
||||
for i in count_to_n(10) { // ok!
|
||||
println!("{}", i);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
See [RFC 1522] for more details.
|
||||
|
||||
[RFC 1522]: https://github.com/rust-lang/rfcs/blob/master/text/1522-conservative-impl-trait.md
|
||||
"##,
|
||||
|
||||
E0593: r##"
|
||||
You tried to supply an `Fn`-based type with an incorrect number of arguments
|
||||
than what was expected.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0593
|
||||
fn foo<F: Fn()>(x: F) { }
|
||||
|
||||
fn main() {
|
||||
// [E0593] closure takes 1 argument but 0 arguments are required
|
||||
foo(|y| { });
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0602: r##"
|
||||
An unknown lint was used on the command line.
|
||||
|
||||
Erroneous example:
|
||||
|
||||
```sh
|
||||
rustc -D bogus omse_file.rs
|
||||
```
|
||||
|
||||
Maybe you just misspelled the lint name or the lint doesn't exist anymore.
|
||||
Either way, try to update/remove it in order to fix the error.
|
||||
"##,
|
||||
|
||||
E0621: r##"
|
||||
This error code indicates a mismatch between the lifetimes appearing in the
|
||||
function signature (i.e., the parameter types and the return type) and the
|
||||
data-flow found in the function body.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0621
|
||||
fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 { // error: explicit lifetime
|
||||
// required in the type of
|
||||
// `y`
|
||||
if x > y { x } else { y }
|
||||
}
|
||||
```
|
||||
|
||||
In the code above, the function is returning data borrowed from either `x` or
|
||||
`y`, but the `'a` annotation indicates that it is returning data only from `x`.
|
||||
To fix the error, the signature and the body must be made to match. Typically,
|
||||
this is done by updating the function signature. So, in this case, we change
|
||||
the type of `y` to `&'a i32`, like so:
|
||||
|
||||
```
|
||||
fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
|
||||
if x > y { x } else { y }
|
||||
}
|
||||
```
|
||||
|
||||
Now the signature indicates that the function data borrowed from either `x` or
|
||||
`y`. Alternatively, you could change the body to not return data from `y`:
|
||||
|
||||
```
|
||||
fn foo<'a>(x: &'a i32, y: &i32) -> &'a i32 {
|
||||
x
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0623: r##"
|
||||
A lifetime didn't match what was expected.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0623
|
||||
struct Foo<'a> {
|
||||
x: &'a isize,
|
||||
}
|
||||
|
||||
fn bar<'short, 'long>(c: Foo<'short>, l: &'long isize) {
|
||||
let _: Foo<'long> = c; // error!
|
||||
}
|
||||
```
|
||||
|
||||
In this example, we tried to set a value with an incompatible lifetime to
|
||||
another one (`'long` is unrelated to `'short`). We can solve this issue in
|
||||
two different ways:
|
||||
|
||||
Either we make `'short` live at least as long as `'long`:
|
||||
|
||||
```
|
||||
struct Foo<'a> {
|
||||
x: &'a isize,
|
||||
}
|
||||
|
||||
// we set 'short to live at least as long as 'long
|
||||
fn bar<'short: 'long, 'long>(c: Foo<'short>, l: &'long isize) {
|
||||
let _: Foo<'long> = c; // ok!
|
||||
}
|
||||
```
|
||||
|
||||
Or we use only one lifetime:
|
||||
|
||||
```
|
||||
struct Foo<'a> {
|
||||
x: &'a isize,
|
||||
}
|
||||
|
||||
fn bar<'short>(c: Foo<'short>, l: &'short isize) {
|
||||
let _: Foo<'short> = c; // ok!
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0635: r##"
|
||||
The `#![feature]` attribute specified an unknown feature.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0635
|
||||
#![feature(nonexistent_rust_feature)] // error: unknown feature
|
||||
```
|
||||
|
||||
"##,
|
||||
|
||||
E0636: r##"
|
||||
A `#![feature]` attribute was declared multiple times.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0636
|
||||
#![allow(stable_features)]
|
||||
#![feature(rust1)]
|
||||
#![feature(rust1)] // error: the feature `rust1` has already been declared
|
||||
```
|
||||
|
||||
"##,
|
||||
|
||||
E0644: r##"
|
||||
A closure or generator was constructed that references its own type.
|
||||
|
||||
Erroneous example:
|
||||
|
||||
```compile-fail,E0644
|
||||
fn fix<F>(f: &F)
|
||||
where F: Fn(&F)
|
||||
{
|
||||
f(&f);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fix(&|y| {
|
||||
// Here, when `x` is called, the parameter `y` is equal to `x`.
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
Rust does not permit a closure to directly reference its own type,
|
||||
either through an argument (as in the example above) or by capturing
|
||||
itself through its environment. This restriction helps keep closure
|
||||
inference tractable.
|
||||
|
||||
The easiest fix is to rewrite your closure into a top-level function,
|
||||
or into a method. In some cases, you may also be able to have your
|
||||
closure call itself by capturing a `&Fn()` object or `fn()` pointer
|
||||
that refers to itself. That is permitting, since the closure would be
|
||||
invoking itself via a virtual call, and hence does not directly
|
||||
reference its own *type*.
|
||||
|
||||
"##,
|
||||
|
||||
E0692: r##"
|
||||
A `repr(transparent)` type was also annotated with other, incompatible
|
||||
representation hints.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0692
|
||||
#[repr(transparent, C)] // error: incompatible representation hints
|
||||
struct Grams(f32);
|
||||
```
|
||||
|
||||
A type annotated as `repr(transparent)` delegates all representation concerns to
|
||||
another type, so adding more representation hints is contradictory. Remove
|
||||
either the `transparent` hint or the other hints, like this:
|
||||
|
||||
```
|
||||
#[repr(transparent)]
|
||||
struct Grams(f32);
|
||||
```
|
||||
|
||||
Alternatively, move the other attributes to the contained type:
|
||||
|
||||
```
|
||||
#[repr(C)]
|
||||
struct Foo {
|
||||
x: i32,
|
||||
// ...
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct FooWrapper(Foo);
|
||||
```
|
||||
|
||||
Note that introducing another `struct` just to have a place for the other
|
||||
attributes may have unintended side effects on the representation:
|
||||
|
||||
```
|
||||
#[repr(transparent)]
|
||||
struct Grams(f32);
|
||||
|
||||
#[repr(C)]
|
||||
struct Float(f32);
|
||||
|
||||
#[repr(transparent)]
|
||||
struct Grams2(Float); // this is not equivalent to `Grams` above
|
||||
```
|
||||
|
||||
Here, `Grams2` is a not equivalent to `Grams` -- the former transparently wraps
|
||||
a (non-transparent) struct containing a single float, while `Grams` is a
|
||||
transparent wrapper around a float. This can make a difference for the ABI.
|
||||
"##,
|
||||
|
||||
E0697: r##"
|
||||
A closure has been used as `static`.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0697
|
||||
fn main() {
|
||||
static || {}; // used as `static`
|
||||
}
|
||||
```
|
||||
|
||||
Closures cannot be used as `static`. They "save" the environment,
|
||||
and as such a static closure would save only a static environment
|
||||
which would consist only of variables with a static lifetime. Given
|
||||
this it would be better to use a proper function. The easiest fix
|
||||
is to remove the `static` keyword.
|
||||
"##,
|
||||
|
||||
E0698: r##"
|
||||
When using generators (or async) all type variables must be bound so a
|
||||
generator can be constructed.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```edition2018,compile-fail,E0698
|
||||
async fn bar<T>() -> () {}
|
||||
|
||||
async fn foo() {
|
||||
bar().await; // error: cannot infer type for `T`
|
||||
}
|
||||
```
|
||||
|
||||
In the above example `T` is unknowable by the compiler.
|
||||
To fix this you must bind `T` to a concrete type such as `String`
|
||||
so that a generator can then be constructed:
|
||||
|
||||
```edition2018
|
||||
async fn bar<T>() -> () {}
|
||||
|
||||
async fn foo() {
|
||||
bar::<String>().await;
|
||||
// ^^^^^^^^ specify type explicitly
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0700: r##"
|
||||
The `impl Trait` return type captures lifetime parameters that do not
|
||||
appear within the `impl Trait` itself.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile-fail,E0700
|
||||
use std::cell::Cell;
|
||||
|
||||
trait Trait<'a> { }
|
||||
|
||||
impl<'a, 'b> Trait<'b> for Cell<&'a u32> { }
|
||||
|
||||
fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y>
|
||||
where 'x: 'y
|
||||
{
|
||||
x
|
||||
}
|
||||
```
|
||||
|
||||
Here, the function `foo` returns a value of type `Cell<&'x u32>`,
|
||||
which references the lifetime `'x`. However, the return type is
|
||||
declared as `impl Trait<'y>` -- this indicates that `foo` returns
|
||||
"some type that implements `Trait<'y>`", but it also indicates that
|
||||
the return type **only captures data referencing the lifetime `'y`**.
|
||||
In this case, though, we are referencing data with lifetime `'x`, so
|
||||
this function is in error.
|
||||
|
||||
To fix this, you must reference the lifetime `'x` from the return
|
||||
type. For example, changing the return type to `impl Trait<'y> + 'x`
|
||||
would work:
|
||||
|
||||
```
|
||||
use std::cell::Cell;
|
||||
|
||||
trait Trait<'a> { }
|
||||
|
||||
impl<'a,'b> Trait<'b> for Cell<&'a u32> { }
|
||||
|
||||
fn foo<'x, 'y>(x: Cell<&'x u32>) -> impl Trait<'y> + 'x
|
||||
where 'x: 'y
|
||||
{
|
||||
x
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0701: r##"
|
||||
This error indicates that a `#[non_exhaustive]` attribute was incorrectly placed
|
||||
on something other than a struct or enum.
|
||||
|
||||
Examples of erroneous code:
|
||||
|
||||
```compile_fail,E0701
|
||||
#[non_exhaustive]
|
||||
trait Foo { }
|
||||
```
|
||||
"##,
|
||||
|
||||
E0718: r##"
|
||||
This error indicates that a `#[lang = ".."]` attribute was placed
|
||||
on the wrong type of item.
|
||||
|
||||
Examples of erroneous code:
|
||||
|
||||
```compile_fail,E0718
|
||||
#![feature(lang_items)]
|
||||
|
||||
#[lang = "arc"]
|
||||
static X: u32 = 42;
|
||||
```
|
||||
"##,
|
||||
|
||||
E0728: r##"
|
||||
[`await`] has been used outside [`async`] function or block.
|
||||
|
||||
Erroneous code examples:
|
||||
|
||||
```edition2018,compile_fail,E0728
|
||||
# use std::pin::Pin;
|
||||
# use std::future::Future;
|
||||
# use std::task::{Context, Poll};
|
||||
#
|
||||
# struct WakeOnceThenComplete(bool);
|
||||
#
|
||||
# fn wake_and_yield_once() -> WakeOnceThenComplete {
|
||||
# WakeOnceThenComplete(false)
|
||||
# }
|
||||
#
|
||||
# impl Future for WakeOnceThenComplete {
|
||||
# type Output = ();
|
||||
# fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
|
||||
# if self.0 {
|
||||
# Poll::Ready(())
|
||||
# } else {
|
||||
# cx.waker().wake_by_ref();
|
||||
# self.0 = true;
|
||||
# Poll::Pending
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
fn foo() {
|
||||
wake_and_yield_once().await // `await` is used outside `async` context
|
||||
}
|
||||
```
|
||||
|
||||
[`await`] is used to suspend the current computation until the given
|
||||
future is ready to produce a value. So it is legal only within
|
||||
an [`async`] context, like an `async fn` or an `async` block.
|
||||
|
||||
```edition2018
|
||||
# use std::pin::Pin;
|
||||
# use std::future::Future;
|
||||
# use std::task::{Context, Poll};
|
||||
#
|
||||
# struct WakeOnceThenComplete(bool);
|
||||
#
|
||||
# fn wake_and_yield_once() -> WakeOnceThenComplete {
|
||||
# WakeOnceThenComplete(false)
|
||||
# }
|
||||
#
|
||||
# impl Future for WakeOnceThenComplete {
|
||||
# type Output = ();
|
||||
# fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
|
||||
# if self.0 {
|
||||
# Poll::Ready(())
|
||||
# } else {
|
||||
# cx.waker().wake_by_ref();
|
||||
# self.0 = true;
|
||||
# Poll::Pending
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
#
|
||||
async fn foo() {
|
||||
wake_and_yield_once().await // `await` is used within `async` function
|
||||
}
|
||||
|
||||
fn bar(x: u8) -> impl Future<Output = u8> {
|
||||
async move {
|
||||
wake_and_yield_once().await; // `await` is used within `async` block
|
||||
x
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[`async`]: https://doc.rust-lang.org/std/keyword.async.html
|
||||
[`await`]: https://doc.rust-lang.org/std/keyword.await.html
|
||||
"##,
|
||||
|
||||
E0734: r##"
|
||||
A stability attribute has been used outside of the standard library.
|
||||
|
||||
Erroneous code examples:
|
||||
|
||||
```compile_fail,E0734
|
||||
#[rustc_deprecated(since = "b", reason = "text")] // invalid
|
||||
#[stable(feature = "a", since = "b")] // invalid
|
||||
#[unstable(feature = "b", issue = "0")] // invalid
|
||||
fn foo(){}
|
||||
```
|
||||
|
||||
These attributes are meant to only be used by the standard library and are
|
||||
rejected in your own crates.
|
||||
"##,
|
||||
|
||||
E0736: r##"
|
||||
`#[track_caller]` and `#[naked]` cannot both be applied to the same function.
|
||||
|
||||
Erroneous code example:
|
||||
|
||||
```compile_fail,E0736
|
||||
#![feature(track_caller)]
|
||||
|
||||
#[naked]
|
||||
#[track_caller]
|
||||
fn foo() {}
|
||||
```
|
||||
|
||||
This is primarily due to ABI incompatibilities between the two attributes.
|
||||
See [RFC 2091] for details on this and other limitations.
|
||||
|
||||
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
|
||||
"##,
|
||||
|
||||
E0738: r##"
|
||||
`#[track_caller]` cannot be used in traits yet. This is due to limitations in
|
||||
the compiler which are likely to be temporary. See [RFC 2091] for details on
|
||||
this and other restrictions.
|
||||
|
||||
Erroneous example with a trait method implementation:
|
||||
|
||||
```compile_fail,E0738
|
||||
#![feature(track_caller)]
|
||||
|
||||
trait Foo {
|
||||
fn bar(&self);
|
||||
}
|
||||
|
||||
impl Foo for u64 {
|
||||
#[track_caller]
|
||||
fn bar(&self) {}
|
||||
}
|
||||
```
|
||||
|
||||
Erroneous example with a blanket trait method implementation:
|
||||
|
||||
```compile_fail,E0738
|
||||
#![feature(track_caller)]
|
||||
|
||||
trait Foo {
|
||||
#[track_caller]
|
||||
fn bar(&self) {}
|
||||
fn baz(&self);
|
||||
}
|
||||
```
|
||||
|
||||
Erroneous example with a trait method declaration:
|
||||
|
||||
```compile_fail,E0738
|
||||
#![feature(track_caller)]
|
||||
|
||||
trait Foo {
|
||||
fn bar(&self) {}
|
||||
|
||||
#[track_caller]
|
||||
fn baz(&self);
|
||||
}
|
||||
```
|
||||
|
||||
Note that while the compiler may be able to support the attribute in traits in
|
||||
the future, [RFC 2091] prohibits their implementation without a follow-up RFC.
|
||||
|
||||
[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md
|
||||
"##,
|
||||
|
||||
;
|
||||
// E0006, // merged with E0005
|
||||
// E0101, // replaced with E0282
|
||||
// E0102, // replaced with E0282
|
||||
// E0134,
|
||||
// E0135,
|
||||
// E0272, // on_unimplemented #0
|
||||
// E0273, // on_unimplemented #1
|
||||
// E0274, // on_unimplemented #2
|
||||
// E0278, // requirement is not satisfied
|
||||
E0279, // requirement is not satisfied
|
||||
E0280, // requirement is not satisfied
|
||||
// E0285, // overflow evaluation builtin bounds
|
||||
// E0296, // replaced with a generic attribute input check
|
||||
// E0300, // unexpanded macro
|
||||
// E0304, // expected signed integer constant
|
||||
// E0305, // expected constant
|
||||
E0311, // thing may not live long enough
|
||||
E0313, // lifetime of borrowed pointer outlives lifetime of captured
|
||||
// variable
|
||||
E0314, // closure outlives stack frame
|
||||
E0315, // cannot invoke closure outside of its lifetime
|
||||
E0316, // nested quantification of lifetimes
|
||||
E0320, // recursive overflow during dropck
|
||||
E0473, // dereference of reference outside its lifetime
|
||||
E0474, // captured variable `..` does not outlive the enclosing closure
|
||||
E0475, // index of slice outside its lifetime
|
||||
E0476, // lifetime of the source pointer does not outlive lifetime bound...
|
||||
E0477, // the type `..` does not fulfill the required lifetime...
|
||||
E0479, // the type `..` (provided as the value of a type parameter) is...
|
||||
E0480, // lifetime of method receiver does not outlive the method call
|
||||
E0481, // lifetime of function argument does not outlive the function call
|
||||
E0482, // lifetime of return value does not outlive the function call
|
||||
E0483, // lifetime of operand does not outlive the operation
|
||||
E0484, // reference is not valid at the time of borrow
|
||||
E0485, // automatically reference is not valid at the time of borrow
|
||||
E0486, // type of expression contains references that are not valid during..
|
||||
E0487, // unsafe use of destructor: destructor might be called while...
|
||||
E0488, // lifetime of variable does not enclose its declaration
|
||||
E0489, // type/lifetime parameter not in scope here
|
||||
E0490, // a value of type `..` is borrowed for too long
|
||||
E0628, // generators cannot have explicit parameters
|
||||
E0631, // type mismatch in closure arguments
|
||||
E0637, // "'_" is not a valid lifetime bound
|
||||
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
|
||||
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
|
||||
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
|
||||
E0703, // invalid ABI
|
||||
// E0707, // multiple elided lifetimes used in arguments of `async fn`
|
||||
E0708, // `async` non-`move` closures with parameters are not currently
|
||||
// supported
|
||||
// E0709, // multiple different lifetimes used in arguments of `async fn`
|
||||
E0710, // an unknown tool name found in scoped lint
|
||||
E0711, // a feature has been declared with conflicting stability attributes
|
||||
// E0702, // replaced with a generic attribute input check
|
||||
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
|
||||
E0727, // `async` generators are not yet supported
|
||||
E0739, // invalid track_caller application/syntax
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
use syntax::{attr, symbol::sym};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
pub(crate) enum MethodKind {
|
||||
Trait { body: bool },
|
||||
|
||||
@@ -74,6 +74,8 @@
|
||||
use syntax_pos::hygiene::ExpnId;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
|
||||
|
||||
pub struct LoweringContext<'a> {
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
use syntax::source_map::{respan, DesugaringKind, Span, Spanned};
|
||||
use syntax::symbol::{sym, Symbol};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
impl LoweringContext<'_> {
|
||||
fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> HirVec<hir::Expr> {
|
||||
exprs.iter().map(|x| self.lower_expr(x)).collect()
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
use syntax::symbol::{kw, sym};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
pub(super) struct ItemLowerer<'tcx, 'interner> {
|
||||
pub(super) lctx: &'tcx mut LoweringContext<'interner>,
|
||||
}
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
use std::{cmp, fmt};
|
||||
use syntax_pos::{Pos, Span};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
mod note;
|
||||
|
||||
mod need_type_info;
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
use syntax_pos::Span;
|
||||
use errors::{Applicability, DiagnosticBuilder};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
struct FindLocalByTypeVisitor<'a, 'tcx> {
|
||||
infcx: &'a InferCtxt<'a, 'tcx>,
|
||||
target_ty: Ty<'tcx>,
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
use crate::infer::error_reporting::nice_region_error::util::AnonymousParamInfo;
|
||||
use crate::util::common::ErrorReported;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||
/// Print the error message for lifetime errors when both the concerned regions are anonymous.
|
||||
///
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
use crate::ty;
|
||||
use errors::{Applicability, DiagnosticBuilder};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||
/// When given a `ConcreteFailure` for a function with parameters containing a named region and
|
||||
/// an anonymous region, emit an descriptive diagnostic error.
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
use crate::ty::error::TypeError;
|
||||
use errors::DiagnosticBuilder;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub(super) fn note_region_origin(&self,
|
||||
err: &mut DiagnosticBuilder<'_>,
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
pub type OpaqueTypeMap<'tcx> = DefIdMap<OpaqueTypeDecl<'tcx>>;
|
||||
|
||||
/// Information about the opaque types whose values we
|
||||
|
||||
@@ -83,8 +83,6 @@
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
pub mod error_codes;
|
||||
|
||||
#[macro_use]
|
||||
pub mod query;
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
use syntax::visit as ast_visit;
|
||||
use syntax_pos::{MultiSpan, Span, symbol::Symbol};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
/// Information about the registered lints.
|
||||
///
|
||||
/// This is basically the subset of `Context` that we can
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
use syntax::source_map::MultiSpan;
|
||||
use syntax::symbol::{Symbol, sym};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
pub struct LintLevelSets {
|
||||
list: Vec<LintSet>,
|
||||
lint_cap: Level,
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
use crate::hir::itemlikevisit::ItemLikeVisitor;
|
||||
use crate::hir;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
// The actual lang items defined come at the end of this file in one handy table.
|
||||
// So you probably just want to nip down to the end.
|
||||
macro_rules! language_item_table {
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
use syntax_pos::{Span, sym};
|
||||
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
|
||||
use rustc_macros::HashStable;
|
||||
use errors::DiagnosticId;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
#[derive(HashStable)]
|
||||
pub struct LibFeatures {
|
||||
@@ -98,15 +99,16 @@ fn collect_feature(&mut self, feature: Symbol, since: Option<Symbol>, span: Span
|
||||
(Some(since), _, false) => {
|
||||
if let Some(prev_since) = self.lib_features.stable.get(&feature) {
|
||||
if *prev_since != since {
|
||||
let msg = format!(
|
||||
"feature `{}` is declared stable since {}, \
|
||||
but was previously declared stable since {}",
|
||||
feature,
|
||||
since,
|
||||
prev_since,
|
||||
self.span_feature_error(
|
||||
span,
|
||||
&format!(
|
||||
"feature `{}` is declared stable since {}, \
|
||||
but was previously declared stable since {}",
|
||||
feature,
|
||||
since,
|
||||
prev_since,
|
||||
),
|
||||
);
|
||||
self.tcx.sess.struct_span_err_with_code(span, &msg,
|
||||
DiagnosticId::Error("E0711".into())).emit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -117,17 +119,27 @@ fn collect_feature(&mut self, feature: Symbol, since: Option<Symbol>, span: Span
|
||||
self.lib_features.unstable.insert(feature);
|
||||
}
|
||||
(Some(_), _, true) | (None, true, _) => {
|
||||
let msg = format!(
|
||||
"feature `{}` is declared {}, but was previously declared {}",
|
||||
feature,
|
||||
if since.is_some() { "stable" } else { "unstable" },
|
||||
if since.is_none() { "stable" } else { "unstable" },
|
||||
self.span_feature_error(
|
||||
span,
|
||||
&format!(
|
||||
"feature `{}` is declared {}, but was previously declared {}",
|
||||
feature,
|
||||
if since.is_some() { "stable" } else { "unstable" },
|
||||
if since.is_none() { "stable" } else { "unstable" },
|
||||
),
|
||||
);
|
||||
self.tcx.sess.struct_span_err_with_code(span, &msg,
|
||||
DiagnosticId::Error("E0711".into())).emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn span_feature_error(&self, span: Span, msg: &str) {
|
||||
struct_span_err!(
|
||||
self.tcx.sess,
|
||||
span,
|
||||
E0711,
|
||||
"{}", &msg,
|
||||
).emit();
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor<'tcx> for LibFeatureCollector<'tcx> {
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
use crate::hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use crate::hir::{self, GenericParamKind, LifetimeParamKind};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
/// The origin of a named lifetime definition.
|
||||
///
|
||||
/// This is used to prevent the usage of in-band lifetimes in `Fn`/`fn` syntax.
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
use std::mem::replace;
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
|
||||
#[derive(PartialEq, Clone, Copy, Debug)]
|
||||
pub enum StabilityLevel {
|
||||
Unstable,
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
use crate::hir;
|
||||
use crate::ty::TyCtxt;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
macro_rules! weak_lang_items {
|
||||
($($name:ident, $item:ident, $sym:ident;)*) => (
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
use std::{fmt, env};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable, RustcEncodable, RustcDecodable)]
|
||||
pub enum ErrorHandled {
|
||||
/// Already reported a lint or an error for this evaluation.
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
use syntax::symbol::{sym, kw};
|
||||
use syntax_pos::{DUMMY_SP, Span, ExpnKind, MultiSpan};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
pub fn report_fulfillment_errors(
|
||||
&self,
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
use syntax::symbol::{Symbol, kw, sym};
|
||||
use syntax_pos::Span;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct OnUnimplementedFormatString(Symbol);
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
use crate::ty::subst::GenericArg;
|
||||
use crate::ty::{self, Ty, TyCtxt};
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
impl<'cx, 'tcx> At<'cx, 'tcx> {
|
||||
/// Given a type `ty` of some value being dropped, computes a set
|
||||
/// of "kinds" (types, regions) that must be outlive the execution
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
use super::{SelectionContext, FulfillmentContext};
|
||||
use super::util::impl_trait_ref_and_oblig;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
/// Information pertinent to an overlapping impl error.
|
||||
#[derive(Debug)]
|
||||
pub struct OverlapError {
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
use syntax_pos::Span;
|
||||
use syntax::source_map::DUMMY_SP;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
pub struct QueryCache<'tcx, D: QueryConfig<'tcx> + ?Sized> {
|
||||
pub(super) results: FxHashMap<D::Key, QueryValue<D::Value>>,
|
||||
pub(super) active: FxHashMap<D::Key, QueryResult<'tcx>>,
|
||||
|
||||
@@ -31,3 +31,4 @@ rustc_fs_util = { path = "../librustc_fs_util" }
|
||||
rustc_incremental = { path = "../librustc_incremental" }
|
||||
rustc_index = { path = "../librustc_index" }
|
||||
rustc_target = { path = "../librustc_target" }
|
||||
rustc_error_codes = { path = "../librustc_error_codes" }
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
use rustc::hir;
|
||||
use crate::traits::BuilderMethods;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
pub enum IntPredicate {
|
||||
IntEQ,
|
||||
IntNE,
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
syntax::register_diagnostics! {
|
||||
|
||||
E0511: r##"
|
||||
Invalid monomorphization of an intrinsic function was used. Erroneous code
|
||||
example:
|
||||
|
||||
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
|
||||
#![feature(platform_intrinsics)]
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
fn simd_add<T>(a: T, b: T) -> T;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
unsafe { simd_add(0, 1); }
|
||||
// error: invalid monomorphization of `simd_add` intrinsic
|
||||
}
|
||||
```
|
||||
|
||||
The generic type has to be a SIMD type. Example:
|
||||
|
||||
```
|
||||
#![feature(repr_simd)]
|
||||
#![feature(platform_intrinsics)]
|
||||
|
||||
#[repr(simd)]
|
||||
#[derive(Copy, Clone)]
|
||||
struct i32x2(i32, i32);
|
||||
|
||||
extern "platform-intrinsic" {
|
||||
fn simd_add<T>(a: T, b: T) -> T;
|
||||
}
|
||||
|
||||
unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok!
|
||||
```
|
||||
"##,
|
||||
|
||||
E0668: r##"
|
||||
Malformed inline assembly rejected by LLVM.
|
||||
|
||||
LLVM checks the validity of the constraints and the assembly string passed to
|
||||
it. This error implies that LLVM seems something wrong with the inline
|
||||
assembly call.
|
||||
|
||||
In particular, it can happen if you forgot the closing bracket of a register
|
||||
constraint (see issue #51430):
|
||||
```ignore (error-emitted-at-codegen-which-cannot-be-handled-by-compile_fail)
|
||||
#![feature(asm)]
|
||||
|
||||
fn main() {
|
||||
let rax: u64;
|
||||
unsafe {
|
||||
asm!("" :"={rax"(rax));
|
||||
println!("Accumulator is: {}", rax);
|
||||
}
|
||||
}
|
||||
```
|
||||
"##,
|
||||
|
||||
E0669: r##"
|
||||
Cannot convert inline assembly operand to a single LLVM value.
|
||||
|
||||
This error usually happens when trying to pass in a value to an input inline
|
||||
assembly operand that is actually a pair of values. In particular, this can
|
||||
happen when trying to pass in a slice, for instance a `&str`. In Rust, these
|
||||
values are represented internally as a pair of values, the pointer and its
|
||||
length. When passed as an input operand, this pair of values can not be
|
||||
coerced into a register and thus we must fail with an error.
|
||||
"##,
|
||||
|
||||
}
|
||||
@@ -35,8 +35,6 @@
|
||||
use rustc::middle::dependency_format::Dependencies;
|
||||
use syntax_pos::symbol::Symbol;
|
||||
|
||||
mod error_codes;
|
||||
|
||||
pub mod common;
|
||||
pub mod traits;
|
||||
pub mod mir;
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
use super::OperandValue;
|
||||
use crate::traits::*;
|
||||
|
||||
use rustc_error_codes::*;
|
||||
|
||||
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
pub fn codegen_statement(
|
||||
&mut self,
|
||||
|
||||
@@ -524,13 +524,13 @@ fn handle_explain(code: &str,
|
||||
let mut text = String::new();
|
||||
|
||||
// Slice off the leading newline and print.
|
||||
for line in description[1..].lines() {
|
||||
for line in description.lines() {
|
||||
let indent_level = line.find(|c: char| !c.is_whitespace())
|
||||
.unwrap_or_else(|| line.len());
|
||||
let dedented_line = &line[indent_level..];
|
||||
if dedented_line.starts_with("```") {
|
||||
is_in_code_block = !is_in_code_block;
|
||||
text.push_str(&line[..(indent_level+3)]);
|
||||
text.push_str(&line[..(indent_level + 3)]);
|
||||
} else if is_in_code_block && dedented_line.starts_with("# ") {
|
||||
continue;
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
authors = ["The Rust Project Developers"]
|
||||
name = "rustc_error_codes"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "rustc_error_codes"
|
||||
path = "lib.rs"
|
||||
@@ -0,0 +1,609 @@
|
||||
// Error messages for EXXXX errors. Each message should start and end with a
|
||||
// new line, and be wrapped to 80 characters. In vim you can `:set tw=80` and
|
||||
// use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
|
||||
|
||||
crate::register_diagnostics! {
|
||||
|
||||
E0001: include_str!("./error_codes/E0001.md"),
|
||||
E0002: include_str!("./error_codes/E0002.md"),
|
||||
E0004: include_str!("./error_codes/E0004.md"),
|
||||
E0005: include_str!("./error_codes/E0005.md"),
|
||||
E0007: include_str!("./error_codes/E0007.md"),
|
||||
E0009: include_str!("./error_codes/E0009.md"),
|
||||
E0010: include_str!("./error_codes/E0010.md"),
|
||||
E0013: include_str!("./error_codes/E0013.md"),
|
||||
E0014: include_str!("./error_codes/E0014.md"),
|
||||
E0015: include_str!("./error_codes/E0015.md"),
|
||||
E0017: include_str!("./error_codes/E0017.md"),
|
||||
E0019: include_str!("./error_codes/E0019.md"),
|
||||
E0023: include_str!("./error_codes/E0023.md"),
|
||||
E0025: include_str!("./error_codes/E0025.md"),
|
||||
E0026: include_str!("./error_codes/E0026.md"),
|
||||
E0027: include_str!("./error_codes/E0027.md"),
|
||||
E0029: include_str!("./error_codes/E0029.md"),
|
||||
E0030: include_str!("./error_codes/E0030.md"),
|
||||
E0033: include_str!("./error_codes/E0033.md"),
|
||||
E0034: include_str!("./error_codes/E0034.md"),
|
||||
E0038: include_str!("./error_codes/E0038.md"),
|
||||
E0040: include_str!("./error_codes/E0040.md"),
|
||||
E0044: include_str!("./error_codes/E0044.md"),
|
||||
E0045: include_str!("./error_codes/E0045.md"),
|
||||
E0046: include_str!("./error_codes/E0046.md"),
|
||||
E0049: include_str!("./error_codes/E0049.md"),
|
||||
E0050: include_str!("./error_codes/E0050.md"),
|
||||
E0053: include_str!("./error_codes/E0053.md"),
|
||||
E0054: include_str!("./error_codes/E0054.md"),
|
||||
E0055: include_str!("./error_codes/E0055.md"),
|
||||
E0057: include_str!("./error_codes/E0057.md"),
|
||||
E0059: include_str!("./error_codes/E0059.md"),
|
||||
E0060: include_str!("./error_codes/E0060.md"),
|
||||
E0061: include_str!("./error_codes/E0061.md"),
|
||||
E0062: include_str!("./error_codes/E0062.md"),
|
||||
E0063: include_str!("./error_codes/E0063.md"),
|
||||
E0067: include_str!("./error_codes/E0067.md"),
|
||||
E0069: include_str!("./error_codes/E0069.md"),
|
||||
E0070: include_str!("./error_codes/E0070.md"),
|
||||
E0071: include_str!("./error_codes/E0071.md"),
|
||||
E0072: include_str!("./error_codes/E0072.md"),
|
||||
E0073: include_str!("./error_codes/E0073.md"),
|
||||
E0074: include_str!("./error_codes/E0074.md"),
|
||||
E0075: include_str!("./error_codes/E0075.md"),
|
||||
E0076: include_str!("./error_codes/E0076.md"),
|
||||
E0077: include_str!("./error_codes/E0077.md"),
|
||||
E0080: include_str!("./error_codes/E0080.md"),
|
||||
E0081: include_str!("./error_codes/E0081.md"),
|
||||
E0084: include_str!("./error_codes/E0084.md"),
|
||||
E0087: include_str!("./error_codes/E0087.md"),
|
||||
E0088: include_str!("./error_codes/E0088.md"),
|
||||
E0089: include_str!("./error_codes/E0089.md"),
|
||||
E0090: include_str!("./error_codes/E0090.md"),
|
||||
E0091: include_str!("./error_codes/E0091.md"),
|
||||
E0092: include_str!("./error_codes/E0092.md"),
|
||||
E0093: include_str!("./error_codes/E0093.md"),
|
||||
E0094: include_str!("./error_codes/E0094.md"),
|
||||
E0106: include_str!("./error_codes/E0106.md"),
|
||||
E0107: include_str!("./error_codes/E0107.md"),
|
||||
E0109: include_str!("./error_codes/E0109.md"),
|
||||
E0110: include_str!("./error_codes/E0110.md"),
|
||||
E0116: include_str!("./error_codes/E0116.md"),
|
||||
E0117: include_str!("./error_codes/E0117.md"),
|
||||
E0118: include_str!("./error_codes/E0118.md"),
|
||||
E0119: include_str!("./error_codes/E0119.md"),
|
||||
E0120: include_str!("./error_codes/E0120.md"),
|
||||
E0121: include_str!("./error_codes/E0121.md"),
|
||||
E0124: include_str!("./error_codes/E0124.md"),
|
||||
E0128: include_str!("./error_codes/E0128.md"),
|
||||
E0130: include_str!("./error_codes/E0130.md"),
|
||||
E0131: include_str!("./error_codes/E0131.md"),
|
||||
E0132: include_str!("./error_codes/E0132.md"),
|
||||
E0133: include_str!("./error_codes/E0133.md"),
|
||||
E0136: include_str!("./error_codes/E0136.md"),
|
||||
E0137: include_str!("./error_codes/E0137.md"),
|
||||
E0138: include_str!("./error_codes/E0138.md"),
|
||||
E0139: include_str!("./error_codes/E0139.md"),
|
||||
E0152: include_str!("./error_codes/E0152.md"),
|
||||
E0154: include_str!("./error_codes/E0154.md"),
|
||||
E0158: include_str!("./error_codes/E0158.md"),
|
||||
E0161: include_str!("./error_codes/E0161.md"),
|
||||
E0162: include_str!("./error_codes/E0162.md"),
|
||||
E0164: include_str!("./error_codes/E0164.md"),
|
||||
E0165: include_str!("./error_codes/E0165.md"),
|
||||
E0170: include_str!("./error_codes/E0170.md"),
|
||||
E0178: include_str!("./error_codes/E0178.md"),
|
||||
E0184: include_str!("./error_codes/E0184.md"),
|
||||
E0185: include_str!("./error_codes/E0185.md"),
|
||||
E0186: include_str!("./error_codes/E0186.md"),
|
||||
E0191: include_str!("./error_codes/E0191.md"),
|
||||
E0192: include_str!("./error_codes/E0192.md"),
|
||||
E0193: include_str!("./error_codes/E0193.md"),
|
||||
E0195: include_str!("./error_codes/E0195.md"),
|
||||
E0197: include_str!("./error_codes/E0197.md"),
|
||||
E0198: include_str!("./error_codes/E0198.md"),
|
||||
E0199: include_str!("./error_codes/E0199.md"),
|
||||
E0200: include_str!("./error_codes/E0200.md"),
|
||||
E0201: include_str!("./error_codes/E0201.md"),
|
||||
E0202: include_str!("./error_codes/E0202.md"),
|
||||
E0204: include_str!("./error_codes/E0204.md"),
|
||||
E0205: include_str!("./error_codes/E0205.md"),
|
||||
E0206: include_str!("./error_codes/E0206.md"),
|
||||
E0207: include_str!("./error_codes/E0207.md"),
|
||||
E0210: include_str!("./error_codes/E0210.md"),
|
||||
E0211: include_str!("./error_codes/E0211.md"),
|
||||
E0214: include_str!("./error_codes/E0214.md"),
|
||||
E0220: include_str!("./error_codes/E0220.md"),
|
||||
E0221: include_str!("./error_codes/E0221.md"),
|
||||
E0223: include_str!("./error_codes/E0223.md"),
|
||||
E0225: include_str!("./error_codes/E0225.md"),
|
||||
E0229: include_str!("./error_codes/E0229.md"),
|
||||
E0230: include_str!("./error_codes/E0230.md"),
|
||||
E0231: include_str!("./error_codes/E0231.md"),
|
||||
E0232: include_str!("./error_codes/E0232.md"),
|
||||
E0243: include_str!("./error_codes/E0243.md"),
|
||||
E0244: include_str!("./error_codes/E0244.md"),
|
||||
E0251: include_str!("./error_codes/E0251.md"),
|
||||
E0252: include_str!("./error_codes/E0252.md"),
|
||||
E0253: include_str!("./error_codes/E0253.md"),
|
||||
E0254: include_str!("./error_codes/E0254.md"),
|
||||
E0255: include_str!("./error_codes/E0255.md"),
|
||||
E0256: include_str!("./error_codes/E0256.md"),
|
||||
E0259: include_str!("./error_codes/E0259.md"),
|
||||
E0260: include_str!("./error_codes/E0260.md"),
|
||||
E0261: include_str!("./error_codes/E0261.md"),
|
||||
E0262: include_str!("./error_codes/E0262.md"),
|
||||
E0263: include_str!("./error_codes/E0263.md"),
|
||||
E0264: include_str!("./error_codes/E0264.md"),
|
||||
E0267: include_str!("./error_codes/E0267.md"),
|
||||
E0268: include_str!("./error_codes/E0268.md"),
|
||||
E0271: include_str!("./error_codes/E0271.md"),
|
||||
E0275: include_str!("./error_codes/E0275.md"),
|
||||
E0276: include_str!("./error_codes/E0276.md"),
|
||||
E0277: include_str!("./error_codes/E0277.md"),
|
||||
E0281: include_str!("./error_codes/E0281.md"),
|
||||
E0282: include_str!("./error_codes/E0282.md"),
|
||||
E0283: include_str!("./error_codes/E0283.md"),
|
||||
E0284: include_str!("./error_codes/E0284.md"),
|
||||
E0297: include_str!("./error_codes/E0297.md"),
|
||||
E0301: include_str!("./error_codes/E0301.md"),
|
||||
E0302: include_str!("./error_codes/E0302.md"),
|
||||
E0303: include_str!("./error_codes/E0303.md"),
|
||||
E0307: include_str!("./error_codes/E0307.md"),
|
||||
E0308: include_str!("./error_codes/E0308.md"),
|
||||
E0309: include_str!("./error_codes/E0309.md"),
|
||||
E0310: include_str!("./error_codes/E0310.md"),
|
||||
E0312: include_str!("./error_codes/E0312.md"),
|
||||
E0317: include_str!("./error_codes/E0317.md"),
|
||||
E0321: include_str!("./error_codes/E0321.md"),
|
||||
E0322: include_str!("./error_codes/E0322.md"),
|
||||
E0323: include_str!("./error_codes/E0323.md"),
|
||||
E0324: include_str!("./error_codes/E0324.md"),
|
||||
E0325: include_str!("./error_codes/E0325.md"),
|
||||
E0326: include_str!("./error_codes/E0326.md"),
|
||||
E0328: include_str!("./error_codes/E0328.md"),
|
||||
E0329: include_str!("./error_codes/E0329.md"),
|
||||
E0364: include_str!("./error_codes/E0364.md"),
|
||||
E0365: include_str!("./error_codes/E0365.md"),
|
||||
E0366: include_str!("./error_codes/E0366.md"),
|
||||
E0367: include_str!("./error_codes/E0367.md"),
|
||||
E0368: include_str!("./error_codes/E0368.md"),
|
||||
E0369: include_str!("./error_codes/E0369.md"),
|
||||
E0370: include_str!("./error_codes/E0370.md"),
|
||||
E0371: include_str!("./error_codes/E0371.md"),
|
||||
E0373: include_str!("./error_codes/E0373.md"),
|
||||
E0374: include_str!("./error_codes/E0374.md"),
|
||||
E0375: include_str!("./error_codes/E0375.md"),
|
||||
E0376: include_str!("./error_codes/E0376.md"),
|
||||
E0378: include_str!("./error_codes/E0378.md"),
|
||||
E0379: include_str!("./error_codes/E0379.md"),
|
||||
E0380: include_str!("./error_codes/E0380.md"),
|
||||
E0381: include_str!("./error_codes/E0381.md"),
|
||||
E0382: include_str!("./error_codes/E0382.md"),
|
||||
E0383: include_str!("./error_codes/E0383.md"),
|
||||
E0384: include_str!("./error_codes/E0384.md"),
|
||||
E0386: include_str!("./error_codes/E0386.md"),
|
||||
E0387: include_str!("./error_codes/E0387.md"),
|
||||
E0388: include_str!("./error_codes/E0388.md"),
|
||||
E0389: include_str!("./error_codes/E0389.md"),
|
||||
E0390: include_str!("./error_codes/E0390.md"),
|
||||
E0391: include_str!("./error_codes/E0391.md"),
|
||||
E0392: include_str!("./error_codes/E0392.md"),
|
||||
E0393: include_str!("./error_codes/E0393.md"),
|
||||
E0398: include_str!("./error_codes/E0398.md"),
|
||||
E0399: include_str!("./error_codes/E0399.md"),
|
||||
E0401: include_str!("./error_codes/E0401.md"),
|
||||
E0403: include_str!("./error_codes/E0403.md"),
|
||||
E0404: include_str!("./error_codes/E0404.md"),
|
||||
E0405: include_str!("./error_codes/E0405.md"),
|
||||
E0407: include_str!("./error_codes/E0407.md"),
|
||||
E0408: include_str!("./error_codes/E0408.md"),
|
||||
E0409: include_str!("./error_codes/E0409.md"),
|
||||
E0411: include_str!("./error_codes/E0411.md"),
|
||||
E0412: include_str!("./error_codes/E0412.md"),
|
||||
E0415: include_str!("./error_codes/E0415.md"),
|
||||
E0416: include_str!("./error_codes/E0416.md"),
|
||||
E0422: include_str!("./error_codes/E0422.md"),
|
||||
E0423: include_str!("./error_codes/E0423.md"),
|
||||
E0424: include_str!("./error_codes/E0424.md"),
|
||||
E0425: include_str!("./error_codes/E0425.md"),
|
||||
E0426: include_str!("./error_codes/E0426.md"),
|
||||
E0428: include_str!("./error_codes/E0428.md"),
|
||||
E0429: include_str!("./error_codes/E0429.md"),
|
||||
E0430: include_str!("./error_codes/E0430.md"),
|
||||
E0431: include_str!("./error_codes/E0431.md"),
|
||||
E0432: include_str!("./error_codes/E0432.md"),
|
||||
E0433: include_str!("./error_codes/E0433.md"),
|
||||
E0434: include_str!("./error_codes/E0434.md"),
|
||||
E0435: include_str!("./error_codes/E0435.md"),
|
||||
E0436: include_str!("./error_codes/E0436.md"),
|
||||
E0437: include_str!("./error_codes/E0437.md"),
|
||||
E0438: include_str!("./error_codes/E0438.md"),
|
||||
E0439: include_str!("./error_codes/E0439.md"),
|
||||
E0445: include_str!("./error_codes/E0445.md"),
|
||||
E0446: include_str!("./error_codes/E0446.md"),
|
||||
E0447: include_str!("./error_codes/E0447.md"),
|
||||
E0448: include_str!("./error_codes/E0448.md"),
|
||||
E0449: include_str!("./error_codes/E0449.md"),
|
||||
E0451: include_str!("./error_codes/E0451.md"),
|
||||
E0452: include_str!("./error_codes/E0452.md"),
|
||||
E0453: include_str!("./error_codes/E0453.md"),
|
||||
E0454: include_str!("./error_codes/E0454.md"),
|
||||
E0455: include_str!("./error_codes/E0455.md"),
|
||||
E0458: include_str!("./error_codes/E0458.md"),
|
||||
E0459: include_str!("./error_codes/E0459.md"),
|
||||
E0463: include_str!("./error_codes/E0463.md"),
|
||||
E0466: include_str!("./error_codes/E0466.md"),
|
||||
E0468: include_str!("./error_codes/E0468.md"),
|
||||
E0469: include_str!("./error_codes/E0469.md"),
|
||||
E0478: include_str!("./error_codes/E0478.md"),
|
||||
E0491: include_str!("./error_codes/E0491.md"),
|
||||
E0492: include_str!("./error_codes/E0492.md"),
|
||||
E0493: include_str!("./error_codes/E0493.md"),
|
||||
E0495: include_str!("./error_codes/E0495.md"),
|
||||
E0496: include_str!("./error_codes/E0496.md"),
|
||||
E0497: include_str!("./error_codes/E0497.md"),
|
||||
E0499: include_str!("./error_codes/E0499.md"),
|
||||
E0500: include_str!("./error_codes/E0500.md"),
|
||||
E0501: include_str!("./error_codes/E0501.md"),
|
||||
E0502: include_str!("./error_codes/E0502.md"),
|
||||
E0503: include_str!("./error_codes/E0503.md"),
|
||||
E0504: include_str!("./error_codes/E0504.md"),
|
||||
E0505: include_str!("./error_codes/E0505.md"),
|
||||
E0506: include_str!("./error_codes/E0506.md"),
|
||||
E0507: include_str!("./error_codes/E0507.md"),
|
||||
E0508: include_str!("./error_codes/E0508.md"),
|
||||
E0509: include_str!("./error_codes/E0509.md"),
|
||||
E0510: include_str!("./error_codes/E0510.md"),
|
||||
E0511: include_str!("./error_codes/E0511.md"),
|
||||
E0512: include_str!("./error_codes/E0512.md"),
|
||||
E0515: include_str!("./error_codes/E0515.md"),
|
||||
E0516: include_str!("./error_codes/E0516.md"),
|
||||
E0517: include_str!("./error_codes/E0517.md"),
|
||||
E0518: include_str!("./error_codes/E0518.md"),
|
||||
E0520: include_str!("./error_codes/E0520.md"),
|
||||
E0522: include_str!("./error_codes/E0522.md"),
|
||||
E0524: include_str!("./error_codes/E0524.md"),
|
||||
E0525: include_str!("./error_codes/E0525.md"),
|
||||
E0527: include_str!("./error_codes/E0527.md"),
|
||||
E0528: include_str!("./error_codes/E0528.md"),
|
||||
E0529: include_str!("./error_codes/E0529.md"),
|
||||
E0530: include_str!("./error_codes/E0530.md"),
|
||||
E0531: include_str!("./error_codes/E0531.md"),
|
||||
E0532: include_str!("./error_codes/E0532.md"),
|
||||
E0533: include_str!("./error_codes/E0533.md"),
|
||||
E0534: include_str!("./error_codes/E0534.md"),
|
||||
E0535: include_str!("./error_codes/E0535.md"),
|
||||
E0536: include_str!("./error_codes/E0536.md"),
|
||||
E0537: include_str!("./error_codes/E0537.md"),
|
||||
E0538: include_str!("./error_codes/E0538.md"),
|
||||
E0541: include_str!("./error_codes/E0541.md"),
|
||||
E0550: include_str!("./error_codes/E0550.md"),
|
||||
E0551: include_str!("./error_codes/E0551.md"),
|
||||
E0552: include_str!("./error_codes/E0552.md"),
|
||||
E0554: include_str!("./error_codes/E0554.md"),
|
||||
E0556: include_str!("./error_codes/E0556.md"),
|
||||
E0557: include_str!("./error_codes/E0557.md"),
|
||||
E0559: include_str!("./error_codes/E0559.md"),
|
||||
E0560: include_str!("./error_codes/E0560.md"),
|
||||
E0561: include_str!("./error_codes/E0561.md"),
|
||||
E0562: include_str!("./error_codes/E0562.md"),
|
||||
E0565: include_str!("./error_codes/E0565.md"),
|
||||
E0566: include_str!("./error_codes/E0566.md"),
|
||||
E0567: include_str!("./error_codes/E0567.md"),
|
||||
E0568: include_str!("./error_codes/E0568.md"),
|
||||
E0569: include_str!("./error_codes/E0569.md"),
|
||||
E0570: include_str!("./error_codes/E0570.md"),
|
||||
E0571: include_str!("./error_codes/E0571.md"),
|
||||
E0572: include_str!("./error_codes/E0572.md"),
|
||||
E0573: include_str!("./error_codes/E0573.md"),
|
||||
E0574: include_str!("./error_codes/E0574.md"),
|
||||
E0575: include_str!("./error_codes/E0575.md"),
|
||||
E0576: include_str!("./error_codes/E0576.md"),
|
||||
E0577: include_str!("./error_codes/E0577.md"),
|
||||
E0578: include_str!("./error_codes/E0578.md"),
|
||||
E0579: include_str!("./error_codes/E0579.md"),
|
||||
E0580: include_str!("./error_codes/E0580.md"),
|
||||
E0581: include_str!("./error_codes/E0581.md"),
|
||||
E0582: include_str!("./error_codes/E0582.md"),
|
||||
E0583: include_str!("./error_codes/E0583.md"),
|
||||
E0584: include_str!("./error_codes/E0584.md"),
|
||||
E0585: include_str!("./error_codes/E0585.md"),
|
||||
E0586: include_str!("./error_codes/E0586.md"),
|
||||
E0587: include_str!("./error_codes/E0587.md"),
|
||||
E0588: include_str!("./error_codes/E0588.md"),
|
||||
E0589: include_str!("./error_codes/E0589.md"),
|
||||
E0590: include_str!("./error_codes/E0590.md"),
|
||||
E0591: include_str!("./error_codes/E0591.md"),
|
||||
E0592: include_str!("./error_codes/E0592.md"),
|
||||
E0593: include_str!("./error_codes/E0593.md"),
|
||||
E0595: include_str!("./error_codes/E0595.md"),
|
||||
E0596: include_str!("./error_codes/E0596.md"),
|
||||
E0597: include_str!("./error_codes/E0597.md"),
|
||||
E0599: include_str!("./error_codes/E0599.md"),
|
||||
E0600: include_str!("./error_codes/E0600.md"),
|
||||
E0601: include_str!("./error_codes/E0601.md"),
|
||||
E0602: include_str!("./error_codes/E0602.md"),
|
||||
E0603: include_str!("./error_codes/E0603.md"),
|
||||
E0604: include_str!("./error_codes/E0604.md"),
|
||||
E0605: include_str!("./error_codes/E0605.md"),
|
||||
E0606: include_str!("./error_codes/E0606.md"),
|
||||
E0607: include_str!("./error_codes/E0607.md"),
|
||||
E0608: include_str!("./error_codes/E0608.md"),
|
||||
E0609: include_str!("./error_codes/E0609.md"),
|
||||
E0610: include_str!("./error_codes/E0610.md"),
|
||||
E0614: include_str!("./error_codes/E0614.md"),
|
||||
E0615: include_str!("./error_codes/E0615.md"),
|
||||
E0616: include_str!("./error_codes/E0616.md"),
|
||||
E0617: include_str!("./error_codes/E0617.md"),
|
||||
E0618: include_str!("./error_codes/E0618.md"),
|
||||
E0619: include_str!("./error_codes/E0619.md"),
|
||||
E0620: include_str!("./error_codes/E0620.md"),
|
||||
E0621: include_str!("./error_codes/E0621.md"),
|
||||
E0622: include_str!("./error_codes/E0622.md"),
|
||||
E0623: include_str!("./error_codes/E0623.md"),
|
||||
E0624: include_str!("./error_codes/E0624.md"),
|
||||
E0626: include_str!("./error_codes/E0626.md"),
|
||||
E0633: include_str!("./error_codes/E0633.md"),
|
||||
E0635: include_str!("./error_codes/E0635.md"),
|
||||
E0636: include_str!("./error_codes/E0636.md"),
|
||||
E0638: include_str!("./error_codes/E0638.md"),
|
||||
E0639: include_str!("./error_codes/E0639.md"),
|
||||
E0642: include_str!("./error_codes/E0642.md"),
|
||||
E0643: include_str!("./error_codes/E0643.md"),
|
||||
E0644: include_str!("./error_codes/E0644.md"),
|
||||
E0646: include_str!("./error_codes/E0646.md"),
|
||||
E0647: include_str!("./error_codes/E0647.md"),
|
||||
E0648: include_str!("./error_codes/E0648.md"),
|
||||
E0658: include_str!("./error_codes/E0658.md"),
|
||||
E0659: include_str!("./error_codes/E0659.md"),
|
||||
E0660: include_str!("./error_codes/E0660.md"),
|
||||
E0661: include_str!("./error_codes/E0661.md"),
|
||||
E0662: include_str!("./error_codes/E0662.md"),
|
||||
E0663: include_str!("./error_codes/E0663.md"),
|
||||
E0664: include_str!("./error_codes/E0664.md"),
|
||||
E0665: include_str!("./error_codes/E0665.md"),
|
||||
E0666: include_str!("./error_codes/E0666.md"),
|
||||
E0668: include_str!("./error_codes/E0668.md"),
|
||||
E0669: include_str!("./error_codes/E0669.md"),
|
||||
E0670: include_str!("./error_codes/E0670.md"),
|
||||
E0671: include_str!("./error_codes/E0671.md"),
|
||||
E0689: include_str!("./error_codes/E0689.md"),
|
||||
E0690: include_str!("./error_codes/E0690.md"),
|
||||
E0691: include_str!("./error_codes/E0691.md"),
|
||||
E0692: include_str!("./error_codes/E0692.md"),
|
||||
E0695: include_str!("./error_codes/E0695.md"),
|
||||
E0697: include_str!("./error_codes/E0697.md"),
|
||||
E0698: include_str!("./error_codes/E0698.md"),
|
||||
E0699: include_str!("./error_codes/E0699.md"),
|
||||
E0700: include_str!("./error_codes/E0700.md"),
|
||||
E0701: include_str!("./error_codes/E0701.md"),
|
||||
E0704: include_str!("./error_codes/E0704.md"),
|
||||
E0705: include_str!("./error_codes/E0705.md"),
|
||||
E0712: include_str!("./error_codes/E0712.md"),
|
||||
E0713: include_str!("./error_codes/E0713.md"),
|
||||
E0714: include_str!("./error_codes/E0714.md"),
|
||||
E0715: include_str!("./error_codes/E0715.md"),
|
||||
E0716: include_str!("./error_codes/E0716.md"),
|
||||
E0718: include_str!("./error_codes/E0718.md"),
|
||||
E0720: include_str!("./error_codes/E0720.md"),
|
||||
E0723: include_str!("./error_codes/E0723.md"),
|
||||
E0725: include_str!("./error_codes/E0725.md"),
|
||||
E0728: include_str!("./error_codes/E0728.md"),
|
||||
E0729: include_str!("./error_codes/E0729.md"),
|
||||
E0730: include_str!("./error_codes/E0730.md"),
|
||||
E0731: include_str!("./error_codes/E0731.md"),
|
||||
E0732: include_str!("./error_codes/E0732.md"),
|
||||
E0733: include_str!("./error_codes/E0733.md"),
|
||||
E0734: include_str!("./error_codes/E0734.md"),
|
||||
E0735: include_str!("./error_codes/E0735.md"),
|
||||
E0736: include_str!("./error_codes/E0736.md"),
|
||||
E0737: include_str!("./error_codes/E0737.md"),
|
||||
E0738: include_str!("./error_codes/E0738.md"),
|
||||
E0740: include_str!("./error_codes/E0740.md"),
|
||||
E0741: include_str!("./error_codes/E0741.md"),
|
||||
E0742: include_str!("./error_codes/E0742.md"),
|
||||
E0743: include_str!("./error_codes/E0743.md"),
|
||||
E0744: include_str!("./error_codes/E0744.md"),
|
||||
;
|
||||
// E0006, // merged with E0005
|
||||
// E0008, // cannot bind by-move into a pattern guard
|
||||
// E0035, merged into E0087/E0089
|
||||
// E0036, merged into E0087/E0089
|
||||
// E0068,
|
||||
// E0085,
|
||||
// E0086,
|
||||
// E0101, // replaced with E0282
|
||||
// E0102, // replaced with E0282
|
||||
// E0103,
|
||||
// E0104,
|
||||
// E0122, // bounds in type aliases are ignored, turned into proper lint
|
||||
// E0123,
|
||||
// E0127,
|
||||
// E0129,
|
||||
// E0134,
|
||||
// E0135,
|
||||
// E0141,
|
||||
// E0153, unused error code
|
||||
// E0157, unused error code
|
||||
// E0159, // use of trait `{}` as struct constructor
|
||||
// E0163, // merged into E0071
|
||||
// E0167,
|
||||
// E0168,
|
||||
// E0172, // non-trait found in a type sum, moved to resolve
|
||||
// E0173, // manual implementations of unboxed closure traits are experimental
|
||||
// E0174,
|
||||
// E0182, // merged into E0229
|
||||
E0183,
|
||||
// E0187, // cannot infer the kind of the closure
|
||||
// E0188, // can not cast an 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
|
||||
// E0194, // merged into E0403
|
||||
// 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
|
||||
// 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
|
||||
// E0222, // Error code E0045 (variadic function must have C or cdecl 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
|
||||
// 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,
|
||||
// E0245, // not a trait
|
||||
// E0246, // invalid recursive type
|
||||
// E0247,
|
||||
// E0248, // value used as a type, now reported earlier during resolution
|
||||
// as E0412
|
||||
// E0249,
|
||||
// E0257,
|
||||
// E0258,
|
||||
// E0272, // on_unimplemented #0
|
||||
// E0273, // on_unimplemented #1
|
||||
// E0274, // on_unimplemented #2
|
||||
// E0278, // requirement is not satisfied
|
||||
E0279, // requirement is not satisfied
|
||||
E0280, // requirement is not satisfied
|
||||
// E0285, // overflow evaluation builtin bounds
|
||||
// E0296, // replaced with a generic attribute input check
|
||||
// E0298, // cannot compare constants
|
||||
// E0299, // mismatched types between arms
|
||||
// E0300, // unexpanded macro
|
||||
// E0304, // expected signed integer constant
|
||||
// E0305, // expected constant
|
||||
E0311, // thing may not live long enough
|
||||
E0313, // lifetime of borrowed pointer outlives lifetime of captured
|
||||
// variable
|
||||
E0314, // closure outlives stack frame
|
||||
E0315, // cannot invoke closure outside of its lifetime
|
||||
E0316, // nested quantification of lifetimes
|
||||
// E0319, // trait impls for defaulted traits allowed just for structs/enums
|
||||
E0320, // recursive overflow during dropck
|
||||
// E0372, // coherence not object safe
|
||||
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
|
||||
// between structures with the same definition
|
||||
// E0385, // {} in an aliasable location
|
||||
// E0402, // cannot use an outer type parameter in this context
|
||||
// E0406, merged into 420
|
||||
// E0410, merged into 408
|
||||
// E0413, merged into 530
|
||||
// E0414, merged into 530
|
||||
// E0417, merged into 532
|
||||
// E0418, merged into 532
|
||||
// E0419, merged into 531
|
||||
// E0420, merged into 532
|
||||
// E0421, merged into 531
|
||||
// E0427, merged into 530
|
||||
E0456, // plugin `..` is not available for triple `..`
|
||||
E0457, // plugin `..` only found in rlib format, but must be available...
|
||||
E0460, // found possibly newer version of crate `..`
|
||||
E0461, // couldn't find crate `..` with expected target triple ..
|
||||
E0462, // found staticlib `..` instead of rlib or dylib
|
||||
E0464, // multiple matching crates for `..`
|
||||
E0465, // multiple .. candidates for `..` found
|
||||
// E0467, removed
|
||||
// E0470, removed
|
||||
// E0471, // constant evaluation error (in pattern)
|
||||
E0472, // asm! is unsupported on this target
|
||||
E0473, // dereference of reference outside its lifetime
|
||||
E0474, // captured variable `..` does not outlive the enclosing closure
|
||||
E0475, // index of slice outside its lifetime
|
||||
E0476, // lifetime of the source pointer does not outlive lifetime bound...
|
||||
E0477, // the type `..` does not fulfill the required lifetime...
|
||||
E0479, // the type `..` (provided as the value of a type parameter) is...
|
||||
E0480, // lifetime of method receiver does not outlive the method call
|
||||
E0481, // lifetime of function argument does not outlive the function call
|
||||
E0482, // lifetime of return value does not outlive the function call
|
||||
E0483, // lifetime of operand does not outlive the operation
|
||||
E0484, // reference is not valid at the time of borrow
|
||||
E0485, // automatically reference is not valid at the time of borrow
|
||||
E0486, // type of expression contains references that are not valid during..
|
||||
E0487, // unsafe use of destructor: destructor might be called while...
|
||||
E0488, // lifetime of variable does not enclose its declaration
|
||||
E0489, // type/lifetime parameter not in scope here
|
||||
E0490, // a value of type `..` is borrowed for too long
|
||||
E0498, // malformed plugin attribute
|
||||
E0514, // metadata version mismatch
|
||||
E0519, // local crate and dependency have same (crate-name, disambiguator)
|
||||
// two dependencies have same (crate-name, disambiguator) but different SVH
|
||||
E0521, // borrowed data escapes outside of closure
|
||||
E0523,
|
||||
// E0526, // shuffle indices are not constant
|
||||
E0539, // incorrect meta item
|
||||
E0540, // multiple rustc_deprecated attributes
|
||||
E0542, // missing 'since'
|
||||
E0543, // missing 'reason'
|
||||
E0544, // multiple stability levels
|
||||
E0545, // incorrect 'issue'
|
||||
E0546, // missing 'feature'
|
||||
E0547, // missing 'issue'
|
||||
// E0548, // replaced with a generic attribute input check
|
||||
// rustc_deprecated attribute must be paired with either stable or unstable
|
||||
// attribute
|
||||
E0549,
|
||||
E0553, // multiple rustc_const_unstable attributes
|
||||
// E0555, // replaced with a generic attribute input check
|
||||
// E0558, // replaced with a generic attribute input check
|
||||
// E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
|
||||
// E0564, // only named lifetimes are allowed in `impl Trait`,
|
||||
// but `{}` was found in the type `{}`
|
||||
E0594, // cannot assign to {}
|
||||
// E0598, // lifetime of {} is too short to guarantee its contents can be...
|
||||
// E0611, // merged into E0616
|
||||
// E0612, // merged into E0609
|
||||
// E0613, // Removed (merged with E0609)
|
||||
E0625, // thread-local statics cannot be accessed at compile-time
|
||||
E0627, // yield statement outside of generator literal
|
||||
E0628, // generators cannot have explicit parameters
|
||||
E0629, // missing 'feature' (rustc_const_unstable)
|
||||
// rustc_const_unstable attribute must be paired with stable/unstable
|
||||
// attribute
|
||||
E0630,
|
||||
E0631, // type mismatch in closure arguments
|
||||
E0632, // cannot provide explicit generic arguments when `impl Trait` is
|
||||
// used in argument position
|
||||
E0634, // type has conflicting packed representaton hints
|
||||
E0637, // "'_" is not a valid lifetime bound
|
||||
E0640, // infer outlives requirements
|
||||
E0641, // cannot cast to/from a pointer with an unknown kind
|
||||
// E0645, // trait aliases not finished
|
||||
E0657, // `impl Trait` can only capture lifetimes bound at the fn level
|
||||
E0667, // `impl Trait` in projections
|
||||
E0687, // in-band lifetimes cannot be used in `fn`/`Fn` syntax
|
||||
E0688, // in-band lifetimes cannot be mixed with explicit lifetime binders
|
||||
E0693, // incorrect `repr(align)` attribute format
|
||||
// E0694, // an unknown tool name found in scoped attributes
|
||||
E0696, // `continue` pointing to a labeled block
|
||||
// E0702, // replaced with a generic attribute input check
|
||||
E0703, // invalid ABI
|
||||
E0706, // `async fn` in trait
|
||||
// E0707, // multiple elided lifetimes used in arguments of `async fn`
|
||||
E0708, // `async` non-`move` closures with parameters are not currently
|
||||
// supported
|
||||
// E0709, // multiple different lifetimes used in arguments of `async fn`
|
||||
E0710, // an unknown tool name found in scoped lint
|
||||
E0711, // a feature has been declared with conflicting stability attributes
|
||||
E0717, // rustc_promotable without stability attribute
|
||||
E0719, // duplicate values for associated type binding
|
||||
// E0721, // `await` keyword
|
||||
E0722, // Malformed `#[optimize]` attribute
|
||||
E0724, // `#[ffi_returns_twice]` is only allowed in foreign functions
|
||||
E0726, // non-explicit (not `'_`) elided lifetime in unsupported position
|
||||
E0727, // `async` generators are not yet supported
|
||||
E0739, // invalid track_caller application/syntax
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -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 => {}
|
||||
_ => {}
|
||||
}
|
||||
```
|
||||
@@ -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
|
||||
}
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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!()
|
||||
}
|
||||
```
|
||||
@@ -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;
|
||||
```
|
||||
@@ -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;
|
||||
```
|
||||
@@ -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
|
||||
```
|
||||
@@ -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
|
||||
@@ -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`.
|
||||
@@ -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!
|
||||
}
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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!
|
||||
}
|
||||
```
|
||||
@@ -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 } => {}
|
||||
}
|
||||
```
|
||||
@@ -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, .. } => {}
|
||||
}
|
||||
```
|
||||
@@ -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" => {}
|
||||
_ => {}
|
||||
}
|
||||
```
|
||||
@@ -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 => {}
|
||||
}
|
||||
```
|
||||
@@ -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
|
||||
@@ -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"
|
||||
}
|
||||
```
|
||||
@@ -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>`.
|
||||
@@ -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
|
||||
}
|
||||
```
|
||||
@@ -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); }
|
||||
```
|
||||
@@ -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, ...);
|
||||
}
|
||||
```
|
||||
@@ -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!
|
||||
}
|
||||
```
|
||||
@@ -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 }
|
||||
}
|
||||
```
|
||||
@@ -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 }
|
||||
}
|
||||
```
|
||||
@@ -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) { }
|
||||
}
|
||||
```
|
||||
@@ -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;
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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
|
||||
}
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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);
|
||||
}
|
||||
# }
|
||||
```
|
||||
@@ -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).
|
||||
@@ -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!
|
||||
}
|
||||
```
|
||||
@@ -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!
|
||||
}
|
||||
```
|
||||
@@ -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 !
|
||||
}
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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 !
|
||||
}
|
||||
```
|
||||
@@ -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;
|
||||
}
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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 }`.
|
||||
@@ -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);
|
||||
```
|
||||
@@ -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);
|
||||
```
|
||||
@@ -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);
|
||||
```
|
||||
@@ -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);
|
||||
```
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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 {}
|
||||
```
|
||||
@@ -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.
|
||||
@@ -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());
|
||||
}
|
||||
```
|
||||
@@ -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)`
|
||||
}
|
||||
```
|
||||
@@ -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>();
|
||||
}
|
||||
```
|
||||
@@ -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!
|
||||
```
|
||||
@@ -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!
|
||||
}
|
||||
```
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -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!
|
||||
}
|
||||
```
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
```
|
||||
|
||||
@@ -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`.
|
||||
@@ -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.
|
||||
@@ -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
|
||||
```
|
||||
@@ -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
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -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
|
||||
}
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user