@@ -1734,18 +1734,6 @@ Constraint *ConstraintSystem::getUnboundBindOverloadDisjunction(
17341734 return result->first ;
17351735}
17361736
1737- static bool isOperatorBindOverload (Constraint *bindOverload) {
1738- if (bindOverload->getKind () != ConstraintKind::BindOverload)
1739- return false ;
1740-
1741- auto choice = bindOverload->getOverloadChoice ();
1742- if (!choice.isDecl ())
1743- return false ;
1744-
1745- auto *funcDecl = dyn_cast<FuncDecl>(choice.getDecl ());
1746- return funcDecl && funcDecl->getOperatorDecl ();
1747- }
1748-
17491737// Performance hack: if there are two generic overloads, and one is
17501738// more specialized than the other, prefer the more-specialized one.
17511739static Constraint *tryOptimizeGenericDisjunction (
@@ -1878,15 +1866,14 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS,
18781866 }
18791867}
18801868
1881- void ConstraintSystem::partitionGenericOperators (ArrayRef<Constraint *> constraints,
1882- SmallVectorImpl<unsigned >::iterator first,
1883- SmallVectorImpl<unsigned >::iterator last,
1884- ConstraintLocator *locator) {
1885- auto *argFnType = AppliedDisjunctions[locator];
1886- if (!isOperatorBindOverload (constraints[0 ]) || !argFnType)
1869+ void DisjunctionChoiceProducer::partitionGenericOperators (
1870+ SmallVectorImpl<unsigned >::iterator first,
1871+ SmallVectorImpl<unsigned >::iterator last) {
1872+ auto *argFnType = CS.getAppliedDisjunctionArgumentFunction (Disjunction);
1873+ if (!isOperatorDisjunction (Disjunction) || !argFnType)
18871874 return ;
18881875
1889- auto operatorName = constraints [0 ]->getOverloadChoice ().getName ();
1876+ auto operatorName = Choices [0 ]->getOverloadChoice ().getName ();
18901877 if (!operatorName.getBaseIdentifier ().isArithmeticOperator ())
18911878 return ;
18921879
@@ -1899,7 +1886,8 @@ void ConstraintSystem::partitionGenericOperators(ArrayRef<Constraint *> constrai
18991886 if (!nominal)
19001887 return false ;
19011888
1902- auto *protocol = TypeChecker::getProtocol (getASTContext (), SourceLoc (), kind);
1889+ auto *protocol =
1890+ TypeChecker::getProtocol (CS.getASTContext (), SourceLoc (), kind);
19031891
19041892 if (auto *refined = dyn_cast<ProtocolDecl>(nominal))
19051893 return refined->inheritsFrom (protocol);
@@ -1911,7 +1899,7 @@ void ConstraintSystem::partitionGenericOperators(ArrayRef<Constraint *> constrai
19111899 // Gather Numeric and Sequence overloads into separate buckets.
19121900 for (auto iter = first; iter != last; ++iter) {
19131901 unsigned index = *iter;
1914- auto *decl = constraints [index]->getOverloadChoice ().getDecl ();
1902+ auto *decl = Choices [index]->getOverloadChoice ().getDecl ();
19151903 auto *nominal = decl->getDeclContext ()->getSelfNominalTypeDecl ();
19161904 if (!decl->getInterfaceType ()->is <GenericFunctionType>()) {
19171905 concreteOverloads.push_back (index);
@@ -1926,8 +1914,10 @@ void ConstraintSystem::partitionGenericOperators(ArrayRef<Constraint *> constrai
19261914
19271915 auto sortPartition = [&](SmallVectorImpl<unsigned > &partition) {
19281916 llvm::sort (partition, [&](unsigned lhs, unsigned rhs) -> bool {
1929- auto *declA = dyn_cast<ValueDecl>(constraints[lhs]->getOverloadChoice ().getDecl ());
1930- auto *declB = dyn_cast<ValueDecl>(constraints[rhs]->getOverloadChoice ().getDecl ());
1917+ auto *declA =
1918+ dyn_cast<ValueDecl>(Choices[lhs]->getOverloadChoice ().getDecl ());
1919+ auto *declB =
1920+ dyn_cast<ValueDecl>(Choices[rhs]->getOverloadChoice ().getDecl ());
19311921
19321922 return TypeChecker::isDeclRefinementOf (declA, declB);
19331923 });
@@ -1946,19 +1936,22 @@ void ConstraintSystem::partitionGenericOperators(ArrayRef<Constraint *> constrai
19461936 // overload choices first.
19471937 for (auto arg : argFnType->getParams ()) {
19481938 auto argType = arg.getPlainType ();
1949- argType = getFixedTypeRecursive (argType, /* wantRValue=*/ true );
1939+ argType = CS. getFixedTypeRecursive (argType, /* wantRValue=*/ true );
19501940
19511941 if (argType->isTypeVariableOrMember ())
19521942 continue ;
19531943
1954- if (conformsToKnownProtocol (DC, argType, KnownProtocolKind::AdditiveArithmetic)) {
1955- first = std::copy (numericOverloads.begin (), numericOverloads.end (), first);
1944+ if (conformsToKnownProtocol (CS.DC , argType,
1945+ KnownProtocolKind::AdditiveArithmetic)) {
1946+ first =
1947+ std::copy (numericOverloads.begin (), numericOverloads.end (), first);
19561948 numericOverloads.clear ();
19571949 break ;
19581950 }
19591951
1960- if (conformsToKnownProtocol (DC, argType, KnownProtocolKind::Sequence)) {
1961- first = std::copy (sequenceOverloads.begin (), sequenceOverloads.end (), first);
1952+ if (conformsToKnownProtocol (CS.DC , argType, KnownProtocolKind::Sequence)) {
1953+ first =
1954+ std::copy (sequenceOverloads.begin (), sequenceOverloads.end (), first);
19621955 sequenceOverloads.clear ();
19631956 break ;
19641957 }
@@ -1969,17 +1962,23 @@ void ConstraintSystem::partitionGenericOperators(ArrayRef<Constraint *> constrai
19691962 first = std::copy (sequenceOverloads.begin (), sequenceOverloads.end (), first);
19701963}
19711964
1972- void ConstraintSystem ::partitionDisjunction (
1973- ArrayRef<Constraint *> Choices, SmallVectorImpl<unsigned > &Ordering,
1965+ void DisjunctionChoiceProducer ::partitionDisjunction (
1966+ SmallVectorImpl<unsigned > &Ordering,
19741967 SmallVectorImpl<unsigned > &PartitionBeginning) {
19751968 // Apply a special-case rule for favoring one generic function over
19761969 // another.
1977- if (auto favored = tryOptimizeGenericDisjunction (DC, Choices)) {
1978- favorConstraint (favored);
1970+ if (auto favored = tryOptimizeGenericDisjunction (CS. DC , Choices)) {
1971+ CS. favorConstraint (favored);
19791972 }
19801973
19811974 SmallSet<Constraint *, 16 > taken;
19821975
1976+ using ConstraintMatcher = std::function<bool (unsigned index, Constraint *)>;
1977+ using ConstraintMatchLoop =
1978+ std::function<void (ArrayRef<Constraint *>, ConstraintMatcher)>;
1979+ using PartitionAppendCallback =
1980+ std::function<void (SmallVectorImpl<unsigned > & options)>;
1981+
19831982 // Local function used to iterate over the untaken choices from the
19841983 // disjunction and use a higher-order function to determine if they
19851984 // should be part of a partition.
@@ -2006,7 +2005,7 @@ void ConstraintSystem::partitionDisjunction(
20062005
20072006 // Add existing operator bindings to the main partition first. This often
20082007 // helps the solver find a solution fast.
2009- existingOperatorBindingsForDisjunction (* this , Choices, everythingElse);
2008+ existingOperatorBindingsForDisjunction (CS , Choices, everythingElse);
20102009 for (auto index : everythingElse)
20112010 taken.insert (Choices[index]);
20122011
@@ -2026,7 +2025,7 @@ void ConstraintSystem::partitionDisjunction(
20262025 });
20272026
20282027 // Then unavailable constraints if we're skipping them.
2029- if (!shouldAttemptFixes ()) {
2028+ if (!CS. shouldAttemptFixes ()) {
20302029 forEachChoice (Choices, [&](unsigned index, Constraint *constraint) -> bool {
20312030 if (constraint->getKind () != ConstraintKind::BindOverload)
20322031 return false ;
@@ -2036,7 +2035,7 @@ void ConstraintSystem::partitionDisjunction(
20362035 if (!funcDecl)
20372036 return false ;
20382037
2039- if (!isDeclUnavailable (funcDecl, constraint->getLocator ()))
2038+ if (!CS. isDeclUnavailable (funcDecl, constraint->getLocator ()))
20402039 return false ;
20412040
20422041 unavailable.push_back (index);
@@ -2045,11 +2044,8 @@ void ConstraintSystem::partitionDisjunction(
20452044 }
20462045
20472046 // Partition SIMD operators.
2048- if (isOperatorBindOverload (Choices[ 0 ] )) {
2047+ if (isOperatorDisjunction (Disjunction )) {
20492048 forEachChoice (Choices, [&](unsigned index, Constraint *constraint) -> bool {
2050- if (!isOperatorBindOverload (constraint))
2051- return false ;
2052-
20532049 if (isSIMDOperator (constraint->getOverloadChoice ().getDecl ())) {
20542050 simdOperators.push_back (index);
20552051 return true ;
@@ -2103,8 +2099,7 @@ Constraint *ConstraintSystem::selectDisjunction() {
21032099 unsigned firstFavored = first->countFavoredNestedConstraints ();
21042100 unsigned secondFavored = second->countFavoredNestedConstraints ();
21052101
2106- if (!isOperatorBindOverload (first->getNestedConstraints ().front ()) ||
2107- !isOperatorBindOverload (second->getNestedConstraints ().front ()))
2102+ if (!isOperatorDisjunction (first) || !isOperatorDisjunction (second))
21082103 return firstActive < secondActive;
21092104
21102105 if (firstFavored == secondFavored) {
0 commit comments