From 307a3569c5025e72e3020a393689d10a6f5e2109 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 10 Oct 2019 10:29:03 +0200 Subject: [PATCH 1/4] Sort long error code explanation by error code --- src/librustc_mir/error_codes.rs | 406 ++++++++++++++++---------------- 1 file changed, 203 insertions(+), 203 deletions(-) diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs index 77853ff1fe80a..b2d7bc6a30661 100644 --- a/src/librustc_mir/error_codes.rs +++ b/src/librustc_mir/error_codes.rs @@ -208,6 +208,124 @@ match x { ``` "##, +E0010: r##" +The value of statics and constants must be known at compile time, and they live +for the entire lifetime of a program. Creating a boxed value allocates memory on +the heap at runtime, and therefore cannot be done at compile time. Erroneous +code example: + +```compile_fail,E0010 +#![feature(box_syntax)] + +const CON : Box = box 0; +``` +"##, + +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: + +```compile_fail,E0013 +static X: i32 = 42; +const Y: i32 = X; +``` + +To fix this, the value can be extracted as a const and then used: + +``` +const A: i32 = 42; +static X: i32 = A; +const Y: i32 = A; +``` +"##, + +// FIXME(#57563) Change the language here when const fn stabilizes +E0015: r##" +The only functions that can be called in static or constant expressions are +`const` functions, and struct/enum constructors. `const` functions are only +available on a nightly compiler. Rust currently does not support more general +compile-time function execution. + +``` +const FOO: Option = Some(1); // enum constructor +struct Bar {x: u8} +const BAR: Bar = Bar {x: 1}; // struct constructor +``` + +See [RFC 911] for more details on the design of `const fn`s. + +[RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md +"##, + +E0017: r##" +References in statics and constants may only refer to immutable values. +Erroneous code example: + +```compile_fail,E0017 +static X: i32 = 1; +const C: i32 = 2; + +// these three are not allowed: +const CR: &mut i32 = &mut C; +static STATIC_REF: &'static mut i32 = &mut X; +static CONST_REF: &'static mut i32 = &mut C; +``` + +Statics are shared everywhere, and if they refer to mutable data one might +violate memory safety since holding multiple mutable references to shared data +is not allowed. + +If you really want global mutable state, try using `static mut` or a global +`UnsafeCell`. +"##, + +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. Erroneous code +example: + +```compile_fail +enum Test { + V1 +} + +impl Test { + fn test(&self) -> i32 { + 12 + } +} + +fn main() { + const FOO: Test = Test::V1; + + const A: i32 = FOO.test(); // You can't call Test::func() here! +} +``` + +Remember: you can't use a function call inside a const's initialization +expression! However, you can totally use it anywhere else: + +``` +enum Test { + V1 +} + +impl Test { + fn func(&self) -> i32 { + 12 + } +} + +fn main() { + const FOO: Test = Test::V1; + + FOO.func(); // here is good + let x = FOO.func(); // or even here! +} +``` +"##, + E0030: r##" When matching against a range, the compiler verifies that the range is non-empty. Range patterns include both end-points, so this is equivalent to @@ -226,6 +344,40 @@ match 5u32 { ``` "##, +E0133: r##" +Unsafe code was used outside of an unsafe function or block. + +Erroneous code example: + +```compile_fail,E0133 +unsafe fn f() { return; } // This is the unsafe code + +fn main() { + f(); // error: call to unsafe function requires unsafe function or block +} +``` + +Using unsafe functionality is potentially dangerous and disallowed by safety +checks. Examples: + +* Dereferencing raw pointers +* Calling functions via FFI +* Calling functions marked unsafe + +These safety checks can be relaxed for a section of the code by wrapping the +unsafe instructions with an `unsafe` block. For instance: + +``` +unsafe fn f() { return; } + +fn main() { + unsafe { f(); } // ok! +} +``` + +See also https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html +"##, + E0158: r##" `const` and `static` mean different things. A `const` is a compile-time constant, an alias for a literal value. This property means you can match it @@ -247,6 +399,39 @@ match Some(42) { ``` "##, +E0161: r##" +A value was moved. However, its size was not known at compile time, and only +values of a known size can be moved. + +Erroneous code example: + +```compile_fail +#![feature(box_syntax)] + +fn main() { + let array: &[isize] = &[1, 2, 3]; + let _x: Box<[isize]> = box *array; + // error: cannot move a value of type [isize]: the size of [isize] cannot + // be statically determined +} +``` + +In Rust, you can only move a value when its size is known at compile time. + +To work around this restriction, consider "hiding" the value behind a reference: +either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move +it around as usual. Example: + +``` +#![feature(box_syntax)] + +fn main() { + let array: &[isize] = &[1, 2, 3]; + let _x: Box<&[isize]> = box array; // ok! +} +``` +"##, + E0162: r##" #### Note: this error code is no longer emitted by the compiler. @@ -468,158 +653,6 @@ The `op_string_ref` binding has type `&Option<&String>` in both cases. See also https://github.com/rust-lang/rust/issues/14587 "##, -E0010: r##" -The value of statics and constants must be known at compile time, and they live -for the entire lifetime of a program. Creating a boxed value allocates memory on -the heap at runtime, and therefore cannot be done at compile time. Erroneous -code example: - -```compile_fail,E0010 -#![feature(box_syntax)] - -const CON : Box = box 0; -``` -"##, - -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: - -```compile_fail,E0013 -static X: i32 = 42; -const Y: i32 = X; -``` - -To fix this, the value can be extracted as a const and then used: - -``` -const A: i32 = 42; -static X: i32 = A; -const Y: i32 = A; -``` -"##, - -// FIXME(#57563) Change the language here when const fn stabilizes -E0015: r##" -The only functions that can be called in static or constant expressions are -`const` functions, and struct/enum constructors. `const` functions are only -available on a nightly compiler. Rust currently does not support more general -compile-time function execution. - -``` -const FOO: Option = Some(1); // enum constructor -struct Bar {x: u8} -const BAR: Bar = Bar {x: 1}; // struct constructor -``` - -See [RFC 911] for more details on the design of `const fn`s. - -[RFC 911]: https://github.com/rust-lang/rfcs/blob/master/text/0911-const-fn.md -"##, - -E0017: r##" -References in statics and constants may only refer to immutable values. -Erroneous code example: - -```compile_fail,E0017 -static X: i32 = 1; -const C: i32 = 2; - -// these three are not allowed: -const CR: &mut i32 = &mut C; -static STATIC_REF: &'static mut i32 = &mut X; -static CONST_REF: &'static mut i32 = &mut C; -``` - -Statics are shared everywhere, and if they refer to mutable data one might -violate memory safety since holding multiple mutable references to shared data -is not allowed. - -If you really want global mutable state, try using `static mut` or a global -`UnsafeCell`. -"##, - -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. Erroneous code -example: - -```compile_fail -enum Test { - V1 -} - -impl Test { - fn test(&self) -> i32 { - 12 - } -} - -fn main() { - const FOO: Test = Test::V1; - - const A: i32 = FOO.test(); // You can't call Test::func() here! -} -``` - -Remember: you can't use a function call inside a const's initialization -expression! However, you can totally use it anywhere else: - -``` -enum Test { - V1 -} - -impl Test { - fn func(&self) -> i32 { - 12 - } -} - -fn main() { - const FOO: Test = Test::V1; - - FOO.func(); // here is good - let x = FOO.func(); // or even here! -} -``` -"##, - -E0133: r##" -Unsafe code was used outside of an unsafe function or block. - -Erroneous code example: - -```compile_fail,E0133 -unsafe fn f() { return; } // This is the unsafe code - -fn main() { - f(); // error: call to unsafe function requires unsafe function or block -} -``` - -Using unsafe functionality is potentially dangerous and disallowed by safety -checks. Examples: - -* Dereferencing raw pointers -* Calling functions via FFI -* Calling functions marked unsafe - -These safety checks can be relaxed for a section of the code by wrapping the -unsafe instructions with an `unsafe` block. For instance: - -``` -unsafe fn f() { return; } - -fn main() { - unsafe { f(); } // ok! -} -``` - -See also https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html -"##, - E0373: r##" 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 @@ -1022,39 +1055,6 @@ fn main() { ``` "##, -E0161: r##" -A value was moved. However, its size was not known at compile time, and only -values of a known size can be moved. - -Erroneous code example: - -```compile_fail -#![feature(box_syntax)] - -fn main() { - let array: &[isize] = &[1, 2, 3]; - let _x: Box<[isize]> = box *array; - // error: cannot move a value of type [isize]: the size of [isize] cannot - // be statically determined -} -``` - -In Rust, you can only move a value when its size is known at compile time. - -To work around this restriction, consider "hiding" the value behind a reference: -either `&x` or `&mut x`. Since a reference has a fixed size, this lets you move -it around as usual. Example: - -``` -#![feature(box_syntax)] - -fn main() { - let array: &[isize] = &[1, 2, 3]; - let _x: Box<&[isize]> = box array; // ok! -} -``` -"##, - E0492: r##" A borrow of a constant containing interior mutability was attempted. Erroneous code example: @@ -1982,24 +1982,6 @@ Here executing `x = None` would modify the value being matched and require us to go "back in time" to the `None` arm. "##, -E0579: r##" -When matching against an exclusive range, the compiler verifies that the range -is non-empty. Exclusive range patterns include the start point but not the end -point, so this is equivalent to requiring the start of the range to be less -than the end of the range. - -For example: - -```compile_fail -match 5u32 { - // This range is ok, albeit pointless. - 1 .. 2 => {} - // This range is empty, and the compiler can tell. - 5 .. 5 => {} -} -``` -"##, - E0515: r##" Cannot return value that references local variable @@ -2101,6 +2083,24 @@ fn dragoooon(x: &mut isize) { ``` "##, +E0579: r##" +When matching against an exclusive range, the compiler verifies that the range +is non-empty. Exclusive range patterns include the start point but not the end +point, so this is equivalent to requiring the start of the range to be less +than the end of the range. + +For example: + +```compile_fail +match 5u32 { + // This range is ok, albeit pointless. + 1 .. 2 => {} + // This range is empty, and the compiler can tell. + 5 .. 5 => {} +} +``` +"##, + E0595: r##" #### Note: this error code is no longer emitted by the compiler. From c6de3ebd69acc627d3a8560587e5475f2240ce8a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 10 Oct 2019 10:33:46 +0200 Subject: [PATCH 2/4] Uncomment E0386 to let users have access to its old definition --- src/librustc_mir/error_codes.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs index b2d7bc6a30661..93fd00c265bef 100644 --- a/src/librustc_mir/error_codes.rs +++ b/src/librustc_mir/error_codes.rs @@ -875,7 +875,8 @@ x = Foo { a: 2 }; E0384: r##" This error occurs when an attempt is made to reassign an immutable variable. -For example: + +Erroneous code example: ```compile_fail,E0384 fn main() { @@ -895,13 +896,15 @@ fn main() { ``` "##, -/*E0386: r##" +E0386: r##" +#### Note: this error code is no longer emitted by the compiler. + This error occurs when an attempt is made to mutate the target of a mutable reference stored inside an immutable container. For example, this can happen when storing a `&mut` inside an immutable `Box`: -```compile_fail,E0386 +``` let mut x: i64 = 1; let y: Box<_> = Box::new(&mut x); **y = 2; // error, cannot assign to data in an immutable container @@ -925,7 +928,7 @@ let x: i64 = 1; let y: Box> = Box::new(Cell::new(x)); y.set(2); ``` -"##,*/ +"##, E0387: r##" #### Note: this error code is no longer emitted by the compiler. From 65458190c55b06cc8301e6c16b06679677af3945 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 10 Oct 2019 10:53:08 +0200 Subject: [PATCH 3/4] Unification and cleanup of librustc_mir error codes --- src/librustc_mir/error_codes.rs | 142 +++++++++++++++++++++----------- 1 file changed, 92 insertions(+), 50 deletions(-) diff --git a/src/librustc_mir/error_codes.rs b/src/librustc_mir/error_codes.rs index 93fd00c265bef..419c905cb5127 100644 --- a/src/librustc_mir/error_codes.rs +++ b/src/librustc_mir/error_codes.rs @@ -64,7 +64,9 @@ E0004: r##" This error indicates that the compiler cannot guarantee a matching pattern for one or more possible inputs to a match expression. Guaranteed matches are required in order to assign values to match expressions, or alternatively, -determine the flow of execution. Erroneous code example: +determine the flow of execution. + +Erroneous code example: ```compile_fail,E0004 enum Terminator { @@ -109,7 +111,9 @@ match x { E0005: r##" Patterns used to bind names must be irrefutable, that is, they must guarantee -that a name will be extracted in all cases. Erroneous code example: +that a name will be extracted in all cases. + +Erroneous code example: ```compile_fail,E0005 let x = Some(1); @@ -145,6 +149,8 @@ like 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`. +Erroneous code example: + ```compile_fail,E0007 let x = Some("s".to_string()); @@ -211,8 +217,9 @@ match x { E0010: r##" The value of statics and constants must be known at compile time, and they live for the entire lifetime of a program. Creating a boxed value allocates memory on -the heap at runtime, and therefore cannot be done at compile time. Erroneous -code example: +the heap at runtime, and therefore cannot be done at compile time. + +Erroneous code example: ```compile_fail,E0010 #![feature(box_syntax)] @@ -223,15 +230,17 @@ const CON : Box = box 0; 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. + +Erroneous code example: ```compile_fail,E0013 static X: i32 = 42; const Y: i32 = X; ``` -To fix this, the value can be extracted as a const and then used: +In this example, `Y` cannot refer to `X` here. To fix this, the value can be +extracted as a const and then used: ``` const A: i32 = 42; @@ -260,6 +269,7 @@ See [RFC 911] for more details on the design of `const fn`s. E0017: r##" References in statics and constants may only refer to immutable values. + Erroneous code example: ```compile_fail,E0017 @@ -282,24 +292,17 @@ If you really want global mutable state, try using `static mut` or a global 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. Erroneous code -example: +because the expression's value must be known at compile-time. -```compile_fail -enum Test { - V1 -} +Erroneous code example: -impl Test { - fn test(&self) -> i32 { - 12 - } -} +```compile_fail,E0019 +#![feature(box_syntax)] fn main() { - const FOO: Test = Test::V1; + struct MyOwned; - const A: i32 = FOO.test(); // You can't call Test::func() here! + static STATIC11: Box = box MyOwned; // error! } ``` @@ -328,13 +331,13 @@ fn main() { E0030: r##" When matching against a range, the compiler verifies that the range is -non-empty. Range patterns include both end-points, so this is equivalent to +non-empty. Range patterns include both end-points, so this is equivalent to requiring the start of the range to be less than or equal to the end of the range. -For example: +Erroneous code example: -```compile_fail +```compile_fail,E0030 match 5u32 { // This range is ok, albeit pointless. 1 ..= 1 => {} @@ -379,6 +382,26 @@ See also https://doc.rust-lang.org/book/ch19-01-unsafe-rust.html "##, E0158: r##" +An associated const has been referenced in a pattern. + +Erroneous code example: + +```compile_fail,E0158 +enum EFoo { A, B, C, D } + +trait Foo { + const X: EFoo; +} + +fn test(arg: EFoo) { + match arg { + A::X => { // error! + println!("A::X"); + } + } +} +``` + `const` and `static` mean different things. A `const` is a compile-time constant, an alias for a literal value. This property means you can match it directly within a pattern. @@ -405,7 +428,7 @@ values of a known size can be moved. Erroneous code example: -```compile_fail +```compile_fail,E0161 #![feature(box_syntax)] fn main() { @@ -705,7 +728,9 @@ about safety. "##, E0381: r##" -It is not allowed to use or capture an uninitialized variable. For example: +It is not allowed to use or capture an uninitialized variable. + +Erroneous code example: ```compile_fail,E0381 fn main() { @@ -727,7 +752,9 @@ fn main() { E0382: r##" This error occurs when an attempt is made to use a variable after its contents -have been moved elsewhere. For example: +have been moved elsewhere. + +Erroneous code example: ```compile_fail,E0382 struct MyStruct { s: u32 } @@ -934,7 +961,9 @@ E0387: r##" #### Note: this error code is no longer emitted by the compiler. This error occurs when an attempt is made to mutate or mutably reference data -that a closure has captured immutably. Examples of this error are shown below: +that a closure has captured immutably. + +Erroneous code example: ```compile_fail // Accepts a function or a closure that captures its environment immutably. @@ -999,7 +1028,7 @@ An attempt was made to mutate data using a non-mutable reference. This commonly occurs when attempting to assign to a non-mutable reference of a mutable reference (`&(&mut T)`). -Example of erroneous code: +Erroneous code example: ```compile_fail struct FancyNum { @@ -1059,8 +1088,9 @@ fn main() { "##, E0492: r##" -A borrow of a constant containing interior mutability was attempted. Erroneous -code example: +A borrow of a constant containing interior mutability was attempted. + +Erroneous code example: ```compile_fail,E0492 use std::sync::atomic::AtomicUsize; @@ -1177,7 +1207,9 @@ static FOO: Foo = Foo { field1: DropType::A }; // We initialize all fields "##, E0499: r##" -A variable was borrowed as mutable more than once. Erroneous code example: +A variable was borrowed as mutable more than once. + +Erroneous code example: ```compile_fail,E0499 let mut i = 0; @@ -1208,7 +1240,9 @@ a; "##, E0500: r##" -A borrowed variable was used by a closure. Example of erroneous code: +A borrowed variable was used by a closure. + +Erroneous code example: ```compile_fail,E0500 fn you_know_nothing(jon_snow: &mut i32) { @@ -1259,7 +1293,7 @@ situation, the closure is borrowing the variable. Take a look at http://rustbyexample.com/fn/closures/capture.html for more information about capturing. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0501 fn inside_closure(x: &mut i32) { @@ -1332,7 +1366,7 @@ E0502: r##" This error indicates that you are trying to borrow a variable as mutable when it has already been borrowed as immutable. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0502 fn bar(x: &mut i32) {} @@ -1363,7 +1397,7 @@ https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html. E0503: r##" A value was used after it was mutably borrowed. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0503 fn main() { @@ -1421,7 +1455,7 @@ E0504: r##" This error occurs when an attempt is made to move a borrowed variable into a closure. -Example of erroneous code: +Erroneous code example: ```compile_fail struct FancyNum { @@ -1612,7 +1646,7 @@ http://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html E0506: r##" This error occurs when an attempt is made to assign to a borrowed value. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0506 struct FancyNum { @@ -1830,7 +1864,7 @@ http://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html E0508: r##" A value was moved out of a non-copy fixed-size array. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0508 struct NonCopy; @@ -1875,7 +1909,7 @@ E0509: r##" This error occurs when an attempt is made to move out of a value whose type implements the `Drop` trait. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0509 struct FancyNum { @@ -1991,6 +2025,8 @@ Cannot return value that references local variable Local variables, function parameters and temporaries are all dropped before the end of the function body. So a reference to them cannot be returned. +Erroneous code example: + ```compile_fail,E0515 fn get_dangling_reference() -> &'static i32 { let x = 0; @@ -2092,14 +2128,18 @@ is non-empty. Exclusive range patterns include the start point but not the end point, so this is equivalent to requiring the start of the range to be less than the end of the range. -For example: +Erroneous code example: -```compile_fail -match 5u32 { - // This range is ok, albeit pointless. - 1 .. 2 => {} - // This range is empty, and the compiler can tell. - 5 .. 5 => {} +```compile_fail,E0579 +#![feature(exclusive_range_pattern)] + +fn main() { + match 5u32 { + // This range is ok, albeit pointless. + 1 .. 2 => {} + // This range is empty, and the compiler can tell. + 5 .. 5 => {} // error! + } } ``` "##, @@ -2127,7 +2167,7 @@ let mut c = || { x += 1 }; E0596: r##" This error occurs because you tried to mutably borrow a non-mutable variable. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0596 let x = 1; @@ -2146,7 +2186,7 @@ let y = &mut x; // ok! E0597: r##" This error occurs because a value was dropped while it was still borrowed -Example of erroneous code: +Erroneous code example: ```compile_fail,E0597 struct Foo<'a> { @@ -2183,6 +2223,8 @@ E0626: r##" This error occurs because a borrow in a generator persists across a yield point. +Erroneous code example: + ```compile_fail,E0626 # #![feature(generators, generator_trait, pin)] # use std::ops::Generator; @@ -2274,7 +2316,7 @@ E0712: r##" This error occurs because a borrow of a thread-local variable was made inside a function which outlived the lifetime of the function. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0712 #![feature(thread_local)] @@ -2296,7 +2338,7 @@ E0713: r##" This error occurs when an attempt is made to borrow state past the end of the lifetime of a type that implements the `Drop` trait. -Example of erroneous code: +Erroneous code example: ```compile_fail,E0713 #![feature(nll)] From d4e3e6bc15ece1c017ec7bd1fd892c6a981b2020 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 14 Oct 2019 13:01:12 +0200 Subject: [PATCH 4/4] Delete extra file --- .../feature-gate-exhaustive-patterns.nll.stderr | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr deleted file mode 100644 index d77fbc1e8239d..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0005]: refutable pattern in local binding: `Err(_)` not covered - --> $DIR/feature-gate-exhaustive-patterns.rs:7:9 - | -LL | let Ok(_x) = foo(); - | ^^^^^^ pattern `Err(_)` not covered - | - = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant - = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html -help: you might want to use `if let` to ignore the variant that isn't matched - | -LL | if let Ok(_x) = foo() { /* */ } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0005`.