Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 24 additions & 12 deletions src/librustc_mir/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,22 +467,34 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
mir_place: &mir::Place<'tcx>,
layout: Option<TyLayout<'tcx>>,
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*;
use rustc::mir::Place;
use rustc::mir::PlaceBase;
let op = match *mir_place {
Base(PlaceBase::Local(mir::RETURN_PLACE)) => return err!(ReadFromReturnPointer),
Base(PlaceBase::Local(local)) => self.access_local(self.frame(), local, layout)?,

Projection(ref proj) => {
let op = self.eval_place_to_op(&proj.base, None)?;
self.operand_projection(op, &proj.elem)?
}
mir_place.iterate(|place_base, place_projection| {
let mut op = match place_base {
PlaceBase::Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
PlaceBase::Local(local) => {
// FIXME use place_projection.is_empty() when is available
let layout = if let Place::Base(_) = mir_place {
layout
} else {
None
};

self.access_local(self.frame(), *local, layout)?
}
PlaceBase::Static(place_static) => {
self.eval_static_to_mplace(place_static)?.into()
}
};

_ => self.eval_place_to_mplace(mir_place)?.into(),
};
for proj in place_projection {
op = self.operand_projection(op, &proj.elem)?
}

trace!("eval_place_to_op: got {:?}", *op);
Ok(op)
trace!("eval_place_to_op: got {:?}", *op);
Ok(op)
})
}

/// Evaluate the operand, returning a place where you can then find the data.
Expand Down
30 changes: 15 additions & 15 deletions src/librustc_mir/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,23 +562,23 @@ where

/// Evaluate statics and promoteds to an `MPlace`. Used to share some code between
/// `eval_place` and `eval_place_to_op`.
pub(super) fn eval_place_to_mplace(
pub(super) fn eval_static_to_mplace(
&self,
mir_place: &mir::Place<'tcx>
place_static: &mir::Static<'tcx>
) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*;
use rustc::mir::PlaceBase;
use rustc::mir::{Static, StaticKind};
Ok(match *mir_place {
Base(PlaceBase::Static(box Static { kind: StaticKind::Promoted(promoted), .. })) => {
use rustc::mir::StaticKind;

Ok(match place_static.kind {
StaticKind::Promoted(promoted) => {
let instance = self.frame().instance;
self.const_eval_raw(GlobalId {
instance,
promoted: Some(promoted),
})?
}

Base(PlaceBase::Static(box Static { kind: StaticKind::Static(def_id), ty })) => {
StaticKind::Static(def_id) => {
let ty = place_static.ty;
assert!(!ty.needs_subst());
let layout = self.layout_of(ty)?;
let instance = ty::Instance::mono(*self.tcx, def_id);
Expand All @@ -600,8 +600,6 @@ where
let alloc = self.tcx.alloc_map.lock().intern_static(cid.instance.def_id());
MPlaceTy::from_aligned_ptr(Pointer::from(alloc).with_default_tag(), layout)
}

_ => bug!("eval_place_to_mplace called on {:?}", mir_place),
})
}

Expand All @@ -613,7 +611,7 @@ where
) -> EvalResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
use rustc::mir::Place::*;
use rustc::mir::PlaceBase;
let place = match *mir_place {
let place = match mir_place {
Base(PlaceBase::Local(mir::RETURN_PLACE)) => match self.frame().return_place {
Some(return_place) =>
// We use our layout to verify our assumption; caller will validate
Expand All @@ -628,17 +626,19 @@ where
// This works even for dead/uninitialized locals; we check further when writing
place: Place::Local {
frame: self.cur_frame(),
local,
local: *local,
},
layout: self.layout_of_local(self.frame(), local, None)?,
layout: self.layout_of_local(self.frame(), *local, None)?,
},

Projection(ref proj) => {
Projection(proj) => {
let place = self.eval_place(&proj.base)?;
self.place_projection(place, &proj.elem)?
}

_ => self.eval_place_to_mplace(mir_place)?.into(),
Base(PlaceBase::Static(place_static)) => {
self.eval_static_to_mplace(place_static)?.into()
}
};

self.dump_place(place.place);
Expand Down