Skip to content

Commit

Permalink
Add long diagnostics for enum repr errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelsproul committed Apr 30, 2015
1 parent f0bd14f commit 63e6321
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 7 deletions.
27 changes: 25 additions & 2 deletions src/librustc/diagnostics.rs
Expand Up @@ -221,6 +221,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.
"##,

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##"
Using unsafe functionality, such as dereferencing raw pointers and calling
functions via FFI or marked as unsafe, is potentially dangerous and disallowed
Expand Down Expand Up @@ -502,8 +527,6 @@ register_diagnostics! {
E0017,
E0019,
E0022,
E0079, // enum variant: expected signed integer constant
E0080, // enum variant: constant evaluation error
E0109,
E0110,
E0134,
Expand Down
4 changes: 3 additions & 1 deletion src/librustc/middle/ty.rs
Expand Up @@ -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_uint(val)) => current_disr_val = val as Disr,
Ok(_) => {
let sign_desc = if repr_type.is_signed() { "signed" } else { "unsigned" };
span_err!(cx.sess, e.span, E0079,
"expected signed integer constant");
"expected {} integer constant",
sign_desc);
current_disr_val = attempt_fresh_value();
}
Err(ref err) => {
Expand Down
83 changes: 79 additions & 4 deletions src/librustc_typeck/diagnostics.rs
Expand Up @@ -10,6 +10,85 @@

#![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! {
E0023,
E0024,
Expand Down Expand Up @@ -51,10 +130,6 @@ register_diagnostics! {
E0075,
E0076,
E0077,
E0081,
E0082,
E0083,
E0084,
E0085,
E0086,
E0087,
Expand Down

0 comments on commit 63e6321

Please sign in to comment.