Description
When we optimized product types with uninhabited fields to be ZST, partial initialization was overlooked, i.e. writes to the inhabited sibling fields are allowed despite missing in the layout.
Thankfully, it's impossible to read or borrow such fields, because the whole value must be initialized (although this may be relaxed in the future). However , the initialized fields are still dropped.
One way we could work around this is track uninhabitedness but only take advantage of it in enums.
(I am not aware of a solution that works with variant types, which I think we should keep in mind.)
EDIT: we can disallow creating the enum
from an incomplete variant. This is also required by niche optimizations because the niche slot being uninitialized would result in UB.
EDIT2: incomplete variants might be possible today already (#49298 (comment)).
As an example, in debug mode, this snippet prints 0
, because x.1
and y
overlap:
enum Void {}
fn main() {
let mut x: (Void, usize);
let y = 1;
x.1 = 0;
println!("{}", y)
}