Try playing around with these types:
(Playground)
#[repr(C)]
struct MyStruct<H, const N: usize, T> {
head: H,
body: [u8; N],
tail: T,
}
#[repr(u8)]
enum U8SingleVariant {
OnlyVariant,
}
fn main() {
show_size!(header); // see macro definition in playground
show_size!(U8SingleVariant);
show_size!(MyStruct<u8, 6, u8>);
show_size!(MyStruct<u8, 6, NonZeroU8>);
show_size!(MyStruct<u8, 6, U8SingleVariant>);
show_size!(MyStruct<u8, 6, ()>);
// ...
}
We got:
Type T Option<T>
U8SingleVariant 1 1
MyStruct<u8, 6, u8> 8 9
MyStruct<u8, 6, NonZeroU8> 8 8
MyStruct<NonZeroU8, 6, u8> 8 8
MyStruct<(), 7, NonZeroU8> 8 8
MyStruct<NonZeroU8, 7, ()> 8 8
MyStruct<u8, 6, U8SingleVariant> 8 8
MyStruct<U8SingleVariant, 6, u8> 8 8
MyStruct<u8, 6, ()> 7 8
MyStruct<u16, 5, u8> 8 10
MyStruct<u16, 5, NonZeroU8> 8 8
MyStruct<u16, 5, U8SingleVariant> 8 8
MyStruct<u16, 5, ()> 8 10 // <- doesn't look smart
MyStruct<u16, 4, NonZeroU16> 8 8
MyStruct<u16, 4, U8SingleVariant> 8 8
MyStruct<u16, 4, u8> 8 10 // <- doesn't look smart
MyStruct<u16, 4, ()> 6 8
MyStruct<u64, 7, NonZeroU8> 16 16
MyStruct<u64, 7, U8SingleVariant> 16 16
MyStruct<u64, 7, ()> 16 24 // <- doesn't look smart
Can niche optimization be enhanced to make use of padding bytes in the future?
P.S. There's something else that could theoretically have its layout automated, basically:
enum Category0 {
Variant0 = 0,
Variant1 = 1,
}
enum Category1 { // valid patterns of `Category0` & `Category1` do not overlap
Variant2 = 2,
Variant3 = 3,
}
enum MyEnum { // make sizeof::<MyEnum>() == 1
Category0(Category0),
Category1(Category1),
}
But I guess this might be too heavy.
On the other hand, making use of padding bytes doesn't seem too complicated.