Merge pull request #12346 from adrian-prantl/18296829

Revert
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 7f17f1f..3b9024e 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -562,8 +562,10 @@
   class AssociatedTypeDeclBitfields {
     friend class AssociatedTypeDecl;
     unsigned : NumTypeDeclBits;
+    unsigned ComputedOverridden : 1;
+    unsigned HasOverridden : 1;
   };
-  enum { NumAssociatedTypeDeclBits = NumTypeDeclBits };
+  enum { NumAssociatedTypeDeclBits = NumTypeDeclBits + 2 };
   static_assert(NumAssociatedTypeDeclBits <= 32, "fits in an unsigned");
 
   class ImportDeclBitfields {
@@ -2662,6 +2664,33 @@
   /// type; can only be called after the alias type has been resolved.
   void computeType();
 
+  /// Retrieve the associated type "anchor", which is the associated type
+  /// declaration that will be used to describe this associated type in the
+  /// ABI.
+  ///
+  /// The associated type "anchor" is an associated type that does not
+  /// override any other associated type. There may be several such associated
+  /// types; select one deterministically.
+  AssociatedTypeDecl *getAssociatedTypeAnchor() const;
+
+  /// Retrieve the (first) overridden associated type declaration, if any.
+  AssociatedTypeDecl *getOverriddenDecl() const;
+
+  /// Retrieve the set of associated types overridden by this associated
+  /// type.
+  ArrayRef<AssociatedTypeDecl *> getOverriddenDecls() const;
+
+  /// Whether the overridden declarations have already been computed.
+  bool overriddenDeclsComputed() const {
+    return AssociatedTypeDeclBits.ComputedOverridden;
+  }
+
+  /// Record the set of overridden declarations.
+  ///
+  /// \returns the array recorded in the AST.
+  ArrayRef<AssociatedTypeDecl *> setOverriddenDecls(
+                                   ArrayRef<AssociatedTypeDecl *> overridden);
+
   SourceLoc getStartLoc() const { return KeywordLoc; }
   SourceRange getSourceRange() const;
 
diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index e55ee0b..5aa9dc6 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -1452,18 +1452,13 @@
   /// associated type.
   PotentialArchetype(PotentialArchetype *parent, Identifier name);
 
-  /// \brief Construct a new potential archetype for an associated type.
-  PotentialArchetype(PotentialArchetype *parent, AssociatedTypeDecl *assocType)
-    : parentOrBuilder(parent), identifier(assocType)
-  {
-    assert(parent != nullptr && "Not an associated type?");
-  }
-
   /// \brief Construct a new potential archetype for a concrete declaration.
   PotentialArchetype(PotentialArchetype *parent, TypeDecl *concreteDecl)
     : parentOrBuilder(parent), identifier(concreteDecl)
   {
-    assert(parent != nullptr && "Not an associated type?");
+    assert(parent != nullptr && "Not a nested type?");
+    assert(!isa<AssociatedTypeDecl>(concreteDecl) ||
+      cast<AssociatedTypeDecl>(concreteDecl)->getOverriddenDecls().empty());
   }
 
   /// \brief Construct a new potential archetype for a generic parameter.
diff --git a/include/swift/Serialization/ModuleFormat.h b/include/swift/Serialization/ModuleFormat.h
index cf4e11e..4101be6 100644
--- a/include/swift/Serialization/ModuleFormat.h
+++ b/include/swift/Serialization/ModuleFormat.h
@@ -54,7 +54,7 @@
 /// in source control, you should also update the comment to briefly
 /// describe what change you made. The content of this comment isn't important;
 /// it just ensures a conflict if two people change the module format.
-const uint16_t VERSION_MINOR = 368; // Last change: objc_method, objc_super_method
+const uint16_t VERSION_MINOR = 369; // Last change: associated type overrides
 
 using DeclID = PointerEmbeddedInt<unsigned, 31>;
 using DeclIDField = BCFixed<31>;
@@ -815,10 +815,11 @@
 
   using AssociatedTypeDeclLayout = BCRecordLayout<
     ASSOCIATED_TYPE_DECL,
-    IdentifierIDField, // name
-    DeclContextIDField,// context decl
-    TypeIDField,       // default definition
-    BCFixed<1>         // implicit flag
+    IdentifierIDField,   // name
+    DeclContextIDField,  // context decl
+    TypeIDField,         // default definition
+    BCFixed<1>,          // implicit flag
+    BCArray<DeclIDField> // overridden associated types
   >;
 
   using StructLayout = BCRecordLayout<
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 01e1798..c794667 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -278,6 +278,10 @@
   /// The existential signature <T : P> for each P.
   llvm::DenseMap<CanType, CanGenericSignature> ExistentialSignatures;
 
+  /// Overridden associated type declarations.
+  llvm::DenseMap<const AssociatedTypeDecl *, ArrayRef<AssociatedTypeDecl *>>
+    AssociatedTypeOverrides;
+
   /// \brief Structure that captures data that is segregated into different
   /// arenas.
   struct Arena {
@@ -1541,6 +1545,125 @@
   return env;
 }
 
+/// Minimize the set of overridden associated types, eliminating any
+/// associated types that are overridden by other associated types.
+static void minimizeOverriddenAssociatedTypes(
+                           SmallVectorImpl<AssociatedTypeDecl *> &assocTypes) {
+  // Mark associated types that are "worse" than some other associated type,
+  // because they come from an inherited protocol.
+  bool anyWorse = false;
+  std::vector<bool> worseThanAny(assocTypes.size(), false);
+  for (unsigned i : indices(assocTypes)) {
+    auto proto1 = assocTypes[i]->getProtocol();
+    for (unsigned j : range(i + 1, assocTypes.size())) {
+      auto proto2 = assocTypes[j]->getProtocol();
+      if (proto1->inheritsFrom(proto2)) {
+        anyWorse = true;
+        worseThanAny[j] = true;
+      } else if (proto2->inheritsFrom(proto1)) {
+        anyWorse = true;
+        worseThanAny[i] = true;
+        break;
+      }
+    }
+  }
+
+  // If we didn't find any associated types that were "worse", we're done.
+  if (!anyWorse) return;
+
+  // Copy in the associated types that aren't worse than any other associated
+  // type.
+  unsigned nextIndex = 0;
+  for (unsigned i : indices(assocTypes)) {
+    if (worseThanAny[i]) continue;
+    assocTypes[nextIndex++] = assocTypes[i];
+  }
+
+  assocTypes.erase(assocTypes.begin() + nextIndex, assocTypes.end());
+}
+
+/// Sort associated types just based on the protocol.
+static int compareSimilarAssociatedTypes(AssociatedTypeDecl *const *lhs,
+                                         AssociatedTypeDecl *const *rhs) {
+  auto lhsProto = (*lhs)->getProtocol();
+  auto rhsProto = (*rhs)->getProtocol();
+  return ProtocolType::compareProtocols(&lhsProto, &rhsProto);
+}
+
+ArrayRef<AssociatedTypeDecl *> AssociatedTypeDecl::getOverriddenDecls() const {
+  // If we already computed the set of overridden associated types, return it.
+  if (AssociatedTypeDeclBits.ComputedOverridden) {
+    // We didn't override any associated types, so return the empty set.
+    if (!AssociatedTypeDeclBits.HasOverridden)
+      return { };
+
+    // Look up the overrides.
+    auto known = getASTContext().Impl.AssociatedTypeOverrides.find(this);
+    assert(known != getASTContext().Impl.AssociatedTypeOverrides.end());
+    return known->second;
+  }
+
+  // Find associated types with the given name in all of the inherited
+  // protocols.
+  SmallVector<AssociatedTypeDecl *, 4> inheritedAssociatedTypes;
+  auto proto = getProtocol();
+  proto->walkInheritedProtocols([&](ProtocolDecl *inheritedProto) {
+    if (proto == inheritedProto) return TypeWalker::Action::Continue;
+
+    // Objective-C protocols
+    if (inheritedProto->isObjC()) return TypeWalker::Action::Continue;
+
+    // Look for associated types with the same name.
+    bool foundAny = false;
+    for (auto member : inheritedProto->lookupDirect(
+                                              getFullName(),
+                                              /*ignoreNewExtensions=*/true)) {
+      if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
+        inheritedAssociatedTypes.push_back(assocType);
+        foundAny = true;
+      }
+    }
+
+    return foundAny ? TypeWalker::Action::SkipChildren
+                    : TypeWalker::Action::Continue;
+  });
+
+  // Minimize the set of inherited associated types, eliminating any that
+  // themselves are overridden.
+  minimizeOverriddenAssociatedTypes(inheritedAssociatedTypes);
+
+  // Sort the set of inherited associated types.
+  llvm::array_pod_sort(inheritedAssociatedTypes.begin(),
+                       inheritedAssociatedTypes.end(),
+                       compareSimilarAssociatedTypes);
+
+  return const_cast<AssociatedTypeDecl *>(this)
+    ->setOverriddenDecls(inheritedAssociatedTypes);
+}
+
+ArrayRef<AssociatedTypeDecl *> AssociatedTypeDecl::setOverriddenDecls(
+                                  ArrayRef<AssociatedTypeDecl *> overridden) {
+  assert(!AssociatedTypeDeclBits.ComputedOverridden &&
+         "Overridden decls already computed");
+  AssociatedTypeDeclBits.ComputedOverridden = true;
+
+  // If the set of overridden declarations is empty, note that.
+  if (overridden.empty()) {
+    AssociatedTypeDeclBits.HasOverridden = false;
+    return { };
+  }
+
+  // Record the overrides in the context.
+  auto &ctx = getASTContext();
+  AssociatedTypeDeclBits.HasOverridden = true;
+  auto overriddenCopy = ctx.AllocateCopy(overridden);
+  auto inserted =
+    ctx.Impl.AssociatedTypeOverrides.insert({this, overriddenCopy}).second;
+  (void)inserted;
+  assert(inserted && "Already recorded associated type overrides");
+  return overriddenCopy;
+}
+
 bool ASTContext::canImportModule(std::pair<Identifier, SourceLoc> ModulePath) {
   // If this module has already been successfully imported, it is importable.
   if (getLoadedModule(ModulePath) != nullptr)
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 295c39d..e0987bd 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -667,6 +667,15 @@
                    [&](const RequirementRepr &req) { req.print(OS); },
                    [&] { OS << ", "; });
       }
