Update long error explanations

This commit is contained in:
Guillaume Gomez 2016-02-07 13:02:52 +01:00
parent eb5b9037ad
commit 6407b9405f
8 changed files with 848 additions and 493 deletions

View File

@ -178,13 +178,13 @@ fn main_with_result(format: OutputFormat) -> Result<(), Box<Error>> {
let metadata_dir = get_metadata_dir(&build_arch); let metadata_dir = get_metadata_dir(&build_arch);
let err_map = try!(load_all_errors(&metadata_dir)); let err_map = try!(load_all_errors(&metadata_dir));
match format { match format {
OutputFormat::Unknown(s) => panic!("Unknown output format: {}", s), OutputFormat::Unknown(s) => panic!("Unknown output format: {}", s),
OutputFormat::HTML(h) => try!(render_error_page(&err_map, OutputFormat::HTML(h) => try!(render_error_page(&err_map,
Path::new("doc/error-index.html"), Path::new("doc/error-index.html"),
h)), h)),
OutputFormat::Markdown(m) => try!(render_error_page(&err_map, OutputFormat::Markdown(m) => try!(render_error_page(&err_map,
Path::new("doc/error-index.html"), Path::new("doc/error-index.md"),
m)), m)),
} }
Ok(()) Ok(())
} }

View File

