@@ -1228,8 +1228,7 @@ struct TypeReprCycleCheckWalker : ASTWalker {
1228
1228
bool checkForPotentialCycle (ValueDecl *witness) {
1229
1229
// Don't do this for protocol extension members, because we have a
1230
1230
// mini "solver" that avoids similar issues instead.
1231
- if (witness->getDeclContext ()->getSelfProtocolDecl () != nullptr )
1232
- return false ;
1231
+ assert (!witness->getDeclContext ()->getExtendedProtocolDecl ());
1233
1232
1234
1233
// If we already have an interface type, don't bother trying to
1235
1234
// avoid a cycle.
@@ -1383,12 +1382,9 @@ enum class InferenceCandidateKind {
1383
1382
static InferenceCandidateKind checkInferenceCandidate (
1384
1383
std::pair<AssociatedTypeDecl *, Type> *result,
1385
1384
NormalProtocolConformance *conformance,
1386
- ValueDecl *witness) {
1387
- auto witnessContext = witness->getDeclContext ();
1388
- auto &ctx = witnessContext->getASTContext ();
1389
-
1390
- assert (witnessContext->getExtendedProtocolDecl ());
1391
- auto selfTy = witnessContext->getSelfInterfaceType ();
1385
+ DeclContext *witnessDC,
1386
+ Type selfTy) {
1387
+ auto &ctx = selfTy->getASTContext ();
1392
1388
1393
1389
auto isTautological = [&](Type t) -> bool {
1394
1390
auto dmt = t->getAs <DependentMemberType>();
@@ -1416,17 +1412,16 @@ static InferenceCandidateKind checkInferenceCandidate(
1416
1412
return true ;
1417
1413
};
1418
1414
1415
+ // Self.X == Self.X doesn't give us any new information, nor does it
1416
+ // immediately fail.
1419
1417
if (isTautological (result->second )) {
1420
1418
auto *dmt = result->second ->castTo <DependentMemberType>();
1421
1419
1422
- // If this associated type is same-typed to another associated type
1423
- // on `Self`, then it may still be an interesting candidate if we find
1424
- // an answer for that other type.
1425
- auto selfTy = witnessContext->getSelfInterfaceType ();
1426
- auto selfAssocTy = DependentMemberType::get (selfTy,
1427
- dmt->getAssocType ());
1428
- for (auto &reqt : witnessContext->getGenericSignatureOfContext ()
1429
- .getRequirements ()) {
1420
+ auto selfAssocTy = DependentMemberType::get (selfTy, dmt->getAssocType ());
1421
+
1422
+ // If we have a same-type requirement `Self.X == Self.Y`,
1423
+ // introduce a binding `Self.X := Self.Y`.
1424
+ for (auto &reqt : witnessDC->getGenericSignatureOfContext ().getRequirements ()) {
1430
1425
switch (reqt.getKind ()) {
1431
1426
case RequirementKind::SameShape:
1432
1427
llvm_unreachable (" Same-shape requirement not supported here" );
@@ -1460,8 +1455,6 @@ static InferenceCandidateKind checkInferenceCandidate(
1460
1455
1461
1456
}
1462
1457
1463
- // We may be able to infer one associated type from the
1464
- // other.
1465
1458
result->second = result->second .transform ([&](Type t) -> Type{
1466
1459
if (t->isEqual (dmt))
1467
1460
return otherDMT;
@@ -1479,6 +1472,8 @@ static InferenceCandidateKind checkInferenceCandidate(
1479
1472
return InferenceCandidateKind::Tautological;
1480
1473
}
1481
1474
1475
+ // If we have something like `Self.X := G<Self.X>` on the other hand,
1476
+ // the binding can never be satisfied.
1482
1477
if (result->second .findIf (isTautological))
1483
1478
return InferenceCandidateKind::Infinite;
1484
1479
@@ -1537,6 +1532,10 @@ AssociatedTypeInference::getPotentialTypeWitnessesFromRequirement(
1537
1532
LLVM_DEBUG (llvm::dbgs () << " Inferring associated types from decl:\n " ;
1538
1533
witness->dump (llvm::dbgs ()));
1539
1534
1535
+ // This is the protocol `Self` type if the witness is declared in a protocol
1536
+ // extension, or nullptr.
1537
+ Type selfTy;
1538
+
1540
1539
// If the potential witness came from an extension, and our `Self`
1541
1540
// type can't use it regardless of what associated types we end up
1542
1541
// inferring, skip the witness.
@@ -1545,18 +1544,28 @@ AssociatedTypeInference::getPotentialTypeWitnessesFromRequirement(
1545
1544
LLVM_DEBUG (llvm::dbgs () << " Extension not usable for inference\n " );
1546
1545
continue ;
1547
1546
}
1547
+
1548
+ if (auto *proto = dyn_cast<ProtocolDecl>(extension->getExtendedNominal ()))
1549
+ selfTy = proto->getSelfInterfaceType ();
1548
1550
}
1549
1551
1550
- if (cycleCheck.checkForPotentialCycle (witness)) {
1551
- LLVM_DEBUG (llvm::dbgs () << " Skipping witness to avoid request cycle\n " );
1552
+ if (!selfTy) {
1553
+ if (cycleCheck.checkForPotentialCycle (witness)) {
1554
+ LLVM_DEBUG (llvm::dbgs () << " Skipping witness to avoid request cycle\n " );
1552
1555
1553
- // We must consider the possibility that none of the witnesses for this
1554
- // requirement can be chosen.
1555
- hadTautologicalWitness = true ;
1556
- continue ;
1556
+ // We must consider the possibility that none of the witnesses for this
1557
+ // requirement can be chosen.
1558
+ hadTautologicalWitness = true ;
1559
+ continue ;
1560
+ }
1557
1561
}
1558
1562
1559
- // Try to resolve the type witness via this value witness.
1563
+ // Match the type of the requirement against the type of the witness to
1564
+ // produce a list of bindings. The left-hand side of each binding is an
1565
+ // associated type of our protocol, and the right-hand side is either
1566
+ // a concrete type (possibly containing archetypes of the conforming type)
1567
+ // or a type parameter rooted in the protocol 'Self' type, representing
1568
+ // an unresolved type witness.
1560
1569
auto witnessResult = getPotentialTypeWitnessesByMatchingTypes (req, witness);
1561
1570
1562
1571
// Filter out duplicated inferred types as well as inferred types
@@ -1574,9 +1583,10 @@ AssociatedTypeInference::getPotentialTypeWitnessesFromRequirement(
1574
1583
<< " can infer to:\n " ;
1575
1584
result.second ->dump (llvm::dbgs ()));
1576
1585
1577
- bool fromProtocolExtension =
1578
- witness->getDeclContext ()->getExtendedProtocolDecl ();
1579
- assert (!result.second ->hasTypeParameter () || fromProtocolExtension);
1586
+ assert (!result.second ->hasTypeParameter () || selfTy &&
1587
+ " We should only see unresolved type witnesses on the "
1588
+ " right-hand side of a binding when the value witness came from a "
1589
+ " protocol extension" );
1580
1590
1581
1591
// Filter out errors.
1582
1592
if (result.second ->hasError ()) {
@@ -1595,42 +1605,48 @@ AssociatedTypeInference::getPotentialTypeWitnessesFromRequirement(
1595
1605
REJECT;
1596
1606
}
1597
1607
1598
- if (fromProtocolExtension) {
1599
- // Filter out circular possibilities, e.g. that
1600
- // AssocType == Self.AssocType or
1601
- // AssocType == Foo<Self.AssocType>.
1602
- switch (checkInferenceCandidate (&result, conformance, witness)) {
1608
+ // The type of a potential value witness in a protocol extensions may
1609
+ // itself involve unresolved type witnesses.
1610
+ if (selfTy) {
1611
+ // Handle Self.X := Self.X and Self.X := G<Self.X>.
1612
+ switch (checkInferenceCandidate (&result, conformance,
1613
+ witness->getDeclContext (), selfTy)) {
1603
1614
case InferenceCandidateKind::Good:
1604
- // Continued below .
1615
+ // The "good" case is something like `Self.X := Self.Y` .
1605
1616
break ;
1606
1617
1607
1618
case InferenceCandidateKind::Tautological: {
1608
1619
LLVM_DEBUG (llvm::dbgs () << " -- tautological\n " );
1620
+ // A tautology is the `Self.X := Self.X` case.
1621
+ //
1609
1622
// Skip this binding because it is immediately satisfied.
1610
1623
REJECT;
1611
1624
}
1612
1625
1613
1626
case InferenceCandidateKind::Infinite: {
1614
1627
LLVM_DEBUG (llvm::dbgs () << " -- infinite\n " );
1628
+ // The infinite case is `Self.X := G<Self.X>`.
1629
+ //
1615
1630
// Discard this witness altogether, because it has an unsatisfiable
1616
1631
// binding.
1617
1632
goto next_witness;
1618
1633
}
1619
1634
}
1620
1635
}
1621
1636
1622
- // Check that the binding doesn't contradict an explicitly-given type
1623
- // witness. If it does contradict, throw out the witness completely.
1637
+ // Check that the binding doesn't contradict a type witness previously
1638
+ // resolved via name lookup.
1639
+ //
1640
+ // If it does contradict, throw out the witness entirely.
1624
1641
if (!allUnresolved.count (result.first )) {
1625
1642
auto existingWitness =
1626
1643
conformance->getTypeWitness (result.first );
1627
1644
existingWitness = dc->mapTypeIntoContext (existingWitness);
1628
1645
1629
- // If the deduced type contains an irreducible
1630
- // DependentMemberType, that indicates a dependency
1631
- // on another associated type we haven't deduced,
1632
- // so we can't tell whether there's a contradiction
1633
- // yet.
1646
+ // For now, only a fully-concrete binding can contradict an existing
1647
+ // type witness.
1648
+ //
1649
+ // FIXME: Generate new constraints by matching the two types.
1634
1650
auto newWitness = result.second ->getCanonicalType ();
1635
1651
if (!newWitness->hasTypeParameter () &&
1636
1652
!newWitness->hasDependentMember () &&
@@ -1641,8 +1657,8 @@ AssociatedTypeInference::getPotentialTypeWitnessesFromRequirement(
1641
1657
}
1642
1658
}
1643
1659
1644
- // Check that the type witness meets the requirements on the
1645
- // associated type.
1660
+ // Check that the potential type witness satisfies the local requirements
1661
+ // imposed upon the associated type.
1646
1662
if (auto failed =
1647
1663
checkTypeWitness (result.second , result.first , conformance)) {
1648
1664
witnessResult.NonViable .push_back (
@@ -1661,15 +1677,15 @@ AssociatedTypeInference::getPotentialTypeWitnessesFromRequirement(
1661
1677
#undef REJECT
1662
1678
1663
1679
// If no viable or non-viable bindings remain, the witness does not
1664
- // inter anything new, nor contradict any existing bindings. We collapse
1665
- // all tautological witnesses into a single element of the disjunction.
1680
+ // give us anything new or contradict any existing bindings. We collapse
1681
+ // all tautological witnesses into a single disjunction term .
1666
1682
if (witnessResult.Inferred .empty () && witnessResult.NonViable .empty ()) {
1667
1683
hadTautologicalWitness = true ;
1668
1684
continue ;
1669
1685
}
1670
1686
1671
- // If there were any non-viable inferred associated types, don't
1672
- // infer anything from this witness.
1687
+ // If we had at least one non-viable binding, drop the viable bindings;
1688
+ // we cannot infer anything from this witness.
1673
1689
if (!witnessResult.NonViable .empty ())
1674
1690
witnessResult.Inferred .clear ();
1675
1691
@@ -3627,6 +3643,8 @@ void AssociatedTypeInference::findSolutionsRec(
3627
3643
3628
3644
// If one has a type parameter remaining but the other does not,
3629
3645
// drop the one with the type parameter.
3646
+ //
3647
+ // FIXME: This is too ad-hoc. Generate new constraints instead.
3630
3648
if ((known->first ->hasTypeParameter () ||
3631
3649
known->first ->hasDependentMember ())
3632
3650
!= (typeWitness.second ->hasTypeParameter () ||
0 commit comments