@@ -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