transparent_enums
The tracking issue for this feature is [#60405]
The transparent_enums feature allows you mark enums as
#[repr(transparent)]. An enum may be #[repr(transparent)] if it has
exactly one variant, and that variant matches the same conditions which struct
requires for transparency. Some concrete illustrations follow.
# #![allow(unused_variables)] #![feature(transparent_enums)] #fn main() { // This enum has the same representation as `f32`. #[repr(transparent)] enum SingleFieldEnum { Variant(f32) } // This enum has the same representation as `usize`. #[repr(transparent)] enum MultiFieldEnum { Variant { field: usize, nothing: () }, } #}
For consistency with transparent structs, enums must have exactly one
non-zero-sized field. If all fields are zero-sized, the enum must not be
#[repr(transparent)]:
# #![allow(unused_variables)] #![feature(transparent_enums)] #fn main() { // This (non-transparent) enum is already valid in stable Rust: pub enum GoodEnum { Nothing, } // Error: transparent enum needs exactly one non-zero-sized field, but has 0 // #[repr(transparent)] // pub enum BadEnum { // Nothing(()), // } // Error: transparent enum needs exactly one non-zero-sized field, but has 0 // #[repr(transparent)] // pub enum BadEmptyEnum { // Nothing, // } #}
The one exception is if the enum is generic over T and has a field of type
T, it may be #[repr(transparent)] even if T is a zero-sized type:
# #![allow(unused_variables)] #![feature(transparent_enums)] #fn main() { // This enum has the same representation as `T`. #[repr(transparent)] pub enum GenericEnum<T> { Variant(T, ()), } // This is okay even though `()` is a zero-sized type. pub const THIS_IS_OKAY: GenericEnum<()> = GenericEnum::Variant((), ()); #}
Transparent enums require exactly one variant:
# #![allow(unused_variables)] #fn main() { // Error: transparent enum needs exactly one variant, but has 0 // #[repr(transparent)] // pub enum TooFewVariants { // } // Error: transparent enum needs exactly one variant, but has 2 // #[repr(transparent)] // pub enum TooManyVariants { // First(usize), // Second, // } #}
Like transarent structs, a transparent enum of type E has the same layout,
size, and ABI as its single non-ZST field. If it is generic over a type T, and
all its fields are ZSTs except for exactly one field of type T, then it has
the same layout and ABI as T (even if T is a ZST when monomorphized).
Like transparent structs, transparent enums are FFI-safe if and only if
their underlying representation type is also FFI-safe.