@@ -1461,7 +1461,8 @@ ConstraintSystem::solveSingle(FreeTypeVariableBinding allowFreeTypeVariables) {
1461
1461
return std::move (solutions[0 ]);
1462
1462
}
1463
1463
1464
- bool ConstraintSystem::Candidate::solve () {
1464
+ bool ConstraintSystem::Candidate::solve (
1465
+ llvm::SmallDenseSet<Expr *> &shrunkExprs) {
1465
1466
// Don't attempt to solve candidate if there is closure
1466
1467
// expression involved, because it's handled specially
1467
1468
// by parent constraint system (e.g. parameter lists).
@@ -1504,6 +1505,11 @@ bool ConstraintSystem::Candidate::solve() {
1504
1505
return true ;
1505
1506
}
1506
1507
1508
+ // If this candidate is too complex given the number
1509
+ // of the domains we have reduced so far, let's bail out early.
1510
+ if (isTooComplexGiven (&cs, shrunkExprs))
1511
+ return false ;
1512
+
1507
1513
if (TC.getLangOpts ().DebugConstraintSolver ) {
1508
1514
auto &log = cs.getASTContext ().TypeCheckerDebug ->getStream ();
1509
1515
log << " --- Solving candidate for shrinking at " ;
@@ -1557,7 +1563,7 @@ bool ConstraintSystem::Candidate::solve() {
1557
1563
}
1558
1564
1559
1565
// Record found solutions as suggestions.
1560
- this ->applySolutions (solutions);
1566
+ this ->applySolutions (solutions, shrunkExprs );
1561
1567
1562
1568
// Let's double-check if we have any implicit expressions
1563
1569
// with type variables and nullify their types.
@@ -1569,7 +1575,8 @@ bool ConstraintSystem::Candidate::solve() {
1569
1575
}
1570
1576
1571
1577
void ConstraintSystem::Candidate::applySolutions (
1572
- llvm::SmallVectorImpl<Solution> &solutions) const {
1578
+ llvm::SmallVectorImpl<Solution> &solutions,
1579
+ llvm::SmallDenseSet<Expr *> &shrunkExprs) const {
1573
1580
// A collection of OSRs with their newly reduced domains,
1574
1581
// it's domains are sets because multiple solutions can have the same
1575
1582
// choice for one of the type variables, and we want no duplication.
@@ -1616,6 +1623,9 @@ void ConstraintSystem::Candidate::applySolutions(
1616
1623
= TC.Context .AllocateUninitialized <ValueDecl *>(choices.size ());
1617
1624
std::uninitialized_copy (choices.begin (), choices.end (), decls.begin ());
1618
1625
OSR->setDecls (decls);
1626
+
1627
+ // Record successfully shrunk expression.
1628
+ shrunkExprs.insert (OSR);
1619
1629
}
1620
1630
}
1621
1631
@@ -1684,7 +1694,8 @@ void ConstraintSystem::shrink(Expr *expr) {
1684
1694
auto func = applyExpr->getFn ();
1685
1695
// Let's record this function application for post-processing
1686
1696
// as well as if it contains overload set, see walkToExprPost.
1687
- ApplyExprs.push_back ({applyExpr, isa<OverloadSetRefExpr>(func)});
1697
+ ApplyExprs.push_back (
1698
+ {applyExpr, isa<OverloadSetRefExpr>(func) || isa<TypeExpr>(func)});
1688
1699
}
1689
1700
1690
1701
return { true , expr };
@@ -1918,11 +1929,12 @@ void ConstraintSystem::shrink(Expr *expr) {
1918
1929
// so we can start solving them separately.
1919
1930
expr->walk (collector);
1920
1931
1932
+ llvm::SmallDenseSet<Expr *> shrunkExprs;
1921
1933
for (auto &candidate : collector.Candidates ) {
1922
1934
// If there are no results, let's forget everything we know about the
1923
1935
// system so far. This actually is ok, because some of the expressions
1924
1936
// might require manual salvaging.
1925
- if (candidate.solve ()) {
1937
+ if (candidate.solve (shrunkExprs )) {
1926
1938
// Let's restore all of the original OSR domains for this sub-expression,
1927
1939
// this means that we can still make forward progress with solving of the
1928
1940
// top sub-expressions.
@@ -1933,6 +1945,7 @@ void ConstraintSystem::shrink(Expr *expr) {
1933
1945
return childExpr;
1934
1946
1935
1947
OSR->setDecls (domain->getSecond ());
1948
+ shrunkExprs.erase (OSR);
1936
1949
}
1937
1950
1938
1951
return childExpr;
0 commit comments