@@ -1469,7 +1469,8 @@ ConstraintSystem::solveSingle(FreeTypeVariableBinding allowFreeTypeVariables) {
1469
1469
return std::move (solutions[0 ]);
1470
1470
}
1471
1471
1472
- bool ConstraintSystem::Candidate::solve () {
1472
+ bool ConstraintSystem::Candidate::solve (
1473
+ llvm::SmallDenseSet<Expr *> &shrunkExprs) {
1473
1474
// Don't attempt to solve candidate if there is closure
1474
1475
// expression involved, because it's handled specially
1475
1476
// by parent constraint system (e.g. parameter lists).
@@ -1512,6 +1513,11 @@ bool ConstraintSystem::Candidate::solve() {
1512
1513
return true ;
1513
1514
}
1514
1515
1516
+ // If this candidate is too complex given the number
1517
+ // of the domains we have reduced so far, let's bail out early.
1518
+ if (isTooComplexGiven (&cs, shrunkExprs))
1519
+ return false ;
1520
+
1515
1521
if (TC.getLangOpts ().DebugConstraintSolver ) {
1516
1522
auto &log = cs.getASTContext ().TypeCheckerDebug ->getStream ();
1517
1523
log << " --- Solving candidate for shrinking at " ;
@@ -1565,7 +1571,7 @@ bool ConstraintSystem::Candidate::solve() {
1565
1571
}
1566
1572
1567
1573
// Record found solutions as suggestions.
1568
- this ->applySolutions (solutions);
1574
+ this ->applySolutions (solutions, shrunkExprs );
1569
1575
1570
1576
// Let's double-check if we have any implicit expressions
1571
1577
// with type variables and nullify their types.
@@ -1577,7 +1583,8 @@ bool ConstraintSystem::Candidate::solve() {
1577
1583
}
1578
1584
1579
1585
void ConstraintSystem::Candidate::applySolutions (
1580
- llvm::SmallVectorImpl<Solution> &solutions) const {
1586
+ llvm::SmallVectorImpl<Solution> &solutions,
1587
+ llvm::SmallDenseSet<Expr *> &shrunkExprs) const {
1581
1588
// A collection of OSRs with their newly reduced domains,
1582
1589
// it's domains are sets because multiple solutions can have the same
1583
1590
// choice for one of the type variables, and we want no duplication.
@@ -1624,6 +1631,9 @@ void ConstraintSystem::Candidate::applySolutions(
1624
1631
= TC.Context .AllocateUninitialized <ValueDecl *>(choices.size ());
1625
1632
std::uninitialized_copy (choices.begin (), choices.end (), decls.begin ());
1626
1633
OSR->setDecls (decls);
1634
+
1635
+ // Record successfully shrunk expression.
1636
+ shrunkExprs.insert (OSR);
1627
1637
}
1628
1638
}
1629
1639
@@ -1692,7 +1702,8 @@ void ConstraintSystem::shrink(Expr *expr) {
1692
1702
auto func = applyExpr->getFn ();
1693
1703
// Let's record this function application for post-processing
1694
1704
// as well as if it contains overload set, see walkToExprPost.
1695
- ApplyExprs.push_back ({applyExpr, isa<OverloadSetRefExpr>(func)});
1705
+ ApplyExprs.push_back (
1706
+ {applyExpr, isa<OverloadSetRefExpr>(func) || isa<TypeExpr>(func)});
1696
1707
}
1697
1708
1698
1709
return { true , expr };
@@ -1926,11 +1937,12 @@ void ConstraintSystem::shrink(Expr *expr) {
1926
1937
// so we can start solving them separately.
1927
1938
expr->walk (collector);
1928
1939
1940
+ llvm::SmallDenseSet<Expr *> shrunkExprs;
1929
1941
for (auto &candidate : collector.Candidates ) {
1930
1942
// If there are no results, let's forget everything we know about the
1931
1943
// system so far. This actually is ok, because some of the expressions
1932
1944
// might require manual salvaging.
1933
- if (candidate.solve ()) {
1945
+ if (candidate.solve (shrunkExprs )) {
1934
1946
// Let's restore all of the original OSR domains for this sub-expression,
1935
1947
// this means that we can still make forward progress with solving of the
1936
1948
// top sub-expressions.
@@ -1941,6 +1953,7 @@ void ConstraintSystem::shrink(Expr *expr) {
1941
1953
return childExpr;
1942
1954
1943
1955
OSR->setDecls (domain->getSecond ());
1956
+ shrunkExprs.erase (OSR);
1944
1957
}
1945
1958
1946
1959
return childExpr;
0 commit comments