Auto merge of #24975 - michaelsproul:enum-diagnostics, r=pnkfelix
Explanations for E0079, E0080, E0081, E0082, E0083 and E0084 as part of #24407. All the errors concern the use of `#[repr(X)]` with enum types. I also updated the short description for E0079 so that it takes sign into account.
This commit is contained in:
commit
e962870420
3 changed files with 107 additions and 7 deletions
|
@ -227,6 +227,31 @@ 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.
|
remainder of a zero divisor) in a static or constant expression.
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
|
E0079: r##"
|
||||||
|
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.
|
||||||
|
"##,
|
||||||
|
|
||||||
|
E0080: r##"
|
||||||
|
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:
|
||||||
|
|
||||||
|
```
|
||||||
|
enum Enum {
|
||||||
|
X = (1 << 500),
|
||||||
|
Y = (1 / 0)
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Ensure that the expressions given can be evaluated as the desired integer type.
|
||||||
|
See the FFI section of the Reference for more information about using a custom
|
||||||
|
integer type:
|
||||||
|
|
||||||
|
http://doc.rust-lang.org/reference.html#ffi-attributes
|
||||||
|
"##,
|
||||||
|
|
||||||
E0133: r##"
|
E0133: r##"
|
||||||
Using unsafe functionality, such as dereferencing raw pointers and calling
|
Using unsafe functionality, such as dereferencing raw pointers and calling
|
||||||
functions via FFI or marked as unsafe, is potentially dangerous and disallowed
|
functions via FFI or marked as unsafe, is potentially dangerous and disallowed
|
||||||
|
@ -507,8 +532,6 @@ register_diagnostics! {
|
||||||
E0017,
|
E0017,
|
||||||
E0019,
|
E0019,
|
||||||
E0022,
|
E0022,
|
||||||
E0079, // enum variant: expected signed integer constant
|
|
||||||
E0080, // enum variant: constant evaluation error
|
|
||||||
E0109,
|
E0109,
|
||||||
E0110,
|
E0110,
|
||||||
E0134,
|
E0134,
|
||||||
|
|
|
@ -5732,8 +5732,10 @@ fn compute_enum_variants<'tcx>(cx: &ctxt<'tcx>,
|
||||||
Ok(const_eval::const_int(val)) => current_disr_val = val as Disr,
|
Ok(const_eval::const_int(val)) => current_disr_val = val as Disr,
|
||||||
Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr,
|
Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr,
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
let sign_desc = if repr_type.is_signed() { "signed" } else { "unsigned" };
|
||||||
span_err!(cx.sess, e.span, E0079,
|
span_err!(cx.sess, e.span, E0079,
|
||||||
"expected signed integer constant");
|
"expected {} integer constant",
|
||||||
|
sign_desc);
|
||||||
current_disr_val = attempt_fresh_value();
|
current_disr_val = attempt_fresh_value();
|
||||||
}
|
}
|
||||||
Err(ref err) => {
|
Err(ref err) => {
|
||||||
|
|
|
@ -10,6 +10,85 @@
|
||||||
|
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
|
register_long_diagnostics! {
|
||||||
|
|
||||||
|
E0081: r##"
|
||||||
|
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.
|
||||||
|
|
||||||
|
```
|
||||||
|
// Good.
|
||||||
|
enum Enum {
|
||||||
|
P,
|
||||||
|
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.
|
||||||
|
|
||||||
|
```
|
||||||
|
enum Bad {
|
||||||
|
X,
|
||||||
|
Y = 0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here `X` will have already been assigned the discriminant 0 by the time `Y` is
|
||||||
|
encountered, so a conflict occurs.
|
||||||
|
"##,
|
||||||
|
|
||||||
|
E0082: r##"
|
||||||
|
The default type for enum discriminants is `isize`, but it can be adjusted by
|
||||||
|
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:
|
||||||
|
|
||||||
|
```
|
||||||
|
#[repr(u8)]
|
||||||
|
enum Thing {
|
||||||
|
A = 1024,
|
||||||
|
B = 5
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, 1024 lies outside the valid range for `u8`, so the discriminant for `A` is
|
||||||
|
invalid. You may want to change representation types to fix this, or else change
|
||||||
|
invalid discriminant values so that they fit within the existing type.
|
||||||
|
|
||||||
|
Note also that without a representation manually defined, the compiler will
|
||||||
|
optimize by using the smallest integer type possible.
|
||||||
|
"##,
|
||||||
|
|
||||||
|
E0083: r##"
|
||||||
|
At present, it's not possible to define a custom representation for an enum with
|
||||||
|
a single variant. As a workaround you can add a `Dummy` variant.
|
||||||
|
|
||||||
|
See: https://github.com/rust-lang/rust/issues/10292
|
||||||
|
"##,
|
||||||
|
|
||||||
|
E0084: r##"
|
||||||
|
It is impossible to define an integer type to be used to represent zero-variant
|
||||||
|
enum values because there are no zero-variant enum values. There is no way to
|
||||||
|
construct an instance of the following type using only safe code:
|
||||||
|
|
||||||
|
```
|
||||||
|
enum Empty {}
|
||||||
|
```
|
||||||
|
"##
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
register_diagnostics! {
|
register_diagnostics! {
|
||||||
E0023,
|
E0023,
|
||||||
E0024,
|
E0024,
|
||||||
|
@ -51,10 +130,6 @@ register_diagnostics! {
|
||||||
E0075,
|
E0075,
|
||||||
E0076,
|
E0076,
|
||||||
E0077,
|
E0077,
|
||||||
E0081,
|
|
||||||
E0082,
|
|
||||||
E0083,
|
|
||||||
E0084,
|
|
||||||
E0085,
|
E0085,
|
||||||
E0086,
|
E0086,
|
||||||
E0087,
|
E0087,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue