diff --git a/src/doc/reference.md b/src/doc/reference.md index c2b22ef3e72c2..5708d8092a256 100644 --- a/src/doc/reference.md +++ b/src/doc/reference.md @@ -1191,7 +1191,8 @@ a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 }; In this example, `Cat` is a _struct-like enum variant_, whereas `Dog` is simply called an enum variant. -Enums have a discriminant. You can assign them explicitly: +Each enum value has a _discriminant_ which is an integer associated to it. You +can specify it explicitly: ``` enum Foo { @@ -1199,10 +1200,15 @@ enum Foo { } ``` -If a discriminant isn't assigned, they start at zero, and add one for each +The right hand side of the specification is interpreted as an `isize` value, +but the compiler is allowed to use a smaller type in the actual memory layout. +The [`repr` attribute](#ffi-attributes) can be added in order to change +the type of the right hand side and specify the memory layout. + +If a discriminant isn't specified, they start at zero, and add one for each variant, in order. -You can cast an enum to get this value: +You can cast an enum to get its discriminant: ``` # enum Foo { Bar = 123 } diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 01f7d6b456582..cfe76206b0290 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1133,15 +1133,16 @@ enum Bad { } ``` -Here `X` will have already been assigned the discriminant 0 by the time `Y` is +Here `X` will have already been specified 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: +When you specify enum discriminants with `=`, the compiler expects `isize` +values by default. Or you can add the `repr` attibute to the enum declaration +for an explicit choice of the discriminant type. In either cases, the +discriminant values must fall within a valid range for the expected type; +otherwise this error is raised. For example: ```compile_fail #[repr(u8)] @@ -1152,11 +1153,19 @@ enum Thing { ``` 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. +invalid. Here is another, more subtle example which depends on target word size: -Note also that without a representation manually defined, the compiler will -optimize by using the smallest integer type possible. +```compile_fail +enum DependsOnPointerSize { + A = 1 << 32 +} +``` + +Here, `1 << 32` is interpreted as an `isize` value. So it is invalid for 32 bit +target (`target_pointer_width = "32"`) but valid for 64 bit target. + +You may want to change representation types to fix this, or else change invalid +discriminant values so that they fit within the existing type. "##, E0084: r##"