diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 709ccce517a36..02f6e1ea76b68 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -10,17 +10,25 @@ register_diagnostics! { E0001: include_str!("./error_codes/E0001.md"), E0002: include_str!("./error_codes/E0002.md"), +E0003: include_str!("./error_codes/E0003.md"), E0004: include_str!("./error_codes/E0004.md"), E0005: include_str!("./error_codes/E0005.md"), E0007: include_str!("./error_codes/E0007.md"), +E0008: include_str!("./error_codes/E0008.md"), E0009: include_str!("./error_codes/E0009.md"), E0010: include_str!("./error_codes/E0010.md"), +E0011: include_str!("./error_codes/E0011.md"), E0013: include_str!("./error_codes/E0013.md"), E0014: include_str!("./error_codes/E0014.md"), E0015: include_str!("./error_codes/E0015.md"), +E0016: include_str!("./error_codes/E0016.md"), E0017: include_str!("./error_codes/E0017.md"), +E0018: include_str!("./error_codes/E0018.md"), E0019: include_str!("./error_codes/E0019.md"), +E0020: include_str!("./error_codes/E0020.md"), +E0022: include_str!("./error_codes/E0022.md"), E0023: include_str!("./error_codes/E0023.md"), +E0024: include_str!("./error_codes/E0024.md"), E0025: include_str!("./error_codes/E0025.md"), E0026: include_str!("./error_codes/E0026.md"), E0027: include_str!("./error_codes/E0027.md"), @@ -412,7 +420,6 @@ E0744: include_str!("./error_codes/E0744.md"), E0745: include_str!("./error_codes/E0745.md"), ; // E0006, // merged with E0005 -// E0008, // cannot bind by-move into a pattern guard // E0035, merged into E0087/E0089 // E0036, merged into E0087/E0089 // E0068, diff --git a/src/librustc_error_codes/error_codes/E0003.md b/src/librustc_error_codes/error_codes/E0003.md new file mode 100644 index 0000000000000..bfd8cfab01323 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0003.md @@ -0,0 +1,15 @@ +#### Note: this error code is no longer emitted by the compiler. + +Not-a-Number (NaN) values cannot be compared for equality and hence can never +match the input to a match expression. To match against NaN values, you should +instead use the `is_nan()` method in a guard, like so: + +``` +let number = 0f64; + +match number { + // ... + x if x.is_nan() => { /* ... */ } + x => { /* ... */ } +} +``` diff --git a/src/librustc_error_codes/error_codes/E0008.md b/src/librustc_error_codes/error_codes/E0008.md new file mode 100644 index 0000000000000..0989513556ac3 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0008.md @@ -0,0 +1,73 @@ +#### Note: this error code is no longer emitted by the compiler. + +Names bound in match arms retain their type in pattern guards. As such, if a +name is bound by move in a pattern, it should also be moved to wherever it is +referenced in the pattern guard code. Doing so however would prevent the name +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. + _ => {}, +} +``` + +The variable `s` has type `String`, and its use in the guard is as a variable of +type `String`. The guard code effectively executes in a separate scope to the +body of the arm, so the value would be moved into this anonymous scope and +therefore becomes unavailable in the body of the arm. +The problem above can be solved by using the `ref` keyword. + +``` +match Some("hi".to_string()) { + Some(ref s) if s.len() == 0 => {}, + _ => {}, +} +``` + +Though this example seems innocuous and easy to solve, the problem becomes clear +when it encounters functions which consume the value: + +```compile_fail,E0507 +struct A {} + +impl A { + fn consume(self) -> usize { + 0 + } +} + +fn main() { + let a = Some(A{}); + match a { + Some(y) if y.consume() > 0 => {} + _ => {} + } +} +``` + +In this situation, even the `ref` keyword cannot solve it, since borrowed +content cannot be moved. This problem cannot be solved generally. If the value +can be cloned, here is a not-so-specific solution: + +``` +#[derive(Clone)] +struct A {} + +impl A { + fn consume(self) -> usize { + 0 + } +} + +fn main() { + let a = Some(A{}); + match a{ + Some(ref y) if y.clone().consume() > 0 => {} + _ => {} + } +} +``` + +If the value will be consumed in the pattern guard, using its clone will not +move its ownership, so the code works. diff --git a/src/librustc_error_codes/error_codes/E0011.md b/src/librustc_error_codes/error_codes/E0011.md new file mode 100644 index 0000000000000..cc3646342352d --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0011.md @@ -0,0 +1,30 @@ +#### Note: this error code is no longer emitted by the compiler. + +Using a user-defined operator on const/static variable is restricted to what +can be evaluated at compile-time. Using an user-defined operator could call a +user-defined function, which is not allowed. + +Bad example: + +```compile_fail,E0015 +use std::ops::Index; + +struct Foo { a: u8 } + +impl ::std::ops::Index for Foo { + type Output = u8; + fn index<'a>(&'a self, idx: u8) -> &'a u8 { &self.a } +} + +const a: Foo = Foo { a: 0u8 }; +const b: u8 = a[0]; // Index trait is defined by the user, bad! +``` + +Only operators on builtin types are allowed. + +Example: + +``` +const a: &'static [i32] = &[1, 2, 3]; +const b: i32 = a[0]; // Good! +``` diff --git a/src/librustc_error_codes/error_codes/E0016.md b/src/librustc_error_codes/error_codes/E0016.md new file mode 100644 index 0000000000000..310820caa2f25 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0016.md @@ -0,0 +1,14 @@ +#### Note: this error code is no longer emitted by the compiler. + +Blocks in constants may only contain items (such as constant, function +definition, etc...) and a tail expression. Erroneous code example: + +``` +const FOO: i32 = { let x = 0; x }; // 'x' isn't an item! +``` + +To avoid it, you have to replace the non-item object: + +``` +const FOO: i32 = { const X : i32 = 0; X }; +``` diff --git a/src/librustc_error_codes/error_codes/E0018.md b/src/librustc_error_codes/error_codes/E0018.md new file mode 100644 index 0000000000000..66bde4fcb5bba --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0018.md @@ -0,0 +1,29 @@ +#### Note: this error code is no longer emitted by the compiler. + +The value of static and constant integers must be known at compile time. You +can't cast a pointer to an integer because the address of a pointer can vary. + +For example, if you write: + +```compile_fail,E0658 +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; +``` + +Then `MY_STATIC_ADDR` would contain the address of `MY_STATIC`. However, +the address can change when the program is linked, as well as change +between different executions due to ASLR, and many linkers would +not be able to calculate the value of `WHAT`. + +On the other hand, static and constant pointers can point either to +a known numeric address or to the address of a symbol. + +``` +static MY_STATIC: u32 = 42; +static MY_STATIC_ADDR: &'static u32 = &MY_STATIC; +const CONST_ADDR: *const u8 = 0x5f3759df as *const u8; +``` + +This does not pose a problem by itself because they can't be +accessed directly. diff --git a/src/librustc_error_codes/error_codes/E0020.md b/src/librustc_error_codes/error_codes/E0020.md new file mode 100644 index 0000000000000..2cd4ac8983d97 --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0020.md @@ -0,0 +1,12 @@ +#### Note: this error code is no longer emitted by the compiler. + +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 +#[deny(const_err)] + +const X: i32 = 42 / 0; +// error: attempt to divide by zero in a constant expression +``` diff --git a/src/librustc_error_codes/error_codes/E0022.md b/src/librustc_error_codes/error_codes/E0022.md new file mode 100644 index 0000000000000..742bc257ad98d --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0022.md @@ -0,0 +1,17 @@ +#### Note: this error code is no longer emitted by the compiler. + +Constant functions are not allowed to mutate anything. Thus, binding to an +argument with a mutable pattern is not allowed. For example, + +``` +const fn foo(mut x: u8) { + // do stuff +} +``` + +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 +instead of using a `const fn`, or refactoring the code to a functional style to +avoid mutation if possible. diff --git a/src/librustc_error_codes/error_codes/E0024.md b/src/librustc_error_codes/error_codes/E0024.md new file mode 100644 index 0000000000000..f479dd5b9c5fa --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0024.md @@ -0,0 +1,24 @@ +#### Note: this error code is no longer emitted by the compiler. + +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,E0532 +// This enum has two variants. +enum Number { + // This variant has no fields. + Zero, + // This variant has one field. + One(u32) +} + +// Assuming x is a Number we can pattern match on its contents. +match Number::Zero { + Number::Zero(inside) => {} + Number::One(inside) => {} +} +``` + +The pattern match `Zero(inside)` is incorrect because the `Zero` variant +contains no fields, yet the `inside` name attempts to bind the first field of +the enum.