@@ -152,7 +152,11 @@ impl<Prov: Provenance> Immediate<Prov> {
152
152
}
153
153
}
154
154
( Immediate :: Uninit , _) => {
155
- assert ! ( abi. is_sized( ) , "{msg}: unsized immediates are not a thing" ) ;
155
+ assert_matches ! (
156
+ abi,
157
+ BackendRepr :: Memory { sized: true } ,
158
+ "{msg}: unsized zsts are not a thing"
159
+ ) ;
156
160
}
157
161
_ => {
158
162
bug ! ( "{msg}: value {self:?} does not match ABI {abi:?})" , )
@@ -267,7 +271,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
267
271
match ( imm, layout. backend_repr) {
268
272
( Immediate :: Scalar ( ..) , BackendRepr :: Scalar ( ..) ) => true ,
269
273
( Immediate :: ScalarPair ( ..) , BackendRepr :: ScalarPair ( ..) ) => true ,
270
- ( Immediate :: Uninit , _) if layout. is_sized( ) => true ,
274
+ ( Immediate :: Uninit , _) if layout. is_sized( ) && layout . is_zst ( ) => true ,
271
275
_ => false ,
272
276
} ,
273
277
"immediate {imm:?} does not fit to layout {layout:?}" ,
@@ -276,8 +280,9 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
276
280
}
277
281
278
282
#[ inline]
279
- pub fn uninit ( layout : TyAndLayout < ' tcx > ) -> Self {
283
+ pub fn zst ( layout : TyAndLayout < ' tcx > ) -> Self {
280
284
debug_assert ! ( layout. is_sized( ) , "immediates must be sized" ) ;
285
+ debug_assert ! ( layout. is_zst( ) ) ;
281
286
ImmTy { imm : Immediate :: Uninit , layout }
282
287
}
283
288
@@ -382,15 +387,16 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
382
387
// This makes several assumptions about what layouts we will encounter; we match what
383
388
// codegen does as good as we can (see `extract_field` in `rustc_codegen_ssa/src/mir/operand.rs`).
384
389
let inner_val: Immediate < _ > = match ( * * self , self . layout . backend_repr ) {
385
- // If the entire value is uninit, then so is the field (can happen in ConstProp).
386
- ( Immediate :: Uninit , _) => Immediate :: Uninit ,
387
390
// If the field is uninhabited, we can forget the data (can happen in ConstProp).
388
391
// `enum S { A(!), B, C }` is an example of an enum with Scalar layout that
389
392
// has an uninhabited variant, which means this case is possible.
390
393
_ if layout. is_uninhabited ( ) => Immediate :: Uninit ,
391
394
// the field contains no information, can be left uninit
392
395
// (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST)
393
396
_ if layout. is_zst ( ) => Immediate :: Uninit ,
397
+ // If the value is a zst, then so is the field (can happen in ConstProp).
398
+ // This is handled by the zst field read above.
399
+ ( Immediate :: Uninit , _) => unreachable ! ( ) ,
394
400
// some fieldless enum variants can have non-zero size but still `Aggregate` ABI... try
395
401
// to detect those here and also give them no data
396
402
_ if matches ! ( layout. backend_repr, BackendRepr :: Memory { .. } )
@@ -572,8 +578,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
572
578
}
573
579
574
580
let Some ( alloc) = self . get_place_alloc ( mplace) ? else {
575
- // zero-sized type can be left uninit
576
- return interp_ok ( Some ( ImmTy :: uninit ( mplace. layout ) ) ) ;
581
+ return interp_ok ( Some ( ImmTy :: zst ( mplace. layout ) ) ) ;
577
582
} ;
578
583
579
584
// It may seem like all types with `Scalar` or `ScalarPair` ABI are fair game at this point.
0 commit comments