Skip to content

Commit 745e926

Browse files
committed
Auto merge of #93381 - tmiasko:is-self-recursive, r=ecstatic-morse
Check the number of arguments first in `is_recursive_call`
2 parents 498eeb7 + 35b5daa commit 745e926

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

compiler/rustc_mir_build/src/lints.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,14 @@ struct Search<'mir, 'tcx> {
6666

6767
impl<'mir, 'tcx> Search<'mir, 'tcx> {
6868
/// 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 {
7070
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+
}
7177
let caller = body.source.def_id();
7278
let param_env = tcx.param_env(caller);
7379

@@ -141,8 +147,8 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> {
141147
fn node_settled(&mut self, bb: BasicBlock) -> ControlFlow<Self::BreakVal> {
142148
// When we examine a node for the last time, remember it if it is a recursive call.
143149
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) {
146152
self.reachable_recursive_calls.push(terminator.source_info.span);
147153
}
148154
}
@@ -157,7 +163,7 @@ impl<'mir, 'tcx> TriColorVisitor<&'mir Body<'tcx>> for Search<'mir, 'tcx> {
157163
}
158164
// Don't traverse successors of recursive calls or false CFG edges.
159165
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),
161167
TerminatorKind::FalseEdge { imaginary_target, .. } => imaginary_target == target,
162168
_ => false,
163169
}

0 commit comments

Comments
 (0)