Merge pull request #15864 from jrose-apple/get-set-stop

Diagnose unavailable getters and setters
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 310aea1..3ca27c6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -311,6 +311,10 @@
   "Enable runtime function counters and expose the API."
   FALSE)
 
+option(SWIFT_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING
+  "Build stdlibCore with exclusivity checking enabled"
+  FALSE)
+
 #
 # End of user-configurable options.
 #
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index 7d70616..9e5215b 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -1265,6 +1265,8 @@
       "expected an attribute name", ())
 ERROR(unknown_attribute,none,
       "unknown attribute '%0'", (StringRef))
+ERROR(unexpected_lparen_in_attribute,none,
+      "unexpected '(' in attribute '%0'", (StringRef))
 ERROR(duplicate_attribute,none,
       "duplicate %select{attribute|modifier}0", (bool))
 NOTE(previous_attribute,none,
diff --git a/include/swift/Basic/Statistic.h b/include/swift/Basic/Statistic.h
index 7f9e48b..228a139 100644
--- a/include/swift/Basic/Statistic.h
+++ b/include/swift/Basic/Statistic.h
@@ -205,16 +205,16 @@
   /// entity type, and produce a tracer that's either active or inert depending
   /// on whether the provided \p Reporter is null (nullptr means "tracing is
   /// disabled").
-  FrontendStatsTracer(UnifiedStatsReporter *Reporter,  StringRef EventName);
-  FrontendStatsTracer(UnifiedStatsReporter *Reporter,  StringRef EventName,
+  FrontendStatsTracer(UnifiedStatsReporter *Reporter, StringRef EventName);
+  FrontendStatsTracer(UnifiedStatsReporter *Reporter, StringRef EventName,
                       const Decl *D);
-  FrontendStatsTracer(UnifiedStatsReporter *Reporter,  StringRef EventName,
+  FrontendStatsTracer(UnifiedStatsReporter *Reporter, StringRef EventName,
                       const ProtocolConformance *P);
-  FrontendStatsTracer(UnifiedStatsReporter *Reporter,  StringRef EventName,
+  FrontendStatsTracer(UnifiedStatsReporter *Reporter, StringRef EventName,
                       const clang::Decl *D);
-  FrontendStatsTracer(UnifiedStatsReporter *Reporter,  StringRef EventName,
+  FrontendStatsTracer(UnifiedStatsReporter *Reporter, StringRef EventName,
                       const Expr *E);
-  FrontendStatsTracer(UnifiedStatsReporter *Reporter,  StringRef EventName,
+  FrontendStatsTracer(UnifiedStatsReporter *Reporter, StringRef EventName,
                       const SILFunction *F);
 };
 
@@ -225,20 +225,61 @@
 // for those entity types. If you want to trace those types, it's assumed you're
 // linking with the object files that define the tracer.
 
-template<> const UnifiedStatsReporter::TraceFormatter*
+template <>
+const UnifiedStatsReporter::TraceFormatter *
 FrontendStatsTracer::getTraceFormatter<const Decl *>();
 
-template<> const UnifiedStatsReporter::TraceFormatter*
+template <>
+const UnifiedStatsReporter::TraceFormatter *
 FrontendStatsTracer::getTraceFormatter<const ProtocolConformance *>();
 
-template<> const UnifiedStatsReporter::TraceFormatter*
+template <>
+const UnifiedStatsReporter::TraceFormatter *
 FrontendStatsTracer::getTraceFormatter<const clang::Decl *>();
 
-template<> const UnifiedStatsReporter::TraceFormatter*
+template <>
+const UnifiedStatsReporter::TraceFormatter *
 FrontendStatsTracer::getTraceFormatter<const Expr *>();
 
-template<> const UnifiedStatsReporter::TraceFormatter*
+template <>
+const UnifiedStatsReporter::TraceFormatter *
 FrontendStatsTracer::getTraceFormatter<const SILFunction *>();
 
-}
+// Provide inline definitions for the delegating constructors.  These avoid
+// introducing a circular dependency between libParse and libSIL.  They are
+// marked as `inline` explicitly to prevent ODR violations due to multiple
+// emissions.  We cannot force the inlining by defining them in the declaration
+// due to the explicit template specializations of the `getTraceFormatter`,
+// which is declared in the `FrontendStatsTracer` scope (the nested name
+// specifier scope cannot be used to declare them).
+
+inline FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R,
+                                                StringRef S)
+    : FrontendStatsTracer(R, S, nullptr, nullptr) {}
+
+inline FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R,
+                                                StringRef S, const Decl *D)
+    : FrontendStatsTracer(R, S, D, getTraceFormatter<const Decl *>()) {}
+
+inline FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R,
+                                                StringRef S,
+                                                const ProtocolConformance *P)
+    : FrontendStatsTracer(R, S, P,
+                          getTraceFormatter<const ProtocolConformance *>()) {}
+
+inline FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R,
+                                                StringRef S,
+                                                const clang::Decl *D)
+    : FrontendStatsTracer(R, S, D, getTraceFormatter<const clang::Decl *>()) {}
+
+inline FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R,
+                                                StringRef S, const Expr *E)
+    : FrontendStatsTracer(R, S, E, getTraceFormatter<const Expr *>()) {}
+
+inline FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R,
+                                                StringRef S,
+                                                const SILFunction *F)
+    : FrontendStatsTracer(R, S, F, getTraceFormatter<const SILFunction *>()) {}
+
+} // namespace swift
 #endif // SWIFT_BASIC_STATISTIC_H
diff --git a/include/swift/IRGen/IRGenPublic.h b/include/swift/IRGen/IRGenPublic.h
index d344769..c379919 100644
--- a/include/swift/IRGen/IRGenPublic.h
+++ b/include/swift/IRGen/IRGenPublic.h
@@ -14,9 +14,12 @@
 
 namespace llvm {
   class LLVMContext;
+  template<typename T, unsigned N> class SmallVector;
 }
 
 namespace swift {
+class ASTContext;
+class LinkLibrary;
 class SILModule;
 
 namespace irgen {
@@ -33,6 +36,20 @@
 /// Delete the IRGenModule and IRGenerator obtained by the above call.
 void deleteIRGenModule(std::pair<IRGenerator *, IRGenModule *> &Module);
 
+/// Collect the set of libraries to autolink against by mining the
+/// external definitions stored in an AST context.
+///
+/// This entire thing is a hack that we shouldn't need, but it reflects the
+/// fact that we can end up referencing something via an external definition
+/// (e.g., an imported Clang declaration) indirectly via the Clang importer
+/// that would not be visible directly. In such cases, we would fail to
+/// link against the shared library that defines the entity or an overlay that
+/// is needed as part of its import from Clang (e.g., the Foundation overlay
+/// is needed when bridging NSString, even if there is no other mention of
+/// an entity from the Foundation overlay).
+llvm::SmallVector<LinkLibrary, 4> collectLinkLibrariesFromExternals(
+                                                           ASTContext &ctx);
+
 } // end namespace irgen
 } // end namespace swift
 
diff --git a/include/swift/SILOptimizer/Analysis/EscapeAnalysis.h b/include/swift/SILOptimizer/Analysis/EscapeAnalysis.h
index 2c9ed07..db62cb1 100644
--- a/include/swift/SILOptimizer/Analysis/EscapeAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/EscapeAnalysis.h
@@ -769,12 +769,6 @@
   /// address of a contained property escapes, but not the object itself.
   bool canEscapeTo(SILValue V, FullApplySite FAS);
 
-  /// Returns true if the value \p V or its content can escape to the
-  /// function call \p FAS.
-  /// This is the same as above, except that it returns true if an address of
-  /// a contained property escapes.
-  bool canObjectOrContentEscapeTo(SILValue V, FullApplySite FAS);
-
   /// Returns true if the value \p V can escape to the release-instruction \p
   /// RI. This means that \p RI may release \p V or any called destructor may
   /// access (or release) \p V.
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index b71cb0a..1642439 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -2878,12 +2878,13 @@
         }
         PrintWithColorRAII(out, ParenthesisColor) << ')';
       });
+
+      for (auto conformance : normal->getSignatureConformances()) {
+        out << '\n';
+        conformance.dump(out, indent + 2);
+      }
     }
 
-    for (auto conformance : normal->getSignatureConformances()) {
-      out << '\n';
-      conformance.dump(out, indent + 2);
-    }
     for (auto requirement : normal->getConditionalRequirements()) {
       out << '\n';
       out.indent(indent + 2);
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 526d3d3..0c6a1e8 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -1309,7 +1309,7 @@
 
   case Concrete:
     return parent->withoutRedundantSubpath(builder, start, end)
-      ->viaParent(builder, getAssociatedType());
+      ->viaConcrete(builder, getProtocolConformance());
 
   case Derived:
     return parent->withoutRedundantSubpath(builder, start, end)
diff --git a/lib/AST/Module.cpp b/lib/AST/Module.cpp
index 866018d..6ed4015 100644
--- a/lib/AST/Module.cpp
+++ b/lib/AST/Module.cpp
@@ -1208,8 +1208,14 @@
 
 void
 SourceFile::collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const {
-  for (auto importPair : Imports)
-    importPair.first.second->collectLinkLibraries(callback);
+
+  const_cast<SourceFile *>(this)->forAllVisibleModules([&](swift::ModuleDecl::ImportedModule import) {
+    swift::ModuleDecl *next = import.second;
+    if (next->getName() == getParentModule()->getName())
+      return;
+
+    next->collectLinkLibraries(callback);
+  });
 }
 
 bool ModuleDecl::walk(ASTWalker &Walker) {
diff --git a/lib/Basic/Statistic.cpp b/lib/Basic/Statistic.cpp
index accc584..35fceb3 100644
--- a/lib/Basic/Statistic.cpp
+++ b/lib/Basic/Statistic.cpp
@@ -453,35 +453,6 @@
 
 FrontendStatsTracer::FrontendStatsTracer() = default;
 
-FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R, StringRef S)
-    : FrontendStatsTracer(R, S, nullptr, nullptr)
-{}
-
-FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R, StringRef S,
-                                         const Decl *D)
-    : FrontendStatsTracer(R, S, D, getTraceFormatter<const Decl *>())
-{}
-
-FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R, StringRef S,
-                                         const ProtocolConformance *P)
-    : FrontendStatsTracer(R, S, P,
-                          getTraceFormatter<const ProtocolConformance *>()) {}
-
-FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R, StringRef S,
-                                         const Expr *E)
-    : FrontendStatsTracer(R, S, E, getTraceFormatter<const Expr *>())
-{}
-
-FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R, StringRef S,
-                                         const clang::Decl *D)
-    : FrontendStatsTracer(R, S, D, getTraceFormatter<const clang::Decl *>())
-{}
-
-FrontendStatsTracer::FrontendStatsTracer(UnifiedStatsReporter *R, StringRef S,
-                                         const SILFunction *F)
-    : FrontendStatsTracer(R, S, F, getTraceFormatter<const SILFunction *>())
-{}
-
 FrontendStatsTracer&
 FrontendStatsTracer::operator=(FrontendStatsTracer&& other)
 {
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 3ff4742..bbc4482 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -483,14 +483,8 @@
   for (auto *localDecl : SF.LocalTypeDecls)
     emitGlobalDecl(localDecl);
 
-  SF.forAllVisibleModules([&](swift::ModuleDecl::ImportedModule import) {
-    swift::ModuleDecl *next = import.second;
-    if (next->getName() == SF.getParentModule()->getName())
-      return;
-
-    next->collectLinkLibraries([this](LinkLibrary linkLib) {
+  SF.collectLinkLibraries([this](LinkLibrary linkLib) {
       this->addLinkLibrary(linkLib);
-    });
   });
 
   if (ObjCInterop)
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 70f7308..e66b9b9 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -3348,7 +3348,7 @@
   if (auto classType = dyn_cast<ClassType>(type)) {
     assert(!classType.getParent());
     auto classDecl = classType->getDecl();
-    assert(classDecl->isForeign());
+    assert(classDecl->getForeignClassKind() == ClassDecl::ForeignKind::CFType);
 
     ForeignClassMetadataBuilder builder(*this, classDecl, init);
     builder.layout();
@@ -3389,7 +3389,8 @@
   if (auto enclosing = type->getNominalParent()) {
     auto canonicalEnclosing = enclosing->getCanonicalType();
     if (requiresForeignTypeMetadata(canonicalEnclosing)) {
-      getAddrOfForeignTypeMetadataCandidate(canonicalEnclosing);
+      (void)getTypeMetadataAccessFunction(*this, canonicalEnclosing,
+                                          ForDefinition);
     }
   }
 
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index a7992c9..62ad4e8 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -2187,8 +2187,19 @@
 
   // Trigger the lazy emission of the foreign type metadata.
   CanType conformingType = conf->getType()->getCanonicalType();
-  if (requiresForeignTypeMetadata(conformingType))
-    (void)getAddrOfForeignTypeMetadataCandidate(conformingType);
+  if (requiresForeignTypeMetadata(conformingType)) {
+    // Make sure we emit the metadata access function.
+    (void)getTypeMetadataAccessFunction(*this, conformingType,
+                                        ForDefinition);
+
+    // Make sure we emit the nominal type descriptor.
+    auto *nominal = conformingType->getAnyNominal();
+    auto entity = LinkEntity::forNominalTypeDescriptor(nominal);
+    if (auto entry = GlobalVars[entity])
+      return;
+
+    emitLazyTypeContextDescriptor(*this, nominal, RequireMetadata);
+  }
 }
 
 /// True if a function's signature in LLVM carries polymorphic parameters.
diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp
index 3a7ad3c..92fea19 100644
--- a/lib/IRGen/IRGen.cpp
+++ b/lib/IRGen/IRGen.cpp
@@ -19,6 +19,7 @@
 #include "swift/AST/DiagnosticsIRGen.h"
 #include "swift/AST/IRGenOptions.h"
 #include "swift/AST/LinkLibrary.h"
+#include "swift/AST/ProtocolConformance.h"
 #include "swift/Basic/Defer.h"
 #include "swift/Basic/Dwarf.h"
 #include "swift/Basic/Platform.h"
@@ -26,6 +27,7 @@
 #include "swift/Basic/Timer.h"
 #include "swift/Basic/Version.h"
 #include "swift/ClangImporter/ClangImporter.h"
+#include "swift/ClangImporter/ClangModule.h"
 #include "swift/IRGen/IRGenPublic.h"
 #include "swift/IRGen/IRGenSILPasses.h"
 #include "swift/LLVMPasses/Passes.h"
@@ -792,20 +794,8 @@
     });
 
     // Hack to handle thunks eagerly synthesized by the Clang importer.
-    swift::ModuleDecl *prev = nullptr;
-    for (auto external : Ctx.ExternalDefinitions) {
-      swift::ModuleDecl *next = external->getModuleContext();
-      if (next == prev)
-        continue;
-      prev = next;
-
-      if (next->getName() == M->getName())
-        continue;
-
-      next->collectLinkLibraries([&](LinkLibrary linkLib) {
-        IGM.addLinkLibrary(linkLib);
-      });
-    }
+    for (const auto &linkLib : collectLinkLibrariesFromExternals(Ctx))
+      IGM.addLinkLibrary(linkLib);
 
     if (!IGM.finalize())
       return nullptr;
@@ -977,21 +967,9 @@
                 });
   
   // Hack to handle thunks eagerly synthesized by the Clang importer.
-  swift::ModuleDecl *prev = nullptr;
-  for (auto external : Ctx.ExternalDefinitions) {
-    swift::ModuleDecl *next = external->getModuleContext();
-    if (next == prev)
-      continue;
-    prev = next;
-    
-    if (next->getName() == M->getName())
-      continue;
-    
-    next->collectLinkLibraries([&](LinkLibrary linkLib) {
-      PrimaryGM->addLinkLibrary(linkLib);
-    });
-  }
-  
+  for (const auto &linkLib : collectLinkLibrariesFromExternals(Ctx))
+    PrimaryGM->addLinkLibrary(linkLib);
+
   llvm::StringSet<> referencedGlobals;
 
   for (auto it = irgen.begin(); it != irgen.end(); ++it) {
@@ -1172,3 +1150,20 @@
     return true;
   return false;
 }
