Skip to content

Commit deca9b6

Browse files
committed
[CSOptimizer] attempt to rank only standard/simd operators and fully concrete overload sets
1 parent 3819ddf commit deca9b6

File tree

1 file changed

+46
-8
lines changed

1 file changed

+46
-8
lines changed

lib/Sema/CSOptimizer.cpp

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,48 @@ using namespace constraints;
3434

3535
namespace {
3636

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+
3779
NullablePtr<Constraint> getApplicableFnConstraint(ConstraintGraph &CG,
3880
Constraint *disjunction) {
3981
auto *boundVar = disjunction->getNestedConstraints()[0]
@@ -112,6 +154,9 @@ static Constraint *determineBestChoicesInContext(
112154
favoredChoicesPerDisjunction;
113155

114156
for (auto *disjunction : disjunctions) {
157+
if (!isSupportedDisjunction(disjunction))
158+
continue;
159+
115160
auto applicableFn =
116161
getApplicableFnConstraint(cs.getConstraintGraph(), disjunction);
117162

@@ -337,7 +382,7 @@ static Constraint *determineBestChoicesInContext(
337382
// types match i.e. Array<Element> as a parameter.
338383
//
339384
// 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.
341386
if (paramType->hasTypeParameter()) {
342387
auto *candidateDecl = candidateType->getAnyNominal();
343388
auto *paramDecl = paramType->getAnyNominal();
@@ -365,13 +410,6 @@ static Constraint *determineBestChoicesInContext(
365410
} else if (auto *SD = dyn_cast<SubscriptDecl>(decl)) {
366411
genericSig = SD->getGenericSignature();
367412
}
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;
375413
}
376414

377415
auto matchings =

0 commit comments

Comments
 (0)