]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_mir/interpret/terminator.rs
Rollup merge of #62096 - spastorino:impl-place-from, r=oli-obk,Centril
[rust.git] / src / librustc_mir / interpret / terminator.rs
index 452aa75e3b3dedc30eba5d7e007a8c66dd454924..13baf245d10fbeb865097e86e39419978a0823e3 100644 (file)
@@ -11,7 +11,7 @@
     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 {
@@ -79,7 +79,7 @@ pub(super) fn eval_terminator(
                 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)
                     }
@@ -281,15 +281,15 @@ fn eval_fn_call(
                 }
 
                 // 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),
                 )?;
@@ -307,8 +307,8 @@ fn eval_fn_call(
                     );
                     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)
                             )
@@ -352,12 +352,12 @@ fn eval_fn_call(
                     // 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)?;
@@ -388,12 +388,10 @@ fn eval_fn_call(
                             ));
                         }
                     } 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(())
@@ -425,12 +423,15 @@ fn eval_fn_call(
                     }
                 };
                 // 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