File tree 2 files changed +31
-2
lines changed
2 files changed +31
-2
lines changed Original file line number Diff line number Diff line change @@ -828,6 +828,7 @@ fn univariant(
828
828
if optimize && fields. len ( ) > 1 {
829
829
let end = if let StructKind :: MaybeUnsized = kind { fields. len ( ) - 1 } else { fields. len ( ) } ;
830
830
let optimizing = & mut inverse_memory_index. raw [ ..end] ;
831
+ let fields_excluding_tail = & fields. raw [ ..end] ;
831
832
832
833
// If `-Z randomize-layout` was enabled for the type definition we can shuffle
833
834
// the field ordering to try and catch some code making assumptions about layouts
@@ -844,8 +845,11 @@ fn univariant(
844
845
}
845
846
// Otherwise we just leave things alone and actually optimize the type's fields
846
847
} 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
849
853
. iter ( )
850
854
. filter_map ( |f| f. largest_niche ( ) )
851
855
. 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