Skip to content

Commit 1cd3ddd

Browse files
authored
Rollup merge of rust-lang#61104 - spastorino:eval-place-to-op-iterate, r=oli-obk
Make eval_place_to_op iterate instead of recurse r? @oli-obk
2 parents dd33e8a + e38b399 commit 1cd3ddd

File tree

2 files changed

+39
-27
lines changed

2 files changed

+39
-27
lines changed

src/librustc_mir/interpret/operand.rs

+24-12
Original file line numberDiff line numberDiff line change
@@ -467,22 +467,34 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
467467
mir_place: &mir::Place<'tcx>,
468468
layout: Option<TyLayout<'tcx>>,
469469
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
470-
use rustc::mir::Place::*;
470+
use rustc::mir::Place;
471471
use rustc::mir::PlaceBase;
472-
let op = match *mir_place {
473-
Base(PlaceBase::Local(mir::RETURN_PLACE)) => return err!(ReadFromReturnPointer),
474-
Base(PlaceBase::Local(local)) => self.access_local(self.frame(), local, layout)?,
475472

476-
Projection(ref proj) => {
477-
let op = self.eval_place_to_op(&proj.base, None)?;
478-
self.operand_projection(op, &proj.elem)?
479-
}
473+
mir_place.iterate(|place_base, place_projection| {
474+
let mut op = match place_base {
475+
PlaceBase::Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
476+
PlaceBase::Local(local) => {
477+
// FIXME use place_projection.is_empty() when is available
478+
let layout = if let Place::Base(_) = mir_place {
479+
layout
480+
} else {
481+
None
482+
};
483+
484+
self.access_local(self.frame(), *local, layout)?
485+
}
486+
PlaceBase::Static(place_static) => {
487+
self.eval_static_to_mplace(place_static)?.into()
488+
}
489+
};
480490

481-
_ => self.eval_place_to_mplace(mir_place)?.into(),
482-
};
491+
for proj in place_projection {
492+
op = self.operand_projection(op, &proj.elem)?
493+
}
483494

484-
trace!("eval_place_to_op: got {:?}", *op);
485-
Ok(op)
495+
trace!("eval_place_to_op: got {:?}", *op);
496+
Ok(op)
497+
})
486498
}
487499

488500
/// Evaluate the operand, returning a place where you can then find the data.

src/librustc_mir/interpret/place.rs

+15-15
Original file line numberDiff line numberDiff line change
@@ -562,23 +562,23 @@ where
562562

563563
/// Evaluate statics and promoteds to an `MPlace`. Used to share some code between
564564
/// `eval_place` and `eval_place_to_op`.
565-
pub(super) fn eval_place_to_mplace(
565+
pub(super) fn eval_static_to_mplace(
566566
&self,
567-
mir_place: &mir::Place<'tcx>
567+
place_static: &mir::Static<'tcx>
568568
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
569-
use rustc::mir::Place::*;
570-
use rustc::mir::PlaceBase;
571-
use rustc::mir::{Static, StaticKind};
572-
Ok(match *mir_place {
573-
Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), .. })) => {
569+
use rustc::mir::StaticKind;
570+
571+
Ok(match place_static.kind {
572+
StaticKind::Promoted(promoted) => {
574573
let instance = self.frame().instance;
575574
self.const_eval_raw(GlobalId {
576575
instance,
577576
promoted: Some(promoted),
578577
})?
579578
}
580579

581-
Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), ty })) => {
580+
StaticKind::Static(def_id) => {
581+
let ty = place_static.ty;
582582
assert!(!ty.needs_subst());
583583
let layout = self.layout_of(ty)?;
584584
let instance = ty::Instance::mono(*self.tcx, def_id);
@@ -600,8 +600,6 @@ where
600600
let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id());
601601
MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout)
602602
}
603-
604-
_ => bug!("eval_place_to_mplace called on {:?}", mir_place),
605603
})
606604
}
607605

@@ -613,7 +611,7 @@ where
613611
) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
614612
use rustc::mir::Place::*;
615613
use rustc::mir::PlaceBase;
616-
let place = match *mir_place {
614+
let place = match mir_place {
617615
Base(PlaceBase::Local(mir::RETURN_PLACE)) => match self.frame().return_place {
618616
Some(return_place) =>
619617
// We use our layout to verify our assumption; caller will validate
@@ -628,17 +626,19 @@ where
628626
// This works even for dead/uninitialized locals; we check further when writing
629627
place: Place::Local {
630628
frame: self.cur_frame(),
631-
local,
629+
local: *local,
632630
},
633-
layout: self.layout_of_local(self.frame(), local, None)?,
631+
layout: self.layout_of_local(self.frame(), *local, None)?,
634632
},
635633

636-
Projection(ref proj) => {
634+
Projection(proj) => {
637635
let place = self.eval_place(&proj.base)?;
638636
self.place_projection(place, &proj.elem)?
639637
}
640638

641-
_ => self.eval_place_to_mplace(mir_place)?.into(),
639+
Base(PlaceBase::Static(place_static)) => {
640+
self.eval_static_to_mplace(place_static)?.into()
641+
}
642642
};
643643

644644
self.dump_place(place.place);

0 commit comments

Comments
 (0)