Why is safety dependent on context?
In order to be safe, a well-defined transmutation must also not allow you to:
- construct instances of a hidden
Dst
type - mutate hidden fields of the
Src
type - construct hidden fields of the
Dst
type
Whether these conditions are satisfied depends on the context of the transmutation, because scope determines the visibility of fields. Consider:
#![allow(unused)] fn main() { mod a { use super::*; #[repr(C)] pub struct NonZeroU32(u32); impl NonZeroU32 { fn new(v: u32) -> Self { unsafe { core::mem::transmute(v) } // sound. } } } mod b { use super::*; fn new(v: u32) -> a::NonZeroU32 { unsafe { core::mem::transmute(v) } // ☢️ UNSOUND! } } }
The transmutation in b
is unsound because it constructs a hidden field of NonZeroU32
.