4
4
//! useful because (unlike MIR building) it runs after type checking, so it can make use of
5
5
//! `TypingMode::PostAnalysis` to provide more precise type information, especially about opaque
6
6
//! types.
7
+ //!
8
+ //! When we're optimizing, we also remove calls to `drop_in_place<T>` when `T` isn't `needs_drop`,
9
+ //! as those are essentially equivalent to `Drop` terminators. While the compiler doesn't insert
10
+ //! them automatically, preferring the built-in instead, they're common in generic code (such as
11
+ //! `Vec::truncate`) so removing them from things like inlined `Vec<u8>` is helpful.
7
12
13
+ use rustc_hir:: LangItem ;
8
14
use rustc_middle:: mir:: * ;
9
15
use rustc_middle:: ty:: TyCtxt ;
10
16
use tracing:: { debug, trace} ;
@@ -21,15 +27,26 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops {
21
27
let mut should_simplify = false ;
22
28
for block in body. basic_blocks . as_mut ( ) {
23
29
let terminator = block. terminator_mut ( ) ;
24
- if let TerminatorKind :: Drop { place, target, .. } = terminator. kind {
25
- let ty = place. ty ( & body. local_decls , tcx) ;
26
- if ty. ty . needs_drop ( tcx, typing_env) {
27
- continue ;
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)
28
40
}
29
- debug ! ( "SUCCESS: replacing `drop` with goto({:?})" , target) ;
30
- terminator. kind = TerminatorKind :: Goto { target } ;
31
- should_simplify = true ;
41
+ _ => continue ,
42
+ } ;
43
+
44
+ if ty. needs_drop ( tcx, typing_env) {
45
+ continue ;
32
46
}
47
+ debug ! ( "SUCCESS: replacing `drop` with goto({:?})" , target) ;
48
+ terminator. kind = TerminatorKind :: Goto { target } ;
49
+ should_simplify = true ;
33
50
}
34
51
35
52
// if we applied optimizations, we potentially have some cfg to cleanup to
0 commit comments