Description
This is an issue to track making a decision on how to handle certain styles of enums with respect to the new arbitrary_enum_discriminant
which has been stabilized in 1.56 (#86860) which will be released October 21st 2021. I think it would be good to make a decision before it reaches stable.
I have a concern that this introduces three styles of enums, and I think it would be best to only have two styles. In summary, as of 1.56, they will be:
Kind 1: Unit-only variants:
// Does not require repr
enum Kind1 {
Foo = 1,
Bar = 2,
Baz = 3,
}
// Can be cast to its discriminant:
let x = Kind1::Foo as u8;
Kind 2: Tuple or struct variants without fields:
#[repr(u8)] // Required repr
enum Kind2 {
Foo() = 1,
Bar{} = 2,
Baz = 3,
}
// Can be cast to its discriminant:
let x = Kind2::Foo() as u8;
Kind 3: Tuple or struct variants with fields:
#[repr(u8)] // Required repr
enum Kind3 {
Foo(i32) = 1,
Bar{f: i32} = 2,
Bar = 3,
}
// ERROR: Does not allow casting.
let x = Kind3::Foo(1) as u8;
The question mainly centers on how Kind2
should be treated. #88203 is a proposal to make it treated the same as Kind1
(that is, does not require repr
). Another proposal is to make it treated the same as Kind3
(does not allow casting), PR up at #89234. Another option it to leave it as-is, and keep three styles.
Only Kind1
is allowed in 1.55 and older versions.
(As an aside, this also highlights that our current terminology of "Fieldless enums" is confusing, since it has historically meant only Kind1
style, but it can be confused with Kind2
since those do not have fields, either.)
More discussion at https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/arbitrary.20enum.20discriminants/near/251899236