@@ -1957,64 +1957,12 @@ Constraint *ConstraintSystem::selectDisjunction() {
1957
1957
}
1958
1958
1959
1959
bool ConstraintSystem::solveForDisjunctionChoices (
1960
- Constraint *disjunction, SmallVectorImpl<Solution> &solutions,
1961
- FreeTypeVariableBinding allowFreeTypeVariables) {
1962
- assert (disjunction->getKind () == ConstraintKind::Disjunction);
1963
-
1964
- // Remove this disjunction constraint from the list.
1965
- auto afterDisjunction = InactiveConstraints.erase (disjunction);
1966
- CG.removeConstraint (disjunction);
1967
-
1968
- // Check if selected disjunction has a representative
1969
- // this might happen when there are multiple binary operators
1970
- // chained together. If so, disable choices which differ
1971
- // from currently selected representative.
1972
- auto pruneOverloadSet = [&](Constraint *disjunction) -> bool {
1973
- auto *choice = disjunction->getNestedConstraints ().front ();
1974
- auto *typeVar = choice->getFirstType ()->getAs <TypeVariableType>();
1975
- if (!typeVar)
1976
- return false ;
1977
-
1978
- auto *repr = typeVar->getImpl ().getRepresentative (nullptr );
1979
- if (!repr || repr == typeVar)
1980
- return false ;
1981
-
1982
- bool isPruned = false ;
1983
- for (auto resolved = resolvedOverloadSets; resolved;
1984
- resolved = resolved->Previous ) {
1985
- if (!resolved->BoundType ->isEqual (repr))
1986
- continue ;
1987
-
1988
- auto &representative = resolved->Choice ;
1989
- if (!representative.isDecl ())
1990
- return false ;
1991
-
1992
- // Disable all of the overload choices which are different from
1993
- // the one which is currently picked for representative.
1994
- for (auto *constraint : disjunction->getNestedConstraints ()) {
1995
- auto choice = constraint->getOverloadChoice ();
1996
- if (!choice.isDecl ())
1997
- continue ;
1998
-
1999
- if (choice.getDecl () != representative.getDecl ()) {
2000
- constraint->setDisabled ();
2001
- isPruned = true ;
2002
- }
2003
- }
2004
- break ;
2005
- }
2006
-
2007
- return isPruned;
2008
- };
2009
-
2010
- bool hasDisabledChoices = pruneOverloadSet (disjunction);
2011
-
2012
- Optional<std::pair<DisjunctionChoice, Score>> lastSolvedChoice;
1960
+ ArrayRef<Constraint *> constraints, ConstraintLocator *disjunctionLocator,
1961
+ SmallVectorImpl<Solution> &solutions,
1962
+ FreeTypeVariableBinding allowFreeTypeVariables, bool explicitConversion) {
2013
1963
Optional<Score> bestNonGenericScore;
1964
+ Optional<std::pair<DisjunctionChoice, Score>> lastSolvedChoice;
2014
1965
2015
- ++solverState->NumDisjunctions ;
2016
- bool explicitConversion = isExplicitConversionConstraint (disjunction);
2017
- auto constraints = disjunction->getNestedConstraints ();
2018
1966
// Try each of the constraints within the disjunction.
2019
1967
for (auto index : indices (constraints)) {
2020
1968
auto currentChoice =
@@ -2052,15 +2000,14 @@ bool ConstraintSystem::solveForDisjunctionChoices(
2052
2000
2053
2001
// If the disjunction requested us to, remember which choice we
2054
2002
// took for it.
2055
- if (disjunction->shouldRememberChoice ()) {
2056
- auto locator = disjunction->getLocator ();
2057
- assert (locator && " remembered disjunction doesn't have a locator?" );
2058
- DisjunctionChoices.push_back ({locator, index});
2003
+
2004
+ if (disjunctionLocator) {
2005
+ DisjunctionChoices.push_back ({disjunctionLocator, index});
2059
2006
2060
2007
// Implicit unwraps of optionals are worse solutions than those
2061
2008
// not involving implicit unwraps.
2062
- if (!locator ->getPath ().empty ()) {
2063
- auto kind = locator ->getPath ().back ().getKind ();
2009
+ if (!disjunctionLocator ->getPath ().empty ()) {
2010
+ auto kind = disjunctionLocator ->getPath ().back ().getKind ();
2064
2011
if (kind == ConstraintLocator::ImplicitlyUnwrappedDisjunctionChoice ||
2065
2012
kind == ConstraintLocator::DynamicLookupResult) {
2066
2013
assert (index == 0 || index == 1 );
@@ -2086,6 +2033,71 @@ bool ConstraintSystem::solveForDisjunctionChoices(
2086
2033
}
2087
2034
}
2088
2035
2036
+ return !bool (lastSolvedChoice.hasValue ());
2037
+ }
2038
+
2039
+ bool ConstraintSystem::solveForDisjunction (
2040
+ Constraint *disjunction, SmallVectorImpl<Solution> &solutions,
2041
+ FreeTypeVariableBinding allowFreeTypeVariables) {
2042
+ assert (disjunction->getKind () == ConstraintKind::Disjunction);
2043
+
2044
+ // Remove this disjunction constraint from the list.
2045
+ auto afterDisjunction = InactiveConstraints.erase (disjunction);
2046
+ CG.removeConstraint (disjunction);
2047
+
2048
+ // Check if selected disjunction has a representative
2049
+ // this might happen when there are multiple binary operators
2050
+ // chained together. If so, disable choices which differ
2051
+ // from currently selected representative.
2052
+ auto pruneOverloadSet = [&](Constraint *disjunction) -> bool {
2053
+ auto *choice = disjunction->getNestedConstraints ().front ();
2054
+ auto *typeVar = choice->getFirstType ()->getAs <TypeVariableType>();
2055
+ if (!typeVar)
2056
+ return false ;
2057
+
2058
+ auto *repr = typeVar->getImpl ().getRepresentative (nullptr );
2059
+ if (!repr || repr == typeVar)
2060
+ return false ;
2061
+
2062
+ bool isPruned = false ;
2063
+ for (auto resolved = resolvedOverloadSets; resolved;
2064
+ resolved = resolved->Previous ) {
2065
+ if (!resolved->BoundType ->isEqual (repr))
2066
+ continue ;
2067
+
2068
+ auto &representative = resolved->Choice ;
2069
+ if (!representative.isDecl ())
2070
+ return false ;
2071
+
2072
+ // Disable all of the overload choices which are different from
2073
+ // the one which is currently picked for representative.
2074
+ for (auto *constraint : disjunction->getNestedConstraints ()) {
2075
+ auto choice = constraint->getOverloadChoice ();
2076
+ if (!choice.isDecl ())
2077
+ continue ;
2078
+
2079
+ if (choice.getDecl () != representative.getDecl ()) {
2080
+ constraint->setDisabled ();
2081
+ isPruned = true ;
2082
+ }
2083
+ }
2084
+ break ;
2085
+ }
2086
+
2087
+ return isPruned;
2088
+ };
2089
+
2090
+ bool hasDisabledChoices = pruneOverloadSet (disjunction);
2091
+
2092
+ ++solverState->NumDisjunctions ;
2093
+ auto *locator =
2094
+ disjunction->shouldRememberChoice () ? disjunction->getLocator () : nullptr ;
2095
+ assert (!disjunction->shouldRememberChoice () || disjunction->getLocator ());
2096
+
2097
+ auto noSolutions = solveForDisjunctionChoices (
2098
+ disjunction->getNestedConstraints (), locator, solutions,
2099
+ allowFreeTypeVariables, isExplicitConversionConstraint (disjunction));
2100
+
2089
2101
if (hasDisabledChoices) {
2090
2102
// Re-enable previously disabled overload choices.
2091
2103
for (auto *choice : disjunction->getNestedConstraints ()) {
@@ -2098,7 +2110,7 @@ bool ConstraintSystem::solveForDisjunctionChoices(
2098
2110
InactiveConstraints.insert (afterDisjunction, disjunction);
2099
2111
CG.addConstraint (disjunction);
2100
2112
2101
- return bool (lastSolvedChoice. hasValue ()) ;
2113
+ return noSolutions ;
2102
2114
}
2103
2115
2104
2116
bool ConstraintSystem::solveSimplified (
@@ -2123,10 +2135,8 @@ bool ConstraintSystem::solveSimplified(
2123
2135
allowFreeTypeVariables);
2124
2136
}
2125
2137
2126
- if (disjunction) {
2127
- return !solveForDisjunctionChoices (disjunction, solutions,
2128
- allowFreeTypeVariables);
2129
- }
2138
+ if (disjunction)
2139
+ return solveForDisjunction (disjunction, solutions, allowFreeTypeVariables);
2130
2140
2131
2141
// If there are no disjunctions we can't solve this system unless we have
2132
2142
// free type variables and are allowing them in the solution.
0 commit comments