Merge pull request #19392 from xedin/use-unique_ptr-for-worklist

[CSStep] Switch to use `std::unique_ptr` for work list
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 71a8090..cf33184 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -141,7 +141,8 @@
   global ::= protocol 'TL'               // protocol requirements base descriptor
   global ::= assoc-type-name 'Tl'        // associated type descriptor
   global ::= assoc-type-name 'TM'        // default associated type witness accessor
-
+  global ::= type assoc-type-path protocol 'Tn' // associated conformance descriptor
+  global ::= type assoc-type-path protocol 'TN' // default associated conformance witness accessor
 
   REABSTRACT-THUNK-TYPE ::= 'R'          // reabstraction thunk helper function
   REABSTRACT-THUNK-TYPE ::= 'r'          // reabstraction thunk
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index ff0ee4a..370dcf8 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -3979,6 +3979,19 @@
   /// Record the default witness for a requirement.
   void setDefaultWitness(ValueDecl *requirement, Witness witness);
 
+  /// Returns the default associated conformance witness for an associated
+  /// type, or \c None if there is no default.
+  Optional<ProtocolConformanceRef> getDefaultAssociatedConformanceWitness(
+                                              CanType association,
+                                              ProtocolDecl *requirement) const;
+
+  /// Set the default associated conformance witness for the given
+  /// associated conformance.
+  void setDefaultAssociatedConformanceWitness(
+                                            CanType association,
+                                            ProtocolDecl *requirement,
+                                            ProtocolConformanceRef conformance);
+
   /// Retrieve the name to use for this protocol when interoperating
   /// with the Objective-C runtime.
   StringRef getObjCRuntimeName(llvm::SmallVectorImpl<char> &buffer) const;
diff --git a/include/swift/AST/DiagnosticsModuleDiffer.def b/include/swift/AST/DiagnosticsModuleDiffer.def
index c5b0a7d..9f216d1 100644
--- a/include/swift/AST/DiagnosticsModuleDiffer.def
+++ b/include/swift/AST/DiagnosticsModuleDiffer.def
@@ -52,6 +52,10 @@
 
 ERROR(decl_new_attr,none,"%0 is now %1", (StringRef, StringRef))
 
+ERROR(decl_reorder,none,"%0 in a non-resilient type changes position from %1 to %2", (StringRef, unsigned, unsigned))
+
+ERROR(decl_added,none,"%0 is added to a non-resilient type", (StringRef))
+
 #ifndef DIAG_NO_UNDEF
 # if defined(DIAG)
 #  undef DIAG
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index e8653c3..d85dd41 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1696,6 +1696,11 @@
 NOTE(witness_fix_access,none,
      "mark the %0 as '%select{%error|fileprivate|internal|public|%error}1' to "
      "satisfy the requirement", (DescriptiveDeclKind, AccessLevel))
+WARNING(assoc_type_default_conformance_failed,none,
+        "default type %0 for associated type %1 does not satisfy constraint "
+        "%2: %3", (Type, DeclName, Type, Type))
+NOTE(assoc_type_default_here,none,
+     "associated type %0 has default type %1 written here", (DeclName, Type))
 
 ERROR(protocol_access,none,
       "%select{protocol must be declared %select{"
diff --git a/include/swift/AST/LazyResolver.h b/include/swift/AST/LazyResolver.h
index a600fdf..b2911aa 100644
--- a/include/swift/AST/LazyResolver.h
+++ b/include/swift/AST/LazyResolver.h
@@ -63,9 +63,6 @@
   /// Resolve the generic environment of the given protocol.
   virtual void resolveProtocolEnvironment(ProtocolDecl *proto) = 0;
 
-  /// Bind an extension to its extended type.
-  virtual void bindExtension(ExtensionDecl *ext) = 0;
-
   /// Resolve the type of an extension.
   ///
   /// This can be called to ensure that the members of an extension can be
diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def
index cb1d6f3..ed283d6 100644
--- a/include/swift/Demangling/DemangleNodes.def
+++ b/include/swift/Demangling/DemangleNodes.def
@@ -211,6 +211,7 @@
 NODE(MethodDescriptor)
 NODE(ProtocolRequirementsBaseDescriptor)
 NODE(AssociatedConformanceDescriptor)
+NODE(DefaultAssociatedConformanceAccessor)
 NODE(AssociatedTypeDescriptor)
 NODE(ThrowsAnnotation)
 NODE(EmptyList)
diff --git a/include/swift/IDE/DigesterEnums.def b/include/swift/IDE/DigesterEnums.def
index 0092af8..f730523 100644
--- a/include/swift/IDE/DigesterEnums.def
+++ b/include/swift/IDE/DigesterEnums.def
@@ -100,6 +100,7 @@
 KEY(mutating)
 KEY(static)
 KEY(deprecated)
+KEY(implicit)
 KEY(typeAttributes)
 KEY(declAttributes)
 KEY(declKind)
@@ -109,6 +110,7 @@
 KEY(conformingProtocols)
 KEY(enumRawTypeName)
 KEY(genericSig)
+KEY(fixedbinaryorder)
 
 KNOWN_TYPE(Optional)
 KNOWN_TYPE(ImplicitlyUnwrappedOptional)
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index e5d486f..2e99868 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -213,6 +213,11 @@
     /// is stored in the data.
     AssociatedConformanceDescriptor,
 
+    /// A default accessor for an associated conformance of a protocol.
+    /// The pointer is a ProtocolDecl*; the index of the associated conformance
+    /// is stored in the data.
+    DefaultAssociatedConformanceAccessor,
+
     /// A function which returns the default type metadata for the associated
     /// type of a protocol.  The secondary pointer is a ProtocolDecl*.
     /// The index of the associated type declaration is stored in the data.
@@ -795,14 +800,13 @@
   }
 
   static LinkEntity
-  forAssociatedConformanceDescriptor(ProtocolDecl *proto,
-                                     CanType associatedType,
-                                     ProtocolDecl *associatedProtocol) {
+  forAssociatedConformanceDescriptor(AssociatedConformance conformance) {
     LinkEntity entity;
     entity.setForProtocolAndAssociatedConformance(
         Kind::AssociatedConformanceDescriptor,
-        proto, associatedType,
-        associatedProtocol);
+        conformance.getSourceProtocol(),
+        conformance.getAssociation(),
+        conformance.getAssociatedRequirement());
     return entity;
   }
 
@@ -835,6 +839,17 @@
     return entity;
   }
 
+  static LinkEntity
+  forDefaultAssociatedConformanceAccessor(AssociatedConformance conformance) {
+    LinkEntity entity;
+    entity.setForProtocolAndAssociatedConformance(
+        Kind::DefaultAssociatedConformanceAccessor,
+        conformance.getSourceProtocol(),
+        conformance.getAssociation(),
+        conformance.getAssociatedRequirement());
+    return entity;
+  }
+
   static LinkEntity forReflectionBuiltinDescriptor(CanType type) {
     LinkEntity entity;
     entity.setForType(Kind::ReflectionBuiltinDescriptor, type);
@@ -925,7 +940,8 @@
                        LINKENTITY_GET_FIELD(Data, AssociatedConformanceIndex));
     }
 
-    assert(getKind() == Kind::AssociatedConformanceDescriptor);
+    assert(getKind() == Kind::AssociatedConformanceDescriptor ||
+           getKind() == Kind::DefaultAssociatedConformanceAccessor);
     return getAssociatedConformanceByIndex(
              cast<ProtocolDecl>(getDecl()),
              LINKENTITY_GET_FIELD(Data, AssociatedConformanceIndex));
diff --git a/include/swift/Parse/Lexer.h b/include/swift/Parse/Lexer.h
index d71c0d6..35f172e 100644
--- a/include/swift/Parse/Lexer.h
+++ b/include/swift/Parse/Lexer.h
@@ -506,9 +506,10 @@
     return diagnose(Loc, Diagnostic(DiagID, std::forward<ArgTypes>(Args)...));
   }
 
-  void formToken(tok Kind, const char *TokStart, bool IsMultilineString = false,
-                 unsigned CustomDelimiterLen = 0);
+  void formToken(tok Kind, const char *TokStart);
   void formEscapedIdentifierToken(const char *TokStart);
+  void formStringLiteralToken(const char *TokStart, bool IsMultilineString,
+                              unsigned CustomDelimiterLen);
 
   /// Advance to the end of the line.
   /// If EatNewLine is true, CurPtr will be at end of newline character.
diff --git a/include/swift/Parse/Token.h b/include/swift/Parse/Token.h
index 6cd0fc9..59e3e45 100644
--- a/include/swift/Parse/Token.h
+++ b/include/swift/Parse/Token.h
@@ -220,6 +220,21 @@
     default: return false;
     }
   }
+
+  /// \brief True if the string literal token is multiline.
+  bool isMultilineString() const {
+    return MultilineString;
+  }
+  /// \brief Count of extending escaping '#'.
+  unsigned getCustomDelimiterLen() const {
+    return CustomDelimiterLen;
+  }
+  /// \brief Set characteristics of string literal token.
+  void setStringLiteral(bool IsMultilineString, unsigned CustomDelimiterLen) {
+    assert(Kind == tok::string_literal);
+    this->MultilineString = IsMultilineString;
+    this->CustomDelimiterLen = CustomDelimiterLen;
+  }
   
   /// getLoc - Return a source location identifier for the specified
   /// offset in the current file.
@@ -268,25 +283,16 @@
   void setText(StringRef T) { Text = T; }
 
   /// \brief Set the token to the specified kind and source range.
-  void setToken(tok K, StringRef T, unsigned CommentLength = 0,
-                bool IsMultilineString = false, unsigned CustomDelimiterLen = 0) {
+  void setToken(tok K, StringRef T, unsigned CommentLength = 0) {
     Kind = K;
     Text = T;
     this->CommentLength = CommentLength;
     EscapedIdentifier = false;
-    this->MultilineString = IsMultilineString;
-    this->CustomDelimiterLen = CustomDelimiterLen;
+    this->MultilineString = false;
+    this->CustomDelimiterLen = 0;
     assert(this->CustomDelimiterLen == CustomDelimiterLen &&
            "custom string delimiter length > 255");
   }
-
-  bool isMultilineString() const {
-    return MultilineString;
-  }
-
-  unsigned getCustomDelimiterLen() const {
-    return CustomDelimiterLen;
-  }
 };
   
 } // end namespace swift
diff --git a/include/swift/Serialization/Validation.h b/include/swift/Serialization/Validation.h
index 1942d5e..723bbb9 100644
--- a/include/swift/Serialization/Validation.h
+++ b/include/swift/Serialization/Validation.h
@@ -20,6 +20,7 @@
 
 namespace swift {
 
+class ModuleFile;
 enum class ResilienceStrategy : unsigned;
 
 namespace serialization {
@@ -147,6 +148,24 @@
 validateSerializedAST(StringRef data,
                       ExtendedValidationInfo *extendedInfo = nullptr);
 
+/// Emit diagnostics explaining a failure to load a serialized AST.
+///
+/// - \p Ctx is an AST context through which any diagnostics are surfaced.
+/// - \p diagLoc is the (possibly invalid) location used in the diagnostics.
+/// - \p loadInfo and \p extendedInfo describe the attempt to load an AST
+///   (\ref validateSerializedAST). Note that loadInfo.Status must not be
+///   Status::Valid.
+/// - \p moduleBufferID and \p moduleDocBufferID are the buffer identifiers
+///   of the module input and doc input buffers respectively (\ref 
+///   SerializedModuleLoader::loadAST, \ref ModuleFile::load).
+/// - \p loadedModuleFile is an invalid loaded module.
+/// - \p ModuleName is the name used to refer to the module in diagnostics.
+void diagnoseSerializedASTLoadFailure(
+    ASTContext &Ctx, SourceLoc diagLoc, const ValidationInfo &loadInfo,
+    const ExtendedValidationInfo &extendedInfo, StringRef moduleBufferID,
+    StringRef moduleDocBufferID, ModuleFile *loadedModuleFile,
+    Identifier ModuleName);
+
 } // end namespace serialization
 } // end namespace swift
 
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index ea0de37..b0cea9a 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -285,6 +285,11 @@
   llvm::DenseMap<std::pair<const ProtocolDecl *, AssociatedTypeDecl *>, Type>
     DefaultTypeWitnesses;
 
+  /// Default associated conformance witnesses for protocols.
+  llvm::DenseMap<std::tuple<const ProtocolDecl *, CanType, ProtocolDecl *>,
+                 ProtocolConformanceRef>
+    DefaultAssociatedConformanceWitnesses;
+
   /// \brief Structure that captures data that is segregated into different
   /// arenas.
   struct Arena {
@@ -1709,6 +1714,32 @@
   (void)pair;
 }
 
+Optional<ProtocolConformanceRef>
+ProtocolDecl::getDefaultAssociatedConformanceWitness(
+                                             CanType association,
+                                             ProtocolDecl *requirement) const {
+  auto &ctx = getASTContext();
+  auto found =
+    ctx.getImpl().DefaultAssociatedConformanceWitnesses.find(
+      std::make_tuple(this, association, requirement));
+  if (found == ctx.getImpl().DefaultAssociatedConformanceWitnesses.end())
+    return None;
+
+  return found->second;
+}
+
+void ProtocolDecl::setDefaultAssociatedConformanceWitness(
+                                          CanType association,
+                                          ProtocolDecl *requirement,
+                                          ProtocolConformanceRef conformance) {
+  auto &ctx = getASTContext();
+  auto pair = ctx.getImpl().DefaultAssociatedConformanceWitnesses.insert(
+                std::make_pair(std::make_tuple(this, association, requirement),
+                               conformance));
+  assert(pair.second && "Already have a default associated conformance");
+  (void)pair;
+}
+
 bool ASTContext::canImportModule(std::pair<Identifier, SourceLoc> ModulePath) {
   // If this module has already been successfully imported, it is importable.
   if (getLoadedModule(ModulePath) != nullptr)
diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp
index 925e667..55bbda3 100644
--- a/lib/AST/DeclContext.cpp
+++ b/lib/AST/DeclContext.cpp
@@ -92,7 +92,11 @@
     const_cast<ProtocolDecl *>(proto)->createGenericParamsIfMissing();
   }
 
-  return getGenericParamsOfContext()->getParams().front()
+  auto *genericParams = getGenericParamsOfContext();
+  if (genericParams == nullptr)
+    return nullptr;
+
+  return genericParams->getParams().front()
       ->getDeclaredInterfaceType()
       ->castTo<GenericTypeParamType>();
 }
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index 1ef30d5..699a8b7 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -564,6 +564,9 @@
 
   ASTContext &ctx = proto->getASTContext();
   TinyPtrVector<NominalTypeDecl *> result;
+  if (!ext->getGenericParams())
+    return result;
+
   for (const auto &req : ext->getGenericParams()->getTrailingRequirements()) {
     // We only care about type constraints.
     if (req.getKind() != RequirementReprKind::TypeConstraint)
@@ -709,6 +712,7 @@
   };
 
   if (Loc.isValid() &&
+      DC->getParentSourceFile() &&
       DC->getParentSourceFile()->Kind != SourceFileKind::REPL &&
       Ctx.LangOpts.EnableASTScopeLookup) {
     // Find the source file in which we are performing the lookup.
diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp
index a41f978..9048834 100644
--- a/lib/Demangling/Demangler.cpp
+++ b/lib/Demangling/Demangler.cpp
@@ -1841,6 +1841,15 @@
                                 protoTy, assocTypePath, requirementTy);
     }
 
+    case 'N': {
+      NodePointer requirementTy = popProtocol();
+      auto assocTypePath = popAssocTypePath();
+      NodePointer protoTy = popNode(Node::Kind::Type);
+      return createWithChildren(
+                            Node::Kind::DefaultAssociatedConformanceAccessor,
+                            protoTy, assocTypePath, requirementTy);
+    }
+
     case 'H':
     case 'h': {
       auto nodeKind = c == 'H' ? Node::Kind::KeyPathEqualsThunkHelper
diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp
index 50e451b..363d552 100644
--- a/lib/Demangling/NodePrinter.cpp
+++ b/lib/Demangling/NodePrinter.cpp
@@ -323,6 +323,7 @@
     case Node::Kind::DeclContext:
     case Node::Kind::DefaultArgumentInitializer:
     case Node::Kind::DefaultAssociatedTypeMetadataAccessor:
+    case Node::Kind::DefaultAssociatedConformanceAccessor:
     case Node::Kind::DependentAssociatedTypeRef:
     case Node::Kind::DependentGenericSignature:
     case Node::Kind::DependentGenericParamCount:
@@ -1564,6 +1565,14 @@
     Printer << ": ";
     print(Node->getChild(2));
     return nullptr;
+  case Node::Kind::DefaultAssociatedConformanceAccessor:
+    Printer << "default associated conformance accessor for ";
+    print(Node->getChild(0));
+    Printer << ".";
+    print(Node->getChild(1));
+    Printer << ": ";
+    print(Node->getChild(2));
+    return nullptr;
   case Node::Kind::AssociatedTypeDescriptor:
     Printer << "associated type descriptor for ";
     print(Node->getChild(0));
diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp
index 2549d1a..e4f08ee 100644
--- a/lib/Demangling/OldRemangler.cpp
+++ b/lib/Demangling/OldRemangler.cpp
@@ -888,6 +888,10 @@
   Out << "<associated-conformance-descriptor>";
 }
 
+void Remangler::mangleDefaultAssociatedConformanceAccessor(Node *node) {
+  Out << "<default-associated-conformance-descriptor>";
+}
+
 void Remangler::mangleAssociatedTypeMetadataAccessor(Node *node) {
   Out << "Wt";
   mangleChildNodes(node); // protocol conformance, identifier
diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp
index f7ffe88..348b288 100644
--- a/lib/Demangling/Remangler.cpp
+++ b/lib/Demangling/Remangler.cpp
@@ -579,6 +579,11 @@
   Buffer << "Tn";
 }
 
+void Remangler::mangleDefaultAssociatedConformanceAccessor(Node *node) {
+  mangleChildNodes(node);
+  Buffer << "TN";
+}
+
 void Remangler::mangleAssociatedTypeMetadataAccessor(Node *node) {
   mangleChildNodes(node); // protocol conformance, identifier
   Buffer << "Wt";
diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp
index ec487ba..23048cd 100644
--- a/lib/Frontend/Frontend.cpp
+++ b/lib/Frontend/Frontend.cpp
@@ -517,7 +517,9 @@
   }
 
   FrontendStatsTracer tracer(Context->Stats, "perform-sema");
-  Context->LoadedModules[MainModule->getName()] = getMainModule();
+
+  ModuleDecl *mainModule = getMainModule();
+  Context->LoadedModules[mainModule->getName()] = mainModule;
 
   if (Invocation.getInputKind() == InputFileKind::SIL) {
     assert(!InputSourceCodeBufferIDs.empty());
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index d48d029..0cc89af 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -3389,21 +3389,15 @@
 
 llvm::Constant *IRGenModule::getAddrOfAssociatedConformanceDescriptor(
                                           AssociatedConformance conformance) {
-  auto entity = LinkEntity::forAssociatedConformanceDescriptor(
-                  conformance.getSourceProtocol(),
-                  conformance.getAssociation(),
-                  conformance.getAssociatedRequirement());
+  auto entity = LinkEntity::forAssociatedConformanceDescriptor(conformance);
   return getAddrOfLLVMVariable(entity, getPointerAlignment(), ConstantInit(),
                                ProtocolRequirementStructTy, DebugTypeInfo());
 }
 
 llvm::GlobalValue *IRGenModule::defineAssociatedConformanceDescriptor(
-                                                ProtocolDecl *proto,
-                                                CanType subject,
-                                                ProtocolDecl *requirement,
-                                                llvm::Constant *definition) {
-  auto entity = LinkEntity::forAssociatedConformanceDescriptor(proto, subject,
-                                                               requirement);
+                                            AssociatedConformance conformance,
+                                            llvm::Constant *definition) {
+  auto entity = LinkEntity::forAssociatedConformanceDescriptor(conformance);
   return defineAlias(entity, definition);
 }
 
@@ -3989,6 +3983,25 @@
 }
 
 llvm::Function *
+IRGenModule::getAddrOfDefaultAssociatedConformanceAccessor(
+                                         AssociatedConformance requirement) {
+  auto forDefinition = ForDefinition;
+
+  LinkEntity entity =
+    LinkEntity::forDefaultAssociatedConformanceAccessor(requirement);
+  llvm::Function *&entry = GlobalFuncs[entity];
+  if (entry) {
+    if (forDefinition) updateLinkageForDefinition(*this, entry, entity);
+    return entry;
+  }
+
+  auto signature = getAssociatedTypeWitnessTableAccessFunctionSignature();
+  LinkInfo link = LinkInfo::get(*this, entity, forDefinition);
+  entry = createFunction(*this, link, signature);
+  return entry;
+}
+
+llvm::Function *
 IRGenModule::getAddrOfContinuationPrototype(CanSILFunctionType fnType) {
   LinkEntity entity = LinkEntity::forCoroutineContinuationPrototype(fnType);
 
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index f0198cf..a75abe0 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -647,7 +647,14 @@
 
       if (entry.isAssociatedConformance()) {
         auto flags = Flags(Flags::Kind::AssociatedConformanceAccessFunction);
-        return { flags, nullptr };
+
+        // Look for a default witness.
+        llvm::Constant *defaultImpl =
+          findDefaultAssociatedConformanceWitness(
+            entry.getAssociatedConformancePath(),
+            entry.getAssociatedConformanceRequirement());
+
+        return { flags, defaultImpl };
       }
 
       assert(entry.isFunction());
@@ -712,10 +719,12 @@
         if (entry.isAssociatedConformance()) {
           // Define the associated conformance descriptor to point to the
           // current position in the protocol descriptor.
+          AssociatedConformance conformance(
+                                  Proto,
+                                  entry.getAssociatedConformancePath(),
+                                  entry.getAssociatedConformanceRequirement());
           IGM.defineAssociatedConformanceDescriptor(
-              Proto,
-              entry.getAssociatedConformancePath(),
-              entry.getAssociatedConformanceRequirement(),
+              conformance,
               B.getAddrOfCurrentPosition(IGM.ProtocolRequirementStructTy));
         }
 
@@ -800,6 +809,89 @@
       IGF.Builder.CreateRet(returnValue);
       return accessor;
     }
