@@ -2034,7 +2034,14 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS,
2034
2034
if (!decl->isOperator ())
2035
2035
return ;
2036
2036
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;
2038
2045
for (auto overload : CS.getResolvedOverloads ()) {
2039
2046
auto resolved = overload.second ;
2040
2047
if (!resolved.choice .isDecl ())
@@ -2044,7 +2051,12 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS,
2044
2051
if (!representativeDecl->isOperator ())
2045
2052
continue ;
2046
2053
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
+ }
2048
2060
}
2049
2061
2050
2062
for (auto index : indices (constraints)) {
@@ -2053,7 +2065,10 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS,
2053
2065
continue ;
2054
2066
2055
2067
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 ())))
2057
2072
found.push_back (index);
2058
2073
}
2059
2074
}
0 commit comments