|
15 | 15 | //===----------------------------------------------------------------------===//
|
16 | 16 | #include "ConstraintSystem.h"
|
17 | 17 | #include "ConstraintGraph.h"
|
| 18 | +#include "swift/AST/ParameterList.h" |
18 | 19 | #include "swift/AST/TypeWalker.h"
|
19 | 20 | #include "llvm/ADT/Statistic.h"
|
20 | 21 | #include "llvm/Support/Compiler.h"
|
@@ -2480,6 +2481,28 @@ static bool isGenericOperatorOrUnavailable(Constraint *constraint) {
|
2480 | 2481 | decl->getAttrs().isUnavailable(ctx);
|
2481 | 2482 | }
|
2482 | 2483 |
|
| 2484 | +/// Whether this constraint refers to a symmetric operator. |
| 2485 | +static bool isSymmetricOperator(Constraint *constraint) { |
| 2486 | + if (constraint->getKind() != ConstraintKind::BindOverload || |
| 2487 | + constraint->getOverloadChoice().getKind() != OverloadChoiceKind::Decl || |
| 2488 | + !constraint->getOverloadChoice().getDecl()->isOperator()) |
| 2489 | + return false; |
| 2490 | + |
| 2491 | + // If it's a binary operator, check that the types on both sides are the |
| 2492 | + // same. Otherwise, don't perform this optimization. |
| 2493 | + auto func = dyn_cast<FuncDecl>(constraint->getOverloadChoice().getDecl()); |
| 2494 | + auto paramList = |
| 2495 | + func->getParameterList(func->getDeclContext()->isTypeContext()); |
| 2496 | + if (paramList->size() != 2) |
| 2497 | + return true; |
| 2498 | + |
| 2499 | + auto firstType = |
| 2500 | + paramList->get(0)->getInterfaceType()->getLValueOrInOutObjectType(); |
| 2501 | + auto secondType = |
| 2502 | + paramList->get(1)->getInterfaceType()->getLValueOrInOutObjectType(); |
| 2503 | + return firstType->isEqual(secondType); |
| 2504 | +} |
| 2505 | + |
2483 | 2506 | bool ConstraintSystem::solveSimplified(
|
2484 | 2507 | SmallVectorImpl<Solution> &solutions,
|
2485 | 2508 | FreeTypeVariableBinding allowFreeTypeVariables) {
|
@@ -2694,7 +2717,8 @@ bool ConstraintSystem::solveSimplified(
|
2694 | 2717 |
|
2695 | 2718 | if (!solveRec(solutions, allowFreeTypeVariables)) {
|
2696 | 2719 | if (!firstNonGenericOperatorSolution &&
|
2697 |
| - !isGenericOperatorOrUnavailable(constraint)) |
| 2720 | + !isGenericOperatorOrUnavailable(constraint) && |
| 2721 | + isSymmetricOperator(constraint)) |
2698 | 2722 | firstNonGenericOperatorSolution = constraint;
|
2699 | 2723 |
|
2700 | 2724 | firstSolvedConstraint = constraint;
|
|
0 commit comments