+      if (decl->overriddenDeclsComputed()) {
+        OS << " overridden=";
+        interleave(decl->getOverriddenDecls(),
+                   [&](AssociatedTypeDecl *overridden) {
+                     OS << overridden->getProtocol()->getName();
+                   }, [&]() {
+                     OS << ", ";
+                   });
+      }
 
       OS << ")";
     }
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 8c44db6..ede44db 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1593,6 +1593,8 @@
     return sdd->getOverriddenDecl();
   if (auto cd = dyn_cast<ConstructorDecl>(this))
     return cd->getOverriddenDecl();
+  if (auto at = dyn_cast<AssociatedTypeDecl>(this))
+    return at->getOverriddenDecl();
   return nullptr;
 }
 
@@ -2580,7 +2582,11 @@
                                        TrailingWhereClause *trailingWhere)
     : AbstractTypeParamDecl(DeclKind::AssociatedType, dc, name, nameLoc),
       KeywordLoc(keywordLoc), DefaultDefinition(defaultDefinition),
-      TrailingWhere(trailingWhere) {}
+      TrailingWhere(trailingWhere) {
+
+  AssociatedTypeDeclBits.ComputedOverridden = false;
+  AssociatedTypeDeclBits.HasOverridden = false;
+}
 
 AssociatedTypeDecl::AssociatedTypeDecl(DeclContext *dc, SourceLoc keywordLoc,
                                        Identifier name, SourceLoc nameLoc,
@@ -2591,6 +2597,8 @@
       KeywordLoc(keywordLoc), TrailingWhere(trailingWhere),
       Resolver(definitionResolver), ResolverContextData(resolverData) {
   assert(Resolver && "missing resolver");
+  AssociatedTypeDeclBits.ComputedOverridden = false;
+  AssociatedTypeDeclBits.HasOverridden = false;
 }
 
 void AssociatedTypeDecl::computeType() {
@@ -2617,6 +2625,29 @@
   return SourceRange(KeywordLoc, endLoc);
 }
 
+AssociatedTypeDecl *AssociatedTypeDecl::getAssociatedTypeAnchor() const {
+  auto overridden = getOverriddenDecls();
+
+  // If this declaration does not override any other declarations, it's
+  // the anchor.
+  if (overridden.empty()) return const_cast<AssociatedTypeDecl *>(this);
+
+  // Find the best anchor among the anchors of the overridden decls.
+  AssociatedTypeDecl *bestAnchor = nullptr;
+  for (auto assocType : overridden) {
+    auto anchor = assocType->getAssociatedTypeAnchor();
+    if (!bestAnchor || compare(anchor, bestAnchor) < 0)
+      bestAnchor = anchor;
+  }
+
+  return bestAnchor;
+}
+
+AssociatedTypeDecl *AssociatedTypeDecl::getOverriddenDecl() const {
+  auto overridden = getOverriddenDecls();
+  return overridden.empty() ? nullptr : overridden.front();
+}
+
 EnumDecl::EnumDecl(SourceLoc EnumLoc,
                      Identifier Name, SourceLoc NameLoc,
                      MutableArrayRef<TypeLoc> Inherited,
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index eb2de97..ba903ae 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -1604,6 +1604,13 @@
                                               assocType2->getName().str()))
     return result;
 
