@@ -119,6 +119,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
119119. chain ( Niche :: from_scalar ( dl, Size :: ZERO , a) )
120120. max_by_key ( |niche| niche. available ( dl) ) ;
121121
122+ let combined_seed = a. size ( & self . cx ) . bytes ( ) . wrapping_add ( b. size ( & self . cx ) . bytes ( ) ) ;
123+
122124LayoutData {
123125variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
124126fields : FieldsShape :: Arbitrary {
@@ -131,6 +133,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
131133 size,
132134max_repr_align : None ,
133135unadjusted_abi_align : align. abi ,
136+ randomization_seed : combined_seed,
134137}
135138}
136139
@@ -223,6 +226,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
223226size : Size :: ZERO ,
224227max_repr_align : None ,
225228unadjusted_abi_align : dl. i8_align . abi ,
229+ randomization_seed : 0 ,
226230}
227231}
228232
@@ -385,6 +389,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
385389return Err ( LayoutCalculatorError :: EmptyUnion ) ;
386390} ;
387391
392+ let combined_seed = only_variant
393+ . iter ( )
394+ . map ( |v| v. randomization_seed )
395+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
396+
388397Ok ( LayoutData {
389398variants : Variants :: Single { index : only_variant_idx } ,
390399fields : FieldsShape :: Union ( union_field_count) ,
@@ -394,6 +403,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
394403size : size. align_to ( align. abi ) ,
395404 max_repr_align,
396405 unadjusted_abi_align,
406+ randomization_seed : combined_seed,
397407} )
398408}
399409
@@ -650,6 +660,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
650660BackendRepr :: Memory { sized : true }
651661} ;
652662
663+ let combined_seed = variant_layouts
664+ . iter ( )
665+ . map ( |v| v. randomization_seed )
666+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
667+
653668let layout = LayoutData {
654669variants : Variants :: Multiple {
655670tag : niche_scalar,
@@ -671,6 +686,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
671686 align,
672687 max_repr_align,
673688 unadjusted_abi_align,
689+ randomization_seed : combined_seed,
674690} ;
675691
676692Some ( TmpLayout { layout, variants : variant_layouts } )
@@ -961,6 +977,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
961977
962978let largest_niche = Niche :: from_scalar ( dl, Size :: ZERO , tag) ;
963979
980+ let combined_seed = layout_variants
981+ . iter ( )
982+ . map ( |v| v. randomization_seed )
983+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
984+
964985let tagged_layout = LayoutData {
965986variants : Variants :: Multiple {
966987 tag,
@@ -978,6 +999,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
978999 size,
9791000 max_repr_align,
9801001 unadjusted_abi_align,
1002+ randomization_seed : combined_seed,
9811003} ;
9821004
9831005let tagged_layout = TmpLayout { layout : tagged_layout, variants : layout_variants } ;
@@ -1030,12 +1052,15 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10301052let mut max_repr_align = repr. align ;
10311053let mut inverse_memory_index: IndexVec < u32 , FieldIdx > = fields. indices ( ) . collect ( ) ;
10321054let optimize_field_order = !repr. inhibit_struct_field_reordering ( ) ;
1033- if optimize_field_order && fields. len ( ) > 1 {
1034- let end =
1035- if let StructKind :: MaybeUnsized = kind { fields. len ( ) - 1 } else { fields. len ( ) } ;
1036- let optimizing = & mut inverse_memory_index. raw [ ..end] ;
1037- let fields_excluding_tail = & fields. raw [ ..end] ;
1055+ let end = if let StructKind :: MaybeUnsized = kind { fields. len ( ) - 1 } else { fields. len ( ) } ;
1056+ let optimizing = & mut inverse_memory_index. raw [ ..end] ;
1057+ let fields_excluding_tail = & fields. raw [ ..end] ;
1058+ // unsizable tail fields are excluded so that we use the same seed for the sized and unsized layouts.
1059+ let field_seed = fields_excluding_tail
1060+ . iter ( )
1061+ . fold ( 0u64 , |acc, f| acc. wrapping_add ( f. randomization_seed ) ) ;
10381062
1063+ if optimize_field_order && fields. len ( ) > 1 {
10391064// If `-Z randomize-layout` was enabled for the type definition we can shuffle
10401065// the field ordering to try and catch some code making assumptions about layouts
10411066// we don't guarantee.
@@ -1046,8 +1071,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10461071use rand:: seq:: SliceRandom ;
10471072// `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field
10481073// ordering.
1049- let mut rng =
1050- rand_xoshiro:: Xoshiro128StarStar :: seed_from_u64 ( repr. field_shuffle_seed ) ;
1074+ let mut rng = rand_xoshiro:: Xoshiro128StarStar :: seed_from_u64 (
1075+ field_seed. wrapping_add ( repr. field_shuffle_seed ) ,
1076+ ) ;
10511077
10521078// Shuffle the ordering of the fields.
10531079 optimizing. shuffle ( & mut rng) ;
@@ -1344,6 +1370,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13441370 unadjusted_abi_align
13451371} ;
13461372
1373+ let seed = field_seed. wrapping_add ( repr. field_shuffle_seed ) ;
1374+
13471375Ok ( LayoutData {
13481376variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
13491377fields : FieldsShape :: Arbitrary { offsets, memory_index } ,
@@ -1353,6 +1381,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13531381 size,
13541382 max_repr_align,
13551383 unadjusted_abi_align,
1384+ randomization_seed : seed,
13561385} )
13571386}
13581387
0 commit comments