@@ -34,6 +34,48 @@ using namespace constraints;
34
34
35
35
namespace {
36
36
37
+ static bool isSupportedOperator (Constraint *disjunction) {
38
+ if (!isOperatorDisjunction (disjunction))
39
+ return false ;
40
+
41
+ auto choices = disjunction->getNestedConstraints ();
42
+ auto *decl = getOverloadChoiceDecl (choices.front ());
43
+
44
+ auto name = decl->getBaseIdentifier ();
45
+ if (name.isArithmeticOperator () || name.isStandardComparisonOperator () ||
46
+ name.is (" ^" )) {
47
+ return true ;
48
+ }
49
+
50
+ // Operators like &<<, &>>, &+, .== etc.
51
+ if (llvm::any_of (choices, [](Constraint *choice) {
52
+ return isSIMDOperator (getOverloadChoiceDecl (choice));
53
+ })) {
54
+ return true ;
55
+ }
56
+
57
+ return false ;
58
+ }
59
+
60
+ static bool isSupportedDisjunction (Constraint *disjunction) {
61
+ auto choices = disjunction->getNestedConstraints ();
62
+
63
+ if (isSupportedOperator (disjunction))
64
+ return true ;
65
+
66
+ // Non-operator disjunctions are supported only if they don't
67
+ // have any generic choices.
68
+ return llvm::all_of (choices, [&](Constraint *choice) {
69
+ if (choice->getKind () != ConstraintKind::BindOverload)
70
+ return false ;
71
+
72
+ if (auto *decl = getOverloadChoiceDecl (choice))
73
+ return decl->getInterfaceType ()->is <FunctionType>();
74
+
75
+ return false ;
76
+ });
77
+ }
78
+
37
79
NullablePtr<Constraint> getApplicableFnConstraint (ConstraintGraph &CG,
38
80
Constraint *disjunction) {
39
81
auto *boundVar = disjunction->getNestedConstraints ()[0 ]
@@ -112,6 +154,9 @@ static Constraint *determineBestChoicesInContext(
112
154
favoredChoicesPerDisjunction;
113
155
114
156
for (auto *disjunction : disjunctions) {
157
+ if (!isSupportedDisjunction (disjunction))
158
+ continue ;
159
+
115
160
auto applicableFn =
116
161
getApplicableFnConstraint (cs.getConstraintGraph (), disjunction);
117
162
@@ -337,7 +382,7 @@ static Constraint *determineBestChoicesInContext(
337
382
// types match i.e. Array<Element> as a parameter.
338
383
//
339
384
// This is slightly better than all of the conformances matching
340
- // because the parameter is concrete and could split the graph.
385
+ // because the parameter is concrete and could split the graph.
341
386
if (paramType->hasTypeParameter ()) {
342
387
auto *candidateDecl = candidateType->getAnyNominal ();
343
388
auto *paramDecl = paramType->getAnyNominal ();
@@ -365,13 +410,6 @@ static Constraint *determineBestChoicesInContext(
365
410
} else if (auto *SD = dyn_cast<SubscriptDecl>(decl)) {
366
411
genericSig = SD->getGenericSignature ();
367
412
}
368
-
369
- // Let's not consider non-operator generic overloads because we
370
- // need conformance checking functionality to determine best
371
- // favoring, preferring such overloads based on concrete types
372
- // alone leads to subpar choices due to missed information.
373
- if (genericSig && !decl->isOperator ())
374
- return ;
375
413
}
376
414
377
415
auto matchings =
0 commit comments