1 //! This pass replaces a drop of a type that does not need dropping, with a goto
3 use crate::transform::MirPass;
4 use rustc_middle::mir::*;
5 use rustc_middle::ty::TyCtxt;
7 use super::simplify::simplify_cfg;
9 pub struct RemoveUnneededDrops;
11 impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
12 fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
13 trace!("Running RemoveUnneededDrops on {:?}", body.source);
15 let did = body.source.def_id();
16 let param_env = tcx.param_env(did);
17 let mut should_simplify = false;
19 let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
20 for block in basic_blocks {
21 let terminator = block.terminator_mut();
22 if let TerminatorKind::Drop { place, target, .. } = terminator.kind {
23 let ty = place.ty(local_decls, tcx);
24 if ty.ty.needs_drop(tcx, param_env) {
27 if !tcx.consider_optimizing(|| format!("RemoveUnneededDrops {:?} ", did)) {
30 debug!("SUCCESS: replacing `drop` with goto({:?})", target);
31 terminator.kind = TerminatorKind::Goto { target };
32 should_simplify = true;
36 // if we applied optimizations, we potentially have some cfg to cleanup to
37 // make it easier for further passes