Skip to content

Commit 93776bb

Browse files
Glossary: add new entry documenting zero-sized types
1 parent 8c88f9d commit 93776bb

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

src/glossary.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,68 @@ r[glossary.uninhabited]
211211

212212
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).
213213

214+
r[glossary.zst]
215+
### Zero-sized type (ZST)
216+
217+
A type is zero sized (a ZST) if its size is 0. Such types have at most one possible value. Examples include:
218+
219+
- The [unit type] (see [layout.tuple.unit]).
220+
- [Function items] (see [type.fn-item.intro]).
221+
- The constructors of tuple-like structs (see [type.fn-item.intro]).
222+
- The constructors of tuple-like enum variants (see [type.fn-item.intro]).
223+
- `#[repr(C)]` structs with no fields ([unit-like structs]) or where all fields are zero-sized (see [layout.repr.c.struct.size-field-offset]).
224+
- `#[repr(transparent)]` structs with no fields ([unit-like structs]) or where all fields are zero-sized (see [layout.repr.transparent.layout-abi]).
225+
- [Arrays] of zero-sized types (see [layout.array]).
226+
- [Arrays] of length zero (see [layout.array]).
227+
- [Unions] of zero-sized types (see [items.union.common-storage]).
228+
229+
```rust
230+
# use core::mem::{size_of, size_of_val};
231+
fn f() {}
232+
struct S(u8);
233+
enum E{ V(u8) }
234+
#[repr(C)]
235+
struct C1 {}
236+
#[repr(C)]
237+
struct C2 {
238+
f1: (),
239+
f2: [(); 10],
240+
f3: [u8; 0],
241+
f4: C1,
242+
}
243+
#[repr(transparent)]
244+
struct T1 {}
245+
#[repr(transparent)]
246+
struct T2 {
247+
f1: (),
248+
f2: [(); 10],
249+
f3: [u8; 0],
250+
}
251+
union U {
252+
f1: (),
253+
f2: [(); 10],
254+
f3: [u8; 0],
255+
}
256+
assert_eq!(0, size_of::<()>());
257+
assert_eq!(0, size_of_val(&f));
258+
// Note that here we are checking the size of the constructors, *not* the
259+
// underlying type, for `S` and `E::V`. The constructors just have the same
260+
// names as the types.
261+
assert_eq!(0, size_of_val(&S));
262+
assert_eq!(0, size_of_val(&E::V));
263+
assert_eq!(0, size_of::<C1>());
264+
assert_eq!(0, size_of::<C2>());
265+
assert_eq!(0, size_of::<T1>());
266+
assert_eq!(0, size_of::<T2>());
267+
assert_eq!(0, size_of::<[(); 10]>());
268+
assert_eq!(0, size_of::<[u8; 0]>());
269+
assert_eq!(0, size_of::<U>());
270+
```
271+
214272
[`extern` blocks]: items.extern
215273
[`extern fn`]: items.fn.extern
216274
[alignment]: type-layout.md#size-and-alignment
275+
[arrays]: type.array
217276
[associated item]: #associated-item
218277
[attributes]: attributes.md
219278
[*entity*]: names.md
@@ -222,6 +281,7 @@ A type is uninhabited if it has no constructors and therefore can never be insta
222281
[enums]: items/enumerations.md
223282
[fields]: expressions/field-expr.md
224283
[free item]: #free-item
284+
[function items]: type.fn-item
225285
[generic parameters]: items/generics.md
226286
[identifier]: identifiers.md
227287
[identifiers]: identifiers.md
@@ -252,5 +312,7 @@ A type is uninhabited if it has no constructors and therefore can never be insta
252312
[types]: types.md
253313
[undefined-behavior]: behavior-considered-undefined.md
254314
[unions]: items/unions.md
315+
[unit type]: type.tuple.unit
316+
[unit-like structs]: items.struct.unit
255317
[variable bindings]: patterns.md
256318
[visibility rules]: visibility-and-privacy.md

0 commit comments

Comments
 (0)