rustc_mir_transform/
remove_unneeded_drops.rs1use rustc_hir::LangItem;
14use rustc_middle::mir::*;
15use rustc_middle::ty::TyCtxt;
16use tracing::{debug, trace};
17
18use super::simplify::simplify_cfg;
19
20pub(super) struct RemoveUnneededDrops;
21
22impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops {
23 fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
24 trace!("Running RemoveUnneededDrops on {:?}", body.source);
25
26 let typing_env = body.typing_env(tcx);
27 let mut should_simplify = false;
28 for block in body.basic_blocks.as_mut() {
29 let terminator = block.terminator_mut();
30 let (ty, target) = match terminator.kind {
31 TerminatorKind::Drop { place, target, .. } => {
32 (place.ty(&body.local_decls, tcx).ty, target)
33 }
34 TerminatorKind::Call { ref func, target: Some(target), .. }
35 if tcx.sess.mir_opt_level() > 0
36 && let Some((def_id, generics)) = func.const_fn_def()
37 && tcx.is_lang_item(def_id, LangItem::DropInPlace) =>
38 {
39 (generics.type_at(0), target)
40 }
41 _ => continue,
42 };
43
44 if ty.needs_drop(tcx, typing_env) {
45 continue;
46 }
47 debug!("SUCCESS: replacing `drop` with goto({:?})", target);
48 terminator.kind = TerminatorKind::Goto { target };
49 should_simplify = true;
50 }
51
52 if should_simplify {
55 simplify_cfg(tcx, body);
56 }
57 }
58
59 fn is_required(&self) -> bool {
60 true
61 }
62}