Skip to content

Commit

Permalink
Auto merge of #118538 - RalfJung:size-of-val-comments, r=WaffleLapkin
Browse files Browse the repository at this point in the history
fix dynamic size/align computation logic for packed types with dyn trait tail

This logic was never updated to support `packed(N)` where `N > 1`, and it turns out to be wrong for that case.

Fixes rust-lang/rust#80925

`@bjorn3` I have not looked at cranelift; I assume it basically copied the size-of-val logic and hence could use much the same patch.
  • Loading branch information
bors committed Dec 14, 2023
2 parents 3fee9c9 + 1c171ec commit 70db9df
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions tests/pass/packed-struct-dyn-trait.rs
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 70db9df

Please sign in to comment.