1
1
use rustc_middle:: mir:: visit:: * ;
2
2
use rustc_middle:: mir:: * ;
3
- use rustc_middle:: ty:: { self , ParamEnv , TyCtxt } ;
3
+ use rustc_middle:: ty:: { self , ParamEnv , Ty , TyCtxt } ;
4
4
5
5
const INSTR_COST : usize = 5 ;
6
6
const CALL_PENALTY : usize = 25 ;
@@ -14,14 +14,14 @@ pub(crate) struct CostChecker<'b, 'tcx> {
14
14
param_env : ParamEnv < ' tcx > ,
15
15
cost : usize ,
16
16
callee_body : & ' b Body < ' tcx > ,
17
- instance : ty:: Instance < ' tcx > ,
17
+ instance : Option < ty:: Instance < ' tcx > > ,
18
18
}
19
19
20
20
impl < ' b , ' tcx > CostChecker < ' b , ' tcx > {
21
21
pub fn new (
22
22
tcx : TyCtxt < ' tcx > ,
23
23
param_env : ParamEnv < ' tcx > ,
24
- instance : ty:: Instance < ' tcx > ,
24
+ instance : Option < ty:: Instance < ' tcx > > ,
25
25
callee_body : & ' b Body < ' tcx > ,
26
26
) -> CostChecker < ' b , ' tcx > {
27
27
CostChecker { tcx, param_env, callee_body, instance, cost : 0 }
@@ -30,6 +30,14 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> {
30
30
pub fn cost ( & self ) -> usize {
31
31
self . cost
32
32
}
33
+
34
+ fn instantiate_ty ( & self , v : Ty < ' tcx > ) -> Ty < ' tcx > {
35
+ if let Some ( instance) = self . instance {
36
+ instance. instantiate_mir ( self . tcx , ty:: EarlyBinder :: bind ( & v) )
37
+ } else {
38
+ v
39
+ }
40
+ }
33
41
}
34
42
35
43
impl < ' tcx > Visitor < ' tcx > for CostChecker < ' _ , ' tcx > {
@@ -49,10 +57,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
49
57
match terminator. kind {
50
58
TerminatorKind :: Drop { ref place, unwind, .. } => {
51
59
// If the place doesn't actually need dropping, treat it like a regular goto.
52
- let ty = self . instance . instantiate_mir (
53
- tcx,
54
- ty:: EarlyBinder :: bind ( & place. ty ( self . callee_body , tcx) . ty ) ,
55
- ) ;
60
+ let ty = self . instantiate_ty ( place. ty ( self . callee_body , tcx) . ty ) ;
56
61
if ty. needs_drop ( tcx, self . param_env ) {
57
62
self . cost += CALL_PENALTY ;
58
63
if let UnwindAction :: Cleanup ( _) = unwind {
@@ -63,8 +68,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
63
68
}
64
69
}
65
70
TerminatorKind :: Call { func : Operand :: Constant ( ref f) , unwind, .. } => {
66
- let fn_ty =
67
- self . instance . instantiate_mir ( tcx, ty:: EarlyBinder :: bind ( & f. const_ . ty ( ) ) ) ;
71
+ let fn_ty = self . instantiate_ty ( f. const_ . ty ( ) ) ;
68
72
self . cost += if let ty:: FnDef ( def_id, _) = * fn_ty. kind ( ) && tcx. is_intrinsic ( def_id) {
69
73
// Don't give intrinsics the extra penalty for calls
70
74
INSTR_COST
0 commit comments