@@ -2480,8 +2480,9 @@ bool ConstraintSystem::solveSimplified(
2480
2480
auto afterDisjunction = InactiveConstraints.erase (disjunction);
2481
2481
CG.removeConstraint (disjunction);
2482
2482
2483
+ Score initialScore = CurrentScore;
2483
2484
Optional<DisjunctionChoice> lastSolvedChoice;
2484
- Optional<DisjunctionChoice> firstNonGenericOperatorSolution ;
2485
+ Optional<Score> bestNonGenericScore ;
2485
2486
2486
2487
++solverState->NumDisjunctions ;
2487
2488
auto constraints = disjunction->getNestedConstraints ();
@@ -2507,9 +2508,13 @@ bool ConstraintSystem::solveSimplified(
2507
2508
// already have a solution involving non-generic operators,
2508
2509
// but continue looking for a better non-generic operator
2509
2510
// solution.
2510
- if (firstNonGenericOperatorSolution &&
2511
- currentChoice.isGenericOperatorOrUnavailable ())
2512
- continue ;
2511
+ if (bestNonGenericScore && currentChoice.isGenericOperatorOrUnavailable ()) {
2512
+ // If non-generic solution increased the score by applying any
2513
+ // fixes or restrictions to the solution, let's not skip generic
2514
+ // overloads because they could produce a better solution.
2515
+ if (bestNonGenericScore <= initialScore)
2516
+ continue ;
2517
+ }
2513
2518
2514
2519
// We already have a solution; check whether we should
2515
2520
// short-circuit the disjunction.
@@ -2542,11 +2547,12 @@ bool ConstraintSystem::solveSimplified(
2542
2547
DisjunctionChoices.push_back ({locator, index});
2543
2548
}
2544
2549
2545
- if (currentChoice.solve (solutions, allowFreeTypeVariables)) {
2546
- if (!firstNonGenericOperatorSolution &&
2547
- !currentChoice.isGenericOperatorOrUnavailable () &&
2548
- currentChoice.isSymmetricOperator ())
2549
- firstNonGenericOperatorSolution = currentChoice;
2550
+ if (auto score = currentChoice.solve (solutions, allowFreeTypeVariables)) {
2551
+ if (!currentChoice.isGenericOperatorOrUnavailable () &&
2552
+ currentChoice.isSymmetricOperator ()) {
2553
+ if (!bestNonGenericScore || score < bestNonGenericScore)
2554
+ bestNonGenericScore = score;
2555
+ }
2550
2556
2551
2557
lastSolvedChoice = currentChoice;
2552
2558
@@ -2578,10 +2584,12 @@ bool ConstraintSystem::solveSimplified(
2578
2584
return tooComplex || !lastSolvedChoice;
2579
2585
}
2580
2586
2581
- bool DisjunctionChoice::solve (SmallVectorImpl<Solution> &solutions,
2582
- FreeTypeVariableBinding allowFreeTypeVariables) {
2587
+ Optional<Score>
2588
+ DisjunctionChoice::solve (SmallVectorImpl<Solution> &solutions,
2589
+ FreeTypeVariableBinding allowFreeTypeVariables) {
2583
2590
CS->simplifyDisjunctionChoice (Choice);
2584
- return !CS->solveRec (solutions, allowFreeTypeVariables);
2591
+ bool failed = CS->solveRec (solutions, allowFreeTypeVariables);
2592
+ return failed ? None : Optional<Score>(CS->CurrentScore );
2585
2593
}
2586
2594
2587
2595
bool DisjunctionChoice::isGenericOperatorOrUnavailable () const {
0 commit comments