Merge pull request #12662 from eeckstein/globalopt-assert

diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 6fc95dd..8fa09bc 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1635,17 +1635,18 @@
      (DescriptiveDeclKind, DeclName, DeclName))
 
 // "Near matches"
-WARNING(optional_req_near_match,none,
-        "%0 %1 nearly matches optional requirement %2 of protocol %3",
-        (DescriptiveDeclKind, DeclName, DeclName, DeclName))
+WARNING(req_near_match,none,
+        "%0 %1 nearly matches %select{defaulted|optional}2 requirement %3 "
+        "of protocol %4",
+        (DescriptiveDeclKind, DeclName, bool, DeclName, DeclName))
 NOTE(optional_req_nonobjc_near_match_add_objc,none,
      "add '@objc' to provide an Objective-C entrypoint", ())
-NOTE(optional_req_near_match_move,none,
+NOTE(req_near_match_move,none,
      "move %0 to %select{an|another}1 extension to silence this warning",
      (DeclName, unsigned))
-NOTE(optional_req_near_match_nonobjc,none,
+NOTE(req_near_match_nonobjc,none,
      "add '@nonobjc' to silence this %select{warning|error}0", (bool))
-NOTE(optional_req_near_match_access,none,
+NOTE(req_near_match_access,none,
      "make %0 %select{ERROR|private|private|non-public|non-public}1 to silence this "
      "warning", (DeclName, AccessLevel))
 
diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index 508f9e2..cd38cde 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -91,9 +91,12 @@
   using UnresolvedType = llvm::PointerUnion<PotentialArchetype *, Type>;
   class ResolvedType;
 
-  using RequirementRHS =
+  using UnresolvedRequirementRHS =
       llvm::PointerUnion3<Type, PotentialArchetype *, LayoutConstraint>;
 
+  using RequirementRHS =
+    llvm::PointerUnion3<Type, PotentialArchetype *, LayoutConstraint>;
+
   /// The location of a requirement as written somewhere in the source.
   typedef llvm::PointerUnion<const TypeRepr *, const RequirementRepr *>
     WrittenRequirementLoc;
@@ -158,7 +161,7 @@
     /// the equivalence class that is held together by derived constraints.
     struct DerivedSameTypeComponent {
       /// The potential archetype that acts as the anchor for this component.
-      PotentialArchetype *anchor;
+      UnresolvedType anchor;
 
       /// The (best) requirement source within the component that makes the
       /// potential archetypes in this component equivalent to the concrete
@@ -223,15 +226,13 @@
     /// archetype in this equivalence class to a concrete type along with
     /// that concrete type as written.
     Optional<ConcreteConstraint>
-    findAnyConcreteConstraintAsWritten(
-                              PotentialArchetype *preferredPA = nullptr) const;
+    findAnyConcreteConstraintAsWritten(Type preferredType = Type()) const;
 
     /// Find a source of the superclass constraint in this equivalence class
     /// that has a type equivalence to \c superclass, along with that
     /// superclass type as written.
     Optional<ConcreteConstraint>
-    findAnySuperclassConstraintAsWritten(
-                              PotentialArchetype *preferredPA = nullptr) const;
+    findAnySuperclassConstraintAsWritten(Type preferredType = Type()) const;
 
     /// Determine whether conformance to the given protocol is satisfied by
     /// a superclass requirement.
@@ -267,8 +268,8 @@
 
     /// The cached archetype anchor.
     struct {
-      /// The cached archetype anchor itself.
-      PotentialArchetype *anchor = nullptr;
+      /// The cached anchor itself.
+      Type anchor;
 
       /// The number of members of the equivalence class when the archetype
       /// anchor was cached.
@@ -339,7 +340,7 @@
   /// as appropriate based on \c unresolvedHandling.
   ConstraintResult handleUnresolvedRequirement(RequirementKind kind,
                                    UnresolvedType lhs,
-                                   RequirementRHS rhs,
+                                   UnresolvedRequirementRHS rhs,
                                    FloatingRequirementSource source,
                                    EquivalenceClass *unresolvedEquivClass,
                                    UnresolvedHandlingKind unresolvedHandling);
@@ -536,13 +537,14 @@
   ///
   /// \param f A function object that will be passed each requirement
   /// and requirement source.
-  void enumerateRequirements(llvm::function_ref<
+  void enumerateRequirements(
+                    ArrayRef<GenericTypeParamType *> genericParams,
+                    llvm::function_ref<
                       void (RequirementKind kind,
-                            PotentialArchetype *archetype,
+                            Type type,
                             RequirementRHS constraint,
                             const RequirementSource *source)> f);
 
-public:
   /// Retrieve the generic parameters used to describe the generic
   /// signature being built.
   ArrayRef<GenericTypeParamType *> getGenericParams() const;
@@ -727,30 +729,36 @@
   /// class of the given potential archetype.
   void checkConcreteTypeConstraints(
                             ArrayRef<GenericTypeParamType *> genericParams,
-                            PotentialArchetype *pa);
+                            EquivalenceClass *equivClass);
 
   /// Check the superclass constraints within the equivalence
   /// class of the given potential archetype.
   void checkSuperclassConstraints(
                             ArrayRef<GenericTypeParamType *> genericParams,
-                            PotentialArchetype *pa);
+                            EquivalenceClass *equivClass);
 
   /// Check conformance constraints within the equivalence class of the
   /// given potential archetype.
   void checkConformanceConstraints(
                             ArrayRef<GenericTypeParamType *> genericParams,
-                            PotentialArchetype *pa);
+                            EquivalenceClass *equivClass);
 
   /// Check layout constraints within the equivalence class of the given
   /// potential archetype.
   void checkLayoutConstraints(ArrayRef<GenericTypeParamType *> genericParams,
-                              PotentialArchetype *pa);
+                              EquivalenceClass *equivClass);
 
   /// Check same-type constraints within the equivalence class of the
   /// given potential archetype.
   void checkSameTypeConstraints(
                             ArrayRef<GenericTypeParamType *> genericParams,
-                            PotentialArchetype *pa);
+                            EquivalenceClass *equivClass);
+
+  /// Realize a potential archetype for the given type.
+  ///
+  /// The resolved archetype will be written back into the unresolved type,
+  /// to make the next resolution more efficient.
+  PotentialArchetype *realizePotentialArchetype(UnresolvedType &type);
 
 public:
   /// \brief Try to resolve the equivalence class of the given type.
@@ -1656,20 +1664,6 @@
                                        const_cast<PotentialArchetype *>(this));
   }
 
-  /// \brief Retrieve the potential archetype to be used as the anchor for
-  /// potential archetype computations.
-  PotentialArchetype *getArchetypeAnchor(GenericSignatureBuilder &builder);
-
-  /// \brief Retrieve (or create) a nested type that is the current best
-  /// nested archetype anchor (locally) with the given name.
-  ///
-  /// When called on the archetype anchor, this will produce the named
-  /// archetype anchor.
-  PotentialArchetype *getNestedArchetypeAnchor(
-                       Identifier name,
-                       GenericSignatureBuilder &builder,
-                       ArchetypeResolutionKind kind);
-
   /// Update the named nested type when we know this type conforms to the given
   /// protocol.
   ///
@@ -1727,7 +1721,7 @@
 
   Kind kind;
   UnresolvedType lhs;
-  RequirementRHS rhs;
+  UnresolvedRequirementRHS rhs;
   FloatingRequirementSource source;
 
   /// Dump a debugging representation of this delayed requirement class.
diff --git a/include/swift/SIL/TypeLowering.h b/include/swift/SIL/TypeLowering.h
index 7f1904c..84376c5 100644
--- a/include/swift/SIL/TypeLowering.h
+++ b/include/swift/SIL/TypeLowering.h
@@ -531,9 +531,9 @@
 
   llvm::SmallVector<DependentTypeState, 1> DependentTypes;
 
-  llvm::DenseMap<SILDeclRef, SILConstantInfo> ConstantTypes;
+  llvm::DenseMap<SILDeclRef, SILConstantInfo *> ConstantTypes;
   
-  llvm::DenseMap<OverrideKey, SILConstantInfo> ConstantOverrideTypes;
+  llvm::DenseMap<OverrideKey, SILConstantInfo *> ConstantOverrideTypes;
 
   llvm::DenseMap<AnyFunctionRef, CaptureInfo> LoweredCaptures;
 
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 8aefea5..ac5aba6 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2874,7 +2874,7 @@
     if (auto objcAttr = conflicts[0]->getAttrs().getAttribute<ObjCAttr>())
       hasExplicitObjCAttribute = !objcAttr->isImplicit();
     if (!hasExplicitObjCAttribute)
-      Diags.diagnose(conflicts[0], diag::optional_req_near_match_nonobjc, true)
+      Diags.diagnose(conflicts[0], diag::req_near_match_nonobjc, true)
         .fixItInsert(
           conflicts[0]->getAttributeInsertionLoc(/*forModifier=*/false),
           "@nonobjc ");
diff --git a/lib/AST/ASTWalker.cpp b/lib/AST/ASTWalker.cpp
index 053e189..87a506b 100644
--- a/lib/AST/ASTWalker.cpp
+++ b/lib/AST/ASTWalker.cpp
@@ -137,6 +137,12 @@
       if (doIt(Inherit))
         return true;
     }
