@@ -499,6 +499,55 @@ fn layout_of_uncached<'tcx>(
499
499
return Err ( error ( cx, LayoutError :: SizeOverflow ( ty) ) ) ;
500
500
} ;
501
501
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
+
502
551
tcx. mk_layout ( layout)
503
552
}
504
553
0 commit comments