@@ -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
@@ -222,6 +225,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
222225 size : Size :: ZERO ,
223226 max_repr_align : None ,
224227 unadjusted_abi_align : dl. i8_align . abi ,
228+ randomization_seed : 0 ,
225229 }
226230 }
227231
@@ -384,6 +388,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
384388 return Err ( LayoutCalculatorError :: EmptyUnion ) ;
385389 } ;
386390
391+ let combined_seed = only_variant
392+ . iter ( )
393+ . map ( |v| v. randomization_seed )
394+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
395+
387396 Ok ( LayoutData {
388397 variants : Variants :: Single { index : only_variant_idx } ,
389398 fields : FieldsShape :: Union ( union_field_count) ,
@@ -393,6 +402,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
393402 size : size. align_to ( align. abi ) ,
394403 max_repr_align,
395404 unadjusted_abi_align,
405+ randomization_seed : combined_seed,
396406 } )
397407 }
398408
@@ -649,6 +659,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
649659 BackendRepr :: Memory { sized : true }
650660 } ;
651661
662+ let combined_seed = variant_layouts
663+ . iter ( )
664+ . map ( |v| v. randomization_seed )
665+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
666+
652667 let layout = LayoutData {
653668 variants : Variants :: Multiple {
654669 tag : niche_scalar,
@@ -670,6 +685,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
670685 align,
671686 max_repr_align,
672687 unadjusted_abi_align,
688+ randomization_seed : combined_seed,
673689 } ;
674690
675691 Some ( TmpLayout { layout, variants : variant_layouts } )
@@ -960,6 +976,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
960976
961977 let largest_niche = Niche :: from_scalar ( dl, Size :: ZERO , tag) ;
962978
979+ let combined_seed = layout_variants
980+ . iter ( )
981+ . map ( |v| v. randomization_seed )
982+ . fold ( repr. field_shuffle_seed , |acc, seed| acc. wrapping_add ( seed) ) ;
983+
963984 let tagged_layout = LayoutData {
964985 variants : Variants :: Multiple {
965986 tag,
@@ -977,6 +998,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
977998 size,
978999 max_repr_align,
9791000 unadjusted_abi_align,
1001+ randomization_seed : combined_seed,
9801002 } ;
9811003
9821004 let tagged_layout = TmpLayout { layout : tagged_layout, variants : layout_variants } ;
@@ -1028,6 +1050,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10281050 let mut align = if pack. is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
10291051 let mut max_repr_align = repr. align ;
10301052 let mut inverse_memory_index: IndexVec < u32 , FieldIdx > = fields. indices ( ) . collect ( ) ;
1053+ let field_seed =
1054+ fields. raw . iter ( ) . fold ( 0u64 , |acc, f| acc. wrapping_add ( f. randomization_seed ) ) ;
10311055 let optimize_field_order = !repr. inhibit_struct_field_reordering ( ) ;
10321056 if optimize_field_order && fields. len ( ) > 1 {
10331057 let end =
@@ -1043,10 +1067,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
10431067 {
10441068 use rand:: SeedableRng ;
10451069 use rand:: seq:: SliceRandom ;
1070+ //let field_entropy = fields_excluding_tail.iter().map(|f| f.).sum();
10461071 // `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field
10471072 // ordering.
1048- let mut rng =
1049- 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+ ) ;
10501076
10511077 // Shuffle the ordering of the fields.
10521078 optimizing. shuffle ( & mut rng) ;
@@ -1343,6 +1369,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13431369 unadjusted_abi_align
13441370 } ;
13451371
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+
13461379 Ok ( LayoutData {
13471380 variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
13481381 fields : FieldsShape :: Arbitrary { offsets, memory_index } ,
@@ -1352,6 +1385,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
13521385 size,
13531386 max_repr_align,
13541387 unadjusted_abi_align,
1388+ randomization_seed : seed,
13551389 } )
13561390 }
13571391
0 commit comments