I know that all types I work with are packed and cannot be represented by zero-bit patterns(ensured by zerocopy::{TryFromBytes, Immutable, IntoBytes}
and a similar custom NonZeroable
trait ). No I'm trying to build a custom Option type for these types such that the None
variant is guaranteed to be represented by a zero-bit pattern. See
Rust Playground (T is unconstrained here to make code shorter).
Is it sound to cast MaybeUninit
to bytes pointer and check if all bytes are zero when I guarantee that MaybeUninit
is either MaybeUninit::new(T)
or MaybeUninit::zeroed()
? So far MIRI is happy.
This is, I think, only true because of your IntoBytes
bound preventing padding and undef. It's very much not true in general -- MaybeUninit<(u16, u8)>
being the easiest counterexample.
1 Like
Yes, so my only concern is if it's ok to read bytes of MaybeUninit<T>
when all underlying bytes are initialized but constitute an invalid bit pattern for T
.
Unlike C++, Rust does not have typed memory. If you're reading memory and it's initialized, it doesn't matter what "type" it was declared as originally. Period.
If fact, if you look at the LLVM IR these days, every single local variable alloca
is just emitted as a byte array of whatever width is needed to match the type (and the appropriate alignment).
3 Likes