@@ -66,8 +66,14 @@ struct Search<'mir, 'tcx> {
66
66
67
67
impl < ' mir , ' tcx > Search < ' mir , ' tcx > {
68
68
/// Returns `true` if `func` refers to the function we are searching in.
69
- fn is_recursive_call ( & self , func : & Operand < ' tcx > ) -> bool {
69
+ fn is_recursive_call ( & self , func : & Operand < ' tcx > , args : & [ Operand < ' tcx > ] ) -> bool {
70
70
let Search { tcx, body, trait_substs, .. } = * self ;
71
+ // Resolving function type to a specific instance that is being called is expensive. To
72
+ // avoid the cost we check the number of arguments first, which is sufficient to reject
73
+ // most of calls as non-recursive.
74
+ if args. len ( ) != body. arg_count {
75
+ return false ;
76
+ }
71
77
let caller = body. source . def_id ( ) ;
72
78
let param_env = tcx. param_env ( caller) ;
73
79
@@ -141,8 +147,8 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> {
141
147
fn node_settled ( & mut self , bb : BasicBlock ) -> ControlFlow < Self :: BreakVal > {
142
148
// When we examine a node for the last time, remember it if it is a recursive call.
143
149
let terminator = self . body [ bb] . terminator ( ) ;
144
- if let TerminatorKind :: Call { func, .. } = & terminator. kind {
145
- if self . is_recursive_call ( func) {
150
+ if let TerminatorKind :: Call { func, args , .. } = & terminator. kind {
151
+ if self . is_recursive_call ( func, args ) {
146
152
self . reachable_recursive_calls . push ( terminator. source_info . span ) ;
147
153
}
148
154
}
@@ -157,7 +163,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> {
157
163
}
158
164
// Don't traverse successors of recursive calls or false CFG edges.
159
165
match self . body [ bb] . terminator ( ) . kind {
160
- TerminatorKind :: Call { ref func, .. } => self . is_recursive_call ( func) ,
166
+ TerminatorKind :: Call { ref func, ref args , .. } => self . is_recursive_call ( func, args ) ,
161
167
TerminatorKind :: FalseEdge { imaginary_target, .. } => imaginary_target == target,
162
168
_ => false ,
163
169
}
0 commit comments