Skip to content

Commit 1f656fa

Browse files
committed
Recursive solver: Exit early on ambiguity
If we have an ambiguous solution while going through program clauses, it's not going to become less ambiguous, so there's no use in continuing to go through everything. This gives a 10-20% speedup in rust-analyzer analysis.
1 parent 27a9850 commit 1f656fa

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

chalk-solve/src/recursive.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,11 @@ impl<'me, I: Interner> Solver<'me, I> {
362362
for program_clause in clauses {
363363
debug_heading!("clause={:?}", program_clause);
364364

365+
// If we have a completely ambiguous answer, it's not going to get better, so stop
366+
if cur_solution == Some((Solution::Ambig(Guidance::Unknown), ClausePriority::High)) {
367+
return (Ok(Solution::Ambig(Guidance::Unknown)), ClausePriority::High);
368+
}
369+
365370
match program_clause.data(self.program.interner()) {
366371
ProgramClauseData::Implies(implication) => {
367372
let res = self.solve_via_implication(
@@ -515,6 +520,12 @@ fn combine_with_priorities<I: Interner>(
515520
match (prio_a, prio_b, a, b) {
516521
(ClausePriority::High, ClausePriority::Low, higher, lower)
517522
| (ClausePriority::Low, ClausePriority::High, lower, higher) => {
523+
// if we have a high-priority solution and a low-priority solution,
524+
// the high-priority solution overrides *if* they are both for the
525+
// same inputs -- we don't want a more specific high-priority
526+
// solution overriding a general low-priority one. Currently inputs
527+
// only matter for projections; in a goal like `AliasEq(<?0 as
528+
// Trait>::Type = ?1)`, ?0 is the input.
518529
let inputs_higher = calculate_inputs(interner, domain_goal, &higher);
519530
let inputs_lower = calculate_inputs(interner, domain_goal, &lower);
520531
if inputs_higher == inputs_lower {

0 commit comments

Comments
 (0)