transparent_enums
The tracking issue for this feature is [#60405]
The transparent_enums
feature allows you mark enum
s 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 struct
s, enum
s 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 enum
s 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 struct
s, 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 struct
s, transparent enum
s are FFI-safe if and only if
their underlying representation type is also FFI-safe.