@@ -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