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
::visit
::Visitor
;
5 use rustc_middle
::mir
::*;
6 use rustc_middle
::ty
::{ParamEnv, TyCtxt}
;
8 use super::simplify
::simplify_cfg
;
10 pub struct RemoveUnneededDrops
;
12 impl<'tcx
> MirPass
<'tcx
> for RemoveUnneededDrops
{
13 fn run_pass(&self, tcx
: TyCtxt
<'tcx
>, body
: &mut Body
<'tcx
>) {
14 trace
!("Running RemoveUnneededDrops on {:?}", body
.source
);
15 let mut opt_finder
= RemoveUnneededDropsOptimizationFinder
{
18 param_env
: tcx
.param_env(body
.source
.def_id()),
19 optimizations
: vec
![],
21 opt_finder
.visit_body(body
);
22 let should_simplify
= !opt_finder
.optimizations
.is_empty();
23 for (loc
, target
) in opt_finder
.optimizations
{
25 .consider_optimizing(|| format
!("RemoveUnneededDrops {:?} ", body
.source
.def_id()))
30 let terminator
= body
.basic_blocks_mut()[loc
.block
].terminator_mut();
31 debug
!("SUCCESS: replacing `drop` with goto({:?})", target
);
32 terminator
.kind
= TerminatorKind
::Goto { target }
;
35 // if we applied optimizations, we potentially have some cfg to cleanup to
36 // make it easier for further passes
43 impl<'a
, 'tcx
> Visitor
<'tcx
> for RemoveUnneededDropsOptimizationFinder
<'a
, 'tcx
> {
44 fn visit_terminator(&mut self, terminator
: &Terminator
<'tcx
>, location
: Location
) {
45 match terminator
.kind
{
46 TerminatorKind
::Drop { place, target, .. }
=> {
47 let ty
= place
.ty(self.body
, self.tcx
);
48 let needs_drop
= ty
.ty
.needs_drop(self.tcx
, self.param_env
);
50 self.optimizations
.push((location
, target
));
55 self.super_terminator(terminator
, location
);
58 pub struct RemoveUnneededDropsOptimizationFinder
<'a
, 'tcx
> {
61 optimizations
: Vec
<(Location
, BasicBlock
)>,
62 param_env
: ParamEnv
<'tcx
>,