@@ -1734,18 +1734,6 @@ Constraint *ConstraintSystem::getUnboundBindOverloadDisjunction(
1734
1734
return result->first ;
1735
1735
}
1736
1736
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
-
1749
1737
// Performance hack: if there are two generic overloads, and one is
1750
1738
// more specialized than the other, prefer the more-specialized one.
1751
1739
static Constraint *tryOptimizeGenericDisjunction (
@@ -1878,15 +1866,14 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS,
1878
1866
}
1879
1867
}
1880
1868
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)
1887
1874
return ;
1888
1875
1889
- auto operatorName = constraints [0 ]->getOverloadChoice ().getName ();
1876
+ auto operatorName = Choices [0 ]->getOverloadChoice ().getName ();
1890
1877
if (!operatorName.getBaseIdentifier ().isArithmeticOperator ())
1891
1878
return ;
1892
1879
@@ -1899,7 +1886,8 @@ void ConstraintSystem::partitionGenericOperators(ArrayRef<Constraint *> constrai
1899
1886
if (!nominal)
1900
1887
return false ;
1901
1888
1902
- auto *protocol = TypeChecker::getProtocol (getASTContext (), SourceLoc (), kind);
1889
+ auto *protocol =
1890
+ TypeChecker::getProtocol (CS.getASTContext (), SourceLoc (), kind);
1903
1891
1904
1892
if (auto *refined = dyn_cast<ProtocolDecl>(nominal))
1905
1893
return refined->inheritsFrom (protocol);
@@ -1911,7 +1899,7 @@ void ConstraintSystem::partitionGenericOperators(ArrayRef<Constraint *> constrai
1911
1899
// Gather Numeric and Sequence overloads into separate buckets.
1912
1900
for (auto iter = first; iter != last; ++iter) {
1913
1901
unsigned index = *iter;
1914
- auto *decl = constraints [index]->getOverloadChoice ().getDecl ();
1902
+ auto *decl = Choices [index]->getOverloadChoice ().getDecl ();
1915
1903
auto *nominal = decl->getDeclContext ()->getSelfNominalTypeDecl ();
1916
1904
if (!decl->getInterfaceType ()->is <GenericFunctionType>()) {
1917
1905
concreteOverloads.push_back (index);
@@ -1926,8 +1914,10 @@ void ConstraintSystem::partitionGenericOperators(ArrayRef<Constraint *> constrai
1926
1914
1927
1915
auto sortPartition = [&](SmallVectorImpl<unsigned > &partition) {
1928
1916
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 ());
1931
1921
1932
1922
return TypeChecker::isDeclRefinementOf (declA, declB);
1933
1923
});
@@ -1946,19 +1936,22 @@ void ConstraintSystem::partitionGenericOperators(ArrayRef<Constraint *> constrai
1946
1936
// overload choices first.
1947
1937
for (auto arg : argFnType->getParams ()) {
1948
1938
auto argType = arg.getPlainType ();
1949
- argType = getFixedTypeRecursive (argType, /* wantRValue=*/ true );
1939
+ argType = CS. getFixedTypeRecursive (argType, /* wantRValue=*/ true );
1950
1940
1951
1941
if (argType->isTypeVariableOrMember ())
1952
1942
continue ;
1953
1943
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);
1956
1948
numericOverloads.clear ();
1957
1949
break ;
1958
1950
}
1959
1951
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);
1962
1955
sequenceOverloads.clear ();
1963
1956
break ;
1964
1957
}
@@ -1969,17 +1962,23 @@ void ConstraintSystem::partitionGenericOperators(ArrayRef<Constraint *> constrai
1969
1962
first = std::copy (sequenceOverloads.begin (), sequenceOverloads.end (), first);
1970
1963
}
1971
1964
1972
- void ConstraintSystem ::partitionDisjunction (
1973
- ArrayRef<Constraint *> Choices, SmallVectorImpl<unsigned > &Ordering,
1965
+ void DisjunctionChoiceProducer ::partitionDisjunction (
1966
+ SmallVectorImpl<unsigned > &Ordering,
1974
1967
SmallVectorImpl<unsigned > &PartitionBeginning) {
1975
1968
// Apply a special-case rule for favoring one generic function over
1976
1969
// another.
1977
- if (auto favored = tryOptimizeGenericDisjunction (DC, Choices)) {
1978
- favorConstraint (favored);
1970
+ if (auto favored = tryOptimizeGenericDisjunction (CS. DC , Choices)) {
1971
+ CS. favorConstraint (favored);
1979
1972
}
1980
1973
1981
1974
SmallSet<Constraint *, 16 > taken;
1982
1975
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
+
1983
1982
// Local function used to iterate over the untaken choices from the
1984
1983
// disjunction and use a higher-order function to determine if they
1985
1984
// should be part of a partition.
@@ -2006,7 +2005,7 @@ void ConstraintSystem::partitionDisjunction(
2006
2005
2007
2006
// Add existing operator bindings to the main partition first. This often
2008
2007
// helps the solver find a solution fast.
2009
- existingOperatorBindingsForDisjunction (* this , Choices, everythingElse);
2008
+ existingOperatorBindingsForDisjunction (CS , Choices, everythingElse);
2010
2009
for (auto index : everythingElse)
2011
2010
taken.insert (Choices[index]);
2012
2011
@@ -2026,7 +2025,7 @@ void ConstraintSystem::partitionDisjunction(
2026
2025
});
2027
2026
2028
2027
// Then unavailable constraints if we're skipping them.
2029
- if (!shouldAttemptFixes ()) {
2028
+ if (!CS. shouldAttemptFixes ()) {
2030
2029
forEachChoice (Choices, [&](unsigned index, Constraint *constraint) -> bool {
2031
2030
if (constraint->getKind () != ConstraintKind::BindOverload)
2032
2031
return false ;
@@ -2036,7 +2035,7 @@ void ConstraintSystem::partitionDisjunction(
2036
2035
if (!funcDecl)
2037
2036
return false ;
2038
2037
2039
- if (!isDeclUnavailable (funcDecl, constraint->getLocator ()))
2038
+ if (!CS. isDeclUnavailable (funcDecl, constraint->getLocator ()))
2040
2039
return false ;
2041
2040
2042
2041
unavailable.push_back (index);
@@ -2045,11 +2044,8 @@ void ConstraintSystem::partitionDisjunction(
2045
2044
}
2046
2045
2047
2046
// Partition SIMD operators.
2048
- if (isOperatorBindOverload (Choices[ 0 ] )) {
2047
+ if (isOperatorDisjunction (Disjunction )) {
2049
2048
forEachChoice (Choices, [&](unsigned index, Constraint *constraint) -> bool {
2050
- if (!isOperatorBindOverload (constraint))
2051
- return false ;
2052
-
2053
2049
if (isSIMDOperator (constraint->getOverloadChoice ().getDecl ())) {
2054
2050
simdOperators.push_back (index);
2055
2051
return true ;
@@ -2103,8 +2099,7 @@ Constraint *ConstraintSystem::selectDisjunction() {
2103
2099
unsigned firstFavored = first->countFavoredNestedConstraints ();
2104
2100
unsigned secondFavored = second->countFavoredNestedConstraints ();
2105
2101
2106
- if (!isOperatorBindOverload (first->getNestedConstraints ().front ()) ||
2107
- !isOperatorBindOverload (second->getNestedConstraints ().front ()))
2102
+ if (!isOperatorDisjunction (first) || !isOperatorDisjunction (second))
2108
2103
return firstActive < secondActive;
2109
2104
2110
2105
if (firstFavored == secondFavored) {
0 commit comments