diff options
Diffstat (limited to 'tests/ui/packed/dyn-trait.rs')
-rw-r--r-- | tests/ui/packed/dyn-trait.rs | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/tests/ui/packed/dyn-trait.rs b/tests/ui/packed/dyn-trait.rs new file mode 100644 index 000000000..bb73c26c1 --- /dev/null +++ b/tests/ui/packed/dyn-trait.rs @@ -0,0 +1,21 @@ +// run-pass +use std::ptr::addr_of; + +// When the unsized tail is a `dyn Trait`, its alignments is only dynamically known. This means the +// packed(2) needs to be applied at runtime: the actual alignment of the field is `min(2, +// usual_alignment)`. Here we check that we do this right by comparing size, alignment, and field +// offset before and after unsizing. +fn main() { + #[repr(C, packed(2))] + struct Packed<T: ?Sized>(u8, core::mem::ManuallyDrop<T>); + + let p = Packed(0, core::mem::ManuallyDrop::new(1)); + let p: &Packed<usize> = &p; + let sized = (core::mem::size_of_val(p), core::mem::align_of_val(p)); + let sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) }; + let p: &Packed<dyn Send> = p; + let un_sized = (core::mem::size_of_val(p), core::mem::align_of_val(p)); + let un_sized_offset = unsafe { addr_of!(p.1).cast::<u8>().offset_from(addr_of!(p.0)) }; + assert_eq!(sized, un_sized); + assert_eq!(sized_offset, un_sized_offset); +} |