Closed
Description
The following test fails:
struct NeedAlign(u64);
impl Drop for NeedAlign {
fn drop(&mut self) {
assert_eq!(self as *mut _ as usize % 8, 0);
}
}
#[repr(packed)]
#[derive(Copy, Clone)]
struct Unalign<T>(T);
struct Breakit {
x: u8,
y: Unalign<NeedAlign>,
}
fn main() {
println!("before");
{
let x = NeedAlign(0);
}
println!("middle");
{
let x = Breakit { x : 0, y : Unalign(NeedAlign(0)) };
}
println!("after");
}
This could lead to UB, because code for drop
is generated under the assumption that the pointer is aligned.
Related to #27060, but not solved by making taking references to field of packed structs unsafe.
We furthermore have to forbid using types which implement Drop
in a packed struct.
Open question:
How is this supposed to handle generic types, like in the example above? Error on declaration (T
may implement Drop
), or only error when Unalign
is actually used with a type that implements Drop
?
IIRC unions also have a no-drop restriction, so this should probably use the same rules.