+    if (auto *Where = ED->getTrailingWhereClause()) {
+      for(auto &Req: Where->getRequirements()) {
+        if (doIt(Req))
+          return true;
+      }
+    }
     for (Decl *M : ED->getMembers()) {
       if (doIt(M))
         return true;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 6a079db..7551830 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3401,7 +3401,7 @@
 }
 
 GenericParamList *ProtocolDecl::createGenericParams(DeclContext *dc) {
-  auto *outerGenericParams = dc->getParent()->getGenericParamsOfContext();
+  auto *outerGenericParams = getParent()->getGenericParamsOfContext();
 
   // The generic parameter 'Self'.
   auto &ctx = getASTContext();
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index e4e89e9..2b31ca1 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -975,6 +975,16 @@
       return;
     }
 
+    // If we have a superclass or concrete requirement, the conformance
+    // we need is stored in it.
+    if (source->kind == RequirementSource::Superclass ||
+        source->kind == RequirementSource::Concrete) {
+      auto conformance = source->getProtocolConformance();
+      assert(conformance.getRequirement() == conformingProto);
+      path.path.push_back({source->getAffectedType(), conformingProto});
+      return;
+    }
+
     // If we still have a parent, keep going.
     if (source->parent) {
       buildPath(reqs, source->parent, conformingProto, rootType,
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 6ab1b65..0ce322a 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -61,6 +61,8 @@
   typedef EquivalenceClass::DerivedSameTypeComponent DerivedSameTypeComponent;
   typedef GenericSignatureBuilder::DelayedRequirement DelayedRequirement;
   typedef GenericSignatureBuilder::ResolvedType ResolvedType;
+  typedef GenericSignatureBuilder::UnresolvedType GSBUnresolvedType;
+  typedef GenericSignatureBuilder::RequirementRHS RequirementRHS;
 } // end anonymous namespace
 
 namespace llvm {
@@ -391,6 +393,20 @@
   };
 } // end namespace llvm
 
+namespace {
+  /// Retrieve the type described by the given unresolved tyoe.
+  Type getUnresolvedType(GSBUnresolvedType type,
+                         ArrayRef<GenericTypeParamType *> genericParams) {
+    if (auto concrete = type.dyn_cast<Type>())
+      return concrete;
+
+    if (auto pa = type.dyn_cast<PotentialArchetype *>())
+      return pa->getDependentType(genericParams);
+
+    return Type();
+  }
+}
+
 #pragma mark Requirement sources
 
 #ifndef NDEBUG
@@ -1681,8 +1697,7 @@
 }
 
 Optional<ConcreteConstraint>
-EquivalenceClass::findAnyConcreteConstraintAsWritten(
-                                      PotentialArchetype *preferredPA) const {
+EquivalenceClass::findAnyConcreteConstraintAsWritten(Type preferredType) const {
   // If we don't have a concrete type, there's no source.
   if (!concreteType) return None;
 
@@ -1691,7 +1706,8 @@
   for (const auto &constraint : concreteTypeConstraints) {
     if (constraint.source->getLoc().isValid()) {
       result = constraint;
-      if (!preferredPA || constraint.isSubjectEqualTo(preferredPA))
+      if (!preferredType ||
+          constraint.getSubjectDependentType({ })->isEqual(preferredType))
         return result;
     }
   }
@@ -1701,7 +1717,7 @@
 
 Optional<ConcreteConstraint>
 EquivalenceClass::findAnySuperclassConstraintAsWritten(
-                                      PotentialArchetype *preferredPA) const {
+                                                   Type preferredType) const {
   // If we don't have a superclass, there's no source.
   if (!superclass) return None;
 
@@ -1712,7 +1728,8 @@
         constraint.value->isEqual(superclass)) {
       result = constraint;
 
-      if (!preferredPA || constraint.isSubjectEqualTo(preferredPA))
+      if (!preferredType ||
+          constraint.getSubjectDependentType({ })->isEqual(preferredType))
         return result;
     }
   }
@@ -1915,11 +1932,108 @@
   return populateResult((nestedTypeNameCache[name] = std::move(entry)));
 }
 
+/// Determine whether any part of this potential archetype's path to the
+/// root contains the given equivalence class.
+static bool pathContainsEquivalenceClass(GenericSignatureBuilder &builder,
+                                         PotentialArchetype *pa,
+                                         EquivalenceClass *equivClass) {
+  // Chase the potential archetype up to the root.
+  for (; pa; pa = pa->getParent()) {
+    // Check whether this potential archetype is in the given equivalence
+    // class.
+    if (pa->getOrCreateEquivalenceClass(builder) == equivClass)
+      return true;
+  }
+
+  return false;
+}
+
 Type EquivalenceClass::getAnchor(
                             GenericSignatureBuilder &builder,
                             ArrayRef<GenericTypeParamType *> genericParams) {
-  auto anchorPA = members.front()->getArchetypeAnchor(builder);
-  return anchorPA->getDependentType(genericParams);
+  // Check whether the cache is valid.
+  if (archetypeAnchorCache.anchor &&
+      archetypeAnchorCache.numMembers == members.size()) {
+    ++NumArchetypeAnchorCacheHits;
+
+    // Reparent the anchor using genericParams.
+    return archetypeAnchorCache.anchor.subst(
+             [&](SubstitutableType *dependentType) {
+               if (auto gp = dyn_cast<GenericTypeParamType>(dependentType)) {
+                 unsigned index =
+                   GenericParamKey(gp).findIndexIn(genericParams);
+                 return Type(genericParams[index]);
+               }
+
+               return Type(dependentType);
+             },
+             MakeAbstractConformanceForGenericType());
+  }
+
+  // Map the members of this equivalence class to the best associated type
+  // within that equivalence class.
+  llvm::SmallDenseMap<EquivalenceClass *, AssociatedTypeDecl *> nestedTypes;
+
+  PotentialArchetype *bestGenericParam = nullptr;
+  for (auto member : members) {
+    // If the member is a generic parameter, keep the best generic parameter.
+    if (member->isGenericParam()) {
+      if (!bestGenericParam ||
+          compareDependentTypes(&member, &bestGenericParam) < 0)
+        bestGenericParam = member;
+      continue;
+    }
+
+    // If we saw a generic parameter, ignore any nested types.
+    if (bestGenericParam) continue;
+
+    // If the nested type doesn't have an associated type, skip it.
+    auto assocType = member->getResolvedAssociatedType();
+    if (!assocType) continue;
+
+    // Dig out the equivalence class of the parent.
+    auto parentEquivClass =
+      member->getParent()->getOrCreateEquivalenceClass(builder);
+
+    // If the path from this member to the root contains this equivalence
+    // class, it cannot be part of the anchor.
+    if (pathContainsEquivalenceClass(builder, member->getParent(), this))
+      continue;
+
+    // Take the best associated type for this equivalence class.
+    assocType = assocType->getAssociatedTypeAnchor();
+    auto &bestAssocType = nestedTypes[parentEquivClass];
+    if (!bestAssocType ||
+        compareAssociatedTypes(assocType, bestAssocType) < 0)
+      bestAssocType = assocType;
+  }
+
+  // If we found a generic parameter, return that.
+  if (bestGenericParam)
+    return bestGenericParam->getDependentType(genericParams);
+
+  // Determine the best anchor among the parent equivalence classes.
+  Type bestParentAnchor;
+  AssociatedTypeDecl *bestAssocType = nullptr;
+  std::pair<EquivalenceClass *, Identifier> bestNestedType;
+  for (const auto &nestedType : nestedTypes) {
+    auto parentAnchor = nestedType.first->getAnchor(builder, genericParams);
+    if (!bestParentAnchor ||
+        compareDependentTypes(parentAnchor, bestParentAnchor) < 0) {
+      bestParentAnchor = parentAnchor;
+      bestAssocType = nestedType.second;
+    }
+  }
+
+  // Form the anchor type.
+  Type anchorType = DependentMemberType::get(bestParentAnchor, bestAssocType);
+
+  // Record the cache miss and update the cache.
+  ++NumArchetypeAnchorCacheMisses;
+  archetypeAnchorCache.anchor = anchorType;
+  archetypeAnchorCache.numMembers = members.size();
+
+  return anchorType;
 }
 
 Type EquivalenceClass::getTypeInContext(GenericSignatureBuilder &builder,
@@ -2157,7 +2271,7 @@
 ConstraintResult GenericSignatureBuilder::handleUnresolvedRequirement(
                                    RequirementKind kind,
                                    UnresolvedType lhs,
-                                   RequirementRHS rhs,
+                                   UnresolvedRequirementRHS rhs,
                                    FloatingRequirementSource source,
                                    EquivalenceClass *unresolvedEquivClass,
                                    UnresolvedHandlingKind unresolvedHandling) {
@@ -2272,7 +2386,7 @@
   // appropriately.
   const RequirementSource *superclassSource;
   if (auto writtenSource =
-        equivClass->findAnySuperclassConstraintAsWritten(nullptr))
+        equivClass->findAnySuperclassConstraintAsWritten())
     superclassSource = writtenSource->source;
   else
     superclassSource = equivClass->superclassConstraints.front().source;
@@ -2287,22 +2401,8 @@
 /// Realize a potential archetype for this type parameter.
 PotentialArchetype *ResolvedType::realizePotentialArchetype(
                                            GenericSignatureBuilder &builder) {
-  if (auto pa = getPotentialArchetypeIfKnown())
-    return pa;
-
-  // Resolve the potential archetype now.
-  Type type = this->type.get<Type>();
-  assert(type->isTypeParameter());
-  auto pa =
-    builder.maybeResolveEquivalenceClass(type,
-                                         ArchetypeResolutionKind::WellFormed,
-                                         /*wantExactPotentialArchetype=*/true)
-      .getPotentialArchetypeIfKnown();
-  assert(pa && "Not a resolvable type!");
-
-  // Cache the potential archetype, now that it's been realized.
-  this->type = pa;
-  return pa;
+  // Realize and cache the potential archetype.
+  return builder.realizePotentialArchetype(type);
 }
 
 Type ResolvedType::getDependentType(GenericSignatureBuilder &builder) const {
@@ -2328,7 +2428,8 @@
 
   // Dig out the associated type.
   AssociatedTypeDecl *assocType = nullptr;
-  if (auto depMemTy = nested.getDependentType(builder)->getAs<DependentMemberType>())
+  if (auto depMemTy =
+        nested.getDependentType(builder)->getAs<DependentMemberType>())
     assocType = depMemTy->getAssocType();
 
   if (!assocType) return;
@@ -2546,60 +2647,6 @@
   llvm_unreachable("potential archetype total order failure");
 }
 
-PotentialArchetype *PotentialArchetype::getArchetypeAnchor(
-                                           GenericSignatureBuilder &builder) {
-  // Find the best archetype within this equivalence class.
-  PotentialArchetype *rep = getRepresentative();
-  PotentialArchetype *anchor;
-  if (auto parent = getParent()) {
-    // For a nested type, retrieve the parent archetype anchor first.
-    auto parentAnchor = parent->getArchetypeAnchor(builder);
-    assert(parentAnchor->getNestingDepth() <= parent->getNestingDepth());
-    anchor = parentAnchor->getNestedArchetypeAnchor(
-                                  getNestedName(), builder,
-                                  ArchetypeResolutionKind::CompleteWellFormed);
-
-    // FIXME: Hack for cases where we couldn't resolve the nested type.
-    if (!anchor)
-      anchor = rep;
-  } else {
-    anchor = rep;
-  }
-
-  auto equivClass = rep->getEquivalenceClassIfPresent();
-  if (!equivClass) return anchor;
-
-  // Check whether
-  if (equivClass->archetypeAnchorCache.anchor &&
-      equivClass->archetypeAnchorCache.numMembers
-        == equivClass->members.size()) {
-    ++NumArchetypeAnchorCacheHits;
-    return equivClass->archetypeAnchorCache.anchor;
-  }
-
-  // Find the best type within this equivalence class.
-  for (auto pa : equivClass->members) {
-    if (compareDependentTypes(&pa, &anchor) < 0)
-      anchor = pa;
-  }
-
-#if SWIFT_GSB_EXPENSIVE_ASSERTIONS
-  // Make sure that we did, in fact, get one that is better than all others.
-  for (auto pa : equivClass->members) {
-    assert((pa == anchor || compareDependentTypes(&anchor, &pa) < 0) &&
-           compareDependentTypes(&pa, &anchor) >= 0 &&
-           "archetype anchor isn't a total order");
-  }
-#endif
-
-  // Record the cache miss and update the cache.
-  ++NumArchetypeAnchorCacheMisses;
-  equivClass->archetypeAnchorCache.anchor = anchor;
-  equivClass->archetypeAnchorCache.numMembers = equivClass->members.size();
-
-  return anchor;
-}
-
 namespace {
   /// Function object used to suppress conflict diagnoses when we know we'll
   /// see them again later.
@@ -2667,32 +2714,6 @@
          SameTypeConflictCheckedLater());
 }
 
