Oh and I discovered of course that observation migth appear where the user does not consider it:
Some(mem::uninitialized::<&T>())
Reading the enum tag equals reading the “inner” value, because of the enum layout optimization. Consider what struct and enum layout optimizations are still valid if we release the private fields restriction.
For a more vivid picture, imagine the Option is in one crate’s code, and the unintialized &T is nested inside a struct in another crate’s code. This means that pointers must not be uninitialized ever (?).
How does arrayvec avoid this mess? It uses an #[repr(u8)] enum NoDrop<T> { A(T), B } – repr(u8) fortunately is a barrier to layout optimization across the inside/outside of NoDrop<T>. (Which I tried to document)
Since both arrayvec and servo’s smallvec need to use an uninitialized (or zeroed, same problem) interior, it would be nice to solve this officially. There’s some proposals towards that in the manually drop RFC.
Edit: I think I initiated Gankro’s question with a question, so I’m shooting down myself here. I’m happy as long as we discuss these issues so that we get to know the language better, and that’s exactly the goal of Gankro’s current project too right?