Merge pull request #5124 from rudkx/fix-stray-line

diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 43284c5..da5657a 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -373,12 +373,15 @@
 #
 # Usage:
 #   _add_swift_lipo_target(
+#     sdk                 # The name of the SDK the target was created for.
+#                         # Examples include "OSX", "IOS", "ANDROID", etc.
 #     target              # The name of the target to create
 #     output              # The file to be created by this target
 #     source_targets...   # The source targets whose outputs will be
 #                         # lipo'd into the output.
 #   )
-function(_add_swift_lipo_target target output)
+function(_add_swift_lipo_target sdk target output)
+  precondition(sdk MESSAGE "sdk is required")
   precondition(target MESSAGE "target is required")
   precondition(output MESSAGE "output is required")
 
@@ -397,7 +400,8 @@
     endif()
   endforeach()
 
-  if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
+  is_darwin_based_sdk("${sdk}" IS_DARWIN)
+  if(IS_DARWIN)
     # Use lipo to create the final binary.
     add_custom_command_target(unused_var
         COMMAND "${LIPO}" "-create" "-output" "${output}" ${source_binaries}
@@ -1467,6 +1471,7 @@
         endif()
         
         _add_swift_lipo_target(
+            ${sdk}
             ${lipo_target}${unsigned}
             "${UNIVERSAL_LIBRARY_NAME}${unsigned}"
             ${THIN_INPUT_TARGETS})
@@ -1529,6 +1534,7 @@
           set(UNIVERSAL_LIBRARY_NAME
               "${SWIFTSTATICLIB_DIR}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
           _add_swift_lipo_target(
+              ${sdk}
               ${lipo_target_static}
               "${UNIVERSAL_LIBRARY_NAME}"
               ${THIN_INPUT_TARGETS_STATIC})
diff --git a/docs/ContinuousIntegration.md b/docs/ContinuousIntegration.md
index 3ca81b0..e606afa 100644
--- a/docs/ContinuousIntegration.md
+++ b/docs/ContinuousIntegration.md
@@ -36,7 +36,7 @@
         Platform     | Comment | Check Status
         ------------ | ------- | ------------
         All supported platforms     | @swift-ci Please smoke test                | Swift Test Linux Platform (smoke test)<br>Swift Test OS X Platform (smoke test)
-        All supported platforms     | @swift-ci Please smoke test and mere       | Swift Test Linux Platform (smoke test)<br>Swift Test OS X Platform (smoke test)
+        All supported platforms     | @swift-ci Please smoke test and merge      | Swift Test Linux Platform (smoke test)<br>Swift Test OS X Platform (smoke test)
         OS X platform               | @swift-ci Please smoke test OS X platform  | Swift Test OS X Platform (smoke test)
         Linux platform              | @swift-ci Please smoke test Linux platform | Swift Test Linux Platform (smoke test)
 
diff --git a/include/swift/Basic/DemangleNodes.def b/include/swift/Basic/DemangleNodes.def
index f96b380..70c788e 100644
--- a/include/swift/Basic/DemangleNodes.def
+++ b/include/swift/Basic/DemangleNodes.def
@@ -131,7 +131,6 @@
 NODE(ReabstractionThunkHelper)
 NODE(ReturnType)
 NODE(SILBoxType)
-NODE(SelfTypeRef)
 CONTEXT_NODE(Setter)
 NODE(SpecializationPassID)
 NODE(SpecializationIsFragile)
diff --git a/include/swift/Serialization/ModuleFile.h b/include/swift/Serialization/ModuleFile.h
index ba1ef5f..55492f1 100644
--- a/include/swift/Serialization/ModuleFile.h
+++ b/include/swift/Serialization/ModuleFile.h
@@ -70,6 +70,7 @@
 
   /// The name of the module.
   StringRef Name;
+  friend StringRef getNameOfModule(const ModuleFile *);
 
   /// The target the module was built for.
   StringRef TargetTriple;
@@ -363,8 +364,11 @@
   /// as being malformed.
   Status error(Status issue = Status::Malformed) {
     assert(issue != Status::Valid);
-    assert((!FileContext || issue != Status::Malformed) &&
-           "error deserializing an individual record");
+    // This would normally be an assertion but it's more useful to print the
+    // PrettyStackTrace here even in no-asserts builds. Malformed modules are
+    // generally unrecoverable.
+    if (FileContext && issue == Status::Malformed)
+      abort();
     setStatus(issue);
     return getStatus();
   }
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index bcdca9b..ec51245 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -2800,8 +2800,6 @@
         printField("parent", static_cast<void *>(parent));
       if (auto assocType = T->getAssocType())
         printField("assoc_type", assocType->printRef());
-      if (auto selfProto = T->getSelfProtocol())
-        printField("self_proto", selfProto->printRef());
 
       // FIXME: This is ugly.
       OS << "\n";
diff --git a/lib/AST/ArchetypeBuilder.cpp b/lib/AST/ArchetypeBuilder.cpp
index e68a408..6a3fb1e 100644
--- a/lib/AST/ArchetypeBuilder.cpp
+++ b/lib/AST/ArchetypeBuilder.cpp
@@ -439,13 +439,11 @@
           if (!containingProtocol) continue;
           
           // Go up archetype parents until we find our containing protocol.
-          while (archetype->getSelfProtocol() != containingProtocol) {
+          while (archetype->getParent()) {
             identifiers.push_back(archetype->getName());
             archetype = archetype->getParent();
-            if (!archetype)
-              break;
           }
-          if (!archetype)
+          if (!archetype->isEqual(containingProtocol->getSelfTypeInContext()))
             continue;
         } else if (auto dependent = type->getAs<DependentMemberType>()) {
           do {
diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp
index 2ace3ef..65cd238 100644
--- a/lib/AST/Mangle.cpp
+++ b/lib/AST/Mangle.cpp
@@ -1091,15 +1091,6 @@
       return;
     }
     
-    // associated-type ::= 'Q' protocol-context
-    // Mangle the Self archetype of a protocol.
-    if (auto proto = archetype->getSelfProtocol()) {
-      Buffer << 'P';
-      mangleProtocolName(proto);
-      addSubstitution(archetype);
-      return;
-    }
-    
     // archetype ::= 'Q' <index>             # archetype with depth=0, index=N
     // archetype ::= 'Qd' <index> <index>    # archetype with depth=M+1, index=N
     // Mangle generic parameter archetypes.
diff --git a/lib/AST/PrettyStackTrace.cpp b/lib/AST/PrettyStackTrace.cpp
index 5b3dbaf..05ec8e9 100644
--- a/lib/AST/PrettyStackTrace.cpp
+++ b/lib/AST/PrettyStackTrace.cpp
@@ -35,6 +35,7 @@
 
 void swift::printDeclDescription(llvm::raw_ostream &out, const Decl *D,
                                  ASTContext &Context) {
+  SourceLoc loc = D->getStartLoc();
   bool hasPrintedName = false;
   if (auto *named = dyn_cast<ValueDecl>(D)) {
     if (named->hasName()) {
@@ -71,16 +72,27 @@
           
           out << " for " << ASD->getFullName();
           hasPrintedName = true;
+          loc = ASD->getStartLoc();
         }
       }
     }
+  } else if (auto *extension = dyn_cast<ExtensionDecl>(D)) {
+    Type extendedTy = extension->getExtendedType();
+    if (extendedTy) {
+      out << "extension of " << extendedTy;
+      hasPrintedName = true;
+    }
   }
 
   if (!hasPrintedName)
     out << "declaration " << (const void *)D;
 
-  out << " at ";
-  D->getStartLoc().print(out, Context.SourceMgr);
+  if (loc.isValid()) {
+    out << " at ";
+    loc.print(out, Context.SourceMgr);
+  } else {
+    out << " in module '" << D->getModuleContext()->getName() << '\'';
+  }
   out << '\n';
 }
 
@@ -168,9 +180,11 @@
                                  ASTContext &Context) {
   out << "type '" << type << '\'';
   if (Decl *decl = InterestingDeclForType().visit(type)) {
-    out << " (declared at ";
-    decl->getSourceRange().print(out, Context.SourceMgr);
-    out << ')';
+    if (decl->getSourceRange().isValid()) {
+      out << " (declared at ";
+      decl->getSourceRange().print(out, Context.SourceMgr);
+      out << ')';
+    }
   }
   out << '\n';
 }
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 5664247..23f24c4 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -979,9 +979,6 @@
     return depMem->getAssocType();
 
   if (auto archetype = dyn_cast<ArchetypeType>(this)) {
-    if (auto proto = archetype->getSelfProtocol())
-      return proto->getProtocolSelf();
-
     if (auto assoc = archetype->getAssocType())
       return assoc;
 
diff --git a/lib/Basic/Demangle.cpp b/lib/Basic/Demangle.cpp
index 665b7ef..f4fd0ba 100644
--- a/lib/Basic/Demangle.cpp
+++ b/lib/Basic/Demangle.cpp
@@ -1710,13 +1710,6 @@
   }
   
   NodePointer demangleArchetypeType() {
-    auto makeSelfType = [&](NodePointer proto) -> NodePointer {
-      auto selfType = NodeFactory::create(Node::Kind::SelfTypeRef);
-      selfType->addChild(proto);
-      Substitutions.push_back(selfType);
-      return selfType;
-    };
-    
     auto makeAssociatedType = [&](NodePointer root) -> NodePointer {
       NodePointer name = demangleIdentifier();
       if (!name) return nullptr;
@@ -1727,12 +1720,6 @@
       return assocType;
     };
     
-    if (Mangled.nextIf('P')) {
-      NodePointer proto = demangleProtocolName();
-      if (!proto) return nullptr;
-      return makeSelfType(proto);
-    }
-    
     if (Mangled.nextIf('Q')) {
       NodePointer root = demangleArchetypeType();
       if (!root) return nullptr;
@@ -1741,10 +1728,7 @@
     if (Mangled.nextIf('S')) {
       NodePointer sub = demangleSubstitutionIndex();
       if (!sub) return nullptr;
-      if (sub->getKind() == Node::Kind::Protocol)
-        return makeSelfType(sub);
-      else
-        return makeAssociatedType(sub);
+      return makeAssociatedType(sub);
     }
     if (Mangled.nextIf('s')) {
       NodePointer stdlib = NodeFactory::create(Node::Kind::Module, STDLIB_NAME);
@@ -2404,7 +2388,6 @@
     case Node::Kind::Protocol:
     case Node::Kind::QualifiedArchetype:
     case Node::Kind::ReturnType:
-    case Node::Kind::SelfTypeRef:
     case Node::Kind::SILBoxType:
     case Node::Kind::Structure:
     case Node::Kind::TupleElementName:
@@ -3462,10 +3445,6 @@
     print(pointer->getChild(0));
     Printer << '.' << pointer->getChild(1)->getText();
     return;
-  case Node::Kind::SelfTypeRef:
-    print(pointer->getChild(0));
-    Printer << ".Self";
-    return;
   case Node::Kind::ProtocolList: {
     NodePointer type_list = pointer->getChild(0);
     if (!type_list)
diff --git a/lib/Basic/Remangle.cpp b/lib/Basic/Remangle.cpp
index 36de4c2..b43001f 100644
--- a/lib/Basic/Remangle.cpp
+++ b/lib/Basic/Remangle.cpp
@@ -1374,15 +1374,6 @@
   }
 }
 
-void Remangler::mangleSelfTypeRef(Node *node) {
-  SubstitutionEntry entry;
-  if (trySubstitution(node, entry)) return;
-  Out << "QP";
-  assert(node->getNumChildren() == 1);
-  mangleProtocolWithoutPrefix(node->begin()[0].get());
-  addSubstitution(entry);
-}
-
 void Remangler::mangleArchetypeRef(Node *node) {
   Node::IndexType relativeDepth = node->getChild(0)->getIndex();
   Node::IndexType index = node->getChild(1)->getIndex();
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index 90e17c0..9dd82b4 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -55,6 +55,7 @@
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Sema.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CrashRecoveryContext.h"
 #include "llvm/Support/Path.h"
 #include <algorithm>
@@ -575,6 +576,12 @@
   }
   invocationArgStrs.push_back("-iapinotes-modules");
   invocationArgStrs.push_back(searchPathOpts.RuntimeLibraryImportPath);
+
+  // Map the Swift major version into the API notes version for Swift. This
+  // has the effect of allowing API notes to effect changes only on Swift
+  // major versions, not minor versions.
+  invocationArgStrs.push_back("-fapinotes-swift-version=" +
+    llvm::itostr(ctx.LangOpts.EffectiveLanguageVersion[0]));
 }
 
 std::unique_ptr<ClangImporter>
diff --git a/lib/IDE/TypeReconstruction.cpp b/lib/IDE/TypeReconstruction.cpp
index 4a56266..c6cba87 100644
--- a/lib/IDE/TypeReconstruction.cpp
+++ b/lib/IDE/TypeReconstruction.cpp
@@ -105,6 +105,10 @@
       return ArchetypeBuilder::mapTypeIntoContext(
           paramDecl->getDeclContext(), paramType).getPointer();
     } break;
