Description
Tested on latest stable and nightly.
I wanted to build an enum X such that
enum X {
Inline(MyType /* size: 24, align: 8 */),
Heap(Vec<MyType>),
}
is 24 bytes large.
I tried various things to exploit Vec's niches (0/null on ptr, > isize::MAX on capacity), including using explicit-zero padding.
Unfortunately for this very specific case it seems Vec lacks alignment niches on its pointer field to make this work, and/or I can't make a niche that's big enough for the compiler to prove the two variants are fully "disjoint" in their valid bit patterns.
However, even testing with much simpler types with much simpler niches I could not get the compiler to produce an optimal enum layout:
#[repr(u64)]
enum AlwaysZero {
VALUE = 0
}
enum X {
A(AlwaysZero),
B(std::num::NonZeroU64)
}
X is 16 bytes here, even though AlwaysZero
and NonZeroU64
's niches are exact opposites of each other, so the entire enum should just be 8 bytes. It would be nice if rustc could support at least simple two-variant cases like this. I can see it coming in handy for things like Result
and possibly Cow
.