@@ -1120,21 +1120,12 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
1120
1120
match st[ i] . abi ( ) {
1121
1121
Abi :: Scalar ( _) => Abi :: Scalar ( niche_scalar) ,
1122
1122
Abi :: ScalarPair ( first, second) => {
1123
- // We need to use scalar_unit to reset the
1124
- // valid range to the maximal one for that
1125
- // primitive, because only the niche is
1126
- // guaranteed to be initialised, not the
1127
- // other primitive.
1123
+ // Only the niche is guaranteed to be initialised,
1124
+ // so use union layout for the other primitive.
1128
1125
if offset. bytes ( ) == 0 {
1129
- Abi :: ScalarPair (
1130
- niche_scalar,
1131
- scalar_unit ( second. primitive ( ) ) ,
1132
- )
1126
+ Abi :: ScalarPair ( niche_scalar, second. to_union ( ) )
1133
1127
} else {
1134
- Abi :: ScalarPair (
1135
- scalar_unit ( first. primitive ( ) ) ,
1136
- niche_scalar,
1137
- )
1128
+ Abi :: ScalarPair ( first. to_union ( ) , niche_scalar)
1138
1129
}
1139
1130
}
1140
1131
_ => Abi :: Aggregate { sized : true } ,
@@ -1329,22 +1320,30 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
1329
1320
} else {
1330
1321
// Try to use a ScalarPair for all tagged enums.
1331
1322
let mut common_prim = None ;
1323
+ let mut common_prim_initialized_in_all_variants = true ;
1332
1324
for ( field_layouts, layout_variant) in iter:: zip ( & variants, & layout_variants) {
1333
1325
let FieldsShape :: Arbitrary { ref offsets, .. } = layout_variant. fields else {
1334
1326
bug ! ( ) ;
1335
1327
} ;
1336
1328
let mut fields =
1337
1329
iter:: zip ( field_layouts, offsets) . filter ( |p| !p. 0 . is_zst ( ) ) ;
1338
1330
let ( field, offset) = match ( fields. next ( ) , fields. next ( ) ) {
1339
- ( None , None ) => continue ,
1331
+ ( None , None ) => {
1332
+ common_prim_initialized_in_all_variants = false ;
1333
+ continue ;
1334
+ }
1340
1335
( Some ( pair) , None ) => pair,
1341
1336
_ => {
1342
1337
common_prim = None ;
1343
1338
break ;
1344
1339
}
1345
1340
} ;
1346
1341
let prim = match field. abi {
1347
- Abi :: Scalar ( scalar) => scalar. primitive ( ) ,
1342
+ Abi :: Scalar ( scalar) => {
1343
+ common_prim_initialized_in_all_variants &=
1344
+ matches ! ( scalar, Scalar :: Initialized { .. } ) ;
1345
+ scalar. primitive ( )
1346
+ }
1348
1347
_ => {
1349
1348
common_prim = None ;
1350
1349
break ;
@@ -1364,7 +1363,13 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
1364
1363
}
1365
1364
}
1366
1365
if let Some ( ( prim, offset) ) = common_prim {
1367
- let pair = self . scalar_pair ( tag, scalar_unit ( prim) ) ;
1366
+ let prim_scalar = if common_prim_initialized_in_all_variants {
1367
+ scalar_unit ( prim)
1368
+ } else {
1369
+ // Common prim might be uninit.
1370
+ Scalar :: Union { value : prim }
1371
+ } ;
1372
+ let pair = self . scalar_pair ( tag, prim_scalar) ;
1368
1373
let pair_offsets = match pair. fields {
1369
1374
FieldsShape :: Arbitrary { ref offsets, ref memory_index } => {
1370
1375
assert_eq ! ( memory_index, & [ 0 , 1 ] ) ;
0 commit comments