diff --git a/src/glossary.md b/src/glossary.md index e48bcf4f9c..55ac13d785 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][glossary.zst]. 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 diff --git a/src/type-layout.md b/src/type-layout.md index db43a87394..591dcaa9a7 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] +For [enums] (without a [primitive representation] specified) with no variants, the enums themselves 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