Merge pull request #15172 from DougGregor/gsb-weaken-potential-archetypes

[GSB] Reduce dependence on potential archetypes for rewrite tree
diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index 7eb4f11..6cf3b17 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -445,19 +445,16 @@
   /// Note that we have added the nested type nestedPA
   void addedNestedType(PotentialArchetype *nestedPA);
 
-  /// Add a rewrite rule that makes \c otherPA a part of the given equivalence
-  /// class.
+  /// Add a rewrite rule from that makes the two types equivalent.
   ///
   /// \returns true if a new rewrite rule was added, and false otherwise.
-  bool addSameTypeRewriteRule(EquivalenceClass *equivClass,
-                              PotentialArchetype *otherPA);
+  bool addSameTypeRewriteRule(CanType type1, CanType type2);
 
-  /// \brief Add a new conformance requirement specifying that the given
-  /// potential archetypes are equivalent.
-  ConstraintResult addSameTypeRequirementBetweenArchetypes(
-                                               PotentialArchetype *T1,
-                                               PotentialArchetype *T2,
-                                               const RequirementSource *Source);
+  /// \brief Add a same-type requirement between two types that are known to
+  /// refer to type parameters.
+  ConstraintResult addSameTypeRequirementBetweenTypeParameters(
+                                         ResolvedType type1, ResolvedType type2,
+                                         const RequirementSource *source);
   
   /// \brief Add a new conformance requirement specifying that the given
   /// potential archetype is bound to a concrete type.
@@ -811,9 +808,6 @@
   bool areInSameEquivalenceClass(Type type1, Type type2);
 
   /// Simplify the given dependent type down to its canonical representation.
-  ///
-  /// \returns null if the type involved dependent member types that
-  /// don't have associated types.
   Type getCanonicalTypeParameter(Type type);
 
   /// For each requirement in \c sig, create a new signature without it and see
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 4154b8c..158ab66 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -166,17 +166,17 @@
   ///
   /// \returns the path, or None if it contained unresolved dependent member
   /// types.
-  Optional<RewritePath> static createPath(Type type);
+  RewritePath static createPath(Type type);
 
   /// Decompose a type into a path.
   ///
   /// \param path Will be filled in with the components of the path, in
   /// reverse order.
   ///
-  /// \returns the generic parameter at the start of the path, or \c None if
-  ///
-  Optional<GenericParamKey>
-  static createPath(Type type, SmallVectorImpl<AssociatedTypeDecl *> &path);
+  /// \returns the generic parameter at the start of the path.
+  static GenericParamKey createPath(
+                                Type type,
+                                SmallVectorImpl<AssociatedTypeDecl *> &path);
 
   /// Compute the longer common prefix between this path and \c other.
   RewritePath commonPath(const RewritePath &other) const;
@@ -216,11 +216,11 @@
                   EquivalenceClass &equivClass)
     : builder(builder), equivClass(equivClass) { }
 
-  Optional<RewritePath> getAnchorPath() {
-    if (anchorPath) return anchorPath;
+  const RewritePath &getAnchorPath() {
+    if (anchorPath) return *anchorPath;
 
     anchorPath = RewritePath::createPath(equivClass.getAnchor(builder, { }));
-    return anchorPath;
+    return *anchorPath;
   }
 };
 
@@ -437,9 +437,9 @@
   /// Equivalence classes that are not currently being used.
   std::vector<void *> FreeEquivalenceClasses;
 
-  /// The roots of the rewrite tree.
-  DenseMap<const EquivalenceClass *, std::unique_ptr<RewriteTreeNode>>
-    RewriteTreeRoots;
+  /// The roots of the rewrite tree, keyed on the canonical, dependent
+  /// types.
+  DenseMap<CanType, std::unique_ptr<RewriteTreeNode>> RewriteTreeRoots;
 
   /// The generation number for the term-rewriting system, which is
   /// increased every time a new rule gets added.
