From 6407b9405f834feb530c0e365865fb169125f6a1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 7 Feb 2016 13:02:52 +0100 Subject: [PATCH] Update long error explanations --- src/error-index-generator/main.rs | 14 +- src/librustc/diagnostics.rs | 318 ++++++++----- src/librustc_borrowck/diagnostics.rs | 37 +- src/librustc_passes/diagnostics.rs | 79 ++-- src/librustc_privacy/diagnostics.rs | 40 +- src/librustc_resolve/diagnostics.rs | 161 ++++--- src/librustc_trans/diagnostics.rs | 21 +- src/librustc_typeck/diagnostics.rs | 671 ++++++++++++++++++--------- 8 files changed, 848 insertions(+), 493 deletions(-) diff --git a/src/error-index-generator/main.rs b/src/error-index-generator/main.rs index 2271e55ee28..db9dd006f3c 100644 --- a/src/error-index-generator/main.rs +++ b/src/error-index-generator/main.rs @@ -178,13 +178,13 @@ fn main_with_result(format: OutputFormat) -> Result<(), Box> { let metadata_dir = get_metadata_dir(&build_arch); let err_map = try!(load_all_errors(&metadata_dir)); match format { - OutputFormat::Unknown(s) => panic!("Unknown output format: {}", s), - OutputFormat::HTML(h) => try!(render_error_page(&err_map, - Path::new("doc/error-index.html"), - h)), - OutputFormat::Markdown(m) => try!(render_error_page(&err_map, - Path::new("doc/error-index.html"), - m)), + OutputFormat::Unknown(s) => panic!("Unknown output format: {}", s), + OutputFormat::HTML(h) => try!(render_error_page(&err_map, + Path::new("doc/error-index.html"), + h)), + OutputFormat::Markdown(m) => try!(render_error_page(&err_map, + Path::new("doc/error-index.md"), + m)), } Ok(()) } diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 9dbc75b960e..a2b85ef831b 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -25,7 +25,7 @@ is too specific or the ordering is incorrect. For example, the following `match` block has too many arms: -``` +```compile_fail match foo { Some(bar) => {/* ... */} 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: ``` +enum Empty {} + fn foo(x: Empty) { match x { // empty @@ -59,7 +61,9 @@ fn foo(x: Empty) { However, this won't: -``` +```compile_fail +enum Empty {} + fn foo(x: Option) { match x { // empty @@ -72,12 +76,14 @@ E0003: r##" 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: -``` +```compile_fail const NAN: f32 = 0.0 / 0.0; +let number = 0.1f32; + match number { NAN => { /* ... */ }, - // ... + _ => {} } ``` @@ -85,10 +91,11 @@ To match against NaN values, you should instead use the `is_nan()` method in a guard, like so: ``` +let number = 0.1f32; + match number { - // ... x if x.is_nan() => { /* ... */ } - // ... + _ => {} } ``` "##, @@ -120,15 +127,16 @@ the following is invalid as it requires the entire `Option` to be moved into a variable called `op_string` while simultaneously requiring the inner String to be moved into a variable called `s`. -``` +```compile_fail let x = Some("s".to_string()); + match x { - op_string @ Some(s) => ... - None => ... + op_string @ Some(s) => {} + None => {} } ``` -See also Error 303. +See also the error E0303. "##, E0008: r##" @@ -140,7 +148,7 @@ from being available in the body of the match arm. Consider the following: ``` match Some("hi".to_string()) { Some(s) if s.len() == 0 => // use s. - ... + _ => {} } ``` @@ -155,7 +163,7 @@ argument by value. match Some("hi".to_string()) { Some(s) if { drop(s); false } => (), Some(s) => // use s. - ... + _ => {} } ``` @@ -174,7 +182,7 @@ This limitation may be removed in a future version of Rust. Wrong example: -``` +```compile_fail struct 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 code example: -``` +```compile_fail const X: i32 = 42 / 0; // 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: -``` +```compile_fail trait Trait { 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 situation like the following: -``` +```compile_fail +trait Trait { + fn foo(&self) -> Self; +} + fn call_foo(x: Box) { let y = x.foo(); // What type is y? // ... @@ -324,11 +336,13 @@ have: trait Trait { fn foo(&self); } + impl Trait for String { fn foo(&self) { // implementation 1 } } + impl Trait for u8 { fn foo(&self) { // implementation 2 @@ -351,7 +365,7 @@ fn foo(x: T) { } ``` -the machine code for `foo::()`, `foo::()`, `foo::()`, or any +The machine code for `foo::()`, `foo::()`, `foo::()`, 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::()`. When we have additional @@ -373,22 +387,25 @@ trait Trait { fn foo(&self, on: T); // more methods } + impl Trait for String { fn foo(&self, on: T) { // implementation 1 } } + impl Trait for u8 { fn foo(&self, on: T) { // implementation 2 } } + // 8 more implementations ``` Now, if we have the following code: -``` +```ignore fn call_foo(thing: Box) { thing.foo(true); // this could be any one of the 8 types above thing.foo(1); @@ -396,7 +413,7 @@ fn call_foo(thing: Box) { } ``` -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 `foo()`. In this case this turns out to be (10 types implementing `Trait`)*(3 types being fed to `foo()`) = 30 implementations! @@ -422,7 +439,7 @@ 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 +a way to get a pointer to the method table for them. ``` trait Foo { @@ -446,7 +463,7 @@ trait Foo { This is similar to the second sub-error, but subtler. It happens in situations like the following: -``` +```compile_fail trait Super {} trait Trait: Super { @@ -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: -``` +```compile_fail // error, invalid recursive struct type struct ListNode { head: u8, @@ -521,7 +538,7 @@ E0109: r##" You tried to give a type parameter to a type which doesn't need it. Erroneous code example: -``` +```compile_fail type X = u32; // 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. Erroneous code example: -``` +```compile_fail type X = u32<'static>; // error: lifetime parameters are not allowed on // this type ``` @@ -605,8 +622,8 @@ parameters are involved, this cannot always be done. So, for example, the following is not allowed: -``` -struct Foo(Vec) +```compile_fail +struct Foo(Vec); fn foo(x: Vec) { // we are transmuting between Vec and Foo 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, for example: -``` +```ignore +struct Foo(Vec); + trait MyTransmutableType { - fn transmute(Vec) -> Foo + fn transmute(Vec) -> Foo; } impl MyTransmutableType for u8 { @@ -641,11 +660,13 @@ impl MyTransmutableType for u8 { transmute(x) } } + impl MyTransmutableType for String { fn transmute(x: Foo) -> Vec { transmute(x) } } + // ... more impls for the types you intend to transmute fn foo(x: Vec) { @@ -660,7 +681,7 @@ is a size mismatch in one of the impls. It is also possible to manually transmute: -``` +```ignore 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; + 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), use a regular `let`-binding instead. For instance: -``` +```compile_fail struct Irrefutable(i32); let irr = Irrefutable(0); @@ -717,8 +739,14 @@ if let Irrefutable(x) = irr { // This body will always be executed. foo(x); } +``` + +Try this instead: + +```ignore +struct Irrefutable(i32); +let irr = Irrefutable(0); -// Try this instead: let Irrefutable(x) = irr; 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), use a regular `let`-binding inside a `loop` instead. For instance: -``` +```compile_fail struct Irrefutable(i32); 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 { let Irrefutable(x) = irr; ... @@ -752,16 +785,23 @@ Enum variants are qualified by default. For example, given this type: ``` enum Method { GET, - POST + POST, } ``` -you would match it using: +You would match it using: ``` +enum Method { + GET, + POST, +} + +let m = Method::GET; + match m { - Method::GET => ... - Method::POST => ... + Method::GET => {}, + Method::POST => {}, } ``` @@ -772,7 +812,7 @@ that happens. Qualified names are good practice, and most code works well with them. But if you prefer them unqualified, you can import the variants into scope: -``` +```ignore use Method::*; 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 `pub use`: -``` +```ignore pub use Method::*; enum Method { GET, POST } ``` @@ -790,7 +830,7 @@ E0229: r##" An associated type binding was done outside of the type parameter declaration and `where` clause. Erroneous code example: -``` +```compile_fail pub trait Foo { type A; fn boo(&self) -> ::A; @@ -810,13 +850,13 @@ fn baz(x: &>::A) {} To solve this error, please move the type bindings in the type parameter declaration: -``` +```ignore fn baz>(x: &::A) {} // ok! ``` -or in the `where` clause: +Or in the `where` clause: -``` +```ignore fn baz(x: &::A) where I: Foo {} ``` "##, @@ -827,7 +867,7 @@ used. These two examples illustrate the problem: -``` +```compile_fail // error, use of undeclared lifetime name `'a` fn foo(x: &'a str) { } @@ -840,7 +880,7 @@ struct Foo { These can be fixed by declaring lifetime parameters: ``` -fn foo<'a>(x: &'a str) { } +fn foo<'a>(x: &'a str) {} struct Foo<'a> { 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 the lifetime of the entire program, this is an error: -``` +```compile_fail // error, invalid lifetime parameter name `'static` 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 example: -``` +```compile_fail // error, lifetime name `'a` declared twice in the same scope 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##" An unknown external lang item was used. Erroneous code example: -``` +```compile_fail #![feature(lang_items)] extern "C" { @@ -896,9 +936,9 @@ extern "C" { E0269: r##" 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 { if x > 0 { 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 returned. All possible control paths must eventually return a `u8`, which is not happening here. @@ -915,7 +955,7 @@ happening here. An easy fix for this in a complicated function is to specify a default return value, if possible: -``` +```ignore fn foo(x: u8) -> u8 { if x > 0 { 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: -``` +```no_run fn foo() -> ! { loop {} } @@ -947,18 +987,24 @@ fn bar() -> ! { fn baz() -> ! { 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 -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 { 1 => 1, 2 => 4, _ => foo() // diverging function called here }; + 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 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: -``` -fn foo() -> { +```ignore +fn foo() -> ! { 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 { 1 => 1, 2 => 4, _ => foo() }; + println!("{}", y); ``` @@ -1004,18 +1057,21 @@ Examples follow. Here is a basic example: -``` +```compile_fail trait Trait { type AssociatedType; } + fn foo(t: T) where T: Trait { println!("in foo"); } + impl Trait for i8 { type AssociatedType = &'static str; } + foo(3_i8); ``` Here is that same example again, with some explanatory comments: -``` +```ignore trait Trait { type AssociatedType; } fn foo(t: T) where T: Trait { @@ -1053,12 +1109,12 @@ foo(3_i8); Here is a more subtle instance of the same problem, that can arise with for-loops in Rust: -``` +```compile_fail let vs: Vec = vec![1, 2, 3, 4]; for v in &vs { 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 explanatory comments for the same example: -``` +```ignore { let vs = vec![1, 2, 3, 4]; @@ -1115,10 +1171,13 @@ So we can fix the previous examples like this: ``` // Basic Example: trait Trait { type AssociatedType; } + fn foo(t: T) where T: Trait { println!("in foo"); } + impl Trait for i8 { type AssociatedType = &'static str; } + foo(3_i8); // 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 compiled: -``` +```compile_fail fn foo>(x: T){} #[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 compiled: -``` +```compile_fail fn foo>(x: T){} #[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 compiled: -``` +```compile_fail fn foo>(x: T){} #[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 in resolving some type bounds. -For example, in the following code +For example, in the following code: -``` +```compile_fail trait Foo {} struct Bar(T); @@ -1228,7 +1287,7 @@ struct Bar(T); impl Foo for T where Bar: Foo {} ``` -to determine if a `T` is `Foo`, we need to check if `Bar` is `Foo`. However, +To determine if a `T` is `Foo`, we need to check if `Bar` is `Foo`. However, to do this check, we need to determine that `Bar>` is `Foo`. To determine this, we check if `Bar>>` is `Foo`, and so on. This is clearly a 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 the bounds specified in the original trait. For example: -``` +```compile_fail trait Foo { - fn foo(x: T); + fn foo(x: T); } impl Foo for bool { - fn foo(x: T) where T: Copy {} + fn foo(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 expected that trait. Erroneous code example: -``` +```compile_fail // here we declare the Foo trait with a bar method trait Foo { 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 `Fn`-based types. Erroneous code example: -``` +```compile_fail fn foo(x: F) { } 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 that reverses the characters of a string: -``` +```compile_fail 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 have the same return type. For instance: -``` +```compile_fail struct Foo { - // Some fields omitted. + num: T, } impl Foo { @@ -1399,17 +1458,19 @@ to unambiguously choose an implementation. For example: -``` +```compile_fail 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 } } @@ -1424,6 +1485,16 @@ fn main() { 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(); @@ -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 instance: -``` +```compile_fail +let xs : Vec> = vec!(Some(1), None); + // This fails because `None` is not covered. for Some(x) in xs { - ... + // ... } +``` + +Match inside the loop instead: + +``` +let xs : Vec> = vec!(Some(1), None); -// Match inside the loop instead: for item in xs { match item { - Some(x) => ... - None => ... + Some(x) => {}, + None => {}, } } +``` + +Or use `if let`: + +``` +let xs : Vec> = vec!(Some(1), None); -// Or use `if let`: for item in xs { 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 borrows were allowed: -``` +```compile_fail match Some(()) { None => { }, 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 were allowed: -``` +```compile_fail match Some(()) { None => { }, 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 restriction, but for now patterns must be rewritten without sub-bindings. -``` +```ignore // Before. match Some("hi".to_string()) { - ref op_string_ref @ Some(ref s) => ... - None => ... + ref op_string_ref @ Some(s) => {}, + None => {}, } // After. match Some("hi".to_string()) { Some(ref s) => { let op_string_ref = &Some(s); - ... - } - None => ... + // ... + }, + None => {}, } ``` @@ -1549,7 +1632,7 @@ variable. For example: -``` +```compile_fail 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 denotes this will cause this error. -``` +```compile_fail // 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 struct 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> { 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 denotes this will cause this error. -``` +```compile_fail // This won't compile because T is not constrained to the static lifetime // the reference needs struct Foo { 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 { 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 defined as follows: -``` +```ignore fn foo(arg: &Box) { ... } ``` -you might change it to: +You might change it to: -``` +```ignore fn foo<'a>(arg: &Box) { ... } ``` @@ -1663,7 +1751,7 @@ contain references (with a maximum lifetime of `'a`). E0452: r##" An invalid lint attribute has been given. Erroneous code example: -``` +```compile_fail #![allow(foo = "")] // error: malformed lint attribute ``` @@ -1680,7 +1768,7 @@ lint name). Ensure the attribute is of this form: E0496: r##" A lifetime name is shadowing another lifetime name. Erroneous code example: -``` +```compile_fail struct Foo<'a> { a: &'a i32, } @@ -1713,7 +1801,7 @@ E0497: r##" 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() {} @@ -1729,7 +1817,7 @@ item. Examples of erroneous code: -``` +```compile_fail #[repr(C)] type Foo = u8; @@ -1777,7 +1865,7 @@ something other than a function or method. Examples of erroneous code: -``` +```compile_fail #[inline(always)] struct Foo; @@ -1811,9 +1899,9 @@ register_diagnostics! { // E0285, // overflow evaluation builtin bounds E0298, // mismatched types between arms E0299, // mismatched types between arms - // E0300, // unexpanded macro - // E0304, // expected signed integer constant - // E0305, // expected constant +// E0300, // unexpanded macro +// E0304, // expected signed integer constant +// E0305, // expected constant E0311, // thing may not live long enough E0312, // lifetime of reference outlives lifetime of borrowed content E0313, // lifetime of borrowed pointer outlives lifetime of captured variable diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs index 6cbea1abbb5..29944aaf367 100644 --- a/src/librustc_borrowck/diagnostics.rs +++ b/src/librustc_borrowck/diagnostics.rs @@ -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 return a closure: -``` +```compile_fail fn foo() -> Box u32> { let x = 0u32; 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: -``` +```compile_fail fn foo() { let x = 0u32; let y = 1u32; @@ -65,10 +65,11 @@ about safety. E0381: r##" It is not allowed to use or capture an uninitialized variable. For example: -``` +```compile_fail fn main() { let x: i32; let y = x; // error, use of possibly uninitialized variable +} ``` 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 have been moved elsewhere. For example: -``` +```compile_fail struct MyStruct { s: u32 } fn main() { @@ -144,7 +145,11 @@ structure that is currently uninitialized. For example, this can happen when a drop has taken place: -``` +```compile_fail +struct Foo { + a: u32, +} + let mut x = Foo { a: 1 }; drop(x); // `x` is now uninitialized 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: ``` +struct Foo { + a: u32, +} + let mut x = Foo { a: 1 }; drop(x); x = Foo { a: 2 }; @@ -163,7 +172,7 @@ E0384: r##" This error occurs when an attempt is made to reassign an immutable variable. For example: -``` +```compile_fail fn main(){ let x = 3; 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`: -``` +```compile_fail let mut x: i64 = 1; let y: Box<_> = Box::new(&mut x); **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`: ``` +use std::cell::Cell; + let x: i64 = 1; let y: Box> = Box::new(Cell::new(x)); y.set(2); @@ -215,12 +226,12 @@ E0387: r##" 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: -``` +```compile_fail // 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. fn foo(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...` fn mutable() { let mut x = 0u32; @@ -254,6 +265,8 @@ could be redefined as below: ``` use std::cell::Cell; +fn foo(f: F) { } + fn mutable() { let x = Cell::new(0u32); foo(|| x.set(2)); @@ -268,7 +281,7 @@ https://doc.rust-lang.org/std/cell/ E0499: r##" A variable was borrowed as mutable more than once. Erroneous code example: -``` +```compile_fail let mut i = 0; let mut x = &mut i; let mut a = &mut i; @@ -296,7 +309,7 @@ let c = &i; // still ok! E0507: r##" You tried to move out of a value which was borrowed. Erroneous code example: -``` +```compile_fail use std::cell::RefCell; struct TheDarkKnight; @@ -380,7 +393,7 @@ fn main() { Moving out of a member of a mutably borrowed struct is fine if you put something back. `mem::replace` can be used for that: -``` +```ignore struct TheDarkKnight; impl TheDarkKnight { diff --git a/src/librustc_passes/diagnostics.rs b/src/librustc_passes/diagnostics.rs index 27354c28d85..c89e9bb1959 100644 --- a/src/librustc_passes/diagnostics.rs +++ b/src/librustc_passes/diagnostics.rs @@ -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 code example: -``` +```compile_fail #![feature(box_syntax)] const CON : Box = 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 at compile time. -Bad example: +Erroneous code example: -``` +```compile_fail use std::ops::Index; struct Foo { a: u8 } @@ -53,16 +53,16 @@ Example: ``` const a: &'static [i32] = &[1, 2, 3]; -const b: i32 = a[0]; // Good! +const b: i32 = a[0]; // Ok! ``` "##, E0013: r##" 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` -here: +variable cannot refer to a static variable. For example, `Y` cannot refer to +`X` here: -``` +```compile_fail static X: i32 = 42; const Y: i32 = X; ``` @@ -80,9 +80,9 @@ E0014: r##" 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. Example: +allowed items. Erroneous code xample: -``` +```compile_fail 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 }; // 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##" 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! ``` @@ -129,9 +129,10 @@ const FOO: i32 = { const X : i32 = 0; X }; "##, 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; const C: i32 = 2; @@ -156,7 +157,8 @@ can't cast a pointer to an integer because the address of a pointer can vary. For example, if you write: -``` + +```compile_fail static MY_STATIC: u32 = 42; static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize; static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR; @@ -184,10 +186,10 @@ accessed directly. E0019: r##" 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 -erroneous code: +because the expression's value must be known at compile-time. Erroneous code +example: -``` +```compile_fail enum Test { V1 } @@ -222,13 +224,13 @@ E0022: r##" Constant functions are not allowed to mutate anything. Thus, binding to an argument with a mutable pattern is not allowed. For example, -``` +```compile_fail const fn foo(mut x: u8) { // 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 you need to mutate the argument, try lazily initializing a global variable @@ -244,12 +246,12 @@ range. For example: -``` +```compile_fail match 5u32 { // This range is ok, albeit pointless. - 1 ... 1 => ... + 1 ... 1 => {} // 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: -``` +```compile_fail const X: u32 = X; ``` -``` +```compile_fail const X: u32 = Y; const Y: u32 = X; ``` @@ -282,7 +284,7 @@ E0267: r##" This error indicates the use of a loop keyword (`break` or `continue`) inside a closure but outside of any loop. Erroneous code example: -``` +```compile_fail 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 be taken. Erroneous code example: -``` +```compile_fail fn some_func() { break; // error: `break` outside of loop } @@ -329,7 +331,7 @@ in statics, constants, and constant functions. For example: -``` +```compile_fail const BAZ: i32 = Foo(25).bar(); // error, `bar` isn't `const` struct Foo(i32); @@ -362,9 +364,9 @@ E0395: r##" The value assigned to a constant scalar must be known at compile time, which is not the case when comparing raw pointers. - Erroneous code example: -``` + +```compile_fail static FOO: i32 = 42; static BAR: i32 = 42; @@ -391,10 +393,9 @@ let baz: bool = { (&FOO as *const i32) == (&BAR as *const i32) }; E0396: r##" 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 -expression. +expression. Erroneous code example: -For example: -``` +```compile_fail const REG_ADDR: *const u8 = 0x5f3759df as *const u8; 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 example: -``` +```compile_fail // error: mutable statics are not allowed to have boxes static mut FOO: Option> = None; @@ -429,7 +430,7 @@ E0400: r##" A user-defined dereference was attempted in an invalid context. Erroneous code example: -``` +```compile_fail use std::ops::Deref; struct A; @@ -473,7 +474,7 @@ E0492: r##" A borrow of a constant containing interior mutability was attempted. Erroneous code example: -``` +```compile_fail use std::sync::atomic::{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: -``` +```compile_fail #![feature(const_fn)] use std::cell::Cell; @@ -552,7 +553,7 @@ E0493: r##" A type with a destructor was assigned to an invalid type of variable. Erroneous code example: -``` +```compile_fail struct Foo { a: u32 } @@ -575,7 +576,7 @@ E0494: r##" A reference of an interior static was assigned to another const/static. Erroneous code example: -``` +```compile_fail struct Foo { a: u32 } diff --git a/src/librustc_privacy/diagnostics.rs b/src/librustc_privacy/diagnostics.rs index 3fbe3bc2005..d124ead5091 100644 --- a/src/librustc_privacy/diagnostics.rs +++ b/src/librustc_privacy/diagnostics.rs @@ -16,28 +16,27 @@ E0445: r##" A private trait was used on a public type parameter bound. Erroneous code examples: -``` +```compile_fail trait Foo { fn dummy(&self) { } } pub trait Bar : Foo {} // error: private trait in public interface -pub struct Bar(pub T); // same error +pub struct Bar2(pub T); // same error pub fn foo (t: T) {} // same error ``` 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, -but it still has to be marked with `pub`. -Example: +but it still has to be marked with `pub`. Example: -``` +```ignore pub trait Foo { // we set the Foo trait public fn dummy(&self) { } } pub trait Bar : Foo {} // ok! -pub struct Bar(pub T); // ok! +pub struct Bar2(pub T); // ok! pub fn foo (t: T) {} // ok! ``` "##, @@ -45,7 +44,7 @@ pub fn foo (t: T) {} // ok! E0446: r##" A private type was used in a public type signature. Erroneous code example: -``` +```compile_fail mod Foo { struct Bar(u32); @@ -74,7 +73,7 @@ mod Foo { E0447: r##" The `pub` keyword was used inside a function. Erroneous code example: -``` +```compile_fail fn foo() { pub struct Bar; // error: visibility has no effect inside functions } @@ -88,7 +87,7 @@ is invalid. E0448: r##" The `pub` keyword was used inside a public enum. Erroneous code example: -``` +```compile_fail pub enum Foo { 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 unnecessary. Example: -``` +```compile_fail enum Foo { - pub Bar, // ok! + pub Bar, // not ok! } +``` -// or: +This is the correct syntax: +```ignore pub enum Foo { Bar, // ok! } @@ -114,7 +115,7 @@ E0449: r##" A visibility qualifier was used when it was unnecessary. Erroneous code examples: -``` +```compile_fail struct Bar; 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 required. Example: -``` +```ignore struct Bar; trait Foo { @@ -154,7 +155,7 @@ E0450: r##" A tuple constructor was invoked while some of its fields are private. Erroneous code example: -``` +```compile_fail mod Bar { pub struct Foo(isize); } @@ -179,7 +180,7 @@ mod bar { pub struct Foo(isize); impl Foo { - pub fn new(x: isize) { + pub fn new(x: isize) -> Foo { Foo(x) } } @@ -192,7 +193,7 @@ let f = bar::Foo::new(1); E0451: r##" A struct constructor with private fields was invoked. Erroneous code example: -``` +```compile_fail mod Bar { pub struct Foo { pub a: isize, @@ -216,8 +217,11 @@ mod Bar { } let f = Bar::Foo{ a: 0, b: 0 }; // ok! +``` -// or: +Or: + +``` mod Bar { pub struct Foo { pub a: isize, diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 16bcf84b795..99c29bbb8ef 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -21,12 +21,12 @@ variable declarations and expression statements. Here is an example that demonstrates the error: -``` +```compile_fail fn f() { // Variable declaration before import let x = 0; use std::io::Read; - ... + // ... } ``` @@ -39,7 +39,7 @@ Here is the previous example again, with the correct order: fn f() { use std::io::Read; let x = 0; - ... + // ... } ``` @@ -55,7 +55,7 @@ items under a new local name. An example of this error: -``` +```compile_fail use foo::baz; 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: -``` +```compile_fail use foo::baz; 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 trying to import a method from a trait. An example of this error: -``` +```compile_fail mod foo { pub trait MyTrait { fn do_something(); } } + use foo::MyTrait::do_something; ``` @@ -115,7 +116,7 @@ module. An example of this error: -``` +```compile_fail use bar::foo; // error, do `use bar::foo as baz` instead fn foo() {} @@ -134,7 +135,7 @@ the same as another type or submodule defined in the module. An example of this error: -``` +```compile_fail use foo::Bar; // error type Bar = u32; @@ -153,7 +154,7 @@ has been imported into the current module. Wrong example: -``` +```compile_fail extern crate a; extern crate crate_a as a; ``` @@ -163,7 +164,7 @@ external crate imported into the current module. Correct example: -``` +```ignore extern crate a; extern crate crate_a as other_name; ``` @@ -172,9 +173,9 @@ extern crate crate_a as other_name; E0260: r##" The name for an item declaration conflicts with an external crate's name. -For instance, +For instance: -``` +```ignore extern crate abc; struct abc; @@ -184,7 +185,7 @@ There are two possible solutions: Solution #1: Rename the item. -``` +```ignore extern crate abc; struct xyz; @@ -192,7 +193,7 @@ struct xyz; Solution #2: Import the crate with a different name. -``` +```ignore extern crate abc as xyz; 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 name as an existing primitive type: -``` +```compile_fail 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 primitive type. An example would be something like: -``` +```compile_fail impl MyTrait for Option { // ... } @@ -229,7 +230,7 @@ impl MyTrait for Option { 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: -``` +```ignore impl MyTrait for Option { // ... } @@ -238,7 +239,7 @@ impl MyTrait for Option { On the other hand, if you wished to refer to the specific type `u8`, remove it from the type parameter list: -``` +```ignore impl MyTrait for Option { // ... } @@ -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: -``` +```compile_fail mod foo { const X: u32 = 1; } + pub use foo::X; ``` The solution to this problem is to ensure that the items that you are re-exporting are themselves marked with `pub`: -``` +```ignore mod foo { pub const X: u32 = 1; } + 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: -``` +```compile_fail mod foo { 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 re-exporting is itself marked with `pub`: -``` +```ignore pub mod foo { pub const X: u32 = 1; } + pub use foo as foo2; ``` @@ -311,7 +316,7 @@ E0401: r##" Inner items do not inherit type parameters from the functions they are embedded in. For example, this will not compile: -``` +```compile_fail fn foo(x: T) { fn bar(y: T) { // T is defined in the "outer" function // .. @@ -320,18 +325,18 @@ fn foo(x: T) { } ``` -nor will this: +Nor will this: -``` +```compile_fail fn foo(x: T) { type MaybeT = Option; // ... } ``` -or this: +Or this: -``` +```compile_fail fn foo(x: T) { struct Foo { x: T, @@ -351,7 +356,7 @@ If the item is a function, you may use a closure: fn foo(x: T) { let bar = |y: T| { // explicit type annotation may not be necessary // .. - } + }; 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 function might be easier: -``` +```ignore impl Foo { pub fn foo(&self, x: T) { self.bar(x); } + fn bar(&self, y: T) { // .. } @@ -415,7 +421,7 @@ closures or copying the parameters should still work. E0403: r##" Some type parameters have the same name. Example of erroneous code: -``` +```compile_fail fn foo(s: T, u: T) {} // error: the name `T` is already used for a type // 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 erroneous code: -``` +```compile_fail struct Foo; struct Bar; @@ -457,7 +463,7 @@ impl Foo for Bar { // ok! E0405: r##" An unknown trait was implemented. Example of erroneous code: -``` +```compile_fail struct Foo; 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 was imported. Example: -``` +```ignore // solution 1: 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 implementation. Example of erroneous code: -``` +```compile_fail trait Foo { fn a(); } @@ -540,7 +546,7 @@ E0411: r##" The `Self` keyword was used outside an impl or a trait. Erroneous code example: -``` +```compile_fail ::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: -``` +```compile_fail trait Foo { type Bar; } @@ -579,6 +585,14 @@ This problem can be solved by specifying from which trait we want to use the `Bar` type: ``` +trait Foo { + type Bar; +} + +trait Foo2 { + type Bar; +} + trait Baz : Foo + Foo2 { fn bar() -> ::Bar; // ok! } @@ -588,7 +602,7 @@ trait Baz : Foo + Foo2 { E0412: r##" An undeclared type name was used. Example of erroneous codes: -``` +```compile_fail impl Something {} // error: use of undeclared type name `Something` // or: trait Foo { @@ -605,13 +619,17 @@ you did declare it or imported it into the scope. Examples: struct Something; impl Something {} // ok! + // or: + trait Foo { type N; fn bar(Self::N); // ok! } -//or: + +// or: + fn foo(x: T) {} // ok! ``` "##, @@ -620,14 +638,13 @@ E0413: r##" A declaration shadows an enum variant or unit-like struct in scope. Example of erroneous code: -``` +```compile_fail struct Foo; let Foo = 12i32; // error: declaration of `Foo` shadows an enum variant or // unit-like struct in scope ``` - To fix this error, rename the variable such that it doesn't shadow any enum variable or structure in scope. Example: @@ -652,7 +669,7 @@ E0415: r##" More than one function parameter have the same name. Example of erroneous code: -``` +```compile_fail fn foo(f: i32, f: i32) {} // error: identifier `f` is bound more than // once in this parameter list ``` @@ -668,7 +685,7 @@ E0416: r##" An identifier is bound more than once in a pattern. Example of erroneous code: -``` +```compile_fail match (1, 2) { (x, x) => {} // error: identifier `x` is bound more than once in the // same pattern @@ -685,7 +702,7 @@ match (1, 2) { Or maybe did you mean to unify? Consider using a guard: -``` +```ignore match (A, B, C) { (x, x2, see) if x == x2 => { /* A and B are equal, do one thing */ } (y, z, see) => { /* A and B unequal; do another thing */ } @@ -696,7 +713,7 @@ match (A, B, C) { E0417: r##" A static variable was referenced in a pattern. Example of erroneous code: -``` +```compile_fail static FOO : i32 = 0; match 0 { @@ -725,7 +742,7 @@ E0419: r##" An unknown enum variant, struct or const was used. Example of erroneous code: -``` +```compile_fail match 0 { Something::Foo => {} // error: unresolved enum variant, struct // or const `Foo` @@ -751,7 +768,8 @@ match Something::NotFoo { E0422: r##" You are trying to use an identifier that is either undefined or not a struct. For instance: -``` + +``` compile_fail fn main () { 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 definitely not a struct. -``` +```compile_fail fn main () { let foo = 1; 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 erroneous code: -``` +```compile_fail struct Foo { a: bool}; let f = Foo(); @@ -796,7 +814,7 @@ let f = Foo(); // ok! E0424: r##" The `self` keyword was used in a static method. Example of erroneous code: -``` +```compile_fail struct Foo; impl Foo { @@ -828,7 +846,7 @@ impl Foo { E0425: r##" An unresolved name was used. Example of erroneous codes: -``` +```compile_fail 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 { - foo + Foo, } +``` -// or: +Or: + +``` mod something_that_does_exist { pub static foo : i32 = 0i32; } something_that_does_exist::foo; // ok! +``` -// or: +Or: + +``` let unknown_variable = 12u32; let x = unknown_variable; // ok! ``` @@ -867,7 +891,7 @@ let x = unknown_variable; // ok! E0426: r##" An undeclared label was used. Example of erroneous code: -``` +```compile_fail loop { 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 code: -``` +```compile_fail struct Bar; struct Bar; // error: duplicate definition of value `Bar` ``` @@ -903,7 +927,7 @@ struct Bar2; // ok! E0430: r##" 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 // 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 `self` import. Example: -``` +```ignore use something::self; // ok! ``` "##, @@ -919,7 +943,7 @@ use something::self; // ok! E0431: r##" `self` import was made. Erroneous code example: -``` +```compile_fail use {self}; // error: `self` import can only appear in an import list with a // non-empty prefix ``` @@ -931,14 +955,14 @@ or verify you didn't misspell it. E0432: r##" An import was unresolved. Erroneous code example: -``` +```compile_fail use something::Foo; // error: unresolved import `something::Foo`. ``` 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: -``` +```ignore use something::Foo; // ok! mod something { @@ -949,7 +973,7 @@ mod something { Or, if you tried to use a module from an external crate, you may have missed the `extern crate` declaration: -``` +```ignore extern crate homura; // Required to use the `homura` crate use homura::Madoka; @@ -959,7 +983,7 @@ use homura::Madoka; E0433: r##" Invalid import. Example of erroneous code: -``` +```compile_fail use 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 code: -``` +```compile_fail let foo = 42u32; const FOO : u32 = foo; // error: attempt to use a non-constant value in a // constant @@ -981,8 +1005,11 @@ To fix this error, please replace the value with a constant. Example: ``` const FOO : u32 = 42u32; // ok! +``` -// or: +Or: + +``` const OTHER_FOO : u32 = 42u32; const FOO : u32 = OTHER_FOO; // ok! ``` @@ -996,7 +1023,7 @@ in the trait. Here is an example that demonstrates the error: -``` +```compile_fail trait Foo {} 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: -``` +```compile_fail #![feature(associated_consts)] trait Foo {} diff --git a/src/librustc_trans/diagnostics.rs b/src/librustc_trans/diagnostics.rs index 539b9a4171f..5ae60d18240 100644 --- a/src/librustc_trans/diagnostics.rs +++ b/src/librustc_trans/diagnostics.rs @@ -15,12 +15,14 @@ register_long_diagnostics! { E0510: r##" `return_address` was used in an invalid context. Erroneous code example: -``` +```compile_fail +#![feature(intrinsics)] + extern "rust-intrinsic" { fn return_address() -> *const u8; } -pub unsafe fn by_value() -> i32 { +unsafe fn by_value() -> i32 { let _ = return_address(); // error: invalid use of `return_address` intrinsic: function does // 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: ``` +#![feature(intrinsics)] + extern "rust-intrinsic" { fn return_address() -> *const u8; } -pub unsafe fn by_pointer() -> String { +unsafe fn by_pointer() -> String { let _ = return_address(); String::new() // ok! } @@ -50,7 +54,9 @@ E0511: r##" Invalid monomorphization of an intrinsic function was used. Erroneous code example: -``` +```compile_fail +#![feature(platform_intrinsics)] + extern "platform-intrinsic" { fn simd_add(a: T, b: T) -> T; } @@ -62,6 +68,9 @@ unsafe { simd_add(0, 1); } The generic type has to be a SIMD type. Example: ``` +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] #[derive(Copy, Clone)] struct i32x1(i32); @@ -78,7 +87,7 @@ E0512: r##" Transmute with two differently sized types was attempted. Erroneous code example: -``` +```compile_fail fn takes_u8(_: u8) {} fn main() { @@ -103,7 +112,7 @@ fn main() { E0515: r##" 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 ``` diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index f138b997f4c..5c79e9a4ec5 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -19,27 +19,42 @@ extract an incorrect number of fields from a variant. ``` enum Fruit { - Apple(String, String) - Pear(u32) + 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 { - Apple(a, b) => ... + Fruit::Apple(a, b) => {}, + _ => {} } ``` Matching with the wrong number of fields has no sensible interpretation: -``` +```compile_fail +enum Fruit { + Apple(String, String), + Pear(u32), +} + +let x = Fruit::Apple(String::new(), String::new()); + // Incorrect. match x { - Apple(a) => ..., - Apple(a, b, c) => ... + Apple(a) => {}, + Apple(a, b, c) => {}, } ``` @@ -51,7 +66,7 @@ E0024: r##" This error indicates that a pattern attempted to extract the fields of an enum variant with no fields. Here's a tiny example of this error: -``` +```compile_fail // This enum has two variants. enum Number { // This variant has no fields. @@ -62,8 +77,8 @@ enum Number { // Assuming x is a Number we can pattern match on its contents. match x { - Zero(inside) => ..., - One(inside) => ... + Zero(inside) => {}, + One(inside) => {}, } ``` @@ -76,7 +91,7 @@ E0025: r##" Each field of a struct can only be bound once in a pattern. Erroneous code example: -``` +```compile_fail struct Foo { a: u8, b: u8, @@ -122,23 +137,42 @@ struct Thing { } let thing = Thing { x: 1, y: 2 }; + match thing { - Thing { x: xfield, y: yfield } => ... + Thing { x: xfield, y: yfield } => {} } ``` If you are using shorthand field patterns but want to refer to the struct field by a different name, you should rename it explicitly. -``` -// Change this: -match thing { - Thing { x, z } => ... +Change this: + +```compile_fail +struct Thing { + x: u32, + y: u32 } -// To this: +let thing = Thing { x: 0, y: 0 }; + match thing { - Thing { x, y: z } => ... + Thing { x, z } => {} +} +``` + +To this: + +``` +struct Thing { + x: u32, + y: u32 +} + +let thing = Thing { x: 0, y: 0 }; + +match thing { + Thing { x, y: z } => {} } ``` "##, @@ -150,27 +184,37 @@ definition is mentioned in the pattern, or use `..` to ignore unwanted fields. For example: -``` +```compile_fail struct Dog { name: String, - age: u32 + age: u32, } let d = Dog { name: "Rusty".to_string(), age: 8 }; // This is incorrect. match d { - Dog { age: x } => ... + Dog { age: x } => {} +} +``` + +This is correct (explicit): + +``` +struct Dog { + name: String, + age: u32, } -// This is correct (explicit). +let d = Dog { name: "Rusty".to_string(), age: 8 }; + match d { - Dog { name: n, age: x } => ... + Dog { name: ref n, age: x } => {} } // This is also correct (ignore unused fields). match d { - Dog { age: x, .. } => ... + Dog { age: x, .. } => {} } ``` "##, @@ -182,18 +226,18 @@ 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 // The ordering relation for strings can't be evaluated at compile time, // so this doesn't work: match string { - "hello" ... "world" => ... - _ => ... + "hello" ... "world" => {} + _ => {} } // This is a more general version, using a guard: match string { - s if s >= "hello" && s <= "world" => ... - _ => ... + s if s >= "hello" && s <= "world" => {} + _ => {} } ``` "##, @@ -205,7 +249,7 @@ size of trait implementors isn't fixed, this type has no compile-time size. Therefore, all accesses to trait types must be through pointers. If you encounter this error you should try to avoid dereferencing the pointer. -``` +```ignore let trait_obj: &SomeTrait = ...; // This tries to implicitly dereference to create an unsized local variable. @@ -224,9 +268,9 @@ https://doc.rust-lang.org/reference.html#trait-objects E0034: r##" The compiler doesn't know what method to call because more than one method -has the same prototype. Example: +has the same prototype. Erroneous code example: -``` +```compile_fail struct Test; trait Trait1 { @@ -286,9 +330,10 @@ fn main() { "##, E0035: r##" -You tried to give a type parameter where it wasn't needed. Bad example: +You tried to give a type parameter where it wasn't needed. Erroneous code +example: -``` +```compile_fail struct Test; impl Test { @@ -321,9 +366,9 @@ fn main() { E0036: r##" This error occurrs when you pass too many or not enough type parameters to -a method. Example: +a method. Erroneous code example: -``` +```compile_fail struct Test; impl Test { @@ -361,7 +406,7 @@ fn main() { Please note on the last example that we could have called `method` like this: -``` +```ignore x.method(v); ``` "##, @@ -373,7 +418,7 @@ out of scope. Here's an example of this error: -``` +```compile_fail struct Foo { x: i32, } @@ -394,7 +439,7 @@ fn main() { E0044: r##" You can't use type parameters on foreign items. Example of erroneous code: -``` +```compile_fail extern { fn some_func(x: T); } ``` @@ -412,17 +457,23 @@ 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 extern "rust-call" { fn foo(x: u8, ...); } + // or + fn foo(x: u8, ...) {} ``` To fix such code, put them in an extern "C" block: +```ignore +extern "C" fn foo(x: u8, ...); +``` + +Or: + ``` -extern "C" fn foo (x: u8, ...); -// or: extern "C" { fn foo (x: u8, ...); } @@ -432,7 +483,7 @@ extern "C" { E0046: r##" Items are missing in a trait implementation. Erroneous code example: -``` +```compile_fail trait Foo { fn foo(); } @@ -468,7 +519,7 @@ has the wrong number of type parameters. For example, the trait below has a method `foo` with a type parameter `T`, but the implementation of `foo` for the type `Bar` is missing this parameter: -``` +```compile_fail trait Foo { fn foo(x: T) -> Self; } @@ -491,7 +542,7 @@ 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 trait Foo { fn foo(&self, x: u8) -> bool; } @@ -512,7 +563,7 @@ and the trait definition. Here are a couple examples of this error: -``` +```compile_fail trait Foo { fn foo(x: u16); fn bar(&self); @@ -534,14 +585,18 @@ E0054: r##" It is not allowed to cast to a bool. If you are trying to cast a numeric type to a bool, you can compare it with zero instead: +```compile_fail +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; - -// Not allowed, won't compile -let x_is_nonzero = x as bool; ``` "##, @@ -553,7 +608,7 @@ recursion limit (which can be set via the `recursion_limit` attribute). For a somewhat artificial example: -``` +```compile_fail #![recursion_limit="2"] struct Foo; @@ -583,7 +638,7 @@ function must match its definition. An example using a closure: -``` +```compile_fail let f = |x| x * 3; let a = f(); // invalid, too few parameters let b = f(4); // this works! @@ -609,13 +664,13 @@ 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 fn foo>(f: F) -> F::Output { f(3) } ``` It can be fixed by adjusting the trait bound like this: -``` +```ignore fn foo>(f: F) -> F::Output { f(3) } ``` @@ -628,7 +683,7 @@ 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: -``` +```ignore extern crate libc; use libc::{ c_char, c_int }; @@ -640,7 +695,7 @@ extern "C" { Using this declaration, it must be called with at least one argument, so simply calling `printf()` is invalid. But the following uses are allowed: -``` +```ignore unsafe { use std::ffi::CString; @@ -655,13 +710,13 @@ E0061: r##" The number of arguments passed to a function must match the number of arguments specified in the function signature. -For example, a function like +For example, a function like: ``` fn f(a: u16, b: &str) {} ``` -must always be called with exactly two arguments, e.g. `f(2, "test")`. +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). @@ -672,7 +727,7 @@ 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 struct Foo { x: i32 } @@ -702,7 +757,7 @@ E0063: r##" This error indicates that during an attempt to build a struct or struct-like enum variant, one of the fields was not provided. Erroneous code example: -``` +```compile_fail struct Foo { x: i32, y: i32 @@ -743,9 +798,9 @@ expression. An lvalue expression represents a memory location and includes item paths (ie, namespaced variables), dereferences, indexing expressions, and field references. -Let's start with some bad examples: +Let's start with some erroneous code examples: -``` +```compile_fail use std::collections::LinkedList; // Bad: assignment to non-lvalue expression @@ -758,7 +813,7 @@ fn some_func(i: &mut i32) { } ``` -And now some good examples: +And now some working examples: ``` let mut i : i32 = 0; @@ -777,7 +832,7 @@ E0069: r##" The compiler found a function whose body contains a `return;` statement but whose return type is not `()`. An example of this is: -``` +```compile_fail // error fn foo() -> u8 { return; @@ -797,13 +852,14 @@ reference. More details can be found here: https://doc.rust-lang.org/reference.html#lvalues-rvalues-and-temporaries -Now, we can go further. Here are some bad examples: +Now, we can go further. Here are some erroneous code examples: -``` +```compile_fail struct SomeStruct { x: i32, y: i32 } + const SOME_CONST : i32 = 12; fn some_other_func() {} @@ -817,7 +873,7 @@ fn some_function() { } ``` -And now let's give good examples: +And now let's give working examples: ``` struct SomeStruct { @@ -842,7 +898,7 @@ not a struct-style structure or enum variant. Example of erroneous code: -``` +```compile_fail enum Foo { FirstValue(i32) }; let u = Foo::FirstValue { value: 0i32 }; // error: Foo::FirstValue @@ -876,7 +932,7 @@ first instance of `Foo` could be made to initialize another instance! Here's an example of a struct that has this problem: -``` +```compile_fail struct Foo { x: Box } // error ``` @@ -895,12 +951,22 @@ tuple struct must all be of a concrete, nongeneric type so the compiler can reason about how to use SIMD with them. This error will occur if the types are generic. -``` -#[simd] -struct Bad(T, T, T); // This will cause an error +This will cause an error: + +```compile_fail +#![feature(simd)] #[simd] -struct Good(u32, u32, u32); // This will not +struct Bad(T, T, T); +``` + +This will not: + +``` +#![feature(simd)] + +#[simd] +struct Good(u32, u32, u32); ``` "##, @@ -909,12 +975,22 @@ The `#[simd]` attribute can only be applied to non empty tuple structs, because it doesn't make sense to try to use SIMD operations when there are no values to operate on. -``` -#[simd] -struct Bad; // This will cause an error +This will cause an error: + +```compile_fail +#![feature(simd)] #[simd] -struct Good(u32); // This will not +struct Bad; +``` + +This will not: + +``` +#![feature(simd)] + +#[simd] +struct Good(u32); ``` "##, @@ -923,26 +999,45 @@ When using the `#[simd]` attribute to automatically use SIMD operations in tuple struct, the types in the struct must all be of the same type, or the compiler will trigger this error. -``` -#[simd] -struct Bad(u16, u32, u32); // This will cause an error +This will cause an error: + +```compile_fail +#![feature(simd)] #[simd] -struct Good(u32, u32, u32); // This will not +struct Bad(u16, u32, u32); ``` +This will not: + +``` +#![feature(simd)] + +#[simd] +struct Good(u32, u32, u32); +``` "##, E0077: r##" When using the `#[simd]` attribute on a tuple struct, the elements in the tuple must be machine types so SIMD operations can be applied to them. -``` -#[simd] -struct Bad(String); // This will cause an error +This will cause an error: + +```compile_fail +#![feature(simd)] #[simd] -struct Good(u32, u32, u32); // This will not +struct Bad(String); +``` + +This will not: + +``` +#![feature(simd)] + +#[simd] +struct Good(u32, u32, u32); ``` "##, @@ -951,15 +1046,15 @@ Enum variants which contain no data can be given a custom integer representation. This error indicates that the value provided is not an integer literal and is therefore invalid. -For example, in the following code, +For example, in the following code: -``` +```compile_fail enum Foo { Q = "32" } ``` -we try to set the representation to a string. +We try to set the representation to a string. There's no general fix for this; if you can work with an integer then just set it to one: @@ -970,7 +1065,7 @@ enum Foo { } ``` -however if you actually wanted a mapping between variants and non-integer +However if you actually wanted a mapping between variants and non-integer objects, it may be preferable to use a method with a match instead: ``` @@ -990,7 +1085,7 @@ This error indicates that the compiler was unable to sensibly evaluate an integer expression provided as an enum discriminant. Attempting to divide by 0 or causing integer overflow are two ways to induce this error. For example: -``` +```compile_fail enum Enum { X = (1 << 500), Y = (1 / 0) @@ -1009,6 +1104,15 @@ 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 +// Bad. +enum Enum { + P = 3, + X = 3, + Y = 5 +} +``` + ``` // Good. enum Enum { @@ -1016,20 +1120,13 @@ enum Enum { X = 3, Y = 5 } - -// Bad. -enum Enum { - P = 3, - X = 3, - Y = 5 -} ``` Note that variants without a manually specified discriminant are numbered from top to bottom starting from 0, so clashes can occur with seemingly unrelated variants. -``` +```compile_fail enum Bad { X, Y = 0 @@ -1046,7 +1143,7 @@ adding the `repr` attribute to the enum declaration. This error indicates that an integer literal given as a discriminant is not a member of the discriminant type. For example: -``` +```compile_fail #[repr(u8)] enum Thing { A = 1024, @@ -1075,7 +1172,7 @@ enum Empty {} E0087: r##" Too many type parameters were supplied for a function. For example: -``` +```compile_fail fn foo() {} fn main() { @@ -1090,7 +1187,7 @@ parameters. E0088: r##" You gave too many lifetime parameters. Erroneous code example: -``` +```compile_fail fn f() {} fn main() { @@ -1135,7 +1232,7 @@ fn main() { E0089: r##" Not enough type parameters were supplied for a function. For example: -``` +```compile_fail fn foo() {} fn main() { @@ -1146,7 +1243,7 @@ fn main() { Note that if a function takes multiple type parameters but you want the compiler to infer some of them, you can use type placeholders: -``` +```compile_fail fn foo(x: T) {} fn main() { @@ -1161,7 +1258,7 @@ E0091: r##" You gave an unnecessary type parameter in a type alias. Erroneous code example: -``` +```compile_fail type Foo = u32; // error: type parameter `T` is unused // or: type Foo = Box; // error: type parameter `B` is unused @@ -1171,7 +1268,7 @@ Please check you didn't write too many type parameters. Example: ``` type Foo = u32; // ok! -type Foo = Box; // ok! +type Foo2 = Box; // ok! ``` "##, @@ -1179,7 +1276,7 @@ E0092: r##" You tried to declare an undefined atomic operation function. Erroneous code example: -``` +```compile_fail #![feature(intrinsics)] extern "rust-intrinsic" { @@ -1204,7 +1301,7 @@ extern "rust-intrinsic" { E0093: r##" You declared an unknown intrinsic function. Erroneous code example: -``` +```compile_fail #![feature(intrinsics)] extern "rust-intrinsic" { @@ -1241,7 +1338,7 @@ E0094: r##" You gave an invalid number of type parameters to an intrinsic function. Erroneous code example: -``` +```compile_fail #![feature(intrinsics)] extern "rust-intrinsic" { @@ -1267,7 +1364,7 @@ E0101: r##" You hit this error because the compiler lacks the information to determine a type for this expression. Erroneous code example: -``` +```compile_fail fn main() { let x = |_| {}; // error: cannot determine a type for this expression } @@ -1293,7 +1390,7 @@ E0102: r##" You hit this error because the compiler lacks information to determine a type for this variable. Erroneous code example: -``` +```compile_fail fn demo(devil: fn () -> !) { let x: &_ = devil(); // error: cannot determine a type for this local variable @@ -1310,6 +1407,8 @@ To solve this situation, constrain the type of the variable. Examples: ``` +#![allow(unused_variables)] + fn some_func(x: &u32) { // some code } @@ -1338,7 +1437,7 @@ lifetime elision rules (see below). Here are some simple examples of where you'll run into this error: -``` +```compile_fail struct Foo { x: &bool } // error struct Foo<'a> { x: &'a bool } // correct @@ -1366,15 +1465,15 @@ same as the lifetime on `&self` or `&mut self`. Here are some examples of elision errors: -``` +```compile_fail // error, no input lifetimes -fn foo() -> &str { ... } +fn foo() -> &str { } // error, `x` and `y` have distinct lifetimes inferred -fn bar(x: &str, y: &str) -> &str { ... } +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 { ... } +fn baz<'a>(x: &'a str, y: &str) -> &str { } ``` [book-le]: https://doc.rust-lang.org/nightly/book/lifetimes.html#lifetime-elision @@ -1386,7 +1485,7 @@ for a type (like a struct or enum) or trait. Some basic examples include: -``` +```compile_fail struct Foo<'a>(&'a str); enum Bar { A, B, C } @@ -1399,7 +1498,7 @@ struct Baz<'a> { Here's an example that is currently an error, but may work in a future version of Rust: -``` +```compile_fail struct Foo<'a>(&'a str); trait Quux { } @@ -1417,8 +1516,8 @@ You can only define an inherent implementation for a type in the same crate where the type was defined. For example, an `impl` block as below is not allowed since `Vec` is defined in the standard library: -``` -impl Vec { ... } // error +```compile_fail +impl Vec { } // error ``` To fix this problem, you can do either of these things: @@ -1431,10 +1530,10 @@ To fix this problem, you can do either of these things: Note that using the `type` keyword does not work here because `type` only introduces a type alias: -``` +```compile_fail type Bytes = Vec; -impl Bytes { ... } // error, same as above +impl Bytes { } // error, same as above ``` "##, @@ -1449,14 +1548,14 @@ trait defined in another crate) where Here's one example of this error: -``` +```compile_fail impl Drop for u32 {} ``` To avoid this kind of error, ensure that at least one local type is referenced by the `impl`: -``` +```ignore pub struct Foo; // you define your type in your crate impl Drop for Foo { // and you can implement the trait on it! @@ -1492,7 +1591,7 @@ E0118: r##" You're trying to write an inherent implementation for something which isn't a struct nor an enum. Erroneous code example: -``` +```compile_fail impl (u8, u8) { // error: no base type found for inherent implementation fn get_state(&self) -> String { // ... @@ -1536,7 +1635,7 @@ E0119: r##" There are conflicting trait implementations for the same type. Example of erroneous code: -``` +```compile_fail trait MyTrait { fn get(&self) -> usize; } @@ -1561,6 +1660,10 @@ 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 MyTrait for T { fn get(&self) -> usize { 0 } } @@ -1593,7 +1696,7 @@ E0120: r##" An attempt was made to implement Drop on a trait, which is not allowed: only structs and enums can implement Drop. An example causing this error: -``` +```compile_fail trait MyTrait {} impl Drop for MyTrait { @@ -1634,7 +1737,7 @@ placeholders are disallowed by design in item signatures. Examples of this error include: -``` +```compile_fail fn foo() -> _ { 5 } // error, explicitly write out the return type instead static BAR: _ = "test"; // error, explicitly write out the type instead @@ -1665,10 +1768,10 @@ E0124: r##" You declared two fields of a struct with the same name. Erroneous code example: -``` +```compile_fail struct Foo { field1: i32, - field1: i32 // error: field is already declared + field1: i32, // error: field is already declared } ``` @@ -1677,7 +1780,7 @@ Please verify that the field names have been correctly spelled. Example: ``` struct Foo { field1: i32, - field2: i32 // ok! + field2: i32, // ok! } ``` "##, @@ -1686,8 +1789,8 @@ E0128: r##" Type parameter defaults can only use parameters that occur before them. Erroneous code example: -``` -pub struct Foo { +```compile_fail +struct Foo { field1: T, filed2: U, } @@ -1699,7 +1802,7 @@ Since type parameters are evaluated in-order, you may be able to fix this issue by doing: ``` -pub struct Foo { +struct Foo { field1: T, filed2: U, } @@ -1713,7 +1816,7 @@ E0130: r##" You declared a pattern as an argument in a foreign function declaration. Erroneous code example: -``` +```compile_fail extern { fn foo((a, b): (u32, u32)); // error: patterns aren't allowed in foreign // function declarations @@ -1731,7 +1834,11 @@ struct SomeStruct { extern { fn foo(s: SomeStruct); // ok! } -// or +``` + +Or: + +``` extern { fn foo(a: (u32, u32)); // ok! } @@ -1743,7 +1850,7 @@ It is not possible to define `main` with type parameters, or even with function parameters. When `main` is present, it must take no arguments and return `()`. Erroneous code example: -``` +```compile_fail fn main() { // error: main function is not allowed to have type parameters } ``` @@ -1753,7 +1860,7 @@ E0132: r##" It is not possible to declare type parameters on a function that has the `start` attribute. Such a function must have the following type signature: -``` +```ignore fn(isize, *const *const u8) -> isize; ``` "##, @@ -1762,12 +1869,12 @@ E0163: r##" This error means that an attempt was made to match an enum variant as a struct type when the variant isn't a struct type: -``` +```compile_fail enum Foo { B(u32) } fn bar(foo: Foo) -> u32 { match foo { - Foo::B{i} => i // error 0163 + B{i} => i, // error E0163 } } ``` @@ -1775,25 +1882,26 @@ fn bar(foo: Foo) -> u32 { Try using `()` instead: ``` +enum Foo { B(u32) } + fn bar(foo: Foo) -> u32 { match foo { - Foo::B(i) => i + Foo::B(i) => i, } } ``` "##, E0164: r##" - This error means that an attempt was made to match a struct type enum variant as a non-struct type: -``` -enum Foo { B{ i: u32 } } +```compile_fail +enum Foo { B { i: u32 } } fn bar(foo: Foo) -> u32 { match foo { - Foo::B(i) => i // error 0164 + Foo::B(i) => i, // error E0164 } } ``` @@ -1801,21 +1909,22 @@ fn bar(foo: Foo) -> u32 { Try using `{}` instead: ``` +enum Foo { B { i: u32 } } + fn bar(foo: Foo) -> u32 { match foo { - Foo::B{i} => i + Foo::B{i} => i, } } ``` "##, - E0166: r##" This error means that the compiler found a return expression in a function marked as diverging. A function diverges if it has `!` in the place of the return type in its signature. For example: -``` +```compile_fail fn foo() -> ! { return; } // error ``` @@ -1828,7 +1937,7 @@ E0172: r##" This error means that an attempt was made to specify the type of a variable with a combination of a concrete type and a trait. Consider the following example: -``` +```compile_fail fn foo(bar: i32+std::fmt::Display) {} ``` @@ -1857,7 +1966,7 @@ to use parentheses. For example: -``` +```compile_fail trait Foo {} struct Bar<'a> { @@ -1889,7 +1998,7 @@ take a `self` parameter). Here's an example of this error: -``` +```compile_fail trait Foo { fn foo(); } @@ -1910,7 +2019,7 @@ to be static. Here's an example of this error: -``` +```compile_fail trait Foo { fn foo(&self); } @@ -1929,7 +2038,7 @@ E0191: r##" Trait objects need to have all associated types specified. Erroneous code example: -``` +```compile_fail trait Trait { type Bar; } @@ -1960,7 +2069,7 @@ E0193: r##" `where` clauses must use generic type parameters: it does not make sense to use them otherwise. An example causing this error: -``` +```compile_fail trait Foo { fn bar(&self); } @@ -1979,6 +2088,14 @@ This use of a `where` clause is strange - a more common usage would look something like the following: ``` +trait Foo { + fn bar(&self); +} + +#[derive(Copy,Clone)] +struct Wrapper { + Wrapped: T +} impl Foo for Wrapper where Wrapper: Clone { fn bar(&self) { } } @@ -1997,7 +2114,7 @@ E0194: r##" A type parameter was declared which shadows an existing one. An example of this error: -``` +```compile_fail trait Foo { fn do_something(&self) -> T; fn do_something_else(&self, bar: T); @@ -2013,7 +2130,7 @@ E0195: r##" Your method's lifetime parameters do not match the trait declaration. Erroneous code example: -``` +```compile_fail trait Trait { fn bar<'a,'b:'a>(x: &'a str, y: &'b str); } @@ -2052,7 +2169,7 @@ methods associated with a type) are always safe because they are not implementing an unsafe trait. Removing the `unsafe` keyword from the inherent implementation will resolve this error. -``` +```compile_fail struct Foo; // this will cause this error @@ -2068,22 +2185,38 @@ particular trait. Not being able to use a trait is always a safe operation, so negative implementations are always safe and never need to be marked as unsafe. -``` +```compile_fail +#![feature(optin_builtin_traits)] + struct Foo; // unsafe is unnecessary unsafe impl !Clone for Foo { } -// this will compile -impl !Clone for Foo { } ``` + +This will compile: + +``` +#![feature(optin_builtin_traits)] + +struct Foo; + +trait Enterprise {} + +impl Enterprise for .. { } + +impl !Enterprise for Foo { } +``` + +Please note that negative impls are only allowed for traits with default impls. "##, E0199: r##" Safe traits should not have unsafe implementations, therefore marking an -implementation for a safe trait unsafe will cause a compiler error. Removing the -unsafe marker on the trait noted in the error will resolve this problem. +implementation for a safe trait unsafe will cause a compiler error. Removing +the unsafe marker on the trait noted in the error will resolve this problem. -``` +```compile_fail struct Foo; trait Bar { } @@ -2100,7 +2233,7 @@ Unsafe traits must have unsafe implementations. This error occurs when an implementation for an unsafe trait isn't marked as unsafe. This may be resolved by marking the unsafe implementation as unsafe. -``` +```compile_fail struct Foo; unsafe trait Bar { } @@ -2118,7 +2251,7 @@ associated functions, etc.) with the same identifier. For example: -``` +```compile_fail struct Foo(u8); impl Foo { @@ -2158,7 +2291,7 @@ An attempt to implement the `Copy` trait for a struct failed because one of the fields does not implement `Copy`. To fix this, you must implement `Copy` for the mentioned field. Note that this may not be possible, as in the example of -``` +```compile_fail struct Foo { foo : Vec, } @@ -2170,7 +2303,7 @@ This fails because `Vec` does not implement `Copy` for any `T`. Here's another example that will fail: -``` +```compile_fail #[derive(Copy)] struct Foo<'a> { ty: &'a mut bool, @@ -2186,7 +2319,7 @@ An attempt to implement the `Copy` trait for an enum failed because one of the variants does not implement `Copy`. To fix this, you must implement `Copy` for the mentioned variant. Note that this may not be possible, as in the example of -``` +```compile_fail enum Foo { Bar(Vec), Baz, @@ -2199,7 +2332,7 @@ This fails because `Vec` does not implement `Copy` for any `T`. Here's another example that will fail: -``` +```compile_fail #[derive(Copy)] enum Foo<'a> { Bar(&'a mut bool), @@ -2216,7 +2349,7 @@ You can only implement `Copy` for a struct or enum. Both of the following examples will fail, because neither `i32` (primitive type) nor `&'static Bar` (reference to `Bar`) is a struct or enum: -``` +```compile_fail type Foo = i32; impl Copy for Foo { } // error @@ -2230,7 +2363,7 @@ E0207: r##" You declared an unused type parameter when implementing a trait on an object. Erroneous code example: -``` +```compile_fail trait MyTrait { fn get(&self) -> usize; } @@ -2272,18 +2405,18 @@ what this means, it is perhaps easiest to consider a few examples. If `ForeignTrait` is a trait defined in some external crate `foo`, then the following trait `impl` is an error: -``` +```compile_fail extern crate foo; use foo::ForeignTrait; -impl ForeignTrait for T { ... } // error +impl ForeignTrait for T { } // error ``` To work around this, it can be covered with a local type, `MyType`: -``` +```ignore struct MyType(T); -impl ForeignTrait for MyType { ... } // Ok +impl ForeignTrait for MyType { } // Ok ``` Please note that a type alias is not sufficient. @@ -2292,9 +2425,9 @@ For another example of an error, suppose there's another trait defined in `foo` named `ForeignTrait2` that takes two type parameters. Then this `impl` results in the same rule violation: -``` +```compile_fail struct MyType2; -impl ForeignTrait2> for MyType2 { ... } // error +impl ForeignTrait2> for MyType2 { } // error ``` The reason for this is that there are two appearances of type parameter `T` in @@ -2303,8 +2436,8 @@ is uncovered, and so runs afoul of the orphan rule. Consider one more example: -``` -impl ForeignTrait2, T> for MyType2 { ... } // Ok +```ignore +impl ForeignTrait2, T> for MyType2 { } // Ok ``` This only differs from the previous `impl` in that the parameters `T` and @@ -2314,7 +2447,7 @@ violate the orphan rule; it is permitted. To see why that last example was allowed, you need to understand the general rule. Unfortunately this rule is a bit tricky to state. Consider an `impl`: -``` +```ignore impl ForeignTrait for T0 { ... } ``` @@ -2333,7 +2466,7 @@ E0211: r##" You used a function or type which doesn't fit the requirements for where it was used. Erroneous code examples: -``` +```compile_fail #![feature(intrinsics)] extern "rust-intrinsic" { @@ -2379,7 +2512,7 @@ extern "rust-intrinsic" { The second case example is a bit particular : the main function must always have this definition: -``` +```compile_fail fn main(); ``` @@ -2390,6 +2523,7 @@ as the type you're matching on. Example: ``` let x = 1u8; + match x { 0u8...3u8 => (), // ok! _ => () @@ -2412,7 +2546,7 @@ E0214: r##" A generic type was described using parentheses rather than angle brackets. For example: -``` +```compile_fail fn main() { let v: Vec(&str) = vec!["foo"]; } @@ -2427,7 +2561,7 @@ E0220: r##" You used an associated type which isn't defined in the trait. Erroneous code example: -``` +```compile_fail trait Trait { type Bar; } @@ -2452,7 +2586,7 @@ E0221: r##" An attempt was made to retrieve an associated type, but the type was ambiguous. For example: -``` +```compile_fail trait T1 {} trait T2 {} @@ -2478,8 +2612,18 @@ one of the types. Alternatively, one can specify the intended type using the following syntax: ``` -fn do_something() { - let _: ::A; +trait T1 {} +trait T2 {} + +trait Foo { + type A: T1; +} + +trait Bar : Foo { + type A: T2; + fn do_something() { + let _: ::A; + } } ``` "##, @@ -2488,7 +2632,7 @@ E0223: r##" An attempt was made to retrieve an associated type, but the type was ambiguous. For example: -``` +```compile_fail trait MyTrait {type X; } fn main() { @@ -2523,7 +2667,7 @@ E0225: r##" You attempted to use multiple types as bounds for a closure or trait object. Rust does not currently support this. A simple example that causes this error: -``` +```compile_fail fn main() { let _: Box; } @@ -2543,7 +2687,9 @@ fn main() { E0232: r##" The attribute must have a value. Erroneous code example: -``` +```compile_fail +#![feature(on_unimplemented)] + #[rustc_on_unimplemented] // error: this attribute must have a value trait Bar {} ``` @@ -2551,6 +2697,8 @@ trait Bar {} Please supply the missing value of the attribute. Example: ``` +#![feature(on_unimplemented)] + #[rustc_on_unimplemented = "foo"] // ok! trait Bar {} ``` @@ -2563,7 +2711,7 @@ trait. For example, the `Foo` struct below is defined to be generic in `T`, but the type parameter is missing in the definition of `Bar`: -``` +```compile_fail struct Foo { x: T } struct Bar { x: Foo } @@ -2577,7 +2725,7 @@ trait. For example, the `Foo` struct below has no type parameters, but is supplied with two in the definition of `Bar`: -``` +```compile_fail struct Foo { x: bool } struct Bar { x: Foo } @@ -2588,7 +2736,7 @@ E0248: r##" This error indicates an attempt to use a value where a type is expected. For example: -``` +```compile_fail enum Foo { Bar(u32) } @@ -2609,7 +2757,7 @@ it was not an integer (signed or unsigned) expression. Some examples of code that produces this error are: -``` +```compile_fail const A: [u32; "hello"] = []; // error const B: [u32; true] = []; // error const C: [u32; 0.0] = []; // error @@ -2621,7 +2769,7 @@ size array type. Some examples of this error are: -``` +```compile_fail // divide by zero in the length expression const A: [u32; 1/0] = []; @@ -2645,7 +2793,7 @@ E0321: r##" A cross-crate opt-out trait was implemented on something which wasn't a struct or enum type. Erroneous code example: -``` +```compile_fail #![feature(optin_builtin_traits)] struct Foo; @@ -2674,7 +2822,9 @@ E0323: r##" An associated const was implemented when another trait item was expected. Erroneous code example: -``` +```compile_fail +#![feature(associated_consts)] + trait Foo { type N; } @@ -2701,8 +2851,15 @@ trait Foo { impl Foo for Bar { type N = u32; // ok! } +``` + +Or: + +``` +#![feature(associated_consts)] + +struct Bar; -// or: trait Foo { const N : u32; } @@ -2717,7 +2874,7 @@ E0324: r##" A method was implemented when another trait item was expected. Erroneous code example: -``` +```compile_fail struct Bar; trait Foo { @@ -2737,6 +2894,8 @@ To fix this error, please verify that the method name wasn't misspelled and verify that you are indeed implementing the correct trait items. Example: ``` +#![feature(associated_consts)] + struct Bar; trait Foo { @@ -2757,7 +2916,7 @@ E0325: r##" An associated type was implemented when another trait item was expected. Erroneous code example: -``` +```compile_fail struct Bar; trait Foo { @@ -2784,8 +2943,15 @@ trait Foo { impl Foo for Bar { type N = u32; // ok! } +``` + +Or: + +``` +#![feature(associated_consts)] + +struct Bar; -//or: trait Foo { const N : u32; } @@ -2802,7 +2968,7 @@ types in the trait definition. This error indicates that there was a mismatch. Here's an example of this error: -``` +```compile_fail trait Foo { const BAR: bool; } @@ -2819,7 +2985,7 @@ E0327: r##" You cannot use associated items other than constant items as patterns. This includes method items. Example of erroneous code: -``` +```compile_fail enum B {} impl B { @@ -2856,7 +3022,9 @@ An attempt was made to access an associated constant through either a generic type parameter or `Self`. This is not supported yet. An example causing this error is shown below: -``` +```compile_fail +#![feature(associated_consts)] + trait Foo { const BAR: f64; } @@ -2872,10 +3040,18 @@ fn get_bar_bad(t: F) -> f64 { } ``` -Currently, the value of `BAR` for a particular type can only be accessed through -a concrete type, as shown below: +Currently, the value of `BAR` for a particular type can only be accessed +through a concrete type, as shown below: + +```ignore +#![feature(associated_consts)] + +trait Foo { + const BAR: f64; +} + +struct MyStruct; -``` fn get_bar_good() -> f64 { ::BAR } @@ -2886,7 +3062,7 @@ E0366: r##" An attempt was made to implement `Drop` on a concrete specialization of a generic type. An example is shown below: -``` +```compile_fail struct Foo { t: T } @@ -2919,7 +3095,7 @@ E0367: r##" An attempt was made to implement `Drop` on a specialization of a generic type. An example is shown below: -``` +```compile_fail trait Foo{} struct MyStruct { @@ -2957,9 +3133,9 @@ E0368: r##" This error indicates that a binary assignment operator like `+=` or `^=` was applied to a type that doesn't support it. For example: -``` +```compile_fail let mut x = 12f32; // error: binary operation `<<` cannot be applied to - // type `f32` + // type `f32` x <<= 2; ``` @@ -2967,7 +3143,7 @@ x <<= 2; To fix this error, please check that this type implements this binary operation. Example: -``` +```compile_fail let x = 12u32; // the `u32` type does implement the `ShlAssign` trait x <<= 2; // ok! @@ -2980,7 +3156,7 @@ Another problem you might be facing is this: suppose you've overloaded the `+` operator for some type `Foo` by implementing the `std::ops::Add` trait for `Foo`, but you find that using `+=` does not work, as in this example: -``` +```compile_fail use std::ops::Add; struct Foo(u32); @@ -3007,7 +3183,7 @@ E0369: r##" A binary operation was attempted on a type which doesn't support it. Erroneous code example: -``` +```compile_fail let x = 12f32; // error: binary operation `<<` cannot be applied to // type `f32` @@ -3032,12 +3208,12 @@ E0370: r##" The maximum value of an enum was reached, so it cannot be automatically set in the next enum value. Erroneous code example: -``` +```compile_fail enum Foo { X = 0x7fffffffffffffff, - Y // error: enum discriminant overflowed on value after - // 9223372036854775807: i64; set explicitly via - // Y = -9223372036854775808 if that is desired outcome + Y, // error: enum discriminant overflowed on value after + // 9223372036854775807: i64; set explicitly via + // Y = -9223372036854775808 if that is desired outcome } ``` @@ -3049,8 +3225,11 @@ enum Foo { X = 0x7fffffffffffffff, Y = 0, // ok! } +``` -// or: +Or: + +``` enum Foo { Y = 0, // ok! X = 0x7fffffffffffffff, @@ -3066,7 +3245,7 @@ definition, so it is not useful to do this. Example: -``` +```compile_fail trait Foo { fn foo(&self) { } } trait Bar: Foo { } trait Baz: Bar { } @@ -3094,7 +3273,7 @@ For more information see the [opt-in builtin traits RFC](https://github.com/rust E0390: r##" You tried to implement methods for a primitive type. Erroneous code example: -``` +```compile_fail struct Foo { x: i32 } @@ -3128,7 +3307,7 @@ and therefore cannot be constructed. The following example contains a circular dependency between two traits: -``` +```compile_fail trait FirstTrait : SecondTrait { } @@ -3141,9 +3320,9 @@ trait SecondTrait : FirstTrait { E0392: r##" This error indicates that a type or lifetime parameter has been declared -but not actually used. Here is an example that demonstrates the error: +but not actually used. Here is an example that demonstrates the error: -``` +```compile_fail enum Foo { Bar } @@ -3172,7 +3351,7 @@ example, when using raw pointers one may wish to specify the lifetime for which the pointed-at data is valid. An initial attempt (below) causes this error: -``` +```compile_fail struct Foo<'a, T> { x: *const T } @@ -3203,7 +3382,9 @@ E0439: r##" The length of the platform-intrinsic function `simd_shuffle` wasn't specified. Erroneous code example: -``` +```compile_fail +#![feature(platform_intrinsics)] + extern "platform-intrinsic" { fn simd_shuffle(a: A, b: A, c: [u32; 8]) -> B; // error: invalid `simd_shuffle`, needs length: `simd_shuffle` @@ -3214,6 +3395,8 @@ The `simd_shuffle` function needs the length of the array passed as last parameter in its name. Example: ``` +#![feature(platform_intrinsics)] + extern "platform-intrinsic" { fn simd_shuffle8(a: A, b: A, c: [u32; 8]) -> B; } @@ -3224,7 +3407,10 @@ E0440: r##" A platform-specific intrinsic function has the wrong number of type parameters. Erroneous code example: -``` +```compile_fail +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] struct f64x2(f64, f64); @@ -3239,6 +3425,9 @@ Please refer to the function declaration to see if it corresponds with yours. Example: ``` +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] struct f64x2(f64, f64); @@ -3252,7 +3441,10 @@ E0441: r##" An unknown platform-specific intrinsic function was used. Erroneous code example: -``` +```compile_fail +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16); @@ -3267,6 +3459,9 @@ that it is declared in the rust source code (in the file src/librustc_platform_intrinsics/x86.rs). Example: ``` +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16); @@ -3280,7 +3475,10 @@ E0442: r##" Intrinsic argument(s) and/or return value have the wrong type. Erroneous code example: -``` +```compile_fail +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8); @@ -3299,6 +3497,9 @@ To fix this error, please refer to the function declaration to give it the awaited types. Example: ``` +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16); @@ -3312,7 +3513,10 @@ E0443: r##" Intrinsic argument(s) and/or return value have the wrong type. Erroneous code example: -``` +```compile_fail +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16); #[repr(simd)] @@ -3328,6 +3532,9 @@ To fix this error, please refer to the function declaration to give it the awaited types. Example: ``` +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16); @@ -3341,7 +3548,10 @@ E0444: r##" A platform-specific intrinsic function has wrong number of arguments. Erroneous code example: -``` +```compile_fail +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] struct f64x2(f64, f64); @@ -3355,6 +3565,9 @@ Please refer to the function declaration to see if it corresponds with yours. Example: ``` +#![feature(repr_simd)] +#![feature(platform_intrinsics)] + #[repr(simd)] struct f64x2(f64, f64); @@ -3368,7 +3581,7 @@ E0516: r##" The `typeof` keyword is currently reserved but unimplemented. Erroneous code example: -``` +```compile_fail fn main() { let x: typeof(92) = 92; }