@@ -437,9 +437,9 @@ struct GenericSignatureBuilder::Implementation {
437
437
// / Equivalence classes that are not currently being used.
438
438
std::vector<void *> FreeEquivalenceClasses;
439
439
440
- // / The roots of the rewrite tree.
441
- DenseMap< const EquivalenceClass *, std::unique_ptr<RewriteTreeNode>>
442
- RewriteTreeRoots;
440
+ // / The roots of the rewrite tree, keyed on the canonical types of the
441
+ // / anchors.
442
+ DenseMap<CanType, std::unique_ptr<RewriteTreeNode>> RewriteTreeRoots;
443
443
444
444
// / The generation number for the term-rewriting system, which is
445
445
// / increased every time a new rule gets added.
@@ -482,15 +482,12 @@ struct GenericSignatureBuilder::Implementation {
482
482
// / Deallocate the given equivalence class, returning it to the free list.
483
483
void deallocateEquivalenceClass (EquivalenceClass *equivClass);
484
484
485
- // / Retrieve the rewrite tree root for the given equivalence class,
486
- // / if present.
487
- RewriteTreeNode *getRewriteTreeRootIfPresent (
488
- const EquivalenceClass *equivClass);
485
+ // / Retrieve the rewrite tree root for the given anchor type.
486
+ RewriteTreeNode *getRewriteTreeRootIfPresent (CanType anchor);
489
487
490
- // / Retrieve the rewrite tree root for the given equivalence class ,
488
+ // / Retrieve the rewrite tree root for the given anchor type ,
491
489
// / creating it if needed.
492
- RewriteTreeNode *getOrCreateRewriteTreeRoot (
493
- const EquivalenceClass *equivClass);
490
+ RewriteTreeNode *getOrCreateRewriteTreeRoot (CanType anchor);
494
491
495
492
// / Minimize the rewrite tree by minimizing the right-hand sides and
496
493
// / removing redundant rules.
@@ -2493,7 +2490,11 @@ void EquivalenceClass::dump(llvm::raw_ostream &out,
2493
2490
out << " \n " ;
2494
2491
2495
2492
if (builder) {
2496
- if (auto rewriteRoot = builder->Impl ->getRewriteTreeRootIfPresent (this )) {
2493
+ CanType anchorType =
2494
+ const_cast <EquivalenceClass *>(this )->getAnchor (*builder, { })
2495
+ ->getCanonicalType ();
2496
+ if (auto rewriteRoot =
2497
+ builder->Impl ->getRewriteTreeRootIfPresent (anchorType)) {
2497
2498
out << " ---Rewrite tree---\n " ;
2498
2499
rewriteRoot->dump (out);
2499
2500
}
@@ -3543,20 +3544,20 @@ void RewriteTreeNode::dump(llvm::raw_ostream &out, bool lastChild) const {
3543
3544
3544
3545
RewriteTreeNode *
3545
3546
GenericSignatureBuilder::Implementation::getRewriteTreeRootIfPresent (
3546
- const EquivalenceClass *equivClass ) {
3547
- auto known = RewriteTreeRoots.find (equivClass );
3547
+ CanType anchor ) {
3548
+ auto known = RewriteTreeRoots.find (anchor );
3548
3549
if (known != RewriteTreeRoots.end ()) return known->second .get ();
3549
3550
3550
3551
return nullptr ;
3551
3552
}
3552
3553
3553
3554
RewriteTreeNode *
3554
3555
GenericSignatureBuilder::Implementation::getOrCreateRewriteTreeRoot (
3555
- const EquivalenceClass *equivClass ) {
3556
- auto known = RewriteTreeRoots.find (equivClass );
3556
+ CanType anchor ) {
3557
+ auto known = RewriteTreeRoots.find (anchor );
3557
3558
if (known != RewriteTreeRoots.end ()) return known->second .get ();
3558
3559
3559
- auto &root = RewriteTreeRoots[equivClass ];
3560
+ auto &root = RewriteTreeRoots[anchor ];
3560
3561
root = std::unique_ptr<RewriteTreeNode>(new RewriteTreeNode (nullptr ));
3561
3562
return root.get ();
3562
3563
}
@@ -3585,7 +3586,8 @@ void GenericSignatureBuilder::Implementation::minimizeRewriteTreeRhs(
3585
3586
3586
3587
// Minimize the right-hand sides of each rule in the tree.
3587
3588
for (auto &equivClass : EquivalenceClasses) {
3588
- auto root = RewriteTreeRoots.find (&equivClass);
3589
+ CanType anchorType = equivClass.getAnchor (builder, { })->getCanonicalType ();
3590
+ auto root = RewriteTreeRoots.find (anchorType);
3589
3591
if (root == RewriteTreeRoots.end ()) continue ;
3590
3592
3591
3593
AnchorPathCache anchorPathCache (builder, equivClass);
@@ -3640,7 +3642,8 @@ void GenericSignatureBuilder::Implementation::removeRewriteTreeRedundancies(
3640
3642
3641
3643
// Minimize the right-hand sides of each rule in the tree.
3642
3644
for (auto &equivClass : EquivalenceClasses) {
3643
- auto root = RewriteTreeRoots.find (&equivClass);
3645
+ CanType anchorType = equivClass.getAnchor (builder, { })->getCanonicalType ();
3646
+ auto root = RewriteTreeRoots.find (anchorType);
3644
3647
if (root == RewriteTreeRoots.end ()) continue ;
3645
3648
3646
3649
AnchorPathCache anchorPathCache (builder, equivClass);
@@ -3701,14 +3704,13 @@ bool GenericSignatureBuilder::addSameTypeRewriteRule(
3701
3704
if (compareDependentPaths (relPath1, relPath2) < 0 )
3702
3705
std::swap (relPath1, relPath2);
3703
3706
3704
- // Find the equivalence class for the prefix.
3707
+ // Find the anchor for the prefix.
3705
3708
CanType commonType = prefix.formDependentType (getASTContext ());
3706
- auto equivClass =
3707
- resolveEquivalenceClass (commonType, ArchetypeResolutionKind::WellFormed);
3708
- assert (equivClass && " Prefix cannot be resolved?" );
3709
+ CanType commonAnchor =
3710
+ getCanonicalTypeParameter (commonType)->getCanonicalType ();
3709
3711
3710
3712
// Add the rewrite rule.
3711
- auto root = Impl->getOrCreateRewriteTreeRoot (equivClass );
3713
+ auto root = Impl->getOrCreateRewriteTreeRoot (commonAnchor );
3712
3714
return root->addRewriteRule (
3713
3715
relPath1,
3714
3716
RewritePath (None, relPath2, RewritePath::Forward));
@@ -3726,11 +3728,9 @@ bool GenericSignatureBuilder::addSameTypeRewriteRule(
3726
3728
Type firstBase =
3727
3729
GenericTypeParamType::get (path1.getBase ()->Depth , path1.getBase ()->Index ,
3728
3730
getASTContext ());
3729
- auto baseEquivClass =
3730
- resolveEquivalenceClass (firstBase, ArchetypeResolutionKind::WellFormed);
3731
- assert (baseEquivClass && " Base cannot be resolved?" );
3732
-
3733
- auto root = Impl->getOrCreateRewriteTreeRoot (baseEquivClass);
3731
+ CanType baseAnchor =
3732
+ getCanonicalTypeParameter (firstBase)->getCanonicalType ();
3733
+ auto root = Impl->getOrCreateRewriteTreeRoot (baseAnchor);
3734
3734
return root->addRewriteRule (path1.getPath (), path2);
3735
3735
}
3736
3736
@@ -3752,7 +3752,8 @@ Type GenericSignatureBuilder::getCanonicalTypeParameter(Type type) {
3752
3752
initialPath.getPath ().end ());
3753
3753
bool simplified = false ;
3754
3754
do {
3755
- if (auto rootNode = Impl->getRewriteTreeRootIfPresent (equivClass)) {
3755
+ CanType currentAnchor = currentType->getCanonicalType ();
3756
+ if (auto rootNode = Impl->getRewriteTreeRootIfPresent (currentAnchor)) {
3756
3757
// Find the best rewrite rule for the path starting at startIndex.
3757
3758
auto match =
3758
3759
rootNode->bestRewritePath (genericParamType,
@@ -4876,8 +4877,17 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
4876
4877
std::swap (OrigT1, OrigT2);
4877
4878
}
4878
4879
4879
- // Add a rewrite rule to map T2 down to the anchor.
4880
4880
auto equivClass = T1->getOrCreateEquivalenceClass (*this );
4881
+ auto equivClass2 = T2->getEquivalenceClassIfPresent ();
4882
+
4883
+ // Determine the anchor types of the two equivalence classes.
4884
+ CanType anchor1 = equivClass->getAnchor (*this , { })->getCanonicalType ();
4885
+ CanType anchor2 =
4886
+ (equivClass2 ? equivClass2->getAnchor (*this , { })
4887
+ : getCanonicalTypeParameter (T2->getDependentType ({ })))
4888
+ ->getCanonicalType ();
4889
+
4890
+ // Add a rewrite rule to map T2 down to the anchor.
4881
4891
if (addSameTypeRewriteRule (equivClass, T2))
4882
4892
++Impl->RewriteGeneration ;
4883
4893
@@ -4889,7 +4899,6 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
4889
4899
equivClass->addMember (equiv);
4890
4900
4891
4901
// Grab the old equivalence class, if present. We'll deallocate it at the end.
4892
- auto equivClass2 = T2->getEquivalenceClassIfPresent ();
4893
4902
SWIFT_DEFER {
4894
4903
if (equivClass2)
4895
4904
Impl->deallocateEquivalenceClass (equivClass2);
@@ -4907,18 +4916,18 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
4907
4916
equivClass2->sameTypeConstraints .end ());
4908
4917
4909
4918
// Combine the rewrite rules.
4910
- if (auto rewriteRoot2 = Impl->getOrCreateRewriteTreeRoot (equivClass2 )) {
4911
- if (auto rewriteRoot1 = Impl->getOrCreateRewriteTreeRoot (equivClass )) {
4919
+ if (auto rewriteRoot2 = Impl->getOrCreateRewriteTreeRoot (anchor2 )) {
4920
+ if (auto rewriteRoot1 = Impl->getOrCreateRewriteTreeRoot (anchor1 )) {
4912
4921
// Merge the second rewrite tree into the first.
4913
4922
if (rewriteRoot2->mergeInto (rewriteRoot1))
4914
4923
++Impl->RewriteGeneration ;
4915
- Impl->RewriteTreeRoots .erase (equivClass2 );
4924
+ Impl->RewriteTreeRoots .erase (anchor2 );
4916
4925
} else {
4917
4926
// Take the second rewrite tree and make it the first.
4918
- auto root2Entry = Impl->RewriteTreeRoots .find (equivClass2 );
4927
+ auto root2Entry = Impl->RewriteTreeRoots .find (anchor2 );
4919
4928
auto root2Ptr = std::move (root2Entry->second );
4920
4929
Impl->RewriteTreeRoots .erase (root2Entry);
4921
- (void )Impl->RewriteTreeRoots .insert ({equivClass , std::move (root2Ptr)});
4930
+ (void )Impl->RewriteTreeRoots .insert ({anchor1 , std::move (root2Ptr)});
4922
4931
}
4923
4932
}
4924
4933
}
0 commit comments