+  // Prefer an associated type with no overrides (i.e., an anchor) to one
+  // that has overrides.
+  bool hasOverridden1 = !assocType1->getOverriddenDecls().empty();
+  bool hasOverridden2 = !assocType2->getOverriddenDecls().empty();
+  if (hasOverridden1 != hasOverridden2)
+    return hasOverridden1 ? +1 : -1;
+
   // - by protocol, so t_n_m.`P.T` < t_n_m.`Q.T` (given P < Q)
   auto proto1 = assocType1->getProtocol();
   auto proto2 = assocType2->getProtocol();
@@ -1655,6 +1662,7 @@
 
   // Look for types with the given name in protocols that we know about.
   AssociatedTypeDecl *bestAssocType = nullptr;
+  llvm::SmallSetVector<AssociatedTypeDecl *, 4> assocTypeAnchors;
   SmallVector<TypeDecl *, 4> concreteDecls;
   for (const auto &conforms : conformsTo) {
     ProtocolDecl *proto = conforms.first;
@@ -1665,6 +1673,10 @@
       // If this is an associated type, record whether it is the best
       // associated type we've seen thus far.
       if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
+        // Retrieve the associated type anchor.
+        assocType = assocType->getAssociatedTypeAnchor();
+        assocTypeAnchors.insert(assocType);
+
         if (!bestAssocType ||
              compareAssociatedTypes(assocType, bestAssocType) < 0)
           bestAssocType = assocType;
@@ -1721,6 +1733,22 @@
     }
   }
 
