diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs index 2dd805ccf9b5..b81bb5c81ca1 100644 --- a/src/librustc_mir/transform/inline.rs +++ b/src/librustc_mir/transform/inline.rs @@ -379,8 +379,6 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { TerminatorKind::Call { args, destination: Some(destination), cleanup, .. } => { debug!("Inlined {:?} into {:?}", callsite.callee, self.source); - let is_box_free = Some(callsite.callee) == self.tcx.lang_items().box_free_fn(); - let mut local_map = IndexVec::with_capacity(callee_mir.local_decls.len()); let mut scope_map = IndexVec::with_capacity(callee_mir.visibility_scopes.len()); let mut promoted_map = IndexVec::with_capacity(callee_mir.promoted.len()); @@ -460,24 +458,8 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { let return_block = destination.1; - let args : Vec<_> = if is_box_free { - assert!(args.len() == 1); - // box_free takes a Box, but is defined with a *mut T, inlining - // needs to generate the cast. - // FIXME: we should probably just generate correct MIR in the first place... - - let arg = if let Operand::Move(ref place) = args[0] { - place.clone() - } else { - bug!("Constant arg to \"box_free\""); - }; - - let ptr_ty = args[0].ty(caller_mir, self.tcx); - vec![self.cast_box_free_arg(arg, ptr_ty, &callsite, caller_mir)] - } else { - // Copy the arguments if needed. - self.make_call_args(args, &callsite, caller_mir) - }; + // Copy the arguments if needed. + let args: Vec<_> = self.make_call_args(args, &callsite, caller_mir); let bb_len = caller_mir.basic_blocks().len(); let mut integrator = Integrator { @@ -518,49 +500,6 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> { } } - fn cast_box_free_arg(&self, arg: Place<'tcx>, ptr_ty: Ty<'tcx>, - callsite: &CallSite<'tcx>, caller_mir: &mut Mir<'tcx>) -> Local { - let arg = Rvalue::Ref( - self.tcx.types.re_erased, - BorrowKind::Mut { allow_two_phase_borrow: false }, - arg.deref()); - - let ty = arg.ty(caller_mir, self.tcx); - let ref_tmp = LocalDecl::new_temp(ty, callsite.location.span); - let ref_tmp = caller_mir.local_decls.push(ref_tmp); - let ref_tmp = Place::Local(ref_tmp); - - let ref_stmt = Statement { - source_info: callsite.location, - kind: StatementKind::Assign(ref_tmp.clone(), arg) - }; - - caller_mir[callsite.bb] - .statements.push(ref_stmt); - - let pointee_ty = match ptr_ty.sty { - ty::TyRawPtr(tm) | ty::TyRef(_, tm) => tm.ty, - _ if ptr_ty.is_box() => ptr_ty.boxed_ty(), - _ => bug!("Invalid type `{:?}` for call to box_free", ptr_ty) - }; - let ptr_ty = self.tcx.mk_mut_ptr(pointee_ty); - - let raw_ptr = Rvalue::Cast(CastKind::Misc, Operand::Move(ref_tmp), ptr_ty); - - let cast_tmp = LocalDecl::new_temp(ptr_ty, callsite.location.span); - let cast_tmp = caller_mir.local_decls.push(cast_tmp); - - let cast_stmt = Statement { - source_info: callsite.location, - kind: StatementKind::Assign(Place::Local(cast_tmp), raw_ptr) - }; - - caller_mir[callsite.bb] - .statements.push(cast_stmt); - - cast_tmp - } - fn make_call_args( &self, args: Vec>, diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 19f33ef5d45a..1564db1ee2a5 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -876,14 +876,39 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> let unit_temp = Place::Local(self.new_temp(tcx.mk_nil())); let free_func = tcx.require_lang_item(lang_items::BoxFreeFnLangItem); let substs = tcx.mk_substs(iter::once(Kind::from(ty))); + let ref_ty = tcx.mk_ref(tcx.types.re_erased, ty::TypeAndMut { + ty: ty, + mutbl: hir::Mutability::MutMutable + }); + let ptr_ty = tcx.mk_mut_ptr(ty); + let ref_tmp = Place::Local(self.new_temp(ref_ty)); + let ptr_tmp = Place::Local(self.new_temp(ptr_ty)); - let call = TerminatorKind::Call { - func: Operand::function_handle(tcx, free_func, substs, self.source_info.span), - args: vec![Operand::Move(self.place.clone())], - destination: Some((unit_temp, target)), - cleanup: None - }; // FIXME(#43234) - let free_block = self.new_block(unwind, call); + let free_block = BasicBlockData { + statements: vec![ + self.assign(&ref_tmp, Rvalue::Ref( + tcx.types.re_erased, + BorrowKind::Mut { allow_two_phase_borrow: false }, + self.place.clone().deref() + )), + self.assign(&ptr_tmp, Rvalue::Cast( + CastKind::Misc, + Operand::Move(ref_tmp), + ptr_ty, + )), + ], + terminator: Some(Terminator { + kind: TerminatorKind::Call { + func: Operand::function_handle(tcx, free_func, substs, self.source_info.span), + args: vec![Operand::Move(ptr_tmp)], + destination: Some((unit_temp, target)), + cleanup: None + }, // FIXME(#43234) + source_info: self.source_info, + }), + is_cleanup: unwind.is_cleanup() + }; + let free_block = self.elaborator.patch().new_block(free_block); let block_start = Location { block: free_block, statement_index: 0 }; self.elaborator.clear_drop_flag(block_start, self.path, DropFlagMode::Shallow);