diff --git a/src/glossary.md b/src/glossary.md index 6a7afcfaae..3915083728 100644 --- a/src/glossary.md +++ b/src/glossary.md @@ -220,8 +220,10 @@ 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]). +- `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]). @@ -231,6 +233,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)] @@ -253,10 +262,16 @@ 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)); 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::()); @@ -264,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 2ee902aef0..7624174870 100644 --- a/src/type-layout.md +++ b/src/type-layout.md @@ -180,6 +180,12 @@ 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.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. @@ -556,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