There are 3 cases of this undefined behaviour in std::ascii:
unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
let v: Vec<u8> = mem::transmute(self);
v.into_ascii_nocheck()
}
#[inline]
unsafe fn into_ascii_nocheck(self) -> Vec<Ascii> {
mem::transmute(self)
}
fn into_bytes(self) -> Vec<u8> {
unsafe { mem::transmute(self) }
}
There is no guarantee that Vec<T> and Vec<U> have the same layout under the new rules. This needs to manually copy over the fields one by one which would compile to the same code as long as a feature like struct randomization wasn't enabled. Since vectors expose from_raw_parts, it could be switched to make use of that. However, this is a pervasive issue with transmute in the standard libraries.