@@ -1546,26 +1546,35 @@ static int compareAssociatedTypes(AssociatedTypeDecl *assocType1,
1546
1546
return 0 ;
1547
1547
}
1548
1548
1549
+ // / Whether there are any concrete type declarations in the potential archetype.
1550
+ static bool hasConcreteDecls (const PotentialArchetype *pa) {
1551
+ auto parent = pa->getParent ();
1552
+ if (!parent) return false ;
1553
+
1554
+ if (pa->getConcreteTypeDecl ())
1555
+ return true ;
1556
+
1557
+ return hasConcreteDecls (parent);
1558
+ }
1559
+
1549
1560
// / Canonical ordering for dependent types in generic signatures.
1550
1561
static int compareDependentTypes (PotentialArchetype * const * pa,
1551
- PotentialArchetype * const * pb) {
1562
+ PotentialArchetype * const * pb,
1563
+ bool outermost) {
1552
1564
auto a = *pa, b = *pb;
1553
1565
1554
1566
// Fast-path check for equality.
1555
1567
if (a == b)
1556
1568
return 0 ;
1557
1569
1558
- // Concrete types must be ordered *after* everything else, to ensure they
1559
- // don't become representatives in the case where a concrete type is equated
1560
- // with an associated type.
1561
- if (a->getParent () && b->getParent () &&
1562
- !!a->getConcreteTypeDecl () != !!b->getConcreteTypeDecl ())
1563
- return a->getConcreteTypeDecl () ? +1 : -1 ;
1564
-
1565
- // Types that are equivalent to concrete types follow types that are still
1566
- // type parameters.
1567
- if (a->isConcreteType () != b->isConcreteType ())
1568
- return a->isConcreteType () ? +1 : -1 ;
1570
+ // If one has concrete declarations somewhere but the other does not,
1571
+ // prefer the one without concrete declarations.
1572
+ if (outermost) {
1573
+ bool aHasConcreteDecls = hasConcreteDecls (a);
1574
+ bool bHasConcreteDecls = hasConcreteDecls (b);
1575
+ if (aHasConcreteDecls != bHasConcreteDecls)
1576
+ return aHasConcreteDecls ? +1 : -1 ;
1577
+ }
1569
1578
1570
1579
// Ordering is as follows:
1571
1580
// - Generic params
@@ -1581,9 +1590,21 @@ static int compareDependentTypes(PotentialArchetype * const* pa,
1581
1590
auto ppb = b->getParent ();
1582
1591
1583
1592
// - by base, so t_0_n.`P.T` < t_1_m.`P.T`
1584
- if (int compareBases = compareDependentTypes (&ppa, &ppb))
1593
+ if (int compareBases = compareDependentTypes (&ppa, &ppb, /* outermost= */ false ))
1585
1594
return compareBases;
1586
1595
1596
+ // Types that are equivalent to concrete types follow types that are still
1597
+ // type parameters.
1598
+ if (a->isConcreteType () != b->isConcreteType ())
1599
+ return a->isConcreteType () ? +1 : -1 ;
1600
+
1601
+ // Concrete types must be ordered *after* everything else, to ensure they
1602
+ // don't become representatives in the case where a concrete type is equated
1603
+ // with an associated type.
1604
+ if (a->getParent () && b->getParent () &&
1605
+ !!a->getConcreteTypeDecl () != !!b->getConcreteTypeDecl ())
1606
+ return a->getConcreteTypeDecl () ? +1 : -1 ;
1607
+
1587
1608
// - by name, so t_n_m.`P.T` < t_n_m.`P.U`
1588
1609
if (int compareNames = a->getNestedName ().str ().compare (
1589
1610
b->getNestedName ().str ()))
@@ -1627,6 +1648,11 @@ static int compareDependentTypes(PotentialArchetype * const* pa,
1627
1648
llvm_unreachable (" potential archetype total order failure" );
1628
1649
}
1629
1650
1651
+ static int compareDependentTypes (PotentialArchetype * const * pa,
1652
+ PotentialArchetype * const * pb) {
1653
+ return compareDependentTypes (pa, pb, /* outermost=*/ true );
1654
+ }
1655
+
1630
1656
PotentialArchetype *PotentialArchetype::getArchetypeAnchor (
1631
1657
GenericSignatureBuilder &builder) {
1632
1658
// Find the best archetype within this equivalence class.
@@ -1635,6 +1661,7 @@ PotentialArchetype *PotentialArchetype::getArchetypeAnchor(
1635
1661
if (auto parent = getParent ()) {
1636
1662
// For a nested type, retrieve the parent archetype anchor first.
1637
1663
auto parentAnchor = parent->getArchetypeAnchor (builder);
1664
+ assert (parentAnchor->getNestingDepth () <= parent->getNestingDepth ());
1638
1665
anchor = parentAnchor->getNestedArchetypeAnchor (
1639
1666
getNestedName (), builder,
1640
1667
ArchetypeResolutionKind::AlreadyKnown);
@@ -1654,7 +1681,8 @@ PotentialArchetype *PotentialArchetype::getArchetypeAnchor(
1654
1681
equivClass->archetypeAnchorCache .numMembers
1655
1682
== equivClass->members .size ()) {
1656
1683
++NumArchetypeAnchorCacheHits;
1657
-
1684
+ assert (equivClass->archetypeAnchorCache .anchor ->getNestingDepth ()
1685
+ <= rep->getNestingDepth ());
1658
1686
return equivClass->archetypeAnchorCache .anchor ;
1659
1687
}
1660
1688
@@ -1673,6 +1701,8 @@ PotentialArchetype *PotentialArchetype::getArchetypeAnchor(
1673
1701
}
1674
1702
#endif
1675
1703
1704
+ assert (anchor->getNestingDepth () <= rep->getNestingDepth ());
1705
+
1676
1706
// Record the cache miss and update the cache.
1677
1707
++NumArchetypeAnchorCacheMisses;
1678
1708
equivClass->archetypeAnchorCache .anchor = anchor;
@@ -3300,10 +3330,15 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
3300
3330
if (T1 == T2)
3301
3331
return ConstraintResult::Resolved;
3302
3332
3333
+ unsigned nestingDepth1 = T1->getNestingDepth ();
3334
+ unsigned nestingDepth2 = T2->getNestingDepth ();
3335
+
3303
3336
// Decide which potential archetype is to be considered the representative.
3304
- // It doesn't specifically matter which we use, but it's a minor optimization
3305
- // to prefer the canonical type.
3306
- if (compareDependentTypes (&T2, &T1) < 0 ) {
3337
+ // We prefer potential archetypes with lower nesting depths (because it
3338
+ // prevents us from unnecessarily building deeply nested potential archetypes)
3339
+ // and prefer anchors because it's a minor optimization.
3340
+ if (nestingDepth2 < nestingDepth1 ||
3341
+ compareDependentTypes (&T2, &T1) < 0 ) {
3307
3342
std::swap (T1, T2);
3308
3343
std::swap (OrigT1, OrigT2);
3309
3344
}
0 commit comments