-PotentialArchetype *PotentialArchetype::getNestedArchetypeAnchor(
-                                           Identifier name,
-                                           GenericSignatureBuilder &builder,
-                                           ArchetypeResolutionKind kind) {
-  SmallVector<TypeDecl *, 4> concreteDecls;
-  auto bestType =
-    getOrCreateEquivalenceClass(builder)->lookupNestedType(builder, name,
-                                                           &concreteDecls);
-
-  // We didn't find any type with this name.
-  if (!bestType) return nullptr;
-
-  // Resolve the nested type.
-  auto resultPA = updateNestedTypeForConformance(builder, bestType, kind);
-
-  // Update for all of the concrete decls with this name, which will introduce
-  // various same-type constraints.
-  for (auto concreteDecl : concreteDecls) {
-    (void)updateNestedTypeForConformance(builder, concreteDecl,
-                                         ArchetypeResolutionKind::WellFormed);
-  }
-
-  return resultPA;
-}
-
-
 PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
                                               GenericSignatureBuilder &builder,
                                               TypeDecl *type,
@@ -3091,6 +3112,20 @@
   });
 }
 
+PotentialArchetype *GenericSignatureBuilder::realizePotentialArchetype(
+                                                     UnresolvedType &type) {
+  if (auto pa = type.dyn_cast<PotentialArchetype *>())
+    return pa;
+
+  auto pa = maybeResolveEquivalenceClass(type.get<Type>(),
+                                         ArchetypeResolutionKind::WellFormed,
+                                         /*wantExactPotentialArchetype=*/true)
+    .getPotentialArchetypeIfKnown();
+  if (pa) type = pa;
+
+  return pa;
+}
+
 ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass(
                                     Type type,
                                     ArchetypeResolutionKind resolutionKind,
@@ -3119,11 +3154,14 @@
     // Find the nested type declaration for this.
     auto baseEquivClass = resolvedBase.getEquivalenceClass(*this);
     TypeDecl *nestedTypeDecl;
+    SmallVector<TypeDecl *, 4> concreteDecls;
     if (auto assocType = depMemTy->getAssocType()) {
       nestedTypeDecl = assocType;
     } else {
       nestedTypeDecl =
-        baseEquivClass->lookupNestedType(*this, depMemTy->getName());
+        baseEquivClass->lookupNestedType(*this, depMemTy->getName(),
+                                         &concreteDecls);
+
       if (!nestedTypeDecl) {
         return ResolvedType::forUnresolved(baseEquivClass);
       }
@@ -3146,6 +3184,15 @@
     if (!nestedPA)
       return ResolvedType::forUnresolved(baseEquivClass);
 
+    if (resolutionKind != ArchetypeResolutionKind::AlreadyKnown) {
+      // Update for all of the concrete decls with this name, which will
+      // introduce various same-type constraints.
+      for (auto concreteDecl : concreteDecls) {
+        (void)basePA->updateNestedTypeForConformance(*this, concreteDecl,
+                                                     resolutionKind);
+      }
+    }
+
     // If base resolved to the anchor, then the nested potential archetype
     // we found is the resolved potential archetype. Return it directly,
     // so it doesn't need to be resolved again.
@@ -3786,8 +3833,8 @@
 }
 
 /// Map an unresolved type to a requirement right-hand-side.
-static GenericSignatureBuilder::RequirementRHS
-toRequirementRHS(GenericSignatureBuilder::UnresolvedType unresolved) {
+static GenericSignatureBuilder::UnresolvedRequirementRHS
+toUnresolvedRequirementRHS(GenericSignatureBuilder::UnresolvedType unresolved) {
   if (auto pa = unresolved.dyn_cast<PotentialArchetype *>())
     return pa;
 
@@ -3803,7 +3850,7 @@
   if (!resolvedConstraint) {
     return handleUnresolvedRequirement(
                              RequirementKind::Conformance, subject,
-                             toRequirementRHS(constraint), source,
+                             toUnresolvedRequirementRHS(constraint), source,
                              resolvedConstraint.getUnresolvedEquivClass(),
                              unresolvedHandling);
   }
@@ -4036,7 +4083,8 @@
   if (equivClass2 && equivClass2->superclass) {
     const RequirementSource *source2;
     if (auto existingSource2 =
-          equivClass2->findAnySuperclassConstraintAsWritten(OrigT2))
+          equivClass2->findAnySuperclassConstraintAsWritten(
+            OrigT2->getDependentType(getGenericParams())))
       source2 = existingSource2->source;
     else
       source2 = equivClass2->superclassConstraints.front().source;
@@ -4215,7 +4263,8 @@
   auto resolved1 = resolve(paOrT1, source);
   if (!resolved1) {
     return handleUnresolvedRequirement(RequirementKind::SameType, paOrT1,
-                                       toRequirementRHS(paOrT2), source,
+                                       toUnresolvedRequirementRHS(paOrT2),
+                                       source,
                                        resolved1.getUnresolvedEquivClass(),
                                        unresolvedHandling);
   }
@@ -4223,7 +4272,8 @@
   auto resolved2 = resolve(paOrT2, source);
   if (!resolved2) {
     return handleUnresolvedRequirement(RequirementKind::SameType, paOrT1,
-                                       toRequirementRHS(paOrT2), source,
+                                       toUnresolvedRequirementRHS(paOrT2),
+                                       source,
                                        resolved2.getUnresolvedEquivClass(),
                                        unresolvedHandling);
   }
@@ -4798,8 +4848,6 @@
   // Check for recursive or conflicting same-type bindings and superclass
   // constraints.
   for (auto &equivClass : Impl->EquivalenceClasses) {
-    auto archetype = equivClass.members.front()->getRepresentative();
-
     if (equivClass.concreteType) {
       // Check for recursive same-type bindings.
       if (isRecursiveConcreteType(&equivClass, /*isSuperclass=*/false)) {
@@ -4809,13 +4857,13 @@
 
           Diags.diagnose(constraint->source->getLoc(),
                          diag::recursive_same_type_constraint,
-                         archetype->getDependentType(genericParams),
+                         constraint->getSubjectDependentType(genericParams),
                          constraint->value);
         }
 
         equivClass.recursiveConcreteType = true;
       } else {
-        checkConcreteTypeConstraints(genericParams, archetype);
+        checkConcreteTypeConstraints(genericParams, &equivClass);
       }
     }
 
@@ -4833,12 +4881,12 @@
 
         equivClass.recursiveSuperclassType = true;
       } else {
-        checkSuperclassConstraints(genericParams, archetype);
+        checkSuperclassConstraints(genericParams, &equivClass);
       }
     }
 
-    checkConformanceConstraints(genericParams, archetype);
-    checkLayoutConstraints(genericParams, archetype);
+    checkConformanceConstraints(genericParams, &equivClass);
+    checkLayoutConstraints(genericParams, &equivClass);
   };
 
   // FIXME: Expand all conformance requirements. This is expensive :(
