use rustc::ty::{self, Ty};
use rustc_data_structures::indexed_vec::Idx;
-use super::{EvalResult, EvalContext, MemoryPointer, PrimVal, Value, Pointer, Machine, PtrAndAlign};
+use super::{EvalResult, EvalContext, MemoryPointer, PrimVal, Value, Pointer, Machine, PtrAndAlign, ValTy};
#[derive(Copy, Clone, Debug)]
pub enum Lvalue {
&mut self,
base: Lvalue,
base_ty: Ty<'tcx>,
- proj_elem: &mir::ProjectionElem<'tcx, mir::Operand<'tcx>, Ty<'tcx>>,
+ proj_elem: &mir::ProjectionElem<'tcx, mir::Local, Ty<'tcx>>,
) -> EvalResult<'tcx, Lvalue> {
use rustc::mir::ProjectionElem::*;
let (ptr, extra) = match *proj_elem {
return self.val_to_lvalue(val, pointee_type);
}
- Index(ref operand) => {
- let n_ptr = self.eval_operand(operand)?;
- let n = self.value_to_primval(n_ptr)?.to_u64()?;
+ Index(local) => {
+ let value = self.frame().get_local(local)?;
+ let ty = self.tcx.types.usize;
+ let n = self.value_to_primval(ValTy { value, ty })?.to_u64()?;
return self.lvalue_index(base, base_ty, n);
}
}
}
- // Mark locals as dead or alive.
- StorageLive(ref lvalue) |
- StorageDead(ref lvalue) => {
- let (frame, local) =
- match self.eval_lvalue(lvalue)? {
- Lvalue::Local { frame, local } if self.cur_frame() == frame => (
- frame,
- local,
- ),
- _ => return err!(Unimplemented("Storage annotations must refer to locals of the topmost stack frame.".to_owned())), // FIXME maybe this should get its own error type
- };
- let old_val = match stmt.kind {
- StorageLive(_) => self.stack[frame].storage_live(local)?,
- StorageDead(_) => self.stack[frame].storage_dead(local)?,
- _ => bug!("We already checked that we are a storage stmt"),
- };
+ // Mark locals as alive
+ StorageLive(local) => {
+ let old_val = self.frame_mut().storage_live(local)?;
+ self.deallocate_local(old_val)?;
+ }
+
+ // Mark locals as dead
+ StorageDead(local) => {
+ let old_val = self.frame_mut().storage_dead(local)?;
self.deallocate_local(old_val)?;
}