@@ -482,15 +482,12 @@
   /// Deallocate the given equivalence class, returning it to the free list.
   void deallocateEquivalenceClass(EquivalenceClass *equivClass);
 
-  /// Retrieve the rewrite tree root for the given equivalence class,
-  /// if present.
-  RewriteTreeNode *getRewriteTreeRootIfPresent(
-                                      const EquivalenceClass *equivClass);
+  /// Retrieve the rewrite tree root for the given anchor type.
+  RewriteTreeNode *getRewriteTreeRootIfPresent(CanType anchor);
 
-  /// Retrieve the rewrite tree root for the given equivalence class,
+  /// Retrieve the rewrite tree root for the given anchor type,
   /// creating it if needed.
-  RewriteTreeNode *getOrCreateRewriteTreeRoot(
-                                        const EquivalenceClass *equivClass);
+  RewriteTreeNode *getOrCreateRewriteTreeRoot(CanType anchor);
 
   /// Minimize the rewrite tree by minimizing the right-hand sides and
   /// removing redundant rules.
@@ -2293,8 +2290,8 @@
   bool updatedAnchor = false;
   for (auto member : members) {
     auto anchorType =
-      builder.getCanonicalTypeParameter(member->getDependentType(genericParams));
-    if (!anchorType) continue;
+      builder.getCanonicalTypeParameter(
+                                    member->getDependentType(genericParams));
 
 #ifndef NDEBUG
     // Check that we get consistent results from all of the anchors.
@@ -2493,7 +2490,11 @@
   out << "\n";
 
   if (builder) {
-    if (auto rewriteRoot = builder->Impl->getRewriteTreeRootIfPresent(this)) {
+    CanType anchorType =
+      const_cast<EquivalenceClass *>(this)->getAnchor(*builder, { })
+        ->getCanonicalType();
+    if (auto rewriteRoot =
+          builder->Impl->getRewriteTreeRootIfPresent(anchorType)) {
       out << "---Rewrite tree---\n";
       rewriteRoot->dump(out);
     }
@@ -3173,30 +3174,23 @@
   }
 }
 
-Optional<RewritePath> RewritePath::createPath(Type type) {
+RewritePath RewritePath::createPath(Type type) {
   SmallVector<AssociatedTypeDecl *, 4> path;
-  if (auto genericParam = createPath(type, path)) {
-    return RewritePath(*genericParam, path, Reverse);
-  }
-
-  return None;
+  auto genericParam = createPath(type, path);
+  return RewritePath(genericParam, path, Reverse);
 }
 
-Optional<GenericParamKey>
-RewritePath::createPath(Type type,
-                        SmallVectorImpl<AssociatedTypeDecl *> &path) {
+GenericParamKey RewritePath::createPath(
+                                Type type,
+                                SmallVectorImpl<AssociatedTypeDecl *> &path) {
   while (auto depMemTy = type->getAs<DependentMemberType>()) {
     auto assocType = depMemTy->getAssocType();
-    if (!assocType) return None;
-
+    assert(assocType && "Unresolved dependent member type");
     path.push_back(assocType);
     type = depMemTy->getBase();
   }
 
-  auto genericParam = type->getAs<GenericTypeParamType>();
-  if (!genericParam) return None;
-
-  return GenericParamKey(genericParam);
+  return type->castTo<GenericTypeParamType>();
 }
 
 RewritePath RewritePath::commonPath(const RewritePath &other) const {
@@ -3244,15 +3238,14 @@
     return CanType(::formDependentType(ctx, *base, getPath()));
 
   assert(anchorPathCache && "Need an anchor path cache");
-  Optional<RewritePath> anchorPath = anchorPathCache->getAnchorPath();
-  if (!anchorPath) return CanType();
+  const RewritePath &anchorPath = anchorPathCache->getAnchorPath();
 
   // Add the relative path to the anchor path.
   SmallVector<AssociatedTypeDecl *, 4> absolutePath;
-  absolutePath.append(anchorPath->getPath().begin(),
-                      anchorPath->getPath().end());
+  absolutePath.append(anchorPath.getPath().begin(),
+                      anchorPath.getPath().end());
   absolutePath.append(getPath().begin(), getPath().end());
-  return CanType(::formDependentType(ctx, *anchorPath->getBase(),
+  return CanType(::formDependentType(ctx, *anchorPath.getBase(),
                                      absolutePath));
 
 }
@@ -3551,8 +3544,8 @@
 
 RewriteTreeNode *
 GenericSignatureBuilder::Implementation::getRewriteTreeRootIfPresent(
-                                          const EquivalenceClass *equivClass) {
-  auto known = RewriteTreeRoots.find(equivClass);
+                                          CanType anchor) {
+  auto known = RewriteTreeRoots.find(anchor);
   if (known != RewriteTreeRoots.end()) return known->second.get();
 
   return nullptr;
@@ -3560,11 +3553,11 @@
 
 RewriteTreeNode *
 GenericSignatureBuilder::Implementation::getOrCreateRewriteTreeRoot(
-                                          const EquivalenceClass *equivClass) {
-  auto known = RewriteTreeRoots.find(equivClass);
+                                          CanType anchor) {
+  auto known = RewriteTreeRoots.find(anchor);
   if (known != RewriteTreeRoots.end()) return known->second.get();
 
-  auto &root = RewriteTreeRoots[equivClass];
+  auto &root = RewriteTreeRoots[anchor];
   root = std::unique_ptr<RewriteTreeNode>(new RewriteTreeNode(nullptr));
   return root.get();
 }
@@ -3593,7 +3586,8 @@
 
   // Minimize the right-hand sides of each rule in the tree.
   for (auto &equivClass : EquivalenceClasses) {
-    auto root = RewriteTreeRoots.find(&equivClass);
+    CanType anchorType = equivClass.getAnchor(builder, { })->getCanonicalType();
+    auto root = RewriteTreeRoots.find(anchorType);
     if (root == RewriteTreeRoots.end()) continue;
 
     AnchorPathCache anchorPathCache(builder, equivClass);
@@ -3618,9 +3612,9 @@
       ++NumRewriteRhsSimplified;
 
       // Determine replacement path, which might be relative to the anchor.
-      auto canonicalRhsPath = *RewritePath::createPath(canonicalRhsType);
+      auto canonicalRhsPath = RewritePath::createPath(canonicalRhsType);
       auto anchorPath = anchorPathCache.getAnchorPath();
-      if (auto prefix = anchorPath->commonPath(canonicalRhsPath)) {
+      if (auto prefix = anchorPath.commonPath(canonicalRhsPath)) {
         unsigned prefixLength = prefix.getPath().size();
         RelativeRewritePath replacementRhsPath =
           canonicalRhsPath.getPath().slice(prefixLength);
@@ -3648,7 +3642,8 @@
 
   // Minimize the right-hand sides of each rule in the tree.
   for (auto &equivClass : EquivalenceClasses) {
-    auto root = RewriteTreeRoots.find(&equivClass);
+    CanType anchorType = equivClass.getAnchor(builder, { })->getCanonicalType();
+    auto root = RewriteTreeRoots.find(anchorType);
     if (root == RewriteTreeRoots.end()) continue;
 
     AnchorPathCache anchorPathCache(builder, equivClass);
@@ -3663,7 +3658,6 @@
 
       // Simplify the left-hand type.
       Type simplifiedLhsType = builder.getCanonicalTypeParameter(lhsType);
-      if (!simplifiedLhsType) return RewriteTreeNode::RuleAction::none();
 
       // Compute the type of the right-hand side.
       Type rhsType = rhs.formDependentType(ctx, &anchorPathCache);
@@ -3680,25 +3674,13 @@
   }
 }
 
-bool GenericSignatureBuilder::addSameTypeRewriteRule(
-                                                EquivalenceClass *equivClass,
-                                                PotentialArchetype *otherPA){
-  // Simplify both sides in the hope of uncovering a common path.
-  Type simplifiedType1 = equivClass->getAnchor(*this, { });
-  if (!simplifiedType1) return false;
-
-  Type simplifiedType2;
-  if (auto otherEquivClass = otherPA->getEquivalenceClassIfPresent())
-    simplifiedType2 = otherEquivClass->getAnchor(*this, { });
-  else
-    simplifiedType2 = getCanonicalTypeParameter(otherPA->getDependentType({ }));
-  if (!simplifiedType2) return false;
-
+bool GenericSignatureBuilder::addSameTypeRewriteRule(CanType type1,
+                                                     CanType type2) {
   // We already effectively have this rewrite rule.
-  if (simplifiedType1->isEqual(simplifiedType2)) return false;
+  if (type1 == type2) return false;
 
-  auto path1 = *RewritePath::createPath(simplifiedType1);
-  auto path2 = *RewritePath::createPath(simplifiedType2);
+  auto path1 = RewritePath::createPath(type1);
+  auto path2 = RewritePath::createPath(type2);
 
   // Look for a common prefix. When we have one, form a rewrite rule using
   // relative paths.
@@ -3712,14 +3694,13 @@
     if (compareDependentPaths(relPath1, relPath2) < 0)
       std::swap(relPath1, relPath2);
 
-    // Find the equivalence class for the prefix.
+    // Find the anchor for the prefix.
     CanType commonType = prefix.formDependentType(getASTContext());
-    auto equivClass =
-      resolveEquivalenceClass(commonType, ArchetypeResolutionKind::WellFormed);
-    assert(equivClass && "Prefix cannot be resolved?");
+    CanType commonAnchor =
+      getCanonicalTypeParameter(commonType)->getCanonicalType();
 
     // Add the rewrite rule.
-    auto root = Impl->getOrCreateRewriteTreeRoot(equivClass);
+    auto root = Impl->getOrCreateRewriteTreeRoot(commonAnchor);
     return root->addRewriteRule(
                           relPath1,
                           RewritePath(None, relPath2, RewritePath::Forward));
@@ -3728,44 +3709,36 @@
   // Otherwise, form a rewrite rule with absolute paths.
 
   // Find the better path and make sure it's in path2.
-  if (compareDependentTypes(simplifiedType1, simplifiedType2) < 0) {
+  if (compareDependentTypes(type1, type2) < 0) {
     std::swap(path1, path2);
-    std::swap(simplifiedType1, simplifiedType2);
+    std::swap(type1, type2);
   }
 
   // Add the rewrite rule.
   Type firstBase =
     GenericTypeParamType::get(path1.getBase()->Depth, path1.getBase()->Index,
                               getASTContext());
-  auto baseEquivClass =
-    resolveEquivalenceClass(firstBase, ArchetypeResolutionKind::WellFormed);
-  assert(baseEquivClass && "Base cannot be resolved?");
-
-  auto root = Impl->getOrCreateRewriteTreeRoot(baseEquivClass);
+  CanType baseAnchor =
+    getCanonicalTypeParameter(firstBase)->getCanonicalType();
+  auto root = Impl->getOrCreateRewriteTreeRoot(baseAnchor);
   return root->addRewriteRule(path1.getPath(), path2);
 }
 
 Type GenericSignatureBuilder::getCanonicalTypeParameter(Type type) {
   auto initialPath = RewritePath::createPath(type);
-  if (!initialPath) return nullptr;
-
   auto genericParamType =
-    GenericTypeParamType::get(initialPath->getBase()->Depth,
-                              initialPath->getBase()->Index,
+    GenericTypeParamType::get(initialPath.getBase()->Depth,
+                              initialPath.getBase()->Index,
                               getASTContext());
-  auto initialEquivClass =
-    resolveEquivalenceClass(genericParamType,
-                            ArchetypeResolutionKind::WellFormed);
-  if (!initialEquivClass) return nullptr;
 
   unsigned startIndex = 0;
-  auto equivClass = initialEquivClass;
   Type currentType = genericParamType;
-  SmallVector<AssociatedTypeDecl *, 4> path(initialPath->getPath().begin(),
-                                            initialPath->getPath().end());
+  SmallVector<AssociatedTypeDecl *, 4> path(initialPath.getPath().begin(),
+                                            initialPath.getPath().end());
   bool simplified = false;
   do {
-    if (auto rootNode = Impl->getRewriteTreeRootIfPresent(equivClass)) {
+    CanType currentAnchor = currentType->getCanonicalType();
+    if (auto rootNode = Impl->getRewriteTreeRootIfPresent(currentAnchor)) {
       // Find the best rewrite rule for the path starting at startIndex.
       auto match =
         rootNode->bestRewritePath(genericParamType,
@@ -3795,17 +3768,12 @@
           genericParamType =
             GenericTypeParamType::get(newBase->Depth, newBase->Index,
                                       getASTContext());
-          initialEquivClass =
-            resolveEquivalenceClass(genericParamType,
-                                    ArchetypeResolutionKind::WellFormed);
-          assert(initialEquivClass && "Must have an equivalence class");
         }
 
         // Move back to the beginning; we may have opened up other rewrites.
         simplified = true;
         startIndex = 0;
         currentType = genericParamType;
-        equivClass = initialEquivClass;
         continue;
       }
     }
@@ -3813,12 +3781,7 @@
     // If we've hit the end of the path, we're done.
     if (startIndex >= path.size()) break;
 
-    // FIXME: It would be nice if there were a better way to get the equivalence
-    // class of a named nested type.
     currentType = DependentMemberType::get(currentType, path[startIndex++]);
-    equivClass =
-      resolveEquivalenceClass(currentType, ArchetypeResolutionKind::WellFormed);
-    if (!equivClass) break;
   } while (true);
 
   return formDependentType(genericParamType, path);
@@ -4865,14 +4828,18 @@
 }
 
 ConstraintResult
-GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
-       PotentialArchetype *OrigT1,
-       PotentialArchetype *OrigT2,
-       const RequirementSource *Source) 
+GenericSignatureBuilder::addSameTypeRequirementBetweenTypeParameters(
+                                         ResolvedType type1, ResolvedType type2,
+                                         const RequirementSource *source)
 {
+  // Both sides are type parameters; equate them.
+  // FIXME: Realizes potential archetypes far too early.
+  auto OrigT1 = type1.realizePotentialArchetype(*this);
+  auto OrigT2 = type2.realizePotentialArchetype(*this);
+
   // Record the same-type constraint, and bail out if it was already known.
   if (!OrigT1->getOrCreateEquivalenceClass(*this)
-        ->recordSameTypeConstraint(OrigT1, OrigT2, Source))
+        ->recordSameTypeConstraint(OrigT1, OrigT2, source))
     return ConstraintResult::Resolved;
 
   // Operate on the representatives
@@ -4889,10 +4856,15 @@
     std::swap(OrigT1, OrigT2);
   }
 
-  // Add a rewrite rule to map T2 down to the anchor.
   auto equivClass = T1->getOrCreateEquivalenceClass(*this);
-  if (addSameTypeRewriteRule(equivClass, T2))
-    ++Impl->RewriteGeneration;
+  auto equivClass2 = T2->getEquivalenceClassIfPresent();
+
+  // Determine the anchor types of the two equivalence classes.
+  CanType anchor1 = equivClass->getAnchor(*this, { })->getCanonicalType();
+  CanType anchor2 =
+    (equivClass2 ? equivClass2->getAnchor(*this, { })
+                 : getCanonicalTypeParameter(T2->getDependentType({ })))
+      ->getCanonicalType();
 
   // Merge the equivalence classes.
   equivClass->modified(*this);
@@ -4902,7 +4874,6 @@
     equivClass->addMember(equiv);
 
   // Grab the old equivalence class, if present. We'll deallocate it at the end.
-  auto equivClass2 = T2->getEquivalenceClassIfPresent();
   SWIFT_DEFER {
     if (equivClass2)
       Impl->deallocateEquivalenceClass(equivClass2);
@@ -4918,31 +4889,35 @@
                                    equivClass->sameTypeConstraints.end(),
                                    equivClass2->sameTypeConstraints.begin(),
                                    equivClass2->sameTypeConstraints.end());
+  }
 
-    // Combine the rewrite rules.
-    if (auto rewriteRoot2 = Impl->getOrCreateRewriteTreeRoot(equivClass2)) {
-      if (auto rewriteRoot1 = Impl->getOrCreateRewriteTreeRoot(equivClass)) {
-        // Merge the second rewrite tree into the first.
-        if (rewriteRoot2->mergeInto(rewriteRoot1))
-          ++Impl->RewriteGeneration;
-        Impl->RewriteTreeRoots.erase(equivClass2);
-      } else {
-        // Take the second rewrite tree and make it the first.
-        auto root2Entry = Impl->RewriteTreeRoots.find(equivClass2);
-        auto root2Ptr = std::move(root2Entry->second);
-        Impl->RewriteTreeRoots.erase(root2Entry);
-        (void)Impl->RewriteTreeRoots.insert({equivClass, std::move(root2Ptr)});
-      }
+  // Combine the rewrite rules.
+  if (auto rewriteRoot2 = Impl->getOrCreateRewriteTreeRoot(anchor2)) {
+    if (auto rewriteRoot1 = Impl->getOrCreateRewriteTreeRoot(anchor1)) {
+      // Merge the second rewrite tree into the first.
+      if (rewriteRoot2->mergeInto(rewriteRoot1))
+        ++Impl->RewriteGeneration;
+      Impl->RewriteTreeRoots.erase(anchor2);
+    } else {
+      // Take the second rewrite tree and make it the first.
+      auto root2Entry = Impl->RewriteTreeRoots.find(anchor2);
+      auto root2Ptr = std::move(root2Entry->second);
+      Impl->RewriteTreeRoots.erase(root2Entry);
+      (void)Impl->RewriteTreeRoots.insert({anchor1, std::move(root2Ptr)});
     }
   }
 
+  // Add a rewrite rule to map the anchor of T2 down to the anchor of T1.
+  if (addSameTypeRewriteRule(anchor2, anchor1))
+    ++Impl->RewriteGeneration;
+
   // Same-type-to-concrete requirements.
   bool t1IsConcrete = !equivClass->concreteType.isNull();
   bool t2IsConcrete = equivClass2 && !equivClass2->concreteType.isNull();
   if (t2IsConcrete) {
     if (t1IsConcrete) {
       (void)addSameTypeRequirement(equivClass->concreteType,
-                                   equivClass2->concreteType, Source,
+                                   equivClass2->concreteType, source,
                                    UnresolvedHandlingKind::GenerateConstraints,
                                    SameTypeConflictCheckedLater());
     } else {
@@ -5187,15 +5162,9 @@
                         source.getSource(*this, type1.getDependentType(*this)));
   }
 
-  // Both sides are type parameters; equate them.
-  // FIXME: Realizes potential archetypes far too early.
-  auto pa1 = type1.realizePotentialArchetype(*this);
-  auto pa2 = type2.realizePotentialArchetype(*this);
-
-  return addSameTypeRequirementBetweenArchetypes(
-                     pa1, pa2,
-                     source.getSource(*this,
-                                      type2.getDependentType(*this)));
+  return addSameTypeRequirementBetweenTypeParameters(
+                     type1, type2,
+                     source.getSource(*this, type2.getDependentType(*this)));
 }
 
 ConstraintResult GenericSignatureBuilder::addInheritedRequirements(