Auto merge of #113245 - lukas-code:unsizing-sanity-check, r=the8472
sanity check field offsets in unsizeable structs As promised in https://github.com/rust-lang/rust/pull/112062#issuecomment-1567494994, this PR extends the layout sanity checks to ensure that structs fields don't move around when unsizing and prevent issues like https://github.com/rust-lang/rust/issues/112048 in the future. Like most other layout sanity checks, this only runs on compilers with debug assertions enabled. Here is how it looks when it fails: ```text error: internal compiler error: compiler/rustc_ty_utils/src/layout.rs:533:21: unsizing GcNode<std::boxed::Box<i32>> changed field order! Layout { size: Size(32 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, abi: Aggregate { sized: true }, fields: Arbitrary { offsets: [Size(0 bytes), Size(8 bytes), Size(24 bytes)], memory_index: [0, 1, 2] }, largest_niche: Some(Niche { offset: Size(24 bytes), value: Pointer(AddressSpace(0)), valid_range: 1..=18446744073709551615 }), variants: Single { index: 0 } } Layout { size: Size(24 bytes), align: AbiAndPrefAlign { abi: Align(8 bytes), pref: Align(8 bytes) }, abi: Aggregate { sized: false }, fields: Arbitrary { offsets: [Size(16 bytes), Size(0 bytes), Size(24 bytes)], memory_index: [1, 0, 2] }, largest_niche: None, variants: Single { index: 0 } } ``` r? `@the8472`
This commit is contained in:
commit
cb80ff132a
10 changed files with 107 additions and 56 deletions
|
@ -366,7 +366,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
|
|||
}
|
||||
|
||||
ty::Adt(def, substs) if def.is_struct() => {
|
||||
match def.non_enum_variant().fields.raw.last() {
|
||||
match def.non_enum_variant().tail_opt() {
|
||||
None => tcx.types.unit,
|
||||
Some(field_def) => {
|
||||
let self_ty = field_def.ty(tcx, substs);
|
||||
|
|
|
@ -425,12 +425,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
|||
return Err(NoSolution);
|
||||
}
|
||||
|
||||
let tail_field = a_def
|
||||
.non_enum_variant()
|
||||
.fields
|
||||
.raw
|
||||
.last()
|
||||
.expect("expected unsized ADT to have a tail field");
|
||||
let tail_field = a_def.non_enum_variant().tail();
|
||||
let tail_field_ty = tcx.type_of(tail_field.did);
|
||||
|
||||
let a_tail_ty = tail_field_ty.subst(tcx, a_substs);
|
||||
|
|
|
@ -1125,12 +1125,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
return Err(Unimplemented);
|
||||
}
|
||||
|
||||
let tail_field = def
|
||||
.non_enum_variant()
|
||||
.fields
|
||||
.raw
|
||||
.last()
|
||||
.expect("expected unsized ADT to have a tail field");
|
||||
let tail_field = def.non_enum_variant().tail();
|
||||
let tail_field_ty = tcx.type_of(tail_field.did);
|
||||
|
||||
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue