Skip to content

Commit e38b399

Browse files
committed
Make eval_place_to_op iterate instead of recurse
1 parent 6d7a362 commit e38b399

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

src/librustc_mir/interpret/operand.rs

+24-13
Original file line numberDiff line numberDiff line change
@@ -467,23 +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)?,
475-
Base(PlaceBase::Static(place_static)) => {
476-
self.eval_static_to_mplace(place_static)?.into()
477-
}
478472

479-
Projection(proj) => {
480-
let op = self.eval_place_to_op(&proj.base, None)?;
481-
self.operand_projection(op, &proj.elem)?
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+
};
490+
491+
for proj in place_projection {
492+
op = self.operand_projection(op, &proj.elem)?
482493
}
483-
};
484494

485-
trace!("eval_place_to_op: got {:?}", *op);
486-
Ok(op)
495+
trace!("eval_place_to_op: got {:?}", *op);
496+
Ok(op)
497+
})
487498
}
488499

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

0 commit comments

Comments
 (0)