@@ -1361,6 +1361,215 @@ static Constraint *selectBestBindingDisjunction(
1361
1361
return firstBindDisjunction;
1362
1362
}
1363
1363
1364
+ // For a given type, determine if it's either a concrete type, the
1365
+ // result of converting from a concrete type, or a type variable known
1366
+ // to conform to other types (or the result of converting from such a
1367
+ // type variable).
1368
+ static bool havePotentialTypesOrLiteralConformances (Type ty,
1369
+ ConstraintSystem &cs) {
1370
+ llvm::SmallSet<TypeVariableType *, 4 > visited;
1371
+ llvm::SmallVector<Type, 4 > worklist;
1372
+ worklist.push_back (ty);
1373
+
1374
+ while (!worklist.empty ()) {
1375
+ auto itemTy = worklist.pop_back_val ()->getRValueType ();
1376
+
1377
+ if (!itemTy->is <TypeVariableType>())
1378
+ return true ;
1379
+
1380
+ auto tyvar = itemTy->castTo <TypeVariableType>();
1381
+ if (cs.getFixedType (tyvar))
1382
+ return true ;
1383
+
1384
+ auto *rep = cs.getRepresentative (tyvar);
1385
+
1386
+ // FIXME: This can happen when we have two type variables that are
1387
+ // subtypes of each other. We would ideally merge those type
1388
+ // variables somewhere.
1389
+ if (visited.count (rep))
1390
+ continue ;
1391
+
1392
+ visited.insert (rep);
1393
+
1394
+ // Gather all the constraints involving this type variable, and
1395
+ // then attempt to trace back through each constraint to see if we
1396
+ // can reach a concrete type or a literal.
1397
+
1398
+ llvm::SetVector<Constraint *> constraints;
1399
+ cs.getConstraintGraph ().gatherConstraints (
1400
+ rep, constraints, ConstraintGraph::GatheringKind::EquivalenceClass);
1401
+
1402
+ for (auto *constraint : constraints) {
1403
+ switch (constraint->getKind ()) {
1404
+ case ConstraintKind::LiteralConformsTo:
1405
+ return true ;
1406
+
1407
+ case ConstraintKind::Defaultable:
1408
+ assert (!constraint->getSecondType ()->is <TypeVariableType>());
1409
+ return true ;
1410
+
1411
+ case ConstraintKind::Bind:
1412
+ case ConstraintKind::Equal: {
1413
+ auto firstTy = constraint->getFirstType ();
1414
+ auto secondTy = constraint->getSecondType ();
1415
+ if (firstTy->is <TypeVariableType>()) {
1416
+ auto otherRep =
1417
+ cs.getRepresentative (firstTy->castTo <TypeVariableType>());
1418
+ if (otherRep->isEqual (rep))
1419
+ worklist.push_back (secondTy);
1420
+ }
1421
+ if (secondTy->is <TypeVariableType>()) {
1422
+ auto otherRep =
1423
+ cs.getRepresentative (secondTy->castTo <TypeVariableType>());
1424
+ if (otherRep->isEqual (rep))
1425
+ worklist.push_back (constraint->getFirstType ());
1426
+ }
1427
+ break ;
1428
+ }
1429
+
1430
+ case ConstraintKind::Subtype:
1431
+ case ConstraintKind::OperatorArgumentConversion:
1432
+ case ConstraintKind::ArgumentConversion:
1433
+ case ConstraintKind::Conversion:
1434
+ case ConstraintKind::BridgingConversion:
1435
+ case ConstraintKind::BindParam: {
1436
+ auto secondTy = constraint->getSecondType ();
1437
+ if (secondTy->is <TypeVariableType>()) {
1438
+ auto otherRep =
1439
+ cs.getRepresentative (secondTy->castTo <TypeVariableType>());
1440
+ if (otherRep->isEqual (rep))
1441
+ worklist.push_back (constraint->getFirstType ());
1442
+ }
1443
+ break ;
1444
+ }
1445
+
1446
+ case ConstraintKind::DynamicTypeOf:
1447
+ case ConstraintKind::EscapableFunctionOf: {
1448
+ auto firstTy = constraint->getFirstType ();
1449
+ if (firstTy->is <TypeVariableType>()) {
1450
+ auto otherRep =
1451
+ cs.getRepresentative (firstTy->castTo <TypeVariableType>());
1452
+ if (otherRep->isEqual (rep))
1453
+ worklist.push_back (constraint->getSecondType ());
1454
+ }
1455
+ break ;
1456
+ }
1457
+
1458
+ case ConstraintKind::OptionalObject: {
1459
+ // Get the underlying object type.
1460
+ auto secondTy = constraint->getSecondType ();
1461
+ if (secondTy->is <TypeVariableType>()) {
1462
+ auto otherRep =
1463
+ cs.getRepresentative (secondTy->castTo <TypeVariableType>());
1464
+ if (otherRep->isEqual (rep)) {
1465
+ // See if we can actually determine what the underlying
1466
+ // type is.
1467
+ Type fixedTy;
1468
+ auto firstTy = constraint->getFirstType ();
1469
+ if (!firstTy->is <TypeVariableType>()) {
1470
+ fixedTy = firstTy;
1471
+ } else {
1472
+ fixedTy =
1473
+ cs.getFixedType (firstTy->castTo <TypeVariableType>());
1474
+ }
1475
+ if (fixedTy && fixedTy->getOptionalObjectType ())
1476
+ worklist.push_back (fixedTy->getOptionalObjectType ());
1477
+ }
1478
+ }
1479
+ break ;
1480
+ }
1481
+
1482
+ case ConstraintKind::KeyPathApplication:
1483
+ case ConstraintKind::KeyPath: {
1484
+ auto firstTy = constraint->getFirstType ();
1485
+ if (firstTy->is <TypeVariableType>()) {
1486
+ auto otherRep =
1487
+ cs.getRepresentative (firstTy->castTo <TypeVariableType>());
1488
+ if (otherRep->isEqual (rep))
1489
+ worklist.push_back (constraint->getThirdType ());
1490
+ }
1491
+ break ;
1492
+ }
1493
+
1494
+ case ConstraintKind::BindToPointerType:
1495
+ case ConstraintKind::ValueMember:
1496
+ case ConstraintKind::UnresolvedValueMember:
1497
+ case ConstraintKind::Disjunction:
1498
+ case ConstraintKind::CheckedCast:
1499
+ case ConstraintKind::OpenedExistentialOf:
1500
+ case ConstraintKind::ApplicableFunction:
1501
+ case ConstraintKind::BindOverload:
1502
+ case ConstraintKind::FunctionInput:
1503
+ case ConstraintKind::FunctionResult:
1504
+ case ConstraintKind::SelfObjectOfProtocol:
1505
+ case ConstraintKind::ConformsTo:
1506
+ break ;
1507
+ }
1508
+ }
1509
+ }
1510
+
1511
+ return false ;
1512
+ }
1513
+
1514
+ // Check to see if we know something about the types of all arguments
1515
+ // in the given function type.
1516
+ static bool haveTypeInformationForAllArguments (AnyFunctionType *fnType,
1517
+ ConstraintSystem &cs) {
1518
+ return llvm::all_of (fnType->getParams (), [&](AnyFunctionType::Param param) {
1519
+ return havePotentialTypesOrLiteralConformances (param.getPlainType (), cs);
1520
+ });
1521
+ }
1522
+
1523
+ // Given a type variable representing the RHS of an ApplicableFunction
1524
+ // constraint, attempt to find the disjunction of bind overloads
1525
+ // associated with it. This may return null in cases where have not
1526
+ // yet created a disjunction because we need to resolve a base type,
1527
+ // e.g.: [1].map{ ... } does not have a disjunction until we decide on
1528
+ // a type for [1].
1529
+ static Constraint *getUnboundBindOverloadDisjunction (TypeVariableType *tyvar,
1530
+ ConstraintSystem &cs) {
1531
+ auto *rep = cs.getRepresentative (tyvar);
1532
+ assert (!cs.getFixedType (rep));
1533
+
1534
+ llvm::SetVector<Constraint *> disjunctions;
1535
+ cs.getConstraintGraph ().gatherConstraints (
1536
+ rep, disjunctions, ConstraintGraph::GatheringKind::EquivalenceClass,
1537
+ [](Constraint *match) {
1538
+ return match->getKind () == ConstraintKind::Disjunction &&
1539
+ match->getNestedConstraints ().front ()->getKind () ==
1540
+ ConstraintKind::BindOverload;
1541
+ });
1542
+
1543
+ if (disjunctions.empty ())
1544
+ return nullptr ;
1545
+
1546
+ return disjunctions[0 ];
1547
+ }
1548
+
1549
+ // Find a disjunction associated with an ApplicableFunction constraint
1550
+ // where we have some information about all of the types of in the
1551
+ // function application (even if we only know something about what the
1552
+ // types conform to and not actually a concrete type).
1553
+ Constraint *ConstraintSystem::selectApplyDisjunction () {
1554
+ for (auto &constraint : InactiveConstraints) {
1555
+ if (constraint.getKind () != ConstraintKind::ApplicableFunction)
1556
+ continue ;
1557
+
1558
+ auto *applicable = &constraint;
1559
+ if (haveTypeInformationForAllArguments (
1560
+ applicable->getFirstType ()->castTo <AnyFunctionType>(), *this )) {
1561
+ auto *tyvar = applicable->getSecondType ()->castTo <TypeVariableType>();
1562
+
1563
+ // If we have created the disjunction for this apply, find it.
1564
+ auto *disjunction = getUnboundBindOverloadDisjunction (tyvar, *this );
1565
+ if (disjunction)
1566
+ return disjunction;
1567
+ }
1568
+ }
1569
+
1570
+ return nullptr ;
1571
+ }
1572
+
1364
1573
void ConstraintSystem::partitionDisjunction (
1365
1574
ArrayRef<Constraint *> Choices, SmallVectorImpl<unsigned > &Ordering,
1366
1575
SmallVectorImpl<unsigned > &PartitionBeginning) {
@@ -1386,6 +1595,10 @@ Constraint *ConstraintSystem::selectDisjunction() {
1386
1595
if (auto *disjunction = selectBestBindingDisjunction (*this , disjunctions))
1387
1596
return disjunction;
1388
1597
1598
+ if (getASTContext ().isSwiftVersionAtLeast (5 ))
1599
+ if (auto *disjunction = selectApplyDisjunction ())
1600
+ return disjunction;
1601
+
1389
1602
// Pick the disjunction with the smallest number of active choices.
1390
1603
auto minDisjunction =
1391
1604
std::min_element (disjunctions.begin (), disjunctions.end (),
0 commit comments