@@ -2149,19 +2149,42 @@ Type EquivalenceClass::getAnchor(
2149
2149
}
2150
2150
2151
2151
// Form the anchor.
2152
+ bool updatedAnchor = false ;
2152
2153
for (auto member : members) {
2153
2154
auto anchorType =
2154
2155
builder.getCanonicalTypeParameter (member->getDependentType (genericParams));
2155
2156
if (!anchorType) continue ;
2156
2157
2158
+ #ifndef NDEBUG
2159
+ // Check that we get consistent results from all of the anchors.
2160
+ if (updatedAnchor) {
2161
+ assert (anchorType->isEqual (archetypeAnchorCache.anchor ) &&
2162
+ " Inconsistent anchor computation" );
2163
+ continue ;
2164
+ }
2165
+ #endif
2166
+
2157
2167
// Record the cache miss and update the cache.
2158
2168
++NumArchetypeAnchorCacheMisses;
2159
2169
archetypeAnchorCache.anchor = anchorType;
2160
2170
archetypeAnchorCache.lastGeneration = builder.Impl ->Generation ;
2161
- return substAnchor ();
2171
+ updatedAnchor = true ;
2172
+
2173
+ #if NDEBUG
2174
+ break ;
2175
+ #endif
2162
2176
}
2163
2177
2164
- llvm_unreachable (" Unable to compute anchor" );
2178
+ // FIXME: Once we are no longer constructing potential archetypes with
2179
+ // concrete nested types, we can turn this into assert(updatedAnchor);
2180
+ if (!updatedAnchor) {
2181
+ ++NumArchetypeAnchorCacheMisses;
2182
+ archetypeAnchorCache.anchor =
2183
+ builder.getCanonicalTypeParameter (members.front ()->getDependentType ({ }));
2184
+ archetypeAnchorCache.lastGeneration = builder.Impl ->Generation ;
2185
+ }
2186
+
2187
+ return substAnchor ();
2165
2188
}
2166
2189
2167
2190
Type EquivalenceClass::getTypeInContext (GenericSignatureBuilder &builder,
@@ -3401,39 +3424,29 @@ GenericSignatureBuilder::Implementation::getOrCreateRewriteTreeRoot(
3401
3424
return root;
3402
3425
}
3403
3426
3404
- void GenericSignatureBuilder::addSameTypeRewriteRule (PotentialArchetype *pa1,
3405
- PotentialArchetype *pa2){
3406
- auto pathOpt1 = RewritePath::createPath (pa1);
3407
- if (!pathOpt1) return ;
3408
-
3409
- auto pathOpt2 = RewritePath::createPath (pa2);
3410
- if (!pathOpt2) return ;
3411
-
3412
- auto path1 = std::move (pathOpt1).getValue ();
3413
- auto path2 = std::move (pathOpt2).getValue ();
3427
+ void GenericSignatureBuilder::addSameTypeRewriteRule (
3428
+ EquivalenceClass *equivClass,
3429
+ PotentialArchetype *otherPA){
3430
+ // Simplify both sides in the hope of uncovering a common path.
3431
+ Type simplifiedType1 = equivClass->getAnchor (*this , { });
3432
+ if (!simplifiedType1) return ;
3414
3433
3415
- // Look for a common path.
3416
- auto prefix = path1.commonPath (path2);
3417
-
3418
- // If we didn't find a common path, try harder.
3419
- Type simplifiedType1;
3420
3434
Type simplifiedType2;
3421
- if (!prefix) {
3422
- // Simplify both sides in the hope of uncovering a common path.
3423
- simplifiedType1 = getCanonicalTypeParameter (pa1-> getDependentType ({ }));
3424
- simplifiedType2 = getCanonicalTypeParameter (pa2 ->getDependentType ({ }));
3425
- if (simplifiedType1-> isEqual ( simplifiedType2) ) return ;
3435
+ if (auto otherEquivClass = otherPA-> getEquivalenceClassIfPresent ())
3436
+ simplifiedType2 = otherEquivClass-> getAnchor (* this , { });
3437
+ else
3438
+ simplifiedType2 = getCanonicalTypeParameter (otherPA ->getDependentType ({ }));
3439
+ if (! simplifiedType2) return ;
3426
3440
3427
- // Create new paths from the simplified types.
3428
- path1 = *RewritePath::createPath (simplifiedType1);
3429
- path2 = *RewritePath::createPath (simplifiedType2);
3441
+ // We already effectively have this rewrite rule.
3442
+ if (simplifiedType1->isEqual (simplifiedType2)) return ;
3430
3443
3431
- // Find a common path.
3432
- prefix = path1.commonPath (path2);
3433
- }
3444
+ auto path1 = *RewritePath::createPath (simplifiedType1);
3445
+ auto path2 = *RewritePath::createPath (simplifiedType2);
3434
3446
3435
- // When we have a common prefix, form a rewrite rule using relative paths.
3436
- if (prefix) {
3447
+ // Look for a common prefix. When we have one, form a rewrite rule using
3448
+ // relative paths.
3449
+ if (auto prefix = path1.commonPath (path2)) {
3437
3450
// Find the better relative rewrite path.
3438
3451
RelativeRewritePath relPath1
3439
3452
= path1.getPath ().slice (prefix->getPath ().size ());
@@ -3469,11 +3482,11 @@ void GenericSignatureBuilder::addSameTypeRewriteRule(PotentialArchetype *pa1,
3469
3482
Type firstBase =
3470
3483
GenericTypeParamType::get (path1.getBase ()->Depth , path1.getBase ()->Index ,
3471
3484
getASTContext ());
3472
- auto equivClass =
3485
+ auto baseEquivClass =
3473
3486
resolveEquivalenceClass (firstBase, ArchetypeResolutionKind::WellFormed);
3474
- assert (equivClass && " Base cannot be resolved?" );
3487
+ assert (baseEquivClass && " Base cannot be resolved?" );
3475
3488
3476
- auto root = Impl->getOrCreateRewriteTreeRoot (equivClass );
3489
+ auto root = Impl->getOrCreateRewriteTreeRoot (baseEquivClass );
3477
3490
root->addRewriteRule (path1.getPath (), path2);
3478
3491
}
3479
3492
@@ -4539,9 +4552,6 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
4539
4552
PotentialArchetype *OrigT2,
4540
4553
const RequirementSource *Source)
4541
4554
{
4542
- // Add a rewrite rule based on the given same-type constraint.
4543
- addSameTypeRewriteRule (OrigT1, OrigT2);
4544
-
4545
4555
// Record the same-type constraint, and bail out if it was already known.
4546
4556
if (!OrigT1->getOrCreateEquivalenceClass (*this )
4547
4557
->recordSameTypeConstraint (OrigT1, OrigT2, Source))
@@ -4561,10 +4571,12 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
4561
4571
std::swap (OrigT1, OrigT2);
4562
4572
}
4563
4573
4564
- // Merge the equivalence classes .
4574
+ // Add a rewrite rule to map T2 down to the anchor .
4565
4575
auto equivClass = T1->getOrCreateEquivalenceClass (*this );
4566
- equivClass-> modified (* this );
4576
+ addSameTypeRewriteRule (equivClass, T2 );
4567
4577
4578
+ // Merge the equivalence classes.
4579
+ equivClass->modified (*this );
4568
4580
auto equivClass1Members = equivClass->members ;
4569
4581
auto equivClass2Members = T2->getEquivalenceClassMembers ();
4570
4582
for (auto equiv : equivClass2Members)
0 commit comments