@@ -5356,6 +5356,53 @@ static void collapseSameTypeComponentsThroughDelayedRequirements(
5356
5356
collapsedParents.end ());
5357
5357
}
5358
5358
5359
+ // / Check whether two potential archetypes "structurally" match, e.g.,
5360
+ // / the names match up to the root (which must match).
5361
+ static bool potentialArchetypesStructurallyMatch (PotentialArchetype *pa1,
5362
+ PotentialArchetype *pa2) {
5363
+ auto parent1 = pa1->getParent ();
5364
+ auto parent2 = pa2->getParent ();
5365
+ if (!parent1 && !parent2)
5366
+ return pa1->getGenericParamKey () == pa2->getGenericParamKey ();
5367
+
5368
+ // Check for depth mismatch.
5369
+ if (static_cast <bool >(parent1) != static_cast <bool >(parent2))
5370
+ return false ;
5371
+
5372
+ // Check names.
5373
+ if (pa1->getNestedName () != pa2->getNestedName ())
5374
+ return false ;
5375
+
5376
+ return potentialArchetypesStructurallyMatch (parent1, parent2);
5377
+ }
5378
+
5379
+ // / Look for structurally-equivalent types within the given equivalence class,
5380
+ // / collapsing their components.
5381
+ static void collapseStructurallyEquivalentSameTypeComponents (
5382
+ EquivalenceClass *equivClass,
5383
+ llvm::SmallDenseMap<PotentialArchetype *, unsigned > &componentOf,
5384
+ SmallVectorImpl<unsigned > &collapsedParents,
5385
+ unsigned &remainingComponents) {
5386
+ for (unsigned i : indices (equivClass->members )) {
5387
+ auto pa1 = equivClass->members [i];
5388
+ auto rep1 = findRepresentative (collapsedParents, componentOf[pa1]);
5389
+ for (unsigned j : indices (equivClass->members ).slice (i + 1 )) {
5390
+ auto pa2 = equivClass->members [j];
5391
+ auto rep2 = findRepresentative (collapsedParents, componentOf[pa2]);
5392
+ if (rep1 == rep2) continue ;
5393
+
5394
+ auto depth = pa1->getNestingDepth ();
5395
+ if (depth < 2 || depth != pa2->getNestingDepth ()) continue ;
5396
+
5397
+ if (potentialArchetypesStructurallyMatch (pa1, pa2) &&
5398
+ unionSets (collapsedParents, rep1, rep2)) {
5399
+ --remainingComponents;
5400
+ rep1 = findRepresentative (collapsedParents, componentOf[pa1]);
5401
+ }
5402
+ }
5403
+ }
5404
+ }
5405
+
5359
5406
// / Collapse same-type components within an equivalence class, minimizing the
5360
5407
// / number of requirements required to express the equivalence class.
5361
5408
static void collapseSameTypeComponents (
@@ -5410,9 +5457,19 @@ static void collapseSameTypeComponents(
5410
5457
--remainingComponents;
5411
5458
}
5412
5459
5413
- // Collapse same-type components by looking at the delayed requirements.
5414
- collapseSameTypeComponentsThroughDelayedRequirements (
5460
+ if (remainingComponents > 1 ) {
5461
+ // Collapse same-type components by looking at the delayed requirements.
5462
+ collapseSameTypeComponentsThroughDelayedRequirements (
5415
5463
builder, equivClass, componentOf, collapsedParents, remainingComponents);
5464
+ }
5465
+
5466
+ if (remainingComponents > 1 ) {
5467
+ // Collapse structurally-equivalent components.
5468
+ collapseStructurallyEquivalentSameTypeComponents (equivClass,
5469
+ componentOf,
5470
+ collapsedParents,
5471
+ remainingComponents);
5472
+ }
5416
5473
5417
5474
// If needed, collapse the same-type components merged by a derived
5418
5475
// nested-type-name-match edge.
0 commit comments