Skip to content

Commit 969d027

Browse files
committed
Clarify the semantics of enum discriminants
cf. https://doc.rust-lang.org/error-index.html#E0082
1 parent 21fb3ce commit 969d027

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

src/doc/reference.md

+9-3
Original file line numberDiff line numberDiff line change
@@ -1191,18 +1191,24 @@ a = Animal::Cat { name: "Spotty".to_string(), weight: 2.7 };
11911191
In this example, `Cat` is a _struct-like enum variant_,
11921192
whereas `Dog` is simply called an enum variant.
11931193

1194-
Enums have a discriminant. You can assign them explicitly:
1194+
Each enum value has a _discriminant_ which is an integer associated to it. You
1195+
can specify it explicitly:
11951196

11961197
```
11971198
enum Foo {
11981199
Bar = 123,
11991200
}
12001201
```
12011202

1202-
If a discriminant isn't assigned, they start at zero, and add one for each
1203+
The right hand side of the specification is interpreted as an `isize` value,
1204+
but the compiler is allowed to use a smaller type in the actual memory layout.
1205+
The [`repr` attribute](#ffi-attributes) can be added in order to change
1206+
the type of the right hand side and specify the memory layout.
1207+
1208+
If a discriminant isn't specified, they start at zero, and add one for each
12031209
variant, in order.
12041210

1205-
You can cast an enum to get this value:
1211+
You can cast an enum to get its discriminant:
12061212

12071213
```
12081214
# enum Foo { Bar = 123 }

src/librustc_typeck/diagnostics.rs

+18-9
Original file line numberDiff line numberDiff line change
@@ -1133,15 +1133,16 @@ enum Bad {
11331133
}
11341134
```
11351135
1136-
Here `X` will have already been assigned the discriminant 0 by the time `Y` is
1136+
Here `X` will have already been specified the discriminant 0 by the time `Y` is
11371137
encountered, so a conflict occurs.
11381138
"##,
11391139

11401140
E0082: r##"
1141-
The default type for enum discriminants is `isize`, but it can be adjusted by
1142-
adding the `repr` attribute to the enum declaration. This error indicates that
1143-
an integer literal given as a discriminant is not a member of the discriminant
1144-
type. For example:
1141+
When you specify enum discriminants with `=`, the compiler expects `isize`
1142+
values by default. Or you can add the `repr` attibute to the enum declaration
1143+
for an explicit choice of the discriminant type. In either cases, the
1144+
discriminant values must fall within a valid range for the expected type;
1145+
otherwise this error is raised. For example:
11451146
11461147
```compile_fail
11471148
#[repr(u8)]
@@ -1152,11 +1153,19 @@ enum Thing {
11521153
```
11531154
11541155
Here, 1024 lies outside the valid range for `u8`, so the discriminant for `A` is
1155-
invalid. You may want to change representation types to fix this, or else change
1156-
invalid discriminant values so that they fit within the existing type.
1156+
invalid. Here is another, more subtle example which depends on target word size:
11571157
1158-
Note also that without a representation manually defined, the compiler will
1159-
optimize by using the smallest integer type possible.
1158+
```compile_fail
1159+
enum DependsOnPointerSize {
1160+
A = 1 << 32
1161+
}
1162+
```
1163+
1164+
Here, `1 << 32` is interpreted as an `isize` value. So it is invalid for 32 bit
1165+
target (`target_pointer_width = "32"`) but valid for 64 bit target.
1166+
1167+
You may want to change representation types to fix this, or else change invalid
1168+
discriminant values so that they fit within the existing type.
11601169
"##,
11611170

11621171
E0084: r##"

0 commit comments

Comments
 (0)