+
+SmallVector<LinkLibrary, 4> irgen::collectLinkLibrariesFromExternals(
+                                                           ASTContext &ctx) {
+  SmallVector<LinkLibrary, 4> result;
+  auto addLinkLibrary = [&](LinkLibrary linkLib) {
+    result.push_back(linkLib);
+  };
+
+  llvm::SmallPtrSet<ModuleDecl *, 8> known;
+  for (auto external : ctx.ExternalDefinitions) {
+    swift::ModuleDecl *module = external->getModuleContext();
+    if (known.insert(module).second)
+      module->collectLinkLibraries(addLinkLibrary);
+  }
+
+  return result;
+}
diff --git a/lib/IRGen/MetadataLayout.cpp b/lib/IRGen/MetadataLayout.cpp
index 5d77e7d..bb8eeb8 100644
--- a/lib/IRGen/MetadataLayout.cpp
+++ b/lib/IRGen/MetadataLayout.cpp
@@ -111,7 +111,7 @@
   auto &entry = MetadataLayouts[decl];
   if (!entry) {
     if (auto theClass = dyn_cast<ClassDecl>(decl)) {
-      if (theClass->isForeign())
+      if (theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType)
         entry = new ForeignClassMetadataLayout(*this, theClass);
       else
         entry = new ClassMetadataLayout(*this, theClass);
@@ -456,7 +456,7 @@
 
 Size irgen::getClassFieldOffsetOffset(IRGenModule &IGM, ClassDecl *theClass,
                                       VarDecl *field) {
-  if (theClass->isForeign())
+  if (theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType)
     return Size();
 
   return IGM.getClassMetadataLayout(theClass).getStaticFieldOffset(field);
@@ -602,7 +602,8 @@
 ForeignClassMetadataLayout::ForeignClassMetadataLayout(IRGenModule &IGM,
                                                        ClassDecl *theClass)
     : MetadataLayout(Kind::ForeignClass), Class(theClass) {
-  assert(theClass->isForeign() && "Not a foreign class");
+  assert(theClass->getForeignClassKind() == ClassDecl::ForeignKind::CFType &&
+         "Not a foreign class");
 
   struct Scanner : LayoutScanner<Scanner, ForeignClassMetadataScanner> {
     using super = LayoutScanner;
diff --git a/lib/Immediate/Immediate.cpp b/lib/Immediate/Immediate.cpp
index 6dfe2f5..1396858 100644
--- a/lib/Immediate/Immediate.cpp
+++ b/lib/Immediate/Immediate.cpp
@@ -27,6 +27,7 @@
 #include "swift/Basic/LLVM.h"
 #include "swift/Basic/LLVMContext.h"
 #include "swift/Frontend/Frontend.h"
+#include "swift/IRGen/IRGenPublic.h"
 #include "swift/SILOptimizer/PassManager/Passes.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Config/config.h"
@@ -224,13 +225,9 @@
   });
 
   // Hack to handle thunks eagerly synthesized by the Clang importer.
-  swift::ModuleDecl *prev = nullptr;
-  for (auto external : CI.getASTContext().ExternalDefinitions) {
-    swift::ModuleDecl *next = external->getModuleContext();
-    if (next == prev)
-      continue;
-    next->collectLinkLibraries(addLinkLibrary);
-    prev = next;
+  for (const auto &linkLib :
+          irgen::collectLinkLibrariesFromExternals(CI.getASTContext())) {
+    addLinkLibrary(linkLib);
   }
 
   tryLoadLibraries(AllLinkLibraries, CI.getASTContext().SearchPathOpts,
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index d6c2e34..d9f35b5 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2522,6 +2522,7 @@
     DeclResult = parseDeclOperator(Flags, Attributes);
     break;
   case tok::kw_precedencegroup:
+    DeclParsingContext.setCreateSyntax(SyntaxKind::PrecedenceGroupDecl);
     DeclResult = parseDeclPrecedenceGroup(Flags, Attributes);
     break;
   case tok::kw_protocol:
@@ -6414,6 +6415,14 @@
     diagnose(Tok, diag::expected_precedencegroup_lbrace);
     return createInvalid();
   }
+  // Empty body.
+  if (Tok.is(tok::r_brace)) {
+    // Create empty attribute list.
+    SyntaxParsingContext(SyntaxContext,
+                         SyntaxKind::PrecedenceGroupAttributeList);
+    rbraceLoc = consumeToken(tok::r_brace);
+    return makeParserResult(create());
+  }
 
   auto abortBody = [&] {
     skipUntilDeclRBrace();
@@ -6435,8 +6444,9 @@
     }
   };
 
+
   // Parse the attributes in the body.
-  while (!consumeIf(tok::r_brace, rbraceLoc)) {
+  while (!Tok.is(tok::r_brace)) {
     if (!Tok.is(tok::identifier)) {
       diagnose(Tok, diag::expected_precedencegroup_attribute);
       return abortBody();
@@ -6445,6 +6455,8 @@
     auto attrName = Tok.getText();
 
     if (attrName == "associativity") {
+      SyntaxParsingContext AttrCtxt(SyntaxContext,
+                                    SyntaxKind::PrecedenceGroupAssociativity);
       // "associativity" is considered as a contextual keyword.
       TokReceiver->registerTokenKindChange(Tok.getLoc(),
                                            tok::contextual_keyword);
@@ -6471,6 +6483,8 @@
     }
     
     if (attrName == "assignment") {
+      SyntaxParsingContext AttrCtxt(SyntaxContext,
+                                    SyntaxKind::PrecedenceGroupAssignment);
       parseAttributePrefix(assignmentKeywordLoc);
 
       // "assignment" is considered as a contextual keyword.
@@ -6490,6 +6504,8 @@
     bool isLowerThan = false;
     if (attrName == "higherThan" ||
         (isLowerThan = (attrName == "lowerThan"))) {
+      SyntaxParsingContext AttrCtxt(SyntaxContext,
+                                    SyntaxKind::PrecedenceGroupRelation);
       // "lowerThan" and "higherThan" are contextual keywords.
       TokReceiver->registerTokenKindChange(Tok.getLoc(),
                                            tok::contextual_keyword);
@@ -6498,6 +6514,8 @@
       auto &relations = (isLowerThan ? lowerThan : higherThan);
 
       do {
+        SyntaxParsingContext NameCtxt(SyntaxContext,
+                                      SyntaxKind::PrecedenceGroupNameElement);
         if (!Tok.is(tok::identifier)) {
           diagnose(Tok, diag::expected_precedencegroup_relation, attrName);
           return abortBody();
@@ -6505,13 +6523,19 @@
         auto name = Context.getIdentifier(Tok.getText());
         auto loc = consumeToken();
         relations.push_back({loc, name, nullptr});
-      } while (consumeIf(tok::comma));
+        if (!consumeIf(tok::comma))
+          break;
+      } while (true);
+      SyntaxContext->collectNodesInPlace(SyntaxKind::PrecedenceGroupNameList);
       continue;
     }
     
     diagnose(Tok, diag::unknown_precedencegroup_attribute, attrName);
     return abortBody();
   }
+  SyntaxContext->collectNodesInPlace(SyntaxKind::PrecedenceGroupAttributeList);
+  rbraceLoc = consumeToken(tok::r_brace);
+
 
   auto result = create();
   if (invalid) result->setInvalid();
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index b71429c..8b1bbe2 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -2187,24 +2187,30 @@
   SourceLoc UnknownAttrLoc;
   while (Tok.is(tok::at_sign)) {
     SyntaxParsingContext AttrCtx(SyntaxContext, SyntaxKind::Attribute);
-    UnknownAttrLoc = consumeToken(tok::at_sign);
 
-    if (Tok.isContextualKeyword("unknown")) {
+    if (peekToken().isContextualKeyword("unknown")) {
+      if (!UnknownAttrLoc.isValid()) {
+        UnknownAttrLoc = consumeToken(tok::at_sign);
+      } else {
+        diagnose(Tok, diag::duplicate_attribute, false);
+        diagnose(UnknownAttrLoc, diag::previous_attribute, false);
+        consumeToken(tok::at_sign);
+      }
       consumeIdentifier();
 
-      // Form an empty TokenList for the arguments of the 'Attribute' Syntax
-      // node.
-      SyntaxParsingContext(SyntaxContext, SyntaxKind::TokenList);
+      SyntaxParsingContext Args(SyntaxContext, SyntaxKind::TokenList);
+      if (Tok.is(tok::l_paren)) {
+        diagnose(Tok, diag::unexpected_lparen_in_attribute, "unknown");
+        skipSingle();
+      }
     } else {
-      UnknownAttrLoc = SourceLoc();
-
+      consumeToken(tok::at_sign);
       diagnose(Tok, diag::unknown_attribute, Tok.getText());
       consumeIdentifier();
 
-      if (Tok.is(tok::l_paren)) {
-        SyntaxParsingContext Args(SyntaxContext, SyntaxKind::TokenList);
+      SyntaxParsingContext Args(SyntaxContext, SyntaxKind::TokenList);
+      if (Tok.is(tok::l_paren))
         skipSingle();
-      }
     }
   }
 
@@ -2213,8 +2219,10 @@
   if (Tok.is(tok::kw_case)) {
     Status |=
         ::parseStmtCase(*this, CaseLoc, CaseLabelItems, BoundDecls, ColonLoc);
-  } else {
+  } else if (Tok.is(tok::kw_default)) {
     Status |= parseStmtCaseDefault(*this, CaseLoc, CaseLabelItems, ColonLoc);
+  } else {
+    llvm_unreachable("isAtStartOfSwitchCase() lied.");
   }
 
   assert(!CaseLabelItems.empty() && "did not parse any labels?!");
diff --git a/lib/SIL/Linker.cpp b/lib/SIL/Linker.cpp
index e2d36f8..56b9108 100644
--- a/lib/SIL/Linker.cpp
+++ b/lib/SIL/Linker.cpp
@@ -58,41 +58,11 @@
   return true;
 }
 
-/// Deserialize the VTable mapped to C if it exists and all SIL the VTable
-/// transitively references.
-///
-/// This method assumes that the caller made sure that no vtable existed in
-/// Mod.
-SILVTable *SILLinkerVisitor::processClassDecl(const ClassDecl *C) {
-  // If we are not linking anything, bail.
-  if (Mode == LinkingMode::LinkNone)
-    return nullptr;
-
-  // Attempt to load the VTable from the SerializedSILLoader. If we
-  // fail... bail...
-  SILVTable *Vtbl = Loader->lookupVTable(C);
-  if (!Vtbl)
-    return nullptr;
-
-  // Otherwise, add all the vtable functions in Vtbl to the function
-  // processing list...
-  for (auto &E : Vtbl->getEntries())
-    Worklist.push_back(E.Implementation);
-
-  // And then transitively deserialize all SIL referenced by those functions.
-  process();
-
-  // Return the deserialized Vtbl.
-  return Vtbl;
-}
-
+/// Deserialize the given VTable all SIL the VTable transitively references.
 bool SILLinkerVisitor::linkInVTable(ClassDecl *D) {
   // Attempt to lookup the Vtbl from the SILModule.
   SILVTable *Vtbl = Mod.lookUpVTable(D);
-
-  // If the SILModule does not have the VTable, attempt to deserialize the
-  // VTable. If we fail to do that as well, bail.
-  if (!Vtbl || !(Vtbl = Loader->lookupVTable(D->getName())))
+  if (!Vtbl)
     return false;
 
   // Ok we found our VTable. Visit each function referenced by the VTable. If
@@ -120,16 +90,17 @@
     performFuncDeserialization |= visitApplySubstitutions(
       sig->getSubstitutionMap(AI->getSubstitutions()));
   }
-  
-  // Ok we have a function ref inst, grab the callee.
-  SILFunction *Callee = AI->getReferencedFunction();
-  if (!Callee)
-    return performFuncDeserialization;
 
-  if (isLinkAll() ||
-      hasSharedVisibility(Callee->getLinkage())) {
-    addFunctionToWorklist(Callee);
-    return true;
+  return performFuncDeserialization;
+}
+
+bool SILLinkerVisitor::visitTryApplyInst(TryApplyInst *TAI) {
+  bool performFuncDeserialization = false;
+
+  if (auto sig = TAI->getCallee()->getType().castTo<SILFunctionType>()
+                   ->getGenericSignature()) {
+    performFuncDeserialization |= visitApplySubstitutions(
+      sig->getSubstitutionMap(TAI->getSubstitutions()));
   }
 
   return performFuncDeserialization;
@@ -144,16 +115,6 @@
       sig->getSubstitutionMap(PAI->getSubstitutions()));
   }
 
-  SILFunction *Callee = PAI->getReferencedFunction();
-  if (!Callee)
-    return performFuncDeserialization;
-
-  if (isLinkAll() ||
-      hasSharedVisibility(Callee->getLinkage())) {
-    addFunctionToWorklist(Callee);
-    return true;
-  }
-
   return performFuncDeserialization;
 }
 
@@ -353,6 +314,9 @@
 }
 
 bool SILLinkerVisitor::visitAllocRefInst(AllocRefInst *ARI) {
+  if (!isLinkAll())
+    return false;
+
   // Grab the class decl from the alloc ref inst.
   ClassDecl *D = ARI->getType().getClassOrBoundGenericClass();
   if (!D)
@@ -362,6 +326,9 @@
 }
 
 bool SILLinkerVisitor::visitMetatypeInst(MetatypeInst *MI) {
+  if (!isLinkAll())
+    return false;
+
   CanType instTy = MI->getType().castTo<MetatypeType>().getInstanceType();
   ClassDecl *C = instTy.getClassOrBoundGenericClass();
   if (!C)
diff --git a/lib/SIL/Linker.h b/lib/SIL/Linker.h
index 8cb5a3a..07c4fd5 100644
--- a/lib/SIL/Linker.h
+++ b/lib/SIL/Linker.h
@@ -64,6 +64,7 @@
   bool visitSILInstruction(SILInstruction *I) { return false; }
 
   bool visitApplyInst(ApplyInst *AI);
+  bool visitTryApplyInst(TryApplyInst *TAI);
   bool visitPartialApplyInst(PartialApplyInst *PAI);
   bool visitFunctionRefInst(FunctionRefInst *FRI);
   bool visitProtocolConformance(ProtocolConformanceRef C,
diff --git a/lib/SIL/SILModule.cpp b/lib/SIL/SILModule.cpp
index 7eb36f1..32d34fe 100644
--- a/lib/SIL/SILModule.cpp
+++ b/lib/SIL/SILModule.cpp
@@ -614,9 +614,7 @@
     return R->second;
 
   // If that fails, try to deserialize it. If that fails, return nullptr.
-  SILVTable *Vtbl =
-      SILLinkerVisitor(*this, getSILLoader(), SILModule::LinkingMode::LinkAll)
-          .processClassDecl(C);
+  SILVTable *Vtbl = getSILLoader()->lookupVTable(C);
   if (!Vtbl)
     return nullptr;
 
diff --git a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
index 15bf1ec..dd931ce 100644
--- a/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/EscapeAnalysis.cpp
@@ -1824,39 +1824,7 @@
     return true;
 
   // No hidden escapes: check if the Node is reachable from the UsePoint.
-  return ConGraph->isUsePoint(UsePoint, Node);
-}
-
-bool EscapeAnalysis::canEscapeTo(SILValue V, FullApplySite FAS) {
-  // If it's not a local object we don't know anything about the value.
-  if (!pointsToLocalObject(V))
-    return true;
-  auto *ConGraph = getConnectionGraph(FAS.getFunction());
-  return canEscapeToUsePoint(V, FAS.getInstruction(), ConGraph);
-}
-
-static bool hasReferenceSemantics(SILType T) {
-  // Exclude address types.
-  return T.isObject() && T.hasReferenceSemantics();
-}
-
-bool EscapeAnalysis::canObjectOrContentEscapeTo(SILValue V, FullApplySite FAS) {
-  // If it's not a local object we don't know anything about the value.
-  if (!pointsToLocalObject(V))
-    return true;
-
-  auto *ConGraph = getConnectionGraph(FAS.getFunction());
-  CGNode *Node = ConGraph->getNodeOrNull(V, this);
-  if (!Node)
-    return true;
-
-  // First check if there are escape paths which we don't explicitly see
-  // in the graph.
-  if (Node->escapesInsideFunction(isNotAliasingArgument(V)))
-    return true;
-
   // Check if the object itself can escape to the called function.
-  SILInstruction *UsePoint = FAS.getInstruction();
   if (ConGraph->isUsePoint(UsePoint, Node))
     return true;
 
@@ -1880,6 +1848,19 @@
   return false;
 }
 
+bool EscapeAnalysis::canEscapeTo(SILValue V, FullApplySite FAS) {
+  // If it's not a local object we don't know anything about the value.
+  if (!pointsToLocalObject(V))
+    return true;
+  auto *ConGraph = getConnectionGraph(FAS.getFunction());
+  return canEscapeToUsePoint(V, FAS.getInstruction(), ConGraph);
+}
+
+static bool hasReferenceSemantics(SILType T) {
+  // Exclude address types.
+  return T.isObject() && T.hasReferenceSemantics();
+}
+
 bool EscapeAnalysis::canEscapeTo(SILValue V, RefCountingInst *RI) {
   // If it's not a local object we don't know anything about the value.
   if (!pointsToLocalObject(V))
diff --git a/lib/SILOptimizer/Analysis/MemoryBehavior.cpp b/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
index 527fb9a..17ebb80 100644
--- a/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
+++ b/lib/SILOptimizer/Analysis/MemoryBehavior.cpp
@@ -227,7 +227,7 @@
 MemBehavior MemoryBehaviorVisitor::visitTryApplyInst(TryApplyInst *AI) {
   MemBehavior Behavior = MemBehavior::MayHaveSideEffects;
   // Ask escape analysis.
-  if (!EA->canObjectOrContentEscapeTo(V, AI))
+  if (!EA->canEscapeTo(V, AI))
     Behavior = MemBehavior::None;
 
   // Otherwise be conservative and return that we may have side effects.
@@ -290,7 +290,7 @@
       Behavior = MemBehavior::MayRead;
 
     // Ask escape analysis.
-    if (!EA->canObjectOrContentEscapeTo(V, AI))
+    if (!EA->canEscapeTo(V, AI))
       Behavior = MemBehavior::None;
   }
   DEBUG(llvm::dbgs() << "  Found apply, returning " << Behavior << '\n');
diff --git a/lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp b/lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp
index 978d163..2966519 100644
--- a/lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/RCIdentityAnalysis.cpp
@@ -524,28 +524,26 @@
       if (!VisitedInsts.insert(User).second)
         continue;
 
-      for (auto value : User->getResults()) {
+      if (auto *SVI = dyn_cast<SingleValueInstruction>(User)) {
         // Otherwise attempt to strip off one layer of RC identical instructions
         // from User.
-        SILValue StrippedRCID = stripRCIdentityPreservingInsts(value);
+        SILValue StrippedRCID = stripRCIdentityPreservingInsts(SVI);
 
-        // If StrippedRCID is not V, then we know that User's result is
-        // conservatively not RCIdentical to V.
-        if (StrippedRCID != V) {
-          // If the user is extracting a trivial field of an aggregate structure
-          // that does not overlap with the ref counted part of the aggregate, we
-          // can ignore it.
-          if (isNonOverlappingTrivialAccess(value))
-            continue;
-
-          // Otherwise, it is an RC user that our user wants.
-          Users.push_back(User);
+        // If the User's result has the same RC identity as its operand, V, then
+        // it must still be RC identical to InputValue, so transitively search
+        // for more users.
+        if (StrippedRCID == V) {
+          Worklist.push_back(SVI);
           continue;
         }
-
-        // Otherwise, add the result to our list to continue searching.
-        Worklist.push_back(value);
+        // If the user is extracting a trivial field of an aggregate structure
+        // that does not overlap with the ref counted part of the aggregate, we
+        // can ignore it.
+        if (isNonOverlappingTrivialAccess(SVI))
+          continue;
       }
+      // Otherwise, stop searching and report this RC user.
+      Users.push_back(User);
     }
   }
 }
diff --git a/lib/SILOptimizer/Transforms/CopyForwarding.cpp b/lib/SILOptimizer/Transforms/CopyForwarding.cpp
index 1ef6e52..485ad41 100644
--- a/lib/SILOptimizer/Transforms/CopyForwarding.cpp
+++ b/lib/SILOptimizer/Transforms/CopyForwarding.cpp
@@ -65,6 +65,7 @@
 #include "swift/SILOptimizer/Analysis/AliasAnalysis.h"
 #include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
 #include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
+#include "swift/SILOptimizer/Analysis/RCIdentityAnalysis.h"
 #include "swift/SILOptimizer/PassManager/Passes.h"
 #include "swift/SILOptimizer/PassManager/Transforms.h"
 #include "swift/SILOptimizer/Utils/CFG.h"
@@ -167,6 +168,19 @@
   return Apply->getArgumentConvention(FoundArgIdx.getValue());
 }
 
+/// If the given instruction is a store, return the stored value.
+static SILValue getStoredValue(SILInstruction *I) {
+  switch (I->getKind()) {
+  case SILInstructionKind::StoreInst:
+  case SILInstructionKind::StoreBorrowInst:
+  case SILInstructionKind::StoreUnownedInst:
+  case SILInstructionKind::StoreWeakInst:
+    return I->getOperand(0);
+  default:
+    return SILValue();
+  }
+}
+
 //===----------------------------------------------------------------------===//
 //                 Forward and backward copy propagation
 //===----------------------------------------------------------------------===//
@@ -481,6 +495,7 @@
   // Per-function state.
   PostOrderAnalysis *PostOrder;
   DominanceAnalysis *DomAnalysis;
+  RCIdentityAnalysis *RCIAnalysis;
   bool DoGlobalHoisting;
   bool HasChanged;
   bool HasChangedCFG;
@@ -495,10 +510,15 @@
   // beyond the value's immediate uses.
   bool IsSrcLoadedFrom;
 
+  // Does the address defined by CurrentDef have unrecognized uses of a
+  // nontrivial value stored at its address?
+  bool HasUnknownStoredValue;
+
   bool HasForwardedToCopy;
   SmallPtrSet<SILInstruction*, 16> SrcUserInsts;
   SmallPtrSet<DebugValueAddrInst*, 4> SrcDebugValueInsts;
   SmallVector<CopyAddrInst*, 4> TakePoints;
+  SmallPtrSet<SILInstruction *, 16> StoredValueUserInsts;
   SmallVector<DestroyAddrInst*, 4> DestroyPoints;
   SmallPtrSet<SILBasicBlock*, 32> DeadInBlocks;
 
@@ -514,6 +534,11 @@
       if (isa<LoadInst>(user))
         CPF.IsSrcLoadedFrom = true;
 
+      if (SILValue storedValue = getStoredValue(user)) {
+        if (!CPF.markStoredValueUsers(storedValue))
+          CPF.HasUnknownStoredValue = true;
+      }
+
       // Bail on multiple uses in the same instruction to avoid complexity.
       return CPF.SrcUserInsts.insert(user).second;
     }
@@ -534,10 +559,12 @@
   };
 
 public:
-  CopyForwarding(PostOrderAnalysis *PO, DominanceAnalysis *DA)
-      : PostOrder(PO), DomAnalysis(DA), DoGlobalHoisting(false),
-        HasChanged(false), HasChangedCFG(false), IsSrcLoadedFrom(false),
-        HasForwardedToCopy(false), CurrentCopy(nullptr) {}
+  CopyForwarding(PostOrderAnalysis *PO, DominanceAnalysis *DA,
+                 RCIdentityAnalysis *RCIAnalysis)
+    : PostOrder(PO), DomAnalysis(DA), RCIAnalysis(RCIAnalysis),
+      DoGlobalHoisting(false), HasChanged(false), HasChangedCFG(false),
+      IsSrcLoadedFrom(false), HasUnknownStoredValue(false),
+      HasForwardedToCopy(false), CurrentCopy(nullptr) {}
 
   void reset(SILFunction *F) {
     // Don't hoist destroy_addr globally in transparent functions. Avoid cloning
@@ -552,13 +579,16 @@
       // We'll invalidate the analysis that are used by other passes at the end.
       DomAnalysis->invalidate(F, SILAnalysis::InvalidationKind::Everything);
       PostOrder->invalidate(F, SILAnalysis::InvalidationKind::Everything);
+      RCIAnalysis->invalidate(F, SILAnalysis::InvalidationKind::Everything);
     }
     CurrentDef = SILValue();
     IsSrcLoadedFrom = false;
+    HasUnknownStoredValue = false;
     HasForwardedToCopy = false;
     SrcUserInsts.clear();
     SrcDebugValueInsts.clear();
     TakePoints.clear();
+    StoredValueUserInsts.clear();
     DestroyPoints.clear();
     DeadInBlocks.clear();
     CurrentCopy = nullptr;
@@ -585,6 +615,8 @@
 
   typedef llvm::SmallSetVector<SILInstruction *, 16> UserVector;
   bool doesCopyDominateDestUsers(const UserVector &DirectDestUses);
+
+  bool markStoredValueUsers(SILValue storedValue);
 };
 
 class CopyDestUserVisitor : public AddressUserVisitor {
@@ -805,6 +837,51 @@
   return true;
 }
 
