Merge pull request #10064 from CodaFi/thats-not-my-name

diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 14852dc..9416e6d 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -2372,6 +2372,9 @@
     return D->getKind() >= DeclKind::First_TypeDecl &&
            D->getKind() <= DeclKind::Last_TypeDecl;
   }
+
+  /// Compute an ordering between two type declarations that is ABI-stable.
+  static int compare(const TypeDecl *type1, const TypeDecl *type2);
 };
 
 /// A type declaration that can have generic parameters attached to it.  Because
diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h
index aafc243..b3ba662 100644
--- a/include/swift/AST/DeclContext.h
+++ b/include/swift/AST/DeclContext.h
@@ -494,6 +494,19 @@
                          = nullptr,
                        bool sorted = false) const;
 
+  /// Retrieve the syntactic depth of this declaration context, i.e.,
+  /// the number of non-module-scoped contexts.
+  ///
+  /// For an extension of a nested type, the extension is depth 1.
+  unsigned getSyntacticDepth() const;
+
+  /// Retrieve the semantic depth of this declaration context, i.e.,
+  /// the number of non-module-scoped contexts.
+  ///
+  /// For an extension of a nested type, the depth of the nested type itself
+  /// is also included.
+  unsigned getSemanticDepth() const;
+
   /// \returns true if traversal was aborted, false otherwise.
   bool walkContext(ASTWalker &Walker);
 
diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index cac90b3..f44ad76 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -1248,7 +1248,7 @@
     Identifier name;
 
     /// The associated type or typealias for a resolved nested type.
-    TypeDecl *assocTypeOrAlias;
+    TypeDecl *assocTypeOrConcrete;
 
     /// The generic parameter key for a root.
     GenericParamKey genericParam;
@@ -1256,10 +1256,10 @@
     PAIdentifier(Identifier name) : name(name) { }
 
     PAIdentifier(AssociatedTypeDecl *assocType)
-      : assocTypeOrAlias(assocType) { }
+      : assocTypeOrConcrete(assocType) { }
 
-    PAIdentifier(TypeAliasDecl *typeAlias)
-      : assocTypeOrAlias(typeAlias) { }
+    PAIdentifier(TypeDecl *concreteDecl)
+      : assocTypeOrConcrete(concreteDecl) { }
 
     PAIdentifier(GenericParamKey genericParam) : genericParam(genericParam) { }
   } identifier;
@@ -1342,9 +1342,9 @@
     assert(parent != nullptr && "Not an associated type?");
   }
 
-  /// \brief Construct a new potential archetype for a type alias.
-  PotentialArchetype(PotentialArchetype *parent, TypeAliasDecl *typeAlias)
-    : parentOrBuilder(parent), identifier(typeAlias),
+  /// \brief Construct a new potential archetype for a concrete declaration.
+  PotentialArchetype(PotentialArchetype *parent, TypeDecl *concreteDecl)
+    : parentOrBuilder(parent), identifier(concreteDecl),
       isUnresolvedNestedType(false),
       IsRecursive(false), Invalid(false),
       DiagnosedRename(false)
@@ -1396,16 +1396,19 @@
     if (isUnresolvedNestedType)
       return nullptr;
 
-    return dyn_cast<AssociatedTypeDecl>(identifier.assocTypeOrAlias);
+    return dyn_cast<AssociatedTypeDecl>(identifier.assocTypeOrConcrete);
   }
 
+  /// Determine whether this PA is still unresolved.
+  bool isUnresolved() const { return isUnresolvedNestedType; }
+
   /// Resolve the potential archetype to the given associated type.
   void resolveAssociatedType(AssociatedTypeDecl *assocType,
                              GenericSignatureBuilder &builder);
 
   /// Resolve the potential archetype to the given typealias.
-  void resolveTypeAlias(TypeAliasDecl *typealias,
-                        GenericSignatureBuilder &builder);
+  void resolveConcreteType(TypeDecl *concreteDecl,
+                           GenericSignatureBuilder &builder);
 
   /// Determine whether this is a generic parameter.
   bool isGenericParam() const {
@@ -1436,16 +1439,19 @@
     if (isUnresolvedNestedType)
       return identifier.name;
 
-    return identifier.assocTypeOrAlias->getName();
+    return identifier.assocTypeOrConcrete->getName();
   }
 
-  /// Retrieve the type alias.
-  TypeAliasDecl *getTypeAliasDecl() const {
+  /// Retrieve the concrete type declaration.
+  TypeDecl *getConcreteTypeDecl() const {
     assert(getParent() && "not a nested type");
     if (isUnresolvedNestedType)
       return nullptr;
 
-    return dyn_cast<TypeAliasDecl>(identifier.assocTypeOrAlias);
+    if (isa<AssociatedTypeDecl>(identifier.assocTypeOrConcrete))
+      return nullptr;
+
+    return identifier.assocTypeOrConcrete;
   }
 
   /// Retrieve the set of protocols to which this potential archetype
@@ -1548,8 +1554,9 @@
   PotentialArchetype *getNestedType(AssociatedTypeDecl *assocType,
                                     GenericSignatureBuilder &builder);
 
-  /// \brief Retrieve (or create) a nested type with a known typealias.
-  PotentialArchetype *getNestedType(TypeAliasDecl *typealias,
+  /// \brief Retrieve (or create) a nested type with a known concrete type
+  /// declaration.
+  PotentialArchetype *getNestedType(TypeDecl *concreteDecl,
                                     GenericSignatureBuilder &builder);
 
   /// Describes the kind of update that is performed.
@@ -1581,7 +1588,7 @@
   /// type or typealias of the given protocol, unless the \c kind implies that
   /// a potential archetype should not be created if it's missing.
   PotentialArchetype *updateNestedTypeForConformance(
-                      PointerUnion<AssociatedTypeDecl *, TypeAliasDecl *> type,
+                      PointerUnion<AssociatedTypeDecl *, TypeDecl *> type,
                       NestedTypeUpdate kind);
 
   /// Update the named nested type when we know this type conforms to the given
diff --git a/lib/AST/ASTVerifier.cpp b/lib/AST/ASTVerifier.cpp
index 7c8a676..27e9145 100644
--- a/lib/AST/ASTVerifier.cpp
+++ b/lib/AST/ASTVerifier.cpp
@@ -697,6 +697,11 @@
       if (!shouldVerify(cast<Expr>(expr)))
         return false;
 
+      // In rare instances we clear the opaque value because we no
+      // longer have a subexpression that references it.
+      if (!expr->getOpaqueValue())
+        return true;
+
       assert(!OpaqueValues.count(expr->getOpaqueValue()));
       OpaqueValues[expr->getOpaqueValue()] = 0;
       assert(OpenedExistentialArchetypes.count(expr->getOpenedArchetype())==0);
@@ -705,6 +710,11 @@
     }
 
     void cleanup(OpenExistentialExpr *expr) {
+      // In rare instances we clear the opaque value because we no
+      // longer have a subexpression that references it.
+      if (!expr->getOpaqueValue())
+        return;
+
       assert(OpaqueValues.count(expr->getOpaqueValue()));
       OpaqueValues.erase(expr->getOpaqueValue());
       assert(OpenedExistentialArchetypes.count(expr->getOpenedArchetype())==1);
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 412a0ab..e3014bc 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1165,7 +1165,13 @@
 
   case DeclKind::Class:
     // Final properties can always be direct, even in classes.
-    return !storage->isFinal();
+    if (storage->isFinal())
+      return false;
+    // Extension properties are statically dispatched, unless they're @objc.
+    if (storage->getDeclContext()->isExtensionContext()
+        && !storage->isObjC())
+      return false;
+    return true;
   }
   llvm_unreachable("bad DeclKind");
 }
@@ -2067,6 +2073,47 @@
   return interfaceType->castTo<MetatypeType>()->getInstanceType();
 }
 
+int TypeDecl::compare(const TypeDecl *type1, const TypeDecl *type2) {
+  // Order based on the enclosing declaration.
+  auto dc1 = type1->getDeclContext();
+  auto dc2 = type2->getDeclContext();
+
+  // Prefer lower depths.
+  auto depth1 = dc1->getSemanticDepth();
+  auto depth2 = dc2->getSemanticDepth();
+  if (depth1 != depth2)
+    return depth1 < depth2 ? -1 : +1;
+
+  // Prefer module names earlier in the alphabet.
+  if (dc1->isModuleScopeContext() && dc2->isModuleScopeContext()) {
+    auto module1 = dc1->getParentModule();
+    auto module2 = dc2->getParentModule();
+    if (int result = module1->getName().str().compare(module2->getName().str()))
+      return result;
+  }
+
+  auto nominal1 = dc1->getAsNominalTypeOrNominalTypeExtensionContext();
+  auto nominal2 = dc2->getAsNominalTypeOrNominalTypeExtensionContext();
+  if (static_cast<bool>(nominal1) != static_cast<bool>(nominal2)) {
+    return static_cast<bool>(nominal1) ? -1 : +1;
+  }
+  if (nominal1 && nominal2) {
+    if (int result = compare(nominal1, nominal2))
+      return result;
+  }
+
+  if (int result = type1->getBaseName().getIdentifier().str().compare(
+                                  type2->getBaseName().getIdentifier().str()))
+    return result;
+
+  // Error case: two type declarations that cannot be distinguished.
+  if (type1 < type2)
+    return -1;
+  if (type1 > type2)
+    return +1;
+  return 0;
+}
+
 bool NominalTypeDecl::hasFixedLayout() const {
   // Private and (unversioned) internal types always have a
   // fixed layout.
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index 4926db3..4d5bfdb 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -656,6 +656,30 @@
   return getParent()->isCascadingContextForLookup(true);
 }
 