@@ -4847,10 +4895,9 @@
   }
 
   // Check same-type constraints.
-  for (const auto &equivClass : Impl->EquivalenceClasses) {
-    checkSameTypeConstraints(genericParams,
-                             equivClass.members[0]->getRepresentative());
-  };
+  for (auto &equivClass : Impl->EquivalenceClasses) {
+    checkSameTypeConstraints(genericParams, &equivClass);
+  }
 
   // Check for generic parameters which have been made concrete or equated
   // with each other.
@@ -4928,7 +4975,7 @@
 
 /// Turn a requirement right-hand side into an unresolved type.
 static GenericSignatureBuilder::UnresolvedType asUnresolvedType(
-                                GenericSignatureBuilder::RequirementRHS rhs) {
+                        GenericSignatureBuilder::UnresolvedRequirementRHS rhs) {
   if (auto pa = rhs.dyn_cast<PotentialArchetype *>())
     return GenericSignatureBuilder::UnresolvedType(pa);
 
@@ -5291,11 +5338,7 @@
 
 void GenericSignatureBuilder::checkConformanceConstraints(
                           ArrayRef<GenericTypeParamType *> genericParams,
-                          PotentialArchetype *pa) {
-  auto equivClass = pa->getEquivalenceClassIfPresent();
-  if (!equivClass || equivClass->conformsTo.empty())
-    return;
-
+                          EquivalenceClass *equivClass) {
   for (auto &entry : equivClass->conformsTo) {
     // Remove self-derived constraints.
     assert(!entry.second.empty() && "No constraints to work with?");
@@ -5343,7 +5386,8 @@
 namespace swift {
   bool operator<(const DerivedSameTypeComponent &lhs,
                  const DerivedSameTypeComponent &rhs) {
-    return compareDependentTypes(&lhs.anchor, &rhs.anchor) < 0;
+    return compareDependentTypes(getUnresolvedType(lhs.anchor, { }),
+                                 getUnresolvedType(rhs.anchor, { })) < 0;
   }
 } // namespace swift
 
@@ -5479,7 +5523,9 @@
     componentOf[depType] = componentIndex;
 
     // If this is a better anchor, record it.
-    if (compareDependentTypes(&pa, &components[componentIndex].anchor) < 0)
+    if (compareDependentTypes(
+                depType,
+                getUnresolvedType(components[componentIndex].anchor, { })) < 0)
       components[componentIndex].anchor = pa;
   }
 
@@ -5796,7 +5842,9 @@
       auto &newComponent = newComponents[newRepresentativeIndex];
 
       // If the old component has a better anchor, keep it.
-      if (compareDependentTypes(&oldComponent.anchor, &newComponent.anchor) < 0)
+      if (compareDependentTypes(
+                            getUnresolvedType(oldComponent.anchor, { }),
+                            getUnresolvedType(newComponent.anchor, { })) < 0)
         newComponent.anchor = oldComponent.anchor;
 
       // If the old component has a better concrete type source, keep it.
@@ -5818,9 +5866,8 @@
 
 void GenericSignatureBuilder::checkSameTypeConstraints(
                           ArrayRef<GenericTypeParamType *> genericParams,
-                          PotentialArchetype *pa) {
-  auto equivClass = pa->getEquivalenceClassIfPresent();
-  if (!equivClass || !equivClass->derivedSameTypeComponents.empty())
+                          EquivalenceClass *equivClass) {
+  if (!equivClass->derivedSameTypeComponents.empty())
     return;
 
   bool anyDerivedViaConcrete = false;
@@ -6022,10 +6069,7 @@
 
 void GenericSignatureBuilder::checkConcreteTypeConstraints(
                                  ArrayRef<GenericTypeParamType *> genericParams,
-                                 PotentialArchetype *representative) {
-  auto equivClass = representative->getOrCreateEquivalenceClass(*this);
-  assert(equivClass->concreteType && "No concrete type to check");
-
+                                 EquivalenceClass *equivClass) {
   checkConstraintList<Type>(
     genericParams, equivClass->concreteTypeConstraints,
     [&](const ConcreteConstraint &constraint) {
@@ -6059,8 +6103,7 @@
 
 void GenericSignatureBuilder::checkSuperclassConstraints(
                                  ArrayRef<GenericTypeParamType *> genericParams,
-                                 PotentialArchetype *representative) {
-  auto equivClass = representative->getOrCreateEquivalenceClass(*this);
+                                 EquivalenceClass *equivClass) {
   assert(equivClass->superclass && "No superclass constraint?");
 
   // FIXME: We should be substituting in the canonical type in context so
@@ -6148,9 +6191,8 @@
 
 void GenericSignatureBuilder::checkLayoutConstraints(
                                 ArrayRef<GenericTypeParamType *> genericParams,
-                                PotentialArchetype *pa) {
-  auto equivClass = pa->getEquivalenceClassIfPresent();
-  if (!equivClass || !equivClass->layout) return;
+                                EquivalenceClass *equivClass) {
+  if (!equivClass->layout) return;
 
   checkConstraintList<LayoutConstraint>(
     genericParams, equivClass->layoutConstraints,
@@ -6188,98 +6230,103 @@
 
     return bestSource;
   }
+
+  using SameTypeComponentRef = std::pair<EquivalenceClass *, unsigned>;
+
 } // end anonymous namespace
 
-void GenericSignatureBuilder::enumerateRequirements(llvm::function_ref<
+static int compareSameTypeComponents(const SameTypeComponentRef *lhsPtr,
+                                     const SameTypeComponentRef *rhsPtr){
+  Type lhsType = getUnresolvedType(
+      lhsPtr->first->derivedSameTypeComponents[lhsPtr->second].anchor,
+      { });
+  Type rhsType = getUnresolvedType(
+      rhsPtr->first->derivedSameTypeComponents[rhsPtr->second].anchor,
+      { });
+
+  return compareDependentTypes(lhsType, rhsType);
+}
+
+void GenericSignatureBuilder::enumerateRequirements(
+                   ArrayRef<GenericTypeParamType *> genericParams,
+                   llvm::function_ref<
                      void (RequirementKind kind,
-                           PotentialArchetype *archetype,
-                           GenericSignatureBuilder::RequirementRHS constraint,
+                           Type type,
+                           RequirementRHS constraint,
                            const RequirementSource *source)> f) {
-  // Collect all archetypes.
-  SmallVector<PotentialArchetype *, 8> archetypes;
+  // Collect all of the subject types that will be involved in constraints.
+  SmallVector<SameTypeComponentRef, 8> subjects;
   for (auto &equivClass : Impl->EquivalenceClasses) {
     if (equivClass.derivedSameTypeComponents.empty()) {
-      checkSameTypeConstraints(getGenericParams(),
-                               equivClass.members.front()->getRepresentative());
+      checkSameTypeConstraints(getGenericParams(), &equivClass);
     }
 
-    for (const auto &component : equivClass.derivedSameTypeComponents) {
-      archetypes.push_back(component.anchor);
-    }
+    for (unsigned i : indices(equivClass.derivedSameTypeComponents))
+      subjects.push_back({&equivClass, i});
   }
 
-  // Sort the archetypes in canonical order.
-  llvm::array_pod_sort(archetypes.begin(), archetypes.end(),
-                       compareDependentTypes);
+  // Sort the subject types in canonical order.
+  llvm::array_pod_sort(subjects.begin(), subjects.end(),
+                       compareSameTypeComponents);
 
-  auto genericParams = getGenericParams();
-  for (auto *archetype : archetypes) {
-    // Check whether this archetype is one of the anchors within its
-    // connected component. If so, we may need to emit a same-type constraint.
-    //
-    // FIXME: O(n) in the number of implied connected components within the
-    // equivalence class. The equivalence class should be small, but...
-    auto equivClass = archetype->getOrCreateEquivalenceClass(*this);
+  for (const auto &subject : subjects) {
+    // Dig out the subject type and its corresponding component.
+    auto equivClass = subject.first;
+    auto &component = equivClass->derivedSameTypeComponents[subject.second];
+    Type subjectType = getUnresolvedType(component.anchor, genericParams);
 
-    assert(!equivClass->derivedSameTypeComponents.empty() &&
-           "Didn't compute derived same-type components?");
-    auto knownAnchor =
-      std::find_if(equivClass->derivedSameTypeComponents.begin(),
-                   equivClass->derivedSameTypeComponents.end(),
-                   [&](const DerivedSameTypeComponent &component) {
-                     return component.anchor == archetype;
-                   });
+    // If this equivalence class is bound to a concrete type, equate the
+    // anchor with a concrete type.
+    if (Type concreteType = equivClass->concreteType) {
+      // If the parent of this anchor is also a concrete type, don't
+      // create a requirement.
+      if (!subjectType->is<GenericTypeParamType>() &&
+          maybeResolveEquivalenceClass(
+            subjectType->castTo<DependentMemberType>()->getBase(),
+            ArchetypeResolutionKind::WellFormed,
+            /*wantExactPotentialArchetype=*/false)
+            .getEquivalenceClass(*this)->concreteType)
+        continue;
+
+      auto source =
+        component.concreteTypeSource
+          ? component.concreteTypeSource
+          : RequirementSource::forAbstract(*this, subjectType);
+
+      // Drop recursive and invalid concrete-type constraints.
+      if (equivClass->recursiveConcreteType ||
+          equivClass->invalidConcreteType)
+        continue;
+
+      f(RequirementKind::SameType, subjectType, concreteType, source);
+      continue;
+    }
+
     std::function<void()> deferredSameTypeRequirement;
 
-    if (knownAnchor != equivClass->derivedSameTypeComponents.end()) {
-      // If this equivalence class is bound to a concrete type, equate the
-      // anchor with a concrete type.
-      if (Type concreteType = equivClass->concreteType) {
-        // If the parent of this anchor is also a concrete type, don't
-        // create a requirement.
-        if (!archetype->isGenericParam() &&
-            archetype->getParent()->isConcreteType())
-          continue;
-
-        auto source =
-          knownAnchor->concreteTypeSource
-            ? knownAnchor->concreteTypeSource
-            : RequirementSource::forAbstract(*this,
-                             archetype->getDependentType(getGenericParams()));
-
-        // Drop recursive and invalid concrete-type constraints.
-        if (equivClass->recursiveConcreteType ||
-            equivClass->invalidConcreteType)
-          continue;
-
-        f(RequirementKind::SameType, archetype, concreteType, source);
-        continue;
-      }
-
-      // If we're at the last anchor in the component, do nothing;
-      auto nextAnchor = knownAnchor;
-      ++nextAnchor;
-      if (nextAnchor != equivClass->derivedSameTypeComponents.end() /* &&
-          !equivClass->areAllRequirementsDerived()*/) {
-        // Form a same-type constraint from this anchor within the component
-        // to the next.
-        // FIXME: Distinguish between explicit and inferred here?
-        auto otherPA = nextAnchor->anchor;
-        deferredSameTypeRequirement =
-          [&f, archetype, otherPA, this, genericParams] {
-            f(RequirementKind::SameType, archetype, otherPA,
-              RequirementSource::forAbstract(
-                                     *this,
-                                     archetype->getDependentType(genericParams)));
-          };
-      }
+    // If we're at the last anchor in the component, do nothing;
+    if (subject.second + 1 != equivClass->derivedSameTypeComponents.size()) {
+      // Form a same-type constraint from this anchor within the component
+      // to the next.
+      // FIXME: Distinguish between explicit and inferred here?
+      auto &nextComponent =
+        equivClass->derivedSameTypeComponents[subject.second + 1];
+      Type otherSubjectType =
+        getUnresolvedType(nextComponent.anchor, genericParams);
+      deferredSameTypeRequirement =
+        [&f, subjectType, otherSubjectType, this, genericParams] {
+          f(RequirementKind::SameType, subjectType, otherSubjectType,
+            RequirementSource::forAbstract(*this, otherSubjectType));
+        };
     }
+
     SWIFT_DEFER {
       if (deferredSameTypeRequirement) deferredSameTypeRequirement();
     };
 
-    // If this is not the archetype anchor, we're done.
-    if (archetype != archetype->getArchetypeAnchor(*this))
+    // If this is not the first component anchor in its equivalence class,
+    // we're done.
+    if (subject.second > 0)
       continue;
 
     // If we have a superclass, produce a superclass requirement
@@ -6291,12 +6338,9 @@
           });
 
       if (!bestSource)
-        bestSource =
-          RequirementSource::forAbstract(
-                                 *this,
-                                 archetype->getDependentType(genericParams));
+        bestSource = RequirementSource::forAbstract(*this, subjectType);
 
-      f(RequirementKind::Superclass, archetype, equivClass->superclass,
+      f(RequirementKind::Superclass, subjectType, equivClass->superclass,
         *bestSource);
     }
 
@@ -6308,12 +6352,9 @@
                             return layout == equivClass->layout;
                           });
       if (!bestSource)
-        bestSource =
-          RequirementSource::forAbstract(
-                                   *this,
-                                   archetype->getDependentType(genericParams));
+        bestSource = RequirementSource::forAbstract(*this, subjectType);
 
-      f(RequirementKind::Layout, archetype, equivClass->layout, *bestSource);
+      f(RequirementKind::Layout, subjectType, equivClass->layout, *bestSource);
     }
 
     // Enumerate conformance requirements.
@@ -6341,7 +6382,7 @@
     // Enumerate the conformance requirements.
     for (auto proto : protocols) {
       assert(protocolSources.count(proto) == 1 && "Missing conformance?");
-      f(RequirementKind::Conformance, archetype, 
+      f(RequirementKind::Conformance, subjectType,
         proto->getDeclaredInterfaceType(),
         protocolSources.find(proto)->second);
     }
@@ -6354,29 +6395,30 @@
 
 void GenericSignatureBuilder::dump(llvm::raw_ostream &out) {
   out << "Requirements:";
-  enumerateRequirements([&](RequirementKind kind,
-                            PotentialArchetype *archetype,
-                            GenericSignatureBuilder::RequirementRHS constraint,
+  enumerateRequirements(getGenericParams(),
+                        [&](RequirementKind kind,
+                            Type type,
+                            RequirementRHS constraint,
                             const RequirementSource *source) {
     switch (kind) {
     case RequirementKind::Conformance:
     case RequirementKind::Superclass:
       out << "\n  ";
-      out << archetype->getDebugName() << " : " 
+      out << type.getString() << " : "
           << constraint.get<Type>().getString() << " [";
       source->print(out, &Context.SourceMgr);
       out << "]";
       break;
     case RequirementKind::Layout:
       out << "\n  ";
-      out << archetype->getDebugName() << " : "
+      out << type.getString() << " : "
           << constraint.get<LayoutConstraint>().getString() << " [";
       source->print(out, &Context.SourceMgr);
       out << "]";
       break;
     case RequirementKind::SameType:
       out << "\n  ";
-      out << archetype->getDebugName() << " == " ;
+      out << type.getString() << " == " ;
       if (auto secondType = constraint.dyn_cast<Type>()) {
         out << secondType.getString();
       } else {
@@ -6412,9 +6454,11 @@
 static void collectRequirements(GenericSignatureBuilder &builder,
                                 ArrayRef<GenericTypeParamType *> params,
                                 SmallVectorImpl<Requirement> &requirements) {
-  builder.enumerateRequirements([&](RequirementKind kind,
-          GenericSignatureBuilder::PotentialArchetype *archetype,
-          GenericSignatureBuilder::RequirementRHS type,
+  builder.enumerateRequirements(
+      params,
+      [&](RequirementKind kind,
+          Type depTy,
+          RequirementRHS type,
           const RequirementSource *source) {
     // Filter out derived requirements... except for concrete-type requirements
     // on generic parameters. The exception is due to the canonicalization of
@@ -6422,31 +6466,26 @@
     // they have been mapped to a concrete type.
     if (source->isDerivedRequirement() &&
         !(kind == RequirementKind::SameType &&
-          archetype->isGenericParam() &&
+          depTy->is<GenericTypeParamType>() &&
           type.is<Type>()))
       return;
 
-    auto depTy = archetype->getDependentType(params);
-
     if (depTy->hasError())
       return;
 
     Type repTy;
     if (auto concreteTy = type.dyn_cast<Type>()) {
-      // Maybe we were equated to a concrete type...
+      // Maybe we were equated to a concrete or dependent type...
       repTy = concreteTy;
 
       // Drop requirements involving concrete types containing
       // unresolved associated types.
       if (repTy->findUnresolvedDependentMemberType())
         return;
-    } else if (auto layoutConstraint = type.dyn_cast<LayoutConstraint>()) {
+    } else {
+      auto layoutConstraint = type.get<LayoutConstraint>();
       requirements.push_back(Requirement(kind, depTy, layoutConstraint));
       return;
-    } else {
-      // ...or to a dependent type.
-      repTy = type.get<GenericSignatureBuilder::PotentialArchetype *>()
-          ->getDependentType(params);
     }
 
     if (repTy->hasError())
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index eec64f7..3acbc1c 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -1924,7 +1924,7 @@
 const SILConstantInfo &TypeConverter::getConstantInfo(SILDeclRef constant) {
   auto found = ConstantTypes.find(constant);
   if (found != ConstantTypes.end())
-    return found->second;
+    return *found->second;
 
   // First, get a function type for the constant.  This creates the
   // right type for a getter or setter.
@@ -1956,14 +1956,17 @@
         silFnType.print(llvm::dbgs());
         llvm::dbgs() << "\n");
 
-  auto result = ConstantTypes.try_emplace(constant,
-                                          formalInterfaceType,
-                                          bridgedTypes.Pattern,
-                                          loweredInterfaceType,
-                                          silFnType,
-                                          genericEnv);
-  assert(result.second);
-  return result.first->second;
+  auto resultBuf = M.allocate(sizeof(SILConstantInfo),
+                              alignof(SILConstantInfo));
+
+  auto result = ::new (resultBuf) SILConstantInfo{formalInterfaceType,
+                                                  bridgedTypes.Pattern,
+                                                  loweredInterfaceType,
+                                                  silFnType,
+                                                  genericEnv};
+  auto inserted = ConstantTypes.insert({constant, result});
+  assert(inserted.second);
+  return *result;
 }
 
 /// Returns the SILParameterInfo for the given declaration's `self` parameter.
@@ -2092,7 +2095,7 @@
 
   auto found = ConstantOverrideTypes.find({derived, base});
   if (found != ConstantOverrideTypes.end())
-    return found->second;
+    return *found->second;
 
   assert(requiresNewVTableEntry(base) && "base must not be an override");
 
@@ -2146,14 +2149,18 @@
                                                derived);
 
   // Build the SILConstantInfo and cache it.
-  auto result = ConstantOverrideTypes.try_emplace({derived, base},
+  auto resultBuf = M.allocate(sizeof(SILConstantInfo),
+                              alignof(SILConstantInfo));
+  auto result = ::new (resultBuf) SILConstantInfo{
     derivedInterfaceTy,
     bridgedTypes.Pattern,
     overrideLoweredInterfaceTy,
     fnTy,
-    derivedInfo.GenericEnv);
-  assert(result.second);
-  return result.first->second;
+    derivedInfo.GenericEnv};
+  
+  auto inserted = ConstantOverrideTypes.insert({{derived, base}, result});
+  assert(inserted.second);
+  return *result;
 }
 
 namespace {
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 3955625..73d54ed 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -2719,7 +2719,7 @@
 
       // Suggest '@nonobjc' to suppress this error, and not try to
       // infer @objc for anything.
-      tc.diagnose(decl, diag::optional_req_near_match_nonobjc, true)
+      tc.diagnose(decl, diag::req_near_match_nonobjc, true)
         .fixItInsert(decl->getAttributeInsertionLoc(false), "@nonobjc ");
       break;
     }
@@ -8170,6 +8170,14 @@
     return;
   }
 
+  // If the nominal type has a generic signature that we didn't otherwise
+  // handle yet, use it directly.
+  if (auto genericSig = nominal->getGenericSignature()) {
+    auto genericEnv = genericSig->createGenericEnvironment();
+    ext->setGenericEnvironment(genericEnv);
+    return;
+  }
+
   assert(extendedType->is<NominalType>());
 }
 
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index dc6ba29..e86a809 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -2063,6 +2063,7 @@
     llvm::SmallVector<ConformanceChecker, 4> AllUsedCheckers;
     llvm::SmallVector<NormalProtocolConformance*, 4> AllConformances;
     llvm::SetVector<ValueDecl*> MissingWitnesses;
+    llvm::SmallPtrSet<ValueDecl *, 8> CoveredMembers;
 
     /// Check one conformance.
     ProtocolConformance * checkIndividualConformance(
@@ -2083,6 +2084,11 @@
       return llvm::makeArrayRef(UnsatisfiedReqs);
     }
 
+    /// Whether this member is "covered" by one of the conformances.
+    bool isCoveredMember(ValueDecl *member) const {
+      return CoveredMembers.count(member) > 0;
+    }
+
     /// Check all conformances and emit diagnosis globally.
     void checkAllConformances();
   };
@@ -2092,11 +2098,24 @@
     if (conformance->isInvalid()) return false;
     if (isa<TypeDecl>(req)) return false;
 
+    auto witness = conformance->hasWitness(req)
+      ? conformance->getWitness(req, nullptr).getDecl()
+      : nullptr;
+
     // An optional requirement might not have a witness...
-    if (!conformance->hasWitness(req) ||
-        !conformance->getWitness(req, nullptr).getDecl())
+    if (!witness)
       return req->getAttrs().hasAttribute<OptionalAttr>();
 
+    // If the witness lands within the declaration context of the conformance,
+    // record it as a "covered" member.
+    if (witness->getDeclContext() == conformance->getDeclContext())
+      CoveredMembers.insert(witness);
+
+    // The witness might come from a protocol or protocol extension.
+    if (witness->getDeclContext()
+          ->getAsProtocolOrProtocolExtensionContext())
+      return true;
+
     return false;
   }
 
@@ -5535,7 +5554,7 @@
           // If the requirement is optional, @nonobjc suppresses the
           // diagnostic.
           if (isOptional) {
-            TC.diagnose(witness, diag::optional_req_near_match_nonobjc, false)
+            TC.diagnose(witness, diag::req_near_match_nonobjc, false)
               .fixItInsert(witness->getAttributeInsertionLoc(false),
                            "@nonobjc ");
           }
@@ -6213,11 +6232,14 @@
   DeclName reqName = req->getFullName();
   DeclName witnessName = witness->getFullName();
 
-  // Apply the omit-needless-words heuristics to both names.
-  if (auto adjustedReqName = ::omitNeedlessWords(tc, req))
-    reqName = *adjustedReqName;
-  if (auto adjustedWitnessName = ::omitNeedlessWords(tc, witness))
-    witnessName = *adjustedWitnessName;
+  // For @objc protocols, apply the omit-needless-words heuristics to
+  // both names.
+  if (cast<ProtocolDecl>(req->getDeclContext())->isObjC()) {
+    if (auto adjustedReqName = ::omitNeedlessWords(tc, req))
+      reqName = *adjustedReqName;
+    if (auto adjustedWitnessName = ::omitNeedlessWords(tc, witness))
+      witnessName = *adjustedWitnessName;
+  }
 
   return scorePotentiallyMatchingNames(reqName, witnessName, isa<FuncDecl>(req),
                                        limit);
@@ -6317,19 +6339,40 @@
   return length;
 }
 
+/// Determine whether a particular declaration is generic.
+static bool isGeneric(ValueDecl *decl) {
+  if (auto func = dyn_cast<AbstractFunctionDecl>(decl))
+    return func->isGeneric();
+  if (auto subscript = dyn_cast<SubscriptDecl>(decl))
+    return subscript->isGeneric();
+  return false;
+}
+
 /// Determine whether we should warn about the given witness being a close
 /// match for the given optional requirement.
-static bool shouldWarnAboutPotentialWitness(ValueDecl *req,
-                                            ValueDecl *witness,
-                                            AccessLevel access,
-                                            unsigned score) {
+static bool shouldWarnAboutPotentialWitness(
+                                      MultiConformanceChecker &groupChecker,
+                                      ValueDecl *req,
+                                      ValueDecl *witness,
+                                      AccessLevel access,
+                                      unsigned score) {
+  // If the witness is covered, don't warn about it.
+  if (groupChecker.isCoveredMember(witness))
+    return false;
+
   // If the warning couldn't be suppressed, don't warn.
   if (!canSuppressPotentialWitnessWarningWithMovement(req, witness) &&
       !canSuppressPotentialWitnessWarningWithNonObjC(req, witness))
     return false;
 
-  // If the potential witness is already marked @nonobjc, don't warn.
-  if (witness->getAttrs().hasAttribute<NonObjCAttr>())
+  // If the potential witness for an @objc requirement is already
+  // marked @nonobjc, don't warn.
+  if (req->isObjC() && witness->getAttrs().hasAttribute<NonObjCAttr>())
+    return false;
+
+  // If the witness is generic and requirement is not, or vice-versa,
+  // don't warn.
+  if (isGeneric(req) != isGeneric(witness))
     return false;
 
   // Don't warn if the potential witness has been explicitly given less
@@ -6360,9 +6403,10 @@
   auto proto = cast<ProtocolDecl>(req->getDeclContext());
 
   // Primary warning.
-  tc.diagnose(witness, diag::optional_req_near_match,
+  tc.diagnose(witness, diag::req_near_match,
               witness->getDescriptiveKind(),
               witness->getFullName(),
+              req->getAttrs().hasAttribute<OptionalAttr>(),
               req->getFullName(),
               proto->getFullName());
 
@@ -6385,21 +6429,21 @@
   // If moving the declaration can help, suggest that.
   if (auto move
         = canSuppressPotentialWitnessWarningWithMovement(req, witness)) {
-    tc.diagnose(witness, diag::optional_req_near_match_move,
+    tc.diagnose(witness, diag::req_near_match_move,
                 witness->getFullName(), static_cast<unsigned>(*move));
   }
 
   // If adding 'private', 'fileprivate', or 'internal' can help, suggest that.
   if (access > AccessLevel::FilePrivate &&
       !witness->getAttrs().hasAttribute<AccessControlAttr>()) {
-    tc.diagnose(witness, diag::optional_req_near_match_access,
+    tc.diagnose(witness, diag::req_near_match_access,
                 witness->getFullName(), access)
       .fixItInsert(witness->getAttributeInsertionLoc(true), "private ");
   }
 
   // If adding @nonobjc can help, suggest that.
   if (canSuppressPotentialWitnessWarningWithNonObjC(req, witness)) {
-    tc.diagnose(witness, diag::optional_req_near_match_nonobjc, false)
+    tc.diagnose(witness, diag::req_near_match_nonobjc, false)
       .fixItInsert(witness->getAttributeInsertionLoc(false), "@nonobjc ");
   }
 
@@ -6647,8 +6691,8 @@
 
         bool valueIsType = isa<TypeDecl>(value);
         for (auto requirement
-              : diag.Protocol->lookupDirect(value->getFullName(),
-                                            /*ignoreNewExtensions=*/true)) {
+                : diag.Protocol->lookupDirect(value->getFullName(),
+                                              /*ignoreNewExtensions=*/true)) {
           auto requirementIsType = isa<TypeDecl>(requirement);
           if (valueIsType != requirementIsType)
             continue;
@@ -6742,8 +6786,8 @@
             bestOptionalReqs.begin(),
             bestOptionalReqs.end(),
             [&](ValueDecl *req) {
-              return !shouldWarnAboutPotentialWitness(req, value, defaultAccess,
-                                                      bestScore);
+              return !shouldWarnAboutPotentialWitness(groupChecker, req, value,
+                                                      defaultAccess, bestScore);
             }),
           bestOptionalReqs.end());
       }
@@ -6764,7 +6808,7 @@
         assert(diagnosed && "Failed to find conformance to diagnose?");
         (void)diagnosed;
 
-        // Remove this optional requirement from the list. We don't want to
+        // Remove this requirement from the list. We don't want to
         // complain about it twice.
         unsatisfiedReqs.erase(std::find(unsatisfiedReqs.begin(),
                                         unsatisfiedReqs.end(),
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 77750af..e40ef87 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -760,6 +760,10 @@
       break;
   }
 
+  // Don't create empty generic parameter lists.
+  if (params.empty())
+    return nullptr;
+
   auto paramList = GenericParamList::create(getContext(), SourceLoc(),
                                             params, SourceLoc(), { },
                                             SourceLoc());
diff --git a/stdlib/public/core/RangeReplaceableCollection.swift.gyb b/stdlib/public/core/RangeReplaceableCollection.swift.gyb
index eda9d20..fd539dd 100644
--- a/stdlib/public/core/RangeReplaceableCollection.swift.gyb
+++ b/stdlib/public/core/RangeReplaceableCollection.swift.gyb
@@ -354,6 +354,9 @@
   mutating func removeAll(keepingCapacity keepCapacity: Bool /*= false*/)
 
   // FIXME(ABI): Associated type inference requires this.
+  subscript(bounds: Index) -> Element { get }
+
+  // FIXME(ABI): Associated type inference requires this.
   subscript(bounds: Range<Index>) -> SubSequence { get }
 }
 
diff --git a/stdlib/public/core/Shims.swift b/stdlib/public/core/Shims.swift
index 4596d47..3b453a1 100644
--- a/stdlib/public/core/Shims.swift
+++ b/stdlib/public/core/Shims.swift
@@ -29,6 +29,7 @@
 /// A dummy value to be used as the target for `mutationsPtr` in fast
 /// enumeration implementations.
 @_versioned // FIXME(sil-serialize-all)
+@_fixed_layout
 internal var _fastEnumerationStorageMutationsTarget: CUnsignedLong = 0
 
 /// A dummy pointer to be used as `mutationsPtr` in fast enumeration
@@ -36,6 +37,8 @@
 @_inlineable // FIXME(sil-serialize-all)
 public // SPI(Foundation)
 var _fastEnumerationStorageMutationsPtr: UnsafeMutablePointer<CUnsignedLong> {
+  // Note that either _fastEnumerationStorageMutationsPtr should be
+  // @_fixed_layout, or this function should not be @_inlineable.
   return UnsafeMutablePointer(
       Builtin.addressof(&_fastEnumerationStorageMutationsTarget))
 }
diff --git a/test/Generics/requirement_inference.swift b/test/Generics/requirement_inference.swift
index ca0b3b6..bf6bfa2 100644
--- a/test/Generics/requirement_inference.swift
+++ b/test/Generics/requirement_inference.swift
@@ -295,8 +295,8 @@
 // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P22>
 // CHECK: Protocol requirement signature:
 // CHECK: .P22@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : P20, Self.A == X20<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : P20, τ_0_0.A == X20<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X20<Self.B>, Self.B : P20>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X20<τ_0_0.B>, τ_0_0.B : P20>
 protocol P22 {
   associatedtype A
   associatedtype B where A == X20<B>
@@ -306,8 +306,8 @@
 // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P23>
 // CHECK: Protocol requirement signature:
 // CHECK: .P23@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : P20, Self.A == X20<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : P20, τ_0_0.A == X20<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X20<Self.B>, Self.B : P20>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X20<τ_0_0.B>, τ_0_0.B : P20>
 protocol P23 {
   associatedtype A
   associatedtype B: P20
@@ -323,16 +323,16 @@
 }
 
 // CHECK-LABEL: .P25a@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : P20, Self.A == X24<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : P20, τ_0_0.A == X24<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X24<Self.B>, Self.B : P20>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X24<τ_0_0.B>, τ_0_0.B : P20>
 protocol P25a {
   associatedtype A: P24 // expected-warning{{redundant conformance constraint 'Self.A': 'P24'}}
   associatedtype B where A == X24<B> // expected-note{{conformance constraint 'Self.A': 'P24' implied here}}
 }
 
 // CHECK-LABEL: .P25b@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : P20, Self.A == X24<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : P20, τ_0_0.A == X24<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X24<Self.B>, Self.B : P20>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X24<τ_0_0.B>, τ_0_0.B : P20>
 protocol P25b {
   associatedtype A
   associatedtype B where A == X24<B>
@@ -353,16 +353,16 @@
 }
 
 // CHECK-LABEL: .P27a@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : X3, Self.A == X26<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : X3, τ_0_0.A == X26<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X26<Self.B>, Self.B : X3>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X26<τ_0_0.B>, τ_0_0.B : X3>
 protocol P27a {
   associatedtype A: P26 // expected-warning{{redundant conformance constraint 'Self.A': 'P26'}}
   associatedtype B where A == X26<B> // expected-note{{conformance constraint 'Self.A': 'P26' implied here}}
 }
 
 // CHECK-LABEL: .P27b@
-// CHECK-NEXT: Requirement signature: <Self where Self.B : X3, Self.A == X26<Self.B>>
-// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.B : X3, τ_0_0.A == X26<τ_0_0.B>>
+// CHECK-NEXT: Requirement signature: <Self where Self.A == X26<Self.B>, Self.B : X3>
+// CHECK-NEXT: Canonical requirement signature: <τ_0_0 where τ_0_0.A == X26<τ_0_0.B>, τ_0_0.B : X3>
 protocol P27b {
   associatedtype A
   associatedtype B where A == X26<B>
diff --git a/test/IRGen/unexploded-calls.swift b/test/IRGen/unexploded-calls.swift
index 1146ded..e9046f4 100644
--- a/test/IRGen/unexploded-calls.swift
+++ b/test/IRGen/unexploded-calls.swift
@@ -2,6 +2,8 @@
 // RUN: %swift -target thumbv7-unknown-linux-gnueabihf -parse-stdlib -parse-as-library -I %S/Inputs/usr/include -module-name Swift -S -emit-ir -o - %s | %FileCheck %s
 // RUN: %swift -target thumbv7-unknown-linux-gnueabi -Xcc -mfloat-abi=hard -parse-stdlib -parse-as-library -I %S/Inputs/usr/include -module-name Swift -S -emit-ir -o - %s | %FileCheck %s
 
+// REQUIRES: CODEGENERATOR=ARM
+
 struct Float {
   let _value: Builtin.FPIEEE32
 }
diff --git a/test/Index/roles.swift b/test/Index/roles.swift
index 76fe95a..8c8acaf 100644
--- a/test/Index/roles.swift
+++ b/test/Index/roles.swift
@@ -313,6 +313,12 @@
   func foo() -> Int { return 1 }
 }
 
+protocol ExtendMe {}
+protocol Whatever {}
+// CHECK: [[@LINE-1]]:10 | protocol/Swift | Whatever | [[Whatever_USR:.*]] | Def | rel: 0
+extension ExtendMe where Self: Whatever {}
+// CHECK: [[@LINE-1]]:32 | protocol/Swift | Whatever | [[Whatever_USR]] | Ref | rel: 0
+
 var anInstance = AClass(x: 1)
 // CHECK: [[@LINE-1]]:18 | class/Swift | AClass | s:14swift_ide_test6AClassC | Ref | rel: 0
 // CHECK: [[@LINE-2]]:18 | constructor/Swift | init(x:) | s:14swift_ide_test6AClassCACSi1x_tcfc | Ref,Call | rel: 0
diff --git a/test/Parse/errors.swift b/test/Parse/errors.swift
index 8fb0ecf..628ae9d 100644
--- a/test/Parse/errors.swift
+++ b/test/Parse/errors.swift
@@ -4,8 +4,8 @@
   case Foo, Bar, Baz
   case CarriesInt(Int)
 
-  var domain: String { return "" }
-  var code: Int { return 0 }
+  var _domain: String { return "" }
+  var _code: Int { return 0 }
 }
 
 func opaque_error() -> Error { return MSV.Foo }
diff --git a/test/SILOptimizer/bridged_casts_folding.swift b/test/SILOptimizer/bridged_casts_folding.swift
index 25f5f12..ccd0ab6 100644
--- a/test/SILOptimizer/bridged_casts_folding.swift
+++ b/test/SILOptimizer/bridged_casts_folding.swift
@@ -2,9 +2,6 @@
 
 // REQUIRES: objc_interop
 
-// FIXME: https://bugs.swift.org/browse/SR-2808
-// XFAIL: resilient_stdlib
-
 // Check that casts between bridged types are replaced by more 
 // efficient code sequences.
 // 
diff --git a/test/SILOptimizer/cast_folding_no_bridging.sil b/test/SILOptimizer/cast_folding_no_bridging.sil
index 47dffe2..88c00cf 100644
--- a/test/SILOptimizer/cast_folding_no_bridging.sil
+++ b/test/SILOptimizer/cast_folding_no_bridging.sil
@@ -1,9 +1,6 @@
 // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -O -emit-sil %s | %FileCheck %s
 // REQUIRES: objc_interop
 
-// FIXME: https://bugs.swift.org/browse/SR-2808
-// XFAIL: resilient_stdlib
-
 // We want to check that casts between two types which are both Swift types or
 // both are ObjC types are not optimized by the cast optimizer into casts
 // to/from ObjC.
diff --git a/test/SILOptimizer/prespecialize.swift b/test/SILOptimizer/prespecialize.swift
index b8d0c00..bddb2b9 100644
--- a/test/SILOptimizer/prespecialize.swift
+++ b/test/SILOptimizer/prespecialize.swift
@@ -2,9 +2,6 @@
 
 // REQUIRES: optimized_stdlib
 
-// FIXME: https://bugs.swift.org/browse/SR-2808
-// XFAIL: resilient_stdlib
-
 // Check that pre-specialization works at -Onone.
 // This test requires the standard library to be compiled with pre-specializations!
 
diff --git a/test/SourceKit/DocSupport/doc_swift_module.swift.response b/test/SourceKit/DocSupport/doc_swift_module.swift.response
index ea22b0d..4683135 100644
--- a/test/SourceKit/DocSupport/doc_swift_module.swift.response
+++ b/test/SourceKit/DocSupport/doc_swift_module.swift.response
@@ -1039,7 +1039,7 @@
     key.length: 4
   },
   {
-    key.kind: source.lang.swift.syntaxtype.identifier,
+    key.kind: source.lang.swift.syntaxtype.typeidentifier,
     key.offset: 1207,
     key.length: 7
   },
diff --git a/test/decl/ext/protocol.swift b/test/decl/ext/protocol.swift
index 73e3ac4..117a0b5 100644
--- a/test/decl/ext/protocol.swift
+++ b/test/decl/ext/protocol.swift
@@ -510,7 +510,7 @@
 protocol PConforms8 {
   associatedtype Assoc
 
-  func method() -> Assoc
+  func method() -> Assoc // expected-note{{requirement 'method()' declared here}}
   var property: Assoc { get }
   subscript (i: Assoc) -> Assoc { get }
 }
@@ -535,7 +535,10 @@
 }
 
 struct SConforms8c : PConforms8 { 
-  func method() -> String { return "" }
+  func method() -> String { return "" } // expected-warning{{instance method 'method()' nearly matches defaulted requirement 'method()' of protocol 'PConforms8'}}
+  // expected-note@-1{{candidate has non-matching type '() -> String' [with Assoc = Int]}}
+  // expected-note@-2{{move 'method()' to an extension to silence this warning}}
+  // expected-note@-3{{make 'method()' private to silence this warning}}
 }
 
 func testSConforms8c() {
diff --git a/test/stdlib/RangeTraps.swift b/test/stdlib/RangeTraps.swift
index 865f940..51bde98 100644
--- a/test/stdlib/RangeTraps.swift
+++ b/test/stdlib/RangeTraps.swift
@@ -16,8 +16,6 @@
 // RUN: %target-run %t/a.out_Debug
 // RUN: %target-run %t/a.out_Release
 // REQUIRES: executable_test
-// CountablePartialRangeFrom fails in resilient mode. <rdar://problem/31909976>
-// XFAIL: resilient_stdlib
 
 
 import StdlibUnittest
diff --git a/test/stmt/errors.swift b/test/stmt/errors.swift
index 02051ce..688f15e 100644
--- a/test/stmt/errors.swift
+++ b/test/stmt/errors.swift
@@ -2,8 +2,8 @@
 enum MSV : Error {
   case Foo, Bar, Baz
 
-  var domain: String { return "" }
-  var code: Int { return 0 }
+  var _domain: String { return "" }
+  var _code: Int { return 0 }
 }
 
 func a() {}
diff --git a/validation-test/Sema/type_checker_perf/slow/rdar35213699.swift b/validation-test/Sema/type_checker_perf/slow/rdar35213699.swift
new file mode 100644
index 0000000..3f40370
--- /dev/null
+++ b/validation-test/Sema/type_checker_perf/slow/rdar35213699.swift
@@ -0,0 +1,8 @@
+// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=1
+// REQUIRES: tools-release,no_asserts
+
+func test() {
+  let x: UInt = 1 * 2 + 3 * 4 + 5 * 6 + 7 * 8 + 9 * 10 + 11 * 12 + 13 * 14
+  // expected-error@-1 {{expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions}}
+}
+
diff --git a/validation-test/compiler_crashers_2_fixed/0075-rdar30248571.swift b/validation-test/compiler_crashers_2_fixed/0075-rdar30248571.swift
index e0d33be..967d912 100644
--- a/validation-test/compiler_crashers_2_fixed/0075-rdar30248571.swift
+++ b/validation-test/compiler_crashers_2_fixed/0075-rdar30248571.swift
@@ -1,5 +1,5 @@
 // RUN: %target-swift-frontend %s -typecheck
-// FIXME: %target-swift-frontend %s -emit-ir -- see https://github.com/apple/swift/pull/7414
+// RUN: %target-swift-frontend %s -emit-ir -o /dev/null
 
 protocol P {
   associatedtype A
diff --git a/validation-test/compiler_crashers/28803-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/28803-swift-typebase-getdesugaredtype.swift
similarity index 87%
rename from validation-test/compiler_crashers/28803-swift-typebase-getdesugaredtype.swift
rename to validation-test/compiler_crashers_fixed/28803-swift-typebase-getdesugaredtype.swift
index 4511df4..4ae3193 100644
--- a/validation-test/compiler_crashers/28803-swift-typebase-getdesugaredtype.swift
+++ b/validation-test/compiler_crashers_fixed/28803-swift-typebase-getdesugaredtype.swift
@@ -5,6 +5,6 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 protocol P{typealias a:Collection
 typealias a=(t:Self.a
diff --git a/validation-test/compiler_crashers/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift b/validation-test/compiler_crashers_fixed/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
similarity index 87%
rename from validation-test/compiler_crashers/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
rename to validation-test/compiler_crashers_fixed/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
index 2b015fa..9d62d8f 100644
--- a/validation-test/compiler_crashers/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
+++ b/validation-test/compiler_crashers_fixed/28819-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
@@ -5,5 +5,5 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 class a<a{protocol b}extension a.b
diff --git a/validation-test/compiler_crashers/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift b/validation-test/compiler_crashers_fixed/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
similarity index 87%
rename from validation-test/compiler_crashers/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
rename to validation-test/compiler_crashers_fixed/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
index aad1964..a9fbd25 100644
--- a/validation-test/compiler_crashers/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
+++ b/validation-test/compiler_crashers_fixed/28830-formextensioninterfacetype-swift-type-swift-genericparamlist.swift
@@ -5,5 +5,5 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 protocol P{protocol a:P}extension P.a.a
diff --git a/validation-test/compiler_crashers/28846-swift-typebase-getdesugaredtype.swift b/validation-test/compiler_crashers_fixed/28846-swift-typebase-getdesugaredtype.swift
similarity index 87%
rename from validation-test/compiler_crashers/28846-swift-typebase-getdesugaredtype.swift
rename to validation-test/compiler_crashers_fixed/28846-swift-typebase-getdesugaredtype.swift
index 56eb011..c70c62f 100644
--- a/validation-test/compiler_crashers/28846-swift-typebase-getdesugaredtype.swift
+++ b/validation-test/compiler_crashers_fixed/28846-swift-typebase-getdesugaredtype.swift
@@ -5,5 +5,5 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 protocol A{typealias a:A=a{}typealias a=Self.a
diff --git a/validation-test/compiler_crashers/28848-iscanonicaltypeincontext-result-builder.swift b/validation-test/compiler_crashers_fixed/28848-iscanonicaltypeincontext-result-builder.swift
similarity index 88%
rename from validation-test/compiler_crashers/28848-iscanonicaltypeincontext-result-builder.swift
rename to validation-test/compiler_crashers_fixed/28848-iscanonicaltypeincontext-result-builder.swift
index 72c53f2..504f8d5 100644
--- a/validation-test/compiler_crashers/28848-iscanonicaltypeincontext-result-builder.swift
+++ b/validation-test/compiler_crashers_fixed/28848-iscanonicaltypeincontext-result-builder.swift
@@ -6,5 +6,5 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 protocol P{typealias a{}func a:a.a{}class a{{}protocol 0
diff --git a/validation-test/compiler_crashers/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift b/validation-test/compiler_crashers_fixed/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
similarity index 88%
rename from validation-test/compiler_crashers/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
rename to validation-test/compiler_crashers_fixed/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
index 0e26155..350c824 100644
--- a/validation-test/compiler_crashers/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
+++ b/validation-test/compiler_crashers_fixed/28851-hasconformanceinsignature-inprotocol-getrequirementsignature-subjecttype-conform.swift
@@ -6,5 +6,5 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 protocol A:a{{}typealias a=a{}func a{}typealias a}class a:A{func a
diff --git a/validation-test/compiler_crashers/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift b/validation-test/compiler_crashers_fixed/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift
similarity index 88%
rename from validation-test/compiler_crashers/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift
rename to validation-test/compiler_crashers_fixed/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift
index ea97cf1..40f673d 100644
--- a/validation-test/compiler_crashers/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift
+++ b/validation-test/compiler_crashers_fixed/28864-bool-typesig-bool-extensionsig-unexpected-generic-ness-mismatch-on-conformance.swift
@@ -6,6 +6,6 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 protocol P{class a}protocol A:P
 extension P.a:A