+// Add all recognized users of storedValue to StoredValueUserInsts. Return true
+// if all users were recgonized.
+//
+// To find all SSA users of storedValue, we first find the RC root, then search
+// past any instructions that may propagate the reference.
+bool CopyForwarding::markStoredValueUsers(SILValue storedValue) {
+  if (storedValue->getType().isTrivial(*storedValue->getModule()))
+    return true;
+
+  // Find the RC root, peeking past things like struct_extract.
+  RCIdentityFunctionInfo *RCI = RCIAnalysis->get(storedValue->getFunction());
+  SILValue root = RCI->getRCIdentityRoot(storedValue);
+
+  SmallVector<SILInstruction *, 8> users;
+  RCI->getRCUsers(root, users);
+
+  for (SILInstruction *user : users) {
+    // Recognize any uses that have no results as normal uses. They cannot
+    // transitively propagate a reference.
+    if (user->getResults().empty()) {
+      StoredValueUserInsts.insert(user);
+      continue;
+    }
+    // Recognize full applies as normal uses. They may transitively retain, but
+    // the caller cannot rely on that.
+    if (FullApplySite::isa(user)) {
+      StoredValueUserInsts.insert(user);
+      continue;
+    }
+    // A single-valued use is nontransitive if its result is trivial.
+    if (auto *SVI = dyn_cast<SingleValueInstruction>(user)) {
+      if (SVI->getType().isTrivial(user->getModule())) {
+        StoredValueUserInsts.insert(user);
+        continue;
+      }
+    }
+    // Conservatively treat everything else as potentially transitively
+    // retaining the stored value.
+    DEBUG(llvm::dbgs() << "  Cannot reduce lifetime. May retain " << storedValue
+          << " at: " << *user << "\n");
+    return false;
+  }
+  return true;
+}
+
 /// Returns the associated dealloc_stack if \p ASI has a single dealloc_stack.
 /// Usually this is the case, but the optimizations may generate something like:
 /// %1 = alloc_stack
@@ -1112,10 +1189,10 @@
 /// The copy will be eliminated if the original is not accessed between the
 /// point of copy and the original's destruction.
 ///
-/// Def = <uniquely identified> // no aliases
+/// CurrentDef = <uniquely identified> // no aliases
 /// ...
 /// Copy = copy_addr [init] Def
-/// ...                    // no access to Def
+/// ...                    // no access to CurrentDef
 /// destroy_addr Def
 ///
 /// Return true if a destroy was inserted, forwarded from a copy, or the
@@ -1137,6 +1214,19 @@
     --SI;
     SILInstruction *Inst = &*SI;
     if (!SrcUserInsts.count(Inst)) {
+      if (StoredValueUserInsts.count(Inst)) {
+        // The current definition may take ownership of a value stored into its
+        // address. Its lifetime cannot end before the last use of that stored
+        // value.
+        // CurrentDef = ...
+        // Copy = copy_addr CurrentDef to ...
+        // store StoredValue to CurrentDef
+        // ...                    // no access to CurrentDef
+        // retain StoredValue
+        // destroy_addr CurrentDef
+        DEBUG(llvm::dbgs() << "  Cannot hoist above stored value use:" << *Inst);
+        return false;
+      }
       if (!IsWorthHoisting && isa<ApplyInst>(Inst))
         IsWorthHoisting = true;
       continue;
@@ -1185,7 +1275,7 @@
   // TODO: Record all loads during collectUsers. Implement findRetainPoints to
   // peek though projections of the load, like unchecked_enum_data to find the
   // true extent of the lifetime including transitively referenced objects.
-  if (IsSrcLoadedFrom)
+  if (IsSrcLoadedFrom || HasUnknownStoredValue)
     return;
 
   bool HoistedDestroyFound = false;
@@ -1420,7 +1510,8 @@
 
     auto *PO = getAnalysis<PostOrderAnalysis>();
     auto *DA = getAnalysis<DominanceAnalysis>();
-    auto Forwarding = CopyForwarding(PO, DA);
+    auto *RCIA = getAnalysis<RCIdentityAnalysis>();
+    auto Forwarding = CopyForwarding(PO, DA, RCIA);
 
     for (SILValue Def : CopiedDefs) {
 #ifndef NDEBUG
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 7b66e07..83585f9 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -1980,6 +1980,18 @@
       auto locator = disjunction->getLocator();
       assert(locator && "remembered disjunction doesn't have a locator?");
       DisjunctionChoices.push_back({locator, index});
+
+      // Implicit unwraps of optionals are worse solutions than those
+      // not involving implicit unwraps.
+      if (!locator->getPath().empty()) {
+        auto kind = locator->getPath().back().getKind();
+        if (kind == ConstraintLocator::ImplicitlyUnwrappedDisjunctionChoice ||
+            kind == ConstraintLocator::DynamicLookupResult) {
+          assert(index == 0 || index == 1);
+          if (index == 1)
+            increaseScore(SK_ForceUnchecked);
+        }
+      }
     }
 
     if (auto score = currentChoice.solve(solutions, allowFreeTypeVariables)) {
diff --git a/lib/Sema/ConstraintLocator.cpp b/lib/Sema/ConstraintLocator.cpp
index 0411d9c..37fc2c4 100644
--- a/lib/Sema/ConstraintLocator.cpp
+++ b/lib/Sema/ConstraintLocator.cpp
@@ -252,7 +252,7 @@
       break;
 
     case ImplicitlyUnwrappedDisjunctionChoice:
-      out << "implictly unwrapped disjunction choice";
+      out << "implicitly unwrapped disjunction choice";
       break;
 
     case DynamicLookupResult:
diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp
index c3948d4..8e9a29b 100644
--- a/lib/Sema/ConstraintSystem.cpp
+++ b/lib/Sema/ConstraintSystem.cpp
@@ -1675,31 +1675,6 @@
                              choice.getFunctionRefKind(), locator);
     }
 
-    if (!isRequirementOrWitness(locator) &&
-        choice.getDecl()->getAttrs().hasAttribute<OptionalAttr>() &&
-        !isa<SubscriptDecl>(choice.getDecl())) {
-      // For a non-subscript declaration that is an optional
-      // requirement in a protocol, strip off the lvalue-ness (FIXME:
-      // one cannot assign to such declarations for now) and make a
-      // reference to that declaration be optional.
-      //
-      // Subscript declarations are handled within
-      // getTypeOfMemberReference(); their result types are optional.
-
-      // Deal with values declared as implicitly unwrapped, or
-      // functions with return types that are implicitly unwrapped.
-      if (choice.isImplicitlyUnwrappedValueOrReturnValue()) {
-        // Build the disjunction to attempt binding both T? and T (or
-        // function returning T? and function returning T).
-        Type ty = createTypeVariable(locator);
-        buildDisjunctionForImplicitlyUnwrappedOptional(ty, refType,
-                                                       locator);
-        addConstraint(ConstraintKind::Bind, boundType,
-                      OptionalType::get(ty->getRValueType()), locator);
-        bindConstraintCreated = true;
-      }
-      refType = OptionalType::get(refType->getRValueType());
-    }
     // For a non-subscript declaration found via dynamic lookup, strip
     // off the lvalue-ness (FIXME: as a temporary hack. We eventually
     // want this to work) and make a reference to that declaration be
@@ -1708,7 +1683,7 @@
     // Subscript declarations are handled within
     // getTypeOfMemberReference(); their result types are unchecked
     // optional.
