@@ -527,13 +527,6 @@ bool ConstraintSystem::tryTypeVariableBindings(
527
527
bool anySolved = false ;
528
528
bool sawFirstLiteralConstraint = false ;
529
529
530
- auto attemptTypeVarBinding = [&](TypeVariableBinding &binding) -> bool {
531
- // Try to solve the system with typeVar := type
532
- ConstraintSystem::SolverScope scope (*this );
533
- binding.attempt (*this );
534
- return !solveRec (solutions);
535
- };
536
-
537
530
if (TC.getLangOpts ().DebugConstraintSolver ) {
538
531
auto &log = getASTContext ().TypeCheckerDebug ->getStream ();
539
532
log.indent (solverState->depth * 2 ) << " Initial bindings: " ;
@@ -556,7 +549,7 @@ bool ConstraintSystem::tryTypeVariableBindings(
556
549
if (anySolved) {
557
550
// If this is a defaultable binding and we have found solutions,
558
551
// don't explore the default binding.
559
- if (binding->isDefaultableBinding ())
552
+ if (binding->isDefaultable ())
560
553
continue ;
561
554
562
555
// If we were able to solve this without considering
@@ -567,16 +560,20 @@ bool ConstraintSystem::tryTypeVariableBindings(
567
560
568
561
if (TC.getLangOpts ().DebugConstraintSolver ) {
569
562
auto &log = getASTContext ().TypeCheckerDebug ->getStream ();
570
- log.indent (solverState->depth * 2 )
571
- << " (trying " << typeVar-> getString ()
572
- << " := " << binding-> getType ()-> getString () << ' \n ' ;
563
+ log.indent (solverState->depth * 2 ) << " (trying " ;
564
+ binding-> print (log, & getASTContext (). SourceMgr );
565
+ log << ' \n ' ;
573
566
}
574
567
575
568
if (binding->hasDefaultedProtocol ())
576
569
sawFirstLiteralConstraint = true ;
577
570
578
- if (attemptTypeVarBinding (*binding))
579
- anySolved = true ;
571
+ {
572
+ // Try to solve the system with typeVar := type
573
+ ConstraintSystem::SolverScope scope (*this );
574
+ binding->attempt (*this );
575
+ anySolved |= !solveRec (solutions);
576
+ }
580
577
581
578
if (TC.getLangOpts ().DebugConstraintSolver ) {
582
579
auto &log = getASTContext ().TypeCheckerDebug ->getStream ();
@@ -1617,17 +1614,17 @@ void ConstraintSystem::collectDisjunctions(
1617
1614
}
1618
1615
1619
1616
// / \brief Check if the given disjunction choice should be attempted by solver.
1620
- static bool shouldSkipDisjunctionChoice (DisjunctionChoice &choice,
1617
+ static bool shouldSkipDisjunctionChoice (ConstraintSystem &cs,
1618
+ const TypeBinding &choice,
1621
1619
Optional<Score> &bestNonGenericScore) {
1622
- auto &cs = choice.getCS ();
1623
1620
auto &TC = cs.TC ;
1624
1621
1625
- if (choice-> isDisabled ()) {
1622
+ if (choice. isDisabled ()) {
1626
1623
if (TC.getLangOpts ().DebugConstraintSolver ) {
1627
1624
auto &log = cs.getASTContext ().TypeCheckerDebug ->getStream ();
1628
1625
log.indent (cs.solverState ->depth )
1629
1626
<< " (skipping " ;
1630
- choice-> print (log, &TC.Context .SourceMgr );
1627
+ choice. print (log, &TC.Context .SourceMgr );
1631
1628
log << ' \n ' ;
1632
1629
}
1633
1630
@@ -1746,22 +1743,68 @@ Constraint *ConstraintSystem::selectDisjunction() {
1746
1743
return nullptr ;
1747
1744
}
1748
1745
1749
- bool ConstraintSystem::solveForDisjunctionChoices (
1750
- DisjunctionChoiceProducer &disjunction ,
1746
+ Optional<Score> ConstraintSystem::solveForDisjunctionChoice (
1747
+ const TypeBinding &choice, ConstraintLocator *disjunctionLocator ,
1751
1748
SmallVectorImpl<Solution> &solutions) {
1749
+ SolverScope scope (*this );
1750
+ ++solverState->NumDisjunctionTerms ;
1751
+
1752
+ // If the disjunction requested us to, remember which choice we
1753
+ // took for it.
1754
+ if (disjunctionLocator) {
1755
+ auto index = choice.getIndex ();
1756
+ DisjunctionChoices.push_back ({disjunctionLocator, index});
1757
+
1758
+ // Implicit unwraps of optionals are worse solutions than those
1759
+ // not involving implicit unwraps.
1760
+ if (!disjunctionLocator->getPath ().empty ()) {
1761
+ auto kind = disjunctionLocator->getPath ().back ().getKind ();
1762
+ if (kind == ConstraintLocator::ImplicitlyUnwrappedDisjunctionChoice ||
1763
+ kind == ConstraintLocator::DynamicLookupResult) {
1764
+ assert (index == 0 || index == 1 );
1765
+ if (index == 1 )
1766
+ increaseScore (SK_ForceUnchecked);
1767
+ }
1768
+ }
1769
+ }
1770
+
1771
+ choice.attempt (*this );
1772
+ if (solveRec (solutions))
1773
+ return None;
1774
+
1775
+ assert (!solutions.empty ());
1776
+ Score bestScore = solutions.front ().getFixedScore ();
1777
+ if (solutions.size () == 1 )
1778
+ return bestScore;
1779
+
1780
+ for (unsigned i = 1 , n = solutions.size (); i != n; ++i) {
1781
+ auto &score = solutions[i].getFixedScore ();
1782
+ if (score < bestScore)
1783
+ bestScore = score;
1784
+ }
1785
+
1786
+ return bestScore;
1787
+ }
1788
+
1789
+ bool ConstraintSystem::solveForDisjunctionChoices (
1790
+ ArrayRef<Constraint *> choices, ConstraintLocator *disjunctionLocator,
1791
+ bool isExplicitConversion, SmallVectorImpl<Solution> &solutions) {
1752
1792
Optional<Score> bestNonGenericScore;
1753
- Optional<std::pair<DisjunctionChoice, Score>> lastSolvedChoice;
1793
+ Optional<std::pair<Constraint *, Score>> lastSolvedChoice;
1794
+
1795
+ DisjunctionChoiceProducer producer (*this , choices, disjunctionLocator,
1796
+ isExplicitConversion);
1754
1797
1755
1798
// Try each of the constraints within the disjunction.
1756
- while (auto binding = disjunction ()) {
1757
- auto ¤tChoice = *binding;
1758
- if (shouldSkipDisjunctionChoice (currentChoice, bestNonGenericScore))
1799
+ while (auto currentChoice = producer ()) {
1800
+ if (shouldSkipDisjunctionChoice (*this , *currentChoice, bestNonGenericScore))
1759
1801
continue ;
1760
1802
1761
1803
// We already have a solution; check whether we should
1762
1804
// short-circuit the disjunction.
1763
1805
if (lastSolvedChoice) {
1764
- Constraint *lastChoice = lastSolvedChoice->first ;
1806
+ auto *choice = choices[currentChoice->getIndex ()];
1807
+ auto *lastChoice = lastSolvedChoice->first ;
1765
1808
auto delta = lastSolvedChoice->second - CurrentScore;
1766
1809
bool hasUnavailableOverloads = delta.Data [SK_Unavailable] > 0 ;
1767
1810
bool hasFixes = delta.Data [SK_Fix] > 0 ;
@@ -1771,13 +1814,10 @@ bool ConstraintSystem::solveForDisjunctionChoices(
1771
1814
// selecting unavailable overloads or result in fixes being
1772
1815
// applied to reach a solution.
1773
1816
if (!hasUnavailableOverloads && !hasFixes &&
1774
- shortCircuitDisjunctionAt (currentChoice , lastChoice, getASTContext ()))
1817
+ shortCircuitDisjunctionAt (choice , lastChoice, getASTContext ()))
1775
1818
break ;
1776
1819
}
1777
1820
1778
- // Try to solve the system with this option in the disjunction.
1779
- SolverScope scope (*this );
1780
- ++solverState->NumDisjunctionTerms ;
1781
1821
if (TC.getLangOpts ().DebugConstraintSolver ) {
1782
1822
auto &log = getASTContext ().TypeCheckerDebug ->getStream ();
1783
1823
log.indent (solverState->depth )
@@ -1786,34 +1826,16 @@ bool ConstraintSystem::solveForDisjunctionChoices(
1786
1826
log << ' \n ' ;
1787
1827
}
1788
1828
1789
- // If the disjunction requested us to, remember which choice we
1790
- // took for it.
1791
-
1792
- if (auto *disjunctionLocator = disjunction.getLocator ()) {
1793
- auto index = currentChoice.getIndex ();
1794
- DisjunctionChoices.push_back ({disjunctionLocator, index});
1795
-
1796
- // Implicit unwraps of optionals are worse solutions than those
1797
- // not involving implicit unwraps.
1798
- if (!disjunctionLocator->getPath ().empty ()) {
1799
- auto kind = disjunctionLocator->getPath ().back ().getKind ();
1800
- if (kind == ConstraintLocator::ImplicitlyUnwrappedDisjunctionChoice ||
1801
- kind == ConstraintLocator::DynamicLookupResult) {
1802
- assert (index == 0 || index == 1 );
1803
- if (index == 1 )
1804
- increaseScore (SK_ForceUnchecked);
1805
- }
1806
- }
1807
- }
1808
-
1809
- if (auto score = binding->attempt (solutions)) {
1810
- if (!currentChoice.isGenericOperator () &&
1811
- currentChoice.isSymmetricOperator ()) {
1829
+ // Try to solve the system with this option in the disjunction.
1830
+ if (auto score = solveForDisjunctionChoice (*currentChoice,
1831
+ disjunctionLocator, solutions)) {
1832
+ if (!currentChoice->isGenericOperator () &&
1833
+ currentChoice->isSymmetricOperator ()) {
1812
1834
if (!bestNonGenericScore || score < bestNonGenericScore)
1813
1835
bestNonGenericScore = score;
1814
1836
}
1815
1837
1816
- lastSolvedChoice = {currentChoice, *score};
1838
+ lastSolvedChoice = {choices[ currentChoice-> getIndex ()] , *score};
1817
1839
}
1818
1840
1819
1841
if (TC.getLangOpts ().DebugConstraintSolver ) {
@@ -1882,11 +1904,9 @@ bool ConstraintSystem::solveForDisjunction(
1882
1904
disjunction->shouldRememberChoice () ? disjunction->getLocator () : nullptr ;
1883
1905
assert (!disjunction->shouldRememberChoice () || disjunction->getLocator ());
1884
1906
1885
- auto choices =
1886
- DisjunctionChoiceProducer (*this , disjunction->getNestedConstraints (),
1887
- locator, disjunction->isExplicitConversion ());
1888
-
1889
- auto noSolutions = solveForDisjunctionChoices (choices, solutions);
1907
+ auto noSolutions = solveForDisjunctionChoices (
1908
+ disjunction->getNestedConstraints (), locator,
1909
+ disjunction->isExplicitConversion (), solutions);
1890
1910
1891
1911
if (hasDisabledChoices) {
1892
1912
// Re-enable previously disabled overload choices.
@@ -1956,46 +1976,23 @@ bool ConstraintSystem::solveSimplified(SmallVectorImpl<Solution> &solutions) {
1956
1976
}
1957
1977
1958
1978
void DisjunctionChoice::attempt (ConstraintSystem &cs) const {
1959
- CS-> simplifyDisjunctionChoice (Choice);
1979
+ cs. simplifyDisjunctionChoice (Choice);
1960
1980
1961
1981
if (ExplicitConversion)
1962
- propagateConversionInfo ();
1963
- }
1964
-
1965
- Optional<Score>
1966
- DisjunctionChoice::attempt (SmallVectorImpl<Solution> &solutions) {
1967
- attempt (*CS);
1968
-
1969
- if (CS->solveRec (solutions))
1970
- return None;
1971
-
1972
- assert (!solutions.empty ());
1973
-
1974
- Score bestScore = solutions.front ().getFixedScore ();
1975
-
1976
- if (solutions.size () == 1 )
1977
- return bestScore;
1978
-
1979
- for (unsigned i = 1 , n = solutions.size (); i != n; ++i) {
1980
- auto &score = solutions[i].getFixedScore ();
1981
- if (score < bestScore)
1982
- bestScore = score;
1983
- }
1984
-
1985
- return bestScore;
1982
+ propagateConversionInfo (cs);
1986
1983
}
1987
1984
1988
- bool DisjunctionChoice::isGenericOperator () const {
1989
- auto *decl = getOperatorDecl ();
1985
+ bool DisjunctionChoice::isGenericOp (Constraint *choice) {
1986
+ auto *decl = getOperatorDecl (choice );
1990
1987
if (!decl)
1991
1988
return false ;
1992
1989
1993
1990
auto interfaceType = decl->getInterfaceType ();
1994
1991
return interfaceType->is <GenericFunctionType>();
1995
1992
}
1996
1993
1997
- bool DisjunctionChoice::isSymmetricOperator () const {
1998
- auto *decl = getOperatorDecl ();
1994
+ bool DisjunctionChoice::isSymmetricOp (Constraint *choice) {
1995
+ auto *decl = getOperatorDecl (choice );
1999
1996
if (!decl)
2000
1997
return false ;
2001
1998
@@ -2009,7 +2006,7 @@ bool DisjunctionChoice::isSymmetricOperator() const {
2009
2006
return firstType->isEqual (secondType);
2010
2007
}
2011
2008
2012
- void DisjunctionChoice::propagateConversionInfo () const {
2009
+ void DisjunctionChoice::propagateConversionInfo (ConstraintSystem &cs ) const {
2013
2010
assert (ExplicitConversion);
2014
2011
2015
2012
auto LHS = Choice->getFirstType ();
@@ -2026,28 +2023,28 @@ void DisjunctionChoice::propagateConversionInfo() const {
2026
2023
if (typeVar->getImpl ().getFixedType (nullptr ))
2027
2024
return ;
2028
2025
2029
- auto bindings = CS-> getPotentialBindings (typeVar);
2026
+ auto bindings = cs. getPotentialBindings (typeVar);
2030
2027
if (bindings.InvolvesTypeVariables || bindings.Bindings .size () != 1 )
2031
2028
return ;
2032
2029
2033
2030
auto conversionType = bindings.Bindings [0 ].BindingType ;
2034
2031
llvm::SetVector<Constraint *> constraints;
2035
- CS-> CG .gatherConstraints (typeVar, constraints,
2036
- ConstraintGraph::GatheringKind::EquivalenceClass,
2037
- [](Constraint *constraint) -> bool {
2038
- switch (constraint->getKind ()) {
2039
- case ConstraintKind::Conversion:
2040
- case ConstraintKind::Defaultable:
2041
- case ConstraintKind::ConformsTo:
2042
- case ConstraintKind::LiteralConformsTo:
2043
- return false ;
2044
-
2045
- default :
2046
- return true ;
2047
- }
2048
- });
2032
+ cs. CG .gatherConstraints (typeVar, constraints,
2033
+ ConstraintGraph::GatheringKind::EquivalenceClass,
2034
+ [](Constraint *constraint) -> bool {
2035
+ switch (constraint->getKind ()) {
2036
+ case ConstraintKind::Conversion:
2037
+ case ConstraintKind::Defaultable:
2038
+ case ConstraintKind::ConformsTo:
2039
+ case ConstraintKind::LiteralConformsTo:
2040
+ return false ;
2041
+
2042
+ default :
2043
+ return true ;
2044
+ }
2045
+ });
2049
2046
2050
2047
if (constraints.empty ())
2051
- CS-> addConstraint (ConstraintKind::Bind, typeVar, conversionType,
2052
- Choice->getLocator ());
2048
+ cs. addConstraint (ConstraintKind::Bind, typeVar, conversionType,
2049
+ Choice->getLocator ());
2053
2050
}
0 commit comments