File tree Expand file tree Collapse file tree 2 files changed +31
-2
lines changed Expand file tree Collapse file tree 2 files changed +31
-2
lines changed Original file line number Diff line number Diff line change @@ -828,6 +828,7 @@ fn univariant(
828828 if optimize && fields. len ( ) > 1 {
829829 let end = if let StructKind :: MaybeUnsized = kind { fields. len ( ) - 1 } else { fields. len ( ) } ;
830830 let optimizing = & mut inverse_memory_index. raw [ ..end] ;
831+ let fields_excluding_tail = & fields. raw [ ..end] ;
831832
832833 // If `-Z randomize-layout` was enabled for the type definition we can shuffle
833834 // the field ordering to try and catch some code making assumptions about layouts
@@ -844,8 +845,11 @@ fn univariant(
844845 }
845846 // Otherwise we just leave things alone and actually optimize the type's fields
846847 } else {
847- let max_field_align = fields. iter ( ) . map ( |f| f. align ( ) . abi . bytes ( ) ) . max ( ) . unwrap_or ( 1 ) ;
848- let largest_niche_size = fields
848+ // To allow unsizing `&Foo<Type>` -> `&Foo<dyn Trait>`, the layout of the struct must
849+ // not depend on the layout of the tail.
850+ let max_field_align =
851+ fields_excluding_tail. iter ( ) . map ( |f| f. align ( ) . abi . bytes ( ) ) . max ( ) . unwrap_or ( 1 ) ;
852+ let largest_niche_size = fields_excluding_tail
849853 . iter ( )
850854 . filter_map ( |f| f. largest_niche ( ) )
851855 . map ( |n| n. available ( dl) )
Original file line number Diff line number Diff line change 1+ // run-pass
2+
3+ // Check that unsizing doesn't reorder fields.
4+
5+ #![ allow( dead_code) ]
6+
7+ use std:: fmt:: Debug ;
8+
9+ #[ derive( Debug ) ]
10+ struct GcNode < T : ?Sized > {
11+ gets_swapped_with_next : usize ,
12+ next : Option < & ' static GcNode < dyn Debug > > ,
13+ tail : T ,
14+ }
15+
16+ fn main ( ) {
17+ let node: Box < GcNode < dyn Debug > > = Box :: new ( GcNode {
18+ gets_swapped_with_next : 42 ,
19+ next : None ,
20+ tail : Box :: new ( 1 ) ,
21+ } ) ;
22+
23+ assert_eq ! ( node. gets_swapped_with_next, 42 ) ;
24+ assert ! ( node. next. is_none( ) ) ;
25+ }
You can’t perform that action at this time.
0 commit comments