@@ -119,6 +119,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
119
119
. chain ( Niche :: from_scalar ( dl, Size :: ZERO , a) )
120
120
. max_by_key ( |niche| niche. available ( dl) ) ;
121
121
122
+ let combined_seed = a. size ( & self . cx ) . bytes ( ) . wrapping_add ( b. size ( & self . cx ) . bytes ( ) ) ;
123
+
122
124
LayoutData {
123
125
variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
124
126
fields : FieldsShape :: Arbitrary {
@@ -131,6 +133,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
131
133
size,
132
134
max_repr_align : None ,
133
135
unadjusted_abi_align : align. abi ,
136
+ randomization_seed : combined_seed,
134
137
}
135
138
}
136
139
@@ -223,6 +226,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
223
226
size : Size :: ZERO ,
224
227
max_repr_align : None ,
225
228
unadjusted_abi_align : dl. i8_align . abi ,
229
+ randomization_seed : 0 ,
226
230
}
227
231
}
228
232
@@ -385,6 +389,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
385
389
return Err ( LayoutCalculatorError :: EmptyUnion ) ;
386
390
} ;
387
391
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
+
388
397
Ok ( LayoutData {
389
398
variants : Variants :: Single { index : only_variant_idx } ,
390
399
fields : FieldsShape :: Union ( union_field_count) ,
@@ -394,6 +403,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
394
403
size : size. align_to ( align. abi ) ,
395
404
max_repr_align,
396
405
unadjusted_abi_align,
406
+ randomization_seed : combined_seed,
397
407
} )
398
408
}
399
409
@@ -650,6 +660,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
650
660
BackendRepr :: Memory { sized : true }
651
661
} ;
652
662
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
+
653
668
let layout = LayoutData {
654
669
variants : Variants :: Multiple {
655
670
tag : niche_scalar,
@@ -671,6 +686,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
671
686
align,
672
687
max_repr_align,
673
688
unadjusted_abi_align,
689
+ randomization_seed : combined_seed,
674
690
} ;
675
691
676
692
Some ( TmpLayout { layout, variants : variant_layouts } )
@@ -961,6 +977,11 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
961
977
962
978
let largest_niche = Niche :: from_scalar ( dl, Size :: ZERO , tag) ;
963
979
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
+
964
985
let tagged_layout = LayoutData {
965
986
variants : Variants :: Multiple {
966
987
tag,
@@ -978,6 +999,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
978
999
size,
979
1000
max_repr_align,
980
1001
unadjusted_abi_align,
1002
+ randomization_seed : combined_seed,
981
1003
} ;
982
1004
983
1005
let tagged_layout = TmpLayout { layout : tagged_layout, variants : layout_variants } ;
@@ -1029,6 +1051,8 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1029
1051
let mut align = if pack. is_some ( ) { dl. i8_align } else { dl. aggregate_align } ;
1030
1052
let mut max_repr_align = repr. align ;
1031
1053
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 ) ) ;
1032
1056
let optimize_field_order = !repr. inhibit_struct_field_reordering ( ) ;
1033
1057
if optimize_field_order && fields. len ( ) > 1 {
1034
1058
let end =
@@ -1046,8 +1070,9 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1046
1070
use rand:: seq:: SliceRandom ;
1047
1071
// `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field
1048
1072
// 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
+ ) ;
1051
1076
1052
1077
// Shuffle the ordering of the fields.
1053
1078
optimizing. shuffle ( & mut rng) ;
@@ -1344,6 +1369,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1344
1369
unadjusted_abi_align
1345
1370
} ;
1346
1371
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
+
1347
1379
Ok ( LayoutData {
1348
1380
variants : Variants :: Single { index : VariantIdx :: new ( 0 ) } ,
1349
1381
fields : FieldsShape :: Arbitrary { offsets, memory_index } ,
@@ -1353,6 +1385,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
1353
1385
size,
1354
1386
max_repr_align,
1355
1387
unadjusted_abi_align,
1388
+ randomization_seed : seed,
1356
1389
} )
1357
1390
}
1358
1391
0 commit comments