lvalue: refactoring to permit applying a mir projection to a miri lvalue

This commit is contained in:
Ralf Jung 2017-06-19 20:13:26 -07:00
parent 56d4de303f
commit 2312ac8db6

View File

@ -189,7 +189,10 @@ pub(super) fn eval_and_read_lvalue(&mut self, lvalue: &mir::Lvalue<'tcx>) -> Eva
return Ok(val);
}
let lvalue = self.eval_lvalue(lvalue)?;
self.read_lvalue(lvalue, ty)
}
fn read_lvalue(&self, lvalue: Lvalue<'tcx>, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> {
if ty.is_never() {
return Err(EvalError::Unreachable);
}
@ -219,7 +222,11 @@ pub(super) fn eval_lvalue(&mut self, mir_lvalue: &mir::Lvalue<'tcx>) -> EvalResu
Lvalue::Global(GlobalId { instance, promoted: None })
}
Projection(ref proj) => return self.eval_lvalue_projection(proj),
Projection(ref proj) => {
let ty = self.lvalue_ty(&proj.base);
let lvalue = self.eval_lvalue(&proj.base)?;
return self.eval_lvalue_projection(lvalue, ty, &proj.elem);
}
};
if log_enabled!(::log::LogLevel::Trace) {
@ -348,19 +355,17 @@ pub fn lvalue_field(
fn eval_lvalue_projection(
&mut self,
proj: &mir::LvalueProjection<'tcx>,
base: Lvalue<'tcx>,
base_ty: Ty<'tcx>,
proj_elem: &mir::ProjectionElem<'tcx, mir::Operand<'tcx>>,
) -> EvalResult<'tcx, Lvalue<'tcx>> {
use rustc::mir::ProjectionElem::*;
let (ptr, extra, aligned) = match proj.elem {
let (ptr, extra, aligned) = match *proj_elem {
Field(field, field_ty) => {
let base = self.eval_lvalue(&proj.base)?;
let base_ty = self.lvalue_ty(&proj.base);
return self.lvalue_field(base, field.index(), base_ty, field_ty);
}
Downcast(_, variant) => {
let base = self.eval_lvalue(&proj.base)?;
let base_ty = self.lvalue_ty(&proj.base);
let base_layout = self.type_layout(base_ty)?;
// FIXME(solson)
let base = self.force_allocation(base)?;
@ -376,8 +381,7 @@ fn eval_lvalue_projection(
}
Deref => {
let base_ty = self.lvalue_ty(&proj.base);
let val = self.eval_and_read_lvalue(&proj.base)?;
let val = self.read_lvalue(base, base_ty)?;
let pointee_type = match base_ty.sty {
ty::TyRawPtr(ref tam) |
@ -402,8 +406,6 @@ fn eval_lvalue_projection(
}
Index(ref operand) => {
let base = self.eval_lvalue(&proj.base)?;
let base_ty = self.lvalue_ty(&proj.base);
// FIXME(solson)
let base = self.force_allocation(base)?;
let (base_ptr, _, aligned) = base.to_ptr_extra_aligned();
@ -419,8 +421,6 @@ fn eval_lvalue_projection(
}
ConstantIndex { offset, min_length, from_end } => {
let base = self.eval_lvalue(&proj.base)?;
let base_ty = self.lvalue_ty(&proj.base);
// FIXME(solson)
let base = self.force_allocation(base)?;
let (base_ptr, _, aligned) = base.to_ptr_extra_aligned();
@ -440,8 +440,6 @@ fn eval_lvalue_projection(
}
Subslice { from, to } => {
let base = self.eval_lvalue(&proj.base)?;
let base_ty = self.lvalue_ty(&proj.base);
// FIXME(solson)
let base = self.force_allocation(base)?;
let (base_ptr, _, aligned) = base.to_ptr_extra_aligned();