From 4e32c14d6e387b266a7948811e8785ff0fe4102b Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 5 May 2026 12:48:01 -0700 Subject: [PATCH 1/2] New rule `layout.repr.rust.struct-zst` --- src/glossary.md | 11 +++++++++++ src/type-layout.md | 3 +++ 2 files changed, 14 insertions(+) diff --git a/src/glossary.md b/src/glossary.md index 6a7afcfaae..02585b456f 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -220,6 +220,7 @@ A type is zero sized (a ZST) if its size is 0. Such types have at most one possi - [Function items] (see [type.fn-item.intro]). - The constructors of [tuple-like structs] (see [type.fn-item.intro]). - The constructors of [tuple-like enum variants] (see [type.fn-item.intro]). +- `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]). - [Arrays] of zero-sized types (see [layout.array]). @@ -231,6 +232,13 @@ A type is zero sized (a ZST) if its size is 0. Such types have at most one possi fn f() {} struct S(u8); enum E { V(u8) } +struct UnitLike; +struct NoFields {} +struct OnlyZST { + f1: (), + f2: [(); 10], + f3: [u8; 0], +} #[repr(C)] struct C1 {} #[repr(C)] @@ -257,6 +265,9 @@ assert_eq!(0, size_of::<()>()); assert_eq!(0, size_of_val(&f)); assert_eq!(0, size_of_val(&S)); assert_eq!(0, size_of_val(&E::V)); +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::()); assert_eq!(0, size_of::()); diff --git a/src/type-layout.md b/src/type-layout.md index 2ee902aef0..2af087f43b 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -180,6 +180,9 @@ For [structs], it is further guaranteed that the fields do not overlap. That is, Be aware that this guarantee does not imply that the fields have distinct addresses: [zero-sized types] may have the same address as other fields in the same struct. +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.unspecified] There are no other guarantees of data layout made by this representation. From 5011dcdb90f3b84599ace73a4ee0e05c3de7d286 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Tue, 5 May 2026 12:48:26 -0700 Subject: [PATCH 2/2] New rule `layout.repr.rust.enum-struct-like-zst` --- src/glossary.md | 5 +++++ src/type-layout.md | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/glossary.md b/src/glossary.md index 02585b456f..3915083728 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 a single struct-like variant with no fields or where all 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]). - [Unions] of zero-sized types (see [items.union.common-storage]). @@ -261,6 +262,9 @@ union U { f2: [(); 10], f3: [u8; 0], } +enum E2 { + V1 { f1: (), f2: [(); 10 ] }, +} assert_eq!(0, size_of::<()>()); assert_eq!(0, size_of_val(&f)); assert_eq!(0, size_of_val(&S)); @@ -275,6 +279,7 @@ assert_eq!(0, size_of::()); assert_eq!(0, size_of::<[(); 10]>()); assert_eq!(0, size_of::<[u8; 0]>()); 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 2af087f43b..7624174870 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-struct-like-zst] +For [enums] (without a primitive representation specified) with a single struct-like variant with no fields or where all fields are [zero-sized], the enum itself is [zero-sized]. + r[layout.repr.rust.unspecified] There are no other guarantees of data layout made by this representation. @@ -559,6 +562,7 @@ Because this representation delegates type layout to another type, it cannot be [`Sized`]: std::marker::Sized [`Copy`]: std::marker::Copy [dynamically sized types]: dynamically-sized-types.md +[enums]: items/enumerations.md [field-less enums]: items/enumerations.md#field-less-enum [fn-abi-compatibility]: ../core/primitive.fn.md#abi-compatibility [enumerations]: items/enumerations.md