diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index be5458523d1ca..26e429034dca6 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -540,7 +540,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // \-------/ // let virtual_drop = Instance { - def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), + def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), // idx 0: the drop function args: drop_fn.args, }; debug!("ty = {:?}", ty); @@ -581,7 +581,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // // SO THEN WE CAN USE THE ABOVE CODE. let virtual_drop = Instance { - def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), + def: ty::InstanceDef::Virtual(drop_fn.def_id(), 0), // idx 0: the drop function args: drop_fn.args, }; debug!("ty = {:?}", ty); diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 07425f9a6865c..b474003087ba3 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -169,10 +169,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } Drop { place, target, unwind, replace: _ } => { - let frame = self.frame(); - let ty = place.ty(&frame.body.local_decls, *self.tcx).ty; - let ty = self.instantiate_from_frame_and_normalize_erasing_regions(frame, ty)?; - let instance = Instance::resolve_drop_in_place(*self.tcx, ty); + let place = self.eval_place(place)?; + let instance = Instance::resolve_drop_in_place(*self.tcx, place.layout.ty); if let ty::InstanceDef::DropGlue(_, None) = instance.def { // This is the branch we enter if and only if the dropped type has no drop glue // whatsoever. This can happen as a result of monomorphizing a drop of a @@ -181,8 +179,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.go_to_block(target); return Ok(()); } - let place = self.eval_place(place)?; - trace!("TerminatorKind::drop: {:?}, type {}", place, ty); + trace!("TerminatorKind::drop: {:?}, type {}", place, place.layout.ty); self.drop_in_place(&place, instance, target, unwind)?; } @@ -952,6 +949,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // implementation fail -- a problem shared by rustc. let place = self.force_allocation(place)?; + // We behave a bit different from codegen here. + // Codegen creates an `InstanceDef::Virtual` with index 0 (the slot of the drop method) and + // then dispatches that to the normal call machinery. However, our call machinery currently + // only supports calling `VtblEntry::Method`; it would choke on a `MetadataDropInPlace`. So + // instead we do the virtual call stuff ourselves. It's easier here than in `eval_fn_call` + // since we can just get a place of the underlying type and use `mplace_to_ref`. let place = match place.layout.ty.kind() { ty::Dynamic(data, _, ty::Dyn) => { // Dropping a trait object. Need to find actual drop fn.