+    case TypeKind::Protocol: {
+      return swift_can_type->castTo<ProtocolType>()->getDecl()
+          ->getSelfTypeInContext().getPointer();
+    }
     default:
       break;
     }
@@ -869,19 +873,6 @@
         Type nested;
         if (archetype->hasNestedType(identifier))
           nested = archetype->getNestedTypeValue(identifier);
-        else if (ProtocolDecl *self_protocol = archetype->getSelfProtocol()) {
-          for (auto self_member: self_protocol->getMembers()) {
-            if (AssociatedTypeDecl *associated_decl = llvm::dyn_cast_or_null<AssociatedTypeDecl>(self_member)) {
-              if (associated_decl->hasName()) {
-                llvm::StringRef decl_name = associated_decl->getNameStr();
-                if (decl_name == ident->getText()) {
-                  nested = associated_decl->getDeclaredType();
-                  break;
-                }
-              }
-            }
-          }
-        }
         if (nested) {
           result._types.push_back(nested);
           result._module = type_result._module;
@@ -1239,6 +1230,7 @@
     case Demangle::Node::Kind::Class:
     case Demangle::Node::Kind::Enum:
     case Demangle::Node::Kind::Structure:
+    case Demangle::Node::Kind::Protocol:
       nodes.push_back((*pos));
       VisitNode(ast, nodes, type_result, generic_context);
       break;
@@ -1329,6 +1321,7 @@
     case Demangle::Node::Kind::Enum:
     case Demangle::Node::Kind::Module:
     case Demangle::Node::Kind::Structure:
+    case Demangle::Node::Kind::Protocol:
       nodes.push_back((*pos));
       VisitNode(ast, nodes, decl_scope_result, generic_context);
       break;
@@ -1963,39 +1956,6 @@
   }
 }
 
