From 842f993fa6b4f9d159815fdcf43e021e0dd4d915 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Wed, 17 Jun 2026 04:24:43 -0500 Subject: [PATCH 1/4] New rule `layout.repr.rust.enum-empty-zst` --- src/glossary.md | 4 ++++ src/type-layout.md | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/glossary.md b/src/glossary.md index e48bcf4f9c..8df0e5550e 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -223,6 +223,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 +285,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 +307,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..ead5c948d2 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -183,6 +183,9 @@ 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]. + 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]. From c04b9735fdb43535e9418383008026dfcd9757e3 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Wed, 8 Jul 2026 11:07:03 -0500 Subject: [PATCH 2/4] Add note to `layout.repr.rust.enum-empty-zst` that empty enums are uninhabited --- src/type-layout.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/type-layout.md b/src/type-layout.md index ead5c948d2..afef90ad91 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -186,6 +186,8 @@ For [structs] with no fields or where all fields are [zero sized], it is further r[layout.repr.rust.enum-empty-zst] For [enums] (without a [primitive representation] specified) with no variants, the enums themselves are [zero sized]. +Note that 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]. @@ -651,3 +653,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 From 5c793073e6b3cdadc2ba97b347f77e28b6d0f6d4 Mon Sep 17 00:00:00 2001 From: Zachary S Date: Wed, 8 Jul 2026 11:25:58 -0500 Subject: [PATCH 3/4] Add note that not all uninhabited types are ZSTs to `glossary.uninhabited` --- src/glossary.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/glossary.md b/src/glossary.md index 8df0e5550e..52da9d6bef 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -211,6 +211,8 @@ 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) From 19075c89d116ec6603679e5898e60c5f31b0a219 Mon Sep 17 00:00:00 2001 From: zachs18 <8355914+zachs18@users.noreply.github.com> Date: Wed, 8 Jul 2026 11:38:18 -0500 Subject: [PATCH 4/4] Apply suggestions from code review Co-authored-by: Travis Cross Co-authored-by: zachs18 <8355914+zachs18@users.noreply.github.com> --- src/glossary.md | 3 ++- src/type-layout.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/glossary.md b/src/glossary.md index 52da9d6bef..55ac13d785 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -211,7 +211,8 @@ 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. +> [!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) diff --git a/src/type-layout.md b/src/type-layout.md index afef90ad91..591dcaa9a7 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -186,7 +186,8 @@ For [structs] with no fields or where all fields are [zero sized], it is further r[layout.repr.rust.enum-empty-zst] For [enums] (without a [primitive representation] specified) with no variants, the enums themselves are [zero sized]. -Note that such enums are [uninhabited]. +> [!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].