Skip to content

Commit e962870

Browse files
committed
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.
2 parents 2568a4d + 63e6321 commit e962870

File tree

3 files changed

+107
-7
lines changed

3 files changed

+107
-7
lines changed

src/librustc/diagnostics.rs

+25-2
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,31 @@ This error indicates that an attempt was made to divide by zero (or take the
227227
remainder of a zero divisor) in a static or constant expression.
228228
"##,
229229

230+
E0079: r##"
231+
Enum variants which contain no data can be given a custom integer
232+
representation. This error indicates that the value provided is not an
233+
integer literal and is therefore invalid.
234+
"##,
235+
236+
E0080: r##"
237+
This error indicates that the compiler was unable to sensibly evaluate an
238+
integer expression provided as an enum discriminant. Attempting to divide by 0
239+
or causing integer overflow are two ways to induce this error. For example:
240+
241+
```
242+
enum Enum {
243+
X = (1 << 500),
244+
Y = (1 / 0)
245+
}
246+
```
247+
248+
Ensure that the expressions given can be evaluated as the desired integer type.
249+
See the FFI section of the Reference for more information about using a custom
250+
integer type:
251+
252+
http://doc.rust-lang.org/reference.html#ffi-attributes
253+
"##,
254+
230255
E0133: r##"
231256
Using unsafe functionality, such as dereferencing raw pointers and calling
232257
functions via FFI or marked as unsafe, is potentially dangerous and disallowed
@@ -507,8 +532,6 @@ register_diagnostics! {
507532
E0017,
508533
E0019,
509534
E0022,
510-
E0079, // enum variant: expected signed integer constant
511-
E0080, // enum variant: constant evaluation error
512535
E0109,
513536
E0110,
514537
E0134,

src/librustc/middle/ty.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -5732,8 +5732,10 @@ fn compute_enum_variants<'tcx>(cx: &ctxt<'tcx>,
57325732
Ok(const_eval::const_int(val)) => current_disr_val = val as Disr,
57335733
Ok(const_eval::const_uint(val)) => current_disr_val = val as Disr,
57345734
Ok(_) => {
5735+
let sign_desc = if repr_type.is_signed() { "signed" } else { "unsigned" };
57355736
span_err!(cx.sess, e.span, E0079,
5736-
"expected signed integer constant");
5737+
"expected {} integer constant",
5738+
sign_desc);
57375739
current_disr_val = attempt_fresh_value();
57385740
}
57395741
Err(ref err) => {

src/librustc_typeck/diagnostics.rs

+79-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,85 @@
1010

1111
#![allow(non_snake_case)]
1212

13+
register_long_diagnostics! {
14+
15+
E0081: r##"
16+
Enum discriminants are used to differentiate enum variants stored in memory.
17+
This error indicates that the same value was used for two or more variants,
18+
making them impossible to tell apart.
19+
20+
```
21+
// Good.
22+
enum Enum {
23+
P,
24+
X = 3,
25+
Y = 5
26+
}
27+
28+
// Bad.
29+
enum Enum {
30+
P = 3,
31+
X = 3,
32+
Y = 5
33+
}
34+
```
35+
36+
Note that variants without a manually specified discriminant are numbered from
37+
top to bottom starting from 0, so clashes can occur with seemingly unrelated
38+
variants.
39+
40+
```
41+
enum Bad {
42+
X,
43+
Y = 0
44+
}
45+
```
46+
47+
Here `X` will have already been assigned the discriminant 0 by the time `Y` is
48+
encountered, so a conflict occurs.
49+
"##,
50+
51+
E0082: r##"
52+
The default type for enum discriminants is `isize`, but it can be adjusted by
53+
adding the `repr` attribute to the enum declaration. This error indicates that
54+
an integer literal given as a discriminant is not a member of the discriminant
55+
type. For example:
56+
57+
```
58+
#[repr(u8)]
59+
enum Thing {
60+
A = 1024,
61+
B = 5
62+
}
63+
```
64+
65+
Here, 1024 lies outside the valid range for `u8`, so the discriminant for `A` is
66+
invalid. You may want to change representation types to fix this, or else change
67+
invalid discriminant values so that they fit within the existing type.
68+
69+
Note also that without a representation manually defined, the compiler will
70+
optimize by using the smallest integer type possible.
71+
"##,
72+
73+
E0083: r##"
74+
At present, it's not possible to define a custom representation for an enum with
75+
a single variant. As a workaround you can add a `Dummy` variant.
76+
77+
See: https://github.com/rust-lang/rust/issues/10292
78+
"##,
79+
80+
E0084: r##"
81+
It is impossible to define an integer type to be used to represent zero-variant
82+
enum values because there are no zero-variant enum values. There is no way to
83+
construct an instance of the following type using only safe code:
84+
85+
```
86+
enum Empty {}
87+
```
88+
"##
89+
90+
}
91+
1392
register_diagnostics! {
1493
E0023,
1594
E0024,
@@ -51,10 +130,6 @@ register_diagnostics! {
51130
E0075,
52131
E0076,
53132
E0077,
54-
E0081,
55-
E0082,
56-
E0083,
57-
E0084,
58133
E0085,
59134
E0086,
60135
E0087,

0 commit comments

Comments
 (0)