]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_mir_transform/src/remove_unneeded_drops.rs
Merge commit '3c7e7dbc1583a0b06df5bd7623dd354a4debd23d' into clippyup
[rust.git] / compiler / rustc_mir_transform / src / remove_unneeded_drops.rs
1 //! This pass replaces a drop of a type that does not need dropping, with a goto.
2 //!
3 //! When the MIR is built, we check `needs_drop` before emitting a `Drop` for a place. This pass is
4 //! useful because (unlike MIR building) it runs after type checking, so it can make use of
5 //! `Reveal::All` to provide more precise type information.
6
7 use crate::MirPass;
8 use rustc_middle::mir::*;
9 use rustc_middle::ty::TyCtxt;
10
11 use super::simplify::simplify_cfg;
12
13 pub struct RemoveUnneededDrops;
14
15 impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
16     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
17         trace!("Running RemoveUnneededDrops on {:?}", body.source);
18
19         let did = body.source.def_id();
20         let param_env = tcx.param_env_reveal_all_normalized(did);
21         let mut should_simplify = false;
22
23         for block in body.basic_blocks.as_mut() {
24             let terminator = block.terminator_mut();
25             if let TerminatorKind::Drop { place, target, .. } = terminator.kind {
26                 let ty = place.ty(&body.local_decls, tcx);
27                 if ty.ty.needs_drop(tcx, param_env) {
28                     continue;
29                 }
30                 if !tcx.consider_optimizing(|| format!("RemoveUnneededDrops {:?} ", did)) {
31                     continue;
32                 }
33                 debug!("SUCCESS: replacing `drop` with goto({:?})", target);
34                 terminator.kind = TerminatorKind::Goto { target };
35                 should_simplify = true;
36             }
37         }
38
39         // if we applied optimizations, we potentially have some cfg to cleanup to
40         // make it easier for further passes
41         if should_simplify {
42             simplify_cfg(tcx, body);
43         }
44     }
45 }