+  // Infer same-type constraints among same-named associated type anchors.
+  if (assocTypeAnchors.size() > 1) {
+    auto &builder = *members.front()->getBuilder();
+    auto anchorType = getAnchor({ });
+    auto inferredSource = FloatingRequirementSource::forInferred(nullptr);
+    for (auto assocType : assocTypeAnchors) {
+      if (assocType == bestAssocType) continue;
+
+      builder.addRequirement(
+        Requirement(RequirementKind::SameType,
+                    DependentMemberType::get(anchorType, bestAssocType),
+                    DependentMemberType::get(anchorType, assocType)),
+        inferredSource, nullptr);
+    }
+  }
+
   // Form the new cache entry.
   CachedNestedType entry;
   entry.numConformancesPresent = conformsTo.size();
@@ -1730,6 +1758,8 @@
     entry.types.push_back(bestAssocType);
     entry.types.insert(entry.types.end(),
                        concreteDecls.begin(), concreteDecls.end());
+    assert(bestAssocType->getOverriddenDecls().empty() &&
+           "Lookup should never keep a non-anchor associated type");
   } else if (!concreteDecls.empty()) {
     // Find the best concrete type.
     auto bestConcreteTypeIter =
@@ -2552,6 +2582,11 @@
   if (!type) return nullptr;
 
   AssociatedTypeDecl *assocType = dyn_cast<AssociatedTypeDecl>(type);
+
+  // Always refer to the archetype anchor.
+  if (assocType)
+    assocType = assocType->getAssociatedTypeAnchor();
+
   TypeDecl *concreteDecl = assocType ? nullptr : type;
 
   // If we were asked for a complete, well-formed archetype, make sure we
@@ -3276,10 +3311,6 @@
         // If we have inherited associated type...
         if (auto inheritedAssocTypeDecl =
               dyn_cast<AssociatedTypeDecl>(inheritedType)) {
-          // Infer a same-type requirement among the same-named associated
-          // types.
-          addInferredSameTypeReq(assocTypeDecl, inheritedAssocTypeDecl);
-
           // Complain about the first redeclaration.
           if (shouldWarnAboutRedeclaration) {
             auto inheritedFromProto = inheritedAssocTypeDecl->getProtocol();
@@ -5472,53 +5503,6 @@
                          collapsedParents.end());
 }
 
-/// Check whether two potential archetypes "structurally" match, e.g.,
-/// the names match up to the root (which must match).
-static bool potentialArchetypesStructurallyMatch(PotentialArchetype *pa1,
-                                                 PotentialArchetype *pa2) {
-  auto parent1 = pa1->getParent();
-  auto parent2 = pa2->getParent();
-  if (!parent1 && !parent2)
-    return pa1->getGenericParamKey() == pa2->getGenericParamKey();
-
-  // Check for depth mismatch.
-  if (static_cast<bool>(parent1) != static_cast<bool>(parent2))
-    return false;
-
-  // Check names.
-  if (pa1->getNestedName() != pa2->getNestedName())
-    return false;
-
-  return potentialArchetypesStructurallyMatch(parent1, parent2);
-}
-
-/// Look for structurally-equivalent types within the given equivalence class,
-/// collapsing their components.
-static void collapseStructurallyEquivalentSameTypeComponents(
-              EquivalenceClass *equivClass,
-              llvm::SmallDenseMap<PotentialArchetype *, unsigned> &componentOf,
-              SmallVectorImpl<unsigned> &collapsedParents,
-              unsigned &remainingComponents) {
-  for (unsigned i : indices(equivClass->members)) {
-    auto pa1 = equivClass->members[i];
-    auto rep1 = findRepresentative(collapsedParents, componentOf[pa1]);
-    for (unsigned j : indices(equivClass->members).slice(i + 1)) {
-      auto pa2 = equivClass->members[j];
-      auto rep2 = findRepresentative(collapsedParents, componentOf[pa2]);
-      if (rep1 == rep2) continue;
-
-      auto depth = pa1->getNestingDepth();
-      if (depth < 2 || depth != pa2->getNestingDepth()) continue;
-
-      if (potentialArchetypesStructurallyMatch(pa1, pa2) &&
-          unionSets(collapsedParents, rep1, rep2)) {
-        --remainingComponents;
-        rep1 = findRepresentative(collapsedParents, componentOf[pa1]);
-      }
-    }
-  }
-}
-
 /// Collapse same-type components within an equivalence class, minimizing the
 /// number of requirements required to express the equivalence class.
 static void collapseSameTypeComponents(
@@ -5579,14 +5563,6 @@
       builder, equivClass, componentOf, collapsedParents, remainingComponents);
   }
 
