InterpretCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup
};
-impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
#[inline]
pub fn goto_block(&mut self, target: Option<mir::BasicBlock>) -> InterpResult<'tcx> {
if let Some(target) = target {
let (fn_def, abi) = match func.layout.ty.sty {
ty::FnPtr(sig) => {
let caller_abi = sig.abi();
- let fn_ptr = self.read_scalar(func)?.to_ptr()?;
+ let fn_ptr = self.force_ptr(self.read_scalar(func)?.not_undef()?)?;
let instance = self.memory.get_fn(fn_ptr)?;
(instance, caller_abi)
}
}
// We need MIR for this fn
- let mir = match M::find_fn(self, instance, args, dest, ret)? {
- Some(mir) => mir,
+ let body = match M::find_fn(self, instance, args, dest, ret)? {
+ Some(body) => body,
None => return Ok(()),
};
self.push_stack_frame(
instance,
span,
- mir,
+ body,
dest,
StackPopCleanup::Goto(ret),
)?;
);
trace!(
"spread_arg: {:?}, locals: {:#?}",
- mir.spread_arg,
- mir.args_iter()
+ body.spread_arg,
+ body.args_iter()
.map(|local|
(local, self.layout_of_local(self.frame(), local, None).unwrap().ty)
)
// this is a single iterator (that handles `spread_arg`), then
// `pass_argument` would be the loop body. It takes care to
// not advance `caller_iter` for ZSTs.
- let mut locals_iter = mir.args_iter();
+ let mut locals_iter = body.args_iter();
while let Some(local) = locals_iter.next() {
let dest = self.eval_place(
- &mir::Place::Base(mir::PlaceBase::Local(local))
+ &mir::Place::from(local)
)?;
- if Some(local) == mir.spread_arg {
+ if Some(local) == body.spread_arg {
// Must be a tuple
for i in 0..dest.layout.fields.count() {
let dest = self.place_field(dest, i as u64)?;
));
}
} else {
- let callee_layout =
- self.layout_of_local(self.frame(), mir::RETURN_PLACE, None)?;
- if !callee_layout.abi.is_uninhabited() {
- return err!(FunctionRetMismatch(
- self.tcx.types.never, callee_layout.ty
- ));
+ let local = mir::RETURN_PLACE;
+ let ty = self.frame().body.local_decls[local].ty;
+ if !self.tcx.is_ty_uninhabited_from_any_module(ty) {
+ return err!(FunctionRetMismatch(self.tcx.types.never, ty));
}
}
Ok(())
}
};
// Find and consult vtable
- let vtable = receiver_place.vtable()?;
- self.memory.check_align(vtable.into(), self.tcx.data_layout.pointer_align.abi)?;
- let fn_ptr = self.memory.get(vtable.alloc_id)?.read_ptr_sized(
- self,
- vtable.offset(ptr_size * (idx as u64 + 3), self)?,
- )?.to_ptr()?;
+ let vtable = receiver_place.vtable();
+ let vtable_slot = vtable.ptr_offset(ptr_size * (idx as u64 + 3), self)?;
+ let vtable_slot = self.memory.check_ptr_access(
+ vtable_slot,
+ ptr_size,
+ self.tcx.data_layout.pointer_align.abi,
+ )?.expect("cannot be a ZST");
+ let fn_ptr = self.memory.get(vtable_slot.alloc_id)?
+ .read_ptr_sized(self, vtable_slot)?.to_ptr()?;
let instance = self.memory.get_fn(fn_ptr)?;
// `*mut receiver_place.layout.ty` is almost the layout that we