-    else if (isDynamicResult) {
+    if (isDynamicResult) {
       if (isa<SubscriptDecl>(choice.getDecl())) {
         // We always expect function type for subscripts.
         auto fnTy = refType->castTo<AnyFunctionType>();
@@ -1773,8 +1748,31 @@
       }
 
       bindConstraintCreated = true;
-    }
+    } else if (!isRequirementOrWitness(locator) &&
+               choice.getDecl()->getAttrs().hasAttribute<OptionalAttr>() &&
+               !isa<SubscriptDecl>(choice.getDecl())) {
+      // For a non-subscript declaration that is an optional
+      // requirement in a protocol, strip off the lvalue-ness (FIXME:
+      // one cannot assign to such declarations for now) and make a
+      // reference to that declaration be optional.
+      //
+      // Subscript declarations are handled within
+      // getTypeOfMemberReference(); their result types are optional.
 
+      // Deal with values declared as implicitly unwrapped, or
+      // functions with return types that are implicitly unwrapped.
+      if (choice.isImplicitlyUnwrappedValueOrReturnValue()) {
+        // Build the disjunction to attempt binding both T? and T (or
+        // function returning T? and function returning T).
+        Type ty = createTypeVariable(locator);
+        buildDisjunctionForImplicitlyUnwrappedOptional(ty, refType, locator);
+        addConstraint(ConstraintKind::Bind, boundType,
+                      OptionalType::get(ty->getRValueType()), locator);
+        bindConstraintCreated = true;
+      }
+
+      refType = OptionalType::get(refType->getRValueType());
+    }
     // If the declaration is unavailable, note that in the score.
     if (choice.getDecl()->getAttrs().isUnavailable(getASTContext())) {
       increaseScore(SK_Unavailable);
diff --git a/lib/Sema/ConstraintSystem.h b/lib/Sema/ConstraintSystem.h
index 02f8554..2d524d5 100644
--- a/lib/Sema/ConstraintSystem.h
+++ b/lib/Sema/ConstraintSystem.h
@@ -2414,6 +2414,13 @@
   void
   buildDisjunctionForOptionalVsUnderlying(Type boundTy, Type type,
                                           ConstraintLocator *locator) {
+    // NOTE: If we use other locator kinds for these disjunctions, we
+    // need to account for it in solution scores for forced-unwraps.
+    assert(locator->getPath().back().getKind() ==
+               ConstraintLocator::ImplicitlyUnwrappedDisjunctionChoice ||
+           locator->getPath().back().getKind() ==
+               ConstraintLocator::DynamicLookupResult);
+
     // Create the constraint to bind to the optional type and make it
     // the favored choice.
     auto *bindToOptional =
diff --git a/lib/Syntax/Status.md b/lib/Syntax/Status.md
index 907557e..d37067a 100644
--- a/lib/Syntax/Status.md
+++ b/lib/Syntax/Status.md
@@ -67,9 +67,9 @@
   * DestructorDecl
   * EnumDecl
   * EnumCaseDecl
+  * PrecedenceGroupDecl
 
 ### Not-started (UnknownDecl):
-  * PrecedenceGroupDecl
   * InfixOperatorDecl
   * PrefixOperatorDecl
   * PostfixOperatorDecl
diff --git a/stdlib/public/Reflection/CMakeLists.txt b/stdlib/public/Reflection/CMakeLists.txt
index 0bb36de..dbbc72c 100644
--- a/stdlib/public/Reflection/CMakeLists.txt
+++ b/stdlib/public/Reflection/CMakeLists.txt
@@ -1,3 +1,12 @@
+set(swift_extra_sources)
+
+# When we're building with assertions, include the demangle node dumper to aid
+# in debugging.
+if (LLVM_ENABLE_ASSERTIONS)
+  list(APPEND swift_extra_sources "${SWIFT_SOURCE_DIR}/lib/Demangling/NodeDumper.cpp")
+endif(LLVM_ENABLE_ASSERTIONS)
+
+
 add_swift_library(swiftReflection STATIC TARGET_LIBRARY FORCE_BUILD_FOR_HOST_SDK
   MetadataSource.cpp
   TypeLowering.cpp
@@ -11,7 +20,8 @@
   "${SWIFT_SOURCE_DIR}/lib/Demangling/Punycode.cpp"
   "${SWIFT_SOURCE_DIR}/lib/Demangling/Remangler.cpp"
   "${SWIFT_SOURCE_DIR}/lib/Demangling/TypeDecoder.cpp"
-
+  ${swift_extra_sources}
   C_COMPILE_FLAGS ${SWIFT_RUNTIME_CXX_FLAGS}
   LINK_FLAGS ${SWIFT_RUNTIME_LINK_FLAGS}
   INSTALL_IN_COMPONENT dev)
+
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index 9df70cb..8f116da 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -237,6 +237,9 @@
 list(APPEND swift_stdlib_compile_flags "-Xllvm" "-sil-inline-generics")
 list(APPEND swift_stdlib_compile_flags "-Xllvm" "-sil-partial-specialization")
 list(APPEND swift_stdlib_compile_flags "-Xfrontend" "-enable-sil-ownership")
+if(SWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING)
+  list(APPEND swift_stdlib_compile_flags "-enforce-exclusivity=checked")
+endif()
 
 if(SWIFT_CHECK_ESSENTIAL_STDLIB)
   add_swift_library(swift_stdlib_essential ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB IS_STDLIB_CORE
diff --git a/stdlib/public/core/Codable.swift.gyb b/stdlib/public/core/Codable.swift.gyb
index 807fb17..b51e940 100644
--- a/stdlib/public/core/Codable.swift.gyb
+++ b/stdlib/public/core/Codable.swift.gyb
@@ -1767,7 +1767,8 @@
 }
 
 extension RawRepresentable where RawValue == ${type}, Self : Encodable {
-  /// Encodes this value into the given encoder.
+  /// Encodes this value into the given encoder, when the type's `RawValue`
+  /// is `${type}`.
   ///
   /// This function throws an error if any values are invalid for the given
   /// encoder's format.
@@ -1781,7 +1782,8 @@
 }
 
 extension RawRepresentable where RawValue == ${type}, Self : Decodable {
-  /// Creates a new instance by decoding from the given decoder.
+  /// Creates a new instance by decoding from the given decoder, when the
+  /// type's `RawValue` is `${type}`.
   ///
   /// This initializer throws an error if reading from the decoder fails, or
   /// if the data read is corrupted or otherwise invalid.
diff --git a/stdlib/public/core/CollectionOfOne.swift b/stdlib/public/core/CollectionOfOne.swift
index e4c8084..6bd5a28 100644
--- a/stdlib/public/core/CollectionOfOne.swift
+++ b/stdlib/public/core/CollectionOfOne.swift
@@ -10,7 +10,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-/// An iterator that produces one or fewer instances of `Element`.
+/// An iterator that produces one or zero instances of an element.
+///
+/// `IteratorOverOne` is the iterator for the `CollectionOfOne` type.
 @_fixed_layout // FIXME(sil-serialize-all)
 public struct IteratorOverOne<Element> {
   @usableFromInline // FIXME(sil-serialize-all)
@@ -31,8 +33,8 @@
   ///
   /// Once `nil` has been returned, all subsequent calls return `nil`.
   ///
-  /// - Precondition: `next()` has not been applied to a copy of `self`
-  ///   since the copy was made.
+  /// - Returns: The next element in the underlying sequence, if a next element
+  ///   exists; otherwise, `nil`.
   @inlinable // FIXME(sil-serialize-all)
   public mutating func next() -> Element? {
     let result = _elements
@@ -41,13 +43,25 @@
   }
 }
 
-/// A collection containing a single element of type `Element`.
+/// A collection containing a single element.
+///
+/// You can use a `CollectionOfOne` instance when you need to efficiently
+/// represent a single value as a collection. For example, you can add a
+/// single element to an array by using a `CollectionOfOne` instance with the
+/// concatenation operator (`+`):
+///
+///     let a = [1, 2, 3, 4]
+///     let toAdd = 100
+///     let b = a + CollectionOfOne(toAdd)
+///     // b == [1, 2, 3, 4, 100]
 @_fixed_layout // FIXME(sil-serialize-all)
 public struct CollectionOfOne<Element> {
   @usableFromInline // FIXME(sil-serialize-all)
   internal var _element: Element
 
-  /// Creates an instance containing just `element`.
+  /// Creates an instance containing just the given element.
+  ///
+  /// - Parameter element: The element to store in the collection.
   @inlinable // FIXME(sil-serialize-all)
   public init(_ element: Element) {
     self._element = element
@@ -60,6 +74,8 @@
   public typealias Indices = Range<Int>
 
   /// The position of the first element.
+  ///
+  /// In a `CollectionOfOne` instance, `startIndex` is always `0`.
   @inlinable // FIXME(sil-serialize-all)
   public var startIndex: Int {
     return 0
@@ -68,38 +84,44 @@
   /// The "past the end" position---that is, the position one greater than the
   /// last valid subscript argument.
   ///
-  /// In a `CollectionOfOne` instance, `endIndex` is always identical to
-  /// `index(after: startIndex)`.
+  /// In a `CollectionOfOne` instance, `endIndex` is always `1`.
   @inlinable // FIXME(sil-serialize-all)
   public var endIndex: Int {
     return 1
   }
   
-  /// Always returns `endIndex`.
+  /// Returns the position immediately after the given index.
+  ///
+  /// - Parameter i: A valid index of the collection. `i` must be `0`.
+  /// - Returns: The index value immediately after `i`.
   @inlinable // FIXME(sil-serialize-all)
   public func index(after i: Int) -> Int {
     _precondition(i == startIndex)
     return endIndex
   }
 
-  /// Always returns `startIndex`.
+  /// Returns the position immediately before the given index.
+  ///
+  /// - Parameter i: A valid index of the collection. `i` must be `1`.
+  /// - Returns: The index value immediately before `i`.
   @inlinable // FIXME(sil-serialize-all)
   public func index(before i: Int) -> Int {
     _precondition(i == endIndex)
     return startIndex
   }
 
-  /// Returns an iterator over the elements of this sequence.
+  /// Returns an iterator over the elements of this collection.
   ///
-  /// - Complexity: O(1).
+  /// - Complexity: O(1)
   @inlinable // FIXME(sil-serialize-all)
   public func makeIterator() -> IteratorOverOne<Element> {
     return IteratorOverOne(_elements: _element)
   }
 
-  /// Accesses the element at `position`.
+  /// Accesses the element at the specified position.
   ///
-  /// - Precondition: `position == 0`.
+  /// - Parameter position: The position of the element to access. The only
+  ///   valid position in a `CollectionOfOne` instance is `0`.
   @inlinable // FIXME(sil-serialize-all)
   public subscript(position: Int) -> Element {
     get {
@@ -129,7 +151,7 @@
     }
   }
 
-  /// The number of elements (always one).
+  /// The number of elements in the collection, which is always one.
   @inlinable // FIXME(sil-serialize-all)
   public var count: Int {
     return 1
@@ -137,7 +159,7 @@
 }
 
 extension CollectionOfOne : CustomDebugStringConvertible {
-  /// A textual representation of `self`, suitable for debugging.
+  /// A textual representation of the collection, suitable for debugging.
   @inlinable // FIXME(sil-serialize-all)
   public var debugDescription: String {
     return "CollectionOfOne(\(String(reflecting: _element)))"
diff --git a/stdlib/public/core/CompilerProtocols.swift b/stdlib/public/core/CompilerProtocols.swift
index efc45b8..d49be2c 100644
--- a/stdlib/public/core/CompilerProtocols.swift
+++ b/stdlib/public/core/CompilerProtocols.swift
@@ -178,37 +178,46 @@
   return lhs.rawValue != rhs.rawValue
 }
 
-/// A type that can produce a collection of all of its values.
+/// A type that provides a collection of all of its values.
 ///
-/// Simple Enumerations
-/// ===================
+/// Types that conform to the `CaseIterable` protocol are typically
+/// enumerations without associated values. When using a `CaseIterable` type,
+/// you can access a collection of all of the type's cases by using the type's
+/// `allCases` property.
 ///
-/// For any Swift enumeration where every case does not have an associated
-/// value, the Swift compiler can automatically fill out the `CaseIterable`
-/// conformance. When defining your own custom enumeration, specify a
-/// conformance to `CaseIterable` to take advantage of this automatic
-/// derivation.
+/// For example, the `CompassDirection` enumeration declared in this example
+/// conforms to `CaseIterable`. You access the number of cases and the cases
+/// themselves through `CompassDirection.allCases`.
 ///
-/// For example, every case of the `CardinalPoint` enumeration defined here
-/// does not have an associated value:
-///
-///     enum CardinalPoint: CaseIterable {
+///     enum CompassDirection: CaseIterable {
 ///         case north, south, east, west
 ///     }
 ///
-/// So the compiler automatically creates a conformance.
+///     print("There are \(CompassDirection.allCases.count) directions.")
+///     // Prints "There are 4 directions."
+///     let caseList = CompassDirection.allCases
+///                                    .map({ "\($0)" })
+///                                    .joined(separator: ", ")
+///     // caseList == "north, south, east, west"
 ///
-///     for cardinality in CardinalPoint.allCases {
-///         print(cardinality)
-///     }
-///     // Prints "north"
-///     // Prints "south"
-///     // Prints "east"
-///     // Prints "west"
+/// Conforming to the CaseIterable Protocol
+/// =======================================
+///
+/// The compiler can automatically provide an implementation of the
+/// `CaseIterable` requirements for any enumeration without associated values
+/// or `@available` attributes on its cases. The synthesized `allCases`
+/// collection provides the cases in order of their declaration.
+///
+/// You can take advantage of this compiler support when defining your own
+/// custom enumeration by declaring conformance to `CaseIterable` in the
+/// enumeration's original declaration. The `CompassDirection` example above
+/// demonstrates this automatic implementation.
 public protocol CaseIterable {
+  /// A type that can represent a collection of all values of this type.
   associatedtype AllCases: Collection
     where AllCases.Element == Self
-  /// Returns a collection of all values of this type.
+  
+  /// A collection of all values of this type.
   static var allCases: AllCases { get }
 }
 
diff --git a/stdlib/public/core/Dictionary.swift b/stdlib/public/core/Dictionary.swift
index 98be4e3..d090266 100644
--- a/stdlib/public/core/Dictionary.swift
+++ b/stdlib/public/core/Dictionary.swift
@@ -399,16 +399,16 @@
     self = Dictionary<Key, Value>(_nativeBuffer: _NativeBuffer())
   }
 
-  /// Creates a dictionary with at least the given number of elements worth of
-  /// buffer.
+  /// Creates an empty dictionary with preallocated space for at least the
+  /// specified number of elements.
   ///
-  /// Use this initializer to avoid intermediate reallocations when you know
-  /// how many key-value pairs you are adding to a dictionary. The actual
-  /// capacity of the created dictionary is the smallest power of 2 that
-  /// is greater than or equal to `minimumCapacity`.
+  /// Use this initializer to avoid intermediate reallocations of a dictionary's
+  /// storage buffer when you know how many key-value pairs you are adding to a
+  /// dictionary after creation.
   ///
-  /// - Parameter minimumCapacity: The minimum number of key-value pairs to
-  ///   allocate buffer for in the new dictionary.
+  /// - Parameter minimumCapacity: The minimum number of key-value pairs that
+  ///   the newly created dictionary should be able to store without
+  //    reallocating its storage buffer.
   @inlinable // FIXME(sil-serialize-all)
   public init(minimumCapacity: Int) {
     _variantBuffer = .native(_NativeBuffer(minimumCapacity: minimumCapacity))
diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb
index b2175bc..0389bf7 100644
--- a/stdlib/public/core/Integers.swift.gyb
+++ b/stdlib/public/core/Integers.swift.gyb
@@ -301,6 +301,7 @@
   ///     let x: UInt8 = 5          // 0b00000101
   ///     let y: UInt8 = 14         // 0b00001110
   ///     let z = x & y             // 0b00000100
+  ///     // z == 4
   ///
   /// - Parameters:
   ///   - lhs: An integer value.
@@ -317,6 +318,7 @@
   ///     let x: UInt8 = 5          // 0b00000101
   ///     let y: UInt8 = 14         // 0b00001110
   ///     let z = x | y             // 0b00001111
+  ///     // z == 15
   ///
   /// - Parameters:
   ///   - lhs: An integer value.
@@ -333,6 +335,7 @@
   ///     let x: UInt8 = 5          // 0b00000101
   ///     let y: UInt8 = 14         // 0b00001110
   ///     let z = x ^ y             // 0b00001011
+  ///     // z == 11
   ///
   /// - Parameters:
   ///   - lhs: An integer value.
@@ -343,9 +346,10 @@
   /// specified number of digits to the right, masking the shift amount to the
   /// type's bit width.
   ///
-  /// The masking right shift operator (`&>>`) performs a *masking shift*,
-  /// where the value passed as `rhs` is masked to produce a value in the
-  /// range `0..<lhs.bitWidth`. The shift is performed using this masked
+  /// Use the masking right shift operator (`&>>`) when you need to perform a
+  /// shift and are sure that the shift amount is in the range
+  /// `0..<lhs.bitWidth`. Before shifting, the masking right shift operator
+  /// masks the shift to this range. The shift is performed using this masked
   /// value.
   ///
   /// The following example defines `x` as an instance of `UInt8`, an 8-bit,
@@ -356,11 +360,16 @@
   ///     let y = x &>> 2
   ///     // y == 7                         // 0b00000111
   ///
-  /// However, if you use `19` as `rhs`, the operation first bitmasks `rhs` to
-  /// `3`, and then uses that masked value as the number of bits to shift `lhs`.
+  /// However, if you use `8` as the shift amount, the method first masks the
+  /// shift amount to zero, and then performs the shift, resulting in no change
+  /// to the original value.
   ///
-  ///     let z = x &>> 19
-  ///     // z == 3                         // 0b00000011
+  ///     let z = x &>> 8
+  ///     // z == 30                        // 0b00011110
+  ///
+  /// If the bit width of the shifted integer type is a power of two, masking
+  /// is performed using a bitmask; otherwise, masking is performed using a
+  /// modulo operation.
   ///
   /// - Parameters:
   ///   - lhs: The value to shift.
@@ -373,9 +382,11 @@
   /// specified number of digits to the left, masking the shift amount to the
   /// type's bit width.
   ///
-  /// The masking left shift operator (`&<<`) performs a *masking shift*, where
-  /// the value used as `rhs` is masked to produce a value in the range
-  /// `0..<lhs.bitWidth`. The shift is performed using this masked value.
+  /// Use the masking left shift operator (`&<<`) when you need to perform a
+  /// shift and are sure that the shift amount is in the range
+  /// `0..<lhs.bitWidth`. Before shifting, the masking left shift operator
+  /// masks the shift to this range. The shift is performed using this masked
+  /// value.
   ///
   /// The following example defines `x` as an instance of `UInt8`, an 8-bit,
   /// unsigned integer type. If you use `2` as the right-hand-side value in an
@@ -385,11 +396,16 @@
   ///     let y = x &<< 2
   ///     // y == 120                       // 0b01111000
   ///
-  /// However, if you pass `19` as `rhs`, the method first bitmasks `rhs` to
-  /// `3`, and then uses that masked value as the number of bits to shift `lhs`.
+  /// However, if you use `8` as the shift amount, the method first masks the
+  /// shift amount to zero, and then performs the shift, resulting in no change
+  /// to the original value.
   ///
-  ///     let z = x &<< 19
-  ///     // z == 240                       // 0b11110000
+  ///     let z = x &<< 8
+  ///     // z == 30                        // 0b00011110
+  ///
+  /// If the bit width of the shifted integer type is a power of two, masking
+  /// is performed using a bitmask; otherwise, masking is performed using a
+  /// modulo operation.
   ///
   /// - Parameters:
   ///   - lhs: The value to shift.
@@ -952,9 +968,14 @@
   /// Returns the sum of this value and the given value without checking for
   /// arithmetic overflow.
   ///
-  /// If an arithmetic overflow occurs, the behavior is undefined. Use this
-  /// function only to avoid the cost of overflow checking when you are sure
-  /// that the operation won't overflow.
+  /// Use this function only to avoid the cost of overflow checking when you
+  /// are certain that the operation won't overflow. In optimized builds (`-O`)
+  /// the compiler is free to assume that overflow won't occur. Failure to
+  /// satisfy that assumption is a serious programming error and could lead to
+  /// statements being unexpectedly executed or skipped.
+  ///
+  /// In debug builds (`-Onone`) a runtime error is still triggered if the
+  /// operation overflows.
   ///
   /// - Parameter rhs: The value to add to this value.
   /// - Returns: The sum of this value and `rhs`.
@@ -963,9 +984,14 @@
   /// Returns the difference obtained by subtracting the given value from this
   /// value without checking for arithmetic overflow.
   ///
-  /// If an arithmetic overflow occurs, the behavior is undefined. Use this
-  /// function only to avoid the cost of overflow checking when you are sure
-  /// that the operation won't overflow.
+  /// Use this function only to avoid the cost of overflow checking when you
+  /// are certain that the operation won't overflow. In optimized builds (`-O`)
+  /// the compiler is free to assume that overflow won't occur. Failure to
+  /// satisfy that assumption is a serious programming error and could lead to
+  /// statements being unexpectedly executed or skipped.
+  ///
+  /// In debug builds (`-Onone`) a runtime error is still triggered if the
+  /// operation overflows.
   ///
   /// - Parameter rhs: The value to subtract from this value.
   /// - Returns: The result of subtracting `rhs` from this value.
@@ -974,9 +1000,14 @@
   /// Returns the product of this value and the given value without checking
   /// for arithmetic overflow.
   ///
-  /// If an arithmetic overflow occurs, the behavior is undefined. Use this
-  /// function only to avoid the cost of overflow checking when you are sure
-  /// that the operation won't overflow.
+  /// Use this function only to avoid the cost of overflow checking when you
+  /// are certain that the operation won't overflow. In optimized builds (`-O`)
+  /// the compiler is free to assume that overflow won't occur. Failure to
+  /// satisfy that assumption is a serious programming error and could lead to
+  /// statements being unexpectedly executed or skipped.
+  ///
+  /// In debug builds (`-Onone`) a runtime error is still triggered if the
+  /// operation overflows.
   ///
   /// - Parameter rhs: The value to multiply by this value.
   /// - Returns: The product of this value and `rhs`.
@@ -985,9 +1016,14 @@
   /// Returns the quotient obtained by dividing this value by the given value
   /// without checking for arithmetic overflow.
   ///
-  /// If an arithmetic overflow occurs, the behavior is undefined. Use this
-  /// function only to avoid the cost of overflow checking when you are sure
-  /// that the operation won't overflow.
+  /// Use this function only to avoid the cost of overflow checking when you
+  /// are certain that the operation won't overflow. In optimized builds (`-O`)
+  /// the compiler is free to assume that overflow won't occur. Failure to
+  /// satisfy that assumption is a serious programming error and could lead to
+  /// statements being unexpectedly executed or skipped.
+  ///
+  /// In debug builds (`-Onone`) a runtime error is still triggered if the
+  /// operation overflows.
   ///
   /// - Parameter rhs: The value to divide this value by.
   /// - Returns: The result of dividing this value by `rhs`.
@@ -2256,23 +2292,23 @@
   /// otherwise overflow. Unlike traditional truncating multiplication, the
   /// `multipliedFullWidth(by:)` method returns a tuple containing both the
   /// `high` and `low` parts of the product of this value and `other`. The
-  /// following example uses this method to multiply two `UInt8` values that
+  /// following example uses this method to multiply two `Int8` values that
   /// normally overflow when multiplied:
   ///
-  ///     let x: UInt8 = 100
-  ///     let y: UInt8 = 20
+  ///     let x: Int8 = 48
+  ///     let y: Int8 = -40
   ///     let result = x.multipliedFullWidth(by: y)
-  ///     // result.high == 0b00000111
-  ///     // result.low  == 0b11010000
+  ///     // result.high == -8
+  ///     // result.low  == 128
   ///
-  /// The product of `x` and `y` is 2000, which is too large to represent in a
-  /// `UInt8` instance. The `high` and `low` properties of the `result` value
-  /// represent 2000 when concatenated to form a double-width integer; that
+  /// The product of `x` and `y` is `-1920`, which is too large to represent in
+  /// an `Int8` instance. The `high` and `low` compnents of the `result` value
+  /// represent `-1920` when concatenated to form a double-width integer; that
   /// is, using `result.high` as the high byte and `result.low` as the low byte
-  /// of a `UInt16` instance.
+  /// of an `Int16` instance.
   ///
-  ///     let z = UInt16(result.high) << 8 | UInt16(result.low)
-  ///     // z == 2000
+  ///     let z = Int16(result.high) << 8 | Int16(result.low)
+  ///     // z == -1920
   ///
   /// - Parameter other: The value to multiply this value by.
   /// - Returns: A tuple containing the high and low parts of the result of
@@ -2286,6 +2322,18 @@
   /// type. If the quotient is too large to represent in the type, a runtime
   /// error may occur.
   ///
+  /// The following example divides a value that is too large to be represented
+  /// using a single `Int` instance by another `Int` value. Because the quotient
+  /// is representable as an `Int`, the division succeeds.
+  ///
+  ///     // 'dividend' represents the value 0x506f70652053616e74612049494949
+  ///     let dividend = (22640526660490081, 7959093232766896457 as UInt)
+  ///     let divisor = 2241543570477705381
+  ///
+  ///     let (quotient, remainder) = divisor.dividingFullWidth(dividend)
+  ///     // quotient == 186319822866995413
+  ///     // remainder == 0
+  ///
   /// - Parameter dividend: A tuple containing the high and low parts of a
   ///   double-width integer.
   /// - Returns: A tuple containing the quotient and remainder obtained by
diff --git a/stdlib/public/core/Range.swift b/stdlib/public/core/Range.swift
index 0b0a9de..bac7c3e 100644
--- a/stdlib/public/core/Range.swift
+++ b/stdlib/public/core/Range.swift
@@ -606,18 +606,29 @@
 {
   public typealias Element = Bound
 
+  /// The iterator for a `PartialRangeFrom` instance.
   @_fixed_layout
   public struct Iterator: IteratorProtocol {
     @usableFromInline
     internal var _current: Bound
     @inlinable
     public init(_current: Bound) { self._current = _current }
+
+    /// Advances to the next element and returns it, or `nil` if no next
+    /// element exists.
+    ///
+    /// Once `nil` has been returned, all subsequent calls return `nil`.
+    ///
+    /// - Returns: The next element in the underlying sequence, if a next
+    ///   element exists; otherwise, `nil`.
     @inlinable
     public mutating func next() -> Bound? {
       defer { _current = _current.advanced(by: 1) }
       return _current
     }
   }
+
+  /// Returns an iterator for this sequence.
   @inlinable
   public func makeIterator() -> Iterator { 
     return Iterator(_current: lowerBound) 
@@ -739,30 +750,33 @@
 /// unbounded range is essentially a conversion of a collection instance into
 /// its slice type.
 ///
-/// For example, the following code declares `levenshteinDistance(_:_:)`, a
-/// function that calculates the number of changes required to convert one
-/// string into another. `levenshteinDistance(_:_:)` uses `Substring`, a
-/// string's slice type, for its parameters.
+/// For example, the following code declares `countLetterChanges(_:_:)`, a
+/// function that finds the number of changes required to change one
+/// word or phrase into another. The function uses a recursive approach to
+/// perform the same comparisons on smaller and smaller pieces of the original
+/// strings. In order to use recursion without making copies of the strings at
+/// each step, `countLetterChanges(_:_:)` uses `Substring`, a string's slice
+/// type, for its parameters.
 ///
-///     func levenshteinDistance(_ s1: Substring, _ s2: Substring) -> Int {
+///     func countLetterChanges(_ s1: Substring, _ s2: Substring) -> Int {
 ///         if s1.isEmpty { return s2.count }
 ///         if s2.isEmpty { return s1.count }
 ///
 ///         let cost = s1.first == s2.first ? 0 : 1
 ///
 ///         return min(
-///             levenshteinDistance(s1.dropFirst(), s2) + 1,
-///             levenshteinDistance(s1, s2.dropFirst()) + 1,
-///             levenshteinDistance(s1.dropFirst(), s2.dropFirst()) + cost)
+///             countLetterChanges(s1.dropFirst(), s2) + 1,
+///             countLetterChanges(s1, s2.dropFirst()) + 1,
+///             countLetterChanges(s1.dropFirst(), s2.dropFirst()) + cost)
 ///     }
 ///
-/// To call `levenshteinDistance(_:_:)` with two strings, use an unbounded
-/// range in each string's subscript to convert it to a `Substring`.
+/// To call `countLetterChanges(_:_:)` with two strings, use an unbounded
+/// range in each string's subscript.
 ///
 ///     let word1 = "grizzly"
 ///     let word2 = "grisly"
-///     let distance = levenshteinDistance(word1[...], word2[...])
-///     // distance == 2
+///     let changes = countLetterChanges(word1[...], word2[...])
+///     // changes == 2
 @_frozen // FIXME(sil-serialize-all)
 public enum UnboundedRange_ {
   // FIXME: replace this with a computed var named `...` when the language makes
diff --git a/stdlib/public/core/RangeReplaceableCollection.swift b/stdlib/public/core/RangeReplaceableCollection.swift
index c836848..e9531fe 100644
--- a/stdlib/public/core/RangeReplaceableCollection.swift
+++ b/stdlib/public/core/RangeReplaceableCollection.swift
@@ -553,7 +553,7 @@
   /// Removes the elements in the specified subrange from the collection.
   ///
   /// All the elements following the specified position are moved to close the
-  /// gap. This example removes two elements from the middle of an array of
+  /// gap. This example removes three elements from the middle of an array of
   /// measurements.
   ///
   ///     var measurements = [1.2, 1.5, 2.9, 1.2, 1.5]
@@ -754,7 +754,7 @@
   /// Removes the elements in the specified subrange from the collection.
   ///
   /// All the elements following the specified position are moved to close the
-  /// gap. This example removes two elements from the middle of an array of
+  /// gap. This example removes three elements from the middle of an array of
   /// measurements.
   ///
   ///     var measurements = [1.2, 1.5, 2.9, 1.2, 1.5]
diff --git a/stdlib/public/core/Set.swift b/stdlib/public/core/Set.swift
index 705505a..2fd512c 100644
--- a/stdlib/public/core/Set.swift
+++ b/stdlib/public/core/Set.swift
@@ -160,17 +160,16 @@
 }
 
 extension Set {
-  /// Creates a new, empty set with at least the specified number of elements'
-  /// worth of buffer.
+  /// Creates an empty set with preallocated space for at least the specified
+  /// number of elements.
   ///
-  /// Use this initializer to avoid repeated reallocations of a set's buffer
-  /// if you know you'll be adding elements to the set after creation. The
-  /// actual capacity of the created set will be the smallest power of 2 that
-  /// is greater than or equal to `minimumCapacity`.
+  /// Use this initializer to avoid intermediate reallocations of a set's
+  /// storage buffer when you know how many elements you'll insert into the set
+  /// after creation.
   ///
   /// - Parameter minimumCapacity: The minimum number of elements that the
   ///   newly created set should be able to store without reallocating its
-  ///   buffer.
+  ///   storage buffer.
   @inlinable // FIXME(sil-serialize-all)
   public init(minimumCapacity: Int) {
     _variantBuffer =
diff --git a/stdlib/public/runtime/CMakeLists.txt b/stdlib/public/runtime/CMakeLists.txt
index c83e471..3f7a508 100644
--- a/stdlib/public/runtime/CMakeLists.txt
+++ b/stdlib/public/runtime/CMakeLists.txt
@@ -73,6 +73,12 @@
     "${SWIFT_SOURCE_DIR}/lib/Demangling/ManglingUtils.cpp"
     "${SWIFT_SOURCE_DIR}/lib/Demangling/Punycode.cpp")
 
+# When we're building with assertions, include the demangle node dumper to aid
+# in debugging.
+if (LLVM_ENABLE_ASSERTIONS)
+  list(APPEND swift_runtime_sources "${SWIFT_SOURCE_DIR}/lib/Demangling/NodeDumper.cpp")
+endif(LLVM_ENABLE_ASSERTIONS)
+
 # Acknowledge that the following sources are known.
 set(LLVM_OPTIONAL_SOURCES
     MutexPThread.cpp
diff --git a/stdlib/public/runtime/SwiftDtoa.cpp b/stdlib/public/runtime/SwiftDtoa.cpp
index 4b253cf..802bb00 100644
--- a/stdlib/public/runtime/SwiftDtoa.cpp
+++ b/stdlib/public/runtime/SwiftDtoa.cpp
@@ -1063,7 +1063,9 @@
     int8_t digits[9];
     int digitCount =
         swift_decompose_float(d, digits, sizeof(digits), &decimalExponent);
-    if (decimalExponent < -3 || decimalExponent > 6) {
+    // People use float to model integers <= 2^24, so we use that
+    // as a cutoff for decimal vs. exponential format.
+    if (decimalExponent < -3 || fabsf(d) > 0x1.0p24F) {
         return swift_format_exponential(dest, length, signbit(d),
                  digits, digitCount, decimalExponent);
     } else {
@@ -1117,7 +1119,9 @@
     int8_t digits[17];
     int digitCount =
         swift_decompose_double(d, digits, sizeof(digits), &decimalExponent);
-    if (decimalExponent < -3 || decimalExponent > 15) {
+    // People use double to model integers <= 2^53, so we use that
+    // as a cutoff for decimal vs. exponential format.
+    if (decimalExponent < -3 || fabs(d) > 0x1.0p53) {
         return swift_format_exponential(dest, length, signbit(d),
                  digits, digitCount, decimalExponent);
     } else {
@@ -1167,12 +1171,15 @@
     }
 
     // Decimal numeric formatting
-    // Decimal numeric formatting
     int decimalExponent;
     int8_t digits[21];
     int digitCount =
         swift_decompose_float80(d, digits, sizeof(digits), &decimalExponent);
-    if (decimalExponent < -3 || decimalExponent > 18) {
+    // People use long double to model integers <= 2^64, so we use that
+    // as a cutoff for decimal vs. exponential format.
+    // The constant is written out as a float80 (aka "long double") literal
+    // here since it can't be expressed as a 64-bit integer.
+    if (decimalExponent < -3 || fabsl(d) > 0x1.0p64L) {
         return swift_format_exponential(dest, length, signbit(d),
                  digits, digitCount, decimalExponent);
     } else {
diff --git a/test/Constraints/iuo.swift b/test/Constraints/iuo.swift
index 554adfa..50641d3 100644
--- a/test/Constraints/iuo.swift
+++ b/test/Constraints/iuo.swift
@@ -213,3 +213,13 @@
   return b as? D! // expected-error {{value of optional type 'D?' not unwrapped; did you mean to use '!' or '?'?}}
   // expected-warning@-1 {{using '!' here is deprecated and will be removed in a future release}}
 }
+
+// Ensure that we select the overload that does *not* involve forcing an IUO.
+func sr6988(x: Int?, y: Int?) -> Int { return x! }
+func sr6988(x: Int, y: Int) -> Float { return Float(x) }
+
+var x: Int! = nil
+var y: Int = 2
+
+let r = sr6988(x: x, y: y)
+let _: Int = r
diff --git a/test/Constraints/sr7098.swift b/test/Constraints/sr7098.swift
new file mode 100644
index 0000000..90005f9
--- /dev/null
+++ b/test/Constraints/sr7098.swift
@@ -0,0 +1,13 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s
+// REQUIRES: objc_interop
+
+import Foundation
+
+class C : NSObject, NSWobbling {
+  func wobble() {}
+  func returnMyself() -> Self { return self }
+}
+
+func testDynamicOptionalRequirement(_ a: AnyObject) {
+  a.optionalRequirement?()
+}
diff --git a/test/IRGen/objc_runtime_visible_conformance.swift b/test/IRGen/objc_runtime_visible_conformance.swift
new file mode 100644
index 0000000..0757081
--- /dev/null
+++ b/test/IRGen/objc_runtime_visible_conformance.swift
@@ -0,0 +1,18 @@
+// REQUIRES: objc_interop
+
+// RUN: %target-swift-frontend -I %S/../Inputs/custom-modules %s -emit-ir | %FileCheck %s
+
+import ObjCRuntimeVisible
+
+protocol MyProtocol {}
+protocol YourProtocol {}
+
+extension A : MyProtocol {}
+extension A : YourProtocol {}
+
+// CHECK-LABEL: @"$SSo1ACMn" = linkonce_odr hidden constant <{ {{.*}} }>, section "__TEXT,__const"
+
+// CHECK-LABEL: define linkonce_odr hidden swiftcc %swift.metadata_response @"$SSo1ACMa"({{i32|i64}}) {{.*}} {
+// CHECK: call %objc_class* @objc_lookUpClass
+// CHECK: call %swift.type* @swift_getObjCClassMetadata
+// CHECK: ret
diff --git a/test/Parse/switch.swift b/test/Parse/switch.swift
index 9d6c32f..e3945f6 100644
--- a/test/Parse/switch.swift
+++ b/test/Parse/switch.swift
@@ -502,3 +502,23 @@
 case _:
   @unknown let _ = 1 // expected-error {{unknown attribute 'unknown'}}
 }
+
+switch Whatever.Thing {
+case .Thing:
+  break
+@unknown(garbage) case _: // expected-error {{unexpected '(' in attribute 'unknown'}}
+  break
+}
+switch Whatever.Thing {
+case .Thing:
+  break
+@unknown // expected-note {{attribute already specified here}}
+@unknown // expected-error {{duplicate attribute}}
+case _:
+  break
+}
+switch Whatever.Thing { // expected-warning {{switch must be exhaustive}} expected-note {{add missing case: '.Thing'}}
+@unknown @garbage(foobar) // expected-error {{unknown attribute 'garbage'}}
+case _:
+  break
+}
diff --git a/test/SIL/Serialization/Inputs/vtable_deserialization_input.swift b/test/SIL/Serialization/Inputs/vtable_deserialization_input.swift
index 130b297..250b388 100644
--- a/test/SIL/Serialization/Inputs/vtable_deserialization_input.swift
+++ b/test/SIL/Serialization/Inputs/vtable_deserialization_input.swift
@@ -1,22 +1,11 @@
+public func unknown() {}
 
-public protocol P {
-  func doSomething()
-}
-
-@_silgen_name("unknown") public
-func unknown() -> ()
-
-@_fixed_layout
-public class Y : P {
-  @inlinable
-  public func doAnotherThing() {
+public class Class {
+  @inlinable public class func firstMethod() {
     unknown()
   }
 
-  @inlinable
-  public func doSomething() {
-    doAnotherThing()
-  }
-  @inlinable
-  public init() {}
+  @inlinable public class func secondMethod() {}
+
+  @inlinable public class func thirdMethod() {}
 }
diff --git a/test/SIL/Serialization/vtable_deserialization.swift b/test/SIL/Serialization/vtable_deserialization.swift
index 2f9c5b8..fb2862e 100644
--- a/test/SIL/Serialization/vtable_deserialization.swift
+++ b/test/SIL/Serialization/vtable_deserialization.swift
@@ -1,32 +1,42 @@
 // RUN: %empty-directory(%t)
-// RUN: %target-swift-frontend %S/Inputs/vtable_deserialization_input.swift -o %t/Swift.swiftmodule -emit-module -parse-as-library -parse-stdlib -module-link-name swiftCore -module-name Swift
-// RUN: %target-swift-frontend %s -emit-sil -O -I %t -o - | %FileCheck %s
+// RUN: %target-swift-frontend %S/Inputs/vtable_deserialization_input.swift -emit-module-path %t/vtable_deserialization_input.swiftmodule -emit-module
+// RUN: %target-swift-frontend %s -emit-sil -I %t | %FileCheck %s
+// RUN: %target-swift-frontend %s -emit-sil -O -I %t | %FileCheck %s --check-prefix=OPT
 
-import Swift
+import vtable_deserialization_input
 
-@usableFromInline
-@inlinable
-func WhatShouldIDoImBored<T : P>(_ t : T) {
-  t.doSomething()
-}
-
-@inline(__always)
-func MakeItNotAGlobal() -> Y {
-  let x = Y()
-  WhatShouldIDoImBored(x)
-  return x
-}
+// Make sure we devirtualized the call and inlined the method body.
+// CHECK: function_ref @$S28vtable_deserialization_input5ClassC11firstMethodyyFZ
+// OPT: function_ref @$S28vtable_deserialization_input7unknownyyF
+Class.firstMethod()
 
 
-// Make sure all abstractions have been removed and everything inlined into top_level_method.
-// CHECK-LABEL: sil @main
-// CHECK: bb0({{.*}}):
-// CHECK: [[UNKNOWN:%.*]] = function_ref @unknown
-// CHECK: apply [[UNKNOWN]]
-// CHECK: integer_literal
-// CHECK: return
-MakeItNotAGlobal()
+// For now, we also deserialize the body of firstMethod(), even though it
+// is not transparent.
+// CHECK-LABEL: sil public_external [serialized] @$S28vtable_deserialization_input5ClassC11firstMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
+// OPT-LABEL: sil public_external @$S28vtable_deserialization_input5ClassC11firstMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
 
-// Make sure our vtable/witness tables are properly deserialized.
-// CHECK: sil_vtable Y {
-// CHECK: sil_witness_table public_external Y: P module Swift {
+// The other two methods should not be deserialized in the mandatory
+// pipeline.
+
+// CHECK-LABEL: sil [serialized] @$S28vtable_deserialization_input5ClassC12secondMethodyyFZ : $@convention(method) (@thick Class.Type) -> (){{$}}
+// OPT-LABEL: sil public_external @$S28vtable_deserialization_input5ClassC12secondMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
+
+// CHECK-LABEL: sil [serialized] @$S28vtable_deserialization_input5ClassC11thirdMethodyyFZ : $@convention(method) (@thick Class.Type) -> (){{$}}
+// OPT-LABEL: sil public_external @$S28vtable_deserialization_input5ClassC11thirdMethodyyFZ : $@convention(method) (@thick Class.Type) -> () {
+
+// Make sure we deserialized the vtable.
+
+// CHECK:      sil_vtable [serialized] Class {
+// CHECK-NEXT:   #Class.firstMethod!1: (Class.Type) -> () -> () : @$S28vtable_deserialization_input5ClassC11firstMethodyyFZ
+// CHECK-NEXT:   #Class.secondMethod!1: (Class.Type) -> () -> () : @$S28vtable_deserialization_input5ClassC12secondMethodyyFZ
+// CHECK-NEXT:   #Class.thirdMethod!1: (Class.Type) -> () -> () : @$S28vtable_deserialization_input5ClassC11thirdMethodyyFZ
+// CHECK-NEXT:   #Class.deinit!deallocator: @$S28vtable_deserialization_input5ClassCfD
+// CHECK-NEXT: }
+
+// OPT:      sil_vtable Class {
+// OPT-NEXT:   #Class.firstMethod!1: (Class.Type) -> () -> () : @$S28vtable_deserialization_input5ClassC11firstMethodyyFZ
+// OPT-NEXT:   #Class.secondMethod!1: (Class.Type) -> () -> () : @$S28vtable_deserialization_input5ClassC12secondMethodyyFZ
+// OPT-NEXT:   #Class.thirdMethod!1: (Class.Type) -> () -> () : @$S28vtable_deserialization_input5ClassC11thirdMethodyyFZ
+// OPT-NEXT:   #Class.deinit!deallocator: @$S28vtable_deserialization_input5ClassCfD
+// OPT-NEXT: }
diff --git a/test/SILOptimizer/copyforward.sil b/test/SILOptimizer/copyforward.sil
index 3d1d344..81adc14 100644
--- a/test/SILOptimizer/copyforward.sil
+++ b/test/SILOptimizer/copyforward.sil
@@ -794,3 +794,92 @@
   %6 = tuple ()
   return %6 : $()
 }
+
+// CHECK-LABEL: sil @testKnownStoredValueUser : $@convention(thin) (@guaranteed AClass) -> @out AClass {
+// CHECK: [[ALLOC:%.*]] = alloc_stack $AClass
+// CHECK: copy_addr [[ALLOC]] to %0 : $*AClass
+// CHECK: strong_retain %1 : $AClass
+// CHECK: destroy_addr [[ALLOC]] : $*AClass
+// CHECK-LABEL: } // end sil function 'testKnownStoredValueUser'
+sil @testKnownStoredValueUser : $@convention(thin) (@guaranteed AClass) -> (@out AClass) {
+bb0(%0 : $*AClass, %1 : $AClass):
+  %2 = alloc_stack $AClass
+  store %1 to %2 : $*AClass
+  copy_addr %2 to %0 : $*AClass
+  strong_retain %1 : $AClass
+  destroy_addr %2 : $*AClass
+  dealloc_stack %2 : $*AClass
+  %999 = tuple ()
+  return %999 : $()
+}
+
+// CHECK-LABEL: sil @testExtractedStoredValueUser1 : $@convention(thin) (@guaranteed ObjWrapper) -> @out AnyObject {
+// CHECK: bb0(%0 : $*AnyObject, %1 : $ObjWrapper):
+// CHECK:   [[ALLOC:%.*]] = alloc_stack $AnyObject
+// CHECK:   [[EXTRACT:%.*]] = struct_extract %1 : $ObjWrapper, #ObjWrapper.obj
+// CHECK:   store [[EXTRACT]] to [[ALLOC]] : $*AnyObject
+// CHECK:   copy_addr [[ALLOC]] to %0 : $*AnyObject
+// CHECK:   strong_retain [[EXTRACT]] : $AnyObject
+// CHECK:   destroy_addr [[ALLOC]] : $*AnyObject
+// CHECK-LABEL: } // end sil function 'testExtractedStoredValueUser1'
+sil @testExtractedStoredValueUser1 : $@convention(thin) (@guaranteed ObjWrapper) -> (@out AnyObject) {
+bb0(%0 : $*AnyObject, %1 : $ObjWrapper):
+  %2 = alloc_stack $AnyObject
+  %3 = struct_extract %1 : $ObjWrapper, #ObjWrapper.obj
+  store %3 to %2 : $*AnyObject
+  copy_addr %2 to %0 : $*AnyObject
+  strong_retain %3 : $AnyObject
+  destroy_addr %2 : $*AnyObject
+  dealloc_stack %2 : $*AnyObject
+  %999 = tuple ()
+  return %999 : $()
+}
+
+// CHECK-LABEL: sil @testExtractedStoredValueUser2 : $@convention(thin) (@guaranteed ObjWrapper) -> @out AnyObject {
+// CHECK: bb0(%0 : $*AnyObject, %1 : $ObjWrapper):
+// CHECK:   [[ALLOC:%.*]] = alloc_stack $AnyObject
+// CHECK:   [[EXTRACT:%.*]] = struct_extract %1 : $ObjWrapper, #ObjWrapper.obj
+// CHECK:   store [[EXTRACT]] to [[ALLOC]] : $*AnyObject
+// CHECK:   copy_addr [[ALLOC]] to %0 : $*AnyObject
+// CHECK:   retain_value %1 : $ObjWrapper
+// CHECK:   destroy_addr [[ALLOC]] : $*AnyObject
+// CHECK-LABEL: } // end sil function 'testExtractedStoredValueUser2'
+sil @testExtractedStoredValueUser2 : $@convention(thin) (@guaranteed ObjWrapper) -> (@out AnyObject) {
+bb0(%0 : $*AnyObject, %1 : $ObjWrapper):
+  %2 = alloc_stack $AnyObject
+  %3 = struct_extract %1 : $ObjWrapper, #ObjWrapper.obj
+  store %3 to %2 : $*AnyObject
+  copy_addr %2 to %0 : $*AnyObject
+  retain_value %1 : $ObjWrapper
+  destroy_addr %2 : $*AnyObject
+  dealloc_stack %2 : $*AnyObject
+  %999 = tuple ()
+  return %999 : $()
+}
+
+struct AClassWrapper {
+  var a: AClass
+  var b: AClass
+}
+
+// CHECK-LABEL: sil @testUnknownStoredValueUser : $@convention(thin) (@guaranteed AClass) -> @out AClass {
+// CHECK: bb0(%0 : $*AClass, %1 : $AClass):
+// CHECK:   [[ALLOC:%.*]] = alloc_stack $AClass
+// CHECK:   store %1 to %2 : $*AClass
+// CHECK:   [[STRUCT:%.*]] = struct $AClassWrapper (%1 : $AClass, %1 : $AClass)
+// CHECK:   copy_addr [[ALLOC]] to %0 : $*AClass
+// CHECK:   retain_value [[STRUCT]] : $AClassWrapper
+// CHECK:   destroy_addr [[ALLOC]] : $*AClass
+// CHECK-LABEL: } // end sil function 'testUnknownStoredValueUser'
+sil @testUnknownStoredValueUser : $@convention(thin) (@guaranteed AClass) -> (@out AClass) {
+bb0(%0 : $*AClass, %1 : $AClass):
+  %2 = alloc_stack $AClass
+  store %1 to %2 : $*AClass
+  %3 = struct $AClassWrapper (%1 : $AClass, %1 : $AClass)
+  copy_addr %2 to %0 : $*AClass
+  retain_value %3 : $AClassWrapper
+  destroy_addr %2 : $*AClass
+  dealloc_stack %2 : $*AClass
+  %999 = tuple ()
+  return %999 : $()
+}
diff --git a/test/SILOptimizer/retain_release_code_motion.sil b/test/SILOptimizer/retain_release_code_motion.sil
index 7b5a06b..e10fe72 100644
--- a/test/SILOptimizer/retain_release_code_motion.sil
+++ b/test/SILOptimizer/retain_release_code_motion.sil
@@ -593,3 +593,30 @@
   %26 = tuple ()
   return %26 : $()
 }
+
+// CHECK-LABEL: sil @detect_escape_of_bbarg
+// CHECK:      bb3({{.*}}):
+// CHECK-NEXT:   strong_retain
+// CHECK-NEXT:   apply
+// CHECK-NEXT:   strong_release
+sil @detect_escape_of_bbarg : $@convention(thin) () -> () {
+bb0:
+  %f = function_ref @use_C2 : $@convention(thin) (C2) -> ()
+  cond_br undef, bb1, bb2
+
+bb1:
+  %a = alloc_ref $C2
+  br bb3(%a: $C2, %a: $C2)
+
+bb2:
+  %b = alloc_ref $C2
+  br bb3(%b: $C2, %b: $C2)
+
+bb3(%p1: $C2, %p2: $C2):
+  strong_retain %p1: $C2 // This retain must not be moved over the apply
+  %c = apply %f(%p2) : $@convention(thin) (C2) -> ()
+  strong_release %p2: $C2
+  %10 = tuple ()
+  return %10 : $()
+}
+
diff --git a/test/SourceKit/Demangle/demangle.swift b/test/SourceKit/Demangle/demangle.swift
index 874ce28..4f3f215 100644
--- a/test/SourceKit/Demangle/demangle.swift
+++ b/test/SourceKit/Demangle/demangle.swift
@@ -1,15 +1,17 @@
-// RUN: %sourcekitd-test -req=demangle unmangled _TtBf80_  _TtP3foo3bar_ | %FileCheck %s
+// RUN: %sourcekitd-test -req=demangle unmangled _TtBf80_  _TtP3foo3bar_ '$S3Foo11AppDelegateC29applicationDidFinishLaunchingyy10Foundation12NotificationVF' | %FileCheck %s
 // CHECK:      START DEMANGLE
 // CHECK-NEXT: <empty>
 // CHECK-NEXT: Builtin.Float80
 // CHECK-NEXT: foo.bar
+// CHECK-NEXT: Foo.AppDelegate.applicationDidFinishLaunching(Foundation.Notification) -> ()
 // CHECK-NEXT: END DEMANGLE
 
-// RUN: %sourcekitd-test -req=demangle unmangled _TtBf80_  _TtP3foo3bar_ -simplified-demangling | %FileCheck %s -check-prefix=SIMPLIFIED
+// RUN: %sourcekitd-test -req=demangle unmangled _TtBf80_  _TtP3foo3bar_ '$S3Foo11AppDelegateC29applicationDidFinishLaunchingyy10Foundation12NotificationVF' -simplified-demangling | %FileCheck %s -check-prefix=SIMPLIFIED
 // SIMPLIFIED:      START DEMANGLE
 // SIMPLIFIED-NEXT: <empty>
 // SIMPLIFIED-NEXT: Builtin.Float80
 // SIMPLIFIED-NEXT: bar
+// SIMPLIFIED-NEXT: AppDelegate.applicationDidFinishLaunching(_:)
 // SIMPLIFIED-NEXT: END DEMANGLE
 
 // RUN: %sourcekitd-test -req=mangle Foo.Baru Swift.Beer | %FileCheck %s -check-prefix=MANGLED
diff --git a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
index ce58dcb..b313dbc 100644
--- a/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
+++ b/test/Syntax/Outputs/round_trip_parse_gen.swift.withkinds
@@ -401,7 +401,9 @@
   switch <IdentifierExpr>foo </IdentifierExpr>{<SwitchCase><SwitchCaseLabel>
   case <CaseItem><ExpressionPattern><IntegerLiteralExpr>1</IntegerLiteralExpr></ExpressionPattern>, </CaseItem><CaseItem><ExpressionPattern><IntegerLiteralExpr>2</IntegerLiteralExpr></ExpressionPattern>, </CaseItem><CaseItem><ExpressionPattern><IntegerLiteralExpr>3</IntegerLiteralExpr></ExpressionPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><Attribute>
   // This is rejected in Sema, but should be preserved by Syntax.
-  @unknown </Attribute><SwitchCaseLabel>case <CaseItem><ExpressionPattern><TupleExpr>(<TupleElement><IntegerLiteralExpr>42</IntegerLiteralExpr>, </TupleElement><TupleElement><PrefixOperatorExpr>-<IntegerLiteralExpr>42</IntegerLiteralExpr></PrefixOperatorExpr></TupleElement>) </TupleExpr></ExpressionPattern><WhereClause>where <SequenceExpr><IntegerLiteralExpr>1 </IntegerLiteralExpr><BinaryOperatorExpr>== </BinaryOperatorExpr><IntegerLiteralExpr>2</IntegerLiteralExpr></SequenceExpr></WhereClause></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase>
+  @unknown </Attribute><SwitchCaseLabel>case <CaseItem><ExpressionPattern><TupleExpr>(<TupleElement><IntegerLiteralExpr>42</IntegerLiteralExpr>, </TupleElement><TupleElement><PrefixOperatorExpr>-<IntegerLiteralExpr>42</IntegerLiteralExpr></PrefixOperatorExpr></TupleElement>) </TupleExpr></ExpressionPattern><WhereClause>where <SequenceExpr><IntegerLiteralExpr>1 </IntegerLiteralExpr><BinaryOperatorExpr>== </BinaryOperatorExpr><IntegerLiteralExpr>2</IntegerLiteralExpr></SequenceExpr></WhereClause></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><Attribute>
+  @garbage </Attribute><SwitchCaseLabel>case <CaseItem><ExpressionPattern><IntegerLiteralExpr>0</IntegerLiteralExpr></ExpressionPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase><SwitchCase><Attribute>
+  @garbage(foobar) </Attribute><SwitchCaseLabel>case <CaseItem><ExpressionPattern><PrefixOperatorExpr>-<IntegerLiteralExpr>1</IntegerLiteralExpr></PrefixOperatorExpr></ExpressionPattern></CaseItem>: </SwitchCaseLabel><BreakStmt>break</BreakStmt></SwitchCase>
   }</SwitchStmt>
 }</CodeBlock></FunctionDecl><ExtensionDecl>
 
@@ -457,4 +459,17 @@
   indirect </DeclModifier><DeclModifier>private </DeclModifier>enum E2<GenericParameterClause><<GenericParameter>T</GenericParameter>></GenericParameterClause><TypeInheritanceClause>: <InheritedType><SimpleTypeIdentifier>String </SimpleTypeIdentifier></InheritedType></TypeInheritanceClause><GenericWhereClause>where <ConformanceRequirement><SimpleTypeIdentifier>T</SimpleTypeIdentifier>: <SimpleTypeIdentifier>SomeProtocol </SimpleTypeIdentifier></ConformanceRequirement></GenericWhereClause><MemberDeclBlock>{<EnumCaseDecl>
     case <EnumCaseElement>foo, </EnumCaseElement><EnumCaseElement>bar, </EnumCaseElement><EnumCaseElement>baz</EnumCaseElement></EnumCaseDecl>
   }</MemberDeclBlock></EnumDecl>
-}</MemberDeclBlock></EnumDecl>
+}</MemberDeclBlock></EnumDecl><PrecedenceGroupDecl>
+
+precedencegroup FooPrecedence {<PrecedenceGroupRelation>
+  higherThan: <PrecedenceGroupNameElement>DefaultPrecedence, </PrecedenceGroupNameElement><PrecedenceGroupNameElement>UnknownPrecedence</PrecedenceGroupNameElement></PrecedenceGroupRelation><PrecedenceGroupAssignment>
+  assignment: false</PrecedenceGroupAssignment><PrecedenceGroupAssociativity>
+  associativity: none</PrecedenceGroupAssociativity>
+}</PrecedenceGroupDecl><PrecedenceGroupDecl>
+precedencegroup BarPrecedence {}</PrecedenceGroupDecl><PrecedenceGroupDecl>
+precedencegroup BazPrecedence {<PrecedenceGroupAssociativity>
+  associativity: left</PrecedenceGroupAssociativity><PrecedenceGroupAssignment>
+  assignment: true</PrecedenceGroupAssignment><PrecedenceGroupAssociativity>
+  associativity: right</PrecedenceGroupAssociativity><PrecedenceGroupRelation>
+  lowerThan: <PrecedenceGroupNameElement>DefaultPrecedence</PrecedenceGroupNameElement></PrecedenceGroupRelation>
+}</PrecedenceGroupDecl>
diff --git a/test/Syntax/round_trip_parse_gen.swift b/test/Syntax/round_trip_parse_gen.swift
index 8ac911f..0b448fe 100644
--- a/test/Syntax/round_trip_parse_gen.swift
+++ b/test/Syntax/round_trip_parse_gen.swift
@@ -402,6 +402,8 @@
   case 1, 2, 3: break
   // This is rejected in Sema, but should be preserved by Syntax.
   @unknown case (42, -42) where 1 == 2: break
+  @garbage case 0: break
+  @garbage(foobar) case -1: break
   }
 }
 
@@ -458,3 +460,16 @@
     case foo, bar, baz
   }
 }
+
+precedencegroup FooPrecedence {
+  higherThan: DefaultPrecedence, UnknownPrecedence
+  assignment: false
+  associativity: none
+}
+precedencegroup BarPrecedence {}
+precedencegroup BazPrecedence {
+  associativity: left
+  assignment: true
+  associativity: right
+  lowerThan: DefaultPrecedence
+}
diff --git a/test/lit.cfg b/test/lit.cfg
index f63128a..437c7cd 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -405,7 +405,7 @@
 # Note: %clang is the locally-built clang.
 # To get Xcode's clang, use %target-clang.
 config.substitutions.append( ('%clang',
-                              "%r %r" %
+                              "%r %s" %
                                 (config.clang, clang_mcp_opt)) )
 
 ###
diff --git a/test/multifile/Inputs/rdar-34584596-A.swift b/test/multifile/Inputs/rdar-34584596-A.swift
new file mode 100644
index 0000000..2bb693f
--- /dev/null
+++ b/test/multifile/Inputs/rdar-34584596-A.swift
@@ -0,0 +1,10 @@
+protocol Attributed {
+    var asAttributes: DefaultedAttributes? { get }
+}
+
+extension Attributed {
+    var asAttributes: DefaultedAttributes? { return self as? DefaultedAttributes }
+}
+
+struct Impl: Attributed {
+}
diff --git a/test/multifile/Inputs/rdar-34584596-B.swift b/test/multifile/Inputs/rdar-34584596-B.swift
new file mode 100644
index 0000000..d56b935
--- /dev/null
+++ b/test/multifile/Inputs/rdar-34584596-B.swift
@@ -0,0 +1,12 @@
+protocol DefaultedAttributes: Attributes {
+}
+
+extension DefaultedAttributes {
+    var attributes: [(title: String, description: String)] {
+        var attributes: [(title: String, description: String)] = []
+        return attributes
+    }
+}
+
+extension Impl: DefaultedAttributes {
+}
diff --git a/test/multifile/Inputs/rdar-34584596-C.swift b/test/multifile/Inputs/rdar-34584596-C.swift
new file mode 100644
index 0000000..6007259
--- /dev/null
+++ b/test/multifile/Inputs/rdar-34584596-C.swift
@@ -0,0 +1,3 @@
+protocol Attributes {
+    var attributes: [(title: String, description: String)] { get }
+}
diff --git a/test/multifile/Inputs/sr-285-other.swift b/test/multifile/Inputs/sr-285-other.swift
new file mode 100644
index 0000000..c949408
--- /dev/null
+++ b/test/multifile/Inputs/sr-285-other.swift
@@ -0,0 +1,34 @@
+// Natural numbers encoded as types:
+protocol NaturalNumberType { static var intValue: Int { get } }
+struct NaturalNumberZero : NaturalNumberType {
+    static var intValue: Int { return 0 }
+}
+struct NaturalNumberSuccessorOf<T: NaturalNumberType> : NaturalNumberType {
+    static var intValue: Int { return T.intValue + 1 }
+}
+// See FourFloats below for an example of how to use the following:
+protocol StaticStorageType {
+    associatedtype Element
+    associatedtype Count: NaturalNumberType
+}
+extension StaticStorageType {
+    typealias Successor = StaticStorageSuccessorOf<Self>
+}
+struct StaticStorageOfOne<E> : StaticStorageType {
+    typealias Element = E
+    typealias Count = NaturalNumberZero
+    var storage: Element
+}
+struct StaticStorageSuccessorOf<T: StaticStorageType> : StaticStorageType {
+    typealias Element = T.Element
+    typealias Count = NaturalNumberSuccessorOf<T.Count>
+    var storage: (Element, T)
+}
+// Using the StaticStorage-thing:
+typealias FourFloats = StaticStorageOfOne<Float>.Successor.Successor.Successor
+
+//-----------------------------------------------------------------------------
+// This function works and will print the number of bytes of FourFloats, ie 16.
+// But compiler will crash if an identical function is declared in main.swift.
+//-----------------------------------------------------------------------------
+func definedInOther() { print(MemoryLayout<FourFloats>.size) }
diff --git a/test/multifile/protocol-conformance-rdar-34584596.swift b/test/multifile/protocol-conformance-rdar-34584596.swift
new file mode 100644
index 0000000..5383d62
--- /dev/null
+++ b/test/multifile/protocol-conformance-rdar-34584596.swift
@@ -0,0 +1,2 @@
+// RUN: not --crash %target-swift-frontend -emit-ir -O -o - -primary-file %S/Inputs/rdar-34584596-A.swift %S/Inputs/rdar-34584596-B.swift %S/Inputs/rdar-34584596-C.swift -module-name main
+
diff --git a/test/multifile/protocol-conformance-sr-285.swift b/test/multifile/protocol-conformance-sr-285.swift
new file mode 100644
index 0000000..8febff2
--- /dev/null
+++ b/test/multifile/protocol-conformance-sr-285.swift
@@ -0,0 +1,6 @@
+// RUN: not --crash %target-swift-frontend -emit-ir -o - -primary-file %s %S/Inputs/sr-285-other.swift -module-name main
+
+// SR-285: Crash in IR generation due to missing conformance.
+func definedInMain() { print(MemoryLayout<FourFloats>.size) }
+
+let d = definedInOther()
diff --git a/test/stdlib/PrintFloat.swift.gyb b/test/stdlib/PrintFloat.swift.gyb
index cc3b59e..135841e 100644
--- a/test/stdlib/PrintFloat.swift.gyb
+++ b/test/stdlib/PrintFloat.swift.gyb
@@ -288,6 +288,7 @@
   (0x1.63ed4a60c9c91p+324, "4.751595491707413e+97")
 ]
 
+#if !os(Windows) && (arch(i386) || arch(x86_64))
 // Float80 found via Errol technique.
 //
 // As with Double, except for Float80.  The original list in this
@@ -334,6 +335,7 @@
   (0xd.4d512260c548f17p+242, "9.401053474771583868e+73"),
   (0xc.9240ee0f9d5e4d6p+252, "9.097859174935622588e+76"),
 ]
+#endif
 
 let PrintTests = TestSuite("FloatingPointPrinting")
 
@@ -544,7 +546,7 @@
   // Every power of 10 should print with only a single digit '1'
   for power in -45 ... 38 {
     let s: String
-    if power < -4 || power > 5 { // Exponential form
+    if power < -4 || power > 7 { // Exponential form
       s = exponentialPowerOfTen(power)
     } else if power < 0 { // Fractional decimal form
       s = "0." + String(repeating: "0", count: -power - 1) + "1"
@@ -562,8 +564,14 @@
     expectAccurateDescription(f.nextUp)
   }
 
-  // Check that the formatter chooses exponential
-  // format when it should:
+  // Float can represent all integers -(2^24)...(2^24)
+  let maxDecimalForm = Float(1 << 24)
+  expectDescription("16777216.0", maxDecimalForm)
+  expectDescription("-16777216.0", -maxDecimalForm)
+  // Outside of that range, use exponential form
+  expectDescription("1.6777218e+07", maxDecimalForm.nextUp)
+  expectDescription("-1.6777218e+07", -maxDecimalForm.nextUp)
+
   expectDescription("1.00001", asFloat32(1.00001))
   expectDescription("1.25e+17", asFloat32(125000000000000000.0))
   expectDescription("1.25e+16", asFloat32(12500000000000000.0))
@@ -575,8 +583,8 @@
   expectDescription("1.25e+10", asFloat32(12500000000.0))
   expectDescription("1.25e+09", asFloat32(1250000000.0))
   expectDescription("1.25e+08", asFloat32(125000000.0))
-  expectDescription("1.25e+07", asFloat32(12500000.0))
-  expectDescription("1.25e+06", asFloat32(1250000.0))
+  expectDescription("12500000.0", asFloat32(12500000.0))
+  expectDescription("1250000.0", asFloat32(1250000.0))
   expectDescription("125000.0", asFloat32(125000.0))
   expectDescription("12500.0",  asFloat32(12500.0))
   expectDescription("1250.0",   asFloat32(1250.0))
@@ -660,7 +668,7 @@
   // We know how every power of 10 should print
   for power in -323 ... 308 {
     let s: String
-    if power < -4 || power > 14 { // Exponential form
+    if power < -4 || power > 15 { // Exponential form
       s = exponentialPowerOfTen(power)
     } else if power < 0 { // Fractional decimal form
       s = "0." + String(repeating: "0", count: -power - 1) + "1"
@@ -687,12 +695,18 @@
     }
   }
 
-  // Check that the formatter chooses exponential
-  // format when it should:
+  // Double can represent all integers -(2^53)...(2^53)
+  let maxDecimalForm = Double((1 as Int64) << 53)
+  expectDescription("9007199254740992.0", maxDecimalForm)
+  expectDescription("-9007199254740992.0", -maxDecimalForm)
+  // Outside of that range, we use exponential form:
+  expectDescription("9.007199254740994e+15", maxDecimalForm.nextUp)
+  expectDescription("-9.007199254740994e+15", -maxDecimalForm.nextUp)
+
   expectDescription("1.00000000000001", asFloat64(1.00000000000001))
   expectDescription("1.25e+17", asFloat64(125000000000000000.0))
   expectDescription("1.25e+16", asFloat64(12500000000000000.0))
-  expectDescription("1.25e+15", asFloat64(1250000000000000.0))
+  expectDescription("1250000000000000.0", asFloat64(1250000000000000.0))
   expectDescription("125000000000000.0", asFloat64(125000000000000.0))
   expectDescription("12500000000000.0", asFloat64(12500000000000.0))
   expectDescription("1250000000000.0", asFloat64(1250000000000.0))
@@ -769,7 +783,7 @@
   // We know how every power of 10 should print
   for power in -4950 ... 4932 {
     let s: String
-    if power < -4 || power > 17 { // Exponential form
+    if power < -4 || power > 19 { // Exponential form
       s = exponentialPowerOfTen(power)
     } else if power < 0 { // Fractional decimal form
       s = "0." + String(repeating: "0", count: -power - 1) + "1"
@@ -794,11 +808,19 @@
     }
   }
 
-  // Check that the formatter chooses exponential
-  // format when it should:
+  // Float80 can represent all integers -(2^64)...(2^64):
+  let maxDecimalForm = Float80(UInt64.max) + 1.0
+  expectDescription("18446744073709551616.0", maxDecimalForm)
+  expectDescription("-18446744073709551616.0", -maxDecimalForm)
+  // Outside of that range, use exponential form
+  expectDescription("1.8446744073709551618e+19", maxDecimalForm.nextUp)
+  expectDescription("-1.8446744073709551618e+19", -maxDecimalForm.nextUp)
+
   expectDescription("1.00000000000000001", asFloat80(1.00000000000000001))
-  expectDescription("1.25e+19", asFloat80(12500000000000000000.0))
-  expectDescription("1.25e+18", asFloat80(1250000000000000000.0))
+  expectDescription("1.25e+21", asFloat80(1250000000000000000000.0))
+  expectDescription("1.25e+20", asFloat80(125000000000000000000.0))
+  expectDescription("12500000000000000000.0", asFloat80(12500000000000000000.0))
+  expectDescription("1250000000000000000.0", asFloat80(1250000000000000000.0))
   expectDescription("125000000000000000.0", asFloat80(125000000000000000.0))
   expectDescription("12500000000000000.0", asFloat80(12500000000000000.0))
   expectDescription("1250000000000000.0", asFloat80(1250000000000000.0))
diff --git a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
index 6484aef..ae3236a 100644
--- a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
@@ -1663,10 +1663,13 @@
     llvm::StringRef inputContents = input.get()->getBuffer();
 
     // This doesn't handle Unicode symbols, but maybe that's okay.
-    llvm::Regex maybeSymbol("(_T|" MANGLING_PREFIX_STR ")[_a-zA-Z0-9$]+");
+    // Also accept the future mangling prefix.
+    llvm::Regex maybeSymbol("(_T|_?\\$[Ss])[_a-zA-Z0-9$.]+");
     llvm::SmallVector<llvm::StringRef, 1> matches;
     while (maybeSymbol.match(inputContents, &matches)) {
       addName(matches.front());
+      auto offset = matches.front().data() - inputContents.data();
+      inputContents = inputContents.substr(offset + matches.front().size());
     }
 
   } else {
diff --git a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
index ffe43af..9df7cba 100644
--- a/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
+++ b/tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp
@@ -1230,13 +1230,6 @@
 };
 } // end anonymous namespace
 
-static bool isSwiftPrefixed(StringRef MangledName) {
-  if (MangledName.size() < 2)
-    return false;
-  return MangledName[0] == '_' &&
-         (MangledName[1] == 'T' || MangledName[1] == MANGLING_PREFIX_STR[1]);
-}
-
 static sourcekitd_response_t demangleNames(ArrayRef<const char *> MangledNames,
                                            bool Simplified) {
   swift::Demangle::DemangleOptions DemangleOptions;
@@ -1246,7 +1239,7 @@
   }
 
   auto getDemangledName = [&](StringRef MangledName) -> std::string {
-    if (!isSwiftPrefixed(MangledName))
+    if (!swift::Demangle::isSwiftSymbol(MangledName))
       return std::string(); // Not a mangled name
 
     std::string Result = swift::Demangle::demangleSymbolAsString(
@@ -2753,4 +2746,4 @@
   } else {
     trace::unregisterConsumer(&compileConsumer);
   }
-}
\ No newline at end of file
+}
diff --git a/tools/swift-demangle/swift-demangle.cpp b/tools/swift-demangle/swift-demangle.cpp
index 00e2160..b6ddf19 100644
--- a/tools/swift-demangle/swift-demangle.cpp
+++ b/tools/swift-demangle/swift-demangle.cpp
@@ -174,7 +174,6 @@
 static int demangleSTDIN(const swift::Demangle::DemangleOptions &options) {
   // This doesn't handle Unicode symbols, but maybe that's okay.
   // Also accept the future mangling prefix.
-  // TODO: remove the "_S" as soon as MANGLING_PREFIX_STR gets "_S".
   llvm::Regex maybeSymbol("(_T|_?\\$[Ss])[_a-zA-Z0-9$.]+");
 
   swift::Demangle::Context DCtx;
diff --git a/utils/build_swift/driver_arguments.py b/utils/build_swift/driver_arguments.py
index c8364c4..bd99cc4 100644
--- a/utils/build_swift/driver_arguments.py
+++ b/utils/build_swift/driver_arguments.py
@@ -448,6 +448,9 @@
     option('--disable-guaranteed-normal-arguments', store_true,
            help='Disable guaranteed normal arguments')
 
+    option('--enable-stdlibcore-exclusivity-checking', store_true,
+           help='Enable exclusivity checking in stdlibCore')
+
     option('--force-optimized-typechecker', store_true,
            help='Force the type checker to be built with '
                 'optimization')
diff --git a/utils/build_swift/tests/expected_options.py b/utils/build_swift/tests/expected_options.py
index 3b687b5..7e397ca 100644
--- a/utils/build_swift/tests/expected_options.py
+++ b/utils/build_swift/tests/expected_options.py
@@ -113,6 +113,7 @@
     'enable_lsan': False,
     'enable_sil_ownership': False,
     'disable_guaranteed_normal_arguments': False,
+    'enable_stdlibcore_exclusivity_checking': False,
     'enable_tsan': False,
     'enable_tsan_runtime': False,
     'enable_ubsan': False,
@@ -384,6 +385,7 @@
     SetTrueOption('--dry-run'),
     SetTrueOption('--enable-sil-ownership'),
     SetTrueOption('--disable-guaranteed-normal-arguments'),
+    SetTrueOption('--enable-stdlibcore-exclusivity-checking'),
     SetTrueOption('--force-optimized-typechecker'),
     SetTrueOption('--ios'),
     SetTrueOption('--llbuild', dest='build_llbuild'),
diff --git a/utils/gyb_syntax_support/DeclNodes.py b/utils/gyb_syntax_support/DeclNodes.py
index 3733aba..02dbd59 100644
--- a/utils/gyb_syntax_support/DeclNodes.py
+++ b/utils/gyb_syntax_support/DeclNodes.py
@@ -591,4 +591,123 @@
                    The cases and other members of this enum.
                    ''')
          ]),
+
+    # precedence-group-decl -> attributes? modifiers? 'precedencegroup'
+    #                            identifier '{' precedence-group-attribute-list
+    #                            '}'
+    Node('PrecedenceGroupDecl', kind='Decl', traits=['IdentifiedDecl'],
+         description='A Swift `precedencegroup` declaration.',
+         children=[
+             Child('Attributes', kind='AttributeList', is_optional=True,
+                   description='''
+                   The attributes applied to the 'precedencegroup' declaration.
+                   '''),
+             Child('Modifiers', kind='ModifierList', is_optional=True,
+                   description='''
+                   The declaration modifiers applied to the 'precedencegroup'
+                   declaration.
+                   '''),
+             Child('PrecedencegroupKeyword', kind='PrecedencegroupToken'),
+             Child('Identifier', kind='IdentifierToken',
+                   description='''
+                   The name of this precedence group.
+                   '''),
+             Child('LeftBrace', kind='LeftBraceToken'),
+             Child('GroupAttributes', kind='PrecedenceGroupAttributeList',
+                   description='''
+                   The characteristics of this precedence group.
+                   '''),
+             Child('RightBrace', kind='RightBraceToken'),
+         ]),
+
+    # precedence-group-attribute-list ->
+    #     (precedence-group-relation | precedence-group-assignment |
+    #      precedence-group-associativity )*
+    Node('PrecedenceGroupAttributeList', kind='SyntaxCollection',
+         element='Syntax',
+         element_choices=[
+             'PrecedenceGroupRelation',
+             'PrecedenceGroupAssignment',
+             'PrecedenceGroupAssociativity'
+         ]),
+
+    # precedence-group-relation ->
+    #     ('higherThan' | 'lowerThan') ':' precedence-group-name-list
+    Node('PrecedenceGroupRelation', kind='Syntax',
+         description='''
+         Specify the new precedence group's relation to existing precedence
+         groups.
+         ''',
+         children=[
+             Child('HigherThanOrLowerThan', kind='IdentifierToken',
+                   text_choices=[
+                      'higherThan', 'lowerThan',
+                   ],
+                   description='''
+                   The relation to specified other precedence groups.
+                   '''),
+             Child('Colon', kind='ColonToken'),
+             Child('OtherNames', kind='PrecedenceGroupNameList',
+                   description='''
+                   The name of other precedence group to which this precedence
+                   group relates.
+                   '''),
+         ]),
+
+    # precedence-group-name-list ->
+    #    identifier (',' identifier)*
+    Node('PrecedenceGroupNameList', kind='SyntaxCollection',
+         element='PrecedenceGroupNameElement'),
+    Node('PrecedenceGroupNameElement', kind='Syntax',
+         children=[
+             Child('Name', kind='IdentifierToken'),
+             Child('TrailingComma', kind='CommaToken',
+                   is_optional=True),
+         ]),
+
+    # precedence-group-assignment ->
+    #     'assignment' ':' ('true' | 'false')
+    Node('PrecedenceGroupAssignment', kind='Syntax',
+         description='''
+         Specifies the precedence of an operator when used in an operation
+         that includes optional chaining.
+         ''',
+         children=[
+             Child('AssignmentKeyword', kind='IdentifierToken',
+                   text_choices=['assignment']),
+             Child('Colon', kind='ColonToken'),
+             Child('Flag', kind='Token',
+                   token_choices=[
+                       'TrueToken',
+                       'FalseToken',
+                   ],
+                   description='''
+                   When true, an operator in the corresponding precedence group
+                   uses the same grouping rules during optional chaining as the
+                   assignment operators from the standard library. Otherwise,
+                   operators in the precedence group follows the same optional
+                   chaining rules as operators that don't perform assignment.
+                   '''),
+         ]),
+
+    # precedence-group-associativity ->
+    #     'associativity' ':' ('left' | 'right' | 'none')
+    Node('PrecedenceGroupAssociativity', kind='Syntax',
+         description='''
+         Specifies how a sequence of operators with the same precedence level
+         are grouped together in the absence of grouping parentheses.
+         ''',
+         children=[
+             Child('AssociativityKeyword', kind='IdentifierToken',
+                   text_choices=['associativity']),
+             Child('Colon', kind='ColonToken'),
+             Child('Value', kind='IdentifierToken',
+                   text_choices=['left', 'right', 'none'],
+                   description='''
+                   Operators that are `left`-associative group left-to-right.
+                   Operators that are `right`-associative group right-to-left.
+                   Operators that are specified with an associativity of `none`
+                   don't associate at all
+                   '''),
+         ]),
 ]
diff --git a/utils/gyb_syntax_support/StmtNodes.py b/utils/gyb_syntax_support/StmtNodes.py
index 8bf0d28..1691854 100644
--- a/utils/gyb_syntax_support/StmtNodes.py
+++ b/utils/gyb_syntax_support/StmtNodes.py
@@ -274,13 +274,6 @@
              Child('Colon', kind='ColonToken'),
          ]),
 
-    # switch-unknown-label -> 'unknown' ':'
-    Node('SwitchUnknownLabel', kind='Syntax',
-         children=[
-             Child('UnknownKeyword', kind='Token'),
-             Child('Colon', kind='ColonToken'),
-         ]),
-
     # case-item -> pattern where-clause? ','?
     Node('CaseItem', kind='Syntax',
          traits=['WithTrailingComma'],
diff --git a/utils/swift_build_support/swift_build_support/products/swift.py b/utils/swift_build_support/swift_build_support/products/swift.py
index 374a0cb..0782249 100644
--- a/utils/swift_build_support/swift_build_support/products/swift.py
+++ b/utils/swift_build_support/swift_build_support/products/swift.py
@@ -43,6 +43,9 @@
         # with optimization.
         self.cmake_options.extend(self._force_optimized_typechecker_flags)
 
+        # Add any exclusivity checking flags for stdlibcore.
+        self.cmake_options.extend(self._stdlibcore_exclusivity_checking_flags)
+
     @property
     def _runtime_sanitizer_flags(self):
         sanitizer_list = []
@@ -127,3 +130,11 @@
         if not self.args.force_optimized_typechecker:
             return ['-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE']
         return ['-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=TRUE']
+
+    @property
+    def _stdlibcore_exclusivity_checking_flags(self):
+        # This is just to get around 80 column limitations.
+        result = '-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING={}'
+        if not self.args.enable_stdlibcore_exclusivity_checking:
+            return [result.format("FALSE")]
+        return [result.format("TRUE")]
diff --git a/utils/swift_build_support/tests/products/test_swift.py b/utils/swift_build_support/tests/products/test_swift.py
index 9048335..a32be03 100644
--- a/utils/swift_build_support/tests/products/test_swift.py
+++ b/utils/swift_build_support/tests/products/test_swift.py
@@ -57,7 +57,8 @@
             benchmark_num_o_iterations=3,
             enable_sil_ownership=False,
             disable_guaranteed_normal_arguments=True,
-            force_optimized_typechecker=False)
+            force_optimized_typechecker=False,
+            enable_stdlibcore_exclusivity_checking=False)
 
         # Setup shell
         shell.dry_run = True
@@ -84,11 +85,14 @@
             toolchain=self.toolchain,
             source_dir='/path/to/src',
             build_dir='/path/to/build')
-        self.assertEqual(set(swift.cmake_options), set([
-                         '-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE',
-                         '-DSWIFT_STDLIB_ENABLE_SIL_OWNERSHIP=FALSE',
-                         '-DSWIFT_ENABLE_GUARANTEED_NORMAL_ARGUMENTS=FALSE',
-                         '-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE']))
+        expected = [
+            '-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE',
+            '-DSWIFT_STDLIB_ENABLE_SIL_OWNERSHIP=FALSE',
+            '-DSWIFT_ENABLE_GUARANTEED_NORMAL_ARGUMENTS=FALSE',
+            '-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE',
+            '-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING=FALSE'
+        ]
+        self.assertEqual(set(swift.cmake_options), set(expected))
 
     def test_swift_runtime_tsan(self):
         self.args.enable_tsan_runtime = True
@@ -97,12 +101,15 @@
             toolchain=self.toolchain,
             source_dir='/path/to/src',
             build_dir='/path/to/build')
-        flags_set = set(['-DSWIFT_RUNTIME_USE_SANITIZERS=Thread',
-                         '-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE',
-                         '-DSWIFT_STDLIB_ENABLE_SIL_OWNERSHIP=FALSE',
-                         '-DSWIFT_ENABLE_GUARANTEED_NORMAL_ARGUMENTS=FALSE',
-                         '-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE'])
-        self.assertEqual(set(swift.cmake_options), flags_set)
+        flags_set = [
+            '-DSWIFT_RUNTIME_USE_SANITIZERS=Thread',
+            '-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE',
+            '-DSWIFT_STDLIB_ENABLE_SIL_OWNERSHIP=FALSE',
+            '-DSWIFT_ENABLE_GUARANTEED_NORMAL_ARGUMENTS=FALSE',
+            '-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=FALSE',
+            '-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING=FALSE'
+        ]
+        self.assertEqual(set(swift.cmake_options), set(flags_set))
 
     def test_swift_compiler_vendor_flags(self):
         self.args.compiler_vendor = "none"
@@ -311,3 +318,15 @@
             ['-DSWIFT_FORCE_OPTIMIZED_TYPECHECKER=TRUE'],
             [x for x in swift.cmake_options
              if 'SWIFT_FORCE_OPTIMIZED_TYPECHECKER' in x])
+
+    def test_exclusivity_checking_flags(self):
+        self.args.enable_stdlibcore_exclusivity_checking = True
+        swift = Swift(
+            args=self.args,
+            toolchain=self.toolchain,
+            source_dir='/path/to/src',
+            build_dir='/path/to/build')
+        self.assertEqual(
+            ['-DSWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING=TRUE'],
+            [x for x in swift.cmake_options
+             if 'SWIFT_STDLIB_ENABLE_STDLIBCORE_EXCLUSIVITY_CHECKING' in x])
diff --git a/validation-test/compiler_crashers_2_fixed/0152-sr-7397.swift b/validation-test/compiler_crashers_2_fixed/0152-sr-7397.swift
new file mode 100644
index 0000000..6717466
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0152-sr-7397.swift
@@ -0,0 +1,19 @@
+// RUN: %target-typecheck-verify-swift %s
+
+protocol _UnicodeParser_ {
+    associatedtype Encoding: _UnicodeEncoding_
+}
+protocol _UnicodeEncoding_ {
+    associatedtype CodeUnit : BinaryInteger_
+    associatedtype ForwardParser : _UnicodeParser_
+      where ForwardParser.Encoding == Self
+
+}
+protocol BinaryInteger_ {
+    associatedtype Words: Collection_ where Words.Index == Int_
+}
+protocol Collection_ {
+    associatedtype Index: Comparable_
+}
+protocol Comparable_ {}
+struct Int_: Comparable_ {}