Skip to content

Commit 6cf11b3

Browse files
committed
[CSStep/TypeVar] Check if loop should be stopped even if current binding has failed
Eagerly check if optimal solution has already been found even if current binding attempt has failed, because otherwise it might check too many bindings which would result in ambiguity.
1 parent 2eb0e82 commit 6cf11b3

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

lib/Sema/CSStep.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,11 @@ StepResult TypeVariableStep::take(bool prevFailed) {
394394
// let's try to see if it leads to any solutions.
395395
return suspend(SplitterStep::create(CS, Solutions));
396396
}
397+
398+
// If this binding didn't match, let's check
399+
// if we've checked enough bindings to stop.
400+
if (shouldStop())
401+
break;
397402
}
398403
}
399404

@@ -417,12 +422,10 @@ StepResult TypeVariableStep::resume(bool prevFailed) {
417422
log.indent(CS.solverState->depth * 2) << ")\n";
418423
}
419424

420-
// If there has been at least one solution so far
421-
// at a current batch of bindings is done it's a
422-
// success because each new batch would be less
423-
// and less precise.
424-
if (AnySolved && Producer.needsToComputeNext())
425-
return done(/*isSuccess=*/true);
425+
// Let's check if we should stop right before
426+
// attempting any new bindings.
427+
if (shouldStop())
428+
return done(/*isSuccess=*/AnySolved);
426429

427430
// Attempt next type variable binding.
428431
return take(prevFailed);

lib/Sema/CSStep.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,17 @@ class TypeVariableStep final : public SolverStep {
424424
SmallVectorImpl<Solution> &solutions) {
425425
return new TypeVariableStep(cs, bindings, solutions);
426426
}
427+
428+
private:
429+
/// Check whether attempting type variable binding choices should
430+
/// be stopped, because optimal solution has already been found.
431+
bool shouldStop() const {
432+
// If there has been at least one solution so far
433+
// at a current batch of bindings is done it's a
434+
// success because each new batch would be less
435+
// and less precise.
436+
return AnySolved && Producer.needsToComputeNext();
437+
}
427438
};
428439

429440
class DisjunctionStep final : public SolverStep {

0 commit comments

Comments
 (0)