Zero-sized type
A Zero-sized type (ZST) is a type that occupies no memory and is optimized away by the compiler. For example, a Vec<()>
never allocates memory.
Zero-sized types are:
- The empty tuple
()
- The never type
!
-
Structs, unions and tuples, if all their fields are zero-sized, e.g.
struct Struct; struct Struct2(Struct); struct Struct3(PhantomData<bool>);
- Enums with at most one variant that isn't uninhabited, if all its fields are zero-sized, e.g.
#![feature(never_type)] enum Void {} enum Unit { Unit } enum Unit2 { Unit, Uninhabited(!), Uninhabited2(Void), } enum Phantom { Phantom(PhantomData<bool>), }
Note that PhantomData
is also a ZST. It is a special type, because it is generic, even though it has no fields.
Note that struct Foo(i32, !)
and enum Foo { Foo(i32, !) }
are not zero-sized. Rust doesn't treat them as uninhabited types, even though they have no possible values.
N-ZSTs
One important aspect of memory layout of a type is its alignment. To distinguish ZSTs with different alignments, Rust developers agreed to call them n-ZSTs in natural language and there is a proposal to use ZST1
, ZST2
, ZST4
, ZST8
, ZST16
, ZST32
, ZST64
, and ZST128
as identifiers in programs.