-  if (remainingComponents > 1) {
-    // Collapse structurally-equivalent components.
-    collapseStructurallyEquivalentSameTypeComponents(equivClass,
-                                                     componentOf,
-                                                     collapsedParents,
-                                                     remainingComponents);
-  }
-
   // If needed, collapse the same-type components merged by a derived
   // nested-type-name-match edge.
   unsigned maxComponents = equivClass->derivedSameTypeComponents.size();
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 09f2946..85059fa 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -1022,8 +1022,6 @@
                                    std::get<1>(types))) {
         return *result;
       }
-
-      // FIXME: Consider default arguments here?
     }
 
     // If the witness is 'throws', the requirement must be.
@@ -4276,7 +4274,6 @@
   SWIFT_DEFER { Conformance->setState(initialState); };
 
   for (auto assocType : Proto->getAssociatedTypeMembers()) {
-
     // If we already have a type witness, do nothing.
     if (Conformance->hasTypeWitness(assocType))
       continue;
@@ -4599,6 +4596,24 @@
           continue;
         }
 
+        // If there is a generic parameter of the named type, use that.
+        if (auto gpList = DC->getGenericParamsOfContext()) {
+          GenericTypeParamDecl *foundGP = nullptr;
+          for (auto gp : *gpList) {
+            if (gp->getName() == assocType->getName()) {
+              foundGP = gp;
+              break;
+            }
+          }
+
+          if (foundGP) {
+            auto gpType = DC->mapTypeIntoContext(
+                            foundGP->getDeclaredInterfaceType());
+            typeWitnesses.insert(assocType, {gpType, reqDepth});
+            continue;
+          }
+        }
+
         // The solution is incomplete.
         recordMissing();
         return;
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 4730baf..18a430d 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -2502,11 +2502,13 @@
     DeclContextID contextID;
     TypeID defaultDefinitionID;
     bool isImplicit;
+    ArrayRef<uint64_t> rawOverriddenIDs;
 
     decls_block::AssociatedTypeDeclLayout::readRecord(scratch, nameID,
                                                       contextID,
                                                       defaultDefinitionID,
-                                                      isImplicit);
+                                                      isImplicit,
+                                                      rawOverriddenIDs);
 
     auto DC = ForcedContext ? *ForcedContext : getDeclContext(contextID);
     if (declOrOffset.isComplete())
@@ -2533,6 +2535,17 @@
       assocType->setImplicit();
 
     assocType->setCheckedInheritanceClause();
+
+    // Overridden associated types.
+    SmallVector<AssociatedTypeDecl *, 2> overriddenAssocTypes;
+    for (auto overriddenID : rawOverriddenIDs) {
+      if (auto overriddenAssocType =
+              dyn_cast_or_null<AssociatedTypeDecl>(getDecl(overriddenID))) {
+        overriddenAssocTypes.push_back(overriddenAssocType);
+      }
+    }
+    (void)assocType->setOverriddenDecls(overriddenAssocTypes);
+
     break;
   }
 
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 9340120..bb6ec14 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -2720,6 +2720,10 @@
     verifyAttrSerializable(assocType);
 
     auto contextID = addDeclContextRef(assocType->getDeclContext());
+    SmallVector<DeclID, 4> overriddenAssocTypeIDs;
+    for (auto overridden : assocType->getOverriddenDecls()) {
+      overriddenAssocTypeIDs.push_back(addDeclRef(overridden));
+    }
 
     unsigned abbrCode = DeclTypeAbbrCodes[AssociatedTypeDeclLayout::Code];
     AssociatedTypeDeclLayout::emitRecord(
@@ -2727,7 +2731,8 @@
       addDeclBaseNameRef(assocType->getName()),
       contextID,
       addTypeRef(assocType->getDefaultDefinitionType()),
-      assocType->isImplicit());
+      assocType->isImplicit(),
+      overriddenAssocTypeIDs);
     break;
   }
 
