Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]).
Expand All @@ -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)]
Expand All @@ -253,17 +262,24 @@ 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::<UnitLike>());
assert_eq!(0, size_of::<NoFields>());
assert_eq!(0, size_of::<OnlyZST>());
assert_eq!(0, size_of::<C1>());
assert_eq!(0, size_of::<C2>());
assert_eq!(0, size_of::<T1>());
assert_eq!(0, size_of::<T2>());
assert_eq!(0, size_of::<[(); 10]>());
assert_eq!(0, size_of::<[u8; 0]>());
assert_eq!(0, size_of::<U>());
assert_eq!(0, size_of::<E2>());
```

[`extern` blocks]: items.extern
Expand Down
7 changes: 7 additions & 0 deletions src/type-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Copy link
Copy Markdown
Contributor

@theemathas theemathas May 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems bizarre to guarantee this for struct-like variants but not unit-like variants or tuple-like variants.

View changes since the review


r[layout.repr.rust.unspecified]
There are no other guarantees of data layout made by this representation.

Expand Down Expand Up @@ -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
Expand Down
Loading