@@ -75,7 +75,9 @@ pub enum Place<Prov: Provenance = AllocId> {
75
75
76
76
/// To support alloc-free locals, we are able to write directly to a local.
77
77
/// (Without that optimization, we'd just always be a `MemPlace`.)
78
- Local { frame : usize , local : mir:: Local } ,
78
+ /// This always refers to a local in the current stack frame. That works because `Place` is
79
+ /// never stored anywhere long-term, only for the duration of evaluating a single statement.
80
+ Local { local : mir:: Local } ,
79
81
}
80
82
81
83
#[ derive( Clone , Debug ) ]
@@ -169,9 +171,9 @@ impl<Prov: Provenance> Place<Prov> {
169
171
/// Returns the frame idx and the variable idx.
170
172
#[ inline]
171
173
#[ cfg_attr( debug_assertions, track_caller) ] // only in debug builds due to perf (see #98980)
172
- pub fn assert_local ( & self ) -> ( usize , mir:: Local ) {
174
+ pub fn assert_local ( & self ) -> mir:: Local {
173
175
match self {
174
- Place :: Local { frame , local } => ( * frame , * local) ,
176
+ Place :: Local { local } => * local,
175
177
_ => bug ! ( "assert_local: expected Place::Local, got {:?}" , self ) ,
176
178
}
177
179
}
@@ -283,10 +285,10 @@ impl<'tcx, Prov: Provenance> OpTy<'tcx, Prov> {
283
285
impl < ' tcx , Prov : Provenance > PlaceTy < ' tcx , Prov > {
284
286
/// A place is either an mplace or some local.
285
287
#[ inline]
286
- pub fn as_mplace_or_local ( & self ) -> Either < MPlaceTy < ' tcx , Prov > , ( usize , mir:: Local ) > {
288
+ pub fn as_mplace_or_local ( & self ) -> Either < MPlaceTy < ' tcx , Prov > , mir:: Local > {
287
289
match * * self {
288
290
Place :: Ptr ( mplace) => Left ( MPlaceTy { mplace, layout : self . layout , align : self . align } ) ,
289
- Place :: Local { frame , local } => Right ( ( frame , local) ) ,
291
+ Place :: Local { local } => Right ( local) ,
290
292
}
291
293
}
292
294
@@ -348,7 +350,7 @@ where
348
350
}
349
351
350
352
let mplace = self . ref_to_mplace ( & val) ?;
351
- self . check_mplace ( mplace) ?;
353
+ self . check_mplace ( & mplace) ?;
352
354
Ok ( mplace)
353
355
}
354
356
@@ -379,7 +381,7 @@ where
379
381
}
380
382
381
383
/// Check if this mplace is dereferenceable and sufficiently aligned.
382
- pub fn check_mplace ( & self , mplace : MPlaceTy < ' tcx , M :: Provenance > ) -> InterpResult < ' tcx > {
384
+ pub fn check_mplace ( & self , mplace : & MPlaceTy < ' tcx , M :: Provenance > ) -> InterpResult < ' tcx > {
383
385
let ( size, _align) = self
384
386
. size_and_align_of_mplace ( & mplace) ?
385
387
. unwrap_or ( ( mplace. layout . size , mplace. layout . align . abi ) ) ;
@@ -418,11 +420,10 @@ where
418
420
419
421
pub fn local_to_place (
420
422
& self ,
421
- frame : usize ,
422
423
local : mir:: Local ,
423
424
) -> InterpResult < ' tcx , PlaceTy < ' tcx , M :: Provenance > > {
424
- let layout = self . layout_of_local ( & self . stack ( ) [ frame ] , local, None ) ?;
425
- let place = Place :: Local { frame , local } ;
425
+ let layout = self . layout_of_local ( & self . frame ( ) , local, None ) ?;
426
+ let place = Place :: Local { local } ;
426
427
Ok ( PlaceTy { place, layout, align : layout. align . abi } )
427
428
}
428
429
@@ -433,7 +434,7 @@ where
433
434
& mut self ,
434
435
mir_place : mir:: Place < ' tcx > ,
435
436
) -> InterpResult < ' tcx , PlaceTy < ' tcx , M :: Provenance > > {
436
- let mut place = self . local_to_place ( self . frame_idx ( ) , mir_place. local ) ?;
437
+ let mut place = self . local_to_place ( mir_place. local ) ?;
437
438
// Using `try_fold` turned out to be bad for performance, hence the loop.
438
439
for elem in mir_place. projection . iter ( ) {
439
440
place = self . place_projection ( & place, elem) ?
@@ -509,8 +510,8 @@ where
509
510
// See if we can avoid an allocation. This is the counterpart to `read_immediate_raw`,
510
511
// but not factored as a separate function.
511
512
let mplace = match dest. place {
512
- Place :: Local { frame , local } => {
513
- match M :: access_local_mut ( self , frame , local) ? {
513
+ Place :: Local { local } => {
514
+ match M :: access_local_mut ( self , local) ? {
514
515
Operand :: Immediate ( local) => {
515
516
// Local can be updated in-place.
516
517
* local = src;
@@ -593,8 +594,8 @@ where
593
594
pub fn write_uninit ( & mut self , dest : & PlaceTy < ' tcx , M :: Provenance > ) -> InterpResult < ' tcx > {
594
595
let mplace = match dest. as_mplace_or_local ( ) {
595
596
Left ( mplace) => mplace,
596
- Right ( ( frame , local) ) => {
597
- match M :: access_local_mut ( self , frame , local) ? {
597
+ Right ( local) => {
598
+ match M :: access_local_mut ( self , local) ? {
598
599
Operand :: Immediate ( local) => {
599
600
* local = Immediate :: Uninit ;
600
601
return Ok ( ( ) ) ;
@@ -728,16 +729,15 @@ where
728
729
place : & PlaceTy < ' tcx , M :: Provenance > ,
729
730
) -> InterpResult < ' tcx , MPlaceTy < ' tcx , M :: Provenance > > {
730
731
let mplace = match place. place {
731
- Place :: Local { frame , local } => {
732
- match M :: access_local_mut ( self , frame , local) ? {
732
+ Place :: Local { local } => {
733
+ match M :: access_local_mut ( self , local) ? {
733
734
& mut Operand :: Immediate ( local_val) => {
734
735
// We need to make an allocation.
735
736
736
737
// We need the layout of the local. We can NOT use the layout we got,
737
738
// that might e.g., be an inner field of a struct with `Scalar` layout,
738
739
// that has different alignment than the outer field.
739
- let local_layout =
740
- self . layout_of_local ( & self . stack ( ) [ frame] , local, None ) ?;
740
+ let local_layout = self . layout_of_local ( & self . frame ( ) , local, None ) ?;
741
741
if local_layout. is_unsized ( ) {
742
742
throw_unsup_format ! ( "unsized locals are not supported" ) ;
743
743
}
@@ -755,8 +755,7 @@ where
755
755
}
756
756
// Now we can call `access_mut` again, asserting it goes well,
757
757
// and actually overwrite things.
758
- * M :: access_local_mut ( self , frame, local) . unwrap ( ) =
759
- Operand :: Indirect ( mplace) ;
758
+ * M :: access_local_mut ( self , local) . unwrap ( ) = Operand :: Indirect ( mplace) ;
760
759
mplace
761
760
}
762
761
& mut Operand :: Indirect ( mplace) => mplace, // this already was an indirect local
0 commit comments