1
Fork 0

Auto merge of #115583 - RalfJung:packed-unsized, r=lcnr

fix detecting references to packed unsized fields

Fixes https://github.com/rust-lang/rust/issues/115396

This is a breaking change, but permitted as a soundness fix.
This commit is contained in:
bors 2023-10-07 10:57:18 +00:00
commit 48e24629e9
3 changed files with 73 additions and 12 deletions

View file

@ -21,10 +21,18 @@ where
};
let ty = place.ty(local_decls, tcx).ty;
let unsized_tail = || tcx.struct_tail_with_normalize(ty, |ty| ty, || {});
match tcx.layout_of(param_env.and(ty)) {
Ok(layout) if layout.align.abi <= pack => {
Ok(layout)
if layout.align.abi <= pack
&& (layout.is_sized()
|| matches!(unsized_tail().kind(), ty::Slice(..) | ty::Str)) =>
{
// If the packed alignment is greater or equal to the field alignment, the type won't be
// further disaligned.
// However we need to ensure the field is sized; for unsized fields, `layout.align` is
// just an approximation -- except when the unsized tail is a slice, where the alignment
// is fully determined by the type.
debug!(
"is_disaligned({:?}) - align = {}, packed = {}; not disaligned",
place,