@@ -2348,27 +2348,6 @@ static bool shortCircuitDisjunctionAt(Constraint *constraint,
2348
2348
if (constraint->getKind () == ConstraintKind::CheckedCast)
2349
2349
return true ;
2350
2350
2351
- // Binding an operator overloading to a generic operator is weaker than
2352
- // binding to a non-generic operator, always.
2353
- // FIXME: this is a hack to improve performance when we're dealing with
2354
- // overloaded operators.
2355
- if (constraint->getKind () == ConstraintKind::BindOverload &&
2356
- constraint->getOverloadChoice ().getKind () == OverloadChoiceKind::Decl &&
2357
- constraint->getOverloadChoice ().getDecl ()->isOperator () &&
2358
- successfulConstraint->getKind () == ConstraintKind::BindOverload &&
2359
- successfulConstraint->getOverloadChoice ().getKind ()
2360
- == OverloadChoiceKind::Decl &&
2361
- successfulConstraint->getOverloadChoice ().getDecl ()->isOperator ()) {
2362
- auto decl = constraint->getOverloadChoice ().getDecl ();
2363
- auto successfulDecl = successfulConstraint->getOverloadChoice ().getDecl ();
2364
- auto &ctx = decl->getASTContext ();
2365
- if (decl->getInterfaceType ()->is <GenericFunctionType>() &&
2366
- !successfulDecl->getInterfaceType ()->is <GenericFunctionType>() &&
2367
- (!successfulDecl->getAttrs ().isUnavailable (ctx) ||
2368
- decl->getAttrs ().isUnavailable (ctx)))
2369
- return true ;
2370
- }
2371
-
2372
2351
return false ;
2373
2352
}
2374
2353
@@ -2486,6 +2465,21 @@ static unsigned countUnboundTypes(ConstraintSystem &CS,
2486
2465
return count;
2487
2466
}
2488
2467
2468
+ // Is this constraint a bind overload to a generic operator or one
2469
+ // that is unavailable?
2470
+ static bool isGenericOperatorOrUnavailable (Constraint *constraint) {
2471
+ if (constraint->getKind () != ConstraintKind::BindOverload ||
2472
+ constraint->getOverloadChoice ().getKind () != OverloadChoiceKind::Decl ||
2473
+ !constraint->getOverloadChoice ().getDecl ()->isOperator ())
2474
+ return false ;
2475
+
2476
+ auto decl = constraint->getOverloadChoice ().getDecl ();
2477
+ auto &ctx = decl->getASTContext ();
2478
+
2479
+ return decl->getInterfaceType ()->is <GenericFunctionType>() ||
2480
+ decl->getAttrs ().isUnavailable (ctx);
2481
+ }
2482
+
2489
2483
bool ConstraintSystem::solveSimplified (
2490
2484
SmallVectorImpl<Solution> &solutions,
2491
2485
FreeTypeVariableBinding allowFreeTypeVariables) {
@@ -2620,6 +2614,7 @@ bool ConstraintSystem::solveSimplified(
2620
2614
2621
2615
// Try each of the constraints within the disjunction.
2622
2616
Constraint *firstSolvedConstraint = nullptr ;
2617
+ Constraint *firstNonGenericOperatorSolution = nullptr ;
2623
2618
++solverState->NumDisjunctions ;
2624
2619
auto constraints = disjunction->getNestedConstraints ();
2625
2620
for (auto index : indices (constraints)) {
@@ -2635,12 +2630,24 @@ bool ConstraintSystem::solveSimplified(
2635
2630
continue ;
2636
2631
}
2637
2632
2633
+ // Don't attempt to solve for generic operators if we already have
2634
+ // a non-generic solution.
2635
+
2636
+ // FIXME: Less-horrible but still horrible hack to attempt to
2637
+ // speed things up. Skip the generic operators if we
2638
+ // already have a solution involving non-generic operators,
2639
+ // but continue looking for a better non-generic operator
2640
+ // solution.
2641
+ if (firstNonGenericOperatorSolution &&
2642
+ isGenericOperatorOrUnavailable (constraint))
2643
+ continue ;
2644
+
2638
2645
// We already have a solution; check whether we should
2639
2646
// short-circuit the disjunction.
2640
2647
if (firstSolvedConstraint &&
2641
2648
shortCircuitDisjunctionAt (constraint, firstSolvedConstraint))
2642
2649
break ;
2643
-
2650
+
2644
2651
// If the expression was deemed "too complex", stop now and salvage.
2645
2652
if (getExpressionTooComplex (solutions))
2646
2653
break ;
@@ -2686,6 +2693,10 @@ bool ConstraintSystem::solveSimplified(
2686
2693
solverState->addGeneratedConstraint (constraint);
2687
2694
2688
2695
if (!solveRec (solutions, allowFreeTypeVariables)) {
2696
+ if (!firstNonGenericOperatorSolution &&
2697
+ !isGenericOperatorOrUnavailable (constraint))
2698
+ firstNonGenericOperatorSolution = constraint;
2699
+
2689
2700
firstSolvedConstraint = constraint;
2690
2701
2691
2702
// If we see a tuple-to-tuple conversion that succeeded, we're done.
0 commit comments