@@ -18,7 +18,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
18
18
use rustc:: mir:: * ;
19
19
use rustc:: mir:: transform:: { MirPass , MirSource } ;
20
20
use rustc:: mir:: visit:: * ;
21
- use rustc:: ty:: { self , Ty , TyCtxt , Instance } ;
21
+ use rustc:: ty:: { self , Instance , Ty , TyCtxt , TypeFoldable } ;
22
22
use rustc:: ty:: subst:: { Subst , Substs } ;
23
23
24
24
use std:: collections:: VecDeque ;
@@ -77,8 +77,13 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
77
77
78
78
let mut callsites = VecDeque :: new ( ) ;
79
79
80
+ let param_env;
81
+
80
82
// Only do inlining into fn bodies.
81
83
if let MirSource :: Fn ( caller_id) = self . source {
84
+ let caller_def_id = self . tcx . hir . local_def_id ( caller_id) ;
85
+ param_env = self . tcx . param_env ( caller_def_id) ;
86
+
82
87
for ( bb, bb_data) in caller_mir. basic_blocks ( ) . iter_enumerated ( ) {
83
88
// Don't inline calls that are in cleanup blocks.
84
89
if bb_data. is_cleanup { continue ; }
@@ -88,9 +93,6 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
88
93
if let TerminatorKind :: Call {
89
94
func : Operand :: Constant ( ref f) , .. } = terminator. kind {
90
95
if let ty:: TyFnDef ( callee_def_id, substs) = f. ty . sty {
91
- let caller_def_id = self . tcx . hir . local_def_id ( caller_id) ;
92
- let param_env = self . tcx . param_env ( caller_def_id) ;
93
-
94
96
if let Some ( instance) = Instance :: resolve ( self . tcx ,
95
97
param_env,
96
98
callee_def_id,
@@ -105,6 +107,8 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
105
107
}
106
108
}
107
109
}
110
+ } else {
111
+ return ;
108
112
}
109
113
110
114
let mut local_change;
@@ -123,7 +127,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
123
127
callsite. location . span ,
124
128
callsite. callee ) {
125
129
Ok ( ref callee_mir) if self . should_inline ( callsite, callee_mir) => {
126
- callee_mir . subst ( self . tcx , callsite. substs )
130
+ subst_and_normalize ( callee_mir , self . tcx , & callsite. substs , param_env )
127
131
}
128
132
Ok ( _) => continue ,
129
133
@@ -587,6 +591,30 @@ fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
587
591
} )
588
592
}
589
593
594
+ fn subst_and_normalize < ' a , ' tcx : ' a > (
595
+ mir : & Mir < ' tcx > ,
596
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
597
+ substs : & ' tcx ty:: subst:: Substs < ' tcx > ,
598
+ param_env : ty:: ParamEnv < ' tcx > ,
599
+ ) -> Mir < ' tcx > {
600
+ struct Folder < ' a , ' tcx : ' a > {
601
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
602
+ param_env : ty:: ParamEnv < ' tcx > ,
603
+ substs : & ' tcx ty:: subst:: Substs < ' tcx > ,
604
+ }
605
+ impl < ' a , ' tcx : ' a > ty:: fold:: TypeFolder < ' tcx , ' tcx > for Folder < ' a , ' tcx > {
606
+ fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' tcx , ' tcx > {
607
+ self . tcx
608
+ }
609
+
610
+ fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
611
+ self . tcx . trans_apply_param_substs_env ( & self . substs , self . param_env , & t)
612
+ }
613
+ }
614
+ let mut f = Folder { tcx, param_env, substs } ;
615
+ mir. fold_with ( & mut f)
616
+ }
617
+
590
618
/**
591
619
* Integrator.
592
620
*
0 commit comments