Skip to content

Commit e3de14e

Browse files
author
Lukas Markeffsky
committed
sanity check field offsets in unsizeable structs
1 parent 478071b commit e3de14e

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

compiler/rustc_ty_utils/src/layout.rs

+49
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,55 @@ fn layout_of_uncached<'tcx>(
499499
return Err(error(cx, LayoutError::SizeOverflow(ty)));
500500
};
501501

502+
// If the struct tail is sized and can be unsized, check that unsizing doesn't move the fields around.
503+
if cfg!(debug_assertions)
504+
&& maybe_unsized
505+
&& def
506+
.non_enum_variant()
507+
.fields
508+
.raw
509+
.last()
510+
.unwrap()
511+
.ty(tcx, substs)
512+
.is_sized(tcx, cx.param_env)
513+
{
514+
let mut variants = variants;
515+
let tail_replacement = cx.layout_of(Ty::new_slice(tcx, tcx.types.u8)).unwrap();
516+
*variants[FIRST_VARIANT].raw.last_mut().unwrap() = tail_replacement.layout;
517+
518+
let Some(unsized_layout) = cx.layout_of_struct_or_enum(
519+
&def.repr(),
520+
&variants,
521+
def.is_enum(),
522+
def.is_unsafe_cell(),
523+
tcx.layout_scalar_valid_range(def.did()),
524+
get_discriminant_type,
525+
discriminants_iter(),
526+
dont_niche_optimize_enum,
527+
!maybe_unsized,
528+
) else {
529+
bug!("failed to compute unsized layout of {ty:?}");
530+
};
531+
532+
let FieldsShape::Arbitrary { offsets: sized_offsets, .. } = &layout.fields else {
533+
bug!("unexpected FieldsShape for sized layout of {ty:?}: {:?}", layout.fields);
534+
};
535+
let FieldsShape::Arbitrary { offsets: unsized_offsets, .. } = &unsized_layout.fields else {
536+
bug!("unexpected FieldsShape for unsized layout of {ty:?}: {:?}", unsized_layout.fields);
537+
};
538+
539+
let (sized_tail, sized_fields) = sized_offsets.raw.split_last().unwrap();
540+
let (unsized_tail, unsized_fields) = unsized_offsets.raw.split_last().unwrap();
541+
542+
if sized_fields != unsized_fields {
543+
bug!("unsizing {ty:?} changed field order!\n{layout:?}\n{unsized_layout:?}");
544+
}
545+
546+
if sized_tail < unsized_tail {
547+
bug!("unsizing {ty:?} moved tail backwards!\n{layout:?}\n{unsized_layout:?}");
548+
}
549+
}
550+
502551
tcx.mk_layout(layout)
503552
}
504553

0 commit comments

Comments
 (0)