@@ -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+
122124 LayoutData {
123125 variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
124126 fields : FieldsShape :: Arbitrary {
@@ -131,6 +133,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
131133 size,
132134 max_repr_align : None ,
133135 unadjusted_abi_align : align. abi ,
136+ randomization_seed : combined_seed,
134137 }
135138 }
136139
@@ -223,6 +226,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
223226 size : Size :: ZERO ,
224227 max_repr_align : None ,
225228 unadjusted_abi_align : dl. i8_align . abi ,
229+ randomization_seed : 0 ,
226230 }
227231 }
228232
@@ -385,6 +389,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
385389 return 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+
388397 Ok ( LayoutData {
389398 variants : Variants :: Single { index : only_variant_idx } ,
390399 fields : FieldsShape :: Union ( union_field_count) ,
@@ -394,6 +403,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
394403 size : 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> {
650660 BackendRepr :: 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+
653668 let layout = LayoutData {
654669 variants : Variants :: Multiple {
655670 tag : 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
676692 Some ( TmpLayout { layout, variants : variant_layouts } )
@@ -961,6 +977,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
961977
962978 let 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+
964985 let tagged_layout = LayoutData {
965986 variants : 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
9831005 let tagged_layout = TmpLayout { layout : tagged_layout, variants : layout_variants } ;
@@ -1029,6 +1051,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10291051 let mut align = if pack. is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
10301052 let mut max_repr_align = repr. align ;
10311053 let mut inverse_memory_index: IndexVec < u32 , FieldIdx > = fields. indices ( ) . collect ( ) ;
1054+ let field_seed =
1055+ fields. raw . iter ( ) . fold ( 0u64 , |acc, f| acc. wrapping_add ( f. randomization_seed ) ) ;
10321056 let optimize_field_order = !repr. inhibit_struct_field_reordering ( ) ;
10331057 if optimize_field_order && fields. len ( ) > 1 {
10341058 let end =
@@ -1046,8 +1070,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10461070 use rand:: seq:: SliceRandom ;
10471071 // `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field
10481072 // ordering.
1049- let mut rng =
1050- rand_xoshiro:: Xoshiro128StarStar :: seed_from_u64 ( repr. field_shuffle_seed ) ;
1073+ let mut rng = rand_xoshiro:: Xoshiro128StarStar :: seed_from_u64 (
1074+ field_seed. wrapping_add ( repr. field_shuffle_seed ) ,
1075+ ) ;
10511076
10521077 // Shuffle the ordering of the fields.
10531078 optimizing. shuffle ( & mut rng) ;
@@ -1344,6 +1369,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13441369 unadjusted_abi_align
13451370 } ;
13461371
1372+ // a transparent struct only has a single field, so its seed should be the same as the one we pass forward
1373+ let seed = if repr. transparent ( ) {
1374+ field_seed
1375+ } else {
1376+ field_seed. wrapping_add ( repr. field_shuffle_seed )
1377+ } ;
1378+
13471379 Ok ( LayoutData {
13481380 variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
13491381 fields : FieldsShape :: Arbitrary { offsets, memory_index } ,
@@ -1353,6 +1385,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13531385 size,
13541386 max_repr_align,
13551387 unadjusted_abi_align,
1388+ randomization_seed : seed,
13561389 } )
13571390 }
13581391
0 commit comments