@@ -152,7 +152,11 @@ impl<Prov: Provenance> Immediate<Prov> {
152152 }
153153 }
154154 ( 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+ ) ;
156160 }
157161 _ => {
158162 bug ! ( "{msg}: value {self:?} does not match ABI {abi:?})" , )
@@ -267,7 +271,7 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
267271 match ( imm, layout. backend_repr) {
268272 ( Immediate :: Scalar ( ..) , BackendRepr :: Scalar ( ..) ) => true ,
269273 ( Immediate :: ScalarPair ( ..) , BackendRepr :: ScalarPair ( ..) ) => true ,
270- ( Immediate :: Uninit , _) if layout. is_sized( ) => true ,
274+ ( Immediate :: Uninit , _) if layout. is_sized( ) && layout . is_zst ( ) => true ,
271275 _ => false ,
272276 } ,
273277 "immediate {imm:?} does not fit to layout {layout:?}" ,
@@ -276,8 +280,9 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
276280 }
277281
278282 #[ inline]
279- pub fn uninit ( layout : TyAndLayout < ' tcx > ) -> Self {
283+ pub fn zst ( layout : TyAndLayout < ' tcx > ) -> Self {
280284 debug_assert ! ( layout. is_sized( ) , "immediates must be sized" ) ;
285+ debug_assert ! ( layout. is_zst( ) ) ;
281286 ImmTy { imm : Immediate :: Uninit , layout }
282287 }
283288
@@ -382,15 +387,16 @@ impl<'tcx, Prov: Provenance> ImmTy<'tcx, Prov> {
382387 // This makes several assumptions about what layouts we will encounter; we match what
383388 // codegen does as good as we can (see `extract_field` in `rustc_codegen_ssa/src/mir/operand.rs`).
384389 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 ,
387390 // If the field is uninhabited, we can forget the data (can happen in ConstProp).
388391 // `enum S { A(!), B, C }` is an example of an enum with Scalar layout that
389392 // has an uninhabited variant, which means this case is possible.
390393 _ if layout. is_uninhabited ( ) => Immediate :: Uninit ,
391394 // the field contains no information, can be left uninit
392395 // (Scalar/ScalarPair can contain even aligned ZST, not just 1-ZST)
393396 _ 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 ! ( ) ,
394400 // some fieldless enum variants can have non-zero size but still `Aggregate` ABI... try
395401 // to detect those here and also give them no data
396402 _ if matches ! ( layout. backend_repr, BackendRepr :: Memory { .. } )
@@ -572,8 +578,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
572578 }
573579
574580 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 ) ) ) ;
577582 } ;
578583
579584 // It may seem like all types with `Scalar` or `ScalarPair` ABI are fair game at this point.
0 commit comments