+
+    llvm::Constant *findDefaultAssociatedConformanceWitness(
+                                                  CanType association,
+                                                  ProtocolDecl *requirement) {
+      if (!DefaultWitnesses) return nullptr;
+
+      for (auto &entry : DefaultWitnesses->getEntries()) {
+        if (!entry.isValid() ||
+            entry.getKind() != SILWitnessTable::AssociatedTypeProtocol ||
+            entry.getAssociatedTypeProtocolWitness().Protocol != requirement ||
+            entry.getAssociatedTypeProtocolWitness().Requirement != association)
+          continue;
+
+        auto witness = entry.getAssociatedTypeProtocolWitness().Witness;
+        return getDefaultAssociatedConformanceAccessFunction(
+                 AssociatedConformance(Proto, association, requirement),
+                 witness);
+      }
+
+      return nullptr;
+    }
+
+    llvm::Constant *getDefaultAssociatedConformanceAccessFunction(
+                      AssociatedConformance requirement,
+                      ProtocolConformanceRef conformance) {
+      auto accessor =
+        IGM.getAddrOfDefaultAssociatedConformanceAccessor(requirement);
+
+      IRGenFunction IGF(IGM, accessor);
+      if (IGM.DebugInfo)
+        IGM.DebugInfo->emitArtificialFunction(IGF, accessor);
+
+      Explosion parameters = IGF.collectParameters();
+
+      llvm::Value *associatedTypeMetadata = parameters.claimNext();
+      llvm::Value *self = parameters.claimNext();
+      llvm::Value *wtable = parameters.claimNext();
+
+      bool hasArchetype =
+        !conformance.isConcrete() ||
+        conformance.getConcrete()->getType()->hasArchetype();
+      if (hasArchetype) {
+        // Bind local Self type data from the metadata argument.
+        CanType selfInContext =
+            Proto->mapTypeIntoContext(Proto->getProtocolSelfType())
+              ->getCanonicalType();
+        IGF.bindLocalTypeDataFromTypeMetadata(selfInContext, IsExact, self,
+                                              MetadataState::Abstract);
+        IGF.setUnscopedLocalTypeData(
+            selfInContext,
+            LocalTypeDataKind::forAbstractProtocolWitnessTable(Proto),
+            wtable);
+
+        // Bind the associated type metadata.
+        IGF.bindLocalTypeDataFromTypeMetadata(requirement.getAssociation(),
+                                              IsExact,
+                                              associatedTypeMetadata,
+                                              MetadataState::Abstract);
+      }
+
+      // For a concrete witness table, call it.
+      ProtocolDecl *associatedProtocol = requirement.getAssociatedRequirement();
+      if (conformance.isConcrete()) {
+        auto conformanceI = &IGM.getConformanceInfo(associatedProtocol,
+                                                    conformance.getConcrete());
+        auto returnValue = conformanceI->getTable(IGF, &associatedTypeMetadata);
+        IGF.Builder.CreateRet(returnValue);
+        return accessor;
+      }
+
+      // For an abstract table, emit a reference to the witness table.
+      CanType associatedTypeInContext
+        = Proto->mapTypeIntoContext(requirement.getAssociation())
+            ->getCanonicalType();
+      auto returnValue =
+          emitArchetypeWitnessTableRef(
+            IGF,
+            cast<ArchetypeType>(associatedTypeInContext),
+            associatedProtocol);
+      IGF.Builder.CreateRet(returnValue);
+      return accessor;
+    }
+
     void addAssociatedTypeNames() {
       std::string AssociatedTypeNames;
 
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 0cf4f02..a04e8ae 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -1385,6 +1385,13 @@
     void addAssociatedConformance(AssociatedConformance requirement) {
       // FIXME: Add static witness tables for type conformances.
 
+      auto &entry = SILEntries.front();
+      (void)entry;
+      SILEntries = SILEntries.slice(1);
+
+      if (ResilientConformance)
+        return;
+
       auto associate =
         ConformanceInContext.getAssociatedType(
           requirement.getAssociation())->getCanonicalType();
@@ -1394,9 +1401,8 @@
           requirement.getAssociation(),
           requirement.getAssociatedRequirement());
 
+
 #ifndef NDEBUG
-      auto &entry = SILEntries.front();
-      (void)entry;
       assert(entry.getKind() == SILWitnessTable::AssociatedTypeProtocol
              && "sil witness table does not match protocol");
       auto associatedWitness = entry.getAssociatedTypeProtocolWitness();
@@ -1411,8 +1417,6 @@
              "offset doesn't match ProtocolInfo layout");
 #endif
 
-      SILEntries = SILEntries.slice(1);
-
       llvm::Constant *wtableAccessFunction =
         getAssociatedTypeWitnessTableAccessFunction(requirement,
                                                     associate,
@@ -1644,7 +1648,8 @@
 getAssociatedTypeWitnessTableAccessFunction(AssociatedConformance requirement,
                                             CanType associatedType,
                                 ProtocolConformanceRef associatedConformance) {
-  if (!associatedType->hasArchetype()) {
+  bool hasArchetype = associatedType->hasArchetype();
+  if (!hasArchetype && !ResilientConformance) {
     assert(associatedConformance.isConcrete() &&
            "no concrete conformance for non-dependent type");
     return getOrCreateWitnessTableAccessFunction(IGM,
@@ -1682,13 +1687,6 @@
   Address destTable(parameters.claimNext(), IGM.getPointerAlignment());
   setProtocolWitnessTableName(IGM, destTable.getAddress(), ConcreteType,
                               Conformance.getProtocol());
-  IGF.bindLocalTypeDataFromSelfWitnessTable(
-          &Conformance,
-          destTable.getAddress(),
-          [&](CanType type) {
-            return Conformance.getDeclContext()->mapTypeIntoContext(type)
-                     ->getCanonicalType();
-          });
 
   ProtocolDecl *associatedProtocol = requirement.getAssociatedRequirement();
 
@@ -1710,6 +1708,24 @@
     }
   }
 
+  // If there are no archetypes, return a reference to the table. There is
+  // no need for a cache.
+  if (!hasArchetype) {
+    auto wtable = MetadataResponse::forComplete(
+                    conformanceI->getTable(IGF, &associatedTypeMetadata))
+        .getMetadata();
+    IGF.Builder.CreateRet(wtable);
+    return accessor;
+  }
+
+  IGF.bindLocalTypeDataFromSelfWitnessTable(
+        &Conformance,
+        destTable.getAddress(),
+        [&](CanType type) {
+          return Conformance.getDeclContext()->mapTypeIntoContext(type)
+                   ->getCanonicalType();
+        });
+
   // If the witness table is directly fulfillable from the type,
   // we don't need a cache entry.
   // TODO: maybe we should have a cache entry anyway if the fulfillment
@@ -1869,7 +1885,8 @@
   unsigned count = 0;
   for (auto &entry : SILWT->getEntries()) {
     if (entry.getKind() != SILWitnessTable::Method &&
-        entry.getKind() != SILWitnessTable::AssociatedType)
+        entry.getKind() != SILWitnessTable::AssociatedType &&
+        entry.getKind() != SILWitnessTable::AssociatedTypeProtocol)
       continue;
 
     count++;
@@ -1907,6 +1924,36 @@
       continue;
     }
 
+    // Associated conformance access function.
+    if (entry.getKind() == SILWitnessTable::AssociatedTypeProtocol) {
+      const auto &witness = entry.getAssociatedTypeProtocolWitness();
+
+      // Associated type descriptor.
+      AssociatedConformance requirement(SILWT->getConformance()->getProtocol(),
+                                        witness.Requirement,
+                                        witness.Protocol);
+      auto assocConformanceDescriptor =
+        IGM.getAddrOfLLVMVariableOrGOTEquivalent(
+          LinkEntity::forAssociatedConformanceDescriptor(requirement),
+          Alignment(4), IGM.ProtocolRequirementStructTy);
+      table.addRelativeAddress(assocConformanceDescriptor);
+
+      auto associate =
+        ConformanceInContext.getAssociatedType(
+          witness.Requirement)->getCanonicalType();
+
+      ProtocolConformanceRef associatedConformance =
+        ConformanceInContext.getAssociatedConformance(witness.Requirement,
+                                                      witness.Protocol);
+
+      llvm::Constant *wtableAccessFunction =
+        getAssociatedTypeWitnessTableAccessFunction(requirement,
+                                                    associate,
+                                                    associatedConformance);
+      table.addRelativeAddress(wtableAccessFunction);
+      continue;
+    }
+
     if (entry.getKind() != SILWitnessTable::Method)
       continue;
 
diff --git a/lib/IRGen/IRGenMangler.h b/lib/IRGen/IRGenMangler.h
index edd7713..37c5b95 100644
--- a/lib/IRGen/IRGenMangler.h
+++ b/lib/IRGen/IRGenMangler.h
@@ -197,6 +197,19 @@
     return finalize();
   }
 
+  std::string mangleDefaultAssociatedConformanceAccessor(
+      const ProtocolDecl *proto,
+      CanType subject,
+      const ProtocolDecl *requirement) {
+    beginMangling();
+    appendAnyGenericType(proto);
+    bool isFirstAssociatedTypeIdentifier = true;
+    appendAssociatedTypePath(subject, isFirstAssociatedTypeIdentifier);
+    appendProtocolName(requirement);
+    appendOperator("TN");
+    return finalize();
+  }
+
   std::string mangleProtocolConformanceDescriptor(
                                  const ProtocolConformance *Conformance) {
     beginMangling();
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index fb33001..0c98b82 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -1237,10 +1237,8 @@
   llvm::Constant *getAddrOfAssociatedConformanceDescriptor(
                                             AssociatedConformance conformance);
   llvm::GlobalValue *defineAssociatedConformanceDescriptor(
-                                                  ProtocolDecl *proto,
-                                                  CanType subject,
-                                                  ProtocolDecl *requirement,
-                                                  llvm::Constant *definition);
+                                              AssociatedConformance conformance,
+                                              llvm::Constant *definition);
 
   llvm::Constant *getAddrOfProtocolDescriptor(ProtocolDecl *D,
                                       ConstantInit definition = ConstantInit());
@@ -1293,6 +1291,8 @@
                                      const AssociatedConformance &association);
   llvm::Function *getAddrOfDefaultAssociatedTypeMetadataAccessFunction(
                                            AssociatedType association);
+  llvm::Function *getAddrOfDefaultAssociatedConformanceAccessor(
+                                           AssociatedConformance requirement);
 
   Address getAddrOfObjCISAMask();
 
diff --git a/lib/IRGen/Linking.cpp b/lib/IRGen/Linking.cpp
index 6562b50..b24a247 100644
--- a/lib/IRGen/Linking.cpp
+++ b/lib/IRGen/Linking.cpp
@@ -187,6 +187,14 @@
              assocConformance.second);
   }
 
+  case Kind::DefaultAssociatedConformanceAccessor: {
+    auto assocConformance = getAssociatedConformance();
+    return mangler.mangleDefaultAssociatedConformanceAccessor(
+             cast<ProtocolDecl>(getDecl()),
+             assocConformance.first,
+             assocConformance.second);
+  }
+
   case Kind::ProtocolConformanceDescriptor:
     return mangler.mangleProtocolConformanceDescriptor(
                    cast<NormalProtocolConformance>(getProtocolConformance()));
@@ -498,6 +506,7 @@
   case Kind::AssociatedTypeMetadataAccessFunction:
   case Kind::DefaultAssociatedTypeMetadataAccessFunction:
   case Kind::AssociatedTypeWitnessTableAccessFunction:
+  case Kind::DefaultAssociatedConformanceAccessor:
   case Kind::GenericProtocolWitnessTableCache:
   case Kind::GenericProtocolWitnessTableInstantiationFunction:
     return SILLinkage::Private;
@@ -629,6 +638,7 @@
   case Kind::TypeMetadataCompletionFunction:
   case Kind::TypeMetadataPattern:
   case Kind::DefaultAssociatedTypeMetadataAccessFunction:
+  case Kind::DefaultAssociatedConformanceAccessor:
     return false;
 
   case Kind::ValueWitness:
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index 9192819..b614aa0 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -272,8 +272,7 @@
   return Result;
 }
 
-void Lexer::formToken(tok Kind, const char *TokStart,
-                      bool IsMultilineString, unsigned CustomDelimiterLen) {
+void Lexer::formToken(tok Kind, const char *TokStart) {
   assert(CurPtr >= BufferStart &&
          CurPtr <= BufferEnd && "Current pointer out of range!");
 
@@ -305,8 +304,7 @@
     lexTrivia(TrailingTrivia, /* IsForTrailingTrivia */ true);
   }
 
-  NextToken.setToken(Kind, TokenText, CommentLength,
-                     IsMultilineString, CustomDelimiterLen);
+  NextToken.setToken(Kind, TokenText, CommentLength);
 }
 
 void Lexer::formEscapedIdentifierToken(const char *TokStart) {
@@ -326,6 +324,20 @@
   NextToken.setEscapedIdentifier(true);
 }
 