-static void VisitNodeSelfTypeRef(
-    ASTContext *ast, std::vector<Demangle::NodePointer> &nodes,
-    Demangle::NodePointer &cur_node, VisitNodeResult &result,
-    const VisitNodeResult &generic_context) { // set by GenericType case
-  nodes.push_back(cur_node->getFirstChild());
-  VisitNodeResult type_result;
-  VisitNode(ast, nodes, type_result, generic_context);
-  if (type_result.HasSingleType()) {
-    Type supposed_protocol_type(type_result.GetFirstType());
-    ProtocolType *protocol_type = supposed_protocol_type->getAs<ProtocolType>();
-    ProtocolDecl *protocol_decl =
-        protocol_type ? protocol_type->getDecl() : nullptr;
-    if (protocol_decl) {
-      ArchetypeType::AssocTypeOrProtocolType assoc_protocol_type(protocol_decl);
-      if (ast) {
-        CanTypeWrapper<ArchetypeType> self_type = ArchetypeType::getNew(
-            *ast, nullptr, assoc_protocol_type, ast->getIdentifier("Self"),
-            {supposed_protocol_type}, Type(), false);
-        if (self_type.getPointer())
-          result._types.push_back(Type(self_type));
-        else
-          result._error = "referent type cannot be made into an archetype";
-      } else {
-        result._error = "invalid ASTContext";
-      }
-    } else {
-      result._error = "referent type does not resolve to a protocol";
-    }
-  } else {
-    result._error = "couldn't resolve referent type";
-  }
-}
-
 static void VisitNodeTupleElement(
     ASTContext *ast, std::vector<Demangle::NodePointer> &nodes,
     Demangle::NodePointer &cur_node, VisitNodeResult &result,
@@ -2259,10 +2219,6 @@
     VisitNodeQualifiedArchetype(ast, nodes, node, result, genericContext);
     break;
 
-  case Demangle::Node::Kind::SelfTypeRef:
-    VisitNodeSelfTypeRef(ast, nodes, node, result, genericContext);
-    break;
-
   case Demangle::Node::Kind::TupleElement:
     VisitNodeTupleElement(ast, nodes, node, result, genericContext);
     break;
diff --git a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
index d65234b..e56fed8 100644
--- a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
+++ b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
@@ -75,7 +75,6 @@
     // a pipeline, as it may break some optimizations.
     if (F->isKeepAsPublic()) {
       F->setLinkage(SILLinkage::Public);
-      F->setFragile(IsFragile_t::IsNotFragile);
       DEBUG(llvm::dbgs() << "DFE: Preserve the specialization "
                          << F->getName() << '\n');
       return true;
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index a36aa96..13cf5ba 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -4702,8 +4702,8 @@
     // Check that member operators reference the type of 'Self'.
     if (FD->getNumParameterLists() != 2 || FD->isInvalid()) return;
 
-    auto selfNominal =
-      FD->getDeclContext()->getAsNominalTypeOrNominalTypeExtensionContext();
+    auto *DC = FD->getDeclContext();
+    auto selfNominal = DC->getAsNominalTypeOrNominalTypeExtensionContext();
     if (!selfNominal) return;
 
     // Check the parameters for a reference to 'Self'.
@@ -4725,12 +4725,13 @@
       if (isProtocol) {
         // For a protocol, is it the 'Self' type parameter?
         if (auto genericParam = paramType->getAs<GenericTypeParamType>())
-          if (genericParam->getDepth() == 0 && genericParam->getIndex() == 0)
+          if (genericParam->isEqual(DC->getSelfInterfaceType()))
             return;
 
         // ... or the 'Self' archetype?
         if (auto archetype = paramType->getAs<ArchetypeType>())
-          if (archetype->getSelfProtocol() == selfNominal) return;
+          if (archetype->isEqual(DC->getSelfTypeInContext()))
+            return;
       }
     }
 
diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp
index 4bea257..f0005e2 100644
--- a/lib/Serialization/Deserialization.cpp
+++ b/lib/Serialization/Deserialization.cpp
@@ -25,6 +25,10 @@
 using namespace swift;
 using namespace swift::serialization;
 
+StringRef swift::getNameOfModule(const ModuleFile *MF) {
+  return MF->Name;
+}
+
 namespace {
   struct IDAndKind {
     const Decl *D;
@@ -37,13 +41,15 @@
   }
 
   class PrettyDeclDeserialization : public llvm::PrettyStackTraceEntry {
+    const ModuleFile *MF;
     const ModuleFile::Serialized<Decl*> &DeclOrOffset;
     DeclID ID;
     decls_block::RecordKind Kind;
   public:
-    PrettyDeclDeserialization(const ModuleFile::Serialized<Decl*> &declOrOffset,
+    PrettyDeclDeserialization(ModuleFile *module,
+                              const ModuleFile::Serialized<Decl*> &declOrOffset,
                               DeclID DID, decls_block::RecordKind kind)
-      : DeclOrOffset(declOrOffset), ID(DID), Kind(kind) {
+      : MF(module), DeclOrOffset(declOrOffset), ID(DID), Kind(kind) {
     }
 
     static const char *getRecordKindString(decls_block::RecordKind Kind) {
@@ -56,20 +62,20 @@
     virtual void print(raw_ostream &os) const override {
       if (!DeclOrOffset.isComplete()) {
         os << "While deserializing decl #" << ID << " ("
-           << getRecordKindString(Kind) << ")\n";
-        return;
-      }
-
-      os << "While deserializing ";
-
-      if (auto VD = dyn_cast<ValueDecl>(DeclOrOffset.get())) {
-        os << "'" << VD->getName() << "' (" << IDAndKind{VD, ID} << ") \n";
-      } else if (auto ED = dyn_cast<ExtensionDecl>(DeclOrOffset.get())) {
-        os << "extension of '" << ED->getExtendedType() << "' ("
-           << IDAndKind{ED, ID} << ") \n";
+           << getRecordKindString(Kind) << ")";
       } else {
-        os << IDAndKind{DeclOrOffset.get(), ID} << "\n";
+        os << "While deserializing ";
+
+        if (auto VD = dyn_cast<ValueDecl>(DeclOrOffset.get())) {
+          os << "'" << VD->getName() << "' (" << IDAndKind{VD, ID} << ")";
+        } else if (auto ED = dyn_cast<ExtensionDecl>(DeclOrOffset.get())) {
+          os << "extension of '" << ED->getExtendedType() << "' ("
+             << IDAndKind{ED, ID} << ")";
+        } else {
+          os << IDAndKind{DeclOrOffset.get(), ID};
+        }
       }
+      os << "in '" << getNameOfModule(MF) << "'\n";
     }
   };
 
@@ -224,6 +230,18 @@
       }
     }
   };
+
+  class PrettyStackTraceModuleFile : public llvm::PrettyStackTraceEntry {
+    const char *Action;
+    const ModuleFile *MF;
+  public:
+    explicit PrettyStackTraceModuleFile(const char *action, ModuleFile *module)
+        : Action(action), MF(module) {}
+
+    void print(raw_ostream &os) const override {
+      os << Action << " \'" << getNameOfModule(MF) << "'\n";
+    }
+  };
 } // end anonymous namespace
 
 
@@ -458,6 +476,10 @@
     ASTContext &ctx = getContext();
     Type conformingType = getType(conformingTypeID);
 
+    PrettyStackTraceType trace(getAssociatedModule()->getASTContext(),
+                               "reading specialized conformance for",
+                               conformingType);
+
     // Read the substitutions.
     SmallVector<Substitution, 4> substitutions;
     while (numSubstitutions--) {
@@ -467,6 +489,7 @@
     }
 
     ProtocolConformanceRef genericConformance = readConformance(Cursor);
+    PrettyStackTraceDecl traceTo("... to", genericConformance.getRequirement());
 
     assert(genericConformance.isConcrete() && "Abstract generic conformance?");
     auto conformance =
@@ -482,8 +505,13 @@
 
     ASTContext &ctx = getContext();
     Type conformingType = getType(conformingTypeID);
+    PrettyStackTraceType trace(getAssociatedModule()->getASTContext(),
+                               "reading inherited conformance for",
+                               conformingType);
 
     ProtocolConformanceRef inheritedConformance = readConformance(Cursor);
+    PrettyStackTraceDecl traceTo("... to",
+                                 inheritedConformance.getRequirement());
 
     assert(inheritedConformance.isConcrete() &&
            "Abstract inherited conformance?");
@@ -506,14 +534,22 @@
     ProtocolConformanceXrefLayout::readRecord(scratch, protoID, nominalID,
                                               moduleID);
 
-    auto proto = cast<ProtocolDecl>(getDecl(protoID));
     auto nominal = cast<NominalTypeDecl>(getDecl(nominalID));
+    PrettyStackTraceDecl trace("cross-referencing conformance for", nominal);
+    auto proto = cast<ProtocolDecl>(getDecl(protoID));
+    PrettyStackTraceDecl traceTo("... to", proto);
     auto module = getModule(moduleID);
 
     SmallVector<ProtocolConformance *, 2> conformances;
     nominal->lookupConformance(module, proto,
                                conformances);
-    assert(!conformances.empty() && "Could not find conformance");
+    PrettyStackTraceModuleFile traceMsg(
+        "If you're seeing a crash here, check that your SDK and dependencies "
+        "are at least as new as the versions used to build", this);
+    // This would normally be an assertion but it's more useful to print the
+    // PrettyStackTrace here even in no-asserts builds.
+    if (conformances.empty())
+      abort();
     return ProtocolConformanceRef(conformances.front());
   }
 