@ -25,7 +25,7 @@ is too specific or the ordering is incorrect.
For example, the following `match` block has too many arms: For example, the following `match` block has too many arms:
``` ```compile_fail
match foo { match foo {
Some(bar) => {/* ... */} Some(bar) => {/* ... */}
None => {/* ... */} None => {/* ... */}
@ -50,6 +50,8 @@ one or more cases to the match expression.
An example of an empty type is `enum Empty { }`. So, the following will work: An example of an empty type is `enum Empty { }`. So, the following will work:
``` ```
enum Empty {}
fn foo(x: Empty) { fn foo(x: Empty) {
match x { match x {
// empty // empty
@ -59,7 +61,9 @@ fn foo(x: Empty) {
However, this won't: However, this won't:
``` ```compile_fail
enum Empty {}
fn foo(x: Option<String>) { fn foo(x: Option<String>) {
match x { match x {
// empty // empty
@ -72,12 +76,14 @@ E0003: r##"
Not-a-Number (NaN) values cannot be compared for equality and hence can never Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. So, the following will not compile: match the input to a match expression. So, the following will not compile:
``` ```compile_fail
const NAN: f32 = 0.0 / 0.0; const NAN: f32 = 0.0 / 0.0;
let number = 0.1f32;
match number { match number {
NAN => { /* ... */ }, NAN => { /* ... */ },
// ... _ => {}
} }
``` ```
@ -85,10 +91,11 @@ To match against NaN values, you should instead use the `is_nan()` method in a
guard, like so: guard, like so:
``` ```
let number = 0.1f32;
match number { match number {
// ...
x if x.is_nan() => { /* ... */ } x if x.is_nan() => { /* ... */ }
// ... _ => {}
} }
``` ```
"##, "##,
@ -120,15 +127,16 @@ 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 into a variable called `op_string` while simultaneously requiring the inner
String to be moved into a variable called `s`. String to be moved into a variable called `s`.
``` ```compile_fail
let x = Some("s".to_string()); let x = Some("s".to_string());
match x { match x {
op_string @ Some(s) => ... op_string @ Some(s) => {}
None => ... None => {}
} }
``` ```
See also Error 303. See also the error E0303.
"##, "##,
E0008: r##" E0008: r##"
@ -140,7 +148,7 @@ from being available in the body of the match arm. Consider the following:
``` ```
match Some("hi".to_string()) { match Some("hi".to_string()) {
Some(s) if s.len() == 0 => // use s. Some(s) if s.len() == 0 => // use s.
... _ => {}
} }
``` ```
@ -155,7 +163,7 @@ argument by value.
match Some("hi".to_string()) { match Some("hi".to_string()) {
Some(s) if { drop(s); false } => (), Some(s) if { drop(s); false } => (),
Some(s) => // use s. Some(s) => // use s.
... _ => {}
} }
``` ```
@ -174,7 +182,7 @@ This limitation may be removed in a future version of Rust.
Wrong example: Wrong example:
``` ```compile_fail
struct X { x: (), } struct X { x: (), }
let x = Some((X { x: () }, X { x: () })); let x = Some((X { x: () }, X { x: () }));
@ -220,7 +228,7 @@ This error indicates that an attempt was made to divide by zero (or take the
remainder of a zero divisor) in a static or constant expression. Erroneous remainder of a zero divisor) in a static or constant expression. Erroneous
code example: code example:
``` ```compile_fail
const X: i32 = 42 / 0; const X: i32 = 42 / 0;
// error: attempted to divide by zero in a constant expression // error: attempted to divide by zero in a constant expression
``` ```
@ -267,7 +275,7 @@ this restriction.
This happens when a trait has a method like the following: This happens when a trait has a method like the following:
``` ```compile_fail
trait Trait { trait Trait {
fn foo(&self) -> Self; fn foo(&self) -> Self;
} }
@ -291,7 +299,11 @@ cause this problem)
In such a case, the compiler cannot predict the return type of `foo()` in a In such a case, the compiler cannot predict the return type of `foo()` in a
situation like the following: situation like the following:
``` ```compile_fail
trait Trait {
fn foo(&self) -> Self;
}
fn call_foo(x: Box<Trait>) { fn call_foo(x: Box<Trait>) {
let y = x.foo(); // What type is y? let y = x.foo(); // What type is y?
// ... // ...
@ -324,11 +336,13 @@ have:
trait Trait { trait Trait {
fn foo(&self); fn foo(&self);
} }
impl Trait for String { impl Trait for String {
fn foo(&self) { fn foo(&self) {
// implementation 1 // implementation 1
} }
} }
impl Trait for u8 { impl Trait for u8 {
fn foo(&self) { fn foo(&self) {
// implementation 2 // implementation 2
@ -351,7 +365,7 @@ fn foo<T>(x: T) {
} }
``` ```
the machine code for `foo::<u8>()`, `foo::<bool>()`, `foo::<String>()`, or any The machine code for `foo::<u8>()`, `foo::<bool>()`, `foo::<String>()`, or any
other type substitution is different. Hence the compiler generates the other type substitution is different. Hence the compiler generates the
implementation on-demand. If you call `foo()` with a `bool` parameter, 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 compiler will only generate code for `foo::<bool>()`. When we have additional
@ -373,22 +387,25 @@ trait Trait {
fn foo<T>(&self, on: T); fn foo<T>(&self, on: T);
// more methods // more methods
} }
impl Trait for String { impl Trait for String {
fn foo<T>(&self, on: T) { fn foo<T>(&self, on: T) {
// implementation 1 // implementation 1
} }
} }
impl Trait for u8 { impl Trait for u8 {
fn foo<T>(&self, on: T) { fn foo<T>(&self, on: T) {
// implementation 2 // implementation 2
} }
} }
// 8 more implementations // 8 more implementations
``` ```
Now, if we have the following code: Now, if we have the following code:
``` ```ignore
fn call_foo(thing: Box<Trait>) { fn call_foo(thing: Box<Trait>) {
thing.foo(true); // this could be any one of the 8 types above thing.foo(true); // this could be any one of the 8 types above
thing.foo(1); thing.foo(1);
@ -396,7 +413,7 @@ fn call_foo(thing: Box<Trait>) {
} }
``` ```
we don't just need to create a table of all implementations of all methods of 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 `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 `foo()`. In this case this turns out to be (10 types implementing `Trait`)*(3
types being fed to `foo()`) = 30 implementations! types being fed to `foo()`) = 30 implementations!
@ -422,7 +439,7 @@ out the methods of different types.
### Method has no receiver ### Method has no receiver
Methods that do not take a `self` parameter can't be called since there won't be 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 a way to get a pointer to the method table for them.
``` ```
trait Foo { trait Foo {
@ -446,7 +463,7 @@ trait Foo {
This is similar to the second sub-error, but subtler. It happens in situations This is similar to the second sub-error, but subtler. It happens in situations
like the following: like the following:
``` ```compile_fail
trait Super<A> {} trait Super<A> {}
trait Trait: Super<Self> { trait Trait: Super<Self> {
@ -488,7 +505,7 @@ 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: Consider the following erroneous definition of a type for a list of bytes:
``` ```compile_fail
// error, invalid recursive struct type // error, invalid recursive struct type
struct ListNode { struct ListNode {
head: u8, head: u8,
@ -521,7 +538,7 @@ E0109: r##"
You tried to give a type parameter to a type which doesn't need it. Erroneous You tried to give a type parameter to a type which doesn't need it. Erroneous
code example: code example:
``` ```compile_fail
type X = u32<i32>; // error: type parameters are not allowed on this type type X = u32<i32>; // error: type parameters are not allowed on this type
``` ```
@ -542,7 +559,7 @@ E0110: r##"
You tried to give a lifetime parameter to a type which doesn't need it. You tried to give a lifetime parameter to a type which doesn't need it.
Erroneous code example: Erroneous code example:
``` ```compile_fail
type X = u32<'static>; // error: lifetime parameters are not allowed on type X = u32<'static>; // error: lifetime parameters are not allowed on
// this type // this type
``` ```
@ -605,8 +622,8 @@ parameters are involved, this cannot always be done.
So, for example, the following is not allowed: So, for example, the following is not allowed:
``` ```compile_fail
struct Foo<T>(Vec<T>) struct Foo<T>(Vec<T>);
fn foo<T>(x: Vec<T>) { fn foo<T>(x: Vec<T>) {
// we are transmuting between Vec<T> and Foo<T> here // we are transmuting between Vec<T> and Foo<T> here
@ -631,9 +648,11 @@ 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, possible type substitution. It's possible to use traits to do this cleanly,
for example: for example:
``` ```ignore
struct Foo<T>(Vec<T>);
trait MyTransmutableType { trait MyTransmutableType {
fn transmute(Vec<Self>) -> Foo<Self> fn transmute(Vec<Self>) -> Foo<Self>;
} }
impl MyTransmutableType for u8 { impl MyTransmutableType for u8 {
@ -641,11 +660,13 @@ impl MyTransmutableType for u8 {
transmute(x) transmute(x)
} }
} }
impl MyTransmutableType for String { impl MyTransmutableType for String {
fn transmute(x: Foo<String>) -> Vec<String> { fn transmute(x: Foo<String>) -> Vec<String> {
transmute(x) transmute(x)
} }
} }
// ... more impls for the types you intend to transmute // ... more impls for the types you intend to transmute
fn foo<T: MyTransmutableType>(x: Vec<T>) { fn foo<T: MyTransmutableType>(x: Vec<T>) {
@ -660,7 +681,7 @@ is a size mismatch in one of the impls.
It is also possible to manually transmute: It is also possible to manually transmute:
``` ```ignore
ptr::read(&v as *const _ as *const SomeType) // `v` transmuted to `SomeType` ptr::read(&v as *const _ as *const SomeType) // `v` transmuted to `SomeType`
``` ```
@ -696,9 +717,10 @@ If you want to match against a `static`, consider using a guard instead:
``` ```
static FORTY_TWO: i32 = 42; static FORTY_TWO: i32 = 42;
match Some(42) { match Some(42) {
Some(x) if x == FORTY_TWO => ... Some(x) if x == FORTY_TWO => {}
... _ => {}
} }
``` ```
"##, "##,
@ -708,7 +730,7 @@ An if-let pattern attempts to match the pattern, and enters the body if the
match was successful. If the match is irrefutable (when it cannot fail to match was successful. If the match is irrefutable (when it cannot fail to
match), use a regular `let`-binding instead. For instance: match), use a regular `let`-binding instead. For instance:
``` ```compile_fail
struct Irrefutable(i32); struct Irrefutable(i32);
let irr = Irrefutable(0); let irr = Irrefutable(0);
@ -717,8 +739,14 @@ if let Irrefutable(x) = irr {
// This body will always be executed. // This body will always be executed.
foo(x); foo(x);
} }
```
Try this instead:
```ignore
struct Irrefutable(i32);
let irr = Irrefutable(0);
// Try this instead:
let Irrefutable(x) = irr; let Irrefutable(x) = irr;
foo(x); foo(x);
``` ```
@ -729,7 +757,7 @@ A while-let pattern attempts to match the pattern, and enters the body if the
match was successful. If the match is irrefutable (when it cannot fail to match was successful. If the match is irrefutable (when it cannot fail to
match), use a regular `let`-binding inside a `loop` instead. For instance: match), use a regular `let`-binding inside a `loop` instead. For instance:
``` ```compile_fail
struct Irrefutable(i32); struct Irrefutable(i32);
let irr = Irrefutable(0); let irr = Irrefutable(0);
@ -738,7 +766,12 @@ while let Irrefutable(x) = irr {
... ...
} }
// Try this instead: Try this instead:
```
struct Irrefutable(i32);
let irr = Irrefutable(0);
loop { loop {
let Irrefutable(x) = irr; let Irrefutable(x) = irr;
... ...
@ -752,16 +785,23 @@ Enum variants are qualified by default. For example, given this type:
``` ```
enum Method { enum Method {
GET, GET,
POST POST,
} }
``` ```
you would match it using: You would match it using:
``` ```
enum Method {
GET,
POST,
}
let m = Method::GET;
match m { match m {
Method::GET => ... Method::GET => {},
Method::POST => ... Method::POST => {},
} }
``` ```
@ -772,7 +812,7 @@ that happens.
Qualified names are good practice, and most code works well with them. But if Qualified names are good practice, and most code works well with them. But if
you prefer them unqualified, you can import the variants into scope: you prefer them unqualified, you can import the variants into scope:
``` ```ignore
use Method::*; use Method::*;
enum Method { GET, POST } enum Method { GET, POST }
``` ```
@ -780,7 +820,7 @@ enum Method { GET, POST }
If you want others to be able to import variants from your module directly, use If you want others to be able to import variants from your module directly, use
`pub use`: `pub use`:
``` ```ignore
pub use Method::*; pub use Method::*;
enum Method { GET, POST } enum Method { GET, POST }
``` ```
@ -790,7 +830,7 @@ E0229: r##"
An associated type binding was done outside of the type parameter declaration An associated type binding was done outside of the type parameter declaration
and `where` clause. Erroneous code example: and `where` clause. Erroneous code example:
``` ```compile_fail
pub trait Foo { pub trait Foo {
type A; type A;
fn boo(&self) -> <Self as Foo>::A; fn boo(&self) -> <Self as Foo>::A;
@ -810,13 +850,13 @@ fn baz<I>(x: &<I as Foo<A=Bar>>::A) {}
To solve this error, please move the type bindings in the type parameter To solve this error, please move the type bindings in the type parameter
declaration: declaration:
``` ```ignore
fn baz<I: Foo<A=Bar>>(x: &<I as Foo>::A) {} // ok! fn baz<I: Foo<A=Bar>>(x: &<I as Foo>::A) {} // ok!
``` ```
or in the `where` clause: Or in the `where` clause:
``` ```ignore
fn baz<I>(x: &<I as Foo>::A) where I: Foo<A=Bar> {} fn baz<I>(x: &<I as Foo>::A) where I: Foo<A=Bar> {}
``` ```
"##, "##,
@ -827,7 +867,7 @@ used.
These two examples illustrate the problem: These two examples illustrate the problem:
``` ```compile_fail
// error, use of undeclared lifetime name `'a` // error, use of undeclared lifetime name `'a`
fn foo(x: &'a str) { } fn foo(x: &'a str) { }
@ -840,7 +880,7 @@ struct Foo {
These can be fixed by declaring lifetime parameters: These can be fixed by declaring lifetime parameters:
``` ```
fn foo<'a>(x: &'a str) { } fn foo<'a>(x: &'a str) {}
struct Foo<'a> { struct Foo<'a> {
x: &'a str, x: &'a str,
@ -853,7 +893,7 @@ Declaring certain lifetime names in parameters is disallowed. For example,
because the `'static` lifetime is a special built-in lifetime name denoting because the `'static` lifetime is a special built-in lifetime name denoting
the lifetime of the entire program, this is an error: the lifetime of the entire program, this is an error:
``` ```compile_fail
// error, invalid lifetime parameter name `'static` // error, invalid lifetime parameter name `'static`
fn foo<'static>(x: &'static str) { } fn foo<'static>(x: &'static str) { }
``` ```
@ -863,7 +903,7 @@ E0263: r##"
A lifetime name cannot be declared more than once in the same scope. For A lifetime name cannot be declared more than once in the same scope. For
example: example:
``` ```compile_fail
// error, lifetime name `'a` declared twice in the same scope // error, lifetime name `'a` declared twice in the same scope
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { } fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { }
``` ```
@ -872,7 +912,7 @@ fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { }
E0264: r##" E0264: r##"
An unknown external lang item was used. Erroneous code example: An unknown external lang item was used. Erroneous code example:
``` ```compile_fail
#![feature(lang_items)] #![feature(lang_items)]
extern "C" { extern "C" {
@ -896,9 +936,9 @@ extern "C" {
E0269: r##" E0269: r##"
Functions must eventually return a value of their return type. For example, in Functions must eventually return a value of their return type. For example, in
the following function the following function:
``` ```compile_fail
fn foo(x: u8) -> u8 { fn foo(x: u8) -> u8 {
if x > 0 { if x > 0 {
x // alternatively, `return x` x // alternatively, `return x`
@ -907,7 +947,7 @@ fn foo(x: u8) -> u8 {
} }
``` ```
if the condition is true, the value `x` is returned, but if the condition is If the condition is true, the value `x` is returned, but if the condition is
false, control exits the `if` block and reaches a place where nothing is being false, control exits the `if` block and reaches a place where nothing is being
returned. All possible control paths must eventually return a `u8`, which is not returned. All possible control paths must eventually return a `u8`, which is not
happening here. happening here.
@ -915,7 +955,7 @@ happening here.
An easy fix for this in a complicated function is to specify a default return An easy fix for this in a complicated function is to specify a default return
value, if possible: value, if possible:
``` ```ignore
fn foo(x: u8) -> u8 { fn foo(x: u8) -> u8 {
if x > 0 { if x > 0 {
x // alternatively, `return x` x // alternatively, `return x`
@ -935,7 +975,7 @@ Rust lets you define functions which are known to never return, i.e. are
For example, the following functions never return: For example, the following functions never return:
``` ```no_run
fn foo() -> ! { fn foo() -> ! {
loop {} loop {}
} }
@ -947,18 +987,24 @@ fn bar() -> ! {
fn baz() -> ! { fn baz() -> ! {
panic!(); // this macro internally expands to a call to a diverging function panic!(); // this macro internally expands to a call to a diverging function
} }
``` ```
Such functions can be used in a place where a value is expected without Such functions can be used in a place where a value is expected without
returning a value of that type, for instance: returning a value of that type, for instance:
```no_run
fn foo() -> ! {
loop {}
}
let x = 3;
```
let y = match x { let y = match x {
1 => 1, 1 => 1,
2 => 4, 2 => 4,
_ => foo() // diverging function called here _ => foo() // diverging function called here
}; };
println!("{}", y) println!("{}", y)
``` ```
@ -967,22 +1013,29 @@ return control to the match block, it is fine to use it in a place where an
integer was expected. The `match` block will never finish executing, and any integer was expected. The `match` block will never finish executing, and any
point where `y` (like the print statement) is needed will not be reached. point where `y` (like the print statement) is needed will not be reached.
However, if we had a diverging function that actually does finish execution However, if we had a diverging function that actually does finish execution:
``` ```ignore
fn foo() -> { fn foo() -> ! {
loop {break;} loop {break;}
} }
``` ```
then we would have an unknown value for `y` in the following code: Then we would have an unknown value for `y` in the following code:
```no_run
fn foo() -> ! {
loop {}
}
let x = 3;
```
let y = match x { let y = match x {
1 => 1, 1 => 1,
2 => 4, 2 => 4,
_ => foo() _ => foo()
}; };
println!("{}", y); println!("{}", y);
``` ```
@ -1004,18 +1057,21 @@ Examples follow.
Here is a basic example: Here is a basic example:
``` ```compile_fail
trait Trait { type AssociatedType; } trait Trait { type AssociatedType; }
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> { fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
println!("in foo"); println!("in foo");
} }
impl Trait for i8 { type AssociatedType = &'static str; } impl Trait for i8 { type AssociatedType = &'static str; }
foo(3_i8); foo(3_i8);
``` ```
Here is that same example again, with some explanatory comments: Here is that same example again, with some explanatory comments:
``` ```ignore
trait Trait { type AssociatedType; } trait Trait { type AssociatedType; }
fn foo<T>(t: T) where T: Trait<AssociatedType=u32> { fn foo<T>(t: T) where T: Trait<AssociatedType=u32> {
@ -1053,12 +1109,12 @@ foo(3_i8);
Here is a more subtle instance of the same problem, that can Here is a more subtle instance of the same problem, that can
arise with for-loops in Rust: arise with for-loops in Rust:
``` ```compile_fail
let vs: Vec<i32> = vec![1, 2, 3, 4]; let vs: Vec<i32> = vec![1, 2, 3, 4];
for v in &vs { for v in &vs {
match v { match v {
1 => {} 1 => {},
_ => {} _ => {},
} }
} }
``` ```
@ -1067,7 +1123,7 @@ The above fails because of an analogous type mismatch,
though may be harder to see. Again, here are some though may be harder to see. Again, here are some
explanatory comments for the same example: explanatory comments for the same example:
``` ```ignore
{ {
let vs = vec![1, 2, 3, 4]; let vs = vec![1, 2, 3, 4];
@ -1115,10 +1171,13 @@ So we can fix the previous examples like this:
``` ```
// Basic Example: // Basic Example:
trait Trait { type AssociatedType; } trait Trait { type AssociatedType; }
fn foo<T>(t: T) where T: Trait<AssociatedType = &'static str> { fn foo<T>(t: T) where T: Trait<AssociatedType = &'static str> {
println!("in foo"); println!("in foo");
} }
impl Trait for i8 { type AssociatedType = &'static str; } impl Trait for i8 { type AssociatedType = &'static str; }
foo(3_i8); foo(3_i8);
// For-Loop Example: // For-Loop Example:
@ -1138,7 +1197,7 @@ 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 position that needs that trait. For example, when the following code is
compiled: compiled:
``` ```compile_fail
fn foo<T: Index<u8>>(x: T){} fn foo<T: Index<u8>>(x: T){}
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"] #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
@ -1168,7 +1227,7 @@ 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 position that needs that trait. For example, when the following code is
compiled: compiled:
``` ```compile_fail
fn foo<T: Index<u8>>(x: T){} fn foo<T: Index<u8>>(x: T){}
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"] #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
@ -1196,7 +1255,7 @@ 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 position that needs that trait. For example, when the following code is
compiled: compiled:
``` ```compile_fail
fn foo<T: Index<u8>>(x: T){} fn foo<T: Index<u8>>(x: T){}
#[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"] #[rustc_on_unimplemented = "the type `{Self}` cannot be indexed by `{Idx}`"]
@ -1218,9 +1277,9 @@ 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 before it could be evaluated. Often this means that there is unbounded recursion
in resolving some type bounds. in resolving some type bounds.
For example, in the following code For example, in the following code:
``` ```compile_fail
trait Foo {} trait Foo {}
struct Bar<T>(T); struct Bar<T>(T);
@ -1228,7 +1287,7 @@ struct Bar<T>(T);
impl<T> Foo for T where Bar<T>: Foo {} 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 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 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 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. recursive requirement that can't be resolved directly.
@ -1240,13 +1299,13 @@ E0276: r##"
This error occurs when a bound in an implementation of a trait does not match This error occurs when a bound in an implementation of a trait does not match
the bounds specified in the original trait. For example: the bounds specified in the original trait. For example:
``` ```compile_fail
trait Foo { trait Foo {
fn foo<T>(x: T); fn foo<T>(x: T);
} }
impl Foo for bool { impl Foo for bool {
fn foo<T>(x: T) where T: Copy {} fn foo<T>(x: T) where T: Copy {}
} }
``` ```
@ -1262,7 +1321,7 @@ E0277: r##"
You tried to use a type which doesn't implement some trait in a place which You tried to use a type which doesn't implement some trait in a place which
expected that trait. Erroneous code example: expected that trait. Erroneous code example:
``` ```compile_fail
// here we declare the Foo trait with a bar method // here we declare the Foo trait with a bar method
trait Foo { trait Foo {
fn bar(&self); fn bar(&self);
@ -1310,7 +1369,7 @@ 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 which expected that trait. This error typically occurs when working with
`Fn`-based types. Erroneous code example: `Fn`-based types. Erroneous code example:
``` ```compile_fail
fn foo<F: Fn()>(x: F) { } fn foo<F: Fn()>(x: F) { }
fn main() { fn main() {
@ -1336,7 +1395,7 @@ parameter with a `FromIterator` bound, which for a `char` iterator is
implemented by `Vec` and `String` among others. Consider the following snippet implemented by `Vec` and `String` among others. Consider the following snippet
that reverses the characters of a string: that reverses the characters of a string:
``` ```compile_fail
let x = "hello".chars().rev().collect(); let x = "hello".chars().rev().collect();
``` ```
@ -1373,9 +1432,9 @@ 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 case it is not always possible to use a type annotation, because all candidates
have the same return type. For instance: have the same return type. For instance:
``` ```compile_fail
struct Foo<T> { struct Foo<T> {
// Some fields omitted. num: T,
} }
impl<T> Foo<T> { impl<T> Foo<T> {
@ -1399,17 +1458,19 @@ to unambiguously choose an implementation.
For example: For example:
``` ```compile_fail
trait Generator { trait Generator {
fn create() -> u32; fn create() -> u32;
} }
struct Impl; struct Impl;
impl Generator for Impl { impl Generator for Impl {
fn create() -> u32 { 1 } fn create() -> u32 { 1 }
} }
struct AnotherImpl; struct AnotherImpl;
impl Generator for AnotherImpl { impl Generator for AnotherImpl {
fn create() -> u32 { 2 } fn create() -> u32 { 2 }
} }
@ -1424,6 +1485,16 @@ fn main() {
To resolve this error use the concrete type: 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() { fn main() {
let gen1 = AnotherImpl::create(); let gen1 = AnotherImpl::create();
@ -1448,24 +1519,36 @@ that a name will be extracted in all cases. Instead of pattern matching the
loop variable, consider using a `match` or `if let` inside the loop body. For loop variable, consider using a `match` or `if let` inside the loop body. For
instance: instance:
``` ```compile_fail
let xs : Vec<Option<i32>> = vec!(Some(1), None);
// This fails because `None` is not covered. // This fails because `None` is not covered.
for Some(x) in xs { for Some(x) in xs {
... // ...
} }
```
Match inside the loop instead:
```
let xs : Vec<Option<i32>> = vec!(Some(1), None);
// Match inside the loop instead:
for item in xs { for item in xs {
match item { match item {
Some(x) => ... Some(x) => {},
None => ... None => {},
} }
} }
```
Or use `if let`:
```
let xs : Vec<Option<i32>> = vec!(Some(1), None);
// Or use `if let`:
for item in xs { for item in xs {
if let Some(x) = item { if let Some(x) = item {
... // ...
} }
} }
``` ```
@ -1478,7 +1561,7 @@ on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if mutable exhaustive. For instance, the following would not match any arm if mutable
borrows were allowed: borrows were allowed:
``` ```compile_fail
match Some(()) { match Some(()) {
None => { }, None => { },
option if option.take().is_none() => { /* impossible, option is `Some` */ }, option if option.take().is_none() => { /* impossible, option is `Some` */ },
@ -1494,7 +1577,7 @@ on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if assignments exhaustive. For instance, the following would not match any arm if assignments
were allowed: were allowed:
``` ```compile_fail
match Some(()) { match Some(()) {
None => { }, None => { },
option if { option = None; false } { }, option if { option = None; false } { },
@ -1508,20 +1591,20 @@ In certain cases it is possible for sub-bindings to violate memory safety.
Updates to the borrow checker in a future version of Rust may remove this Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings. restriction, but for now patterns must be rewritten without sub-bindings.
``` ```ignore
// Before. // Before.
match Some("hi".to_string()) { match Some("hi".to_string()) {
ref op_string_ref @ Some(ref s) => ... ref op_string_ref @ Some(s) => {},
None => ... None => {},
} }
// After. // After.
match Some("hi".to_string()) { match Some("hi".to_string()) {
Some(ref s) => { Some(ref s) => {
let op_string_ref = &Some(s); let op_string_ref = &Some(s);
... // ...
} },
None => ... None => {},
} }
``` ```
@ -1549,7 +1632,7 @@ variable.
For example: For example:
``` ```compile_fail
let x: i32 = "I am not a number!"; let x: i32 = "I am not a number!";
// ~~~ ~~~~~~~~~~~~~~~~~~~~ // ~~~ ~~~~~~~~~~~~~~~~~~~~
// | | // | |
@ -1590,14 +1673,17 @@ 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 must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error. denotes this will cause this error.
``` ```compile_fail
// This won't compile because T is not constrained, meaning the data // This won't compile because T is not constrained, meaning the data
// stored in it is not guaranteed to last as long as the reference // stored in it is not guaranteed to last as long as the reference
struct Foo<'a, T> { struct Foo<'a, T> {
foo: &'a T foo: &'a T
} }
```
// This will compile, because it has the constraint on the type parameter This will compile, because it has the constraint on the type parameter:
```
struct Foo<'a, T: 'a> { struct Foo<'a, T: 'a> {
foo: &'a T foo: &'a T
} }
@ -1610,14 +1696,16 @@ 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 must be as long as the data needs to be alive, and missing the constraint that
denotes this will cause this error. denotes this will cause this error.
``` ```compile_fail
// This won't compile because T is not constrained to the static lifetime // This won't compile because T is not constrained to the static lifetime
// the reference needs // the reference needs
struct Foo<T> { struct Foo<T> {
foo: &'static T foo: &'static T
} }
// This will compile, because it has the constraint on the type parameter This will compile, because it has the constraint on the type parameter:
```
struct Foo<T: 'static> { struct Foo<T: 'static> {
foo: &'static T foo: &'static T
} }
@ -1644,13 +1732,13 @@ signature of a function that you are calling. For example, if
the error is reported on a call like `foo(x)`, and `foo` is the error is reported on a call like `foo(x)`, and `foo` is
defined as follows: defined as follows:
``` ```ignore
fn foo(arg: &Box<SomeTrait>) { ... } fn foo(arg: &Box<SomeTrait>) { ... }
``` ```
you might change it to: You might change it to:
``` ```ignore
fn foo<'a>(arg: &Box<SomeTrait+'a>) { ... } fn foo<'a>(arg: &Box<SomeTrait+'a>) { ... }
``` ```
@ -1663,7 +1751,7 @@ contain references (with a maximum lifetime of `'a`).
E0452: r##" E0452: r##"
An invalid lint attribute has been given. Erroneous code example: An invalid lint attribute has been given. Erroneous code example:
``` ```compile_fail
#![allow(foo = "")] // error: malformed lint attribute #![allow(foo = "")] // error: malformed lint attribute
``` ```
@ -1680,7 +1768,7 @@ lint name). Ensure the attribute is of this form:
E0496: r##" E0496: r##"
A lifetime name is shadowing another lifetime name. Erroneous code example: A lifetime name is shadowing another lifetime name. Erroneous code example:
``` ```compile_fail
struct Foo<'a> { struct Foo<'a> {
a: &'a i32, a: &'a i32,
} }
@ -1713,7 +1801,7 @@ E0497: r##"
A stability attribute was used outside of the standard library. Erroneous code A stability attribute was used outside of the standard library. Erroneous code
example: example:
``` ```compile_fail
#[stable] // error: stability attributes may not be used outside of the #[stable] // error: stability attributes may not be used outside of the
// standard library // standard library
fn foo() {} fn foo() {}
@ -1729,7 +1817,7 @@ item.
Examples of erroneous code: Examples of erroneous code:
``` ```compile_fail
#[repr(C)] #[repr(C)]
type Foo = u8; type Foo = u8;
@ -1777,7 +1865,7 @@ something other than a function or method.
Examples of erroneous code: Examples of erroneous code:
``` ```compile_fail
#[inline(always)] #[inline(always)]
struct Foo; struct Foo;
@ -1811,9 +1899,9 @@ register_diagnostics! {
// E0285, // overflow evaluation builtin bounds // E0285, // overflow evaluation builtin bounds
E0298, // mismatched types between arms E0298, // mismatched types between arms
E0299, // mismatched types between arms E0299, // mismatched types between arms
// E0300, // unexpanded macro // E0300, // unexpanded macro
// E0304, // expected signed integer constant // E0304, // expected signed integer constant
// E0305, // expected constant // E0305, // expected constant
E0311, // thing may not live long enough E0311, // thing may not live long enough
E0312, // lifetime of reference outlives lifetime of borrowed content E0312, // lifetime of reference outlives lifetime of borrowed content
E0313, // lifetime of borrowed pointer outlives lifetime of captured variable E0313, // lifetime of borrowed pointer outlives lifetime of captured variable

View File

@ -17,7 +17,7 @@ This error occurs when an attempt is made to use data captured by a closure,
when that data may no longer exist. It's most commonly seen when attempting to when that data may no longer exist. It's most commonly seen when attempting to
return a closure: return a closure:
``` ```compile_fail
fn foo() -> Box<Fn(u32) -> u32> { fn foo() -> Box<Fn(u32) -> u32> {
let x = 0u32; let x = 0u32;
Box::new(|y| x + y) Box::new(|y| x + y)
@ -30,7 +30,7 @@ longer exists. An attempt to access `x` within the closure would thus be unsafe.
Another situation where this might be encountered is when spawning threads: Another situation where this might be encountered is when spawning threads:
``` ```compile_fail
fn foo() { fn foo() {
let x = 0u32; let x = 0u32;
let y = 1u32; let y = 1u32;
@ -65,10 +65,11 @@ about safety.
E0381: r##" E0381: r##"
It is not allowed to use or capture an uninitialized variable. For example: It is not allowed to use or capture an uninitialized variable. For example:
``` ```compile_fail
fn main() { fn main() {
let x: i32; let x: i32;
let y = x; // error, use of possibly uninitialized variable let y = x; // error, use of possibly uninitialized variable
}
``` ```
To fix this, ensure that any declared variables are initialized before being To fix this, ensure that any declared variables are initialized before being
@ -79,7 +80,7 @@ E0382: r##"
This error occurs when an attempt is made to use a variable after its contents This error occurs when an attempt is made to use a variable after its contents
have been moved elsewhere. For example: have been moved elsewhere. For example:
``` ```compile_fail
struct MyStruct { s: u32 } struct MyStruct { s: u32 }
fn main() { fn main() {
@ -144,7 +145,11 @@ structure that is currently uninitialized.
For example, this can happen when a drop has taken place: For example, this can happen when a drop has taken place:
``` ```compile_fail
struct Foo {
a: u32,
}
let mut x = Foo { a: 1 }; let mut x = Foo { a: 1 };
drop(x); // `x` is now uninitialized drop(x); // `x` is now uninitialized
x.a = 2; // error, partial reinitialization of uninitialized structure `t` x.a = 2; // error, partial reinitialization of uninitialized structure `t`
@ -153,6 +158,10 @@ x.a = 2; // error, partial reinitialization of uninitialized structure `t`
This error can be fixed by fully reinitializing the structure in question: This error can be fixed by fully reinitializing the structure in question:
``` ```
struct Foo {
a: u32,
}
let mut x = Foo { a: 1 }; let mut x = Foo { a: 1 };
drop(x); drop(x);
x = Foo { a: 2 }; x = Foo { a: 2 };
@ -163,7 +172,7 @@ E0384: r##"
This error occurs when an attempt is made to reassign an immutable variable. This error occurs when an attempt is made to reassign an immutable variable.
For example: For example:
``` ```compile_fail
fn main(){ fn main(){
let x = 3; let x = 3;
x = 5; // error, reassignment of immutable variable x = 5; // error, reassignment of immutable variable
@ -187,7 +196,7 @@ reference stored inside an immutable container.
For example, this can happen when storing a `&mut` inside an immutable `Box`: For example, this can happen when storing a `&mut` inside an immutable `Box`:
``` ```compile_fail
let mut x: i64 = 1; let mut x: i64 = 1;
let y: Box<_> = Box::new(&mut x); let y: Box<_> = Box::new(&mut x);
**y = 2; // error, cannot assign to data in an immutable container **y = 2; // error, cannot assign to data in an immutable container
@ -205,6 +214,8 @@ It can also be fixed by using a type with interior mutability, such as `Cell` or
`RefCell`: `RefCell`:
``` ```
use std::cell::Cell;
let x: i64 = 1; let x: i64 = 1;
let y: Box<Cell<_>> = Box::new(Cell::new(x)); let y: Box<Cell<_>> = Box::new(Cell::new(x));
y.set(2); y.set(2);
@ -215,12 +226,12 @@ E0387: r##"
This error occurs when an attempt is made to mutate or mutably reference data This error occurs when an attempt is made to mutate or mutably reference data
that a closure has captured immutably. Examples of this error are shown below: that a closure has captured immutably. Examples of this error are shown below:
``` ```compile_fail
// Accepts a function or a closure that captures its environment immutably. // Accepts a function or a closure that captures its environment immutably.
// Closures passed to foo will not be able to mutate their closed-over state. // Closures passed to foo will not be able to mutate their closed-over state.
fn foo<F: Fn()>(f: F) { } fn foo<F: Fn()>(f: F) { }
// Attempts to mutate closed-over data. Error message reads: // Attempts to mutate closed-over data. Error message reads:
// `cannot assign to data in a captured outer variable...` // `cannot assign to data in a captured outer variable...`
fn mutable() { fn mutable() {
let mut x = 0u32; let mut x = 0u32;
@ -254,6 +265,8 @@ could be redefined as below:
``` ```
use std::cell::Cell; use std::cell::Cell;
fn foo<F: Fn()>(f: F) { }
fn mutable() { fn mutable() {
let x = Cell::new(0u32); let x = Cell::new(0u32);
foo(|| x.set(2)); foo(|| x.set(2));
@ -268,7 +281,7 @@ https://doc.rust-lang.org/std/cell/
E0499: r##" E0499: r##"
A variable was borrowed as mutable more than once. Erroneous code example: A variable was borrowed as mutable more than once. Erroneous code example:
``` ```compile_fail
let mut i = 0; let mut i = 0;
let mut x = &mut i; let mut x = &mut i;
let mut a = &mut i; let mut a = &mut i;
@ -296,7 +309,7 @@ let c = &i; // still ok!
E0507: r##" E0507: r##"
You tried to move out of a value which was borrowed. Erroneous code example: You tried to move out of a value which was borrowed. Erroneous code example:
``` ```compile_fail
use std::cell::RefCell; use std::cell::RefCell;
struct TheDarkKnight; struct TheDarkKnight;
@ -380,7 +393,7 @@ fn main() {
Moving out of a member of a mutably borrowed struct is fine if you put something Moving out of a member of a mutably borrowed struct is fine if you put something
back. `mem::replace` can be used for that: back. `mem::replace` can be used for that:
``` ```ignore
struct TheDarkKnight; struct TheDarkKnight;
impl TheDarkKnight { impl TheDarkKnight {

View File

@ -18,7 +18,7 @@ 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 the heap at runtime, and therefore cannot be done at compile time. Erroneous
code example: code example:
``` ```compile_fail
#![feature(box_syntax)] #![feature(box_syntax)]
const CON : Box<i32> = box 0; const CON : Box<i32> = box 0;
@ -30,9 +30,9 @@ Initializers for constants and statics are evaluated at compile time.
User-defined operators rely on user-defined functions, which cannot be evaluated User-defined operators rely on user-defined functions, which cannot be evaluated
at compile time. at compile time.
Bad example: Erroneous code example:
``` ```compile_fail
use std::ops::Index; use std::ops::Index;
struct Foo { a: u8 } struct Foo { a: u8 }
@ -53,16 +53,16 @@ Example:
``` ```
const a: &'static [i32] = &[1, 2, 3]; const a: &'static [i32] = &[1, 2, 3];
const b: i32 = a[0]; // Good! const b: i32 = a[0]; // Ok!
``` ```
"##, "##,
E0013: r##" E0013: r##"
Static and const variables can refer to other const variables. But a const Static and const variables can refer to other const variables. But a const
variable cannot refer to a static variable. For example, `Y` cannot refer to `X` variable cannot refer to a static variable. For example, `Y` cannot refer to
here: `X` here:
``` ```compile_fail
static X: i32 = 42; static X: i32 = 42;
const Y: i32 = X; const Y: i32 = X;
``` ```
@ -80,9 +80,9 @@ E0014: r##"
Constants can only be initialized by a constant value or, in a future 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 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 of a path (like a::b, or x) denoting something other than one of these
allowed items. Example: allowed items. Erroneous code xample:
``` ```compile_fail
const FOO: i32 = { let x = 0; x }; // 'x' isn't a constant nor a function! const FOO: i32 = { let x = 0; x }; // 'x' isn't a constant nor a function!
``` ```
@ -91,7 +91,7 @@ To avoid it, you have to replace the non-constant value:
``` ```
const FOO: i32 = { const X : i32 = 0; X }; const FOO: i32 = { const X : i32 = 0; X };
// or even: // or even:
const FOO: i32 = { 0 }; // but brackets are useless here const FOO2: i32 = { 0 }; // but brackets are useless here
``` ```
"##, "##,
@ -115,9 +115,9 @@ See [RFC 911] for more details on the design of `const fn`s.
E0016: r##" E0016: r##"
Blocks in constants may only contain items (such as constant, function Blocks in constants may only contain items (such as constant, function
definition, etc...) and a tail expression. Example: definition, etc...) and a tail expression. Erroneous code example:
``` ```compile_fail
const FOO: i32 = { let x = 0; x }; // 'x' isn't an item! const FOO: i32 = { let x = 0; x }; // 'x' isn't an item!
``` ```
@ -129,9 +129,10 @@ const FOO: i32 = { const X : i32 = 0; X };
"##, "##,
E0017: r##" E0017: r##"
References in statics and constants may only refer to immutable values. Example: References in statics and constants may only refer to immutable values.
Erroneous code example:
``` ```compile_fail
static X: i32 = 1; static X: i32 = 1;
const C: i32 = 2; const C: i32 = 2;
@ -156,7 +157,8 @@ can't cast a pointer to an integer because the address of a pointer can
vary. vary.
For example, if you write: For example, if you write:
```
```compile_fail
static MY_STATIC: u32 = 42; static MY_STATIC: u32 = 42;
static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize; static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize;
static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR; static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR;
@ -184,10 +186,10 @@ accessed directly.
E0019: r##" E0019: r##"
A function call isn't allowed in the const's initialization expression A function call isn't allowed in the const's initialization expression
because the expression's value must be known at compile-time. Example of because the expression's value must be known at compile-time. Erroneous code
erroneous code: example:
``` ```compile_fail
enum Test { enum Test {
V1 V1
} }
@ -222,13 +224,13 @@ E0022: r##"
Constant functions are not allowed to mutate anything. Thus, binding to an Constant functions are not allowed to mutate anything. Thus, binding to an
argument with a mutable pattern is not allowed. For example, argument with a mutable pattern is not allowed. For example,
``` ```compile_fail
const fn foo(mut x: u8) { const fn foo(mut x: u8) {
// do stuff // do stuff
} }
``` ```
is bad because the function body may not mutate `x`. Is incorrect because the function body may not mutate `x`.
Remove any mutable bindings from the argument list to fix this error. In case Remove any mutable bindings from the argument list to fix this error. In case
you need to mutate the argument, try lazily initializing a global variable you need to mutate the argument, try lazily initializing a global variable
@ -244,12 +246,12 @@ range.
For example: For example:
``` ```compile_fail
match 5u32 { match 5u32 {
// This range is ok, albeit pointless. // This range is ok, albeit pointless.
1 ... 1 => ... 1 ... 1 => {}
// This range is empty, and the compiler can tell. // This range is empty, and the compiler can tell.
1000 ... 5 => ... 1000 ... 5 => {}
} }
``` ```
"##, "##,
@ -268,11 +270,11 @@ All statics and constants need to resolve to a value in an acyclic manner.
For example, neither of the following can be sensibly compiled: For example, neither of the following can be sensibly compiled:
``` ```compile_fail
const X: u32 = X; const X: u32 = X;
``` ```
``` ```compile_fail
const X: u32 = Y; const X: u32 = Y;
const Y: u32 = X; const Y: u32 = X;
``` ```
@ -282,7 +284,7 @@ E0267: r##"
This error indicates the use of a loop keyword (`break` or `continue`) inside a This error indicates the use of a loop keyword (`break` or `continue`) inside a
closure but outside of any loop. Erroneous code example: closure but outside of any loop. Erroneous code example:
``` ```compile_fail
let w = || { break; }; // error: `break` inside of a closure let w = || { break; }; // error: `break` inside of a closure
``` ```
@ -306,7 +308,7 @@ This error indicates the use of a loop keyword (`break` or `continue`) outside
of a loop. Without a loop to break out of or continue in, no sensible action can of a loop. Without a loop to break out of or continue in, no sensible action can
be taken. Erroneous code example: be taken. Erroneous code example:
``` ```compile_fail
fn some_func() { fn some_func() {
break; // error: `break` outside of loop break; // error: `break` outside of loop
} }
@ -329,7 +331,7 @@ in statics, constants, and constant functions.
For example: For example:
``` ```compile_fail
const BAZ: i32 = Foo(25).bar(); // error, `bar` isn't `const` const BAZ: i32 = Foo(25).bar(); // error, `bar` isn't `const`
struct Foo(i32); struct Foo(i32);
@ -362,9 +364,9 @@ E0395: r##"
The value assigned to a constant scalar must be known at compile time, The value assigned to a constant scalar must be known at compile time,
which is not the case when comparing raw pointers. which is not the case when comparing raw pointers.
Erroneous code example: Erroneous code example:
```
```compile_fail
static FOO: i32 = 42; static FOO: i32 = 42;
static BAR: i32 = 42; static BAR: i32 = 42;
@ -391,10 +393,9 @@ let baz: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
E0396: r##" E0396: r##"
The value behind a raw pointer can't be determined at compile-time The value behind a raw pointer can't be determined at compile-time
(or even link-time), which means it can't be used in a constant (or even link-time), which means it can't be used in a constant
expression. expression. Erroneous code example:
For example: ```compile_fail
```
const REG_ADDR: *const u8 = 0x5f3759df as *const u8; const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
const VALUE: u8 = unsafe { *REG_ADDR }; const VALUE: u8 = unsafe { *REG_ADDR };
@ -416,7 +417,7 @@ E0397: r##"
It is not allowed for a mutable static to allocate or have destructors. For It is not allowed for a mutable static to allocate or have destructors. For
example: example:
``` ```compile_fail
// error: mutable statics are not allowed to have boxes // error: mutable statics are not allowed to have boxes
static mut FOO: Option<Box<usize>> = None; static mut FOO: Option<Box<usize>> = None;
@ -429,7 +430,7 @@ E0400: r##"
A user-defined dereference was attempted in an invalid context. Erroneous A user-defined dereference was attempted in an invalid context. Erroneous
code example: code example:
``` ```compile_fail
use std::ops::Deref; use std::ops::Deref;
struct A; struct A;
@ -473,7 +474,7 @@ E0492: r##"
A borrow of a constant containing interior mutability was attempted. Erroneous A borrow of a constant containing interior mutability was attempted. Erroneous
code example: code example:
``` ```compile_fail
use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT}; use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
const A: AtomicUsize = ATOMIC_USIZE_INIT; const A: AtomicUsize = ATOMIC_USIZE_INIT;
@ -500,7 +501,7 @@ static B: &'static AtomicUsize = &A; // ok!
You can also have this error while using a cell type: You can also have this error while using a cell type:
``` ```compile_fail
#![feature(const_fn)] #![feature(const_fn)]
use std::cell::Cell; use std::cell::Cell;
@ -552,7 +553,7 @@ E0493: r##"
A type with a destructor was assigned to an invalid type of variable. Erroneous A type with a destructor was assigned to an invalid type of variable. Erroneous
code example: code example:
``` ```compile_fail
struct Foo { struct Foo {
a: u32 a: u32
} }
@ -575,7 +576,7 @@ E0494: r##"
A reference of an interior static was assigned to another const/static. A reference of an interior static was assigned to another const/static.
Erroneous code example: Erroneous code example:
``` ```compile_fail
struct Foo { struct Foo {
a: u32 a: u32
} }

View File

@ -16,28 +16,27 @@ E0445: r##"
A private trait was used on a public type parameter bound. Erroneous code A private trait was used on a public type parameter bound. Erroneous code
examples: examples:
``` ```compile_fail
trait Foo { trait Foo {
fn dummy(&self) { } fn dummy(&self) { }
} }
pub trait Bar : Foo {} // error: private trait in public interface pub trait Bar : Foo {} // error: private trait in public interface
pub struct Bar<T: Foo>(pub T); // same error pub struct Bar2<T: Foo>(pub T); // same error
pub fn foo<T: Foo> (t: T) {} // same error pub fn foo<T: Foo> (t: T) {} // same error
``` ```
To solve this error, please ensure that the trait is also public. The trait To solve this error, please ensure that the trait is also public. The trait
can be made inaccessible if necessary by placing it into a private inner module, can be made inaccessible if necessary by placing it into a private inner module,
but it still has to be marked with `pub`. but it still has to be marked with `pub`. Example:
Example:
``` ```ignore
pub trait Foo { // we set the Foo trait public pub trait Foo { // we set the Foo trait public
fn dummy(&self) { } fn dummy(&self) { }
} }
pub trait Bar : Foo {} // ok! pub trait Bar : Foo {} // ok!
pub struct Bar<T: Foo>(pub T); // ok! pub struct Bar2<T: Foo>(pub T); // ok!
pub fn foo<T: Foo> (t: T) {} // ok! pub fn foo<T: Foo> (t: T) {} // ok!
``` ```
"##, "##,
@ -45,7 +44,7 @@ pub fn foo<T: Foo> (t: T) {} // ok!
E0446: r##" E0446: r##"
A private type was used in a public type signature. Erroneous code example: A private type was used in a public type signature. Erroneous code example:
``` ```compile_fail
mod Foo { mod Foo {
struct Bar(u32); struct Bar(u32);
@ -74,7 +73,7 @@ mod Foo {
E0447: r##" E0447: r##"
The `pub` keyword was used inside a function. Erroneous code example: The `pub` keyword was used inside a function. Erroneous code example:
``` ```compile_fail
fn foo() { fn foo() {
pub struct Bar; // error: visibility has no effect inside functions pub struct Bar; // error: visibility has no effect inside functions
} }
@ -88,7 +87,7 @@ is invalid.
E0448: r##" E0448: r##"
The `pub` keyword was used inside a public enum. Erroneous code example: The `pub` keyword was used inside a public enum. Erroneous code example:
``` ```compile_fail
pub enum Foo { pub enum Foo {
pub Bar, // error: unnecessary `pub` visibility pub Bar, // error: unnecessary `pub` visibility
} }
@ -97,13 +96,15 @@ pub enum Foo {
Since the enum is already public, adding `pub` on one its elements is Since the enum is already public, adding `pub` on one its elements is
unnecessary. Example: unnecessary. Example:
``` ```compile_fail
enum Foo { enum Foo {
pub Bar, // ok! pub Bar, // not ok!
} }
```
// or: This is the correct syntax:
```ignore
pub enum Foo { pub enum Foo {
Bar, // ok! Bar, // ok!
} }
@ -114,7 +115,7 @@ E0449: r##"
A visibility qualifier was used when it was unnecessary. Erroneous code A visibility qualifier was used when it was unnecessary. Erroneous code
examples: examples:
``` ```compile_fail
struct Bar; struct Bar;
trait Foo { trait Foo {
@ -131,7 +132,7 @@ pub impl Foo for Bar { // error: unnecessary visibility qualifier
To fix this error, please remove the visibility qualifier when it is not To fix this error, please remove the visibility qualifier when it is not
required. Example: required. Example:
``` ```ignore
struct Bar; struct Bar;
trait Foo { trait Foo {
@ -154,7 +155,7 @@ E0450: r##"
A tuple constructor was invoked while some of its fields are private. Erroneous A tuple constructor was invoked while some of its fields are private. Erroneous
code example: code example:
``` ```compile_fail
mod Bar { mod Bar {
pub struct Foo(isize); pub struct Foo(isize);
} }
@ -179,7 +180,7 @@ mod bar {
pub struct Foo(isize); pub struct Foo(isize);
impl Foo { impl Foo {
pub fn new(x: isize) { pub fn new(x: isize) -> Foo {
Foo(x) Foo(x)
} }
} }
@ -192,7 +193,7 @@ let f = bar::Foo::new(1);
E0451: r##" E0451: r##"
A struct constructor with private fields was invoked. Erroneous code example: A struct constructor with private fields was invoked. Erroneous code example:
``` ```compile_fail
mod Bar { mod Bar {
pub struct Foo { pub struct Foo {
pub a: isize, pub a: isize,
@ -216,8 +217,11 @@ mod Bar {
} }
let f = Bar::Foo{ a: 0, b: 0 }; // ok! let f = Bar::Foo{ a: 0, b: 0 }; // ok!
```
// or: Or:
```
mod Bar { mod Bar {
pub struct Foo { pub struct Foo {
pub a: isize, pub a: isize,

View File

@ -21,12 +21,12 @@ variable declarations and expression statements.
Here is an example that demonstrates the error: Here is an example that demonstrates the error:
``` ```compile_fail
fn f() { fn f() {
// Variable declaration before import // Variable declaration before import
let x = 0; let x = 0;
use std::io::Read; use std::io::Read;
... // ...
} }
``` ```
@ -39,7 +39,7 @@ Here is the previous example again, with the correct order:
fn f() { fn f() {
use std::io::Read; use std::io::Read;
let x = 0; let x = 0;
... // ...
} }
``` ```
@ -55,7 +55,7 @@ items under a new local name.
An example of this error: An example of this error:
``` ```compile_fail
use foo::baz; use foo::baz;
use bar::*; // error, do `use foo::baz as quux` instead on the previous line use bar::*; // error, do `use foo::baz as quux` instead on the previous line
@ -77,7 +77,7 @@ items under a new local name.
An example of this error: An example of this error:
``` ```compile_fail
use foo::baz; use foo::baz;
use bar::baz; // error, do `use bar::baz as quux` instead use bar::baz; // error, do `use bar::baz as quux` instead
@ -97,12 +97,13 @@ E0253: r##"
Attempt was made to import an unimportable value. This can happen when Attempt was made to import an unimportable value. This can happen when
trying to import a method from a trait. An example of this error: trying to import a method from a trait. An example of this error:
``` ```compile_fail
mod foo { mod foo {
pub trait MyTrait { pub trait MyTrait {
fn do_something(); fn do_something();
} }
} }
use foo::MyTrait::do_something; use foo::MyTrait::do_something;
``` ```
@ -115,7 +116,7 @@ module.
An example of this error: An example of this error:
``` ```compile_fail
use bar::foo; // error, do `use bar::foo as baz` instead use bar::foo; // error, do `use bar::foo as baz` instead
fn foo() {} fn foo() {}
@ -134,7 +135,7 @@ the same as another type or submodule defined in the module.
An example of this error: An example of this error:
``` ```compile_fail
use foo::Bar; // error use foo::Bar; // error
type Bar = u32; type Bar = u32;
@ -153,7 +154,7 @@ has been imported into the current module.
Wrong example: Wrong example:
``` ```compile_fail
extern crate a; extern crate a;
extern crate crate_a as a; extern crate crate_a as a;
``` ```
@ -163,7 +164,7 @@ external crate imported into the current module.
Correct example: Correct example:
``` ```ignore
extern crate a; extern crate a;
extern crate crate_a as other_name; extern crate crate_a as other_name;
``` ```
@ -172,9 +173,9 @@ extern crate crate_a as other_name;
E0260: r##" E0260: r##"
The name for an item declaration conflicts with an external crate's name. The name for an item declaration conflicts with an external crate's name.
For instance, For instance:
``` ```ignore
extern crate abc; extern crate abc;
struct abc; struct abc;
@ -184,7 +185,7 @@ There are two possible solutions:
Solution #1: Rename the item. Solution #1: Rename the item.
``` ```ignore
extern crate abc; extern crate abc;
struct xyz; struct xyz;
@ -192,7 +193,7 @@ struct xyz;
Solution #2: Import the crate with a different name. Solution #2: Import the crate with a different name.
``` ```ignore
extern crate abc as xyz; extern crate abc as xyz;
struct abc; struct abc;
@ -209,7 +210,7 @@ User-defined types or type parameters cannot shadow the primitive types.
This error indicates you tried to define a type, struct or enum with the same This error indicates you tried to define a type, struct or enum with the same
name as an existing primitive type: name as an existing primitive type:
``` ```compile_fail
struct u8 { struct u8 {
// ... // ...
} }
@ -220,7 +221,7 @@ To fix this, simply name it something else.
Such an error may also occur if you define a type parameter which shadows a Such an error may also occur if you define a type parameter which shadows a
primitive type. An example would be something like: primitive type. An example would be something like:
``` ```compile_fail
impl<u8> MyTrait for Option<u8> { impl<u8> MyTrait for Option<u8> {
// ... // ...
} }
@ -229,7 +230,7 @@ impl<u8> MyTrait for Option<u8> {
In such a case, if you meant for `u8` to be a generic type parameter (i.e. any In such a case, if you meant for `u8` to be a generic type parameter (i.e. any
type can be used in its place), use something like `T` instead: type can be used in its place), use something like `T` instead:
``` ```ignore
impl<T> MyTrait for Option<T> { impl<T> MyTrait for Option<T> {
// ... // ...
} }
@ -238,7 +239,7 @@ impl<T> MyTrait for Option<T> {
On the other hand, if you wished to refer to the specific type `u8`, remove it On the other hand, if you wished to refer to the specific type `u8`, remove it
from the type parameter list: from the type parameter list:
``` ```ignore
impl MyTrait for Option<u8> { impl MyTrait for Option<u8> {
// ... // ...
} }
@ -255,20 +256,22 @@ you attempted to `pub use` a type or value that was not itself public.
Here is an example that demonstrates the error: Here is an example that demonstrates the error:
``` ```compile_fail
mod foo { mod foo {
const X: u32 = 1; const X: u32 = 1;
} }
pub use foo::X; pub use foo::X;
``` ```
The solution to this problem is to ensure that the items that you are The solution to this problem is to ensure that the items that you are
re-exporting are themselves marked with `pub`: re-exporting are themselves marked with `pub`:
``` ```ignore
mod foo { mod foo {
pub const X: u32 = 1; pub const X: u32 = 1;
} }
pub use foo::X; pub use foo::X;
``` ```
@ -284,20 +287,22 @@ that you attempted to `pub use` a module that was not itself public.
Here is an example that demonstrates the error: Here is an example that demonstrates the error:
``` ```compile_fail
mod foo { mod foo {
pub const X: u32 = 1; pub const X: u32 = 1;
} }
pub use foo as foo2;
pub use foo as foo2;
``` ```
The solution to this problem is to ensure that the module that you are The solution to this problem is to ensure that the module that you are
re-exporting is itself marked with `pub`: re-exporting is itself marked with `pub`:
``` ```ignore
pub mod foo { pub mod foo {
pub const X: u32 = 1; pub const X: u32 = 1;
} }
pub use foo as foo2; pub use foo as foo2;
``` ```
@ -311,7 +316,7 @@ E0401: r##"
Inner items do not inherit type parameters from the functions they are Inner items do not inherit type parameters from the functions they are
embedded in. For example, this will not compile: embedded in. For example, this will not compile:
``` ```compile_fail
fn foo<T>(x: T) { fn foo<T>(x: T) {
fn bar(y: T) { // T is defined in the "outer" function fn bar(y: T) { // T is defined in the "outer" function
// .. // ..
@ -320,18 +325,18 @@ fn foo<T>(x: T) {
} }
``` ```
nor will this: Nor will this:
``` ```compile_fail
fn foo<T>(x: T) { fn foo<T>(x: T) {
type MaybeT = Option<T>; type MaybeT = Option<T>;
// ... // ...
} }
``` ```
or this: Or this:
``` ```compile_fail
fn foo<T>(x: T) { fn foo<T>(x: T) {
struct Foo { struct Foo {
x: T, x: T,
@ -351,7 +356,7 @@ If the item is a function, you may use a closure:
fn foo<T>(x: T) { fn foo<T>(x: T) {
let bar = |y: T| { // explicit type annotation may not be necessary let bar = |y: T| { // explicit type annotation may not be necessary
// .. // ..
} };
bar(x); bar(x);
} }
``` ```
@ -397,11 +402,12 @@ This may require additional type hints in the function body.
In case the item is a function inside an `impl`, defining a private helper In case the item is a function inside an `impl`, defining a private helper
function might be easier: function might be easier:
``` ```ignore
impl<T> Foo<T> { impl<T> Foo<T> {
pub fn foo(&self, x: T) { pub fn foo(&self, x: T) {
self.bar(x); self.bar(x);
} }
fn bar(&self, y: T) { fn bar(&self, y: T) {
// .. // ..
} }
@ -415,7 +421,7 @@ closures or copying the parameters should still work.
E0403: r##" E0403: r##"
Some type parameters have the same name. Example of erroneous code: Some type parameters have the same name. Example of erroneous code:
``` ```compile_fail
fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type fn foo<T, T>(s: T, u: T) {} // error: the name `T` is already used for a type
// parameter in this type parameter list // parameter in this type parameter list
``` ```
@ -432,7 +438,7 @@ E0404: r##"
You tried to implement something which was not a trait on an object. Example of You tried to implement something which was not a trait on an object. Example of
erroneous code: erroneous code:
``` ```compile_fail
struct Foo; struct Foo;
struct Bar; struct Bar;
@ -457,7 +463,7 @@ impl Foo for Bar { // ok!
E0405: r##" E0405: r##"
An unknown trait was implemented. Example of erroneous code: An unknown trait was implemented. Example of erroneous code:
``` ```compile_fail
struct Foo; struct Foo;
impl SomeTrait for Foo {} // error: use of undeclared trait name `SomeTrait` impl SomeTrait for Foo {} // error: use of undeclared trait name `SomeTrait`
@ -466,7 +472,7 @@ impl SomeTrait for Foo {} // error: use of undeclared trait name `SomeTrait`
Please verify that the name of the trait wasn't misspelled and ensure that it Please verify that the name of the trait wasn't misspelled and ensure that it
was imported. Example: was imported. Example:
``` ```ignore
// solution 1: // solution 1:
use some_file::SomeTrait; use some_file::SomeTrait;
@ -487,7 +493,7 @@ E0407: r##"
A definition of a method not in the implemented trait was given in a trait A definition of a method not in the implemented trait was given in a trait
implementation. Example of erroneous code: implementation. Example of erroneous code:
``` ```compile_fail
trait Foo { trait Foo {
fn a(); fn a();
} }
@ -540,7 +546,7 @@ E0411: r##"
The `Self` keyword was used outside an impl or a trait. Erroneous The `Self` keyword was used outside an impl or a trait. Erroneous
code example: code example:
``` ```compile_fail
<Self>::foo; // error: use of `Self` outside of an impl or trait <Self>::foo; // error: use of `Self` outside of an impl or trait
``` ```
@ -560,7 +566,7 @@ trait Baz : Foo {
However, be careful when two types has a common associated type: However, be careful when two types has a common associated type:
``` ```compile_fail
trait Foo { trait Foo {
type Bar; type Bar;
} }
@ -579,6 +585,14 @@ This problem can be solved by specifying from which trait we want
to use the `Bar` type: to use the `Bar` type:
``` ```
trait Foo {
type Bar;
}
trait Foo2 {
type Bar;
}
trait Baz : Foo + Foo2 { trait Baz : Foo + Foo2 {
fn bar() -> <Self as Foo>::Bar; // ok! fn bar() -> <Self as Foo>::Bar; // ok!
} }
@ -588,7 +602,7 @@ trait Baz : Foo + Foo2 {
E0412: r##" E0412: r##"
An undeclared type name was used. Example of erroneous codes: An undeclared type name was used. Example of erroneous codes:
``` ```compile_fail
impl Something {} // error: use of undeclared type name `Something` impl Something {} // error: use of undeclared type name `Something`
// or: // or:
trait Foo { trait Foo {
@ -605,13 +619,17 @@ you did declare it or imported it into the scope. Examples:
struct Something; struct Something;
impl Something {} // ok! impl Something {} // ok!
// or: // or:
trait Foo { trait Foo {
type N; type N;
fn bar(Self::N); // ok! fn bar(Self::N); // ok!
} }
//or:
// or:
fn foo<T>(x: T) {} // ok! fn foo<T>(x: T) {} // ok!
``` ```
"##, "##,
@ -620,14 +638,13 @@ E0413: r##"
A declaration shadows an enum variant or unit-like struct in scope. A declaration shadows an enum variant or unit-like struct in scope.
Example of erroneous code: Example of erroneous code:
``` ```compile_fail
struct Foo; struct Foo;
let Foo = 12i32; // error: declaration of `Foo` shadows an enum variant or let Foo = 12i32; // error: declaration of `Foo` shadows an enum variant or
// unit-like struct in scope // unit-like struct in scope
``` ```
To fix this error, rename the variable such that it doesn't shadow any enum To fix this error, rename the variable such that it doesn't shadow any enum
variable or structure in scope. Example: variable or structure in scope. Example:
@ -652,7 +669,7 @@ E0415: r##"
More than one function parameter have the same name. Example of erroneous More than one function parameter have the same name. Example of erroneous
code: code:
``` ```compile_fail
fn foo(f: i32, f: i32) {} // error: identifier `f` is bound more than fn foo(f: i32, f: i32) {} // error: identifier `f` is bound more than
// once in this parameter list // once in this parameter list
``` ```
@ -668,7 +685,7 @@ E0416: r##"
An identifier is bound more than once in a pattern. Example of erroneous An identifier is bound more than once in a pattern. Example of erroneous
code: code:
``` ```compile_fail
match (1, 2) { match (1, 2) {
(x, x) => {} // error: identifier `x` is bound more than once in the (x, x) => {} // error: identifier `x` is bound more than once in the
// same pattern // same pattern
@ -685,7 +702,7 @@ match (1, 2) {
Or maybe did you mean to unify? Consider using a guard: Or maybe did you mean to unify? Consider using a guard:
``` ```ignore
match (A, B, C) { match (A, B, C) {
(x, x2, see) if x == x2 => { /* A and B are equal, do one thing */ } (x, x2, see) if x == x2 => { /* A and B are equal, do one thing */ }
(y, z, see) => { /* A and B unequal; do another thing */ } (y, z, see) => { /* A and B unequal; do another thing */ }
@ -696,7 +713,7 @@ match (A, B, C) {
E0417: r##" E0417: r##"
A static variable was referenced in a pattern. Example of erroneous code: A static variable was referenced in a pattern. Example of erroneous code:
``` ```compile_fail
static FOO : i32 = 0; static FOO : i32 = 0;
match 0 { match 0 {
@ -725,7 +742,7 @@ E0419: r##"
An unknown enum variant, struct or const was used. Example of An unknown enum variant, struct or const was used. Example of
erroneous code: erroneous code:
``` ```compile_fail
match 0 { match 0 {
Something::Foo => {} // error: unresolved enum variant, struct Something::Foo => {} // error: unresolved enum variant, struct
// or const `Foo` // or const `Foo`
@ -751,7 +768,8 @@ match Something::NotFoo {
E0422: r##" E0422: r##"
You are trying to use an identifier that is either undefined or not a You are trying to use an identifier that is either undefined or not a
struct. For instance: struct. For instance:
```
``` compile_fail
fn main () { fn main () {
let x = Foo { x: 1, y: 2 }; let x = Foo { x: 1, y: 2 };
} }
@ -760,7 +778,7 @@ fn main () {
In this case, `Foo` is undefined, so it inherently isn't anything, and In this case, `Foo` is undefined, so it inherently isn't anything, and
definitely not a struct. definitely not a struct.
``` ```compile_fail
fn main () { fn main () {
let foo = 1; let foo = 1;
let x = foo { x: 1, y: 2 }; let x = foo { x: 1, y: 2 };
@ -775,7 +793,7 @@ E0423: r##"
A `struct` variant name was used like a function name. Example of A `struct` variant name was used like a function name. Example of
erroneous code: erroneous code:
``` ```compile_fail
struct Foo { a: bool}; struct Foo { a: bool};
let f = Foo(); let f = Foo();
@ -796,7 +814,7 @@ let f = Foo(); // ok!
E0424: r##" E0424: r##"
The `self` keyword was used in a static method. Example of erroneous code: The `self` keyword was used in a static method. Example of erroneous code:
``` ```compile_fail
struct Foo; struct Foo;
impl Foo { impl Foo {
@ -828,7 +846,7 @@ impl Foo {
E0425: r##" E0425: r##"
An unresolved name was used. Example of erroneous codes: An unresolved name was used. Example of erroneous codes:
``` ```compile_fail
something_that_doesnt_exist::foo; something_that_doesnt_exist::foo;
// error: unresolved name `something_that_doesnt_exist::foo` // error: unresolved name `something_that_doesnt_exist::foo`
@ -848,17 +866,23 @@ identifier being referred to is valid for the given situation. Example:
``` ```
enum something_that_does_exist { enum something_that_does_exist {
foo Foo,
} }
```
// or: Or:
```
mod something_that_does_exist { mod something_that_does_exist {
pub static foo : i32 = 0i32; pub static foo : i32 = 0i32;
} }
something_that_does_exist::foo; // ok! something_that_does_exist::foo; // ok!
```
// or: Or:
```
let unknown_variable = 12u32; let unknown_variable = 12u32;
let x = unknown_variable; // ok! let x = unknown_variable; // ok!
``` ```
@ -867,7 +891,7 @@ let x = unknown_variable; // ok!
E0426: r##" E0426: r##"
An undeclared label was used. Example of erroneous code: An undeclared label was used. Example of erroneous code:
``` ```compile_fail
loop { loop {
break 'a; // error: use of undeclared label `'a` break 'a; // error: use of undeclared label `'a`
} }
@ -886,7 +910,7 @@ E0428: r##"
A type or module has been defined more than once. Example of erroneous A type or module has been defined more than once. Example of erroneous
code: code:
``` ```compile_fail
struct Bar; struct Bar;
struct Bar; // error: duplicate definition of value `Bar` struct Bar; // error: duplicate definition of value `Bar`
``` ```
@ -903,7 +927,7 @@ struct Bar2; // ok!
E0430: r##" E0430: r##"
The `self` import appears more than once in the list. Erroneous code example: The `self` import appears more than once in the list. Erroneous code example:
``` ```compile_fail
use something::{self, self}; // error: `self` import can only appear once in use something::{self, self}; // error: `self` import can only appear once in
// the list // the list
``` ```
@ -911,7 +935,7 @@ use something::{self, self}; // error: `self` import can only appear once in
Please verify you didn't misspell the import name or remove the duplicated Please verify you didn't misspell the import name or remove the duplicated
`self` import. Example: `self` import. Example:
``` ```ignore
use something::self; // ok! use something::self; // ok!
``` ```
"##, "##,
@ -919,7 +943,7 @@ use something::self; // ok!
E0431: r##" E0431: r##"
`self` import was made. Erroneous code example: `self` import was made. Erroneous code example:
``` ```compile_fail
use {self}; // error: `self` import can only appear in an import list with a use {self}; // error: `self` import can only appear in an import list with a
// non-empty prefix // non-empty prefix
``` ```
@ -931,14 +955,14 @@ or verify you didn't misspell it.
E0432: r##" E0432: r##"
An import was unresolved. Erroneous code example: An import was unresolved. Erroneous code example:
``` ```compile_fail
use something::Foo; // error: unresolved import `something::Foo`. use something::Foo; // error: unresolved import `something::Foo`.
``` ```
Please verify you didn't misspell the import name or the import does exist Please verify you didn't misspell the import name or the import does exist
in the module from where you tried to import it. Example: in the module from where you tried to import it. Example:
``` ```ignore
use something::Foo; // ok! use something::Foo; // ok!
mod something { mod something {
@ -949,7 +973,7 @@ mod something {
Or, if you tried to use a module from an external crate, you may have missed Or, if you tried to use a module from an external crate, you may have missed
the `extern crate` declaration: the `extern crate` declaration:
``` ```ignore
extern crate homura; // Required to use the `homura` crate extern crate homura; // Required to use the `homura` crate
use homura::Madoka; use homura::Madoka;
@ -959,7 +983,7 @@ use homura::Madoka;
E0433: r##" E0433: r##"
Invalid import. Example of erroneous code: Invalid import. Example of erroneous code:
``` ```compile_fail
use something_which_doesnt_exist; use something_which_doesnt_exist;
// error: unresolved import `something_which_doesnt_exist` // error: unresolved import `something_which_doesnt_exist`
``` ```
@ -971,7 +995,7 @@ E0435: r##"
A non-constant value was used to initialise a constant. Example of erroneous A non-constant value was used to initialise a constant. Example of erroneous
code: code:
``` ```compile_fail
let foo = 42u32; let foo = 42u32;
const FOO : u32 = foo; // error: attempt to use a non-constant value in a const FOO : u32 = foo; // error: attempt to use a non-constant value in a
// constant // constant
@ -981,8 +1005,11 @@ To fix this error, please replace the value with a constant. Example:
``` ```
const FOO : u32 = 42u32; // ok! const FOO : u32 = 42u32; // ok!
```
// or: Or:
```
const OTHER_FOO : u32 = 42u32; const OTHER_FOO : u32 = 42u32;
const FOO : u32 = OTHER_FOO; // ok! const FOO : u32 = OTHER_FOO; // ok!
``` ```
@ -996,7 +1023,7 @@ in the trait.
Here is an example that demonstrates the error: Here is an example that demonstrates the error:
``` ```compile_fail
trait Foo {} trait Foo {}
impl Foo for i32 { impl Foo for i32 {
@ -1021,7 +1048,7 @@ match the name of any associated constant in the trait.
Here is an example that demonstrates the error: Here is an example that demonstrates the error:
``` ```compile_fail
#![feature(associated_consts)] #![feature(associated_consts)]
trait Foo {} trait Foo {}

View File

@ -15,12 +15,14 @@ register_long_diagnostics! {
E0510: r##" E0510: r##"
`return_address` was used in an invalid context. Erroneous code example: `return_address` was used in an invalid context. Erroneous code example:
``` ```compile_fail
#![feature(intrinsics)]
extern "rust-intrinsic" { extern "rust-intrinsic" {
fn return_address() -> *const u8; fn return_address() -> *const u8;
} }
pub unsafe fn by_value() -> i32 { unsafe fn by_value() -> i32 {
let _ = return_address(); let _ = return_address();
// error: invalid use of `return_address` intrinsic: function does // error: invalid use of `return_address` intrinsic: function does
// not use out pointer // not use out pointer
@ -35,11 +37,13 @@ the return register(s), the compiler will return the value by writing it into
space allocated in the caller's stack frame. Example: space allocated in the caller's stack frame. Example:
``` ```
#![feature(intrinsics)]
extern "rust-intrinsic" { extern "rust-intrinsic" {
fn return_address() -> *const u8; fn return_address() -> *const u8;
} }
pub unsafe fn by_pointer() -> String { unsafe fn by_pointer() -> String {
let _ = return_address(); let _ = return_address();
String::new() // ok! String::new() // ok!
} }
@ -50,7 +54,9 @@ E0511: r##"
Invalid monomorphization of an intrinsic function was used. Erroneous code Invalid monomorphization of an intrinsic function was used. Erroneous code
example: example:
``` ```compile_fail
#![feature(platform_intrinsics)]
extern "platform-intrinsic" { extern "platform-intrinsic" {
fn simd_add<T>(a: T, b: T) -> T; fn simd_add<T>(a: T, b: T) -> T;
} }
@ -62,6 +68,9 @@ unsafe { simd_add(0, 1); }
The generic type has to be a SIMD type. Example: The generic type has to be a SIMD type. Example:
``` ```
#![feature(repr_simd)]
#![feature(platform_intrinsics)]
#[repr(simd)] #[repr(simd)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct i32x1(i32); struct i32x1(i32);
@ -78,7 +87,7 @@ E0512: r##"
Transmute with two differently sized types was attempted. Erroneous code Transmute with two differently sized types was attempted. Erroneous code
example: example:
``` ```compile_fail
fn takes_u8(_: u8) {} fn takes_u8(_: u8) {}
fn main() { fn main() {
@ -103,7 +112,7 @@ fn main() {
E0515: r##" E0515: r##"
A constant index expression was out of bounds. Erroneous code example: A constant index expression was out of bounds. Erroneous code example:
``` ```compile_fail
let x = &[0, 1, 2][7]; // error: const index-expr is out of bounds let x = &[0, 1, 2][7]; // error: const index-expr is out of bounds
``` ```

File diff suppressed because it is too large Load Diff