Skip to content

Commit abfc903

Browse files
committed
[ConstraintSystem] For generic operators, only consider exact decls that
are already bound elsewhere for existingOperatorBindingsForDisjunction, rather than also considering overload choices with the same type.
1 parent 0995608 commit abfc903

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,7 +2034,14 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS,
20342034
if (!decl->isOperator())
20352035
return;
20362036

2037-
SmallSet<CanType, 8> typesFound;
2037+
// For concrete operators, consider overloads that have the same type as
2038+
// an existing binding, because it's very common to write mixed operator
2039+
// expressions where all operands have the same type, e.g. `(x + 10) / 2`.
2040+
// For generic operators, only favor an exact overload that has already
2041+
// been bound, because mixed operator expressions are far less common, and
2042+
// computing generic canonical types is expensive.
2043+
SmallSet<CanType, 4> concreteTypesFound;
2044+
SmallSet<ValueDecl *, 4> genericDeclsFound;
20382045
for (auto overload : CS.getResolvedOverloads()) {
20392046
auto resolved = overload.second;
20402047
if (!resolved.choice.isDecl())
@@ -2044,7 +2051,12 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS,
20442051
if (!representativeDecl->isOperator())
20452052
continue;
20462053

2047-
typesFound.insert(representativeDecl->getInterfaceType()->getCanonicalType());
2054+
auto interfaceType = representativeDecl->getInterfaceType();
2055+
if (interfaceType->is<GenericFunctionType>()) {
2056+
genericDeclsFound.insert(representativeDecl);
2057+
} else {
2058+
concreteTypesFound.insert(interfaceType->getCanonicalType());
2059+
}
20482060
}
20492061

20502062
for (auto index : indices(constraints)) {
@@ -2053,7 +2065,10 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS,
20532065
continue;
20542066

20552067
auto *decl = constraint->getOverloadChoice().getDecl();
2056-
if (typesFound.count(decl->getInterfaceType()->getCanonicalType()))
2068+
auto interfaceType = decl->getInterfaceType();
2069+
bool isGeneric = interfaceType->is<GenericFunctionType>();
2070+
if ((isGeneric && genericDeclsFound.count(decl)) ||
2071+
(!isGeneric && concreteTypesFound.count(interfaceType->getCanonicalType())))
20572072
found.push_back(index);
20582073
}
20592074
}

0 commit comments

Comments
 (0)