diff --git a/src/glossary.md b/src/glossary.md index e48bcf4f9c..4fe80b5681 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -211,6 +211,9 @@ r[glossary.uninhabited] A type is uninhabited if it has no constructors and therefore can never be instantiated. An uninhabited type is "empty" in the sense that there are no values of the type. The canonical example of an uninhabited type is the [never type] `!`, or an enum with no variants `enum Never { }`. Opposite of [Inhabited](#inhabited). +> [!NOTE] +> Uninhabited types are not necessarily [zero sized]. For example, `enum Never { }` is uninhabited and zero sized, but `(u8, Never)` is uninhabited and not zero sized. + r[glossary.zst] ### Zero-sized type (ZST) @@ -223,6 +226,7 @@ A type is zero sized (a ZST) if its size is 0. Such types have at most one possi - `repr(Rust)` [structs] with no fields or where all fields are zero sized (see [layout.repr.rust.struct-zst]). - `repr(C)` [structs] with no fields or where all fields are zero-sized (see [layout.repr.c.struct.size-field-offset]). - `repr(transparent)` [structs] with no fields or where all fields are zero-sized (see [layout.repr.transparent.layout-abi]). +- `repr(Rust)` [enums] (without a [primitive representation] specified) with no variants (see [layout.repr.rust.enum-empty-zst]) - `repr(Rust)` [enums] (without a [primitive representation] specified) with a single [field-struct-like variant], a single [unit-struct-like variant], or a single [tuple-struct-like variant] and where the struct-like thing has no fields or where all of the fields are zero sized (see [layout.repr.rust.enum-struct-like-zst]). - [Arrays] of zero-sized types (see [layout.array]). - [Arrays] of length zero (see [layout.array]). @@ -284,6 +288,8 @@ enum E5 { enum E6 { V1 (), } +# /// An enum with no variants. +enum E7 {} assert_eq!(0, size_of::<()>()); assert_eq!(0, size_of_val(&f)); @@ -304,6 +310,7 @@ assert_eq!(0, size_of::()); assert_eq!(0, size_of::()); assert_eq!(0, size_of::()); assert_eq!(0, size_of::()); +assert_eq!(0, size_of::()); ``` [`extern` blocks]: items.extern @@ -358,3 +365,4 @@ assert_eq!(0, size_of::()); [unit-struct-like variant]: EnumVariant [variable bindings]: patterns.md [visibility rules]: visibility-and-privacy.md +[zero sized]: glossary.zst diff --git a/src/type-layout.md b/src/type-layout.md index db43a87394..b9596f3abf 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -183,6 +183,12 @@ Be aware that this guarantee does not imply that the fields have distinct addres r[layout.repr.rust.struct-zst] For [structs] with no fields or where all fields are [zero sized], it is further guaranteed that the structs are themselves [zero sized]. +r[layout.repr.rust.enum-empty-zst] +[Enums] (without a [primitive representation] specified) with no variants are [zero sized]. + +> [!NOTE] +> Such enums are [uninhabited]. + r[layout.repr.rust.enum-struct-like-zst] For [enums] (without a [primitive representation] specified) with a single [field-struct-like variant], a single [unit-struct-like variant], or a single [tuple-struct-like variant] and where the struct-like thing has no fields or where all of the fields are [zero sized], the enums themselves are [zero sized]. @@ -648,3 +654,4 @@ Because this representation delegates type layout to another type, it cannot be [tuple-struct-like variant]: EnumVariantTuple [unit-struct-like variant]: EnumVariant [`Layout`]: std::alloc::Layout +[uninhabited]: glossary.uninhabited