diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 7fbe89648d547..7e4f97ca698c5 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -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 @@ -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, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 33ba21bc7b154..5f9e282bc53fe 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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) => { diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 0af19e445f26e..154d824e67846 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -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, @@ -51,10 +130,6 @@ register_diagnostics! { E0075, E0076, E0077, - E0081, - E0082, - E0083, - E0084, E0085, E0086, E0087,