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
@@ -1335,321 +1333,6 @@ ConstraintSystem::solveSingle(FreeTypeVariableBinding allowFreeTypeVariables) {
1335
1333
return std::move (solutions[0 ]);
1336
1334
}
1337
1335
1338
- bool ConstraintSystem::Candidate::solve () {
1339
- // Cleanup after constraint system generation/solving,
1340
- // because it would assign types to expressions, which
1341
- // might interfere with solving higher-level expressions.
1342
- ExprCleaner cleaner (E);
1343
-
1344
- // Allocate new constraint system for sub-expression.
1345
- ConstraintSystem cs (TC, DC, None);
1346
-
1347
- // Set contextual type if present. This is done before constraint generation
1348
- // to give a "hint" to that operation about possible optimizations.
1349
- if (!CT.isNull ())
1350
- cs.setContextualType (E, CT, CTP);
1351
-
1352
- // Generate constraints for the new system.
1353
- if (auto generatedExpr = cs.generateConstraints (E)) {
1354
- E = generatedExpr;
1355
- } else {
1356
- // Failure to generate constraint system for sub-expression means we can't
1357
- // continue solving sub-expressions.
1358
- return true ;
1359
- }
1360
-
1361
- // If there is contextual type present, add an explicit "conversion"
1362
- // constraint to the system.
1363
- if (!CT.isNull ()) {
1364
- auto constraintKind = ConstraintKind::Conversion;
1365
- if (CTP == CTP_CallArgument)
1366
- constraintKind = ConstraintKind::ArgumentConversion;
1367
-
1368
- cs.addConstraint (constraintKind, E->getType (), CT.getType (),
1369
- cs.getConstraintLocator (E), /* isFavored=*/ true );
1370
- }
1371
-
1372
- // Try to solve the system and record all available solutions.
1373
- llvm::SmallVector<Solution, 2 > solutions;
1374
- {
1375
- SolverState state (cs);
1376
- cs.solverState = &state;
1377
-
1378
- // Use solveRec() instead of solve() in here, because solve()
1379
- // would try to deduce the best solution, which we don't
1380
- // really want. Instead, we want the reduced set of domain choices.
1381
- cs.solveRec (solutions, FreeTypeVariableBinding::Allow);
1382
-
1383
- cs.solverState = nullptr ;
1384
- }
1385
-
1386
- // No solutions for the sub-expression means that either main expression
1387
- // needs salvaging or it's inconsistent (read: doesn't have solutions).
1388
- if (solutions.empty ())
1389
- return true ;
1390
-
1391
- // Record found solutions as suggestions.
1392
- this ->applySolutions (solutions);
1393
- return false ;
1394
- }
1395
-
1396
- void ConstraintSystem::Candidate::applySolutions (
1397
- llvm::SmallVectorImpl<Solution> &solutions) const {
1398
- // A collection of OSRs with their newly reduced domains,
1399
- // it's domains are sets because multiple solutions can have the same
1400
- // choice for one of the type variables, and we want no duplication.
1401
- llvm::SmallDenseMap<OverloadSetRefExpr *, llvm::SmallSet<ValueDecl *, 2 >>
1402
- domains;
1403
- for (auto &solution : solutions) {
1404
- for (auto choice : solution.overloadChoices ) {
1405
- // Some of the choices might not have locators.
1406
- if (!choice.getFirst ())
1407
- continue ;
1408
-
1409
- auto anchor = choice.getFirst ()->getAnchor ();
1410
- // Anchor is not available or expression is not an overload set.
1411
- if (!anchor || !isa<OverloadSetRefExpr>(anchor))
1412
- continue ;
1413
-
1414
- auto OSR = cast<OverloadSetRefExpr>(anchor);
1415
- auto overload = choice.getSecond ().choice ;
1416
- auto type = overload.getDecl ()->getInterfaceType ();
1417
-
1418
- // One of the solutions has polymorphic type assigned with one of it's
1419
- // type variables. Such functions can only be properly resolved
1420
- // via complete expression, so we'll have to forget solutions
1421
- // we have already recorded. They might not include all viable overload
1422
- // choices.
1423
- if (type->is <GenericFunctionType>()) {
1424
- return ;
1425
- }
1426
-
1427
- domains[OSR].insert (overload.getDecl ());
1428
- }
1429
- }
1430
-
1431
- // Reduce the domains.
1432
- for (auto &domain : domains) {
1433
- auto OSR = domain.getFirst ();
1434
- auto &choices = domain.getSecond ();
1435
-
1436
- // If the domain wasn't reduced, skip it.
1437
- if (OSR->getDecls ().size () == choices.size ()) continue ;
1438
-
1439
- // Update the expression with the reduced domain.
1440
- MutableArrayRef<ValueDecl *> decls
1441
- = TC.Context .AllocateUninitialized <ValueDecl *>(choices.size ());
1442
- std::uninitialized_copy (choices.begin (), choices.end (), decls.begin ());
1443
- OSR->setDecls (decls);
1444
- }
1445
- }
1446
-
1447
- void ConstraintSystem::shrink (Expr *expr) {
1448
- typedef llvm::SmallDenseMap<Expr *, ArrayRef<ValueDecl *>> DomainMap;
1449
-
1450
- // A collection of original domains of all of the expressions,
1451
- // so they can be restored in case of failure.
1452
- DomainMap domains;
1453
-
1454
- struct ExprCollector : public ASTWalker {
1455
- // The primary constraint system.
1456
- ConstraintSystem &CS;
1457
-
1458
- // All of the sub-expressions of certain type (binary/unary/calls) in
1459
- // depth-first order.
1460
- std::queue<Candidate> &SubExprs;
1461
-
1462
- // Counts the number of overload sets present in the tree so far.
1463
- // Note that the traversal is depth-first.
1464
- std::stack<std::pair<ApplyExpr *, unsigned >,
1465
- llvm::SmallVector<std::pair<ApplyExpr *, unsigned >, 4 >>
1466
- ApplyExprs;
1467
-
1468
- // A collection of original domains of all of the expressions,
1469
- // so they can be restored in case of failure.
1470
- DomainMap &Domains;
1471
-
1472
- ExprCollector (ConstraintSystem &cs,
1473
- std::queue<Candidate> &container,
1474
- DomainMap &domains)
1475
- : CS(cs), SubExprs(container), Domains(domains) { }
1476
-
1477
- std::pair<bool , Expr *> walkToExprPre (Expr *expr) override {
1478
- // A dictionary expression is just a set of tuples; try to solve ones
1479
- // that have overload sets.
1480
- if (auto dictionaryExpr = dyn_cast<DictionaryExpr>(expr)) {
1481
- for (auto element : dictionaryExpr->getElements ()) {
1482
- unsigned numOverlaods = 0 ;
1483
- element->walk (OverloadSetCounter (numOverlaods));
1484
-
1485
- // There are no overload sets in the element; skip it.
1486
- if (numOverlaods == 0 )
1487
- continue ;
1488
-
1489
- // FIXME: Could we avoid creating a separate dictionary expression
1490
- // here by introducing a contextual type on the element?
1491
- auto dict = DictionaryExpr::create (CS.getASTContext (),
1492
- dictionaryExpr->getLBracketLoc (),
1493
- { element },
1494
- dictionaryExpr->getRBracketLoc (),
1495
- dictionaryExpr->getType ());
1496
-
1497
- // Make each of the dictionary elements an independent dictionary,
1498
- // such makes it easy to type-check everything separately.
1499
- SubExprs.push (Candidate (CS, dict));
1500
- }
1501
-
1502
- // Don't try to walk into the dictionary.
1503
- return { false , expr };
1504
- }
1505
-
1506
- // Let's not attempt to type-check closures or default values,
1507
- // which has already been type checked anyway.
1508
- if (isa<ClosureExpr>(expr) || isa<DefaultValueExpr>(expr)) {
1509
- return { false , expr };
1510
- }
1511
-
1512
- // Coerce to type expressions are only viable if they have
1513
- // a single child expression.
1514
- if (auto coerceExpr = dyn_cast<CoerceExpr>(expr)) {
1515
- if (!coerceExpr->getSubExpr ()) {
1516
- return { false , expr };
1517
- }
1518
- }
1519
-
1520
- if (auto OSR = dyn_cast<OverloadSetRefExpr>(expr)) {
1521
- Domains[OSR] = OSR->getDecls ();
1522
- }
1523
-
1524
- if (auto applyExpr = dyn_cast<ApplyExpr>(expr)) {
1525
- auto func = applyExpr->getFn ();
1526
- // Let's record this function application for post-processing
1527
- // as well as if it contains overload set, see walkToExprPost.
1528
- ApplyExprs.push ({ applyExpr, isa<OverloadSetRefExpr>(func) });
1529
- }
1530
-
1531
- return { true , expr };
1532
- }
1533
-
1534
- Expr *walkToExprPost (Expr *expr) override {
1535
- if (!isa<ApplyExpr>(expr))
1536
- return expr;
1537
-
1538
- unsigned numOverloadSets = 0 ;
1539
- // Let's count how many overload sets do we have.
1540
- while (!ApplyExprs.empty ()) {
1541
- auto application = ApplyExprs.top ();
1542
- auto applyExpr = application.first ;
1543
-
1544
- // Add overload sets tracked by current expression.
1545
- numOverloadSets += application.second ;
1546
- ApplyExprs.pop ();
1547
-
1548
- // We've found the current expression, so record the number of
1549
- // overloads.
1550
- if (expr == applyExpr) {
1551
- ApplyExprs.push ({ applyExpr, numOverloadSets });
1552
- break ;
1553
- }
1554
- }
1555
-
1556
- // If there are fewer than two overloads in the chain
1557
- // there is no point of solving this expression,
1558
- // because we won't be able to reduce it's domain.
1559
- if (numOverloadSets > 1 )
1560
- SubExprs.push (Candidate (CS, expr));
1561
-
1562
- return expr;
1563
- }
1564
- };
1565
-
1566
- std::queue<Candidate> expressions;
1567
- ExprCollector collector (*this , expressions, domains);
1568
-
1569
- // Collect all of the binary/unary and call sub-expressions
1570
- // so we can start solving them separately.
1571
- expr->walk (collector);
1572
-
1573
- while (!expressions.empty ()) {
1574
- auto &candidate = expressions.front ();
1575
-
1576
- // If there are no results, let's forget everything we know about the
1577
- // system so far. This actually is ok, because some of the expressions
1578
- // might require manual salvaging.
1579
- if (candidate.solve ()) {
1580
- // Let's restore all of the original OSR domains.
1581
- for (auto &domain : domains) {
1582
- if (auto OSR = dyn_cast<OverloadSetRefExpr>(domain.getFirst ())) {
1583
- OSR->setDecls (domain.getSecond ());
1584
- }
1585
- }
1586
- break ;
1587
- }
1588
-
1589
- expressions.pop ();
1590
- }
1591
- }
1592
-
1593
- ConstraintSystem::SolutionKind
1594
- ConstraintSystem::solve (Expr *&expr,
1595
- Type convertType,
1596
- ExprTypeCheckListener *listener,
1597
- SmallVectorImpl<Solution> &solutions,
1598
- FreeTypeVariableBinding allowFreeTypeVariables) {
1599
- assert (!solverState && " use solveRec for recursive calls" );
1600
-
1601
- // Try to shrink the system by reducing disjunction domains. This
1602
- // goes through every sub-expression and generate it's own sub-system, to
1603
- // try to reduce the domains of those subexpressions.
1604
- shrink (expr);
1605
-
1606
- // Generate constraints for the main system.
1607
- if (auto generatedExpr = generateConstraints (expr))
1608
- expr = generatedExpr;
1609
- else {
1610
- return SolutionKind::Error;
1611
- }
1612
-
1613
- // If there is a type that we're expected to convert to, add the conversion
1614
- // constraint.
1615
- if (convertType) {
1616
- auto constraintKind = ConstraintKind::Conversion;
1617
- if (getContextualTypePurpose () == CTP_CallArgument)
1618
- constraintKind = ConstraintKind::ArgumentConversion;
1619
-
1620
- if (allowFreeTypeVariables == FreeTypeVariableBinding::UnresolvedType) {
1621
- convertType = convertType.transform ([&](Type type) -> Type {
1622
- if (type->is <UnresolvedType>())
1623
- return createTypeVariable (getConstraintLocator (expr), 0 );
1624
- return type;
1625
- });
1626
- }
1627
-
1628
- addConstraint (constraintKind, expr->getType (), convertType,
1629
- getConstraintLocator (expr), /* isFavored*/ true );
1630
- }
1631
-
1632
- // Notify the listener that we've built the constraint system.
1633
- if (listener && listener->builtConstraints (*this , expr)) {
1634
- return SolutionKind::Error;
1635
- }
1636
-
1637
- if (TC.getLangOpts ().DebugConstraintSolver ) {
1638
- auto &log = getASTContext ().TypeCheckerDebug ->getStream ();
1639
- log << " ---Initial constraints for the given expression---\n " ;
1640
- expr->print (log);
1641
- log << " \n " ;
1642
- print (log);
1643
- }
1644
-
1645
- // Try to solve the constraint system using computed suggestions.
1646
- solve (solutions, allowFreeTypeVariables);
1647
-
1648
- // If there are no solutions let's mark system as unsolved,
1649
- // and solved otherwise even if there are multiple solutions still present.
1650
- return solutions.empty () ? SolutionKind::Unsolved : SolutionKind::Solved;
1651
- }
1652
-
1653
1336
bool ConstraintSystem::solve (SmallVectorImpl<Solution> &solutions,
1654
1337
FreeTypeVariableBinding allowFreeTypeVariables) {
1655
1338
assert (!solverState && " use solveRec for recursive calls" );
@@ -1673,7 +1356,7 @@ bool ConstraintSystem::solve(SmallVectorImpl<Solution> &solutions,
1673
1356
1674
1357
// Remove the solver state.
1675
1358
this ->solverState = nullptr ;
1676
-
1359
+
1677
1360
// We fail if there is no solution.
1678
1361
return solutions.empty ();
1679
1362
}
0 commit comments