+static void validateMultilineIndents(const Token &Str, DiagnosticEngine *Diags);
+
+void Lexer::formStringLiteralToken(const char *TokStart,
+                                   bool IsMultilineString,
+                                   unsigned CustomDelimiterLen) {
+  formToken(tok::string_literal, TokStart);
+  if (NextToken.is(tok::eof))
+    return;
+  NextToken.setStringLiteral(IsMultilineString, CustomDelimiterLen);
+
+  if (IsMultilineString && Diags)
+    validateMultilineIndents(NextToken, Diags);
+}
+
 Lexer::State Lexer::getStateForBeginningOfTokenLoc(SourceLoc Loc) const {
   const char *Ptr = getBufferPtrForSourceLoc(Loc);
   // Skip whitespace backwards until we hit a newline.  This is needed to
@@ -1238,9 +1250,11 @@
 
 /// advanceIfCustomDelimiter - Extracts/detects any custom delimiter on
 /// opening a string literal, advances CurPtr if a delimiter is found and
-/// returns a non-zero delimiter length. CurPtr[-1] generally '#' when called.
+/// returns a non-zero delimiter length. CurPtr[-1] must be '#' when called.
 static unsigned advanceIfCustomDelimiter(const char *&CurPtr,
                                          DiagnosticEngine *Diags) {
+  assert(CurPtr[-1] == '#');
+
   const char *TmpPtr = CurPtr;
   unsigned CustomDelimiterLen = 1;
   while (diagnoseZeroWidthMatchAndAdvance('#', TmpPtr, Diags))
@@ -1263,24 +1277,28 @@
   if (!CustomDelimiterLen)
     return true;
   const char *TmpPtr = BytesPtr;
-  while (CustomDelimiterLen--)
-    if (!diagnoseZeroWidthMatchAndAdvance('#', TmpPtr, Diags))
-      return false;
-  BytesPtr = TmpPtr;
-  if (*BytesPtr == '#' && Diags)
-    Diags->diagnose(Lexer::getSourceLoc(BytesPtr), IsClosing ?
-                    diag::lex_invalid_closing_delimiter :
-                    diag::lex_invalid_escape_delimiter)
-      .fixItRemoveChars(Lexer::getSourceLoc(BytesPtr),
-                        Lexer::getSourceLoc(BytesPtr + 1));
+  while (diagnoseZeroWidthMatchAndAdvance('#', TmpPtr, Diags)) {}
+
+  if (TmpPtr - BytesPtr < CustomDelimiterLen)
+    return false;
+
+  BytesPtr += CustomDelimiterLen;
+
+  if (Diags && TmpPtr > BytesPtr) {
+    Diag<> message = IsClosing ? diag::lex_invalid_closing_delimiter
+                               : diag::lex_invalid_escape_delimiter;
+    Diags->diagnose(Lexer::getSourceLoc(BytesPtr), message)
+        .fixItRemoveChars(Lexer::getSourceLoc(BytesPtr),
+                          Lexer::getSourceLoc(TmpPtr));
+  }
   return true;
 }
 
 /// lexCharacter - Read a character and return its UTF32 code.  If this is the
 /// end of enclosing string/character sequence (i.e. the character is equal to
-/// 'StopQuote'), this returns ~0U and leaves 'CurPtr' pointing to the terminal
-/// quote.  If this is a malformed character sequence, it emits a diagnostic
-/// (when EmitDiagnostics is true) and returns ~1U.
+/// 'StopQuote'), this returns ~0U and advances 'CurPtr' pointing to the end of
+/// terminal quote.  If this is a malformed character sequence, it emits a
+/// diagnostic (when EmitDiagnostics is true) and returns ~1U.
 /// 
 ///   character_escape  ::= [\][\] | [\]t | [\]n | [\]r | [\]" | [\]' | [\]0
 ///   character_escape  ::= unicode_character_escape
@@ -1291,6 +1309,7 @@
 
   switch (*CurPtr++) {
   default: {// Normal characters are part of the string.
+    // Normal characters are part of the string.
     // If this is a "high" UTF-8 character, validate it.
     if ((signed char)(CurPtr[-1]) >= 0) {
       if (isPrintable(CurPtr[-1]) == 0)
@@ -1308,32 +1327,35 @@
   }
   case '"':
   case '\'':
-    // If we found a closing quote character, we're done.
     if (CurPtr[-1] == StopQuote) {
-      --CurPtr;
+      // Mutliline and custom escaping are only enabled for " quote.
+      if (LLVM_UNLIKELY(StopQuote != '"'))
+        return ~0U;
+      if (!IsMultilineString && !CustomDelimiterLen)
+        return ~0U;
+
+      DiagnosticEngine *D = EmitDiagnostics ? Diags : nullptr;
+      auto TmpPtr = CurPtr;
+      if (IsMultilineString && !advanceIfMultilineDelimiter(TmpPtr, D))
+        return '"';
+      if (CustomDelimiterLen &&
+          !delimiterMatches(CustomDelimiterLen, TmpPtr, D, /*IsClosing=*/true))
+        return '"';
+      CurPtr = TmpPtr;
       return ~0U;
     }
     // Otherwise, this is just a character.
     return CurPtr[-1];
-      
+
   case 0:
-    if (CurPtr-1 != BufferEnd) {
-      if (EmitDiagnostics)
-        diagnose(CurPtr-1, diag::lex_nul_character);
-      return CurPtr[-1];
-    }
-    // Move the pointer back to EOF.
-    --CurPtr;
+    assert(CurPtr - 1 != BufferEnd && "Caller must handle EOF");
     if (EmitDiagnostics)
-      diagnose(CurPtr-1, diag::lex_unterminated_string);
-    return ~1U;
+      diagnose(CurPtr-1, diag::lex_nul_character);
+    return CurPtr[-1];
   case '\n':  // String literals cannot have \n or \r in them.
   case '\r':
-    if (IsMultilineString) // ... unless they are multiline
-      return CurPtr[-1];
-    if (EmitDiagnostics)
-      diagnose(CurPtr-1, diag::lex_unterminated_string);
-    return ~1U;
+    assert(IsMultilineString && "Caller must handle newlines in non-multiline");
+    return CurPtr[-1];
   case '\\':  // Escapes.
     if (!delimiterMatches(CustomDelimiterLen, CurPtr,
                           EmitDiagnostics ? Diags : nullptr))
@@ -1402,7 +1424,6 @@
 /// outstanding delimiters as it scans the string.
 static const char *skipToEndOfInterpolatedExpression(const char *CurPtr,
                                                      const char *EndPtr,
-                                                     DiagnosticEngine *Diags,
                                                      bool IsMultilineString) {
   SmallVector<char, 4> OpenDelimiters;
   SmallVector<bool, 4> AllowNewline;
@@ -1432,81 +1453,71 @@
         continue;
       // Will be diagnosed as an unterminated string literal.
       return CurPtr-1;
+    case 0:
+      if (CurPtr-1 != EndPtr)
+        continue; // CC token or random NUL character.
+      // Will be diagnosed as an unterminated string literal.
+      return CurPtr-1;
 
     case '#':
       if (inStringLiteral() ||
-          !(CustomDelimiterLen = advanceIfCustomDelimiter(CurPtr, Diags)))
+          !(CustomDelimiterLen = advanceIfCustomDelimiter(CurPtr, nullptr)))
         continue;
+      assert(CurPtr[-1] == '"' &&
+             "advanceIfCustomDelimiter() must stop at after the quote");
       LLVM_FALLTHROUGH;
 
     case '"':
     case '\'': {
-      if (!AllowNewline.back() && inStringLiteral()) {
-        if (OpenDelimiters.back() == CurPtr[-1] &&
-            delimiterMatches(CustomDelimiter.back(), CurPtr, Diags, true)) {
-          // Closing single line string literal.
-          OpenDelimiters.pop_back();
-          AllowNewline.pop_back();
-          CustomDelimiter.pop_back();
-        }
-        // Otherwise, it's just a quote in string literal. e.g. "foo's".
-        continue;
-      }
-
-      bool isMultilineQuote = advanceIfMultilineDelimiter(CurPtr, Diags);
-
       if (!inStringLiteral()) {
-        // Open string literal
+        // Open string literal.
         OpenDelimiters.push_back(CurPtr[-1]);
-        AllowNewline.push_back(isMultilineQuote);
+        AllowNewline.push_back(advanceIfMultilineDelimiter(CurPtr, nullptr));
         CustomDelimiter.push_back(CustomDelimiterLen);
         continue;
       }
 
-      // We are in multiline string literal.
-      assert(AllowNewline.back() && "other cases must be handled above");
-      if (isMultilineQuote &&
-          delimiterMatches(CustomDelimiter.back(), CurPtr, Diags, true)) {
-        // Close multiline string literal.
-        OpenDelimiters.pop_back();
-        AllowNewline.pop_back();
-        CustomDelimiter.pop_back();
-      }
+      // In string literal.
 
-      // Otherwise, it's just a normal character in multiline string.
+      // Skip if it's an another kind of quote in string literal. e.g. "foo's".
+      if (OpenDelimiters.back() != CurPtr[-1])
+        continue;
+
+      // Multi-line string can only be closed by '"""'.
+      if (AllowNewline.back() && !advanceIfMultilineDelimiter(CurPtr, nullptr))
+        continue;
+
+      // Check whether we have equivalent number of '#'s.
+      if (!delimiterMatches(CustomDelimiter.back(), CurPtr, nullptr, true))
+        continue;
+
+      // Close string literal.
+      OpenDelimiters.pop_back();
+      AllowNewline.pop_back();
+      CustomDelimiter.pop_back();
       continue;
     }
     case '\\':
+      // We ignore invalid escape sequence here. They should be diagnosed in
+      // the real lexer functions.
       if (inStringLiteral() &&
-          delimiterMatches(CustomDelimiter.back(), CurPtr, Diags)) {
-        char escapedChar = *CurPtr++;
-        switch (escapedChar) {
+          delimiterMatches(CustomDelimiter.back(), CurPtr, nullptr)) {
+        switch (*CurPtr++) {
         case '(':
           // Entering a recursive interpolated expression
           OpenDelimiters.push_back('(');
           continue;
-        case '\n': case '\r':
-          if (AllowNewline.back())
-            continue;
-          LLVM_FALLTHROUGH;
-        case 0:
-          // Don't jump over newline/EOF due to preceding backslash!
-          return CurPtr-1;
+        case '\n': case '\r': case 0:
+          // Don't jump over newline/EOF due to preceding backslash.
+          // Let the outer switch to handle it.
+          --CurPtr;
+          continue;
         default:
           continue;
         }
       }
       continue;
-    case 0:
-      // If we hit EOF, we fail.
-      if (CurPtr-1 == EndPtr) {
-        if (Diags)
-          Diags->diagnose(Lexer::getSourceLoc(CurPtr-1),
-                          diag::lex_unterminated_string);
-        return CurPtr-1;
-      }
-      continue;
-        
+
     // Paren nesting deeper to support "foo = \((a+b)-(c*d)) bar".
     case '(':
       if (!inStringLiteral()) {
@@ -1730,111 +1741,117 @@
                                   commonIndentation);
 }
 
+/// Emit diagnostics for single-quote string and suggest replacement
+/// with double-quoted equivalent.
+static void diagnoseSingleQuoteStringLiteral(const char *TokStart,
+                                             const char *TokEnd,
+                                             DiagnosticEngine *D) {
+  assert(*TokStart == '\'' && TokEnd[-1] == '\'');
+  if (!D)
+    return;
+
+  SmallString<32> replacement;
+  replacement.push_back('"');
+  const char *Ptr = TokStart + 1;
+  const char *OutputPtr = Ptr;
+
+  while (*Ptr++ != '\'' && Ptr < TokEnd) {
+    if (Ptr[-1] == '\\') {
+      if (*Ptr == '\'') {
+        replacement.append(OutputPtr, Ptr - 1);
+        OutputPtr = Ptr + 1;
+        // Un-escape single quotes.
+        replacement.push_back('\'');
+      } else if (*Ptr == '(') {
+        // Preserve the contents of interpolation.
+        Ptr = skipToEndOfInterpolatedExpression(Ptr + 1, replacement.end(),
+                                                /*IsMultiline=*/false);
+        assert(*Ptr == ')');
+      }
+      // Skip over escaped characters.
+      ++Ptr;
+    } else if (Ptr[-1] == '"') {
+      replacement.append(OutputPtr, Ptr - 1);
+      OutputPtr = Ptr;
+      // Escape double quotes.
+      replacement.append("\\\"");
+    }
+  }
+  assert(Ptr == TokEnd && Ptr[-1] == '\'');
+  replacement.append(OutputPtr, Ptr - 1);
+  replacement.push_back('"');
+
+  D->diagnose(Lexer::getSourceLoc(TokStart), diag::lex_single_quote_string)
+      .fixItReplaceChars(Lexer::getSourceLoc(TokStart),
+                         Lexer::getSourceLoc(TokEnd), replacement);
+}
+
 /// lexStringLiteral:
 ///   string_literal ::= ["]([^"\\\n\r]|character_escape)*["]
 ///   string_literal ::= ["]["]["].*["]["]["] - approximately
 ///   string_literal ::= (#+)("")?".*"(\2\1) - "raw" strings
 void Lexer::lexStringLiteral(unsigned CustomDelimiterLen) {
-  const char *TokStart = CurPtr-1;
-  assert((*TokStart == '"' || *TokStart == '\'') && "Unexpected start");
+  const char QuoteChar = CurPtr[-1];
+  const char *TokStart = CurPtr - 1 - CustomDelimiterLen;
+
   // NOTE: We only allow single-quote string literals so we can emit useful
   // diagnostics about changing them to double quotes.
+  assert((QuoteChar == '"' || QuoteChar == '\'') && "Unexpected start");
 
-  bool wasErroneous = false, IsMultilineString = false;
-
-  // Is this the start of a multiline string literal?
-  if ((IsMultilineString = advanceIfMultilineDelimiter(CurPtr, Diags))) {
-    if (*CurPtr != '\n' && *CurPtr != '\r')
-      diagnose(CurPtr, diag::lex_illegal_multiline_string_start)
+  bool IsMultilineString = advanceIfMultilineDelimiter(CurPtr, Diags);
+  if (IsMultilineString && *CurPtr != '\n' && *CurPtr != '\r')
+    diagnose(CurPtr, diag::lex_illegal_multiline_string_start)
         .fixItInsert(Lexer::getSourceLoc(CurPtr), "\n");
-  }
 
+  bool wasErroneous = false;
   while (true) {
+    // Handle string interpolation.
     const char *TmpPtr = CurPtr + 1;
-    if (*CurPtr == '\\' && delimiterMatches(CustomDelimiterLen, TmpPtr, nullptr)
-        && *TmpPtr == '(') {
+    if (*CurPtr == '\\' &&
+        delimiterMatches(CustomDelimiterLen, TmpPtr, nullptr) &&
+        *TmpPtr++ == '(') {
       // Consume tokens until we hit the corresponding ')'.
-      CurPtr = TmpPtr + 1;
-      const char *EndPtr =
-          skipToEndOfInterpolatedExpression(CurPtr, BufferEnd,
-                                            Diags, IsMultilineString);
-      
-      if (*EndPtr == ')') {
+      CurPtr = skipToEndOfInterpolatedExpression(TmpPtr, BufferEnd,
+                                                 IsMultilineString);
+      if (*CurPtr == ')') {
         // Successfully scanned the body of the expression literal.
-        CurPtr = EndPtr+1;
-      } else {
-        CurPtr = EndPtr;
-        wasErroneous = true;
+        ++CurPtr;
+        continue;
       }
-      continue;
+
+      // Being diagnosed below.
+      assert((*CurPtr == '\r' || *CurPtr == '\n' || CurPtr == BufferEnd) &&
+             "Returned at unexpected position");
     }
 
     // String literals cannot have \n or \r in them (unless multiline).
     if (((*CurPtr == '\r' || *CurPtr == '\n') && !IsMultilineString)
         || CurPtr == BufferEnd) {
-      TokStart -= CustomDelimiterLen;
       diagnose(TokStart, diag::lex_unterminated_string);
       return formToken(tok::unknown, TokStart);
     }
 
-    unsigned CharValue = lexCharacter(CurPtr, *TokStart, true,
+    unsigned CharValue = lexCharacter(CurPtr, QuoteChar, true,
                                       IsMultilineString, CustomDelimiterLen);
+    // This is the end of string, we are done.
+    if (CharValue == ~0U)
+      break;
+
+    // Remember we had already-diagnosed invalid characters.
     wasErroneous |= CharValue == ~1U;
-
-    // If this is the end of string, we are done.  If it is a normal character
-    // or an already-diagnosed error, just munch it.
-    if (CharValue == ~0U) {
-      ++CurPtr;
-
-      if (*TokStart == '\'') {
-        // Complain about single-quote string and suggest replacement with
-        // double-quoted equivalent.
-        StringRef orig(TokStart, CurPtr - TokStart);
-        llvm::SmallString<32> replacement;
-        replacement += '"';
-        std::string str = orig.slice(1, orig.size() - 1).str();
-        std::string quot = "\"";
-        size_t pos = 0;
-        while (pos != str.length()) {
-          if (str.at(pos) == '\\') {
-            if (str.at(pos + 1) == '\'') {
-                // Un-escape escaped single quotes.
-                str.replace(pos, 2, "'");
-                ++pos;
-            } else {
-                // Skip over escaped characters.
-                pos += 2;
-            }
-          } else if (str.at(pos) == '"') {
-            str.replace(pos, 1, "\\\"");
-            // Advance past the newly added ["\""].
-            pos += 2;
-          } else {
-            ++pos;
-          }
-        }
-        replacement += StringRef(str);
-        replacement += '"';
-        diagnose(TokStart, diag::lex_single_quote_string)
-          .fixItReplaceChars(getSourceLoc(TokStart), getSourceLoc(CurPtr),
-                             replacement);
-      }
-
-      // Is this the end of multiline/custom-delimited string literal?
-      if ((!IsMultilineString || advanceIfMultilineDelimiter(CurPtr, Diags)) &&
-          delimiterMatches(CustomDelimiterLen, CurPtr, Diags, true)) {
-        TokStart -= CustomDelimiterLen;
-        if (wasErroneous)
-          return formToken(tok::unknown, TokStart);
-
-        formToken(tok::string_literal, TokStart,
-                  IsMultilineString, CustomDelimiterLen);
-        if (IsMultilineString && Diags)
-          validateMultilineIndents(NextToken, Diags);
-        return;
-      }
-    }
   }
+
+  if (QuoteChar == '\'') {
+    assert(!IsMultilineString && CustomDelimiterLen == 0 &&
+           "Single quoted string cannot have custom delimitor, nor multiline");
+    diagnoseSingleQuoteStringLiteral(TokStart, CurPtr, Diags);
+  }
+
+  if (wasErroneous)
+    return formToken(tok::unknown, TokStart);
+
+  return formStringLiteralToken(TokStart, IsMultilineString,
+                                CustomDelimiterLen);
 }
 
 
@@ -2232,9 +2249,8 @@
     IsFirstSegment = false;
 
     // Find the closing ')'.
-    const char *End = skipToEndOfInterpolatedExpression(BytesPtr,
-                                                        Str.getText().end(),
-                                                        Diags, MultilineString);
+    const char *End = skipToEndOfInterpolatedExpression(
+        BytesPtr, Str.getText().end(), MultilineString);
     assert(*End == ')' && "invalid string literal interpolations should"
            " not be returned as string literals");
     ++End;
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index e0fd920..95521e0 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -240,8 +240,8 @@
 
       StringRef Text = SM.extractText({ Loc, Len });
       Token NewTok;
-      NewTok.setToken(tok::string_literal, Text,
-                      IsMultiline, CustomDelimiterLen);
+      NewTok.setToken(tok::string_literal, Text);
+      NewTok.setStringLiteral(IsMultiline, CustomDelimiterLen);
       Toks.push_back(NewTok);
 
     } else {
diff --git a/lib/ParseSIL/ParseSIL.cpp b/lib/ParseSIL/ParseSIL.cpp
index e655e14..75d0bc7 100644
--- a/lib/ParseSIL/ParseSIL.cpp
+++ b/lib/ParseSIL/ParseSIL.cpp
@@ -181,7 +181,8 @@
     ProtocolConformance *
     parseProtocolConformanceHelper(ProtocolDecl *&proto,
                                    GenericEnvironment *GenericEnv,
-                                   bool localScope);
+                                   bool localScope,
+                                   ProtocolDecl *defaultForProto);
   public:
     SILParser(Parser &P)
         : P(P), SILMod(static_cast<SILParserTUState *>(P.SIL)->M),
@@ -391,15 +392,18 @@
     bool isStartOfSILInstruction();
 
     bool parseSubstitutions(SmallVectorImpl<ParsedSubstitution> &parsed,
-                            GenericEnvironment *GenericEnv=nullptr);
+                            GenericEnvironment *GenericEnv=nullptr,
+                            ProtocolDecl *defaultForProto = nullptr);
 
     ProtocolConformance *parseProtocolConformance(ProtocolDecl *&proto,
                              GenericEnvironment *&genericEnv,
-                             bool localScope);
-    ProtocolConformance *parseProtocolConformance() {
+                             bool localScope,
+                             ProtocolDecl *defaultForProto);
+    ProtocolConformance *parseProtocolConformance(
+                                              ProtocolDecl *defaultForProto) {
       ProtocolDecl *dummy;
       GenericEnvironment *env;
-      return parseProtocolConformance(dummy, env, true);
+      return parseProtocolConformance(dummy, env, true, defaultForProto);
     }
 
     Optional<llvm::coverage::Counter>
@@ -1012,6 +1016,8 @@
 
   if (!DC)
     DC = &P.SF;
+  else if (!GenericEnv)
+    GenericEnv = DC->getGenericEnvironmentOfContext();
 
   return swift::performTypeLocChecking(P.Context, T,
                                        /*isSILMode=*/true, IsSILType,
@@ -1510,10 +1516,46 @@
   return false;
 }
 
+/// Bind any unqualified 'Self' references to the given protocol's 'Self'
+/// generic parameter.
+///
+/// FIXME: This is a hack to work around the lack of a DeclContext for
+/// witness tables.
+static void bindProtocolSelfInTypeRepr(TypeLoc &TL, ProtocolDecl *proto) {
+  if (auto typeRepr = TL.getTypeRepr()) {
+    // AST walker to update 'Self' references.
+    class BindProtocolSelf : public ASTWalker {
+      ProtocolDecl *proto;
+      GenericTypeParamDecl *selfParam;
+      Identifier selfId;
+
+    public:
+      BindProtocolSelf(ProtocolDecl *proto)
+        : proto(proto),
+          selfParam(proto->getProtocolSelfType()->getDecl()),
+          selfId(proto->getASTContext().Id_Self) {
+      }
+
+      virtual bool walkToTypeReprPre(TypeRepr *T) override {
+        if (auto ident = dyn_cast<IdentTypeRepr>(T)) {
+          auto firstComponent = ident->getComponentRange().front();
+          if (firstComponent->getIdentifier() == selfId)
+            firstComponent->setValue(selfParam, proto);
+        }
+
+        return true;
+      }
+    };
+
+    typeRepr->walk(BindProtocolSelf(proto));
+  }
+}
+
 /// Parse the substitution list for an apply instruction or
 /// specialized protocol conformance.
 bool SILParser::parseSubstitutions(SmallVectorImpl<ParsedSubstitution> &parsed,
-                                   GenericEnvironment *GenericEnv) {
+                                   GenericEnvironment *GenericEnv,
+                                   ProtocolDecl *defaultForProto) {
   // Check for an opening '<' bracket.
   if (!P.Tok.isContextualPunctuator("<"))
     return false;
@@ -1529,7 +1571,10 @@
     if (TyR.isNull())
       return true;
     TypeLoc Ty = TyR.get();
-    if (performTypeLocChecking(Ty, /*IsSILType=*/ false, GenericEnv))
+    if (defaultForProto)
+      bindProtocolSelfInTypeRepr(Ty, defaultForProto);
+    if (performTypeLocChecking(Ty, /*IsSILType=*/ false, GenericEnv,
+                               defaultForProto))
       return true;
     parsed.push_back({Loc, Ty.getType()});
   } while (P.consumeIf(tok::comma));
@@ -5725,7 +5770,8 @@
 ProtocolConformance *SILParser::parseProtocolConformance(
            ProtocolDecl *&proto,
            GenericEnvironment *&genericEnv,
-           bool localScope) {
+           bool localScope,
+           ProtocolDecl *defaultForProto) {
   // Parse generic params for the protocol conformance. We need to make sure
   // they have the right scope.
   Optional<Scope> GenericsScope;
@@ -5741,7 +5787,8 @@
   }
 
   ProtocolConformance *retVal =
-      parseProtocolConformanceHelper(proto, genericEnv, localScope);
+      parseProtocolConformanceHelper(proto, genericEnv, localScope,
+                                     defaultForProto);
 
   if (localScope) {
     GenericsScope.reset();
@@ -5752,13 +5799,19 @@
 ProtocolConformance *SILParser::parseProtocolConformanceHelper(
                                     ProtocolDecl *&proto,
                                     GenericEnvironment *witnessEnv,
-                                    bool localScope) {
+                                    bool localScope,
+                                    ProtocolDecl *defaultForProto) {
   // Parse AST type.
   ParserResult<TypeRepr> TyR = P.parseType();
   if (TyR.isNull())
     return nullptr;
   TypeLoc Ty = TyR.get();
-  if (performTypeLocChecking(Ty, /*IsSILType=*/ false, witnessEnv))
+  if (defaultForProto) {
+    bindProtocolSelfInTypeRepr(Ty, defaultForProto);
+  }
+
+  if (performTypeLocChecking(Ty, /*IsSILType=*/ false, witnessEnv,
+                             defaultForProto))
     return nullptr;
   auto ConformingTy = Ty.getType();
 
@@ -5770,7 +5823,7 @@
 
     // Parse substitutions for specialized conformance.
     SmallVector<ParsedSubstitution, 4> parsedSubs;
-    if (parseSubstitutions(parsedSubs, witnessEnv))
+    if (parseSubstitutions(parsedSubs, witnessEnv, defaultForProto))
       return nullptr;
 
     if (P.parseToken(tok::l_paren, diag::expected_sil_witness_lparen))
@@ -5778,7 +5831,8 @@
     ProtocolDecl *dummy;
     GenericEnvironment *specializedEnv;
     auto genericConform =
-        parseProtocolConformance(dummy, specializedEnv, localScope);
+        parseProtocolConformance(dummy, specializedEnv, localScope,
+                                 defaultForProto);
     if (!genericConform)
       return nullptr;
     if (P.parseToken(tok::r_paren, diag::expected_sil_witness_rparen))
@@ -5799,7 +5853,7 @@
 
     if (P.parseToken(tok::l_paren, diag::expected_sil_witness_lparen))
       return nullptr;
-    auto baseConform = parseProtocolConformance();
+    auto baseConform = parseProtocolConformance(defaultForProto);
     if (!baseConform)
       return nullptr;
     if (P.parseToken(tok::r_paren, diag::expected_sil_witness_rparen))
@@ -5812,41 +5866,6 @@
   return retVal;
 }
 
-/// Bind any unqualified 'Self' references to the given protocol's 'Self'
-/// generic parameter.
-///
-/// FIXME: This is a hack to work around the lack of a DeclContext for
-/// witness tables.
-static void bindProtocolSelfInTypeRepr(TypeLoc &TL, ProtocolDecl *proto) {
-  if (auto typeRepr = TL.getTypeRepr()) {
-    // AST walker to update 'Self' references.
-    class BindProtocolSelf : public ASTWalker {
-      ProtocolDecl *proto;
-      GenericTypeParamDecl *selfParam;
-      Identifier selfId;
-
-    public:
-      BindProtocolSelf(ProtocolDecl *proto)
-        : proto(proto),
-          selfParam(proto->getProtocolSelfType()->getDecl()),
-          selfId(proto->getASTContext().Id_Self) {
-      }
-
-      virtual bool walkToTypeReprPre(TypeRepr *T) override {
-        if (auto ident = dyn_cast<IdentTypeRepr>(T)) {
-          auto firstComponent = ident->getComponentRange().front();
-          if (firstComponent->getIdentifier() == selfId)
-            firstComponent->setValue(selfParam, proto);
-        }
-
-        return true;
-      }
-    };
-
-    typeRepr->walk(BindProtocolSelf(proto));
-  }
-}
-
 /// Parser a single SIL vtable entry and add it to either \p witnessEntries
 /// or \c conditionalConformances.
 static bool parseSILVTableEntry(
@@ -5859,6 +5878,7 @@
          std::vector<SILWitnessTable::Entry> &witnessEntries,
          std::vector<SILWitnessTable::ConditionalConformance>
            &conditionalConformances) {
+  ProtocolDecl *defaultForProto = isDefaultWitnessTable ? proto : nullptr;
   Identifier EntryKeyword;
   SourceLoc KeywordLoc;
   if (P.parseIdentifier(EntryKeyword, KeywordLoc,
@@ -5878,7 +5898,8 @@
       return true;
     if (P.parseToken(tok::colon, diag::expected_sil_witness_colon))
       return true;
-    ProtocolConformance *conform = witnessState.parseProtocolConformance();
+    ProtocolConformance *conform =
+      witnessState.parseProtocolConformance(defaultForProto);
     if (!conform) // Ignore this witness entry for now.
       return false;
 
@@ -5925,7 +5946,7 @@
 
     ProtocolConformanceRef conformance(proto);
     if (P.Tok.getText() != "dependent") {
-      auto concrete = witnessState.parseProtocolConformance();
+      auto concrete = witnessState.parseProtocolConformance(defaultForProto);
       if (!concrete) // Ignore this witness entry for now.
         return false;
       conformance = ProtocolConformanceRef(concrete);
@@ -6045,7 +6066,8 @@
   GenericEnvironment *witnessEnv;
   auto conf = WitnessState.parseProtocolConformance(proto,
                                                     witnessEnv,
-                                                    false/*localScope*/);
+                                                    false/*localScope*/,
+                                                    nullptr);
   WitnessState.ContextGenericEnv = witnessEnv;
 
   NormalProtocolConformance *theConformance = conf ?
diff --git a/lib/SILGen/SILGenType.cpp b/lib/SILGen/SILGenType.cpp
index 1350026..4182f48 100644
--- a/lib/SILGen/SILGenType.cpp
+++ b/lib/SILGen/SILGenType.cpp
@@ -769,7 +769,19 @@
   }
 
   void addAssociatedConformance(const AssociatedConformance &req) {
-    addMissingDefault();
+    auto witness =
+        Proto->getDefaultAssociatedConformanceWitness(
+          req.getAssociation(),
+          req.getAssociatedRequirement());
+    if (!witness)
+      return addMissingDefault();
+
+    auto entry =
+        SILWitnessTable::AssociatedTypeProtocolWitness{
+          req.getAssociation(),
+          req.getAssociatedRequirement(),
+          *witness};
+    DefaultWitnesses.push_back(entry);
   }
 };
 
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index bf1f963..194f65b 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -4689,7 +4689,25 @@
   (void)decl->isDynamic();
 }
 
-bool swift::isPassThroughTypealias(TypeAliasDecl *typealias) {
+/// Determine whether this is a "pass-through" typealias, which has the
+/// same type parameters as the nominal type it references and specializes
+/// the underlying nominal type with exactly those type parameters.
+/// For example, the following typealias \c GX is a pass-through typealias:
+///
+/// \code
+/// struct X<T, U> { }
+/// typealias GX<A, B> = X<A, B>
+/// \endcode
+///
+/// whereas \c GX2 and \c GX3 are not pass-through because \c GX2 has
+/// different type parameters and \c GX3 doesn't pass its type parameters
+/// directly through.
+///
+/// \code
+/// typealias GX2<A> = X<A, A>
+/// typealias GX3<A, B> = X<B, A>
+/// \endcode
+static bool isPassThroughTypealias(TypeAliasDecl *typealias) {
   // Pass-through only makes sense when the typealias refers to a nominal
   // type.
   Type underlyingType = typealias->getUnderlyingTypeLoc().getType();
@@ -4877,31 +4895,78 @@
   if (ext->hasValidationStarted())
     return;
 
-  bindExtension(ext);
-
   DeclValidationRAII IBV(ext);
 
-  // If the extension is already known to be invalid, we're done.
-  if (ext->isInvalid())
-    return;
+  auto dc = ext->getDeclContext();
 
-  // FIXME: We need to check whether anything is specialized, because
-  // the innermost extended type might itself be a non-generic type
-  // within a generic type.
+  // If we didn't parse a type, fill in an error type and bail out.
+  if (!ext->getExtendedTypeLoc().getTypeRepr()) {
+    ext->setInvalid();
+    ext->getExtendedTypeLoc().setInvalidType(Context);
+    return;
+  }
+
+  // Validate the extended type.
+  TypeResolutionOptions options(TypeResolverContext::ExtensionBinding);
+  options |= TypeResolutionFlags::AllowUnboundGenerics;
+  if (validateType(ext->getExtendedTypeLoc(),
+                   TypeResolution::forContextual(dc), options)) {
+    ext->setInvalid();
+    ext->getExtendedTypeLoc().setInvalidType(Context);
+    return;
+  }
+
+  // Dig out the extended type.
   auto extendedType = ext->getExtendedType();
 
-  if (extendedType.isNull() || extendedType->hasError())
+  // Hack to allow extending a generic typealias.
+  if (auto *unboundGeneric = extendedType->getAs<UnboundGenericType>()) {
+    if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(unboundGeneric->getDecl())) {
+      auto extendedNominal = aliasDecl->getDeclaredInterfaceType()->getAnyNominal();
+      if (extendedNominal) {
+        extendedType = extendedNominal->getDeclaredType();
+        if (!isPassThroughTypealias(aliasDecl))
+          ext->getExtendedTypeLoc().setType(extendedType);
+      }
+    }
+  }
+
+  // Cannot extend a metatype.
+  if (extendedType->is<AnyMetatypeType>()) {
+    diagnose(ext->getLoc(), diag::extension_metatype, extendedType)
+      .highlight(ext->getExtendedTypeLoc().getSourceRange());
+    ext->setInvalid();
+    ext->getExtendedTypeLoc().setInvalidType(Context);
+    return;
+  }
+
+  // Cannot extend a bound generic type.
+  if (extendedType->isSpecialized()) {
+    diagnose(ext->getLoc(), diag::extension_specialization,
+             extendedType->getAnyNominal()->getName())
+      .highlight(ext->getExtendedTypeLoc().getSourceRange());
+    ext->setInvalid();
+    ext->getExtendedTypeLoc().setInvalidType(Context);
+    return;
+  }
+
+  auto *nominal = extendedType->getAnyNominal();
+
+  // Cannot extend function types, tuple types, etc.
+  if (nominal == nullptr) {
+    diagnose(ext->getLoc(), diag::non_nominal_extension, extendedType)
+      .highlight(ext->getExtendedTypeLoc().getSourceRange());
+    ext->setInvalid();
+    ext->getExtendedTypeLoc().setInvalidType(Context);
+    return;
+  }
+
+  // Extensions nested inside other declarations are invalid and we
+  // do not bind them.
+  if (!isa<SourceFile>(dc))
     return;
 
   // Validate the nominal type declaration being extended.
-  NominalTypeDecl *nominal = extendedType->getAnyNominal();
-  if (!nominal) {
-    auto unbound = cast<UnboundGenericType>(extendedType.getPointer());
-    auto typealias = cast<TypeAliasDecl>(unbound->getDecl());
-    validateDecl(typealias);
-
-    nominal = typealias->getUnderlyingTypeLoc().getType()->getAnyNominal();
-  }
   validateDecl(nominal);
 
   if (nominal->getGenericParamsOfContext()) {
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 9cc6860..4b1f7a5 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -5252,6 +5252,30 @@
 void TypeChecker::inferDefaultWitnesses(ProtocolDecl *proto) {
   DefaultWitnessChecker checker(*this, proto);
 
+  // Find the default for the given associated type.
+  auto findAssociatedTypeDefault =
+      [&](AssociatedTypeDecl *assocType,
+      AssociatedTypeDecl **defaultedAssocTypeOut = nullptr) -> Type {
+    auto defaultedAssocType =
+      AssociatedTypeInference::findDefaultedAssociatedType(*this, assocType);
+    if (!defaultedAssocType)
+      return nullptr;;
+
+    Type defaultType = defaultedAssocType->getDefaultDefinitionLoc().getType();
+    if (!defaultType)
+      return nullptr;
+
+    // Map out of its protocol context...
+    defaultType = defaultType->mapTypeOutOfContext();
+    if (defaultType->hasError())
+      return nullptr;
+
+    if (defaultedAssocTypeOut)
+      *defaultedAssocTypeOut = defaultedAssocType;
+
+    return defaultType;
+  };
+
   for (auto *requirement : proto->getMembers()) {
     if (requirement->isInvalid())
       continue;
@@ -5262,19 +5286,8 @@
 
     if (auto assocType = dyn_cast<AssociatedTypeDecl>(valueDecl)) {
       if (assocType->getOverriddenDecls().empty()) {
-        if (auto defaultedAssocType =
-                AssociatedTypeInference::findDefaultedAssociatedType(
-                  *this, assocType)) {
-          Type defaultType =
-            defaultedAssocType->getDefaultDefinitionLoc().getType();
-
-          // Map out of its protocol context...
-          defaultType = defaultType->mapTypeOutOfContext();
-
-          if (!defaultType->hasError()) {
-            proto->setDefaultTypeWitness(assocType, defaultType);
-          }
-        }
+        if (Type defaultType = findAssociatedTypeDefault(assocType))
+          proto->setDefaultTypeWitness(assocType, defaultType);
       }
 
       continue;
@@ -5288,6 +5301,77 @@
 
     checker.resolveWitnessViaLookup(valueDecl);
   }
+
+  // Find defaults for any associated conformances rooted on defaulted
+  // associated types.
+  for (const auto &req : proto->getRequirementSignature()) {
+    if (req.getKind() != RequirementKind::Conformance)
+      continue;
+    if (req.getFirstType()->isEqual(proto->getProtocolSelfType()))
+      continue;
+
+    // Find the innermost dependent member type (e.g., Self.AssocType), so
+    // we can look at the associated type.
+    auto depMemTy = req.getFirstType()->getAs<DependentMemberType>();
+    if (!depMemTy)
+      continue;
+
+    while (auto innerDepMemTy =
+             depMemTy->getBase()->getAs<DependentMemberType>())
+      depMemTy = innerDepMemTy;
+
+    if (!depMemTy->getBase()->isEqual(proto->getProtocolSelfType()))
+      continue;
+
+    auto assocType = depMemTy->getAssocType();
+    if (!assocType)
+      continue;
+
+    // Find the associated type nearest our own protocol, which might have
+    // a default not available in the associated type referenced by the
+    // (canonicalized) requirement.
+    if (assocType->getProtocol() != proto) {
+      SmallVector<ValueDecl *, 2> found;
+      proto->getModuleContext()->lookupQualified(
+                           proto, assocType->getFullName(),
+                           NL_QualifiedDefault|NL_ProtocolMembers|NL_OnlyTypes,
+                           found);
+      if (found.size() == 1 && isa<AssociatedTypeDecl>(found[0]))
+        assocType = cast<AssociatedTypeDecl>(found[0]);
+    }
+
+    // Dig out the default associated type definition.
+    AssociatedTypeDecl *defaultedAssocType = nullptr;
+    Type defaultAssocType = findAssociatedTypeDefault(assocType,
+                                                      &defaultedAssocType);
+    if (!defaultAssocType)
+      continue;
+
+    Type defaultAssocTypeInContext =
+      proto->mapTypeIntoContext(defaultAssocType);
+    auto requirementProto =
+      req.getSecondType()->castTo<ProtocolType>()->getDecl();
+    auto conformance = conformsToProtocol(defaultAssocTypeInContext,
+                                          requirementProto, proto,
+                                          ConformanceCheckFlags::Used);
+    if (!conformance) {
+      // Diagnose the lack of a conformance. This is potentially an ABI
+      // incompatibility.
+      diagnose(proto, diag::assoc_type_default_conformance_failed,
+               defaultAssocType, assocType->getFullName(), req.getFirstType(),
+               req.getSecondType());
+      diagnose(defaultedAssocType, diag::assoc_type_default_here,
+               assocType->getFullName(), defaultAssocType)
+        .highlight(
+          defaultedAssocType->getDefaultDefinitionLoc().getSourceRange());
+
+      continue;
+    }
+
+    // Record the default associated conformance.
+    proto->setDefaultAssociatedConformanceWitness(
+        req.getFirstType()->getCanonicalType(), requirementProto, *conformance);
+  }
 }
 
 void TypeChecker::recordKnownWitness(NormalProtocolConformance *conformance,
diff --git a/lib/Sema/TypeCheckProtocolInference.cpp b/lib/Sema/TypeCheckProtocolInference.cpp
index 8f441ac..615cb50 100644
--- a/lib/Sema/TypeCheckProtocolInference.cpp
+++ b/lib/Sema/TypeCheckProtocolInference.cpp
@@ -183,15 +183,19 @@
     if (extension == conformanceExtension)
       return true;
 
-    tc.bindExtension(extension);
+    auto *extendedNominal = extension->getExtendedNominal();
+
+    // Invalid case.
+    if (extendedNominal == nullptr)
+      return true;
 
     // Assume unconstrained concrete extensions we found witnesses in are
     // always viable.
-    if (!extension->getExtendedType()->isAnyExistentialType()) {
-      // TODO: When constrained extensions are a thing, we'll need an "is
-      // as specialized as" kind of check here.
+    if (!isa<ProtocolDecl>(extendedNominal))
       return !extension->isConstrainedExtension();
-    }
+
+    // Build a generic signature.
+    tc.validateExtension(extension);
 
     // The extension may not have a generic signature set up yet, as a
     // recursion breaker, in which case we can't yet confidently reject its
diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp
index 07fe209..90ab00d 100644
--- a/lib/Sema/TypeChecker.cpp
+++ b/lib/Sema/TypeChecker.cpp
@@ -346,80 +346,6 @@
   nominal->addExtension(ext);
 }
 
-static void bindExtensionDecl(ExtensionDecl *ED, TypeChecker &TC) {
-  if (ED->getExtendedType())
-    return;
-
-  // If we didn't parse a type, fill in an error type and bail out.
-  if (!ED->getExtendedTypeLoc().getTypeRepr()) {
-    ED->setInvalid();
-    ED->getExtendedTypeLoc().setInvalidType(TC.Context);
-    return;
-  }
-
-  auto dc = ED->getDeclContext();
-
-  // Validate the representation.
-  // FIXME: Perform some kind of "shallow" validation here?
-  TypeResolutionOptions options(TypeResolverContext::ExtensionBinding);
-  options |= TypeResolutionFlags::AllowUnboundGenerics;
-  if (TC.validateType(ED->getExtendedTypeLoc(),
-                      TypeResolution::forContextual(dc), options)) {
-    ED->setInvalid();
-    ED->getExtendedTypeLoc().setInvalidType(TC.Context);
-    return;
-  }
-
-  // Dig out the extended type.
-  auto extendedType = ED->getExtendedType();
-
-  // Hack to allow extending a generic typealias.
-  if (auto *unboundGeneric = extendedType->getAs<UnboundGenericType>()) {
-    if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(unboundGeneric->getDecl())) {
-      auto extendedNominal = aliasDecl->getDeclaredInterfaceType()->getAnyNominal();
-      if (extendedNominal) {
-        extendedType = extendedNominal->getDeclaredType();
-        if (!isPassThroughTypealias(aliasDecl))
-          ED->getExtendedTypeLoc().setType(extendedType);
-      }
-    }
-  }
-
-  // Handle easy cases.
-
-  // Cannot extend a metatype.
-  if (extendedType->is<AnyMetatypeType>()) {
-    TC.diagnose(ED->getLoc(), diag::extension_metatype, extendedType)
-      .highlight(ED->getExtendedTypeLoc().getSourceRange());
-    ED->setInvalid();
-    ED->getExtendedTypeLoc().setInvalidType(TC.Context);
-    return;
-  }
-
-  // Cannot extend a bound generic type.
-  if (extendedType->isSpecialized()) {
-    TC.diagnose(ED->getLoc(), diag::extension_specialization,
-                extendedType->getAnyNominal()->getName())
-      .highlight(ED->getExtendedTypeLoc().getSourceRange());
-    ED->setInvalid();
-    ED->getExtendedTypeLoc().setInvalidType(TC.Context);
-    return;
-  }
-
-  // Dig out the nominal type being extended.
-  NominalTypeDecl *extendedNominal = extendedType->getAnyNominal();
-  if (!extendedNominal) {
-    TC.diagnose(ED->getLoc(), diag::non_nominal_extension, extendedType)
-      .highlight(ED->getExtendedTypeLoc().getSourceRange());
-    ED->setInvalid();
-    ED->getExtendedTypeLoc().setInvalidType(TC.Context);
-    return;
-  }
-  assert(extendedNominal && "Should have the nominal type being extended");
-
-  bindExtensionToNominal(ED, extendedNominal);
-}
-
 static void bindExtensions(SourceFile &SF, TypeChecker &TC) {
   // Utility function to try and resolve the extended type without diagnosing.
   // If we succeed, we go ahead and bind the extension. Otherwise, return false.
@@ -467,14 +393,8 @@
     }
   } while(changed);
 
-  // Phase 3 - anything that remains on the worklist cannot be resolved, which
-  // means its invalid. Diagnose.
-  for (auto *ext : worklist)
-    bindExtensionDecl(ext, TC);
-}
-
-void TypeChecker::bindExtension(ExtensionDecl *ext) {
-  ::bindExtensionDecl(ext, *this);
+  // Any remaining extensions are invalid. They will be diagnosed later by
+  // typeCheckDecl().
 }
 
 static void typeCheckFunctionsAndExternalDecls(SourceFile &SF, TypeChecker &TC) {
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index 6dc3db3..6d13959 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -1106,8 +1106,6 @@
     validateDecl(proto);
   }
 
-  virtual void bindExtension(ExtensionDecl *ext) override;
-
   virtual void resolveExtension(ExtensionDecl *ext) override {
     validateExtension(ext);
   }
@@ -2173,26 +2171,6 @@
                                               DeclContext *DC,
                                               TypeChecker &TC);
 
-/// Determine whether this is a "pass-through" typealias, which has the
-/// same type parameters as the nominal type it references and specializes
-/// the underlying nominal type with exactly those type parameters.
-/// For example, the following typealias \c GX is a pass-through typealias:
-///
-/// \code
-/// struct X<T, U> { }
-/// typealias GX<A, B> = X<A, B>
-/// \endcode
-///
-/// whereas \c GX2 and \c GX3 are not pass-through because \c GX2 has
-/// different type parameters and \c GX3 doesn't pass its type parameters
-/// directly through.
-///
-/// \code
-/// typealias GX2<A> = X<A, A>
-/// typealias GX3<A, B> = X<B, A>
-/// \endcode
-bool isPassThroughTypealias(TypeAliasDecl *typealias);
-
 /// Whether an overriding declaration requires the 'override' keyword.
 enum class OverrideRequiresKeyword {
   /// The keyword is never required.
diff --git a/lib/Serialization/SerializedModuleLoader.cpp b/lib/Serialization/SerializedModuleLoader.cpp
index 09b95d2..a97621d 100644
--- a/lib/Serialization/SerializedModuleLoader.cpp
+++ b/lib/Serialization/SerializedModuleLoader.cpp
@@ -326,9 +326,19 @@
   if (auto orphanedBuffer = loadedModuleFile->takeBufferForDiagnostics())
     OrphanedMemoryBuffers.push_back(std::move(orphanedBuffer));
 
-  if (!diagLoc)
-    return nullptr;
+  if (diagLoc)
+    serialization::diagnoseSerializedASTLoadFailure(
+        Ctx, *diagLoc, loadInfo, extendedInfo, moduleBufferID,
+        moduleDocBufferID, loadedModuleFile.get(), M.getName());
+  return nullptr;
+}
 
+void swift::serialization::diagnoseSerializedASTLoadFailure(
+    ASTContext &Ctx, SourceLoc diagLoc,
+    const serialization::ValidationInfo &loadInfo,
+    const serialization::ExtendedValidationInfo &extendedInfo,
+    StringRef moduleBufferID, StringRef moduleDocBufferID,
+    ModuleFile *loadedModuleFile, Identifier ModuleName) {
   auto diagnoseDifferentLanguageVersion = [&](StringRef shortVersion) -> bool {
     if (shortVersion.empty())
       return false;
@@ -339,10 +349,9 @@
     if (versionString.str() == shortVersion)
       return false;
 
-    Ctx.Diags.diagnose(*diagLoc,
-                       diag::serialization_module_language_version_mismatch,
-                       loadInfo.shortVersion, versionString.str(),
-                       moduleBufferID);
+    Ctx.Diags.diagnose(
+        diagLoc, diag::serialization_module_language_version_mismatch,
+        loadInfo.shortVersion, versionString.str(), moduleBufferID);
     return true;
   };
 
@@ -353,23 +362,23 @@
   case serialization::Status::FormatTooNew:
     if (diagnoseDifferentLanguageVersion(loadInfo.shortVersion))
       break;
-    Ctx.Diags.diagnose(*diagLoc, diag::serialization_module_too_new,
+    Ctx.Diags.diagnose(diagLoc, diag::serialization_module_too_new,
                        moduleBufferID);
     break;
   case serialization::Status::FormatTooOld:
     if (diagnoseDifferentLanguageVersion(loadInfo.shortVersion))
       break;
-    Ctx.Diags.diagnose(*diagLoc, diag::serialization_module_too_old,
-                       M.getName(), moduleBufferID);
+    Ctx.Diags.diagnose(diagLoc, diag::serialization_module_too_old, ModuleName,
+                       moduleBufferID);
     break;
   case serialization::Status::Malformed:
-    Ctx.Diags.diagnose(*diagLoc, diag::serialization_malformed_module,
+    Ctx.Diags.diagnose(diagLoc, diag::serialization_malformed_module,
                        moduleBufferID);
     break;
 
   case serialization::Status::MalformedDocumentation:
     assert(!moduleDocBufferID.empty());
-    Ctx.Diags.diagnose(*diagLoc, diag::serialization_malformed_module,
+    Ctx.Diags.diagnose(diagLoc, diag::serialization_malformed_module,
                        moduleDocBufferID);
     break;
 
@@ -379,19 +388,19 @@
     // not now.
     llvm::StringSet<> duplicates;
     llvm::SmallVector<ModuleFile::Dependency, 4> missing;
-    std::copy_if(loadedModuleFile->getDependencies().begin(),
-                 loadedModuleFile->getDependencies().end(),
-                 std::back_inserter(missing),
-                 [&duplicates](const ModuleFile::Dependency &dependency)->bool {
-      if (dependency.isLoaded() || dependency.isHeader())
-        return false;
-      return duplicates.insert(dependency.RawPath).second;
-    });
+    std::copy_if(
+        loadedModuleFile->getDependencies().begin(),
+        loadedModuleFile->getDependencies().end(), std::back_inserter(missing),
+        [&duplicates](const ModuleFile::Dependency &dependency) -> bool {
+          if (dependency.isLoaded() || dependency.isHeader())
+            return false;
+          return duplicates.insert(dependency.RawPath).second;
+        });
 
     // FIXME: only show module part of RawAccessPath
     assert(!missing.empty() && "unknown missing dependency?");
     if (missing.size() == 1) {
-      Ctx.Diags.diagnose(*diagLoc,diag::serialization_missing_single_dependency,
+      Ctx.Diags.diagnose(diagLoc, diag::serialization_missing_single_dependency,
                          missing.front().getPrettyPrintedPath());
     } else {
       llvm::SmallString<64> missingNames;
@@ -403,7 +412,7 @@
                  [&] { missingNames += "', '"; });
       missingNames += '\'';
 
-      Ctx.Diags.diagnose(*diagLoc, diag::serialization_missing_dependencies,
+      Ctx.Diags.diagnose(diagLoc, diag::serialization_missing_dependencies,
                          missingNames);
     }
 
@@ -419,24 +428,25 @@
     auto circularDependencyIter =
         llvm::find_if(loadedModuleFile->getDependencies(),
                       [](const ModuleFile::Dependency &next) {
-      return !next.Import.second->hasResolvedImports();
-    });
-    assert(circularDependencyIter != loadedModuleFile->getDependencies().end()
-           && "circular dependency reported, but no module with unresolved "
-              "imports found");
+                        return !next.Import.second->hasResolvedImports();
+                      });
+    assert(circularDependencyIter !=
+               loadedModuleFile->getDependencies().end() &&
+           "circular dependency reported, but no module with unresolved "
+           "imports found");
 
     // FIXME: We should include the path of the circularity as well, but that's
     // hard because we're discovering this /while/ resolving imports, which
     // means the problematic modules haven't been recorded yet.
-    Ctx.Diags.diagnose(*diagLoc, diag::serialization_circular_dependency,
+    Ctx.Diags.diagnose(diagLoc, diag::serialization_circular_dependency,
                        circularDependencyIter->getPrettyPrintedPath(),
-                       M.getName());
+                       ModuleName);
     break;
   }
 
   case serialization::Status::MissingShadowedModule: {
-    Ctx.Diags.diagnose(*diagLoc, diag::serialization_missing_shadowed_module,
-                       M.getName());
+    Ctx.Diags.diagnose(diagLoc, diag::serialization_missing_shadowed_module,
+                       ModuleName);
     if (Ctx.SearchPathOpts.SDKPath.empty() &&
         llvm::Triple(llvm::sys::getProcessTriple()).isMacOSX()) {
       Ctx.Diags.diagnose(SourceLoc(), diag::sema_no_import_no_sdk);
@@ -448,7 +458,7 @@
   case serialization::Status::FailedToLoadBridgingHeader:
     // We already emitted a diagnostic about the bridging header. Just emit
     // a generic message here.
-    Ctx.Diags.diagnose(*diagLoc, diag::serialization_load_failed, M.getName());
+    Ctx.Diags.diagnose(diagLoc, diag::serialization_load_failed, ModuleName);
     break;
 
   case serialization::Status::NameMismatch: {
@@ -457,8 +467,7 @@
     auto diagKind = diag::serialization_name_mismatch;
     if (Ctx.LangOpts.DebuggerSupport)
       diagKind = diag::serialization_name_mismatch_repl;
-    Ctx.Diags.diagnose(*diagLoc, diagKind,
-                       loadInfo.name, M.getName());
+    Ctx.Diags.diagnose(diagLoc, diagKind, loadInfo.name, ModuleName);
     break;
   }
 
@@ -468,8 +477,8 @@
     auto diagKind = diag::serialization_target_incompatible;
     if (Ctx.LangOpts.DebuggerSupport)
       diagKind = diag::serialization_target_incompatible_repl;
-    Ctx.Diags.diagnose(*diagLoc, diagKind,
-                       M.getName(), loadInfo.targetTriple, moduleBufferID);
+    Ctx.Diags.diagnose(diagLoc, diagKind, ModuleName, loadInfo.targetTriple,
+                       moduleBufferID);
     break;
   }
 
@@ -486,14 +495,12 @@
     auto diagKind = diag::serialization_target_too_new;
     if (Ctx.LangOpts.DebuggerSupport)
       diagKind = diag::serialization_target_too_new_repl;
-    Ctx.Diags.diagnose(*diagLoc, diagKind,
-                       compilationOSInfo.first, compilationOSInfo.second,
-                       M.getName(), moduleOSInfo.second, moduleBufferID);
+    Ctx.Diags.diagnose(diagLoc, diagKind, compilationOSInfo.first,
+                       compilationOSInfo.second, ModuleName,
+                       moduleOSInfo.second, moduleBufferID);
     break;
   }
   }
-
-  return nullptr;
 }
 
 bool
diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp
index 68e0d42..384cd05 100644
--- a/lib/TBDGen/TBDGen.cpp
+++ b/lib/TBDGen/TBDGen.cpp
@@ -100,11 +100,8 @@
 }
 
 void TBDGenVisitor::addAssociatedConformanceDescriptor(
-                                                 ProtocolDecl *proto,
-                                                 CanType subject,
-                                                 ProtocolDecl *requirement) {
-  auto entity = LinkEntity::forAssociatedConformanceDescriptor(proto, subject,
-                                                               requirement);
+                                           AssociatedConformance conformance) {
+  auto entity = LinkEntity::forAssociatedConformanceDescriptor(conformance);
   addSymbol(entity);
 }
 
@@ -426,10 +423,11 @@
       if (req.getFirstType()->isEqual(PD->getProtocolSelfType()))
         continue;
 
-      addAssociatedConformanceDescriptor(
-          PD,
-          req.getFirstType()->getCanonicalType(),
-          req.getSecondType()->castTo<ProtocolType>()->getDecl());
+      AssociatedConformance conformance(
+        PD,
+        req.getFirstType()->getCanonicalType(),
+        req.getSecondType()->castTo<ProtocolType>()->getDecl());
+      addAssociatedConformanceDescriptor(conformance);
     }
 
     for (auto *member : PD->getMembers()) {
@@ -442,7 +440,8 @@
         }
       }
 
-      // Always produce associated type descriptors.
+      // Always produce associated type descriptors, because they can
+      // be referenced by generic signatures.
       if (auto *assocType = dyn_cast<AssociatedTypeDecl>(member)) {
         if (assocType->getOverriddenDecls().empty())
           addAssociatedTypeDescriptor(assocType);
diff --git a/lib/TBDGen/TBDGenVisitor.h b/lib/TBDGen/TBDGenVisitor.h
index 9db482e..e468265 100644
--- a/lib/TBDGen/TBDGenVisitor.h
+++ b/lib/TBDGen/TBDGenVisitor.h
@@ -66,9 +66,7 @@
 
   void addProtocolRequirementsBaseDescriptor(ProtocolDecl *proto);
   void addAssociatedTypeDescriptor(AssociatedTypeDecl *assocType);
-  void addAssociatedConformanceDescriptor(ProtocolDecl *proto,
-                                          CanType subject,
-                                          ProtocolDecl *requirement);
+  void addAssociatedConformanceDescriptor(AssociatedConformance conformance);
 
 public:
   TBDGenVisitor(tapi::internal::InterfaceFile &symbols,
diff --git a/stdlib/public/core/Integers.swift b/stdlib/public/core/Integers.swift
index 0418e5a..2c00e90 100644
--- a/stdlib/public/core/Integers.swift
+++ b/stdlib/public/core/Integers.swift
@@ -303,7 +303,7 @@
 ///
 /// - Parameter x: A signed number.
 /// - Returns: The absolute value of `x`.
-@_transparent
+@inlinable
 public func abs<T : SignedNumeric>(_ x: T) -> T
   where T.Magnitude == T {
   return x.magnitude
@@ -322,9 +322,9 @@
 ///
 /// - Parameter x: A signed number.
 /// - Returns: The absolute value of `x`.
-@inlinable // FIXME(sil-serialize-all)
+@inlinable
 public func abs<T : SignedNumeric & Comparable>(_ x: T) -> T {
-  return x < 0 ? -x : x
+  return x < (0 as T) ? -x : x
 }
 
 extension Numeric {
@@ -1185,7 +1185,7 @@
   ///
   /// - Returns: The sign of this number, expressed as an integer of the same
   ///   type.
-  @_transparent
+  @inlinable
   public func signum() -> Self {
     return (self > (0 as Self) ? 1 : 0) - (self < (0 as Self) ? 1 : 0)
   }
@@ -1196,7 +1196,7 @@
     return it.next() ?? 0
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public func _binaryLogarithm() -> Int {
     _precondition(self > (0 as Self))
     var (quotient, remainder) =
@@ -1233,7 +1233,7 @@
   /// - Parameter rhs: The value to divide this value by.
   /// - Returns: A tuple containing the quotient and remainder of this value
   ///   divided by `rhs`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public func quotientAndRemainder(dividingBy rhs: Self)
     -> (quotient: Self, remainder: Self) {
     return (self / rhs, self % rhs)
@@ -1370,7 +1370,7 @@
   ///   - lhs: The value to shift.
   ///   - rhs: The number of bits to shift `lhs` to the right.
   @_semantics("optimize.sil.specialize.generic.partial.never")
-  @inlinable
+  @_transparent
   public static func >> <RHS: BinaryInteger>(lhs: Self, rhs: RHS) -> Self {
     var r = lhs
     r >>= rhs
@@ -1416,7 +1416,7 @@
   ///   - lhs: The value to shift.
   ///   - rhs: The number of bits to shift `lhs` to the left.
   @_semantics("optimize.sil.specialize.generic.partial.never")
-  @inlinable
+  @_transparent
   public static func << <RHS: BinaryInteger>(lhs: Self, rhs: RHS) -> Self {
     var r = lhs
     r <<= rhs
@@ -1493,7 +1493,6 @@
   }
 
   /// A textual representation of this value.
-  @inlinable // FIXME(sil-serialize-all)
   public var description: String {
     return _description(radix: 10, uppercase: false)
   }
@@ -1505,7 +1504,6 @@
 //===----------------------------------------------------------------------===//
 
 extension BinaryInteger {
-  // FIXME(ABI): using Int as the return type is wrong.
   /// Returns the distance from this value to the given value, expressed as a
   /// stride.
   ///
@@ -1514,7 +1512,7 @@
   ///
   /// - Parameter other: The value to calculate the distance to.
   /// - Returns: The distance from this value to `other`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @inline(__always)
   public func distance(to other: Self) -> Int {
     if !Self.isSigned {
@@ -1542,7 +1540,6 @@
     _preconditionFailure("Distance is not representable in Int")
   }
 
-  // FIXME(ABI): using Int as the parameter type is wrong.
   /// Returns a value that is offset the specified distance from this value.
   ///
   /// Use the `advanced(by:)` method in generic code to offset a value by a
@@ -1554,7 +1551,7 @@
   ///
   /// - Parameter n: The distance to advance this value.
   /// - Returns: A value that is offset from this value by `n`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @inline(__always)
   public func advanced(by n: Int) -> Self {
     if !Self.isSigned {
@@ -1594,8 +1591,7 @@
   /// - Parameters:
   ///   - lhs: An integer to compare.
   ///   - rhs: Another integer to compare.
-  @inlinable // FIXME(sil-serialize-all)
-  @inline(__always)
+  @_transparent
   public static func == <
     Other : BinaryInteger
   >(lhs: Self, rhs: Other) -> Bool {
@@ -1669,8 +1665,7 @@
   /// - Parameters:
   ///   - lhs: An integer to compare.
   ///   - rhs: Another integer to compare.
-  @inlinable // FIXME(sil-serialize-all)
-  @inline(__always)
+  @_transparent
   public static func < <Other : BinaryInteger>(lhs: Self, rhs: Other) -> Bool {
     let lhsNegative = Self.isSigned && lhs < (0 as Self)
     let rhsNegative = Other.isSigned && rhs < (0 as Other)
@@ -1713,7 +1708,6 @@
   ///   - lhs: An integer to compare.
   ///   - rhs: Another integer to compare.
   @_transparent
-  //@inline(__always)
   public static func <= <Other : BinaryInteger>(lhs: Self, rhs: Other) -> Bool {
     return !(rhs < lhs)
   }
@@ -1729,7 +1723,6 @@
   ///   - lhs: An integer to compare.
   ///   - rhs: Another integer to compare.
   @_transparent
-  //@inline(__always)
   public static func >= <Other : BinaryInteger>(lhs: Self, rhs: Other) -> Bool {
     return !(lhs < rhs)
   }
@@ -1745,7 +1738,6 @@
   ///   - lhs: An integer to compare.
   ///   - rhs: Another integer to compare.
   @_transparent
-  //@inline(__always)
   public static func > <Other : BinaryInteger>(lhs: Self, rhs: Other) -> Bool {
     return rhs < lhs
   }
@@ -1773,20 +1765,17 @@
     return !(lhs == rhs)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
-  @inline(__always)
+  @_transparent
   public static func <= (lhs: Self, rhs: Self) -> Bool {
     return !(rhs < lhs)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
-  @inline(__always)
+  @_transparent
   public static func >= (lhs: Self, rhs: Self) -> Bool {
     return !(lhs < rhs)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
-  @inline(__always)
+  @_transparent
   public static func > (lhs: Self, rhs: Self) -> Bool {
     return rhs < lhs
   }
@@ -2214,7 +2203,7 @@
   @inlinable
   public var bitWidth: Int { return Self.bitWidth }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public func _binaryLogarithm() -> Int {
     _precondition(self > (0 as Self))
     return Self.bitWidth &- (leadingZeroBitCount &+ 1)
@@ -2225,7 +2214,7 @@
   ///
   /// - Parameter value: A value to use as the little-endian representation of
   ///   the new integer.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public init(littleEndian value: Self) {
 #if _endian(little)
     self = value
@@ -2239,7 +2228,7 @@
   ///
   /// - Parameter value: A value to use as the big-endian representation of the
   ///   new integer.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public init(bigEndian value: Self) {
 #if _endian(big)
     self = value
@@ -2253,7 +2242,7 @@
   /// If necessary, the byte order of this value is reversed from the typical
   /// byte order of this integer type. On a little-endian platform, for any
   /// integer `x`, `x == x.littleEndian`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public var littleEndian: Self {
 #if _endian(little)
     return self
@@ -2267,7 +2256,7 @@
   /// If necessary, the byte order of this value is reversed from the typical
   /// byte order of this integer type. On a big-endian platform, for any
   /// integer `x`, `x == x.bigEndian`.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   public var bigEndian: Self {
 #if _endian(big)
     return self
@@ -2310,7 +2299,6 @@
   ///   - rhs: The number of bits to shift `lhs` to the right. If `rhs` is
   ///     outside the range `0..<lhs.bitWidth`, it is masked to produce a
   ///     value within that range.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @_transparent
   public static func &>> (lhs: Self, rhs: Self) -> Self {
@@ -2354,7 +2342,7 @@
   ///     outside the range `0..<lhs.bitWidth`, it is masked to produce a
   ///     value within that range.
   @_semantics("optimize.sil.specialize.generic.partial.never")
-  @inlinable
+  @_transparent
   public static func &>> <
     Other : BinaryInteger
   >(lhs: Self, rhs: Other) -> Self {
@@ -2389,7 +2377,6 @@
   ///   - rhs: The number of bits to shift `lhs` to the right. If `rhs` is
   ///     outside the range `0..<lhs.bitWidth`, it is masked to produce a
   ///     value within that range.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @_transparent
   public static func &>>= <
@@ -2432,7 +2419,6 @@
   ///   - rhs: The number of bits to shift `lhs` to the left. If `rhs` is
   ///     outside the range `0..<lhs.bitWidth`, it is masked to produce a
   ///     value within that range.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @_transparent
   public static func &<< (lhs: Self, rhs: Self) -> Self {
@@ -2476,7 +2462,7 @@
   ///     outside the range `0..<lhs.bitWidth`, it is masked to produce a
   ///     value within that range.
   @_semantics("optimize.sil.specialize.generic.partial.never")
-  @inlinable
+  @_transparent
   public static func &<< <
     Other : BinaryInteger
   >(lhs: Self, rhs: Other) -> Self {
@@ -2511,7 +2497,6 @@
   ///   - rhs: The number of bits to shift `lhs` to the left. If `rhs` is
   ///     outside the range `0..<lhs.bitWidth`, it is masked to produce a
   ///     value within that range.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @_transparent
   public static func &<<= <
@@ -2756,7 +2741,6 @@
   /// - Parameters:
   ///   - lhs: The value to shift.
   ///   - rhs: The number of bits to shift `lhs` to the right.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @_transparent
   public static func >> <
@@ -2785,8 +2769,7 @@
     lhs = _nonMaskingRightShift(lhs, shift)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
-  @inline(__always)
+  @_transparent
   public static func _nonMaskingRightShift(_ lhs: Self, _ rhs: Int) -> Self {
     let overshiftR = Self.isSigned ? lhs &>> (Self.bitWidth - 1) : 0
     let overshiftL: Self = 0
@@ -2845,7 +2828,6 @@
   /// - Parameters:
   ///   - lhs: The value to shift.
   ///   - rhs: The number of bits to shift `lhs` to the left.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @_transparent
   public static func << <
@@ -2874,8 +2856,7 @@
     lhs = _nonMaskingLeftShift(lhs, shift)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
-  @inline(__always)
+  @_transparent
   public static func _nonMaskingLeftShift(_ lhs: Self, _ rhs: Int) -> Self {
     let overshiftR = Self.isSigned ? lhs &>> (Self.bitWidth - 1) : 0
     let overshiftL: Self = 0
@@ -2972,9 +2953,8 @@
   ///     // y == nil
   ///
   /// - Parameter source: A floating-point value to convert to an integer.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
-  @inline(__always)
+  @inlinable
   public init?<T : BinaryFloatingPoint>(exactly source: T) {
     let (temporary, exact) = Self._convert(from: source)
     guard exact, let value = temporary else {
@@ -3003,7 +2983,7 @@
   ///     // y == 0
   ///
   /// - Parameter source: An integer to convert to this type.
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @_semantics("optimize.sil.specialize.generic.partial.never")
   public init<Other : BinaryInteger>(clamping source: Other) {
     if _slowPath(source < Self.min) {
@@ -3033,7 +3013,7 @@
   ///
   /// - Parameter rhs: The value to add to this value.
   /// - Returns: The sum of this value and `rhs`.
-  @_transparent
+  @inline(__always)
   public func unsafeAdding(_ other: Self) -> Self {
     let (result, overflow) = self.addingReportingOverflow(other)
 
@@ -3066,7 +3046,7 @@
   ///
   /// - Parameter rhs: The value to subtract from this value.
   /// - Returns: The result of subtracting `rhs` from this value.
-  @_transparent
+  @inline(__always)
   public func unsafeSubtracting(_ other: Self) -> Self {
     let (result, overflow) = self.subtractingReportingOverflow(other)
 
@@ -3099,7 +3079,7 @@
   ///
   /// - Parameter rhs: The value to multiply by this value.
   /// - Returns: The product of this value and `rhs`.
-  @_transparent
+  @inline(__always)
   public func unsafeMultiplied(by other: Self) -> Self {
     let (result, overflow) = self.multipliedReportingOverflow(by: other)
 
@@ -3128,7 +3108,7 @@
   ///
   /// - Parameter rhs: The value to divide this value by.
   /// - Returns: The result of dividing this value by `rhs`.
-  @_transparent
+  @inline(__always)
   public func unsafeDivided(by other: Self) -> Self {
     let (result, overflow) = self.dividedReportingOverflow(by: other)
 
@@ -3179,7 +3159,6 @@
   ///     // 'y' has a binary representation of 11111111_11101011
   ///
   /// - Parameter source: An integer to convert to this type.
-  @inlinable // FIXME(sil-serialize-all)
   @inline(__always)
   public init<T : BinaryInteger>(truncatingIfNeeded source: T) {
     if Self.bitWidth <= Int.bitWidth {
@@ -3421,14 +3400,18 @@
   /// to find an absolute value. In addition, because `abs(_:)` always returns
   /// a value of the same type, even in a generic context, using the function
   /// instead of the `magnitude` property is encouraged.
-  @_transparent
-  public var magnitude: Self { return self }
+  public var magnitude: Self {
+    @inline(__always)
+    get { return self }
+  }
 
   /// A Boolean value indicating whether this type is a signed integer type.
   ///
   /// This property is always `false` for unsigned integer types.
-  @_transparent
-  public static var isSigned: Bool { return false }
+  public static var isSigned: Bool {
+    @inline(__always)
+    get { return false }
+  }
 }
 
 extension UnsignedInteger where Self : FixedWidthInteger {
@@ -3451,7 +3434,6 @@
   ///
   /// - Parameter source: A value to convert to this type of integer. The value
   ///   passed as `source` must be representable in this type.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @inline(__always)
   public init<T : BinaryInteger>(_ source: T) {
@@ -3482,7 +3464,6 @@
   ///     // y == nil
   ///
   /// - Parameter source: A value to convert to this type of integer.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @inline(__always)
   public init?<T : BinaryInteger>(exactly source: T) {
@@ -3503,17 +3484,13 @@
   /// For unsigned integer types, this value is `(2 ** bitWidth) - 1`, where
   /// `**` is exponentiation.
   @_transparent
-  public static var max: Self {
-    return ~0
-  }
+  public static var max: Self { return ~0 }
 
   /// The minimum representable integer in this type.
   ///
   /// For unsigned integer types, this value is always `0`.
   @_transparent
-  public static var min: Self {
-    return 0
-  }
+  public static var min: Self { return 0 }
 }
 
 
@@ -3532,8 +3509,10 @@
   /// A Boolean value indicating whether this type is a signed integer type.
   ///
   /// This property is always `true` for signed integer types.
-  @_transparent
-  public static var isSigned: Bool { return true }
+  public static var isSigned: Bool {
+    @inline(__always)
+    get { return true }
+  }
 }
 
 extension SignedInteger where Self : FixedWidthInteger {
@@ -3556,7 +3535,6 @@
   ///
   /// - Parameter source: A value to convert to this type of integer. The value
   ///   passed as `source` must be representable in this type.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @inline(__always)
   public init<T : BinaryInteger>(_ source: T) {
@@ -3589,7 +3567,6 @@
   ///     // y == nil
   ///
   /// - Parameter source: A value to convert to this type of integer.
-  @inlinable // FIXME(sil-serialize-all)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @inline(__always)
   public init?<T : BinaryInteger>(exactly source: T) {
@@ -3611,9 +3588,7 @@
   /// For signed integer types, this value is `(2 ** (bitWidth - 1)) - 1`,
   /// where `**` is exponentiation.
   @_transparent
-  public static var max: Self {
-    return ~min
-  }
+  public static var max: Self { return ~min }
 
   /// The minimum representable integer in this type.
   ///
@@ -3657,7 +3632,7 @@
 ///
 /// - Parameter x: The integer to convert, and instance of type `T`.
 /// - Returns: The value of `x` converted to type `U`.
-@_transparent
+@inlinable
 public func numericCast<T : BinaryInteger, U : BinaryInteger>(_ x: T) -> U {
   return U(x)
 }
@@ -3669,7 +3644,6 @@
 // At the same time, since they are obsolete in Swift 4, this will not cause
 // `u8 << -1` to fail due to an overflow in an unsigned value.
 extension FixedWidthInteger {
-  @inlinable // FIXME(sil-serialize-all)
   @available(swift, obsoleted: 4)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @_transparent
@@ -3679,7 +3653,6 @@
     return lhs
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   @available(swift, obsoleted: 4)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @_transparent
@@ -3687,7 +3660,6 @@
     _nonMaskingRightShiftGeneric(&lhs, rhs)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   @available(swift, obsoleted: 4)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @_transparent
@@ -3697,7 +3669,6 @@
     return lhs
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   @available(swift, obsoleted: 4)
   @_semantics("optimize.sil.specialize.generic.partial.never")
   @_transparent
@@ -3707,9 +3678,8 @@
 }
 
 extension FixedWidthInteger {
-  @inlinable // FIXME(sil-serialize-all)
   @available(swift, obsoleted: 4, message: "Use addingReportingOverflow(_:) instead.")
-  @_transparent
+  @inlinable
   public static func addWithOverflow(
     _ lhs: Self, _ rhs: Self
   ) -> (Self, overflow: Bool) {
@@ -3718,9 +3688,8 @@
     return (partialValue, overflow: overflow)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
   @available(swift, obsoleted: 4, message: "Use subtractingReportingOverflow(_:) instead.")
-  @_transparent
+  @inlinable
   public static func subtractWithOverflow(
     _ lhs: Self, _ rhs: Self
   ) -> (Self, overflow: Bool) {
@@ -3729,9 +3698,8 @@
     return (partialValue, overflow: overflow)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @available(swift, obsoleted: 4, message: "Use multipliedReportingOverflow(by:) instead.")
-  @_transparent
   public static func multiplyWithOverflow(
     _ lhs: Self, _ rhs: Self
   ) -> (Self, overflow: Bool) {
@@ -3740,9 +3708,8 @@
     return (partialValue, overflow: overflow)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @available(swift, obsoleted: 4, message: "Use dividedReportingOverflow(by:) instead.")
-  @_transparent
   public static func divideWithOverflow(
     _ lhs: Self, _ rhs: Self
   ) -> (Self, overflow: Bool) {
@@ -3751,9 +3718,8 @@
     return (partialValue, overflow: overflow)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @available(swift, obsoleted: 4, message: "Use remainderReportingOverflow(dividingBy:) instead.")
-  @_transparent
   public static func remainderWithOverflow(
     _ lhs: Self, _ rhs: Self
   ) -> (Self, overflow: Bool) {
@@ -3764,7 +3730,7 @@
 }
 
 extension BinaryInteger {
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @available(swift, obsoleted: 3.2,
     message: "Please use FixedWidthInteger protocol as a generic constraint and addingReportingOverflow(_:) method instead.")
   public static func addWithOverflow(
@@ -3773,7 +3739,7 @@
     fatalError("Unavailable")
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @available(swift, obsoleted: 3.2,
     message: "Please use FixedWidthInteger protocol as a generic constraint and subtractingReportingOverflow(_:) method instead.")
   public static func subtractWithOverflow(
@@ -3782,7 +3748,7 @@
     fatalError("Unavailable")
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @available(swift, obsoleted: 3.2,
     message: "Please use FixedWidthInteger protocol as a generic constraint and multipliedReportingOverflow(by:) method instead.")
   public static func multiplyWithOverflow(
@@ -3791,7 +3757,7 @@
     fatalError("Unavailable")
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @available(swift, obsoleted: 3.2,
     message: "Please use FixedWidthInteger protocol as a generic constraint and dividedReportingOverflow(by:) method instead.")
   public static func divideWithOverflow(
@@ -3800,7 +3766,7 @@
     fatalError("Unavailable")
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @inlinable
   @available(swift, obsoleted: 3.2,
     message: "Please use FixedWidthInteger protocol as a generic constraint and remainderReportingOverflow(dividingBy:) method instead.")
   public static func remainderWithOverflow(
@@ -3820,24 +3786,24 @@
 //    var _  = (x &+ (y - 1)) < x
 //                      ^
 extension SignedInteger {
-  @inlinable // FIXME(sil-serialize-all)
+  @_transparent
   public static func _maskingAdd(_ lhs: Self, _ rhs: Self) -> Self {
     fatalError("Should be overridden in a more specific type")
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @_transparent
   @available(swift, obsoleted: 4.0,
       message: "Please use 'FixedWidthInteger' instead of 'SignedInteger' to get '&+' in generic code.")
   public static func &+ (lhs: Self, rhs: Self) -> Self {
     return _maskingAdd(lhs, rhs)
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @_transparent
   public static func _maskingSubtract(_ lhs: Self, _ rhs: Self) -> Self {
     fatalError("Should be overridden in a more specific type")
   }
 
-  @inlinable // FIXME(sil-serialize-all)
+  @_transparent
   @available(swift, obsoleted: 4.0,
       message: "Please use 'FixedWidthInteger' instead of 'SignedInteger' to get '&-' in generic code.")
   public static func &- (lhs: Self, rhs: Self) -> Self {
@@ -3848,7 +3814,7 @@
 extension SignedInteger where Self : FixedWidthInteger {
   // This overload is supposed to break the ambiguity between the
   // implementations on SignedInteger and FixedWidthInteger
-  @inlinable // FIXME(sil-serialize-all)
+  @_transparent
   public static func &+ (lhs: Self, rhs: Self) -> Self {
     return _maskingAdd(lhs, rhs)
   }
@@ -3860,7 +3826,7 @@
 
   // This overload is supposed to break the ambiguity between the
   // implementations on SignedInteger and FixedWidthInteger
-  @inlinable // FIXME(sil-serialize-all)
+  @_transparent
   public static func &- (lhs: Self, rhs: Self) -> Self {
     return _maskingSubtract(lhs, rhs)
   }
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 993c5d7..4b62dbb 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -3620,11 +3620,13 @@
     return false;
   }
 
-  // If we don't have resilient witnesses, the template must provide
-  // everything.
-  assert (genericTable->WitnessTableSizeInWords ==
+  // If we don't have the exact number of witnesses expected, we require
+  // instantiation.
+  if (genericTable->WitnessTableSizeInWords !=
           (genericTable->Protocol->NumRequirements +
-           WitnessTableFirstRequirementOffset));
+           WitnessTableFirstRequirementOffset)) {
+    return false;
+  }
 
   // If we have an instantiation function or private data, we require
   // instantiation.
@@ -3643,39 +3645,65 @@
   auto protocol = genericTable->Protocol.get();
 
   auto requirements = protocol->getRequirements();
-  auto witnesses = genericTable->ResilientWitnesses->getWitnesses();
+  llvm::ArrayRef<TargetResilientWitness<InProcess>> witnesses;
+  if (auto resilientWitnesses = genericTable->ResilientWitnesses.get())
+    witnesses = resilientWitnesses->getWitnesses();
 
-  for (size_t i = 0, e = protocol->NumRequirements; i < e; ++i) {
-    auto &reqt = requirements[i];
+  // Loop over the provided witnesses, filling in appropriate entry.
+  for (const auto &witness : witnesses) {
+    // Retrieve the requirement descriptor.
+    auto reqDescriptor = witness.Requirement.get();
 
-    // Only certain requirements are filled in from the resilient witness table.
-    switch (reqt.Flags.getKind()) {
-    case ProtocolRequirementFlags::Kind::Method:
-    case ProtocolRequirementFlags::Kind::Init:
-    case ProtocolRequirementFlags::Kind::Getter:
-    case ProtocolRequirementFlags::Kind::Setter:
-    case ProtocolRequirementFlags::Kind::ReadCoroutine:
-    case ProtocolRequirementFlags::Kind::ModifyCoroutine:
-    case ProtocolRequirementFlags::Kind::AssociatedTypeAccessFunction:
-      break;
-    case ProtocolRequirementFlags::Kind::BaseProtocol:
-    case ProtocolRequirementFlags::Kind::AssociatedConformanceAccessFunction:
-      continue;
+    // The requirement descriptor may be NULL, in which case this is a
+    // requirement introduced in a later version of the protocol./
+    if (!reqDescriptor) continue;
+
+    // If the requirement descriptor doesn't land within the bounds of the
+    // requirements, abort.
+    if (reqDescriptor < requirements.begin() ||
+        reqDescriptor >= requirements.end()) {
+      fatalError(0, "generic witness table at %p contains out-of-bounds "
+                 "requirement descriptor %p",
+                 genericTable, reqDescriptor);
     }
 
+    unsigned witnessIndex = (reqDescriptor - requirements.data()) +
+      WitnessTableFirstRequirementOffset;
+
+#if !NDEBUG
+    // For debug builds, warn if we already have an entry at this index.
+    if (table[witnessIndex]) {
+      warning(0, "generic witness table at %p contains duplicate entry for "
+              "requirement descriptor %p",
+              genericTable, reqDescriptor);
+    }
+#endif
+
+    table[witnessIndex] = witness.Witness.get();
+  }
+
+  // Loop over the requirements, filling in default implementations where
+  // needed.
+  for (size_t i = 0, e = protocol->NumRequirements; i < e; ++i) {
+    unsigned witnessIndex = WitnessTableFirstRequirementOffset + i;
+
+    // If we already have a witness, there's nothing to do.
+    if (table[witnessIndex])
+      continue;
+
+    // Otherwise, fill in a default implementation.
+    auto &reqt = requirements[i];
     void *impl = reqt.DefaultImplementation.get();
 
-    // Find the witness if there is one, otherwise we use the default.
-    for (auto &witness : witnesses) {
-      if (witness.Requirement.get() == &reqt) {
-        impl = witness.Witness.get();
-        break;
-      }
+#if !NDEBUG
+    // For debug builds, warn if we don't have a default implementation.
+    if (!impl) {
+      warning(0, "generic witness table at %p missing an entry for "
+              "requirement descriptor %p", genericTable,
+              requirements.begin() + i);
     }
+#endif
 
-    assert(impl != nullptr && "no implementation for witness");
-
-    unsigned witnessIndex = WitnessTableFirstRequirementOffset + i;
     table[witnessIndex] = impl;
   }
 }
@@ -3716,8 +3744,7 @@
   }
 
   // Fill in any default requirements.
-  if (genericTable->ResilientWitnesses)
-    initializeResilientWitnessTable(genericTable, table);
+  initializeResilientWitnessTable(genericTable, table);
 
   auto castTable = reinterpret_cast<WitnessTable*>(table);
 
diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt
index 35fe8a3..57244a9 100644
--- a/test/Demangle/Inputs/manglings.txt
+++ b/test/Demangle/Inputs/manglings.txt
@@ -332,3 +332,4 @@
 $S1T19protocol_resilience17ResilientProtocolPTl --> associated type descriptor for T
 $S18resilient_protocol21ResilientBaseProtocolTL --> protocol requirements base descriptor for resilient_protocol.ResilientBaseProtocol
 $S1t1PP10AssocType2_AA1QTn --> associated conformance descriptor for t.P.AssocType2: t.Q
+$S1t1PP10AssocType2_AA1QTN --> default associated conformance accessor for t.P.AssocType2: t.Q
diff --git a/test/IRGen/abi_v7k.swift b/test/IRGen/abi_v7k.swift
index 2bb0163..d4b1af0 100644
--- a/test/IRGen/abi_v7k.swift
+++ b/test/IRGen/abi_v7k.swift
@@ -270,10 +270,10 @@
 // double in d0, i32 in r0, return in d0,...,d3
 // V7K: vmov [[ID:s[0-9]+]], r0
 // V7K: vcvt.f64.s32 [[ID2:d[0-9]+]], [[ID]]
-// V7K: vstr d0, [sp]
+// V7K: vstr d0, [sp, #8]
 // V7K: vmov.f64 d0, [[ID2]]
 // V7K: bl
-// V7K: vldr [[ID3:d[0-9]+]], [sp]
+// V7K: vldr [[ID3:d[0-9]+]], [sp, #8]
 // V7K: vmov.f64 d2, [[ID3]]
 func testRet2(w : Double, i : Int) -> MyRect {
   var r = MyRect(x : Double(i), y : 2.0, w : 3.0, h : 4.0)
diff --git a/test/IRGen/protocol_resilience_descriptors.swift b/test/IRGen/protocol_resilience_descriptors.swift
index 7dd512e..5f6c8ca 100644
--- a/test/IRGen/protocol_resilience_descriptors.swift
+++ b/test/IRGen/protocol_resilience_descriptors.swift
@@ -14,6 +14,7 @@
 
 // Protocol descriptor
 // CHECK-DEFINITION-LABEL: @"$S18resilient_protocol29ProtocolWithAssocTypeDefaultsMp" ={{( protected)?}} constant
+// CHECK-DEFINITION-SAME: @"$S18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0TN"
 // CHECK-DEFINITION-SAME: $S2T118resilient_protocol29ProtocolWithAssocTypeDefaultsPTM
 // CHECK-DEFINITION-SAME: $S2T218resilient_protocol29ProtocolWithAssocTypeDefaultsPTM
 
@@ -25,6 +26,9 @@
 // CHECK-DEFINITION: @"$S1T18resilient_protocol24ProtocolWithRequirementsPTl" ={{( dllexport)?}}{{( protected)?}} alias
 // CHECK-DEFINITION: @"$S18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0Tn" ={{( dllexport)?}}{{( protected)?}} alias
 
+// Default associated conformance witnesses
+// CHECK-DEFINITION-LABEL: define internal swiftcc i8** @"$S18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0TN"
+
 // Default associated type witnesses
 // CHECK-DEFINITION-LABEL: define internal swiftcc %swift.metadata_response @"$S2T118resilient_protocol29ProtocolWithAssocTypeDefaultsPTM"
 
@@ -32,6 +36,8 @@
 // CHECK-DEFINITION: getelementptr inbounds i8*, i8** [[WTABLE:%.*]], i32 2
 // CHECK-DEFINITION: call{{.*}}S18resilient_protocol7WrapperVMa
 
+// CHECK-DEFINITION-LABEL: define internal swiftcc %swift.metadata_response @"$S9AssocType18resilient_protocol20ResilientSelfDefaultPTM
+
 import resilient_protocol
 
 // ----------------------------------------------------------------------------
@@ -51,6 +57,12 @@
 public struct ConditionallyConforms<Element> { }
 public struct Y { }
 
+// CHECK-USAGE: @"$S31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAAWr" = internal
+// CHECK-USAGE-SAME: $S18resilient_protocol29ProtocolWithAssocTypeDefaultsP2T2_AA014OtherResilientC0Tn
+// CHECK-USAGE-SAME: $S31protocol_resilience_descriptors29ConformsWithAssocRequirementsV010resilient_A008ProtocoleF12TypeDefaultsAA2T2_AD014OtherResilientI0PWT
+public struct ConformsWithAssocRequirements : ProtocolWithAssocTypeDefaults {
+}
+
 // CHECK-USAGE: @"$Sx1T_MXA" =
 // CHECK-USAGE-SAME: i32 0
 // CHECK-USAGE-SAME: @"{{got.|__imp_}}$S18resilient_protocol24ProtocolWithRequirementsMp"
diff --git a/test/Inputs/resilient_protocol.swift b/test/Inputs/resilient_protocol.swift
index e6dfcb8..9a93674 100644
--- a/test/Inputs/resilient_protocol.swift
+++ b/test/Inputs/resilient_protocol.swift
@@ -34,3 +34,7 @@
   associatedtype T1 = Self
   associatedtype T2: OtherResilientProtocol = Wrapper<T1>
 }
+
+public protocol ResilientSelfDefault : ResilientBaseProtocol {
+  associatedtype AssocType: ResilientBaseProtocol = Self
+}
diff --git a/test/Parse/raw_string.swift b/test/Parse/raw_string.swift
index 953b923..d96ba2f 100644
--- a/test/Parse/raw_string.swift
+++ b/test/Parse/raw_string.swift
@@ -132,3 +132,6 @@
     ]
     """#
 // CHECK: "[\n    {\n        \"id\": \"12345\",\n        \"title\": \"A title that \\\"contains\\\" \\\\\\\"\"\n    }\n]"
+
+_ = #"# #"#
+// CHECK: "# #"
diff --git a/test/Parse/raw_string_errors.swift b/test/Parse/raw_string_errors.swift
index ca19b41..0ba693f 100644
--- a/test/Parse/raw_string_errors.swift
+++ b/test/Parse/raw_string_errors.swift
@@ -1,14 +1,24 @@
 // RUN: %target-typecheck-verify-swift
 
-#"\##("invalid")"#
+let _ = "foo\(#"bar"##)baz"
+// expected-error@-1{{too many '#' characters in closing delimiter}}
+// expected-error@-2{{expected ',' separator}}
+// expected-error@-3{{expected expression in list of expressions}}
+
+let _ = #"\##("invalid")"#
 // expected-error@-1{{too many '#' characters in delimited escape}}
 // expected-error@-2{{invalid escape sequence in literal}}
 
-####"invalid"###
+let _ = ####"invalid"###
 // expected-error@-1{{unterminated string literal}}
 
-###"invalid"####
-// expected-error@-1{{too many '#' characters in closing delimiter}}
+let _ = ###"invalid"######
+// expected-error@-1{{too many '#' characters in closing delimiter}}{{24-27=}}
 // expected-error@-2{{consecutive statements on a line must be separated by ';'}}
 // expected-error@-3{{expected expression}}
-// expected-warning@-4{{string literal is unused}}
+
+let _ = ##"""##
+  foobar
+  ##"""##
+// expected-error@-3{{multi-line string literal content must begin on a new line}}{{14-14=\n}}
+// expected-error@-2{{multi-line string literal closing delimiter must begin on a new line}}{{5-5=\n}}
diff --git a/test/Parse/string_literal_eof1.swift b/test/Parse/string_literal_eof1.swift
new file mode 100644
index 0000000..accc6a0
--- /dev/null
+++ b/test/Parse/string_literal_eof1.swift
@@ -0,0 +1,5 @@
+// RUN: %target-typecheck-verify-swift
+
+// NOTE: DO NOT add a newline at EOF.
+// expected-error@+1 {{unterminated string literal}}
+_ = "foo\(
\ No newline at end of file
diff --git a/test/Parse/string_literal_eof2.swift b/test/Parse/string_literal_eof2.swift
new file mode 100644
index 0000000..c049557
--- /dev/null
+++ b/test/Parse/string_literal_eof2.swift
@@ -0,0 +1,5 @@
+// RUN: %target-typecheck-verify-swift
+
+// NOTE: DO NOT add a newline at EOF.
+// expected-error@+1 {{unterminated string literal}}
+_ = "foo\("bar
\ No newline at end of file
diff --git a/test/Parse/string_literal_eof3.swift b/test/Parse/string_literal_eof3.swift
new file mode 100644
index 0000000..a5425e6
--- /dev/null
+++ b/test/Parse/string_literal_eof3.swift
@@ -0,0 +1,10 @@
+// RUN: %target-typecheck-verify-swift
+
+// expected-error@+2 {{unterminated string literal}}
+// expected-error@+1 {{invalid escape sequence in literal}}
+_ = "foo \
+
+// NOTE: DO NOT add a newline at EOF.
+// expected-error@+2 {{unterminated string literal}}
+// expected-error@+1 {{invalid escape sequence in literal}}
+_ = "foo \
\ No newline at end of file
diff --git a/test/SIL/Parser/default_witness_tables.sil b/test/SIL/Parser/default_witness_tables.sil
index bb1b8e9..8153e21 100644
--- a/test/SIL/Parser/default_witness_tables.sil
+++ b/test/SIL/Parser/default_witness_tables.sil
@@ -48,7 +48,7 @@
 
 
 // CHECK-LABEL: sil_default_witness_table ResilientProtocol {
-// CHECK: no_default
+// CHECK: associated_type_protocol (T: Proto): Wrapper<Self>: specialize <Self> (<T> Wrapper<T>: Proto module witness_tables)
 // CHECK: associated_type T: Wrapper<Self>
 // CHECK: no_default
 // CHECK: no_default
@@ -58,7 +58,7 @@
 // CHECK: }
 
 sil_default_witness_table ResilientProtocol {
-  no_default
+  associated_type_protocol (T: Proto): Wrapper<Self>: specialize <Self> (<T> Wrapper<T>: Proto module witness_tables)
   associated_type T: Wrapper<Self>
   no_default
   no_default
diff --git a/test/SILGen/protocol_resilience.swift b/test/SILGen/protocol_resilience.swift
index e930bfb..e75df7e 100644
--- a/test/SILGen/protocol_resilience.swift
+++ b/test/SILGen/protocol_resilience.swift
@@ -251,6 +251,13 @@
   inoutFunc(&OtherConformingType.staticPropertyInExtension)
 }
 
+// Protocol is public -- needs resilient witness table
+public struct ConformsToP: P { }
+
+public protocol ResilientAssocTypes {
+  associatedtype AssocType: P = ConformsToP
+}
+
 // CHECK-LABEL: sil_default_witness_table P {
 // CHECK-NEXT: }
 
@@ -312,3 +319,8 @@
 // CHECK-NEXT:   method #ReabstractSelfRefined.callback!setter.1: {{.*}} : @$S19protocol_resilience21ReabstractSelfRefinedP8callbackyxxcvs
 // CHECK-NEXT:   method #ReabstractSelfRefined.callback!modify.1: {{.*}} : @$S19protocol_resilience21ReabstractSelfRefinedP8callbackyxxcvM
 // CHECK-NEXT: }
+
+// CHECK-LABEL: sil_default_witness_table ResilientAssocTypes {
+// CHECK-NEXT:   associated_type_protocol (AssocType: P): ConformsToP: P module protocol_resilience
+// CHECK-NEXT:   associated_type AssocType: ConformsToP
+// CHECK-NEXT: }
diff --git a/test/api-digester/Inputs/cake.swift b/test/api-digester/Inputs/cake.swift
index 34e9637..5ae49f9 100644
--- a/test/api-digester/Inputs/cake.swift
+++ b/test/api-digester/Inputs/cake.swift
@@ -40,4 +40,11 @@
 
 public extension Int {
   public func foo() {}
-}
\ No newline at end of file
+}
+
+@_fixed_layout
+public struct fixedLayoutStruct {
+  public var a = 1
+  private var b = 2
+  var c = 3
+}
diff --git a/test/api-digester/Inputs/cake1.swift b/test/api-digester/Inputs/cake1.swift
index 7ec7e43..a3351b0 100644
--- a/test/api-digester/Inputs/cake1.swift
+++ b/test/api-digester/Inputs/cake1.swift
@@ -47,3 +47,17 @@
 public extension P1 where Self: P2 {
   func P1Constraint() {}
 }
+
+@_fixed_layout
+public struct fixedLayoutStruct {
+  public var b = 2
+  public func foo() {}
+  public var a = 1
+}
+
+@_frozen
+public enum FrozenKind {
+  case Unchanged
+  case Fixed
+  case Rigid
+}
\ No newline at end of file
diff --git a/test/api-digester/Inputs/cake2.swift b/test/api-digester/Inputs/cake2.swift
index 651ac79..da3fe96 100644
--- a/test/api-digester/Inputs/cake2.swift
+++ b/test/api-digester/Inputs/cake2.swift
@@ -47,3 +47,22 @@
 public extension P1 {
   func P1Constraint() {}
 }
+
+@_fixed_layout
+public struct fixedLayoutStruct {
+  public var a = 1
+  public func OKChange() {}
+  private static let constant = 0
+  public var b = 2
+  public func foo() {}
+  private var c = 3
+  private lazy var lazy_d = 4
+}
+
+@_frozen
+public enum FrozenKind {
+  case Unchanged
+  case Rigid
+  case Fixed
+  case AddedCase
+}
\ No newline at end of file
diff --git a/test/api-digester/Outputs/Cake-abi.txt b/test/api-digester/Outputs/Cake-abi.txt
index 093eff1..d162bc6 100644
--- a/test/api-digester/Outputs/Cake-abi.txt
+++ b/test/api-digester/Outputs/Cake-abi.txt
@@ -6,6 +6,7 @@
 
 /* Removed Decls */
 cake1: Constructor Somestruct2.init(_:) has been removed
+cake1: Constructor fixedLayoutStruct.init(b:a:) has been removed
 cake1: Func C4.foo() has been removed
 
 /* Moved Decls */
@@ -29,3 +30,12 @@
 cake1: Struct C6 is now with @_fixed_layout
 cake1: Var C1.CIIns1 changes from weak to strong
 cake1: Var C1.CIIns2 changes from strong to weak
+
+/* Fixed-layout Type changes */
+cake1: EnumElement FrozenKind.Fixed in a non-resilient type changes position from 1 to 2
+cake1: EnumElement FrozenKind.Rigid in a non-resilient type changes position from 2 to 1
+cake1: Var fixedLayoutStruct.a in a non-resilient type changes position from 1 to 0
+cake1: Var fixedLayoutStruct.b in a non-resilient type changes position from 0 to 1
+cake2: EnumElement FrozenKind.AddedCase is added to a non-resilient type
+cake2: Var fixedLayoutStruct.c is added to a non-resilient type
+cake2: Var fixedLayoutStruct.lazy_d.storage is added to a non-resilient type
\ No newline at end of file
diff --git a/test/api-digester/Outputs/Cake.txt b/test/api-digester/Outputs/Cake.txt
index e46efe9..92857e0 100644
--- a/test/api-digester/Outputs/Cake.txt
+++ b/test/api-digester/Outputs/Cake.txt
@@ -6,6 +6,7 @@
 
 /* Removed Decls */
 cake1: Constructor Somestruct2.init(_:) has been removed
+cake1: Constructor fixedLayoutStruct.init(b:a:) has been removed
 cake1: Func C4.foo() has been removed
 
 /* Moved Decls */
diff --git a/test/api-digester/Outputs/cake-abi.json b/test/api-digester/Outputs/cake-abi.json
index 3a068eb..b980795 100644
--- a/test/api-digester/Outputs/cake-abi.json
+++ b/test/api-digester/Outputs/cake-abi.json
@@ -95,6 +95,7 @@
           "usr": "s:4cake2S1VACycfc",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -125,6 +126,7 @@
           "location": "",
           "moduleName": "cake",
           "genericSig": "<τ_0_0, τ_0_1, τ_0_2>",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -241,6 +243,7 @@
               "usr": "s:4cake2C1C3InsACSgXwvg",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "declAttributes": [
                 "Transparent"
               ],
@@ -269,6 +272,7 @@
               "usr": "s:4cake2C1C3InsACSgXwvs",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "declAttributes": [
                 "Transparent"
               ],
@@ -323,6 +327,7 @@
               "usr": "s:4cake2C1C4Ins2ACXovg",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "declAttributes": [
                 "Transparent"
               ],
@@ -343,6 +348,7 @@
               "usr": "s:4cake2C1C4Ins2ACXovs",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "declAttributes": [
                 "Transparent"
               ],
@@ -370,6 +376,7 @@
           "usr": "s:4cake2C1CACycfc",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -462,6 +469,7 @@
           "usr": "s:4cake6NumberO3oneyA2CmF",
           "location": "",
           "moduleName": "cake",
+          "fixedbinaryorder": 0,
           "children": [
             {
               "kind": "TypeFunc",
@@ -499,6 +507,7 @@
           "usr": "s:4cake6NumberO8RawValuea",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -516,6 +525,7 @@
           "usr": "s:4cake6NumberO9hashValueSivp",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -531,6 +541,7 @@
               "usr": "s:4cake6NumberO9hashValueSivg",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "children": [
                 {
                   "kind": "TypeNominal",
@@ -550,6 +561,7 @@
           "usr": "s:4cake6NumberO4hash4intoys6HasherVz_tF",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -572,6 +584,7 @@
           "usr": "s:4cake6NumberO8rawValueACSgSi_tcfc",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "declAttributes": [
             "Inlinable"
           ],
@@ -606,6 +619,7 @@
           "usr": "s:4cake6NumberO8rawValueSivp",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -621,6 +635,7 @@
               "usr": "s:4cake6NumberO8rawValueSivg",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "declAttributes": [
                 "Inlinable"
               ],
@@ -675,6 +690,281 @@
     },
     {
       "kind": "TypeDecl",
+      "name": "fixedLayoutStruct",
+      "printedName": "fixedLayoutStruct",
+      "declKind": "Struct",
+      "usr": "s:4cake17fixedLayoutStructV",
+      "location": "",
+      "moduleName": "cake",
+      "declAttributes": [
+        "FixedLayout"
+      ],
+      "children": [
+        {
+          "kind": "Var",
+          "name": "a",
+          "printedName": "a",
+          "declKind": "Var",
+          "usr": "s:4cake17fixedLayoutStructV1aSivp",
+          "location": "",
+          "moduleName": "cake",
+          "fixedbinaryorder": 0,
+          "declAttributes": [
+            "HasInitialValue"
+          ],
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int",
+              "usr": "s:Si"
+            },
+            {
+              "kind": "Getter",
+              "name": "_",
+              "printedName": "_()",
+              "declKind": "Accessor",
+              "usr": "s:4cake17fixedLayoutStructV1aSivg",
+              "location": "",
+              "moduleName": "cake",
+              "implicit": true,
+              "declAttributes": [
+                "Transparent"
+              ],
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Int",
+                  "printedName": "Int",
+                  "usr": "s:Si"
+                }
+              ]
+            },
+            {
+              "kind": "Setter",
+              "name": "_",
+              "printedName": "_()",
+              "declKind": "Accessor",
+              "usr": "s:4cake17fixedLayoutStructV1aSivs",
+              "location": "",
+              "moduleName": "cake",
+              "implicit": true,
+              "mutating": true,
+              "declAttributes": [
+                "Transparent"
+              ],
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Void",
+                  "printedName": "()"
+                },
+                {
+                  "kind": "TypeNominal",
+                  "name": "Int",
+                  "printedName": "Int",
+                  "usr": "s:Si"
+                }
+              ]
+            }
+          ]
+        },
+        {
+          "kind": "Var",
+          "name": "b",
+          "printedName": "b",
+          "declKind": "Var",
+          "usr": "s:4cake17fixedLayoutStructV1b33_3D8926C30F7417F2EF9A277D0C73FBDBLLSivp",
+          "location": "",
+          "moduleName": "cake",
+          "fixedbinaryorder": 1,
+          "declAttributes": [
+            "HasInitialValue"
+          ],
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int",
+              "usr": "s:Si"
+            },
+            {
+              "kind": "Getter",
+              "name": "_",
+              "printedName": "_()",
+              "declKind": "Accessor",
+              "usr": "s:4cake17fixedLayoutStructV1b33_3D8926C30F7417F2EF9A277D0C73FBDBLLSivg",
+              "location": "",
+              "moduleName": "cake",
+              "implicit": true,
+              "declAttributes": [
+                "Transparent"
+              ],
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Int",
+                  "printedName": "Int",
+                  "usr": "s:Si"
+                }
+              ]
+            },
+            {
+              "kind": "Setter",
+              "name": "_",
+              "printedName": "_()",
+              "declKind": "Accessor",
+              "usr": "s:4cake17fixedLayoutStructV1b33_3D8926C30F7417F2EF9A277D0C73FBDBLLSivs",
+              "location": "",
+              "moduleName": "cake",
+              "implicit": true,
+              "mutating": true,
+              "declAttributes": [
+                "Transparent"
+              ],
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Void",
+                  "printedName": "()"
+                },
+                {
+                  "kind": "TypeNominal",
+                  "name": "Int",
+                  "printedName": "Int",
+                  "usr": "s:Si"
+                }
+              ]
+            }
+          ]
+        },
+        {
+          "kind": "Var",
+          "name": "c",
+          "printedName": "c",
+          "declKind": "Var",
+          "usr": "s:4cake17fixedLayoutStructV1cSivp",
+          "location": "",
+          "moduleName": "cake",
+          "fixedbinaryorder": 2,
+          "declAttributes": [
+            "HasInitialValue"
+          ],
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int",
+              "usr": "s:Si"
+            },
+            {
+              "kind": "Getter",
+              "name": "_",
+              "printedName": "_()",
+              "declKind": "Accessor",
+              "usr": "s:4cake17fixedLayoutStructV1cSivg",
+              "location": "",
+              "moduleName": "cake",
+              "implicit": true,
+              "declAttributes": [
+                "Transparent"
+              ],
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Int",
+                  "printedName": "Int",
+                  "usr": "s:Si"
+                }
+              ]
+            },
+            {
+              "kind": "Setter",
+              "name": "_",
+              "printedName": "_()",
+              "declKind": "Accessor",
+              "usr": "s:4cake17fixedLayoutStructV1cSivs",
+              "location": "",
+              "moduleName": "cake",
+              "implicit": true,
+              "mutating": true,
+              "declAttributes": [
+                "Transparent"
+              ],
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Void",
+                  "printedName": "()"
+                },
+                {
+                  "kind": "TypeNominal",
+                  "name": "Int",
+                  "printedName": "Int",
+                  "usr": "s:Si"
+                }
+              ]
+            }
+          ]
+        },
+        {
+          "kind": "Constructor",
+          "name": "init",
+          "printedName": "init(a:b:c:)",
+          "declKind": "Constructor",
+          "usr": "s:4cake17fixedLayoutStructV1a1b1cACSi_S2itc33_3D8926C30F7417F2EF9A277D0C73FBDBLlfc",
+          "location": "",
+          "moduleName": "cake",
+          "implicit": true,
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "fixedLayoutStruct",
+              "printedName": "fixedLayoutStruct",
+              "usr": "s:4cake17fixedLayoutStructV"
+            },
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int",
+              "usr": "s:Si"
+            },
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int",
+              "usr": "s:Si"
+            },
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int",
+              "usr": "s:Si"
+            }
+          ]
+        },
+        {
+          "kind": "Constructor",
+          "name": "init",
+          "printedName": "init()",
+          "declKind": "Constructor",
+          "usr": "s:4cake17fixedLayoutStructVACycfc",
+          "location": "",
+          "moduleName": "cake",
+          "implicit": true,
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "fixedLayoutStruct",
+              "printedName": "fixedLayoutStruct",
+              "usr": "s:4cake17fixedLayoutStructV"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "kind": "TypeDecl",
       "name": "Int",
       "printedName": "Int",
       "declKind": "Struct",
diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json
index 56af1b7..994ab4e 100644
--- a/test/api-digester/Outputs/cake.json
+++ b/test/api-digester/Outputs/cake.json
@@ -102,6 +102,7 @@
           "usr": "s:4cake2S1VACycfc",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -132,6 +133,7 @@
           "location": "",
           "moduleName": "cake",
           "genericSig": "<T1, T2, T3>",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -248,6 +250,7 @@
               "usr": "s:4cake2C1C3InsACSgXwvg",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "declAttributes": [
                 "Transparent"
               ],
@@ -276,6 +279,7 @@
               "usr": "s:4cake2C1C3InsACSgXwvs",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "declAttributes": [
                 "Transparent"
               ],
@@ -330,6 +334,7 @@
               "usr": "s:4cake2C1C4Ins2ACXovg",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "declAttributes": [
                 "Transparent"
               ],
@@ -350,6 +355,7 @@
               "usr": "s:4cake2C1C4Ins2ACXovs",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "declAttributes": [
                 "Transparent"
               ],
@@ -377,6 +383,7 @@
           "usr": "s:4cake2C1CACycfc",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -469,6 +476,7 @@
           "usr": "s:4cake6NumberO3oneyA2CmF",
           "location": "",
           "moduleName": "cake",
+          "fixedbinaryorder": 0,
           "children": [
             {
               "kind": "TypeFunc",
@@ -513,6 +521,7 @@
           "usr": "s:4cake6NumberO8RawValuea",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -530,6 +539,7 @@
           "usr": "s:4cake6NumberO9hashValueSivp",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -545,6 +555,7 @@
               "usr": "s:4cake6NumberO9hashValueSivg",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "children": [
                 {
                   "kind": "TypeNominal",
@@ -564,6 +575,7 @@
           "usr": "s:4cake6NumberO4hash4intoys6HasherVz_tF",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -586,6 +598,7 @@
           "usr": "s:4cake6NumberO8rawValueACSgSi_tcfc",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "declAttributes": [
             "Inlinable"
           ],
@@ -620,6 +633,7 @@
           "usr": "s:4cake6NumberO8rawValueSivp",
           "location": "",
           "moduleName": "cake",
+          "implicit": true,
           "children": [
             {
               "kind": "TypeNominal",
@@ -635,6 +649,7 @@
               "usr": "s:4cake6NumberO8rawValueSivg",
               "location": "",
               "moduleName": "cake",
+              "implicit": true,
               "declAttributes": [
                 "Inlinable"
               ],
@@ -689,6 +704,143 @@
     },
     {
       "kind": "TypeDecl",
+      "name": "fixedLayoutStruct",
+      "printedName": "fixedLayoutStruct",
+      "declKind": "Struct",
+      "usr": "s:4cake17fixedLayoutStructV",
+      "location": "",
+      "moduleName": "cake",
+      "declAttributes": [
+        "FixedLayout"
+      ],
+      "children": [
+        {
+          "kind": "Var",
+          "name": "a",
+          "printedName": "a",
+          "declKind": "Var",
+          "usr": "s:4cake17fixedLayoutStructV1aSivp",
+          "location": "",
+          "moduleName": "cake",
+          "fixedbinaryorder": 0,
+          "declAttributes": [
+            "HasInitialValue"
+          ],
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int",
+              "usr": "s:Si"
+            },
+            {
+              "kind": "Getter",
+              "name": "_",
+              "printedName": "_()",
+              "declKind": "Accessor",
+              "usr": "s:4cake17fixedLayoutStructV1aSivg",
+              "location": "",
+              "moduleName": "cake",
+              "implicit": true,
+              "declAttributes": [
+                "Transparent"
+              ],
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Int",
+                  "printedName": "Int",
+                  "usr": "s:Si"
+                }
+              ]
+            },
+            {
+              "kind": "Setter",
+              "name": "_",
+              "printedName": "_()",
+              "declKind": "Accessor",
+              "usr": "s:4cake17fixedLayoutStructV1aSivs",
+              "location": "",
+              "moduleName": "cake",
+              "implicit": true,
+              "mutating": true,
+              "declAttributes": [
+                "Transparent"
+              ],
+              "children": [
+                {
+                  "kind": "TypeNominal",
+                  "name": "Void",
+                  "printedName": "()"
+                },
+                {
+                  "kind": "TypeNominal",
+                  "name": "Int",
+                  "printedName": "Int",
+                  "usr": "s:Si"
+                }
+              ]
+            }
+          ]
+        },
+        {
+          "kind": "Constructor",
+          "name": "init",
+          "printedName": "init(a:b:c:)",
+          "declKind": "Constructor",
+          "usr": "s:4cake17fixedLayoutStructV1a1b1cACSi_S2itc33_3D8926C30F7417F2EF9A277D0C73FBDBLlfc",
+          "location": "",
+          "moduleName": "cake",
+          "implicit": true,
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "fixedLayoutStruct",
+              "printedName": "fixedLayoutStruct",
+              "usr": "s:4cake17fixedLayoutStructV"
+            },
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int",
+              "usr": "s:Si"
+            },
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int",
+              "usr": "s:Si"
+            },
+            {
+              "kind": "TypeNominal",
+              "name": "Int",
+              "printedName": "Int",
+              "usr": "s:Si"
+            }
+          ]
+        },
+        {
+          "kind": "Constructor",
+          "name": "init",
+          "printedName": "init()",
+          "declKind": "Constructor",
+          "usr": "s:4cake17fixedLayoutStructVACycfc",
+          "location": "",
+          "moduleName": "cake",
+          "implicit": true,
+          "children": [
+            {
+              "kind": "TypeNominal",
+              "name": "fixedLayoutStruct",
+              "printedName": "fixedLayoutStruct",
+              "usr": "s:4cake17fixedLayoutStructV"
+            }
+          ]
+        }
+      ]
+    },
+    {
+      "kind": "TypeDecl",
       "name": "Int",
       "printedName": "Int",
       "declKind": "Struct",
diff --git a/test/api-digester/Outputs/clang-module-dump.txt b/test/api-digester/Outputs/clang-module-dump.txt
index c26a73a..46c293e 100644
--- a/test/api-digester/Outputs/clang-module-dump.txt
+++ b/test/api-digester/Outputs/clang-module-dump.txt
@@ -54,6 +54,7 @@
           "usr": "c:objc(cs)NSObject(im)init",
           "location": "",
           "moduleName": "Foo",
+          "implicit": true,
           "declAttributes": [
             "Override",
             "ObjC"
diff --git a/test/api-digester/apinotes-diags.swift b/test/api-digester/apinotes-diags.swift
index 4e64c05..6a7b06d 100644
--- a/test/api-digester/apinotes-diags.swift
+++ b/test/api-digester/apinotes-diags.swift
@@ -6,6 +6,12 @@
 // RUN: %api-digester %clang-importer-sdk-nosource -dump-sdk -module APINotesTest -o %t.dump2.json -module-cache-path %t.module-cache -swift-version 3 -I %S/Inputs/APINotesRight
 // RUN: %api-digester %clang-importer-sdk-nosource -dump-sdk -module APINotesTest -o %t.dump3.json -module-cache-path %t.module-cache -swift-version 4 -I %S/Inputs/APINotesRight
 // RUN: %api-digester -diagnose-sdk -print-module -input-paths %t.dump1.json -input-paths %t.dump3.json > %t.result
-// RUN: diff -u %S/Outputs/apinotes-diags.txt %t.result
+
+// RUN: %clang -E -P -x c %S/Outputs/apinotes-diags.txt -o - | sed '/^\s*$/d' > %t.expected
+// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
+// RUN: diff -u %t.expected %t.result.tmp
+
 // RUN: %api-digester -diagnose-sdk -print-module -input-paths %t.dump2.json -input-paths %t.dump3.json > %t.result
-// RUN: diff -u %S/Outputs/apinotes-diags-3-4.txt %t.result
+// RUN: %clang -E -P -x c %S/Outputs/apinotes-diags-3-4.txt -o - | sed '/^\s*$/d' > %t.expected
+// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
+// RUN: diff -u %t.expected %t.result.tmp
diff --git a/test/api-digester/compare-dump.swift b/test/api-digester/compare-dump.swift
index 3a8b92a..e70f166 100644
--- a/test/api-digester/compare-dump.swift
+++ b/test/api-digester/compare-dump.swift
@@ -6,9 +6,15 @@
 // RUN: %api-digester -dump-sdk -module cake1 -o %t.dump1.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod -I %S/Inputs/APINotesLeft
 // RUN: %api-digester -dump-sdk -module cake2 -o %t.dump2.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod -I %S/Inputs/APINotesRight
 // RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json > %t.result
-// RUN: diff -u %S/Outputs/Cake.txt %t.result
+
+// RUN: %clang -E -P -x c %S/Outputs/Cake.txt -o - | sed '/^\s*$/d' > %t.expected
+// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
+// RUN: diff -u %t.expected %t.result.tmp
 
 // RUN: %api-digester -dump-sdk -module cake1 -o %t.dump1.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod -I %S/Inputs/APINotesLeft -abi
 // RUN: %api-digester -dump-sdk -module cake2 -o %t.dump2.json -module-cache-path %t.module-cache %clang-importer-sdk-nosource -I %t.mod -I %S/Inputs/APINotesRight -abi
 // RUN: %api-digester -diagnose-sdk -print-module --input-paths %t.dump1.json -input-paths %t.dump2.json -abi > %t.result
-// RUN: diff -u %S/Outputs/Cake-abi.txt %t.result
+
+// RUN: %clang -E -P -x c %S/Outputs/Cake-abi.txt -o - | sed '/^\s*$/d' > %t.expected
+// RUN: %clang -E -P -x c %t.result -o - | sed '/^\s*$/d' > %t.result.tmp
+// RUN: diff -u %t.expected %t.result.tmp
diff --git a/test/decl/protocol/resilient_defaults.swift b/test/decl/protocol/resilient_defaults.swift
new file mode 100644
index 0000000..b959241
--- /dev/null
+++ b/test/decl/protocol/resilient_defaults.swift
@@ -0,0 +1,18 @@
+// RUN: %target-typecheck-verify-swift -enable-resilience
+
+public struct Wrapper<T: P>: P { }
+extension Wrapper: Q where T: Q { }
+
+public protocol PBase {
+  associatedtype AssocType
+}
+
+public protocol P: PBase {
+  override associatedtype AssocType: P = Wrapper<Self>
+  // expected-note@-1{{associated type 'AssocType' has default type 'Wrapper<Self>' written here}}
+}
+
+public protocol Q: P where Self.AssocType: Q { }
+
+public protocol R: Q where Self.AssocType: R { }
+// expected-warning@-1{{default type 'Wrapper<Self>' for associated type 'AssocType' does not satisfy constraint 'Self.AssocType': 'R'}}
diff --git a/test/expr/expressions.swift b/test/expr/expressions.swift
index 4a38054..85b1a62 100644
--- a/test/expr/expressions.swift
+++ b/test/expr/expressions.swift
@@ -505,6 +505,9 @@
   _ = 'ab\nc' // expected-error{{single-quoted string literal found, use '"'}}{{7-14="ab\\nc"}}
 
   _ = "abc\('def')" // expected-error{{single-quoted string literal found, use '"'}}{{13-18="def"}}
+  _ = 'ab\("c")' // expected-error{{single-quoted string literal found, use '"'}}{{7-17="ab\\("c")"}}
+  _ = 'a\('b')c' // expected-error{{single-quoted string literal found, use '"'}}{{7-17="a\\('b')c"}}
+                 // expected-error@-1{{single-quoted string literal found, use '"'}}{{11-14="b"}}
 
   _ = "abc' // expected-error{{unterminated string literal}}
   _ = 'abc" // expected-error{{unterminated string literal}}
diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp
index 396f6bd..2430cc9 100644
--- a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp
+++ b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp
@@ -42,11 +42,13 @@
   StringRef USR;
   StringRef Location;
   StringRef ModuleName;
+  bool IsImplicit = false;
   bool IsThrowing = false;
   bool IsMutating = false;
   bool IsStatic = false;
   bool IsDeprecated = false;
   Optional<uint8_t> SelfIndex;
+  Optional<unsigned> FixedBinaryOrder;
   ReferenceOwnership ReferenceOwnership = ReferenceOwnership::Strong;
   std::vector<DeclAttrKind> DeclAttrs;
   std::vector<TypeAttrKind> TypeAttrs;
@@ -81,8 +83,8 @@
 SDKNodeDecl::SDKNodeDecl(SDKNodeInitInfo Info, SDKNodeKind Kind)
       : SDKNode(Info, Kind), DKind(Info.DKind), Usr(Info.USR),
         Location(Info.Location), ModuleName(Info.ModuleName),
-        DeclAttributes(Info.DeclAttrs), IsStatic(Info.IsStatic),
-        IsDeprecated(Info.IsDeprecated),
+        DeclAttributes(Info.DeclAttrs), IsImplicit(Info.IsImplicit),
+        IsStatic(Info.IsStatic), IsDeprecated(Info.IsDeprecated),
         ReferenceOwnership(uint8_t(Info.ReferenceOwnership)),
         GenericSig(Info.GenericSig) {}
 
@@ -108,7 +110,8 @@
   SDKNodeDecl(Info, SDKNodeKind::DeclTypeAlias) {}
 
 SDKNodeDeclVar::SDKNodeDeclVar(SDKNodeInitInfo Info): 
-  SDKNodeDecl(Info, SDKNodeKind::DeclVar) {}
+  SDKNodeDecl(Info, SDKNodeKind::DeclVar),
+  FixedBinaryOrder(Info.FixedBinaryOrder) {}
 
 SDKNodeDeclAbstractFunc::SDKNodeDeclAbstractFunc(SDKNodeInitInfo Info,
   SDKNodeKind Kind): SDKNodeDecl(Info, Kind), IsThrowing(Info.IsThrowing),
@@ -153,8 +156,10 @@
   }
 }
 
-unsigned SDKNode::getChildIndex(NodePtr Child) const {
-  return std::find(Children.begin(), Children.end(), Child) - Children.begin();
+unsigned SDKNode::getChildIndex(const SDKNode* Child) const {
+  auto It = std::find(Children.begin(), Children.end(), Child);
+  assert(It != Children.end() && "cannot find the child");
+  return It - Children.begin();
 }
 
 SDKNode* SDKNode::getOnlyChild() const {
@@ -503,6 +508,9 @@
       case KeyKind::KK_selfIndex:
         Info.SelfIndex = getAsInt(Pair.getValue());
         break;
+      case KeyKind::KK_fixedbinaryorder:
+        Info.FixedBinaryOrder = getAsInt(Pair.getValue());
+        break;
       case KeyKind::KK_usr:
         Info.USR = GetScalarString(Pair.getValue());
         break;
@@ -555,6 +563,9 @@
       case KeyKind::KK_deprecated:
         Info.IsDeprecated = true;
         break;
+      case KeyKind::KK_implicit:
+        Info.IsImplicit = true;
+        break;
       case KeyKind::KK_ownership:
         Info.ReferenceOwnership =
             swift::ReferenceOwnership(getAsInt(Pair.getValue()));
@@ -671,8 +682,24 @@
         return false;
       LLVM_FALLTHROUGH;
     }
+
+    case SDKNodeKind::DeclVar: {
+      if (getSDKContext().checkingABI()) {
+        // If we're checking ABI, the definition order matters.
+        // If they're both members for fixed layout types, we never consider
+        // them equal because we need to check definition orders.
+        if (auto *LV = dyn_cast<SDKNodeDeclVar>(this)) {
+          if (auto *RV = dyn_cast<SDKNodeDeclVar>(&Other)) {
+            if (LV->hasFixedBinaryOrder() && RV->hasFixedBinaryOrder()) {
+              if (LV->getFixedBinaryOrder() != RV->getFixedBinaryOrder())
+                return false;
+            }
+          }
+        }
+      }
+      LLVM_FALLTHROUGH;
+    }
     case SDKNodeKind::DeclType:
-    case SDKNodeKind::DeclVar:
     case SDKNodeKind::DeclTypeAlias: {
       auto Left = this->getAs<SDKNodeDecl>();
       auto Right = (&Other)->getAs<SDKNodeDecl>();
@@ -684,6 +711,7 @@
         return false;
       if (Left->getGenericSignature() != Right->getGenericSignature())
         return false;
+
       LLVM_FALLTHROUGH;
     }
     case SDKNodeKind::Root: {
@@ -902,6 +930,39 @@
   return StringRef();
 }
 
+static Optional<unsigned> getFixedBinaryOrder(ValueDecl *VD) {
+  auto D = VD->getDeclContext()->getAsDecl();
+  if (!D)
+    return None;
+
+  if (auto *ED = dyn_cast<EnumDecl>(D)) {
+    auto Check = [](Decl *M) {
+      return isa<EnumElementDecl>(M);
+    };
+    if (!ED->isResilient() && Check(VD)) {
+      auto Members = ED->getMembers();
+      auto End = std::find(Members.begin(), Members.end(), VD);
+      assert(End != Members.end());
+      return std::count_if(Members.begin(), End, Check);
+    }
+  }
+  if (auto *SD = dyn_cast<StructDecl>(D)) {
+    auto Check = [](Decl *M) {
+      if (auto *STD = dyn_cast<AbstractStorageDecl>(M)) {
+        return STD->hasStorage() && !STD->isStatic();
+      }
+      return false;
+    };
+    if (!SD->isResilient() && Check(VD)) {
+      auto Members = SD->getMembers();
+      auto End = std::find(Members.begin(), Members.end(), VD);
+      assert(End != Members.end());
+      return std::count_if(Members.begin(), End, Check);
+    }
+  }
+  return llvm::None;
+}
+
 SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
                                  TypeInitInfo TypeInfo) :
     Ctx(Ctx), Name(getTypeName(Ctx, Ty, TypeInfo.IsImplicitlyUnwrappedOptional)),
@@ -921,10 +982,12 @@
       PrintedName(getPrintedName(Ctx, VD)), DKind(VD->getKind()),
       USR(calculateUsr(Ctx, VD)), Location(calculateLocation(Ctx, VD)),
       ModuleName(VD->getModuleContext()->getName().str()),
+      IsImplicit(VD->isImplicit()),
       IsThrowing(isFuncThrowing(VD)), IsMutating(isFuncMutating(VD)),
       IsStatic(VD->isStatic()),
       IsDeprecated(VD->getAttrs().getDeprecated(VD->getASTContext())),
-      SelfIndex(getSelfIndex(VD)), ReferenceOwnership(getReferenceOwnership(VD)),
+      SelfIndex(getSelfIndex(VD)), FixedBinaryOrder(getFixedBinaryOrder(VD)),
+      ReferenceOwnership(getReferenceOwnership(VD)),
       GenericSig(printGenericSignature(Ctx, VD)) {
 
   // Calculate usr for its super class.
@@ -1054,7 +1117,7 @@
   return Func;
 }
 
-static bool shouldIgnore(Decl *D, const Decl* Parent) {
+static bool shouldIgnore(Decl *D, const Decl* Parent, SDKContext &Ctx) {
   if (D->isPrivateStdlibDecl(false))
     return true;
   if (AvailableAttr::isUnavailable(D))
@@ -1072,6 +1135,10 @@
     case AccessLevel::Internal:
     case AccessLevel::Private:
     case AccessLevel::FilePrivate:
+      // Private vars with fixed binary orders can have ABI-impact, so we should
+      // whitelist them if we're checking ABI.
+      if (Ctx.checkingABI() && getFixedBinaryOrder(VD).hasValue())
+        break;
       return true;
     case AccessLevel::Public:
     case AccessLevel::Open:
@@ -1153,7 +1220,7 @@
                              IterableDeclContext *Context,
                              std::set<ExtensionDecl*> &HandledExts) {
   for (auto *Member : Context->getMembers()) {
-    if (shouldIgnore(Member, Context->getDecl()))
+    if (shouldIgnore(Member, Context->getDecl(), Ctx))
       continue;
     if (auto Func = dyn_cast<FuncDecl>(Member)) {
       Root->addChild(constructFunctionNode(Ctx, Func, SDKNodeKind::DeclFunction));
@@ -1182,7 +1249,7 @@
     llvm::SmallVector<Decl*, 512> Decls;
     M->getDisplayDecls(Decls);
     for (auto D : Decls) {
-      if (shouldIgnore(D, nullptr))
+      if (shouldIgnore(D, nullptr, Ctx))
         continue;
       if (KnownDecls.count(D))
         continue;
@@ -1300,6 +1367,16 @@
       if (bool isDeprecated = D->isDeprecated())
         out.mapRequired(getKeyContent(Ctx, KeyKind::KK_deprecated).data(),
                         isDeprecated);
+      if (bool isImplicit = D->isImplicit())
+        out.mapRequired(getKeyContent(Ctx, KeyKind::KK_implicit).data(),
+                        isImplicit);
+      if (auto V = dyn_cast<SDKNodeDeclVar>(value)) {
+        if (V->hasFixedBinaryOrder()) {
+          auto Order = V->getFixedBinaryOrder();
+          out.mapRequired(getKeyContent(Ctx, KeyKind::KK_fixedbinaryorder).data(),
+                          Order);
+        }
+      }
       if (auto F = dyn_cast<SDKNodeDeclAbstractFunc>(value)) {
         if (bool isThrowing = F->isThrowing())
           out.mapRequired(getKeyContent(Ctx, KeyKind::KK_throwing).data(),
diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.h b/tools/swift-api-digester/ModuleAnalyzerNodes.h
index 11eac7f..660af51 100644
--- a/tools/swift-api-digester/ModuleAnalyzerNodes.h
+++ b/tools/swift-api-digester/ModuleAnalyzerNodes.h
@@ -220,7 +220,6 @@
   std::set<NodeAnnotation> Annotations;
   std::map<NodeAnnotation, StringRef> AnnotateComments;
   NodePtr Parent = nullptr;
-
 protected:
   SDKNode(SDKNodeInitInfo Info, SDKNodeKind Kind);
 
@@ -253,7 +252,7 @@
   void addChild(SDKNode *Child);
   ArrayRef<SDKNode*> getChildren() const;
   bool hasSameChildren(const SDKNode &Other) const;
-  unsigned getChildIndex(NodePtr Child) const;
+  unsigned getChildIndex(const SDKNode *Child) const;
   SDKNode* getOnlyChild() const;
   SDKContext &getSDKContext() const { return Ctx; }
   SDKNodeRoot *getRootNode() const;
@@ -275,6 +274,7 @@
   StringRef Location;
   StringRef ModuleName;
   std::vector<DeclAttrKind> DeclAttributes;
+  bool IsImplicit;
   bool IsStatic;
   bool IsDeprecated;
   uint8_t ReferenceOwnership;
@@ -301,6 +301,7 @@
   bool isSDKPrivate() const;
   bool isDeprecated() const { return IsDeprecated; };
   bool hasDeclAttribute(DeclAttrKind DAKind) const;
+  bool isImplicit() const { return IsImplicit; };
   bool isStatic() const { return IsStatic; };
   StringRef getGenericSignature() const { return GenericSig; }
   StringRef getScreenInfo() const;
@@ -440,9 +441,12 @@
 };
 
 class SDKNodeDeclVar : public SDKNodeDecl {
+  Optional<unsigned> FixedBinaryOrder;
 public:
   SDKNodeDeclVar(SDKNodeInitInfo Info);
   static bool classof(const SDKNode *N);
+  bool hasFixedBinaryOrder() const { return FixedBinaryOrder.hasValue(); }
+  unsigned getFixedBinaryOrder() const { return *FixedBinaryOrder; }
 };
 
 class SDKNodeDeclAbstractFunc : public SDKNodeDecl {
@@ -538,6 +542,7 @@
                        CheckerOptions Opts);
 
 int findDeclUsr(StringRef dumpPath, CheckerOptions Opts);
+
 } // end of abi namespace
 } // end of ide namespace
 } // end of Swift namespace
diff --git a/tools/swift-api-digester/ModuleDiagsConsumer.cpp b/tools/swift-api-digester/ModuleDiagsConsumer.cpp
index c00bad3..88178bd 100644
--- a/tools/swift-api-digester/ModuleDiagsConsumer.cpp
+++ b/tools/swift-api-digester/ModuleDiagsConsumer.cpp
@@ -47,6 +47,9 @@
     return "/* RawRepresentable Changes */";
   case LocalDiagID::generic_sig_change:
     return "/* Generic Signature Changes */";
+  case LocalDiagID::decl_added:
+  case LocalDiagID::decl_reorder:
+    return "/* Fixed-layout Type Changes */";
   default:
     return StringRef();
   }
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index bc3c9e4..9f0f218 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -709,6 +709,17 @@
             Desc);
         }
       }
+      // Detect re-ordering if they're from structs with a fixed layout.
+      auto *LV = dyn_cast<SDKNodeDeclVar>(L);
+      auto *RV = dyn_cast<SDKNodeDeclVar>(R);
+      if (LV && RV &&
+          LV->hasFixedBinaryOrder() && RV->hasFixedBinaryOrder() &&
+          LV->getFixedBinaryOrder() != RV->getFixedBinaryOrder()) {
+        Ctx.getDiags().diagnose(SourceLoc(), diag::decl_reorder,
+                                LV->getScreenInfo(),
+                                LV->getFixedBinaryOrder(),
+                                RV->getFixedBinaryOrder());
+      }
     }
 
     // Diagnose generic signature change
@@ -751,6 +762,14 @@
     case NodeMatchReason::Added:
       assert(!Left);
       Right->annotate(NodeAnnotation::Added);
+      if (Ctx.checkingABI()) {
+        if (auto *VAD = dyn_cast<SDKNodeDeclVar>(Right)) {
+          if (VAD->hasFixedBinaryOrder()) {
+            Ctx.getDiags().diagnose(SourceLoc(), diag::decl_added,
+                                    VAD->getScreenInfo());
+          }
+        }
+      }
       return;
     case NodeMatchReason::Removed:
       assert(!Right);
diff --git a/utils/build-script-impl b/utils/build-script-impl
index 25e9ea2..80d1caf 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -2879,7 +2879,7 @@
                 # Watchpoint testing is currently disabled: see rdar://38566150.
                 if [[ "$(true_false ${LLDB_TEST_SWIFT_ONLY})" == "TRUE" ]]; then
                     LLDB_TEST_SUBDIR_CLAUSE="--test-subdir lang/swift"
-                    LLDB_TEST_CATEGORIES="--skip-category=watchpoint --skip-category=dwo --skip-category=dwarf"
+                    LLDB_TEST_CATEGORIES="--skip-category=watchpoint --skip-category=dwo"
                 else
                     LLDB_TEST_SUBDIR_CLAUSE=""
                     LLDB_TEST_CATEGORIES="--skip-category=watchpoint"
diff --git a/validation-test/Evolution/Inputs/protocol_add_requirements.swift b/validation-test/Evolution/Inputs/protocol_add_requirements.swift
index 6e2eb34..ba05853 100644
--- a/validation-test/Evolution/Inputs/protocol_add_requirements.swift
+++ b/validation-test/Evolution/Inputs/protocol_add_requirements.swift
@@ -176,24 +176,23 @@
 #endif
 }
 
-public struct Wrapper<T> { }
+public protocol SimpleProtocol {
+  static func getString() -> String
+}
+
+public struct Wrapper<T>: SimpleProtocol {
+  public static func getString() -> String {
+    return "I am a wrapper for \(T.self)"
+  }
+}
 
 public protocol AddAssocTypesProtocol {
-  // FIXME: The presence of a single method requirement causes us to
-  // create a resilient witness table, avoiding a runtime assertion.
-  func dummy()
-
 #if AFTER
   associatedtype AssocType = Self
-  associatedtype AssocType2 = Wrapper<AssocType>
+  associatedtype AssocType2: SimpleProtocol = Wrapper<AssocType>
 #endif
 }
 
-extension AddAssocTypesProtocol {
-  public func dummy() { }
-}
-
-
 public func doSomethingWithAssocTypes<T: AddAssocTypesProtocol>(_ value: T)
     -> String {
 #if AFTER
@@ -202,3 +201,17 @@
   return "there are no associated types yet"
 #endif
 }
+
+public func doSomethingWithAssocConformances<T: AddAssocTypesProtocol>(_ value: T)
+    -> String {
+#if AFTER
+  let at2: Any.Type = T.AssocType2.self
+  if let simpleType = at2 as? SimpleProtocol.Type {
+    return simpleType.getString()
+  }
+  
+  return "missing associated conformance"
+#else
+  return "there are no associated conformances yet"
+#endif
+}
diff --git a/validation-test/Evolution/test_protocol_add_requirements.swift b/validation-test/Evolution/test_protocol_add_requirements.swift
index 046b6ee..2acfb7e 100644
--- a/validation-test/Evolution/test_protocol_add_requirements.swift
+++ b/validation-test/Evolution/test_protocol_add_requirements.swift
@@ -154,5 +154,16 @@
   }
 }
 
+ProtocolAddRequirementsTest.test("AddAssociatedConformanceRequirements") {
+  let addString = AddAssociatedType<String>()
+  let stringResult = doSomethingWithAssocConformances(addString)
+
+  if getVersion() == 0 {
+    expectEqual("there are no associated conformances yet", stringResult)
+  } else {
+    expectEqual("I am a wrapper for AddAssociatedType<String>", stringResult)
+  }
+}
+
 runAllTests()