@@ -559,10 +595,14 @@
                                               typeCount, inheritedCount,
                                               rawIDs);
 
-  auto proto = cast<ProtocolDecl>(getDecl(protoID));
   ASTContext &ctx = getContext();
   DeclContext *dc = getDeclContext(contextID);
   Type conformingType = dc->getDeclaredTypeInContext();
+  PrettyStackTraceType trace(ctx, "reading conformance for", conformingType);
+
+  auto proto = cast<ProtocolDecl>(getDecl(protoID));
+  PrettyStackTraceDecl traceTo("... to", proto);
+
   auto conformance = ctx.getConformance(conformingType, proto, SourceLoc(), dc,
                                         ProtocolConformanceState::Incomplete);
 
@@ -1353,6 +1393,10 @@
       return nullptr;
     }
 
+    PrettyStackTraceModuleFile traceMsg(
+        "If you're seeing a crash here, check that your SDK and dependencies "
+        "match the versions used to build", this);
+
     if (values.empty()) {
       error();
       return nullptr;
@@ -2098,7 +2142,7 @@
   }
 
   PrettyDeclDeserialization stackTraceEntry(
-     declOrOffset, DID, static_cast<decls_block::RecordKind>(recordID));
+     this, declOrOffset, DID, static_cast<decls_block::RecordKind>(recordID));
 
   switch (recordID) {
   case decls_block::TYPE_ALIAS_DECL: {
@@ -4073,6 +4117,7 @@
     IDC->addMember(member);
 
   if (auto *proto = dyn_cast<ProtocolDecl>(D)) {
+    PrettyStackTraceDecl trace("reading default witness table for", D);
     bool Err = readDefaultWitnessTable(proto);
     assert(!Err && "unable to read default witness table");
     (void)Err;
diff --git a/stdlib/public/SDK/Foundation/Locale.swift b/stdlib/public/SDK/Foundation/Locale.swift
index d3d0e22..b40ea02 100644
--- a/stdlib/public/SDK/Foundation/Locale.swift
+++ b/stdlib/public/SDK/Foundation/Locale.swift
@@ -80,7 +80,7 @@
     
     /// Returns a localized string for a specified identifier.
     ///
-    /// For example, in the "en" locale, the result for `"en"` is `"Spanish"`.
+    /// For example, in the "en" locale, the result for `"es"` is `"Spanish"`.
     public func localizedString(forIdentifier identifier: String) -> String? {
         return _wrapped.displayName(forKey: .identifier, value: identifier)
     }
@@ -94,7 +94,7 @@
 
     /// Returns a localized string for a specified region code.
     ///
-    /// For example, in the "en" locale, the result for `"fr"` is `"French"`.
+    /// For example, in the "en" locale, the result for `"fr"` is `"France"`.
     public func localizedString(forRegionCode regionCode: String) -> String? {
         return _wrapped.displayName(forKey: .countryCode, value: regionCode)
     }
diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes
index 421c994..1996895 100644
--- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes
@@ -2,3 +2,9 @@
 Functions:
   - Name: jumpToLocation
     SwiftName: 'jumpTo(x:y:z:)'
+SwiftVersions:
+  - Version: 3.0
+    Functions:
+      - Name: acceptDoublePointer
+        SwiftName: 'acceptPointer(_:)'
+        Nullability: [ O ]
diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
index a9dc768..a965a60 100644
--- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
@@ -1 +1,3 @@
-void jumpToLocation(int, int, int);
+void jumpToLocation(double x, double y, double z);
+
+void acceptDoublePointer(double* _Nonnull ptr) __attribute__((swift_name("accept(_:)")));
diff --git a/test/APINotes/versioned.swift b/test/APINotes/versioned.swift
new file mode 100644
index 0000000..3a9179f
--- /dev/null
+++ b/test/APINotes/versioned.swift
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t && mkdir -p %t
+
+// RUN: %target-swift-ide-test  -F %S/Inputs/custom-frameworks -print-module -source-filename %s -module-to-print=APINotesFrameworkTest -function-definitions=false -print-regular-comments -swift-version 4.0 | %FileCheck -check-prefix=CHECK-SWIFT-4 %s 
+
+// RUN: %target-swift-ide-test  -F %S/Inputs/custom-frameworks -print-module -source-filename %s -module-to-print=APINotesFrameworkTest -function-definitions=false -print-regular-comments -swift-version 3.0 | %FileCheck -check-prefix=CHECK-SWIFT-3 %s 
+
+// CHECK-SWIFT-4: func jumpTo(x: Double, y: Double, z: Double)
+// CHECK-SWIFT-3: func jumpTo(x: Double, y: Double, z: Double)
+
+// CHECK-SWIFT-4: func accept(_ ptr: UnsafeMutablePointer<Double>)
+// CHECK-SWIFT-3: func acceptPointer(_ ptr: UnsafeMutablePointer<Double>?)
diff --git a/test/IDE/reconstruct_type_from_mangled_name_invalid.swift b/test/IDE/reconstruct_type_from_mangled_name_invalid.swift
index 3df56f7..96b75f6 100644
--- a/test/IDE/reconstruct_type_from_mangled_name_invalid.swift
+++ b/test/IDE/reconstruct_type_from_mangled_name_invalid.swift
@@ -24,7 +24,7 @@
   associatedtype T
 // CHECK: decl: FAILURE for 'T'
   func foo() -> T
-// CHECK: decl: FAILURE for 'foo'
+// CHECK: decl: func foo() -> Self.T	for 'foo' usr=s:FP14swift_ide_test1P3fooFT_wx1T
 }
 struct SP: P {
 // CHECK: decl: struct SP : P for 'SP'
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index dd45ee4..358b9a6 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -230,6 +230,9 @@
 Triple("target", llvm::cl::desc("target triple"));
 
 static llvm::cl::opt<std::string>
+SwiftVersion("swift-version", llvm::cl::desc("Swift version"));
+
+static llvm::cl::opt<std::string>
 ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"));
 
 static llvm::cl::opt<std::string>
@@ -2769,6 +2772,13 @@
   InitInvok.setSDKPath(options::SDK);
   if (!options::Triple.empty())
     InitInvok.setTargetTriple(options::Triple);
+  if (!options::SwiftVersion.empty()) {
+    if (auto swiftVersion =
+          version::Version::parseVersionString(options::SwiftVersion,
+                                               SourceLoc(), nullptr)) {
+      InitInvok.getLangOptions().EffectiveLanguageVersion = *swiftVersion;
+    }
+  }
   InitInvok.getClangImporterOptions().ModuleCachePath =
     options::ModuleCachePath;
   InitInvok.setImportSearchPaths(options::ImportPaths);
diff --git a/validation-test/Serialization/Inputs/conformance-removed/ObjCLib.h b/validation-test/Serialization/Inputs/conformance-removed/ObjCLib.h
new file mode 100644
index 0000000..58fa1a6
--- /dev/null
+++ b/validation-test/Serialization/Inputs/conformance-removed/ObjCLib.h
@@ -0,0 +1,11 @@
+@import Foundation;
+
+@protocol SomeProto
+@end
+
+@interface Base: NSObject
+#if USE_PROTO
+<SomeProto>
+#endif
+
+@end
diff --git a/validation-test/Serialization/Inputs/conformance-removed/SwiftLib.swift b/validation-test/Serialization/Inputs/conformance-removed/SwiftLib.swift
new file mode 100644
index 0000000..ff477ce
--- /dev/null
+++ b/validation-test/Serialization/Inputs/conformance-removed/SwiftLib.swift
@@ -0,0 +1,3 @@
+import ObjCLib
+
+open class Sub: Base {}
diff --git a/validation-test/Serialization/Inputs/conformance-removed/module.modulemap b/validation-test/Serialization/Inputs/conformance-removed/module.modulemap
new file mode 100644
index 0000000..0e9234f
--- /dev/null
+++ b/validation-test/Serialization/Inputs/conformance-removed/module.modulemap
@@ -0,0 +1,3 @@
+module ObjCLib {
+  header "ObjCLib.h"
+}
diff --git a/validation-test/Serialization/conformance-removed.swift b/validation-test/Serialization/conformance-removed.swift
new file mode 100644
index 0000000..890095e
--- /dev/null
+++ b/validation-test/Serialization/conformance-removed.swift
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-build-swift -emit-sil -emit-module-path %t/SwiftLib.swiftmodule -I %S/Inputs/conformance-removed/ %S/Inputs/conformance-removed/SwiftLib.swift -Xcc -DUSE_PROTO
+// RUN: not --crash %target-build-swift -parse -I %t -I %S/Inputs/custom-modules/ %s 2>&1 | %FileCheck %s
+
+// REQUIRES: objc_interop
+
+import SwiftLib
+class Rdar28282310: Sub {}
+// CHECK: If you're seeing a crash here, check that your SDK and dependencies are at least as new as the versions used to build 'SwiftLib'
diff --git a/validation-test/compiler_crashers/28432-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers/28432-swift-typechecker-validatedecl.swift
new file mode 100644
index 0000000..5d92dba
--- /dev/null
+++ b/validation-test/compiler_crashers/28432-swift-typechecker-validatedecl.swift
@@ -0,0 +1,15 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// RUN: not --crash %target-swift-frontend %s -parse
+// REQUIRES: asserts
+{protocol A
+{func e
+typealias e
+typealias F=(f:A
+typealias F
+typealias e=(
diff --git a/validation-test/compiler_crashers/28433-swift-typechecker-typecheckdecl.swift b/validation-test/compiler_crashers/28433-swift-typechecker-typecheckdecl.swift
new file mode 100644
index 0000000..3c0fa4d
--- /dev/null
+++ b/validation-test/compiler_crashers/28433-swift-typechecker-typecheckdecl.swift
@@ -0,0 +1,12 @@
+// This source file is part of the Swift.org open source project
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+
+// RUN: not --crash %target-swift-frontend %s -parse
+// REQUIRES: asserts
+for in[{protocol a{func e
+typealias e=()
+typealias e