@@ -2013,7 +2013,8 @@ static Constraint *tryOptimizeGenericDisjunction(
2013
2013
llvm_unreachable (" covered switch" );
2014
2014
}
2015
2015
2016
- // Performance hack: favor operator overloads with types we're already binding elsewhere in this expression.
2016
+ // Performance hack: favor operator overloads with decl or type we're already
2017
+ // binding elsewhere in this expression.
2017
2018
static void existingOperatorBindingsForDisjunction (ConstraintSystem &CS, ArrayRef<Constraint *> constraints, SmallVectorImpl<Constraint *> &found) {
2018
2019
auto *choice = constraints.front ();
2019
2020
if (choice->getKind () != ConstraintKind::BindOverload)
@@ -2025,6 +2026,9 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS, ArrayRe
2025
2026
auto decl = overload.getDecl ();
2026
2027
if (!decl->isOperator ())
2027
2028
return ;
2029
+ auto baseName = decl->getBaseName ();
2030
+
2031
+ SmallSet<TypeBase *, 8 > typesFound;
2028
2032
2029
2033
for (auto overload : CS.getResolvedOverloads ()) {
2030
2034
auto resolved = overload.second ;
@@ -2035,12 +2039,33 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS, ArrayRe
2035
2039
if (!representativeDecl->isOperator ())
2036
2040
continue ;
2037
2041
2038
- for (auto *constraint : constraints) {
2039
- if (constraint->isFavored ())
2042
+ if (representativeDecl->getBaseName () == baseName) {
2043
+ // Favor exactly the same decl, if we have a binding to the same name.
2044
+ for (auto *constraint : constraints) {
2045
+ if (constraint->isFavored ())
2046
+ continue ;
2047
+ auto choice = constraint->getOverloadChoice ();
2048
+ if (choice.getDecl () == representativeDecl) {
2049
+ found.push_back (constraint);
2050
+ break ;
2051
+ }
2052
+ }
2053
+ } else {
2054
+ // Favor the same type, if we have a binding to an operator of that type.
2055
+ auto representativeType = representativeDecl->getInterfaceType ();
2056
+ if (typesFound.count (representativeType.getPointer ()))
2040
2057
continue ;
2041
- auto choice = constraint->getOverloadChoice ();
2042
- if (choice.getDecl ()->getInterfaceType ()->isEqual (representativeDecl->getInterfaceType ()))
2043
- found.push_back (constraint);
2058
+ typesFound.insert (representativeType.getPointer ());
2059
+
2060
+ for (auto *constraint : constraints) {
2061
+ if (constraint->isFavored ())
2062
+ continue ;
2063
+ auto choice = constraint->getOverloadChoice ();
2064
+ if (choice.getDecl ()->getInterfaceType ()->isEqual (representativeType)) {
2065
+ found.push_back (constraint);
2066
+ break ;
2067
+ }
2068
+ }
2044
2069
}
2045
2070
}
2046
2071
}
0 commit comments