20
20
#include " llvm/Support/SaveAndRestore.h"
21
21
#include < memory>
22
22
#include < tuple>
23
- #include < stack>
24
- #include < queue>
25
23
using namespace swift ;
26
24
using namespace constraints ;
27
25
@@ -1475,23 +1473,21 @@ void ConstraintSystem::shrink(Expr *expr) {
1475
1473
// The primary constraint system.
1476
1474
ConstraintSystem &CS;
1477
1475
1478
- // All of the sub-expressions of certain type (binary/unary/calls) in
1479
- // depth-first order.
1480
- std::queue<Candidate> &SubExprs;
1476
+ // All of the sub-expressions which are suitable to be solved
1477
+ // separately from the main system e.g. binary expressions, collections,
1478
+ // function calls, coercions etc.
1479
+ llvm::SmallVector<Candidate, 4 > Candidates;
1481
1480
1482
1481
// Counts the number of overload sets present in the tree so far.
1483
1482
// Note that the traversal is depth-first.
1484
- std::stack<std::pair<ApplyExpr *, unsigned >,
1485
- llvm::SmallVector<std::pair<ApplyExpr *, unsigned >, 4 >>
1486
- ApplyExprs;
1483
+ llvm::SmallVector<std::pair<ApplyExpr *, unsigned >, 4 > ApplyExprs;
1487
1484
1488
1485
// A collection of original domains of all of the expressions,
1489
1486
// so they can be restored in case of failure.
1490
1487
DomainMap &Domains;
1491
1488
1492
- ExprCollector (Expr *expr, ConstraintSystem &cs,
1493
- std::queue<Candidate> &container, DomainMap &domains)
1494
- : PrimaryExpr(expr), CS(cs), SubExprs(container), Domains(domains) {}
1489
+ ExprCollector (Expr *expr, ConstraintSystem &cs, DomainMap &domains)
1490
+ : PrimaryExpr(expr), CS(cs), Domains(domains) {}
1495
1491
1496
1492
std::pair<bool , Expr *> walkToExprPre (Expr *expr) override {
1497
1493
// A dictionary expression is just a set of tuples; try to solve ones
@@ -1516,7 +1512,7 @@ void ConstraintSystem::shrink(Expr *expr) {
1516
1512
1517
1513
// Make each of the dictionary elements an independent dictionary,
1518
1514
// such makes it easy to type-check everything separately.
1519
- SubExprs. push (Candidate (CS, dict, isPrimaryExpr));
1515
+ Candidates. push_back (Candidate (CS, dict, isPrimaryExpr));
1520
1516
}
1521
1517
1522
1518
// Don't try to walk into the dictionary.
@@ -1526,7 +1522,7 @@ void ConstraintSystem::shrink(Expr *expr) {
1526
1522
// Consider all of the collections to be candidates,
1527
1523
// FIXME: try to split collections into parts for simplified solving.
1528
1524
if (isa<CollectionExpr>(expr)) {
1529
- SubExprs. push (Candidate (CS, expr, false ));
1525
+ Candidates. push_back (Candidate (CS, expr, false ));
1530
1526
return {false , expr};
1531
1527
}
1532
1528
@@ -1552,7 +1548,7 @@ void ConstraintSystem::shrink(Expr *expr) {
1552
1548
auto func = applyExpr->getFn ();
1553
1549
// Let's record this function application for post-processing
1554
1550
// as well as if it contains overload set, see walkToExprPost.
1555
- ApplyExprs.push ({ applyExpr, isa<OverloadSetRefExpr>(func) });
1551
+ ApplyExprs.push_back ({ applyExpr, isa<OverloadSetRefExpr>(func)});
1556
1552
}
1557
1553
1558
1554
return { true , expr };
@@ -1562,9 +1558,9 @@ void ConstraintSystem::shrink(Expr *expr) {
1562
1558
// If there are sub-expressions to consider and
1563
1559
// contextual type is involved, let's add top-most expression
1564
1560
// to the queue just to make sure that we didn't miss any solutions.
1565
- if (expr == PrimaryExpr && !SubExprs .empty ()) {
1561
+ if (expr == PrimaryExpr && !Candidates .empty ()) {
1566
1562
if (!CS.getContextualType ().isNull ()) {
1567
- SubExprs. push (Candidate (CS, expr, true ));
1563
+ Candidates. push_back (Candidate (CS, expr, true ));
1568
1564
return expr;
1569
1565
}
1570
1566
}
@@ -1575,17 +1571,17 @@ void ConstraintSystem::shrink(Expr *expr) {
1575
1571
unsigned numOverloadSets = 0 ;
1576
1572
// Let's count how many overload sets do we have.
1577
1573
while (!ApplyExprs.empty ()) {
1578
- auto application = ApplyExprs.top ();
1574
+ auto & application = ApplyExprs.back ();
1579
1575
auto applyExpr = application.first ;
1580
1576
1581
1577
// Add overload sets tracked by current expression.
1582
1578
numOverloadSets += application.second ;
1583
- ApplyExprs.pop ();
1579
+ ApplyExprs.pop_back ();
1584
1580
1585
1581
// We've found the current expression, so record the number of
1586
1582
// overloads.
1587
1583
if (expr == applyExpr) {
1588
- ApplyExprs.push ({ applyExpr, numOverloadSets });
1584
+ ApplyExprs.push_back ({ applyExpr, numOverloadSets});
1589
1585
break ;
1590
1586
}
1591
1587
}
@@ -1594,22 +1590,19 @@ void ConstraintSystem::shrink(Expr *expr) {
1594
1590
// there is no point of solving this expression,
1595
1591
// because we won't be able to reduce its domain.
1596
1592
if (numOverloadSets > 1 )
1597
- SubExprs. push (Candidate (CS, expr, expr == PrimaryExpr));
1593
+ Candidates. push_back (Candidate (CS, expr, expr == PrimaryExpr));
1598
1594
1599
1595
return expr;
1600
1596
}
1601
1597
};
1602
1598
1603
- std::queue<Candidate> expressions;
1604
- ExprCollector collector (expr, *this , expressions, domains);
1599
+ ExprCollector collector (expr, *this , domains);
1605
1600
1606
1601
// Collect all of the binary/unary and call sub-expressions
1607
1602
// so we can start solving them separately.
1608
1603
expr->walk (collector);
1609
1604
1610
- while (!expressions.empty ()) {
1611
- auto &candidate = expressions.front ();
1612
-
1605
+ for (auto &candidate : collector.Candidates ) {
1613
1606
// If there are no results, let's forget everything we know about the
1614
1607
// system so far. This actually is ok, because some of the expressions
1615
1608
// might require manual salvaging.
@@ -1629,8 +1622,6 @@ void ConstraintSystem::shrink(Expr *expr) {
1629
1622
return childExpr;
1630
1623
});
1631
1624
}
1632
-
1633
- expressions.pop ();
1634
1625
}
1635
1626
}
1636
1627
0 commit comments