diff options
| author | Ralf Jung <post@ralfj.de> | 2018-08-15 22:39:39 +0200 |
|---|---|---|
| committer | Ralf Jung <post@ralfj.de> | 2018-08-22 09:06:28 +0200 |
| commit | 09b15e9856c3ef77992cc30e772d29a896597041 (patch) | |
| tree | 7ef6946875e4c43a7b483f5708563ba46e9f5a05 | |
| parent | e860ab2dabc281b8d882387fd62e78a6c072e6dc (diff) | |
| download | rust-09b15e9856c3ef77992cc30e772d29a896597041.tar.gz rust-09b15e9856c3ef77992cc30e772d29a896597041.zip | |
fix dropping with vtables
| -rw-r--r-- | src/librustc_mir/interpret/terminator/drop.rs | 17 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/terminator/mod.rs | 3 |
2 files changed, 14 insertions, 6 deletions
diff --git a/src/librustc_mir/interpret/terminator/drop.rs b/src/librustc_mir/interpret/terminator/drop.rs index 98ffacf6b4a..11fd7373284 100644 --- a/src/librustc_mir/interpret/terminator/drop.rs +++ b/src/librustc_mir/interpret/terminator/drop.rs @@ -30,24 +30,29 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { ) -> EvalResult<'tcx> { trace!("drop: {:?},\n {:?}, {:?}", arg, ty.sty, instance.def); - let instance = match ty.sty { + let (instance, arg) = match ty.sty { ty::TyDynamic(..) => { - if let Value::ScalarPair(_, vtable) = arg { - self.read_drop_type_from_vtable(vtable.to_ptr()?)? + if let Value::ScalarPair(ptr, vtable) = arg { + // Figure out the specific drop function to call, and just pass along + // the thin part of the pointer. + let instance = self.read_drop_type_from_vtable(vtable.to_ptr()?)?; + trace!("Dropping via vtable: {:?}", instance.def); + (instance, Value::Scalar(ptr)) } else { bug!("expected fat ptr, got {:?}", arg); } } - _ => instance, + _ => (instance, arg), }; // the drop function expects a reference to the value + let fn_sig = self.tcx.fn_sig(instance.def_id()).skip_binder().clone(); let arg = OpTy { op: Operand::Immediate(arg), - layout: self.layout_of(self.tcx.mk_mut_ptr(ty))?, + layout: self.layout_of(fn_sig.output())?, }; + trace!("Dropped type: {:?}", fn_sig.output()); - let fn_sig = self.tcx.fn_sig(instance.def_id()).skip_binder().clone(); // This should always be (), but getting it from the sig seems // easier than creating a layout of (). let dest = PlaceTy::null(&self, self.layout_of(fn_sig.output())?); diff --git a/src/librustc_mir/interpret/terminator/mod.rs b/src/librustc_mir/interpret/terminator/mod.rs index c947a843463..e0980a4657e 100644 --- a/src/librustc_mir/interpret/terminator/mod.rs +++ b/src/librustc_mir/interpret/terminator/mod.rs @@ -257,6 +257,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> { sig: ty::FnSig<'tcx>, ) -> EvalResult<'tcx> { trace!("eval_fn_call: {:#?}", instance); + if let Some((place, _)) = destination { + assert_eq!(place.layout.ty, sig.output()); + } match instance.def { ty::InstanceDef::Intrinsic(..) => { let (ret, target) = match destination { |