+unsigned DeclContext::getSyntacticDepth() const {
+  // Module scope == depth 0.
+  if (isModuleScopeContext())
+    return 0;
+
+  return 1 + getParent()->getSyntacticDepth();
+}
+
+unsigned DeclContext::getSemanticDepth() const {
+  // For extensions, count the depth of the nominal type being extended.
+  if (auto ext = dyn_cast<ExtensionDecl>(this)) {
+    if (auto nominal = getAsNominalTypeOrNominalTypeExtensionContext())
+      return nominal->getSemanticDepth();
+
+    return 1;
+  }
+
+  // Module scope == depth 0.
+  if (isModuleScopeContext())
+    return 0;
+
+  return 1 + getParent()->getSemanticDepth();
+}
+
 bool DeclContext::walkContext(ASTWalker &Walker) {
   switch (getContextKind()) {
   case DeclContextKind::Module:
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 0bc4f85..afe512e 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -316,19 +316,25 @@
 
     void visitOpenExistentialExpr(OpenExistentialExpr *E,
                                   AccessKind accessKind) {
-      bool opaqueValueHadAK = E->getOpaqueValue()->hasLValueAccessKind();
-      AccessKind oldOpaqueValueAK =
-        (opaqueValueHadAK ? E->getOpaqueValue()->getLValueAccessKind()
-                          : AccessKind::Read);
+      AccessKind oldOpaqueValueAK;
+      bool opaqueValueHadAK;
+      if (E->getOpaqueValue()) {
+        opaqueValueHadAK = E->getOpaqueValue()->hasLValueAccessKind();
+        oldOpaqueValueAK =
+            (opaqueValueHadAK ? E->getOpaqueValue()->getLValueAccessKind()
+                              : AccessKind::Read);
+      }
 
       visit(E->getSubExpr(), accessKind);
 
-      // Propagate the new access kind from the OVE to the original existential
-      // if we just set or changed it on the OVE.
-      if (E->getOpaqueValue()->hasLValueAccessKind()) {
-        auto newOpaqueValueAK = E->getOpaqueValue()->getLValueAccessKind();
-        if (!opaqueValueHadAK || newOpaqueValueAK != oldOpaqueValueAK)
-          visit(E->getExistentialValue(), newOpaqueValueAK);
+      if (E->getOpaqueValue()) {
+        // Propagate the new access kind from the OVE to the original
+        // existential if we just set or changed it on the OVE.
+        if (E->getOpaqueValue()->hasLValueAccessKind()) {
+          auto newOpaqueValueAK = E->getOpaqueValue()->getLValueAccessKind();
+          if (!opaqueValueHadAK || newOpaqueValueAK != oldOpaqueValueAK)
+            visit(E->getExistentialValue(), newOpaqueValueAK);
+        }
       }
     }
 
diff --git a/lib/AST/GenericEnvironment.cpp b/lib/AST/GenericEnvironment.cpp
index 1292e2f..979f899 100644
--- a/lib/AST/GenericEnvironment.cpp
+++ b/lib/AST/GenericEnvironment.cpp
@@ -33,17 +33,6 @@
                           Type());
 }
 
-/// Compute the depth of the \c DeclContext chain.
-static unsigned declContextDepth(const DeclContext *dc) {
-  unsigned depth = 0;
-  while (auto parentDC = dc->getParent()) {
-    ++depth;
-    dc = parentDC;
-  }
-
-  return depth;
-}
-
 void GenericEnvironment::setOwningDeclContext(DeclContext *newOwningDC) {
   if (!OwningDC) {
     OwningDC = newOwningDC;
@@ -54,8 +43,8 @@
     return;
 
   // Find the least common ancestor context to be the owner.
-  unsigned oldDepth = declContextDepth(OwningDC);
-  unsigned newDepth = declContextDepth(newOwningDC);
+  unsigned oldDepth = OwningDC->getSyntacticDepth();
+  unsigned newDepth = newOwningDC->getSyntacticDepth();
 
   while (oldDepth > newDepth) {
     OwningDC = OwningDC->getParent();
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 4e4ca68..283779a 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -1057,8 +1057,9 @@
   ProtocolDecl *proto = nullptr;
   if (auto assocType = getResolvedAssociatedType()) {
     proto = assocType->getProtocol();
-  } else if (auto typeAlias = getTypeAliasDecl()) {
-    proto = typeAlias->getParent()->getAsProtocolOrProtocolExtensionContext();
+  } else if (auto concreteDecl = getConcreteTypeDecl()) {
+    proto = concreteDecl->getDeclContext()
+              ->getAsProtocolOrProtocolExtensionContext();
   }
 
   if (proto) {
@@ -1086,20 +1087,20 @@
        GenericSignatureBuilder &builder) {
   assert(isUnresolvedNestedType && "associated type is already resolved");
   isUnresolvedNestedType = false;
-  identifier.assocTypeOrAlias = assocType;
+  identifier.assocTypeOrConcrete = assocType;
   assert(assocType->getName() == getNestedName());
   assert(builder.Impl->NumUnresolvedNestedTypes > 0 &&
          "Mismatch in number of unresolved nested types");
   --builder.Impl->NumUnresolvedNestedTypes;
 }
 
-void GenericSignatureBuilder::PotentialArchetype::resolveTypeAlias(
-       TypeAliasDecl *typealias,
+void GenericSignatureBuilder::PotentialArchetype::resolveConcreteType(
+       TypeDecl *concreteDecl,
        GenericSignatureBuilder &builder) {
   assert(isUnresolvedNestedType && "nested type is already resolved");
   isUnresolvedNestedType = false;
-  identifier.assocTypeOrAlias = typealias;
-  assert(typealias->getName() == getNestedName());
+  identifier.assocTypeOrConcrete = concreteDecl;
+  assert(concreteDecl->getName() == getNestedName());
   assert(builder.Impl->NumUnresolvedNestedTypes > 0 &&
          "Mismatch in number of unresolved nested types");
   --builder.Impl->NumUnresolvedNestedTypes;
@@ -1285,7 +1286,7 @@
   if (!superSource) return;
 
   auto assocType = nestedPA->getResolvedAssociatedType();
-  assert(assocType && "Not resolved to an associated type?");
+  if (!assocType) return;
 
   // Dig out the type witness.
   auto superConformance = superSource->getProtocolConformance();
@@ -1408,30 +1409,6 @@
   return 0;
 }
 
-/// Compare two typealiases in protocols.
-static int compareTypeAliases(TypeAliasDecl *typealias1,
-                              TypeAliasDecl *typealias2) {
-  // - by name.
-  if (int result = typealias1->getName().str().compare(
-                                              typealias2->getName().str()))
-    return result;
-
-  // - by protocol, so t_n_m.`P.T` < t_n_m.`Q.T` (given P < Q)
-  auto proto1 =
-    typealias1->getDeclContext()->getAsProtocolOrProtocolExtensionContext();
-  auto proto2 =
-    typealias2->getDeclContext()->getAsProtocolOrProtocolExtensionContext();
-  if (int compareProtocols = ProtocolType::compareProtocols(&proto1, &proto2))
-    return compareProtocols;
-
-  // Error case: if we have two associated types with the same name in the
-  // same protocol, just tie-break based on address.
-  if (typealias1 != typealias2)
-    return typealias1 < typealias2 ? -1 : +1;
-
-  return 0;
-}
-
 /// Canonical ordering for dependent types in generic signatures.
 static int compareDependentTypes(PotentialArchetype * const* pa,
                                  PotentialArchetype * const* pb) {
@@ -1441,12 +1418,12 @@
   if (a == b)
     return 0;
 
-  // Typealiases must be ordered *after* everything else, to ensure they
-  // don't become representatives in the case where a typealias is equated
+  // Concrete types must be ordered *after* everything else, to ensure they
+  // don't become representatives in the case where a concrete type is equated
   // with an associated type.
   if (a->getParent() && b->getParent() &&
-      !!a->getTypeAliasDecl() != !!b->getTypeAliasDecl())
-    return a->getTypeAliasDecl() ? +1 : -1;
+      !!a->getConcreteTypeDecl() != !!b->getConcreteTypeDecl())
+    return a->getConcreteTypeDecl() ? +1 : -1;
 
   // Types that are equivalent to concrete types follow types that are still
   // type parameters.
@@ -1489,12 +1466,13 @@
       return +1;
   }
 
-  // Make sure typealiases are properly ordered, to avoid crashers.
-  if (auto *aa = a->getTypeAliasDecl()) {
-    auto *ab = b->getTypeAliasDecl();
+  // Make sure concrete type declarations are properly ordered, to avoid
+  // crashers.
+  if (auto *aa = a->getConcreteTypeDecl()) {
+    auto *ab = b->getConcreteTypeDecl();
     assert(ab != nullptr && "Should have handled this case above");
 
-    if (int result = compareTypeAliases(aa, ab))
+    if (int result = TypeDecl::compare(aa, ab))
       return result;
   }
 
@@ -1575,11 +1553,11 @@
     PotentialArchetype *pa;
 
     void operator()(Type type1, Type type2) const {
-      if (pa->getParent() && pa->getTypeAliasDecl() &&
+      if (pa->getParent() && pa->getConcreteTypeDecl() &&
           source->getLoc().isInvalid()) {
-        diags.diagnose(pa->getTypeAliasDecl()->getLoc(),
+        diags.diagnose(pa->getConcreteTypeDecl()->getLoc(),
                        diag::protocol_typealias_conflict,
-                       pa->getTypeAliasDecl()->getName(),
+                       pa->getConcreteTypeDecl()->getName(),
                        type1, type2);
         return;
       }
@@ -1658,9 +1636,9 @@
 }
 
 PotentialArchetype *PotentialArchetype::getNestedType(
-                                            TypeAliasDecl *typealias,
+                                            TypeDecl *getConcreteTypeDecl,
                                             GenericSignatureBuilder &builder) {
-  return updateNestedTypeForConformance(typealias,
+  return updateNestedTypeForConformance(getConcreteTypeDecl,
                                         NestedTypeUpdate::AddIfMissing);
 }
 
@@ -1668,24 +1646,24 @@
                                            Identifier name,
                                            GenericSignatureBuilder &builder,
                                            NestedTypeUpdate kind) {
-  // Look for the best associated type or typealias within the protocols
+  // Look for the best associated type or concrete type within the protocols
   // we know about.
   AssociatedTypeDecl *bestAssocType = nullptr;
-  TypeAliasDecl *bestTypeAlias = nullptr;
-  SmallVector<TypeAliasDecl *, 4> typealiases;
+  TypeDecl *bestConcreteDecl = nullptr;
+  SmallVector<TypeDecl *, 4> concreteDecls;
   auto rep = getRepresentative();
   for (auto proto : rep->getConformsTo()) {
-    // Look for an associated type and/or typealias with this name.
+    // Look for an associated type and/or concrete type with this name.
     AssociatedTypeDecl *assocType = nullptr;
-    TypeAliasDecl *typealias = nullptr;
+    TypeDecl *concreteDecl = nullptr;
     for (auto member : proto->lookupDirect(name,
                                            /*ignoreNewExtensions=*/true)) {
       if (!assocType)
         assocType = dyn_cast<AssociatedTypeDecl>(member);
 
-      // FIXME: Filter out typealiases that aren't in the protocol itself?
-      if (!typealias)
-        typealias = dyn_cast<TypeAliasDecl>(member);
+      // FIXME: Filter out type declarations that aren't in the protocol itself?
+      if (!concreteDecl && !isa<AssociatedTypeDecl>(member))
+        concreteDecl = dyn_cast<TypeDecl>(member);
     }
 
     if (assocType &&
@@ -1693,13 +1671,14 @@
          compareAssociatedTypes(assocType, bestAssocType) < 0))
       bestAssocType = assocType;
 
-    if (typealias) {
-      // Record every typealias.
-      typealiases.push_back(typealias);
+    if (concreteDecl) {
+      // Record every concrete type.
+      concreteDecls.push_back(concreteDecl);
 
-      // Track the best typealias.
-      if (!bestTypeAlias || compareTypeAliases(typealias, bestTypeAlias) < 0)
-        bestTypeAlias = typealias;
+      // Track the best concrete type.
+      if (!bestConcreteDecl ||
+          TypeDecl::compare(concreteDecl, bestConcreteDecl) < 0)
+        bestConcreteDecl = concreteDecl;
     }
   }
 
@@ -1710,25 +1689,47 @@
                                               NestedTypeUpdate::AddIfMissing);
   }
 
-  // If we have an associated type, drop any typealiases that aren't in
+  // If we have an associated type, drop any concrete decls that aren't in
   // the same module as the protocol.
   // FIXME: This is an unprincipled hack for an unprincipled feature.
-  typealiases.erase(
-    std::remove_if(typealiases.begin(), typealiases.end(),
-                   [&](TypeAliasDecl *typealias) {
-      return typealias->getParentModule() !=
-        typealias->getDeclContext()
+  concreteDecls.erase(
+    std::remove_if(concreteDecls.begin(), concreteDecls.end(),
+                   [&](TypeDecl *concreteDecl) {
+      return concreteDecl->getDeclContext()->getParentModule() !=
+        concreteDecl->getDeclContext()
           ->getAsNominalTypeOrNominalTypeExtensionContext()->getParentModule();
     }),
-    typealiases.end());
+    concreteDecls.end());
 
-  // Update for all of the typealiases with this name, which will introduce
+  // If we haven't found anything yet but have a superclass, look for a type
+  // in the superclass.
+  if (!resultPA && concreteDecls.empty()) {
+    if (auto superclass = getSuperclass()) {
+      if (auto classDecl = superclass->getClassOrBoundGenericClass()) {
+        SmallVector<ValueDecl *, 2> superclassMembers;
+        classDecl->getParentModule()->lookupQualified(superclass, name, NL_QualifiedDefault | NL_OnlyTypes | NL_ProtocolMembers, nullptr,
+            superclassMembers);
+        for (auto member : superclassMembers) {
+          if (auto concreteDecl = dyn_cast<TypeDecl>(member)) {
+            // Track the best concrete type.
+            if (!bestConcreteDecl ||
+                TypeDecl::compare(concreteDecl, bestConcreteDecl) < 0)
+              bestConcreteDecl = concreteDecl;
+
+            concreteDecls.push_back(concreteDecl);
+          }
+        }
+      }
+    }
+  }
+
+  // Update for all of the concrete decls with this name, which will introduce
   // various same-type constraints.
-  for (auto typealias : typealiases) {
-    auto typealiasPA = updateNestedTypeForConformance(typealias,
+  for (auto concreteDecl : concreteDecls) {
+    auto concreteDeclPA = updateNestedTypeForConformance(concreteDecl,
                                           NestedTypeUpdate::AddIfMissing);
-    if (!resultPA && typealias == bestTypeAlias)
-      resultPA = typealiasPA;
+    if (!resultPA && concreteDecl == bestConcreteDecl)
+      resultPA = concreteDeclPA;
   }
 
   if (resultPA)
@@ -1771,48 +1772,49 @@
                                                        Identifier name,
                                                        ProtocolDecl *proto,
                                                        NestedTypeUpdate kind) {
-  /// Determine whether there is an associated type or typealias with this name
-  /// in this protocol. If not, there's nothing to do.
+  /// Determine whether there is an associated type or concrete type with this
+  /// name in this protocol. If not, there's nothing to do.
   AssociatedTypeDecl *assocType = nullptr;
-  TypeAliasDecl *typealias = nullptr;
+  TypeDecl *concreteDecl = nullptr;
   for (auto member : proto->lookupDirect(name, /*ignoreNewExtensions=*/true)) {
     if (!assocType)
       assocType = dyn_cast<AssociatedTypeDecl>(member);
 
-    // FIXME: Filter out typealiases that aren't in the protocol itself?
-    if (!typealias)
-      typealias = dyn_cast<TypeAliasDecl>(member);
+    // FIXME: Filter out concrete types that aren't in the protocol itself?
+    if (!concreteDecl && !isa<AssociatedTypeDecl>(member))
+      concreteDecl = dyn_cast<TypeDecl>(member);
   }
 
-  // There is no associated type or typealias with this name in this protocol
-  if (!assocType && !typealias)
+  // There is no associated type or concrete type with this name in this
+  // protocol
+  if (!assocType && !concreteDecl)
     return nullptr;
 
-  // If we had both an associated type and a typealias, ignore the latter. This
-  // is for ill-formed code.
+  // If we had both an associated type and a concrete type, ignore the latter.
+  // This is for ill-formed code.
   if (assocType)
     return updateNestedTypeForConformance(assocType, kind);
 
-  return updateNestedTypeForConformance(typealias, kind);
+  return updateNestedTypeForConformance(concreteDecl, kind);
 }
 
 PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
-                      PointerUnion<AssociatedTypeDecl *, TypeAliasDecl *> type,
+                      PointerUnion<AssociatedTypeDecl *, TypeDecl *> type,
                       NestedTypeUpdate kind) {
   auto *assocType = type.dyn_cast<AssociatedTypeDecl *>();
-  auto *typealias = type.dyn_cast<TypeAliasDecl *>();
-  if (!assocType && !typealias)
+  auto *concreteDecl = type.dyn_cast<TypeDecl *>();
+  if (!assocType && !concreteDecl)
     return nullptr;
 
-  Identifier name = assocType ? assocType->getName() : typealias->getName();
+  Identifier name = assocType ? assocType->getName() : concreteDecl->getName();
   ProtocolDecl *proto =
     assocType ? assocType->getProtocol()
-              : typealias->getDeclContext()
+              : concreteDecl->getDeclContext()
                   ->getAsProtocolOrProtocolExtensionContext();
 
   // Look for either an unresolved potential archetype (which we can resolve
   // now) or a potential archetype with the appropriate associated type or
-  // typealias.
+  // concrete type.
   PotentialArchetype *resultPA = nullptr;
   auto knownNestedTypes = NestedTypes.find(name);
   bool shouldUpdatePA = false;
@@ -1824,7 +1826,7 @@
         if (assocType) {
           existingPA->resolveAssociatedType(assocType, builder);
         } else {
-          existingPA->resolveTypeAlias(typealias, builder);
+          existingPA->resolveConcreteType(concreteDecl, builder);
         }
 
         // We've resolved this nested type; nothing more to do.
@@ -1839,8 +1841,8 @@
         break;
       }
 
-      // Do we have a typealias match?
-      if (typealias && existingPA->getTypeAliasDecl() == typealias) {
+      // Do we have a concrete type match?
+      if (concreteDecl && existingPA->getConcreteTypeDecl() == concreteDecl) {
         resultPA = existingPA;
         break;
       }
@@ -1860,7 +1862,7 @@
       if (assocType)
         resultPA = new PotentialArchetype(this, assocType);
       else
-        resultPA = new PotentialArchetype(this, typealias);
+        resultPA = new PotentialArchetype(this, concreteDecl);
 
       auto &allNested = NestedTypes[name];
       allNested.push_back(resultPA);
@@ -1903,28 +1905,38 @@
 
   // If we have a potential archetype that requires more processing, do so now.
   if (shouldUpdatePA) {
-    // For typealiases, introduce a same-type requirement to the aliased type.
-    if (typealias) {
+    // For concrete types, introduce a same-type requirement to the aliased
+    // type.
+    if (concreteDecl) {
       // FIXME (recursive decl validation): if the alias doesn't have an
       // interface type when getNestedType is called while building a
       // protocol's generic signature (i.e. during validation), then it'll
       // fail completely, because building that alias's interface type
       // requires the protocol to be validated. This seems to occur when the
       // alias's RHS involves archetypes from the protocol.
-      if (!typealias->hasInterfaceType())
-        builder.getLazyResolver()->resolveDeclSignature(typealias);
-      if (typealias->hasInterfaceType()) {
-        // The protocol typealias has an underlying type written in terms
+      if (!concreteDecl->hasInterfaceType())
+        builder.getLazyResolver()->resolveDeclSignature(concreteDecl);
+      if (concreteDecl->hasInterfaceType()) {
+        // The protocol concrete type has an underlying type written in terms
         // of the protocol's 'Self' type.
-        auto type = typealias->getDeclaredInterfaceType();
+        auto type = concreteDecl->getDeclaredInterfaceType();
 
-        // Substitute in the type of the current PotentialArchetype in
-        // place of 'Self' here.
-        auto subMap = SubstitutionMap::getProtocolSubstitutions(
-          proto, getDependentType(/*genericParams=*/{},
-                                  /*allowUnresolved=*/true),
-          ProtocolConformanceRef(proto));
-        type = type.subst(subMap, SubstFlags::UseErrorType);
+        if (proto) {
+          // Substitute in the type of the current PotentialArchetype in
+          // place of 'Self' here.
+          auto subMap = SubstitutionMap::getProtocolSubstitutions(
+            proto, getDependentType(/*genericParams=*/{},
+                                    /*allowUnresolved=*/true),
+            ProtocolConformanceRef(proto));
+          type = type.subst(subMap, SubstFlags::UseErrorType);
+        } else {
+          // Substitute in the superclass type.
+          auto superclass = getSuperclass();
+          auto superclassDecl = superclass->getClassOrBoundGenericClass();
+          type = superclass->getTypeOfMember(
+                   superclassDecl->getParentModule(), concreteDecl,
+                   concreteDecl->getDeclaredInterfaceType());
+        }
 
         builder.addSameTypeRequirement(
                          UnresolvedType(resultPA),
@@ -1936,8 +1948,12 @@
 
     // If there's a superclass constraint that conforms to the protocol,
     // add the appropriate same-type relationship.
-    if (auto superSource = builder.resolveSuperConformance(this, proto))
-      maybeAddSameTypeRequirementForNestedType(resultPA, superSource, builder);
+    if (proto) {
+      if (auto superSource = builder.resolveSuperConformance(this, proto)) {
+        maybeAddSameTypeRequirementForNestedType(resultPA, superSource,
+                                                 builder);
+      }
+    }
 
     // We know something concrete about the parent PA, so we need to propagate
     // that information to this new archetype.
@@ -2398,18 +2414,6 @@
     if (!pa) return None;
   }
 
-  auto rep = pa->getRepresentative();
-  if (!rep->getParent() || !rep->getTypeAliasDecl())
-    return ResolvedType::forPotentialArchetype(pa);
-
-  // We're assuming that an equivalence class with a type alias representative
-  // doesn't have a "true" (i.e. associated type) potential archetype.
-  assert(llvm::all_of(rep->getEquivalenceClassMembers(),
-                      [&](PotentialArchetype *pa) {
-                        return pa->getParent() && pa->getTypeAliasDecl();
-                      }) &&
-         "unexpected typealias representative with non-typealias equivalent");
-
   return ResolvedType::forPotentialArchetype(pa);
 }
 
@@ -2607,16 +2611,16 @@
                                assocType);
     }
 
-    if (auto typealias = dyn_cast<TypeAliasDecl>(typeDecl)) {
-      // Resolve the underlying type, if we haven't done so yet.
-      if (!typealias->hasInterfaceType()) {
-        getLazyResolver()->resolveDeclSignature(typealias);
-      }
+    // Resolve the underlying type, if we haven't done so yet.
+    if (!typeDecl->hasInterfaceType()) {
+      getLazyResolver()->resolveDeclSignature(typeDecl);
+    }
 
+    if (auto typealias = dyn_cast<TypeAliasDecl>(typeDecl)) {
       return typealias->getUnderlyingTypeLoc().getType();
     }
 
-    return Type();
+    return typeDecl->getDeclaredInterfaceType();
   };
 
   // An inferred same-type requirement between the two type declarations
@@ -2845,11 +2849,24 @@
     }
   };
 
+  // Local function to resolve nested types found in the superclass.
+  auto updateSuperclassNestedTypes = [&] {
+    for (auto &nested : T->getNestedTypes()) {
+      if (nested.second.empty()) continue;
+      if (nested.second.front()->isUnresolved()) {
+        (void)T->getNestedArchetypeAnchor(nested.first, *this,
+          PotentialArchetype::NestedTypeUpdate::ResolveExisting);
+      }
+    }
+  };
+
   // If we haven't yet recorded a superclass constraint for this equivalence
   // class, do so now.
   if (!equivClass->superclass) {
     equivClass->superclass = superclass;
     updateSuperclassConformances();
+    updateSuperclassNestedTypes();
+
     // Presence of a superclass constraint implies a _Class layout
     // constraint.
     auto layoutReqSource = source->viaSuperclass(*this, nullptr);
@@ -2880,6 +2897,7 @@
 
     // We've strengthened the bound, so update superclass conformances.
     updateSuperclassConformances();
+    updateSuperclassNestedTypes();
     return;
   }
 
@@ -4023,10 +4041,7 @@
   if (Impl->NumUnresolvedNestedTypes > 0) {
     visitPotentialArchetypes([&](PotentialArchetype *pa) {
       // We only care about nested types that haven't been resolved.
-      if (pa->getParent() == nullptr || pa->getResolvedAssociatedType() ||
-          pa->getTypeAliasDecl() ||
-          /* FIXME: Should be able to handle this earlier */pa->getSuperclass())
-        return;
+      if (!pa->isUnresolved()) return;
 
       // Try to typo correct to a nested type name.
       Identifier correction = typoCorrectNestedType(pa);
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index dc254fe..860ff42 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -948,17 +948,7 @@
 /// \brief Compare two protocols to establish an ordering between them.
 int ProtocolType::compareProtocols(ProtocolDecl * const* PP1,
                                    ProtocolDecl * const* PP2) {
-  auto *P1 = *PP1;
-  auto *P2 = *PP2;
-  ModuleDecl *M1 = P1->getParentModule();
-  ModuleDecl *M2 = P2->getParentModule();
-
-  // Try ordering based on module name, first.
-  if (int result = M1->getName().str().compare(M2->getName().str()))
-    return result;
-
-  // Order based on protocol name.
-  return P1->getName().str().compare(P2->getName().str());
+  return TypeDecl::compare(*PP1, *PP2);
 }
 
 bool ProtocolType::visitAllProtocols(
diff --git a/lib/IDE/APIDigesterData.cpp b/lib/IDE/APIDigesterData.cpp
index 78f4ec5..8e7450d 100644
--- a/lib/IDE/APIDigesterData.cpp
+++ b/lib/IDE/APIDigesterData.cpp
@@ -251,7 +251,9 @@
   case APIDiffItemKind::ADK_CommonDiffItem: {
     auto *Left = static_cast<const CommonDiffItem*>(this);
     auto *Right = static_cast<const CommonDiffItem*>(&Other);
-    return Left->ChildIndex == Right->ChildIndex;
+    return
+      Left->DiffKind == Right->DiffKind &&
+      Left->ChildIndex == Right->ChildIndex;
   }
   case APIDiffItemKind::ADK_NoEscapeFuncParam: {
     auto *Left = static_cast<const NoEscapeFuncParam*>(this);
diff --git a/lib/SILOptimizer/Utils/Generics.cpp b/lib/SILOptimizer/Utils/Generics.cpp
index 729fd34..0edd00e 100644
--- a/lib/SILOptimizer/Utils/Generics.cpp
+++ b/lib/SILOptimizer/Utils/Generics.cpp
@@ -170,7 +170,8 @@
 // ReabstractionInfo
 // =============================================================================
 
-static bool shouldNotSpecializeCallee(SILFunction *Callee) {
+static bool shouldNotSpecializeCallee(SILFunction *Callee,
+                                      SubstitutionList Subs = {}) {
   if (!Callee->shouldOptimize()) {
     DEBUG(llvm::dbgs() << "    Cannot specialize function " << Callee->getName()
           << " marked to be excluded from optimizations.\n");
@@ -180,6 +181,10 @@
   if (Callee->hasSemanticsAttr("optimize.sil.specialize.generic.never"))
     return true;
 
+  if (!Subs.empty() &&
+      Callee->hasSemanticsAttr("optimize.sil.specialize.generic.partial.never"))
+    return true;
+
   return false;
 }
 
@@ -291,6 +296,10 @@
     // We need a generic environment for the partial specialization.
     if (!CalleeGenericEnv)
       return false;
+
+    // Bail if the callee should not be partially specialized.
+    if (shouldNotSpecializeCallee(Callee, ParamSubs))
+      return false;
   }
 
   return true;
diff --git a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
index 7aecd66..bf5f9f3 100644
--- a/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
+++ b/lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
@@ -591,6 +591,31 @@
   return false;
 }
 
+// Returns true if a given apply site should be skipped during the
+// early inlining pass.
+//
+// NOTE: Add here the checks for any specific @_semantics/@_effects
+// attributes causing a given callee to be excluded from the inlining
+// during the early inlining pass.
+static bool shouldSkipApplyDuringEarlyInlining(FullApplySite AI) {
+  // Add here the checks for any specific @_semantics attributes that need
+  // to be skipped during the early inlining pass.
+  ArraySemanticsCall ASC(AI.getInstruction());
+  if (ASC && !ASC.canInlineEarly())
+    return true;
+
+  SILFunction *Callee = AI.getReferencedFunction();
+  if (!Callee)
+    return false;
+
+  // Add here the checks for any specific @_effects attributes that need
+  // to be skipped during the early inlining pass.
+  if (Callee->hasEffectsKind())
+    return true;
+
+  return false;
+}
+
 // Returns the callee of an apply_inst if it is basically inlineable.
 SILFunction *swift::getEligibleFunction(FullApplySite AI,
                                         InlineSelection WhatToInline) {
@@ -606,8 +631,7 @@
   // attribute if the inliner is asked not to inline them.
   if (Callee->hasSemanticsAttrs() || Callee->hasEffectsKind()) {
     if (WhatToInline == InlineSelection::NoSemanticsAndGlobalInit) {
-      ArraySemanticsCall ASC(AI.getInstruction());
-      if (!ASC.canInlineEarly())
+      if (shouldSkipApplyDuringEarlyInlining(AI))
         return nullptr;
     }
     // The "availability" semantics attribute is treated like global-init.
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index ed10d77..f72f956 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -760,6 +760,12 @@
         if (result == nullptr) {
           result = new (tc.Context) ErrorExpr(range);
           cs.setType(result, erasedTy);
+          // The opaque value is no longer reachable in an AST walk as
+          // a result of the result above being replaced with an
+          // ErrorExpr, but there is code expecting to have a type set
+          // on it. Since we no longer have a reachable reference,
+          // we'll null this out.
+          record.OpaqueValue = nullptr;
         }
       }
 
@@ -768,7 +774,7 @@
       // means this is our only chance to propagate the l-value access kind
       // down to the original existential value.  Otherwise, propagateLVAK
       // will handle this.
-      if (record.OpaqueValue->hasLValueAccessKind())
+      if (record.OpaqueValue && record.OpaqueValue->hasLValueAccessKind())
         cs.propagateLValueAccessKind(record.ExistentialValue,
                                   record.OpaqueValue->getLValueAccessKind());
 
@@ -5861,6 +5867,8 @@
 
 Expr *ExprRewriter::buildObjCBridgeExpr(Expr *expr, Type toType,
                                         ConstraintLocatorBuilder locator) {
+  auto &tc = cs.getTypeChecker();
+
   Type fromType = cs.getType(expr);
 
   // Bridged collection casts always succeed, so we treat them as
@@ -5883,6 +5891,20 @@
     if (!objcExpr)
       return nullptr;
 
+    // We might have a coercion of a Swift type to a CF type toll-free
+    // bridged to Objective-C.
+    //
+    // FIXME: Ideally we would instead have already recorded a restriction
+    // when solving the constraint, and we wouldn't need to duplicate this
+    // part of coerceToType() here.
+    if (auto foreignClass = toType->getClassOrBoundGenericClass()) {
+      if (foreignClass->getForeignClassKind() ==
+            ClassDecl::ForeignKind::CFType) {
+        return cs.cacheType(
+          new (tc.Context) ForeignObjectConversionExpr(objcExpr, toType));
+      }
+    }
+
     return coerceToType(objcExpr, toType, locator);
   }
 
diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp
index ba4600b..88277eb 100644
--- a/lib/Sema/CSRanking.cpp
+++ b/lib/Sema/CSRanking.cpp
@@ -83,6 +83,10 @@
     case SK_KeyPathSubscript:
       log << "key path subscript";
       break;
+
+    case SK_StringToPointerConversion:
+      log << "string-to-pointer conversion";
+      break;
     }
     log << ")\n";
   }
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index b665bcb..041895a 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -4397,6 +4397,8 @@
     // If we haven't resolved the element type, generate constraints.
     if (baseType2->isTypeVariableOrMember()) {
       if (flags.contains(TMF_GenerateConstraints)) {
+        increaseScore(SK_StringToPointerConversion);
+
         auto int8Con = Constraint::create(*this, ConstraintKind::Bind,
                                        baseType2, TC.getInt8Type(DC),
                                        getConstraintLocator(locator));
@@ -4418,6 +4420,8 @@
     if (!isStringCompatiblePointerBaseType(TC, DC, baseType2)) {
       return SolutionKind::Error;
     }
+
+    increaseScore(SK_StringToPointerConversion);
     return SolutionKind::Solved;
   }
       
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 6674481..2171fe2 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -1461,7 +1461,8 @@
   return std::move(solutions[0]);
 }
 
-bool ConstraintSystem::Candidate::solve() {
+bool ConstraintSystem::Candidate::solve(
+    llvm::SmallDenseSet<Expr *> &shrunkExprs) {
   // Don't attempt to solve candidate if there is closure
   // expression involved, because it's handled specially
   // by parent constraint system (e.g. parameter lists).
@@ -1504,6 +1505,11 @@
     return true;
   }
 
+  // If this candidate is too complex given the number
+  // of the domains we have reduced so far, let's bail out early.
+  if (isTooComplexGiven(&cs, shrunkExprs))
+    return false;
+
   if (TC.getLangOpts().DebugConstraintSolver) {
     auto &log = cs.getASTContext().TypeCheckerDebug->getStream();
     log << "--- Solving candidate for shrinking at ";
@@ -1557,7 +1563,7 @@
   }
 
   // Record found solutions as suggestions.
-  this->applySolutions(solutions);
+  this->applySolutions(solutions, shrunkExprs);
 
   // Let's double-check if we have any implicit expressions
   // with type variables and nullify their types.
@@ -1569,7 +1575,8 @@
 }
 
 void ConstraintSystem::Candidate::applySolutions(
-                            llvm::SmallVectorImpl<Solution> &solutions) const {
+    llvm::SmallVectorImpl<Solution> &solutions,
+    llvm::SmallDenseSet<Expr *> &shrunkExprs) const {
   // A collection of OSRs with their newly reduced domains,
   // it's domains are sets because multiple solutions can have the same
   // choice for one of the type variables, and we want no duplication.
@@ -1616,6 +1623,9 @@
       = TC.Context.AllocateUninitialized<ValueDecl *>(choices.size());
     std::uninitialized_copy(choices.begin(), choices.end(), decls.begin());
     OSR->setDecls(decls);
+
+    // Record successfully shrunk expression.
+    shrunkExprs.insert(OSR);
   }
 }
 
@@ -1684,7 +1694,8 @@
         auto func = applyExpr->getFn();
         // Let's record this function application for post-processing
         // as well as if it contains overload set, see walkToExprPost.
-        ApplyExprs.push_back({applyExpr, isa<OverloadSetRefExpr>(func)});
+        ApplyExprs.push_back(
+            {applyExpr, isa<OverloadSetRefExpr>(func) || isa<TypeExpr>(func)});
       }
 
       return { true, expr };
@@ -1918,11 +1929,12 @@
   // so we can start solving them separately.
   expr->walk(collector);
 
+  llvm::SmallDenseSet<Expr *> shrunkExprs;
   for (auto &candidate : collector.Candidates) {
     // If there are no results, let's forget everything we know about the
     // system so far. This actually is ok, because some of the expressions
     // might require manual salvaging.
-    if (candidate.solve()) {
+    if (candidate.solve(shrunkExprs)) {
       // Let's restore all of the original OSR domains for this sub-expression,
       // this means that we can still make forward progress with solving of the
       // top sub-expressions.
@@ -1933,6 +1945,7 @@
             return childExpr;
 
           OSR->setDecls(domain->getSecond());
+          shrunkExprs.erase(OSR);
         }
 
         return childExpr;
@@ -2480,8 +2493,9 @@
   auto afterDisjunction = InactiveConstraints.erase(disjunction);
   CG.removeConstraint(disjunction);
 
+  Score initialScore = CurrentScore;
   Optional<DisjunctionChoice> lastSolvedChoice;
-  Optional<DisjunctionChoice> firstNonGenericOperatorSolution;
+  Optional<Score> bestNonGenericScore;
 
   ++solverState->NumDisjunctions;
   auto constraints = disjunction->getNestedConstraints();
@@ -2507,9 +2521,13 @@
     //        already have a solution involving non-generic operators,
     //        but continue looking for a better non-generic operator
     //        solution.
-    if (firstNonGenericOperatorSolution &&
-        currentChoice.isGenericOperatorOrUnavailable())
-      continue;
+    if (bestNonGenericScore && currentChoice.isGenericOperatorOrUnavailable()) {
+      // If non-generic solution increased the score by applying any
+      // fixes or restrictions to the solution, let's not skip generic
+      // overloads because they could produce a better solution.
+      if (bestNonGenericScore <= initialScore)
+        continue;
+    }
 
     // We already have a solution; check whether we should
     // short-circuit the disjunction.
@@ -2542,11 +2560,12 @@
       DisjunctionChoices.push_back({locator, index});
     }
 
-    if (currentChoice.solve(solutions, allowFreeTypeVariables)) {
-      if (!firstNonGenericOperatorSolution &&
-          !currentChoice.isGenericOperatorOrUnavailable() &&
-          currentChoice.isSymmetricOperator())
-        firstNonGenericOperatorSolution = currentChoice;
+    if (auto score = currentChoice.solve(solutions, allowFreeTypeVariables)) {
+      if (!currentChoice.isGenericOperatorOrUnavailable() &&
+          currentChoice.isSymmetricOperator()) {
+        if (!bestNonGenericScore || score < bestNonGenericScore)
+          bestNonGenericScore = score;
+      }
 
       lastSolvedChoice = currentChoice;
 
@@ -2578,10 +2597,12 @@
   return tooComplex || !lastSolvedChoice;
 }
 
-bool DisjunctionChoice::solve(SmallVectorImpl<Solution> &solutions,
-                              FreeTypeVariableBinding allowFreeTypeVariables) {
+Optional<Score>
+DisjunctionChoice::solve(SmallVectorImpl<Solution> &solutions,
+                         FreeTypeVariableBinding allowFreeTypeVariables) {
   CS->simplifyDisjunctionChoice(Choice);
-  return !CS->solveRec(solutions, allowFreeTypeVariables);
+  bool failed = CS->solveRec(solutions, allowFreeTypeVariables);
+  return failed ? None : Optional<Score>(CS->CurrentScore);
 }
 
 bool DisjunctionChoice::isGenericOperatorOrUnavailable() const {
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 27ae6ac..d81b0a4 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -416,8 +416,10 @@
   SK_EmptyExistentialConversion,
   /// A key path application subscript.
   SK_KeyPathSubscript,
-  
-  SK_LastScoreKind = SK_KeyPathSubscript,
+  // A conversion from a string to a pointer.
+  SK_StringToPointerConversion,
+
+  SK_LastScoreKind = SK_StringToPointerConversion,
 };
 
 /// The number of score kinds.
@@ -998,15 +1000,45 @@
     /// \brief Try to solve this candidate sub-expression
     /// and re-write it's OSR domains afterwards.
     ///
+    /// \param shrunkExprs The set of expressions which
+    /// domains have been successfully shrunk so far.
+    ///
     /// \returns true on solver failure, false otherwise.
-    bool solve();
+    bool solve(llvm::SmallDenseSet<Expr *> &shrunkExprs);
 
     /// \brief Apply solutions found by solver as reduced OSR sets for
     /// for current and all of it's sub-expressions.
     ///
     /// \param solutions The solutions found by running solver on the
     /// this candidate expression.
-    void applySolutions(llvm::SmallVectorImpl<Solution> &solutions) const;
+    ///
+    /// \param shrunkExprs The set of expressions which
+    /// domains have been successfully shrunk so far.
+    void applySolutions(llvm::SmallVectorImpl<Solution> &solutions,
+                        llvm::SmallDenseSet<Expr *> &shrunkExprs) const;
+
+    /// Check if attempt at solving of the candidate makes sense given
+    /// the current conditions - number of shrunk domains which is related
+    /// to the given candidate over the total number of disjunctions present.
+    static bool isTooComplexGiven(ConstraintSystem *const cs,
+                                  llvm::SmallDenseSet<Expr *> &shrunkExprs) {
+      SmallVector<Constraint *, 8> disjunctions;
+      cs->collectDisjunctions(disjunctions);
+
+      unsigned unsolvedDisjunctions = disjunctions.size();
+      for (auto *disjunction : disjunctions) {
+        auto *locator = disjunction->getLocator();
+        if (!locator)
+          continue;
+
+        if (auto *anchor = locator->getAnchor()) {
+          if (shrunkExprs.count(anchor) > 0)
+            --unsolvedDisjunctions;
+        }
+      }
+
+      return unsolvedDisjunctions >= 5;
+    }
   };
 
   /// \brief Describes the current solver state.
@@ -2671,8 +2703,8 @@
   bool isSymmetricOperator() const;
 
   /// \brief Apply given choice to the system and try to solve it.
-  bool solve(SmallVectorImpl<Solution> &solutions,
-             FreeTypeVariableBinding allowFreeTypeVariables);
+  Optional<Score> solve(SmallVectorImpl<Solution> &solutions,
+                        FreeTypeVariableBinding allowFreeTypeVariables);
 
 private:
   static ValueDecl *getOperatorDecl(Constraint *constraint) {
diff --git a/lib/Sema/ITCDecl.cpp b/lib/Sema/ITCDecl.cpp
index 76ae9cc..4602340 100644
--- a/lib/Sema/ITCDecl.cpp
+++ b/lib/Sema/ITCDecl.cpp
@@ -108,14 +108,24 @@
 
   // Validate the type of this inherited clause entry.
   // FIXME: Recursion into existing type checker.
-  GenericTypeToArchetypeResolver resolver(dc);
-  if (TC.validateType(*inherited, dc, options, &resolver,
+  Optional<ProtocolRequirementTypeResolver> protoResolver;
+  Optional<GenericTypeToArchetypeResolver> archetypeResolver;
+  GenericTypeResolver *resolver;
+  if (auto *proto = dyn_cast<ProtocolDecl>(dc)) {
+    protoResolver.emplace(proto);
+    resolver = protoResolver.getPointer();
+  } else {
+    archetypeResolver.emplace(dc);
+    resolver = archetypeResolver.getPointer();
+  }
+
+  if (TC.validateType(*inherited, dc, options, resolver,
                       &unsatisfiedDependency)) {
     inherited->setInvalidType(getASTContext());
   }
 
   auto type = inherited->getType();
-  if (!type.isNull())
+  if (!type.isNull() && !isa<ProtocolDecl>(dc))
     inherited->setType(dc->mapTypeOutOfContext(type));
 }
 
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index d1f4f49..7d76f18 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -209,35 +209,37 @@
     return DependentMemberType::get(baseTy, assocType);
   }
 
-  // If the nested type comes from a type alias, use either the alias's
-  // concrete type, or resolve its components down to another dependent member.
-  if (auto alias = nestedPA->getTypeAliasDecl()) {
-    assert(!alias->getGenericParams() && "Generic typealias in protocol");
-    ref->setValue(alias);
-    return TC.substMemberTypeWithBase(DC->getParentModule(), alias, baseTy);
-  }
-  
-  Identifier name = ref->getIdentifier();
-  SourceLoc nameLoc = ref->getIdLoc();
+  // If the nested type comes from a concrete type, substitute the base type
+  // into it.
+  if (auto concrete = nestedPA->getConcreteTypeDecl()) {
+    ref->setValue(concrete);
 
-  // Check whether the name can be found in the superclass.
-  // FIXME: The generic signature builder should be doing this and mapping down to a
-  // concrete type.
-  if (auto superclassTy = basePA->getSuperclass()) {
-    if (auto lookup = TC.lookupMemberType(DC, superclassTy, name)) {
-      if (lookup.isAmbiguous()) {
-        TC.diagnoseAmbiguousMemberType(baseTy, baseRange, name, nameLoc,
-                                       lookup);
-        return ErrorType::get(TC.Context);
+    if (baseTy->isTypeParameter()) {
+      if (auto proto =
+            concrete->getDeclContext()
+              ->getAsProtocolOrProtocolExtensionContext()) {
+        auto subMap = SubstitutionMap::getProtocolSubstitutions(
+                        proto, baseTy, ProtocolConformanceRef(proto));
+        return concrete->getDeclaredInterfaceType().subst(subMap);
       }
 
-      ref->setValue(lookup.front().first);
-      // FIXME: Record (via type sugar) that this was referenced via baseTy.
-      return lookup.front().second;
+      if (auto superclass = basePA->getSuperclass()) {
+        return superclass->getTypeOfMember(
+                                         DC->getParentModule(), concrete,
+                                         concrete->getDeclaredInterfaceType());
+      }
+
+      llvm_unreachable("shouldn't have a concrete decl here");
     }
+
+    return TC.substMemberTypeWithBase(DC->getParentModule(), concrete, baseTy);
   }
 
+  assert(nestedPA->isUnresolved() && "meaningless unresolved type");
+
   // Complain that there is no suitable type.
+  Identifier name = ref->getIdentifier();
+  SourceLoc nameLoc = ref->getIdLoc();
   TC.diagnose(nameLoc, diag::invalid_member_type, name, baseTy)
     .highlight(baseRange);
   return ErrorType::get(TC.Context);
diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb
index 7540998..1c47aca 100644
--- a/stdlib/public/core/Integers.swift.gyb
+++ b/stdlib/public/core/Integers.swift.gyb
@@ -2271,6 +2271,7 @@
 }
 
 extension FixedWidthInteger {
+  @_semantics("optimize.sil.specialize.generic.partial.never")
   public init<Other: BinaryInteger>(clamping source: Other) {
     if _slowPath(source < Self.min) {
       self = Self.min
@@ -2416,6 +2417,7 @@
 }
 
 extension UnsignedInteger where Self : FixedWidthInteger {
+  @_semantics("optimize.sil.specialize.generic.partial.never")
   @inline(__always)
   public init<T : BinaryInteger>(_ source: T) {
     // This check is potentially removable by the optimizer
@@ -2430,6 +2432,7 @@
     self.init(extendingOrTruncating: source)
   }
 
+  @_semantics("optimize.sil.specialize.generic.partial.never")
   @inline(__always)
   public init?<T : BinaryInteger>(exactly source: T) {
     // This check is potentially removable by the optimizer
@@ -2494,6 +2497,7 @@
 }
 
 extension SignedInteger where Self : FixedWidthInteger {
+  @_semantics("optimize.sil.specialize.generic.partial.never")
   @inline(__always)
   public init<T : BinaryInteger>(_ source: T) {
     // This check is potentially removable by the optimizer
@@ -2510,6 +2514,7 @@
     self.init(extendingOrTruncating: source)
   }
 
+  @_semantics("optimize.sil.specialize.generic.partial.never")
   @inline(__always)
   public init?<T : BinaryInteger>(exactly source: T) {
     // This check is potentially removable by the optimizer
diff --git a/stdlib/public/core/String.swift b/stdlib/public/core/String.swift
index e404fc6..0a4dd9f 100644
--- a/stdlib/public/core/String.swift
+++ b/stdlib/public/core/String.swift
@@ -211,6 +211,7 @@
     }
   }
 
+  @_semantics("optimize.sil.specialize.generic.partial.never")
   internal func _withCSubstringAndLength<
     Result, TargetEncoding: Unicode.Encoding
   >(
diff --git a/test/Constraints/overload.swift b/test/Constraints/overload.swift
index 05338ee..4b06f4d 100644
--- a/test/Constraints/overload.swift
+++ b/test/Constraints/overload.swift
@@ -222,3 +222,4 @@
 // Ensure that we consider these unambiguous
 let _ = curry(+)(1)
 let _ = [0].reduce(0, +)
+let _ = curry(+)("string vs. pointer")
diff --git a/test/Generics/superclass_constraint.swift b/test/Generics/superclass_constraint.swift
index efb35a3..0d585e3 100644
--- a/test/Generics/superclass_constraint.swift
+++ b/test/Generics/superclass_constraint.swift
@@ -152,3 +152,18 @@
 }
 
 func genericFunc<T : Elementary, U : Classical>(_: T, _: U) where T.Element == U.Element {}
+
+// Lookup within superclass constraints.
+protocol P8 {
+  associatedtype B
+}
+
+class C8 {
+  struct A { }
+}
+
+func superclassLookup1<T: C8 & P8>(_: T) where T.A == T.B { }
+
+func superclassLookup2<T: P8>(_: T) where T.A == T.B, T: C8 { }
+
+func superclassLookup3<T>(_: T) where T.A == T.B, T: C8, T: P8 { }
diff --git a/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h b/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
index f628500..3f96927 100644
--- a/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
+++ b/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
@@ -14,6 +14,10 @@
 typedef struct __CFTree *CFTreeRef;
 typedef const struct __attribute__((objc_bridge(CFURL))) __CFURL * CFURLRef;
 
+typedef struct __attribute__((objc_bridge(NSDictionary))) __CFDictionary const *CFDictionaryRef;
+typedef struct __attribute__((objc_bridge(NSArray))) __CFArray const *CFArrayRef;
+typedef struct __attribute__((objc_bridge(NSSet))) __CFSet const *CFSetRef;
+
 typedef CFTypeRef CFAliasForTypeRef;
 
 
diff --git a/test/Migrator/API.json b/test/Migrator/API.json
index 64d8858..610a9dd 100644
--- a/test/Migrator/API.json
+++ b/test/Migrator/API.json
@@ -31,6 +31,28 @@
   {
     "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
+    "NodeAnnotation": "WrapOptional",
+    "ChildIndex": "0",
+    "LeftUsr": "c:objc(cs)PropertyUserInterface(cm)methodPlus",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "",
+    "ModuleName": "bar"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "Rename",
+    "ChildIndex": "0",
+    "LeftUsr": "c:objc(cs)PropertyUserInterface(cm)methodPlus",
+    "LeftComment": "",
+    "RightUsr": "",
+    "RightComment": "newMethodPlus()",
+    "ModuleName": "bar"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
     "NodeAnnotation": "Rename",
     "ChildIndex": "0",
     "LeftUsr": "c:objc(cs)BarForwardDeclaredClass(im)barInstanceFunc1:anotherValue:anotherValue1:anotherValue2:",
diff --git a/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h b/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h
index 2a38c2e..eea572a 100644
--- a/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h
+++ b/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h
@@ -26,6 +26,7 @@
 - (void) setField:(int)info;
 + (int) fieldPlus;
 + (void) methodPlus:(int)info;
++ (void) methodPlus;
 @end
 
 #define BAR_MACRO_1 0
diff --git a/test/Migrator/rename.swift b/test/Migrator/rename.swift
index 5089922..924318b 100644
--- a/test/Migrator/rename.swift
+++ b/test/Migrator/rename.swift
@@ -16,6 +16,7 @@
   b.barInstanceFunc1(0, anotherValue: 1, anotherValue1: 2, anotherValue2: 3)
   barGlobalFuncOldName(2)
   _ = barGlobalVariableOldEnumElement
+  _ = PropertyUserInterface.methodPlus()
 }
 
 func foo1(_ b: BarForwardDeclaredClass) {
diff --git a/test/Migrator/rename.swift.expected b/test/Migrator/rename.swift.expected
index a97ba0a..08f23ff 100644
--- a/test/Migrator/rename.swift.expected
+++ b/test/Migrator/rename.swift.expected
@@ -16,6 +16,7 @@
   b.barNewInstanceFunc1(newlabel1: 0, newlabel2: 1, newlabel3: 2, newlabel4: 3)
   barGlobalFuncNewName(newlabel: 2)
   _ = NewEnum.enumElement
+  _ = PropertyUserInterface.newMethodPlus()
 }
 
 func foo1(_ b: BarForwardDeclaredClass) {
diff --git a/test/SILGen/keypaths_objc.swift b/test/SILGen/keypaths_objc.swift
index ad3b6f1..8bbaf94 100644
--- a/test/SILGen/keypaths_objc.swift
+++ b/test/SILGen/keypaths_objc.swift
@@ -1,4 +1,5 @@
 // RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-keypath-components -emit-silgen -import-objc-header %S/Inputs/keypaths_objc.h %s | %FileCheck %s
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-keypath-components -emit-ir -import-objc-header %S/Inputs/keypaths_objc.h %s
 // REQUIRES: objc_interop
 
 import Foundation
@@ -55,3 +56,23 @@
   // CHECK: keypath $KeyPath<Foo, Int>, (objc "int"; {{.*}} id #Foo.int!getter.1 :
   _ = \Foo.int
 }
+
+struct X {}
+
+extension NSObject {
+    var x: X { return X() }
+    @objc var objc: Int { return 0 }
+    @objc dynamic var dynamic: Int { return 0 }
+}
+
+// CHECK-LABEL: sil hidden @{{.*}}nonobjcExtensionOfObjCClass
+func nonobjcExtensionOfObjCClass() {
+  // Should be treated as a statically-dispatch property
+  // CHECK: keypath $KeyPath<NSObject, X>, ({{.*}} id @
+  _ = \NSObject.x
+  // CHECK: keypath $KeyPath<NSObject, Int>, ({{.*}} id #NSObject.objc!getter.1.foreign
+  _ = \NSObject.objc
+  // CHECK: keypath $KeyPath<NSObject, Int>, ({{.*}} id #NSObject.dynamic!getter.1.foreign
+  _ = \NSObject.dynamic
+
+}
diff --git a/test/SILOptimizer/inline_semantics.sil b/test/SILOptimizer/inline_semantics.sil
index 0b06397..8947788 100644
--- a/test/SILOptimizer/inline_semantics.sil
+++ b/test/SILOptimizer/inline_semantics.sil
@@ -12,10 +12,13 @@
   return %1 : $Int32                               // id: %2
 }
 
+//Not every @_semantics should be skipped during the early inlining pass, but
+//only those ones which are explicitly listed in shouldSkipApplyDuringEarlyInlining.
+
 //CHECK-LABEL: caller_func
-//CHECK: function_ref
-//CHECK: apply
-//CHECK-NEXT: ret
+//CHECK-NOT: function_ref
+//CHECK-NOT: apply
+//CHECK: end sil function 'caller_func'
 sil @caller_func : $@convention(thin) () -> Int32 {
 bb0:
   %0 = function_ref @callee_func : $@convention(thin) () -> Int32 // user: %1
@@ -23,6 +26,29 @@
   return %1 : $Int32                                  // id: %2
 }
 
+sil [_semantics "array.make_mutable"] @callee_func_with_to_be_skipped_during_inlining_semantics : $@convention(method) (@inout Int32) -> Int32 {
+bb0(%self : $*Int32):
+  %0 = integer_literal $Builtin.Int32, 3           // user: %1
+  %1 = struct $Int32 (%0 : $Builtin.Int32)         // user: %2
+  return %1 : $Int32                               // id: %2
+}
+
+//Not every @_semantics should be skipped during the early inlining pass, but
+//only those ones which are explicitly listed in shouldSkipApplyDuringEarlyInlining.
+
+//CHECK-LABEL: caller_func2
+//CHECK: function_ref
+//CHECK: apply
+//CHECK: end sil function 'caller_func2'
+sil @caller_func2 : $@convention(thin) () -> Int32 {
+bb0:
+  %self = alloc_stack $Int32
+  %0 = function_ref @callee_func_with_to_be_skipped_during_inlining_semantics  : $@convention(method) (@inout Int32) -> Int32 // user: %1
+  %1 = apply %0(%self) : $@convention(method) (@inout Int32) -> Int32                 // user: %2
+  dealloc_stack %self : $*Int32
+  return %1 : $Int32                                  // id: %2
+}
+
 // A function annotated with the @effects(readonly) attribute.
 sil [readonly] @callee_func2 : $@convention(thin) () -> Int32 {
 bb0:
diff --git a/test/Sema/circular_decl_checking.swift b/test/Sema/circular_decl_checking.swift
index 1e556fb..efe76cd 100644
--- a/test/Sema/circular_decl_checking.swift
+++ b/test/Sema/circular_decl_checking.swift
@@ -43,9 +43,10 @@
 var TopLevelVar: TopLevelVar? { return nil } // expected-error 2 {{use of undeclared type 'TopLevelVar'}}
 
 
-protocol AProtocol {
-  // FIXME: Should produce an error here, but it's currently causing problems.
-  associatedtype e : e
+// FIXME: The first error is redundant, isn't correct in what it states, and
+// also should be emitted on the inheritance clause.
+protocol AProtocol { // expected-error {{first type 'Self.e' in conformance requirement does not refer to a generic parameter or associated type}}
+  associatedtype e : e // expected-error {{inheritance from non-protocol, non-class type 'Self.e'}}
 }
 
 
diff --git a/test/Sema/complex_expressions.swift b/test/Sema/complex_expressions.swift
index 8ad6c52..27e02e3 100644
--- a/test/Sema/complex_expressions.swift
+++ b/test/Sema/complex_expressions.swift
@@ -117,3 +117,12 @@
      8: { $0 != $1 },  9: { $0 != $1 }, 10: { $0 != $1 }, 11: { $0 != $1 },
     12: { $0 != $1 }, 13: { $0 != $1 }, 14: { $0 != $1 }, 15: { $0 != $1 },
     16: { $0 != $1 }, 17: { $0 != $1 }, 18: { $0 != $1 }, 19: { $0 != $1 } ]
+
+// rdar://problem/32034560 - type-checker hangs trying to solve expression
+struct R32034560 {
+  private var R32034560: Array<Array<UInt32>>
+  private func foo(x: UInt32) -> UInt32 {
+    return ((self.R32034560[0][Int(x >> 24) & 0xFF] &+ self.R32034560[1][Int(x >> 16) & 0xFF]) ^ self.R32034560[2][Int(x >> 8) & 0xFF]) &+ self.R32034560[3][Int(x & 0xFF)]
+    // 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/test/decl/nested/protocol.swift b/test/decl/nested/protocol.swift
index e10d600..231c457 100644
--- a/test/decl/nested/protocol.swift
+++ b/test/decl/nested/protocol.swift
@@ -72,5 +72,6 @@
 
 class OtherGenericClass<T> {
   protocol InnerProtocol : OtherGenericClass { }
-  // expected-error@-1{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
+  // expected-error@-1{{non-class type 'InnerProtocol' cannot inherit from class 'OtherGenericClass<T>'}}
+  // expected-error@-2{{protocol 'InnerProtocol' cannot be nested inside another declaration}}
 }
diff --git a/test/decl/protocol/req/unsatisfiable.swift b/test/decl/protocol/req/unsatisfiable.swift
index 03eec2d..6c10773 100644
--- a/test/decl/protocol/req/unsatisfiable.swift
+++ b/test/decl/protocol/req/unsatisfiable.swift
@@ -30,3 +30,21 @@
   func f<T: P3>(_: T) where T.A == Self.A, T.A: C // expected-error{{instance method requirement 'f' cannot add constraint 'Self.A: C' on 'Self'}}
   func g<T: P3>(_: T) where T.A: C, T.A == Self.A  // expected-error{{instance method requirement 'g' cannot add constraint 'Self.A: C' on 'Self'}}
 }
+
+protocol Base {
+  associatedtype Assoc
+}
+
+// FIXME: The first error is redundant, isn't correct in what it states, and
+// also should be emitted on the inheritance clause.
+// FIXME: This used to /not/ error in Swift 3. It didn't impose any statically-
+// enforced requirements, but the compiler crashed if you used anything but the
+// same type.
+protocol Sub1: Base { // expected-error {{first type 'Self.Assoc' in conformance requirement does not refer to a generic parameter or associated type}}
+  associatedtype SubAssoc: Assoc // expected-error {{inheritance from non-protocol, non-class type 'Self.Assoc'}}
+}
+// FIXME: This error is incorrect in what it states and should be emitted on
+// the where-clause.
+protocol Sub2: Base { // expected-error {{first type 'Self.Assoc' in conformance requirement does not refer to a generic parameter or associated type}}
+  associatedtype SubAssoc where SubAssoc: Assoc
+}
diff --git a/test/expr/cast/cf.swift b/test/expr/cast/cf.swift
index 90d1d7f..343d8cf 100644
--- a/test/expr/cast/cf.swift
+++ b/test/expr/cast/cf.swift
@@ -80,3 +80,25 @@
   acceptNSString(x)
   acceptCFString(y)
 }
+
+func testBridgedCFDowncast(array: [Any], dictionary: [AnyHashable : Any], set: Set<AnyHashable>) {
+  let cfArray = array as CFArray
+  let cfDictionary = dictionary as CFDictionary
+  let cfSet = set as CFSet
+
+  _ = array as? CFArray // expected-warning {{conditional cast from '[Any]' to 'CFArray' always succeeds}}
+  _ = dictionary as? CFDictionary // expected-warning {{conditional cast from '[AnyHashable : Any]' to 'CFDictionary' always succeeds}}
+  _ = set as? CFSet // expected-warning {{conditional cast from 'Set<AnyHashable>' to 'CFSet' always succeeds}}
+
+  _ = array as! CFArray // expected-warning {{forced cast from '[Any]' to 'CFArray' always succeeds}}
+  _ = dictionary as! CFDictionary // expected-warning {{forced cast from '[AnyHashable : Any]' to 'CFDictionary' always succeeds}}
+  _ = set as! CFSet // expected-warning {{forced cast from 'Set<AnyHashable>' to 'CFSet' always succeeds}}
+
+  _ = cfArray as! [Any]
+  _ = cfDictionary as! [AnyHashable : Any]
+  _ = cfSet as! Set<AnyHashable>
+
+  _ = cfArray as? [Any]
+  _ = cfDictionary as? [AnyHashable : Any]
+  _ = cfSet as? Set<AnyHashable>
+}
diff --git a/validation-test/Sema/rdar32204609.swift b/validation-test/Sema/rdar32204609.swift
new file mode 100644
index 0000000..5e14f85
--- /dev/null
+++ b/validation-test/Sema/rdar32204609.swift
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: %target-build-swift %s -o %t/a.out
+// RUN: %target-run %t/a.out
+
+// REQUIRES: executable_test
+
+let x: Int! = nil
+let y: Int! = 1
+
+print(x == y)
diff --git a/validation-test/compiler_crashers/28693-swift-genericenvironment-queryinterfacetypesubstitutions-operator-swift-substitu.swift b/validation-test/compiler_crashers_fixed/28693-swift-genericenvironment-queryinterfacetypesubstitutions-operator-swift-substitu.swift
similarity index 86%
rename from validation-test/compiler_crashers/28693-swift-genericenvironment-queryinterfacetypesubstitutions-operator-swift-substitu.swift
rename to validation-test/compiler_crashers_fixed/28693-swift-genericenvironment-queryinterfacetypesubstitutions-operator-swift-substitu.swift
index d626bb2..03e9930 100644
--- a/validation-test/compiler_crashers/28693-swift-genericenvironment-queryinterfacetypesubstitutions-operator-swift-substitu.swift
+++ b/validation-test/compiler_crashers_fixed/28693-swift-genericenvironment-queryinterfacetypesubstitutions-operator-swift-substitu.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 b:Self