diff --git a/test/Generics/protocol_requirement_signatures.swift b/test/Generics/protocol_requirement_signatures.swift
index 1007e7b..676b1bf 100644
--- a/test/Generics/protocol_requirement_signatures.swift
+++ b/test/Generics/protocol_requirement_signatures.swift
@@ -33,16 +33,16 @@
 
 // inheritance without any new requirements
 // CHECK-LABEL: .Q3@
-// CHECK-NEXT: Requirement signature: <Self where Self : Q1, Self.X == Self.X>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q1, τ_0_0.X == τ_0_0.X>
+// CHECK-NEXT: Requirement signature: <Self where Self : Q1>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q1>
 protocol Q3: Q1 {
     associatedtype X // expected-warning{{redeclaration of associated type 'X'}}
 }
 
 // inheritance adding a new conformance
 // CHECK-LABEL: .Q4@
-// CHECK-NEXT: Requirement signature: <Self where Self : Q1, Self.X : P2, Self.X == Self.X>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q1, τ_0_0.X : P2, τ_0_0.X == τ_0_0.X>
+// CHECK-NEXT: Requirement signature: <Self where Self : Q1, Self.X : P2>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q1, τ_0_0.X : P2>
 protocol Q4: Q1 {
     associatedtype X: P2 // expected-warning{{redeclaration of associated type 'X'}}
                    // expected-note@-1 2{{'X' declared here}}
@@ -56,8 +56,8 @@
 
 // multiple inheritance without any new requirements
 // CHECK-LABEL: .Q6@
-// CHECK-NEXT: Requirement signature: <Self where Self : Q2, Self : Q3, Self : Q4, Self.X == Self.X>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q2, τ_0_0 : Q3, τ_0_0 : Q4, τ_0_0.X == τ_0_0.X>
+// CHECK-NEXT: Requirement signature: <Self where Self : Q2, Self : Q3, Self : Q4>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q2, τ_0_0 : Q3, τ_0_0 : Q4>
 protocol Q6: Q2, // expected-note{{conformance constraint 'Self.X': 'P1' implied here}}
              Q3, Q4 {
     associatedtype X: P1 // expected-warning{{redundant conformance constraint 'Self.X': 'P1'}}
@@ -66,8 +66,8 @@
 
 // multiple inheritance with a new conformance
 // CHECK-LABEL: .Q7@
-// CHECK-NEXT: Requirement signature: <Self where Self : Q2, Self : Q3, Self : Q4, Self.X : P3, Self.X == Self.X>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q2, τ_0_0 : Q3, τ_0_0 : Q4, τ_0_0.X : P3, τ_0_0.X == τ_0_0.X>
+// CHECK-NEXT: Requirement signature: <Self where Self : Q2, Self : Q3, Self : Q4, Self.X : P3>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0 : Q2, τ_0_0 : Q3, τ_0_0 : Q4, τ_0_0.X : P3>
 protocol Q7: Q2, Q3, Q4 {
     associatedtype X: P3 // expected-warning{{redeclaration of associated type 'X'}}
 }
diff --git a/test/Generics/requirement_inference.swift b/test/Generics/requirement_inference.swift
index 1342d29..38fd692 100644
--- a/test/Generics/requirement_inference.swift
+++ b/test/Generics/requirement_inference.swift
@@ -158,7 +158,8 @@
 func sameTypeConcrete1<T : P9 & P10>(_: T) where T.A == X3, T.C == T.B, T.C == Int { }
 
 // CHECK-LABEL: sameTypeConcrete2@
-// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.A == τ_0_0.A, τ_0_0.B == X3, τ_0_0.C == X3>
+// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.B == X3, τ_0_0.C == X3>
+// FIXME: Should have τ_0_0.A == τ_0_0.A
 func sameTypeConcrete2<T : P9 & P10>(_: T) where T.B : X3, T.C == T.B, T.C == X3 { }
 // expected-warning@-1{{redundant superclass constraint 'T.B' : 'X3'}}
 // expected-note@-2{{same-type constraint 'T.C' == 'X3' written here}}
@@ -396,5 +397,5 @@
 protocol P31 { }
 
 // CHECK-LABEL: .sameTypeNameMatch1@
-// Generic signature: <T where T : P29, T : P30, T.X : P31, T.X == T.X>
+// CHECK: Generic signature: <T where T : P29, T : P30, T.X : P31, T.X == T.X>
 func sameTypeNameMatch1<T: P29 & P30>(_: T) where T.X: P31 { }
diff --git a/test/Generics/sr5726.swift b/test/Generics/sr5726.swift
new file mode 100644
index 0000000..70a04d5
--- /dev/null
+++ b/test/Generics/sr5726.swift
@@ -0,0 +1,16 @@
+// RUN: %target-typecheck-verify-swift
+
+// SR-5726
+protocol Foo
+{
+  associatedtype Bar
+  var bar: Bar { get }
+}
+
+extension Foo where Self: Collection, Bar: Collection, Self.SubSequence == Bar.SubSequence, Self.Index == Bar.Index
+{
+  subscript(_ bounds: Range<Index>) -> SubSequence
+  {
+    return bar[bounds]
+  }
+}
diff --git a/test/IRGen/associated_types.swift b/test/IRGen/associated_types.swift
index 62fb04d..7ddaf0e 100644
--- a/test/IRGen/associated_types.swift
+++ b/test/IRGen/associated_types.swift
@@ -66,11 +66,12 @@
 // information for archetypes from all paths to that archetype, not just
 // its parent relationships.
 
-func testFastRuncible<T: Runcible, U: FastRuncible where T.RuncerType == U.RuncerType>(_ t: T, u: U) {
+func testFastRuncible<T: Runcible, U: FastRuncible>(_ t: T, u: U)
+   where T.RuncerType == U.RuncerType {
   U.RuncerType.Runcee.accelerate()
 }
 
-// CHECK: define hidden swiftcc void @_T016associated_types16testFastRuncibleyx_q_1utAA0E0RzAA0dE0R_10RuncerTypeQy_AFRtzr0_lF(%swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type* %T, %swift.type* %U, i8** %T.Runcible, i8** %U.FastRuncible) #0 {
+// CHECK: define hidden swiftcc void @_T016associated_types16testFastRuncibleyx_q_1utAA0E0RzAA0dE0R_10RuncerTypeQy_AFRtzAF_6RunceeAA0F0PQZAF_AiA0dF0PRTzr0_lF(%swift.opaque* noalias nocapture, %swift.opaque* noalias nocapture, %swift.type* %T, %swift.type* %U, i8** %T.Runcible, i8** %U.FastRuncible) #0 {
 //   1. Get the type metadata for U.RuncerType.Runcee.
 //     1a. Get the type metadata for U.RuncerType.
 //         Note that we actually look things up in T, which is going to prove unfortunate.
diff --git a/test/SourceKit/CursorInfo/cursor_overrides.swift b/test/SourceKit/CursorInfo/cursor_overrides.swift
index a302b79..1e6415a 100644
--- a/test/SourceKit/CursorInfo/cursor_overrides.swift
+++ b/test/SourceKit/CursorInfo/cursor_overrides.swift
@@ -16,6 +16,15 @@
   x.meth()
 }
 
+public protocol WithAssocType {
+  /// Some kind of associated type
+  associatedtype AssocType
+}
+
+public protocol WithInheritedAssocType : WithAssocType {
+  associatedtype AssocType = Int
+}
+
 // REQUIRES: objc_interop
 // RUN: %sourcekitd-test -req=cursor -pos=16:7 %s -- -embed-bitcode -I %S/Inputs/cursor-overrides %mcp_opt %s | %FileCheck -check-prefix=CHECK1 %s
 // CHECK1: source.lang.swift.ref.function.method.instance (12:8-12:14)
@@ -28,3 +37,9 @@
 // CHECK1-NEXT: c:objc(cs)B1(im)meth
 // CHECK1-NEXT: c:objc(pl)P1(im)meth
 // CHECK1-NEXT: OVERRIDES END
+
+// RUN: %sourcekitd-test -req=cursor -pos=25:20 %s -- -embed-bitcode -I %S/Inputs/cursor-overrides %mcp_opt %s | %FileCheck -check-prefix=CHECK2 %s
+// CHECK2: s:16cursor_overrides22WithInheritedAssocTypeP0eF0
+// CHECK2: OVERRIDES BEGIN
+// CHECK2-NEXT: s:16cursor_overrides13WithAssocTypeP0dE0
+// CHECK2-NEXT: OVERRIDES END
diff --git a/test/SourceKit/InterfaceGen/gen_swift_module.swift b/test/SourceKit/InterfaceGen/gen_swift_module.swift
index 7df6ce9..33c4418 100644
--- a/test/SourceKit/InterfaceGen/gen_swift_module.swift
+++ b/test/SourceKit/InterfaceGen/gen_swift_module.swift
@@ -15,12 +15,12 @@
 
 // RUN: %swift -emit-module -o %t.mod/swift_mod_syn.swiftmodule %S/Inputs/swift_mod_syn.swift -parse-as-library
 // RUN: %sourcekitd-test -req=interface-gen-open -module swift_mod_syn -- -I %t.mod == -req=cursor -pos=4:7 %s -- %s -I %t.mod | %FileCheck -check-prefix=SYNTHESIZED-USR1 %s
-// SYNTHESIZED-USR1: s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements013BidirectionalB0PRpzlE4sortyyF::SYNTHESIZED::s:Sa
+// SYNTHESIZED-USR1: s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements8SequencePRpzlE4sortyyF::SYNTHESIZED::s:Sa
 
 // RUN: %sourcekitd-test -req=interface-gen-open -module Swift -synthesized-extension \
-// RUN: 	== -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements013BidirectionalB0PRpzlE4sortyyF::SYNTHESIZED::s:Sa" | %FileCheck -check-prefix=SYNTHESIZED-USR2 %s
+// RUN: 	== -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements8SequencePRpzlE4sortyyF::SYNTHESIZED::s:Sa" | %FileCheck -check-prefix=SYNTHESIZED-USR2 %s
 // SYNTHESIZED-USR2-NOT: USR NOT FOUND
 
 // RUN: %sourcekitd-test -req=interface-gen-open -module Swift \
-// RUN: 	== -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements013BidirectionalB0PRpzlE4sortyyF::SYNTHESIZED::s:Sa::SYNTHESIZED::USRDOESNOTEXIST" | %FileCheck -check-prefix=SYNTHESIZED-USR3 %s
+// RUN: 	== -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements8SequencePRpzlE4sortyyF::SYNTHESIZED::s:Sa::SYNTHESIZED::USRDOESNOTEXIST" | %FileCheck -check-prefix=SYNTHESIZED-USR3 %s
 // SYNTHESIZED-USR3-NOT: USR NOT FOUND
diff --git a/test/decl/protocol/associated_type_overrides.swift b/test/decl/protocol/associated_type_overrides.swift
new file mode 100644
index 0000000..99e8eaf
--- /dev/null
+++ b/test/decl/protocol/associated_type_overrides.swift
@@ -0,0 +1,28 @@
+// RUN: %target-swift-frontend -typecheck -dump-ast %s 2>&1 | %FileCheck %s
+
+protocol P1 {
+  associatedtype A
+}
+
+// CHECK-LABEL: protocol "P2"
+// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P1))
+protocol P2 : P1 {
+  associatedtype A
+}
+
+protocol P3 {
+  associatedtype A
+}
+
+// CHECK-LABEL: protocol "P4"
+// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P2, P3))
+protocol P4 : P2, P3 {
+  associatedtype A
+}
+
+// CHECK-LABEL: protocol "P5"
+// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P4))
+protocol P5 : P4, P2 {
+  associatedtype A
+}
+
diff --git a/test/decl/protocol/req/associated_type_inference.swift b/test/decl/protocol/req/associated_type_inference.swift
index 43f99ad..5885342 100644
--- a/test/decl/protocol/req/associated_type_inference.swift
+++ b/test/decl/protocol/req/associated_type_inference.swift
@@ -195,9 +195,9 @@
     func then(_ success: (_: T) -> T) -> Self
 }
 
-public class CorePromise<T> : Thenable { // expected-error{{type 'CorePromise<T>' does not conform to protocol 'Thenable'}}
-    public func then(_ success: @escaping (_ t: T, _: CorePromise<T>) -> T) -> Self {
-        return self.then() { (t: T) -> T in
+public class CorePromise<U> : Thenable { // expected-error{{type 'CorePromise<U>' does not conform to protocol 'Thenable'}}
+    public func then(_ success: @escaping (_ t: U, _: CorePromise<U>) -> U) -> Self {
+        return self.then() { (t: U) -> U in // expected-error{{contextual closure type '(U, CorePromise<U>) -> U' expects 2 arguments, but 1 was used in closure body}}
             return success(t: t, self)
         }
     }
@@ -390,3 +390,13 @@
 struct S13 : P13 { // expected-error{{type 'S13' does not conform to protocol 'P13'}}
   func foo(arg: inout Int) {}
 }
+
+// "Infer" associated type from generic parameter.
+protocol P14 {
+  associatedtype Value
+}
+
+struct P14a<Value>: P14 { }
+
+struct P14b<Value> { }
+extension P14b: P14 { }
diff --git a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift b/validation-test/compiler_crashers/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
similarity index 89%
rename from validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
rename to validation-test/compiler_crashers/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
index 3902655..b57ef5e 100644
--- a/validation-test/compiler_crashers_fixed/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
+++ b/validation-test/compiler_crashers/28807-parentequiv-conformsto-count-proto-0-no-conformance-requirement.swift
@@ -6,5 +6,5 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not %target-swift-frontend %s -emit-ir
+// RUN: not --crash %target-swift-frontend %s -emit-ir
 class a:RangeReplaceableCollection}protocol P{{}typealias e:a{{}}typealias e:Collection