Skip to content

Commit 9f5c9fd

Browse files
committed
Make specifying repr optional for fieldless enums
1 parent 1e3d632 commit 9f5c9fd

File tree

5 files changed

+38
-20
lines changed

5 files changed

+38
-20
lines changed

compiler/rustc_error_codes/src/error_codes/E0732.md

+9-6
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,19 @@ Erroneous code example:
44

55
```compile_fail,E0732
66
enum Enum { // error!
7-
Unit = 1,
8-
Tuple() = 2,
9-
Struct{} = 3,
7+
Unit = 3,
8+
Tuple(u16) = 2,
9+
Struct {
10+
a: u8,
11+
b: u16,
12+
} = 1,
1013
}
1114
# fn main() {}
1215
```
1316

14-
A `#[repr(inttype)]` must be provided on an `enum` if it has a non-unit
15-
variant with a discriminant, or where there are both unit variants with
16-
discriminants and non-unit variants. This restriction ensures that there
17+
A `#[repr(inttype)]` must be provided on an `enum` if it not fieldless and
18+
has a discriminant, or where there are both fieldless variants with
19+
discriminants and variants that have fields. This restriction ensures that there
1720
is a well-defined way to extract a variant's discriminant from a value;
1821
for instance:
1922

compiler/rustc_typeck/src/check/check.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -1384,12 +1384,17 @@ fn check_enum<'tcx>(
13841384
}
13851385

13861386
if tcx.adt_def(def_id).repr.int.is_none() {
1387-
let is_unit = |var: &hir::Variant<'_>| matches!(var.data, hir::VariantData::Unit(..));
1387+
let is_fieldless = |var: &hir::Variant<'_>| match var.data {
1388+
hir::VariantData::Unit(_) => true,
1389+
hir::VariantData::Tuple(fields, _) | hir::VariantData::Struct(fields, _) => {
1390+
fields.is_empty()
1391+
}
1392+
};
13881393

13891394
let has_disr = |var: &hir::Variant<'_>| var.disr_expr.is_some();
1390-
let has_non_units = vs.iter().any(|var| !is_unit(var));
1391-
let disr_units = vs.iter().any(|var| is_unit(&var) && has_disr(&var));
1392-
let disr_non_unit = vs.iter().any(|var| !is_unit(&var) && has_disr(&var));
1395+
let has_non_units = vs.iter().any(|var| !is_fieldless(var));
1396+
let disr_units = vs.iter().any(|var| is_fieldless(&var) && has_disr(&var));
1397+
let disr_non_unit = vs.iter().any(|var| !is_fieldless(&var) && has_disr(&var));
13931398

13941399
if disr_non_unit || (disr_units && has_non_units) {
13951400
let mut err =
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
#![crate_type="lib"]
2-
1+
#![crate_type = "lib"]
32
enum Enum {
4-
//~^ ERROR `#[repr(inttype)]` must be specified
5-
Unit = 1,
6-
Tuple() = 2,
7-
Struct{} = 3,
3+
//~^ ERROR `#[repr(inttype)]` must be specified
4+
Unit = 5,
5+
Tuple(u8) = 3,
6+
Struct {
7+
foo: u16
8+
} = 1,
89
}

src/test/ui/enum-discriminant/arbitrary_enum_discriminant-no-repr.stderr

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
error[E0732]: `#[repr(inttype)]` must be specified
2-
--> $DIR/arbitrary_enum_discriminant-no-repr.rs:3:1
2+
--> $DIR/arbitrary_enum_discriminant-no-repr.rs:2:1
33
|
44
LL | / enum Enum {
55
LL | |
6-
LL | | Unit = 1,
7-
LL | | Tuple() = 2,
8-
LL | | Struct{} = 3,
6+
LL | | Unit = 5,
7+
LL | | Tuple(u8) = 3,
8+
... |
9+
LL | | } = 1,
910
LL | | }
1011
| |_^
1112

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// check-pass
2+
#![crate_type="lib"]
3+
4+
enum Enum {
5+
Unit = 1,
6+
Tuple() = 2,
7+
Struct{} = 3,
8+
}

0 commit comments

Comments
 (0)