Merge pull request #16829 from shajrawi/fix_dynamic_cast

diff --git a/.mailmap b/.mailmap
index 16508c2..34c3d73 100644
--- a/.mailmap
+++ b/.mailmap
@@ -1,6 +1,7 @@
 Adrian-Constantin Popescu <epsilon.gamma@gmail.com> <adrian-constantin.popescu@outlook.com>
 Alex Blewitt <alblue@apple.com> <alex.blewitt@gmail.com>
 Alex Hoppen <alex@alexhoppen.de> <alex@ateamer.de>
+Alex Hoppen <alex@alexhoppen.de> <ahoppen@apple.com>>
 Alexis Beingessner <abeingessner@apple.com> <a.beingessner@gmail.com>
 Alper Çugun <github@alper.nl> <alper@users.noreply.github.com>
 Amr Aboelela <amraboelela@gmail.com> <amraboelela@users.noreply.github.com>
@@ -55,10 +56,12 @@
 GauravDS <er.gauravds@gmail.com> <gaurav.sharma@punchh.com>
 Graydon Hoare <ghoare@apple.com> <graydon@users.noreply.github.com>
 Greg Parker <gparker@apple.com> <gparker-github@sealiesoftware.com>
+Greg Titus <gregomni@gmail.com>
 Guillaume Lessard <dhtnstff@gmail.com> <glessard@users.noreply.github.com>
 Hamish <hamish2knight@gmail.com>
 Han Sangjin <tinysun@jssolution.co.kr> <tinysun.net@gmail.com>
 Harlan Haskins <harlan@apple.com> <harlan@harlanhaskins.com>
+Harlan Haskins <harlan@apple.com> <hbh@google.com>
 Hitster GTD <hitstergtd@users.noreply.github.com>
 Huon Wilson <huon@apple.com> <dbau.pp+github@gmail.com>
 Ingmar Stein <IngmarStein@users.noreply.github.com>
@@ -102,6 +105,7 @@
 Mike Ash <mikeash@apple.com> <mike@mikeash.com>
 Mike Ferris <mferris@apple.com> <mike@lorax.com>
 Mishal Awadah <mawadah@apple.com>
+Mishal Shah <mishal_shah@apple.com>
 Mishal Shah <mishal_shah@apple.com> <shahmishal@users.noreply.github.com>
 Nadav Rotem <nrotem@apple.com> <nadavrot@users.noreply.github.com>
 Nate Cook <natecook@apple.com> <nate@Nates-MacBook-Pro.local>
diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake
index 48243be..f544d5b 100644
--- a/cmake/modules/SwiftSharedCMakeConfig.cmake
+++ b/cmake/modules/SwiftSharedCMakeConfig.cmake
@@ -90,6 +90,7 @@
   # selectively add it to the per-target link flags; this is currently done
   # in add_swift_library within AddSwift.cmake.
   string(REGEX REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
+  string(REGEX REPLACE "-Wl,-z,nodelete" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
 
   set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
   string(REGEX REPLACE "([0-9]+)\\.[0-9]+(\\.[0-9]+)?" "\\1" PACKAGE_VERSION_MAJOR
diff --git a/docs/SIL.rst b/docs/SIL.rst
index 589b0c2..5450b8b 100644
--- a/docs/SIL.rst
+++ b/docs/SIL.rst
@@ -4767,6 +4767,24 @@
 returning two bits: the first indicates whether the object is an Objective-C
 object, the second indicates whether it is an Objective-C tagged pointer value.
 
+value_to_bridge_object
+``````````````````````
+::
+
+  sil-instruction ::= 'value_to_bridge_object' sil-operand
+
+  %1 = value_to_bridge_object %0 : $T
+  // %1 will be of type Builtin.BridgeObject
+
+Sets the BridgeObject to a tagged pointer representation holding its operands
+by tagging and shifting the operand if needed::
+
+  value_to_bridge_object %x ===
+  (x << _swift_abi_ObjCReservedLowBits) | _swift_BridgeObject_TaggedPointerBits
+
+``%x`` thus must not be using any high bits shifted away or the tag bits post-shift.
+ARC operations on such tagged values are NOPs.
+
 ref_to_bridge_object
 ````````````````````
 ::
diff --git a/include/swift/ABI/MetadataValues.h b/include/swift/ABI/MetadataValues.h
index 433e958..0a82e16 100644
--- a/include/swift/ABI/MetadataValues.h
+++ b/include/swift/ABI/MetadataValues.h
@@ -138,6 +138,8 @@
   }
 
   /// True if the type requires out-of-line allocation of its storage.
+  /// This can be the case because the value requires more storage or if it is
+  /// not bitwise takable.
   bool isInlineStorage() const { return !(Data & IsNonInline); }
   constexpr TargetValueWitnessFlags withInlineStorage(bool isInline) const {
     return TargetValueWitnessFlags((Data & ~IsNonInline) |
diff --git a/include/swift/ABI/ValueWitness.def b/include/swift/ABI/ValueWitness.def
index b50da3e..52df0c1 100644
--- a/include/swift/ABI/ValueWitness.def
+++ b/include/swift/ABI/ValueWitness.def
@@ -172,14 +172,6 @@
                        MUTABLE_VALUE_TYPE,
                        (MUTABLE_VALUE_TYPE, MUTABLE_VALUE_TYPE, TYPE_TYPE))
 
-///   T *(*initializeBufferWithTakeOfBuffer)(B *dest, B *src, M *self);
-/// Given an invalid buffer, initialize it by taking the value out of
-/// the source buffer.
-FUNCTION_VALUE_WITNESS(initializeBufferWithTakeOfBuffer,
-                       InitializeBufferWithTakeOfBuffer,
-                       MUTABLE_VALUE_TYPE,
-                       (MUTABLE_BUFFER_TYPE, MUTABLE_BUFFER_TYPE, TYPE_TYPE))
-
 /// unsigned (*getEnumTagSinglePayload)(const T* enum, UINT_TYPE emptyCases)
 /// Given an instance of valid single payload enum with a payload of this
 /// witness table's type (e.g Optional<ThisType>) , get the tag of the enum.
@@ -228,7 +220,7 @@
 /// The ValueWitnessIsNonPOD bit is set if the type is not POD.
 ///
 /// The ValueWitnessIsNonInline bit is set if the type cannot be
-/// represented in a fixed-size buffer.
+/// represented in a fixed-size buffer or if it is not bitwise takable.
 ///
 /// The Enum_HasExtraInhabitants bit is set if the type's binary
 /// representation has "extra inhabitants" that do not form valid values of
diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h
index 5fc411e..69b9169 100644
--- a/include/swift/AST/Decl.h
+++ b/include/swift/AST/Decl.h
@@ -122,7 +122,8 @@
   PrecedenceGroup,
   TypeAlias,
   GenericTypeParam,
-  AssociatedType,  
+  AssociatedType,
+  Type,
   Enum,
   Struct,
   Class,
@@ -130,6 +131,7 @@
   GenericEnum,
   GenericStruct,
   GenericClass,
+  GenericType,
   Subscript,
   Constructor,
   Destructor,
@@ -149,6 +151,7 @@
   EnumElement,
   Module,
   MissingMember,
+  Requirement,
 };
 
 /// Keeps track of stage of circularity checking for the given protocol.
diff --git a/include/swift/AST/DiagnosticsDriver.def b/include/swift/AST/DiagnosticsDriver.def
index 0b2b9b3..90b0ae6 100644
--- a/include/swift/AST/DiagnosticsDriver.def
+++ b/include/swift/AST/DiagnosticsDriver.def
@@ -155,6 +155,10 @@
         "the option '-driver-use-filelists' is deprecated; use "
         "'-driver-filelist-threshold=0' instead", ())
 
+WARNING(warn_emit_public_type_metadata_accessors_deprecated, none,
+        "the option '-emit-public-type-metadata-accessors' is no longer "
+        "needed and is deprecated; consider removing it", ())
+
 REMARK(remark_using_batch_mode,none, "using batch mode", ())
 
 #ifndef DIAG_NO_UNDEF
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 7ce915b..e081ec0 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -37,11 +37,16 @@
   DIAG(NOTE,ID,Options,Text,Signature)
 #endif
 
-
-NOTE(type_declared_here,none,
-     "type declared here", ())
+NOTE(kind_declname_declared_here,none,
+     "%0 %1 declared here", (DescriptiveDeclKind, DeclName))
+NOTE(kind_identifier_declared_here,none,
+     "%0 %1 declared here", (DescriptiveDeclKind, Identifier))
 NOTE(decl_declared_here,none,
      "%0 declared here", (DeclName))
+NOTE(identifier_declared_here,none,
+     "%0 declared here", (Identifier))
+NOTE(kind_declared_here,none,
+     "%0 declared here", (DescriptiveDeclKind))
 NOTE(implicit_member_declared_here,none,
      "%1 '%0' is implicitly declared", (StringRef, StringRef))
 NOTE(extended_type_declared_here,none,
@@ -75,6 +80,11 @@
       "type %0 has no member %1; did you mean %2?",
       (Type, DeclName, DeclName))
 
+ERROR(could_not_find_subscript_member_did_you_mean,none,
+      "value of type %0 has no property or method named 'subscript'; "
+      "did you mean to use the subscript operator?",
+      (Type))
+
 ERROR(could_not_find_enum_case,none,
       "enum type %0 has no case %1; did you mean %2", (Type, DeclName, DeclName))
 
@@ -759,8 +769,6 @@
       "precedence group cannot be given lower precedence than group in same"
       " module; make the other precedence group higher than this one instead",
       ())
-NOTE(precedence_group_declared_here,none,"precedence group declared here",
-      ())
 ERROR(precedence_group_redeclared,none,
       "precedence group redeclared", ())
 NOTE(previous_precedence_group_decl,none,
@@ -1682,8 +1690,6 @@
      "possibly intended match %0 does not "
      "%select{inherit from|conform to}2 %1", (Type, Type, bool))
 
-NOTE(protocol_requirement_here,none,
-     "requirement %0 declared here", (DeclName))
 NOTE(protocol_conformance_here,none,
      "%select{|class }0%1 declares conformance to protocol %2 here",
      (bool, DeclName, DeclName))
@@ -1746,8 +1752,6 @@
 
 ERROR(circular_protocol_def,none,
       "circular protocol inheritance %0", (StringRef))
-NOTE(protocol_here,none,
-     "protocol %0 declared here", (Identifier))
 ERROR(objc_protocol_inherits_non_objc_protocol,none,
       "@objc protocol %0 cannot refine non-@objc protocol %1", (Type, Type))
 WARNING(protocol_composition_with_postfix,none,
@@ -2065,8 +2069,6 @@
   "superclass %0 of open class must be open", (Type))
 ERROR(circular_class_inheritance,none,
       "circular class inheritance %0", (StringRef))
-NOTE(class_here,none,
-     "class %0 declared here", (Identifier))
 ERROR(inheritance_from_final_class,none,
       "inheritance from a final class %0", (Identifier))
 ERROR(inheritance_from_unspecialized_objc_generic_class,none,
@@ -2134,8 +2136,6 @@
         "%select{a private|a fileprivate|an internal|%error|%error}2 type",
         (bool, AccessLevel, AccessLevel, bool))
 
-NOTE(enum_here,none,
-     "enum %0 declared here", (Identifier))
 ERROR(empty_enum_raw_type,none,
       "an enum with no cases cannot declare a raw type", ())
 ERROR(enum_raw_value_without_raw_type,none,
@@ -2240,8 +2240,6 @@
       "property behavior name must refer to a protocol", ())
 ERROR(property_behavior_protocol_reqt_ambiguous,none,
       "property behavior protocol has ambiguous %0 member", (Identifier))
-NOTE(property_behavior_protocol_reqt_here,none,
-     "%0 declared here", (Identifier))
 ERROR(property_behavior_protocol_no_value,none,
       "property behavior protocol does not have a 'value' property", ())
 ERROR(property_behavior_protocol_no_initStorage,none,
@@ -2678,8 +2676,6 @@
       (Identifier, unsigned, unsigned, bool))
 ERROR(generic_type_requires_arguments,none,
       "reference to generic type %0 requires arguments in <...>", (Type))
-NOTE(generic_type_declared_here,none,
-     "generic type %0 declared here", (Identifier))
 NOTE(descriptive_generic_type_declared_here,none,
      "%0 declared here", (StringRef))
 
diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h
index c4fb037..d49f6b9 100644
--- a/include/swift/AST/Expr.h
+++ b/include/swift/AST/Expr.h
@@ -549,6 +549,10 @@
   /// a builtin operator.
   bool isInfixOperator() const;
 
+  /// Returns true if this is a reference to the implicit self of function.
+  bool isSelfExprOf(const AbstractFunctionDecl *AFD,
+                    bool sameBase = false) const;
+
   /// Produce a mapping from each subexpression to its parent
   /// expression, with the provided expression serving as the root of
   /// the parent map.
diff --git a/include/swift/AST/Initializer.h b/include/swift/AST/Initializer.h
index 053cb8a..c3ce60d 100644
--- a/include/swift/AST/Initializer.h
+++ b/include/swift/AST/Initializer.h
@@ -162,7 +162,7 @@
   /// Change the parent of this context.  This is necessary because
   /// the function signature is parsed before the function
   /// declaration/expression itself is built.
-  void changeFunction(DeclContext *parent, MutableArrayRef<ParameterList *> paramLists);
+  void changeFunction(DeclContext *parent, ArrayRef<ParameterList *> paramLists);
 
   static bool classof(const DeclContext *DC) {
     if (auto init = dyn_cast<Initializer>(DC))
diff --git a/include/swift/AST/Stmt.h b/include/swift/AST/Stmt.h
index 6f3b473..c6ea9c8 100644
--- a/include/swift/AST/Stmt.h
+++ b/include/swift/AST/Stmt.h
@@ -128,7 +128,7 @@
   LLVM_ATTRIBUTE_DEPRECATED(
       void dump() const LLVM_ATTRIBUTE_USED,
       "only for use within the debugger");
-  void print(raw_ostream &OS, unsigned Indent = 0) const;
+  void print(raw_ostream &OS, const ASTContext *Ctx = nullptr, unsigned Indent = 0) const;
 
   // Only allow allocation of Exprs using the allocator in ASTContext
   // or by doing a placement new.
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index f31121c..f14fbd2 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -3059,12 +3059,6 @@
   /// function type and return the resulting non-generic type.
   FunctionType *substGenericArgs(SubstitutionMap subs);
 
-  /// Substitute the given generic arguments into this generic
-  /// function type using the given substitution and conformance lookup
-  /// callbacks.
-  FunctionType *substGenericArgs(TypeSubstitutionFn subs,
-                                 LookupConformanceFn conformances);
-
   void Profile(llvm::FoldingSetNodeID &ID) {
     Profile(ID, getGenericSignature(), getInput(), getResult(),
             getExtInfo());
diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index 5ef1aae..2f56591 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -223,9 +223,6 @@
     /// Enables key path resilience.
     bool EnableKeyPathResilience = false;
 
-    /// Enables public emission of private metadata accessors.
-    bool EmitPublicTypeMetadataAccessors = false;
-
     /// If set to true, the diagnosis engine can assume the emitted diagnostics
     /// will be used in editor. This usually leads to more aggressive fixit.
     bool DiagnosticsEditorMode = false;
diff --git a/include/swift/IDE/DigesterEnums.def b/include/swift/IDE/DigesterEnums.def
index 0a21aaf..26fb0cb 100644
--- a/include/swift/IDE/DigesterEnums.def
+++ b/include/swift/IDE/DigesterEnums.def
@@ -79,6 +79,7 @@
 NODE_ANNOTATION_CHANGE_KIND(OptionalArrayMemberUpdate)
 NODE_ANNOTATION_CHANGE_KIND(SimpleStringRepresentableUpdate)
 NODE_ANNOTATION_CHANGE_KIND(SimpleOptionalStringRepresentableUpdate)
+NODE_ANNOTATION_CHANGE_KIND(TypeAliasDeclToRawRepresentable)
 
 NODE_ANNOTATION_CHANGE_KIND(RevertDictionaryKeyUpdate)
 NODE_ANNOTATION_CHANGE_KIND(RevertOptionalDictionaryKeyUpdate)
diff --git a/include/swift/IDE/RefactoringKinds.def b/include/swift/IDE/RefactoringKinds.def
index cbb0e1e..3764fdf 100644
--- a/include/swift/IDE/RefactoringKinds.def
+++ b/include/swift/IDE/RefactoringKinds.def
@@ -44,7 +44,7 @@
 
 CURSOR_REFACTORING(SimplifyNumberLiteral, "Simplify Long Number Literal", simplify.long.number.literal)
 
-CURSOR_REFACTORING(CollapseNestedIfExpr, "Collapse Nested If Expression", collapse.nested.if.expr)
+CURSOR_REFACTORING(CollapseNestedIfStmt, "Collapse Nested If Statements", collapse.nested.ifstmt)
 
 CURSOR_REFACTORING(ConvertToDoCatch, "Convert To Do/Catch", convert.do.catch)
 
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index 36563c9..3fb1be9 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -880,6 +880,9 @@
                      llvm::GlobalValue::VisibilityTypes Visibility,
                      llvm::GlobalValue::DLLStorageClassTypes DLLStorage);
 };
+
+StringRef encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
+                                    StringRef name);
 }
 }
 
@@ -910,5 +913,4 @@
            LHS.SecondaryPointer == RHS.SecondaryPointer && LHS.Data == RHS.Data;
   }
 };
-
 #endif
diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td
index 6d3edf2..dfbf752 100644
--- a/include/swift/Option/Options.td
+++ b/include/swift/Option/Options.td
@@ -358,7 +358,7 @@
 def emit_public_type_metadata_accessors :
   Flag<["-"], "emit-public-type-metadata-accessors">,
   Flags<[FrontendOption]>,
-  HelpText<"Emit all type metadata accessors as public">;
+  HelpText<"Emit all type metadata accessors as public (deprecated: now does nothing)">;
 
 def Rpass_EQ : Joined<["-"], "Rpass=">,
   Flags<[FrontendOption]>,
diff --git a/include/swift/Parse/Parser.h b/include/swift/Parse/Parser.h
index a805082..46d0091 100644
--- a/include/swift/Parse/Parser.h
+++ b/include/swift/Parse/Parser.h
@@ -466,6 +466,16 @@
     return consumeToken();
   }
 
+  SourceLoc consumeArgumentLabel(Identifier &Result) {
+    assert(Tok.canBeArgumentLabel());
+    assert(Result.empty());
+    if (!Tok.is(tok::kw__)) {
+      Tok.setKind(tok::identifier);
+      Result = Context.getIdentifier(Tok.getText());
+    }
+    return consumeToken();
+  }
+
   /// \brief Retrieve the location just past the end of the previous
   /// source location.
   SourceLoc getEndOfPreviousLoc();
@@ -1015,7 +1025,7 @@
 
     /// Set the parsed context for all the initializers to the given
     /// function.
-    void setFunctionContext(DeclContext *DC, MutableArrayRef<ParameterList *> paramList);
+    void setFunctionContext(DeclContext *DC, ArrayRef<ParameterList *> paramList);
     
     DefaultArgumentInfo(bool inTypeContext) {
       NextIndex = inTypeContext ? 1 : 0;
diff --git a/include/swift/Reflection/ReflectionContext.h b/include/swift/Reflection/ReflectionContext.h
index a88e8bc..a58d9e6 100644
--- a/include/swift/Reflection/ReflectionContext.h
+++ b/include/swift/Reflection/ReflectionContext.h
@@ -148,14 +148,14 @@
 
     // The docs say "not all sections may be present." We'll succeed if ANY of
     // them are present. Not sure if that's the right thing to do.
-    auto FieldMd = findSection<FieldSection>(Header, "__swift4_fieldmd");
+    auto FieldMd = findSection<FieldSection>(Header, "__swift5_fieldmd");
     auto AssocTyMd =
-        findSection<AssociatedTypeSection>(Header, "__swift4_assocty");
+        findSection<AssociatedTypeSection>(Header, "__swift5_assocty");
     auto BuiltinTyMd =
-        findSection<BuiltinTypeSection>(Header, "__swift4_builtin");
-    auto CaptureMd = findSection<CaptureSection>(Header, "__swift4_capture");
-    auto TyperefMd = findSection<GenericSection>(Header, "__swift4_typeref");
-    auto ReflStrMd = findSection<GenericSection>(Header, "__swift4_reflstr");
+        findSection<BuiltinTypeSection>(Header, "__swift5_builtin");
+    auto CaptureMd = findSection<CaptureSection>(Header, "__swift5_capture");
+    auto TyperefMd = findSection<GenericSection>(Header, "__swift5_typeref");
+    auto ReflStrMd = findSection<GenericSection>(Header, "__swift5_reflstr");
 
     bool success = FieldMd.second || AssocTyMd.second || BuiltinTyMd.second ||
                    CaptureMd.second || TyperefMd.second || ReflStrMd.second;
diff --git a/include/swift/Runtime/Concurrent.h b/include/swift/Runtime/Concurrent.h
index 274d221..003088c 100644
--- a/include/swift/Runtime/Concurrent.h
+++ b/include/swift/Runtime/Concurrent.h
@@ -451,7 +451,44 @@
   Mutex WriterLock;
   std::vector<Storage *> FreeList;
   
+  void incrementReaders() {
+    ReaderCount.fetch_add(1, std::memory_order_acquire);
+  }
+  
+  void decrementReaders() {
+    ReaderCount.fetch_sub(1, std::memory_order_release);
+  }
+  
+  void deallocateFreeList() {
+    for (Storage *storage : FreeList)
+      storage->deallocate();
+    FreeList.clear();
+    FreeList.shrink_to_fit();
+  }
+  
 public:
+  struct Snapshot {
+    ConcurrentReadableArray *Array;
+    const ElemTy *Start;
+    size_t Count;
+    
+    Snapshot(ConcurrentReadableArray *array, const ElemTy *start, size_t count)
+      : Array(array), Start(start), Count(count) {}
+    
+    Snapshot(const Snapshot &other)
+      : Array(other.Array), Start(other.Start), Count(other.Count) {
+      Array->incrementReaders();
+    }
+    
+    ~Snapshot() {
+      Array->decrementReaders();
+    }
+    
+    const ElemTy *begin() { return Start; }
+    const ElemTy *end() { return Start + Count; }
+    size_t count() { return Count; }
+  };
+  
   // This type cannot be safely copied, moved, or deleted.
   ConcurrentReadableArray(const ConcurrentReadableArray &) = delete;
   ConcurrentReadableArray(ConcurrentReadableArray &&) = delete;
@@ -459,6 +496,12 @@
   
   ConcurrentReadableArray() : Capacity(0), ReaderCount(0), Elements(nullptr) {}
   
+  ~ConcurrentReadableArray() {
+    assert(ReaderCount.load(std::memory_order_acquire) == 0 &&
+           "deallocating ConcurrentReadableArray with outstanding snapshots");
+    deallocateFreeList();
+  }
+  
   void push_back(const ElemTy &elem) {
     ScopedLock guard(WriterLock);
     
@@ -482,32 +525,19 @@
     storage->Count.store(count + 1, std::memory_order_release);
     
     if (ReaderCount.load(std::memory_order_acquire) == 0)
-      for (Storage *storage : FreeList)
-        storage->deallocate();
+      deallocateFreeList();
   }
   
-  /// Read the contents of the array. The parameter `f` is called with
-  /// two parameters: a pointer to the elements in the array, and the
-  /// count. This represents a snapshot of the contents at the time
-  /// `read` was called. The pointer becomes invalid after `f` returns.
-  template <class F> auto read(F f) -> decltype(f(nullptr, 0)) {
-    ReaderCount.fetch_add(1, std::memory_order_acquire);
+  Snapshot snapshot() {
+    incrementReaders();
     auto *storage = Elements.load(SWIFT_MEMORY_ORDER_CONSUME);
+    if (storage == nullptr) {
+      return Snapshot(this, nullptr, 0);
+    }
+    
     auto count = storage->Count.load(std::memory_order_acquire);
     const auto *ptr = storage->data();
-    
-    decltype(f(nullptr, 0)) result = f(ptr, count);
-    
-    ReaderCount.fetch_sub(1, std::memory_order_release);
-    
-    return result;
-  }
-  
-  /// Get the current count. It's just a snapshot and may be obsolete immediately.
-  size_t count() {
-    return read([](const ElemTy *ptr, size_t count) -> size_t {
-      return count;
-    });
+    return Snapshot(this, ptr, count);
   }
 };
 
diff --git a/include/swift/Runtime/Metadata.h b/include/swift/Runtime/Metadata.h
index 3d4e384..897f2b6 100644
--- a/include/swift/Runtime/Metadata.h
+++ b/include/swift/Runtime/Metadata.h
@@ -278,13 +278,15 @@
 using ValueBuffer = TargetValueBuffer<InProcess>;
 
 /// Can a value with the given size and alignment be allocated inline?
-constexpr inline bool canBeInline(size_t size, size_t alignment) {
-  return size <= sizeof(ValueBuffer) && alignment <= alignof(ValueBuffer);
+constexpr inline bool canBeInline(bool isBitwiseTakable, size_t size,
+                                  size_t alignment) {
+  return isBitwiseTakable && size <= sizeof(ValueBuffer) &&
+         alignment <= alignof(ValueBuffer);
 }
 
 template <class T>
-constexpr inline bool canBeInline() {
-  return canBeInline(sizeof(T), alignof(T));
+constexpr inline bool canBeInline(bool isBitwiseTakable) {
+  return canBeInline(isBitwiseTakable, sizeof(T), alignof(T));
 }
 
 struct ValueWitnessTable;
@@ -345,8 +347,8 @@
 
   /// Would values of a type with the given layout requirements be
   /// allocated inline?
-  static bool isValueInline(size_t size, size_t alignment) {
-    return (size <= sizeof(ValueBuffer) &&
+  static bool isValueInline(bool isBitwiseTakable, size_t size, size_t alignment) {
+    return (isBitwiseTakable && size <= sizeof(ValueBuffer) &&
             alignment <= alignof(ValueBuffer));
   }
 
diff --git a/include/swift/SIL/MemAccessUtils.h b/include/swift/SIL/MemAccessUtils.h
index 8eb5145..562f5d8 100644
--- a/include/swift/SIL/MemAccessUtils.h
+++ b/include/swift/SIL/MemAccessUtils.h
@@ -53,17 +53,17 @@
   }
 };
 
-/// Represents the identity of a storage location being accessed.
+/// Represents the identity of a storage object being accessed.
 ///
 /// AccessedStorage may be one of several kinds of "identified" storage
-/// locations, or may be valid, but Unidentified storage. An identified location
+/// objects, or may be valid, but Unidentified storage. An identified object
 /// is known to identify the base of the accessed storage, whether that is a
 /// SILValue that produces the base address, or a variable
 /// declaration. "Uniquely identified" storage refers to identified storage that
 /// cannot be aliased. For example, local allocations are uniquely identified,
 /// while global variables and class properties are not. Unidentified storage is
 /// associated with a SILValue that produces the accessed address but has not
-/// been determined to be the base of a storage location. It may, for example,
+/// been determined to be the base of a storage object. It may, for example,
 /// be a SILPHIArgument.
 ///
 /// An invalid AccessedStorage object is marked Unidentified and contains an
@@ -72,19 +72,19 @@
 /// SILVerification could allow the optimizer to aggressively assert that
 /// AccessedStorage is always valid.
 ///
-/// Note that the SILValue that represents a storage location is not
+/// Note that the SILValue that represents a storage object is not
 /// necessarilly an address type. It may instead be a SILBoxType.
 ///
-/// AccessedStorage hashing and comparison is used to determine when two
-/// 'begin_access' instructions access the same or disjoint underlying
-/// locations.
+/// AccessedStorage hashing and comparison (via DenseMapInfo) is used to
+/// determine when two 'begin_access' instructions access the same or disjoint
+/// underlying objects.
 ///
-/// Equality guarantees that two AccessStorage values refer to the same
-/// memory if both values are valid.
+/// `DenseMapInfo::isEqual()` guarantees that two AccessStorage values refer to
+/// the same memory if both values are valid.
 ///
-/// Inequality does not guarantee that two identified AccessStorage values
-/// distinct. Inequality does guarantee that two *uniquely* identified
-/// AccessStorage values are distinct.
+/// `!DenseMapInfo::isEqual()` does not guarantee that two identified
+/// AccessStorage values are distinct. Inequality does, however, guarantee that
+/// two *uniquely* identified AccessStorage values are distinct.
 class AccessedStorage {
 public:
   /// Enumerate over all valid begin_access bases. Clients can use a covered
@@ -111,26 +111,42 @@
   // with the fields used within this class as a common prefix.
   //
   // This allows passes to embed analysis flags, and reserves enough space to
-  // embed a unique access index.
+  // embed a unique index.
+  //
+  // AccessedStorageAnalysis defines an StorageAccessInfo object that maps each
+  // storage object within a function to its unique storage index and summary
+  // information of that storage object.
+  //
+  // AccessEnforcementOpts defines an AccessEnforcementOptsInfo object that maps
+  // each begin_access to its storage object, unique access index, and summary
+  // info for that access.
   union {
     uint64_t OpaqueBits;
-    SWIFT_INLINE_BITFIELD_BASE(AccessedStorage, bitmax(NumKindBits, 8), Kind
-                               : bitmax(NumKindBits, 8));
+    SWIFT_INLINE_BITFIELD_BASE(AccessedStorage, bitmax(NumKindBits, 8),
+                               Kind : bitmax(NumKindBits, 8));
 
-    // Define bits for use in the AccessEnforcementOpts pass. Reserve the high
-    // bit for a seenNestedConflict flag, which is the result of pass-specific
-    // analysis. The remaning bits are sufficient to index all
+    // Define bits for use in AccessedStorageAnalysis. Each identified storage
+    // object is mapped to one instance of this subclass.
+    SWIFT_INLINE_BITFIELD_FULL(StorageAccessInfo, AccessedStorage,
+                               64 - NumAccessedStorageBits,
+                               accessKind : NumSILAccessKindBits,
+                               noNestedConflict : 1,
+                               storageIndex : 64 - (NumAccessedStorageBits
+                                                    + NumSILAccessKindBits
+                                                    + 1));
+
+    // Define bits for use in the AccessEnforcementOpts pass. Each begin_access
+    // in the function is mapped to one instance of this subclass.  Reserve a
+    // bit for a seenNestedConflict flag, which is the per-begin-access result
+    // of pass-specific analysis. The remaning bits are sufficient to index all
     // begin_[unpaired_]access instructions.
     //
-    // `AccessEnforcementOpts` does not need to be a defined class. This macro
-    // simply defines the pass-specific name "AccessEnforcementOptsBitfield".
-    //
-    // `AccessedStorage` identifies the AccessedStoredBitfield defined above,
+    // `AccessedStorage` refers to the AccessedStorageBitfield defined above,
     // setting aside enough bits for common data.
     SWIFT_INLINE_BITFIELD_FULL(AccessEnforcementOptsInfo, AccessedStorage,
                                64 - NumAccessedStorageBits,
-                               beginAccessIndex : 63 - NumAccessedStorageBits,
-                               seenNestedConflict : 1);
+                               seenNestedConflict : 1,
+                               beginAccessIndex : 63 - NumAccessedStorageBits);
   } Bits;
 
 private:
@@ -156,7 +172,7 @@
     initKind(Class);
   }
 
-  // Return true if this is a valid storage location.
+  // Return true if this is a valid storage object.
   operator bool() const { return getKind() != Unidentified || value; }
 
   Kind getKind() const { return static_cast<Kind>(Bits.AccessedStorage.Kind); }
@@ -205,6 +221,20 @@
     }
   }
 
+  bool isLocal() const {
+    switch (getKind()) {
+    case Box:
+    case Stack:
+      return true;
+    case Global:
+    case Class:
+    case Argument:
+    case Nested:
+    case Unidentified:
+      return false;
+    }
+  }
+
   bool isUniquelyIdentified() const {
     switch (getKind()) {
     case Box:
@@ -231,6 +261,13 @@
 
   void print(raw_ostream &os) const;
   void dump() const;
+
+private:
+  // Disable direct comparison because we allow subclassing with bitfields.
+  // Currently, we use DenseMapInfo to unique storage, which defines key
+  // equalilty only in terms of the base AccessedStorage class bits.
+  bool operator==(const AccessedStorage &) const = delete;
+  bool operator!=(const AccessedStorage &) const = delete;
 };
 } // end namespace swift
 
@@ -300,9 +337,9 @@
 /// memory, return an AccessedStorage object that identifies the formal access.
 ///
 /// The returned AccessedStorage represents the best attempt to find the base of
-/// the storage location being accessed at `sourceAddr`. This may be a fully
+/// the storage object being accessed at `sourceAddr`. This may be a fully
 /// identified storage base of known kind, or a valid but Unidentified storage
-/// location, such as a SILPHIArgument.
+/// object, such as a SILPHIArgument.
 ///
 /// This may return an invalid storage object if the address producer is not
 /// recognized by a whitelist of recognizable access patterns. The result must
@@ -347,6 +384,14 @@
 void visitAccessedAddress(SILInstruction *I,
                           llvm::function_ref<void(Operand *)> visitor);
 
+/// Perform a RAUW operation on begin_access with it's own source operand.
+/// Then erase the begin_access and all associated end_access instructions.
+/// Return an iterator to the following instruction.
+///
+/// The caller should use this iterator rather than assuming that the
+/// instruction following this begin_access was not also erased.
+SILBasicBlock::iterator removeBeginAccess(BeginAccessInst *beginAccess);
+
 } // end namespace swift
 
 #endif
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index cb3830b..0fe4591 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -3184,8 +3184,10 @@
   Deinit,
 
   // This enum is encoded.
-  Last = Deinit
+  Last = Deinit,
 };
+enum { NumSILAccessKindBits = 2 };
+
 StringRef getSILAccessKindName(SILAccessKind kind);
 
 /// Different kinds of exclusivity enforcement for accesses.
diff --git a/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h b/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h
index b4d1024..b0e6af4 100644
--- a/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h
@@ -15,10 +15,10 @@
 // used by AccessEnforcementOpts to locally fold access scopes and remove
 // dynamic checks based on whole module analysis.
 //
-// Note: This can be easily augmented to simultaneously compute
-// FunctionSideEffects by adding FunctionSideEffects as a member of
-// FunctionAccessedStorage. However, currently, the only use of
-// FunctionAccessedStorage is local to summarizeFunction().
+// Note: This interprocedural analysis can be easily augmented to simultaneously
+// compute FunctionSideEffects, without using a separate analysis, by adding
+// FunctionSideEffects as a member of FunctionAccessedStorage. However, passes
+// that use AccessedStorageAnalysis do not currently need SideEffectAnalysis.
 //
 //===----------------------------------------------------------------------===//
 #ifndef SWIFT_SILOPTIMIZER_ANALYSIS_ACCESSED_STORAGE_ANALYSIS_H_
@@ -33,48 +33,139 @@
 
 /// Information about a formal access within a function pertaining to a
 /// particular AccessedStorage location.
-struct StorageAccessInfo {
-  SILAccessKind accessKind;
-  bool noNestedConflict = false;
+class StorageAccessInfo : public AccessedStorage {
+public:
+  StorageAccessInfo(AccessedStorage storage, SILAccessKind accessKind,
+                    bool noNestedConflict)
+    : AccessedStorage(storage) {
+    Bits.StorageAccessInfo.accessKind = unsigned(accessKind);
+    Bits.StorageAccessInfo.noNestedConflict = noNestedConflict;
+    Bits.StorageAccessInfo.storageIndex = 0;
+  }
 
-  StorageAccessInfo() {}
+  // Initialize AccessedStorage from the given storage argument and fill in
+  // subclass fields from otherStorageInfo.
+  StorageAccessInfo(AccessedStorage storage, StorageAccessInfo otherStorageInfo)
+      : StorageAccessInfo(storage, otherStorageInfo.getAccessKind(),
+                          otherStorageInfo.hasNoNestedConflict()) {}
 
   template <typename B>
-  explicit StorageAccessInfo(B *beginAccess)
-      : accessKind(beginAccess->getAccessKind()),
-        noNestedConflict(beginAccess->hasNoNestedConflict()) {
+  StorageAccessInfo(AccessedStorage storage, B *beginAccess)
+      : StorageAccessInfo(storage, beginAccess->getAccessKind(),
+                          beginAccess->hasNoNestedConflict()) {
     // Currently limited to dynamic Read/Modify access.
     assert(beginAccess->getEnforcement() == SILAccessEnforcement::Dynamic);
   }
 
+  /// Get the merged access kind of all accesses on this storage. If any access
+  /// is a Modify, the return Modify, otherwise return Read.
+  SILAccessKind getAccessKind() const {
+    return SILAccessKind(Bits.StorageAccessInfo.accessKind);
+  }
+
+  void setAccessKind(SILAccessKind accessKind) {
+    Bits.StorageAccessInfo.accessKind = unsigned(accessKind);
+  }
+
+  /// Get a unique index for this accessed storage within a function.
+  unsigned getStorageIndex() const {
+    return Bits.StorageAccessInfo.storageIndex;
+  }
+
+  void setStorageIndex(unsigned index) {
+    Bits.StorageAccessInfo.storageIndex = index;
+    assert(unsigned(Bits.StorageAccessInfo.storageIndex) == index);
+  }
+
+  /// Return true if all accesses of this storage within a function have the
+  /// [no_nested_conflict] flag set.
+  bool hasNoNestedConflict() const {
+    return Bits.StorageAccessInfo.noNestedConflict;
+  }
+
+  void setNoNestedConflict(bool val) {
+    Bits.StorageAccessInfo.noNestedConflict = val;
+  }
+
   bool mergeFrom(const StorageAccessInfo &RHS);
+
+  void print(raw_ostream &os) const;
+  void dump() const;
+};
+} // namespace swift
+
+// Use the same DenseMapInfo for StorageAccessInfo as for AccessedStorage. None
+// of the subclass bitfields participate in the Key.
+template <> struct llvm::DenseMapInfo<swift::StorageAccessInfo> {
+  static swift::StorageAccessInfo getEmptyKey() {
+    auto key = DenseMapInfo<swift::AccessedStorage>::getEmptyKey();
+    return static_cast<swift::StorageAccessInfo &>(key);
+  }
+
+  static swift::StorageAccessInfo getTombstoneKey() {
+    auto key = DenseMapInfo<swift::AccessedStorage>::getTombstoneKey();
+    return static_cast<swift::StorageAccessInfo &>(key);
+  }
+  static unsigned getHashValue(swift::StorageAccessInfo storage) {
+    return DenseMapInfo<swift::AccessedStorage>::getHashValue(storage);
+  }
+  static bool isEqual(swift::StorageAccessInfo LHS,
+                      swift::StorageAccessInfo RHS) {
+    return DenseMapInfo<swift::AccessedStorage>::isEqual(LHS, RHS);
+  }
 };
 
+namespace swift {
 /// The per-function result of AccessedStorageAnalysis.
 ///
-/// Maps each unique AccessedStorage location to StorageAccessInfo.
+/// Records each unique AccessedStorage in a set of StorageAccessInfo
+/// objects. Hashing and equality only sees the AccesedStorage data. The
+/// additional StorageAccessInfo bits are recorded as results of this analysis.
 ///
 /// Any unidentified accesses are summarized as a single unidentifiedAccess
 /// property.
 class FunctionAccessedStorage {
-  using AccessedStorageMap =
-      llvm::SmallDenseMap<AccessedStorage, StorageAccessInfo, 8>;
+  using AccessedStorageSet = llvm::SmallDenseSet<StorageAccessInfo, 8>;
 
-  AccessedStorageMap storageAccessMap;
+  AccessedStorageSet storageAccessSet;
   Optional<SILAccessKind> unidentifiedAccess;
 
 public:
   FunctionAccessedStorage() {}
 
+  // ---------------------------------------------------------------------------
+  // Accessing the results.
+
+  bool hasUnidentifiedAccess() const { return unidentifiedAccess != None; }
+
+  /// Return true if the analysis has determined all accesses of otherStorage
+  /// have the [no_nested_conflict] flag set.
+  ///
+  /// Only call this if there is no unidentifiedAccess in the function and the
+  /// given storage is uniquely identified.
+  bool hasNoNestedConflict(const AccessedStorage &otherStorage) const;
+
+  /// Does any of the accesses represented by this FunctionAccessedStorage
+  /// object conflict with the given access kind and storage.
+  bool mayConflictWith(SILAccessKind otherAccessKind,
+                       const AccessedStorage &otherStorage) const;
+
+  /// Raw access to the result for a given AccessedStorage location.
+  StorageAccessInfo
+  getStorageAccessInfo(const AccessedStorage &otherStorage) const;
+
+  // ---------------------------------------------------------------------------
+  // Constructing the results.
+
   void clear() {
-    storageAccessMap.clear();
+    storageAccessSet.clear();
     unidentifiedAccess = None;
   }
 
   /// Sets the most conservative effects, if we don't know anything about the
   /// function.
   void setWorstEffects() {
-    storageAccessMap.clear();
+    storageAccessSet.clear();
     unidentifiedAccess = SILAccessKind::Modify;
   }
 
@@ -98,7 +189,7 @@
   ///
   /// TODO: Summarize ArraySemanticsCall accesses.
   bool summarizeCall(FullApplySite fullApply) {
-    assert(storageAccessMap.empty() && "expected uninitialized results.");
+    assert(storageAccessSet.empty() && "expected uninitialized results.");
     return false;
   }
 
@@ -121,20 +212,22 @@
   /// reaches MaxRecursionDepth.
   void analyzeInstruction(SILInstruction *I);
 
-  /// Does any of the accesses represented by this FunctionAccessedStorage
-  /// object conflict with the given access kind and storage.
-  bool mayConflictWith(SILAccessKind otherAccessKind,
-                       const AccessedStorage &otherStorage);
-
   void print(raw_ostream &os) const;
   void dump() const;
 
 protected:
+  std::pair<AccessedStorageSet::iterator, bool>
+  insertStorageAccess(StorageAccessInfo storageAccess) {
+    storageAccess.setStorageIndex(storageAccessSet.size());
+    return storageAccessSet.insert(storageAccess);
+  }
+
   bool updateUnidentifiedAccess(SILAccessKind accessKind);
 
   bool mergeAccesses(
-      const FunctionAccessedStorage &RHS,
-      std::function<AccessedStorage(const AccessedStorage &)> transformStorage);
+      const FunctionAccessedStorage &other,
+      std::function<StorageAccessInfo(const StorageAccessInfo &)>
+          transformStorage);
 
   template <typename B> void visitBeginAccess(B *beginAccess);
 };
@@ -149,6 +242,10 @@
 /// marked as potentially executing unidentified reads or writes. An incomplete
 /// function, without a known callee set, is considered to have unidentified
 /// writes.
+///
+/// Use the GenericFunctionEffectAnalysis API to get the results of the analysis:
+/// - geEffects(SILFunction*)
+/// - getCallSiteEffects(FunctionEffects &callEffects, FullApplySite fullApply)
 class AccessedStorageAnalysis
     : public GenericFunctionEffectAnalysis<FunctionAccessedStorage> {
 public:
diff --git a/include/swift/SILOptimizer/PassManager/Passes.def b/include/swift/SILOptimizer/PassManager/Passes.def
index 2732582..8d9cab9 100644
--- a/include/swift/SILOptimizer/PassManager/Passes.def
+++ b/include/swift/SILOptimizer/PassManager/Passes.def
@@ -236,6 +236,8 @@
      "Deserialize all referenced SIL functions that are shared or transparent")
 PASS(PerformanceSILLinker, "performance-linker",
      "Deserialize all referenced SIL functions")
+PASS(RawSILInstLowering, "raw-sil-inst-lowering",
+     "Lower all raw SIL instructions to canonical equivalents.")
 PASS(RemovePins, "remove-pins",
      "Remove SIL pin/unpin pairs")
 PASS(TempRValueOpt, "temp-rvalue-opt",
diff --git a/include/swift/TBDGen/TBDGen.h b/include/swift/TBDGen/TBDGen.h
index ba9121c..eca9386 100644
--- a/include/swift/TBDGen/TBDGen.h
+++ b/include/swift/TBDGen/TBDGen.h
@@ -23,13 +23,23 @@
 class FileUnit;
 class ModuleDecl;
 
-void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,
-                            bool hasMultipleIGMs);
-void enumeratePublicSymbols(ModuleDecl *module, llvm::StringSet<> &symbols,
-                            bool hasMultipleIGMs);
+/// \brief Options for controlling the exact set of symbols included in the TBD
+/// output.
+struct TBDGenOptions {
+  /// \brief Whether this compilation has multiple IRGen instances.
+  bool HasMultipleIGMs;
+  /// \brief The install-name used for the compilation.
+  llvm::StringRef InstallName;
+  /// \brief The module link name (for force loading).
+  llvm::StringRef ModuleLinkName;
+};
 
-void writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os, bool hasMultipleIGMs,
-                  llvm::StringRef installName);
+void enumeratePublicSymbols(FileUnit *module, llvm::StringSet<> &symbols,
+                            TBDGenOptions &opts);
+void enumeratePublicSymbols(ModuleDecl *module, llvm::StringSet<> &symbols,
+                            TBDGenOptions &opts);
+
+void writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os, TBDGenOptions &opts);
 
 } // end namespace swift
 
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 6a1ac4c..387f2aa 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2837,8 +2837,8 @@
                    true,
                    classDecl->getFullName(),
                    protocolName);
-    Diags.diagnose(req, diag::protocol_requirement_here,
-                   reqDiagInfo.second);
+    Diags.diagnose(req, diag::kind_declname_declared_here,
+                   DescriptiveDeclKind::Requirement, reqDiagInfo.second);
 
     anyDiagnosed = true;
   }
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 2bddd96..3d01c3e 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -425,7 +425,7 @@
 
     void printRec(Decl *D) { D->dump(OS, Indent + 2); }
     void printRec(Expr *E) { E->print(OS, Indent + 2); }
-    void printRec(Stmt *S) { S->print(OS, Indent + 2); }
+    void printRec(Stmt *S, const ASTContext &Ctx) { S->print(OS, &Ctx, Indent + 2); }
     void printRec(TypeRepr *T);
     void printRec(const Pattern *P) {
       PrintPattern(OS, Indent+2).visit(const_cast<Pattern *>(P));
@@ -553,7 +553,7 @@
     
     void printRec(Decl *D) { PrintDecl(OS, Indent + 2).visit(D); }
     void printRec(Expr *E) { E->print(OS, Indent+2); }
-    void printRec(Stmt *S) { S->print(OS, Indent+2); }
+    void printRec(Stmt *S, const ASTContext &Ctx) { S->print(OS, &Ctx, Indent+2); }
     void printRec(Pattern *P) { PrintPattern(OS, Indent+2).visit(P); }
     void printRec(TypeRepr *T);
 
@@ -575,6 +575,13 @@
       if (D->isImplicit())
         PrintWithColorRAII(OS, DeclModifierColor) << " implicit";
 
+      auto R = D->getSourceRange();
+      if (R.isValid()) {
+        PrintWithColorRAII(OS, RangeColor) << " range=";
+        R.print(PrintWithColorRAII(OS, RangeColor).getOS(),
+                D->getASTContext().SourceMgr, /*PrintText=*/false);
+      }
+
       if (D->TrailingSemiLoc.isValid())
         PrintWithColorRAII(OS, DeclModifierColor) << " trailing_semi";
     }
@@ -984,7 +991,7 @@
       PrintWithColorRAII(OS, ParenthesisColor) << ')';
     }
 
-    void printParameterList(const ParameterList *params) {
+    void printParameterList(const ParameterList *params, const ASTContext *ctx = nullptr) {
       OS.indent(Indent);
       PrintWithColorRAII(OS, ParenthesisColor) << '(';
       PrintWithColorRAII(OS, ParameterColor) << "parameter_list";
@@ -993,6 +1000,19 @@
         OS << '\n';
         printParameter(P);
       }
+
+      if (!ctx && params->size() != 0 && params->get(0))
+        ctx = &params->get(0)->getASTContext();
+
+      if (ctx) {
+        auto R = params->getSourceRange();
+        if (R.isValid()) {
+          PrintWithColorRAII(OS, RangeColor) << " range=";
+          R.print(PrintWithColorRAII(OS, RangeColor).getOS(),
+                  ctx->SourceMgr, /*PrintText=*/false);
+        }
+      }
+
       PrintWithColorRAII(OS, ParenthesisColor) << ')';
       Indent -= 2;
     }
@@ -1001,7 +1021,7 @@
       for (auto pl : D->getParameterLists()) {
         OS << '\n';
         Indent += 2;
-        printParameterList(pl);
+        printParameterList(pl, &D->getASTContext());
         Indent -= 2;
      }
       if (auto FD = dyn_cast<FuncDecl>(D)) {
@@ -1018,7 +1038,7 @@
       }
       if (auto Body = D->getBody(/*canSynthesize=*/false)) {
         OS << '\n';
-        printRec(Body);
+        printRec(Body, D->getASTContext());
       }
     }
 
@@ -1065,12 +1085,12 @@
       printCommon(TLCD, "top_level_code_decl");
       if (TLCD->getBody()) {
         OS << "\n";
-        printRec(TLCD->getBody());
+        printRec(TLCD->getBody(), static_cast<Decl *>(TLCD)->getASTContext());
       }
       PrintWithColorRAII(OS, ParenthesisColor) << ')';
     }
     
-    void printASTNodes(const ArrayRef<ASTNode> &Elements, StringRef Name) {
+    void printASTNodes(const ArrayRef<ASTNode> &Elements, const ASTContext &Ctx, StringRef Name) {
       OS.indent(Indent);
       PrintWithColorRAII(OS, ParenthesisColor) << "(";
       PrintWithColorRAII(OS, ASTNodeColor) << Name;
@@ -1079,7 +1099,7 @@
         if (auto *SubExpr = Elt.dyn_cast<Expr*>())
           printRec(SubExpr);
         else if (auto *SubStmt = Elt.dyn_cast<Stmt*>())
-          printRec(SubStmt);
+          printRec(SubStmt, Ctx);
         else
           printRec(Elt.get<Decl*>());
       }
@@ -1102,7 +1122,7 @@
 
         OS << '\n';
         Indent += 2;
-        printASTNodes(Clause.Elements, "elements");
+        printASTNodes(Clause.Elements, ICD->getASTContext(), "elements");
         Indent -= 2;
       }
 
@@ -1349,9 +1369,11 @@
 class PrintStmt : public StmtVisitor<PrintStmt> {
 public:
   raw_ostream &OS;
+  const ASTContext *Ctx;
   unsigned Indent;
 
-  PrintStmt(raw_ostream &os, unsigned indent) : OS(os), Indent(indent) {
+  PrintStmt(raw_ostream &os, const ASTContext *ctx, unsigned indent)
+    : OS(os), Ctx(ctx), Indent(indent) {
   }
 
   void printRec(Stmt *S) {
@@ -1418,6 +1440,15 @@
     if (S->isImplicit())
       OS << " implicit";
 
+    if (Ctx) {
+      auto R = S->getSourceRange();
+      if (R.isValid()) {
+        PrintWithColorRAII(OS, RangeColor) << " range=";
+        R.print(PrintWithColorRAII(OS, RangeColor).getOS(),
+                Ctx->SourceMgr, /*PrintText=*/false);
+      }
+    }
+
     if (S->TrailingSemiLoc.isValid())
       OS << " trailing_semi";
 
@@ -1425,13 +1456,12 @@
   }
 
   void visitBraceStmt(BraceStmt *S) {
-    printASTNodes(S->getElements(), "brace_stmt");
+    printCommon(S, "brace_stmt");
+    printASTNodes(S->getElements());
+    PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
 
-  void printASTNodes(const ArrayRef<ASTNode> &Elements, StringRef Name) {
-    OS.indent(Indent);
-    PrintWithColorRAII(OS, ParenthesisColor) << "(";
-    PrintWithColorRAII(OS, ASTNodeColor) << Name;
+  void printASTNodes(const ArrayRef<ASTNode> &Elements) {
     for (auto Elt : Elements) {
       OS << '\n';
       if (auto *SubExpr = Elt.dyn_cast<Expr*>())
@@ -1441,7 +1471,6 @@
       else
         printRec(Elt.get<Decl*>());
     }
-    PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
 
   void visitReturnStmt(ReturnStmt *S) {
@@ -1625,8 +1654,8 @@
   llvm::errs() << '\n';
 }
 
-void Stmt::print(raw_ostream &OS, unsigned Indent) const {
-  PrintStmt(OS, Indent).visit(const_cast<Stmt*>(this));
+void Stmt::print(raw_ostream &OS, const ASTContext *Ctx, unsigned Indent) const {
+  PrintStmt(OS, Ctx, Indent).visit(const_cast<Stmt*>(this));
 }
 
 //===----------------------------------------------------------------------===//
@@ -1662,6 +1691,7 @@
     Indent += 2;
     OS.indent(Indent);
     PrintWithColorRAII(OS, ParenthesisColor) << '(';
+    PrintWithColorRAII(OS, ExprColor) << label;
     OS << '\n';
     printRec(E);
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
@@ -1671,7 +1701,7 @@
   /// FIXME: This should use ExprWalker to print children.
 
   void printRec(Decl *D) { D->dump(OS, Indent + 2); }
-  void printRec(Stmt *S) { S->print(OS, Indent + 2); }
+  void printRec(Stmt *S, const ASTContext &Ctx) { S->print(OS, &Ctx, Indent + 2); }
   void printRec(const Pattern *P) {
     PrintPattern(OS, Indent+2).visit(const_cast<Pattern *>(P));
   }
@@ -1720,6 +1750,15 @@
 
     return OS;
   }
+  
+  void printSemanticExpr(Expr * semanticExpr) {
+    if (semanticExpr == nullptr) {
+      return;
+    }
+    
+    OS << '\n';
+    printRecLabeled(semanticExpr, "semantic_expr");
+  }
 
   void visitErrorExpr(ErrorExpr *E) {
     printCommon(E, "error_expr");
@@ -1780,6 +1819,7 @@
       OS << '\n';
       printRec(Segment);
     }
+    printSemanticExpr(E->getSemanticExpr());
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E) {
@@ -1803,6 +1843,8 @@
     printArgumentLabels(E->getArgumentLabels());
     OS << "\n";
     printRec(E->getArg());
+    printSemanticExpr(E->getSemanticExpr());
+    PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
 
   void visitDiscardAssignmentExpr(DiscardAssignmentExpr *E) {
@@ -1954,20 +1996,16 @@
       OS << '\n';
       printRec(elt);
     }
+    printSemanticExpr(E->getSemanticExpr());
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitDictionaryExpr(DictionaryExpr *E) {
     printCommon(E, "dictionary_expr");
-    if (auto semaE = E->getSemanticExpr()) {
-      OS << '\n';
-      printRec(semaE);
-      PrintWithColorRAII(OS, ParenthesisColor) << ')';
-      return;
-    }
     for (auto elt : E->getElements()) {
       OS << '\n';
       printRec(elt);
     }
+    printSemanticExpr(E->getSemanticExpr());
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitSubscriptExpr(SubscriptExpr *E) {
@@ -2274,14 +2312,14 @@
 
     if (E->getParameters()) {
       OS << '\n';
-      PrintDecl(OS, Indent+2).printParameterList(E->getParameters());
+      PrintDecl(OS, Indent+2).printParameterList(E->getParameters(), &E->getASTContext());
     }
 
     OS << '\n';
     if (E->hasSingleExpressionBody()) {
       printRec(E->getSingleExpressionBody());
     } else {
-      printRec(E->getBody());
+      printRec(E->getBody(), E->getASTContext());
     }
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
@@ -2290,7 +2328,7 @@
 
     if (E->getParameters()) {
       OS << '\n';
-      PrintDecl(OS, Indent+2).printParameterList(E->getParameters());
+      PrintDecl(OS, Indent+2).printParameterList(E->getParameters(), &E->getASTContext());
     }
 
     OS << '\n';
@@ -2467,6 +2505,7 @@
       OS << '\n';
       printRec(ExpTyR);
     }
+    printSemanticExpr(E->getSemanticExpr());
     PrintWithColorRAII(OS, ParenthesisColor) << ')';
   }
   void visitObjCSelectorExpr(ObjCSelectorExpr *E) {
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index c324cd6..70041fa 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -252,6 +252,7 @@
   ENTRY(TypeAlias, "type alias");
   ENTRY(GenericTypeParam, "generic parameter");
   ENTRY(AssociatedType, "associated type");
+  ENTRY(Type, "type");
   ENTRY(Enum, "enum");
   ENTRY(Struct, "struct");
   ENTRY(Class, "class");
@@ -259,6 +260,7 @@
   ENTRY(GenericEnum, "generic enum");
   ENTRY(GenericStruct, "generic struct");
   ENTRY(GenericClass, "generic class");
+  ENTRY(GenericType, "generic type");
   ENTRY(Subscript, "subscript");
   ENTRY(Constructor, "initializer");
   ENTRY(Destructor, "deinitializer");
@@ -278,6 +280,7 @@
   ENTRY(EnumElement, "enum element");
   ENTRY(Module, "module");
   ENTRY(MissingMember, "missing member placeholder");
+  ENTRY(Requirement, "requirement");
   }
 #undef ENTRY
   llvm_unreachable("bad DescriptiveDeclKind");
@@ -4551,7 +4554,7 @@
 }
 
 void DefaultArgumentInitializer::changeFunction(
-    DeclContext *parent, MutableArrayRef<ParameterList *> paramLists) {
+    DeclContext *parent, ArrayRef<ParameterList *> paramLists) {
   if (parent->isLocalContext()) {
     setParent(parent);
   }
@@ -5465,21 +5468,6 @@
                                DiagnosticEngine *diags)
         : Decl(decl), Diags(diags) { }
 
-    bool isSelfExpr(Expr *E) {
-      E = E->getSemanticsProvidingExpr();
-
-      if (auto ATSE = dyn_cast<ArchetypeToSuperExpr>(E))
-        E = ATSE->getSubExpr();
-      if (auto IOE = dyn_cast<InOutExpr>(E))
-        E = IOE->getSubExpr();
-      if (auto LE = dyn_cast<LoadExpr>(E))
-        E = LE->getSubExpr();
-      if (auto DRE = dyn_cast<DeclRefExpr>(E))
-        return DRE->getDecl() == Decl->getImplicitSelfDecl();
-
-      return false;
-    }
-
     bool walkToDeclPre(class Decl *D) override {
       // Don't walk into further nominal decls.
       return !isa<NominalTypeDecl>(D);
@@ -5517,7 +5505,7 @@
       BodyInitKind myKind;
       if (arg->isSuperExpr())
         myKind = BodyInitKind::Chained;
-      else if (isSelfExpr(arg))
+      else if (arg->isSelfExprOf(Decl, /*sameBase*/true))
         myKind = BodyInitKind::Delegating;
       else {
         // We're constructing something else.
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 10a2a73..f9f60dd 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2174,6 +2174,23 @@
   return Res;
 }
 
+bool Expr::isSelfExprOf(const AbstractFunctionDecl *AFD, bool sameBase) const {
+  auto *E = getSemanticsProvidingExpr();
+
+  if (auto IOE = dyn_cast<InOutExpr>(E))
+    E = IOE->getSubExpr();
+
+  while (auto ICE = dyn_cast<ImplicitConversionExpr>(E)) {
+    if (sameBase && isa<DerivedToBaseExpr>(ICE))
+      return false;
+    E = ICE->getSubExpr();
+  }
+
+  if (auto DRE = dyn_cast<DeclRefExpr>(E))
+    return DRE->getDecl() == AFD->getImplicitSelfDecl();
+
+  return false;
+}
 
 ArchetypeType *OpenExistentialExpr::getOpenedArchetype() const {
   auto type = getOpaqueValue()->getType()->getRValueType();
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 9334571..d1146f3 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -6988,17 +6988,24 @@
 void GenericSignatureBuilder::checkConcreteTypeConstraints(
                               TypeArrayView<GenericTypeParamType> genericParams,
                               EquivalenceClass *equivClass) {
+  // Resolve any thus-far-unresolved dependent types.
+  Type resolvedConcreteType =
+    resolveDependentMemberTypes(*this, equivClass->concreteType);
+
   checkConstraintList<Type>(
     genericParams, equivClass->concreteTypeConstraints,
     [&](const ConcreteConstraint &constraint) {
-      return constraint.value->isEqual(equivClass->concreteType);
+      if (constraint.value->isEqual(resolvedConcreteType))
+        return true;
+
+      auto resolvedType =
+        resolveDependentMemberTypes(*this, constraint.value);
+      return resolvedType->isEqual(resolvedConcreteType);
     },
     [&](const Constraint<Type> &constraint) {
       Type concreteType = constraint.value;
 
       // If the concrete type is equivalent, the constraint is redundant.
-      // FIXME: Should check this constraint after substituting in the
-      // archetype anchors for each dependent type.
       if (concreteType->isEqual(equivClass->concreteType))
         return ConstraintRelation::Redundant;
 
@@ -7013,9 +7020,7 @@
     diag::redundant_same_type_to_concrete,
     diag::same_type_redundancy_here);
 
-  // Resolve any thus-far-unresolved dependent types.
-  equivClass->concreteType =
-    resolveDependentMemberTypes(*this, equivClass->concreteType);
+  equivClass->concreteType = resolvedConcreteType;
 }
 
 void GenericSignatureBuilder::checkSuperclassConstraints(
@@ -7023,23 +7028,20 @@
                               EquivalenceClass *equivClass) {
   assert(equivClass->superclass && "No superclass constraint?");
 
-  // FIXME: We should be substituting in the canonical type in context so
-  // we can resolve superclass requirements, e.g., if you had:
-  //
-  //   class Foo<T>
-  //   class Bar: Foo<Int>
-  //
-  //   func foo<T, U where U: Bar, U: Foo<T>>(...) { ... }
-  //
-  // then the second `U: Foo<T>` constraint introduces a `T == Int`
-  // constraint, and we will need to perform that substitution for this final
-  // check.
+  // Resolve any this-far-unresolved dependent types.
+  Type resolvedSuperclass =
+    resolveDependentMemberTypes(*this, equivClass->superclass);
 
   auto representativeConstraint =
     checkConstraintList<Type>(
       genericParams, equivClass->superclassConstraints,
       [&](const ConcreteConstraint &constraint) {
-        return constraint.value->isEqual(equivClass->superclass);
+        if (constraint.value->isEqual(resolvedSuperclass))
+          return true;
+
+        Type resolvedType =
+          resolveDependentMemberTypes(*this, constraint.value);
+        return resolvedType->isEqual(equivClass->superclass);
       },
       [&](const Constraint<Type> &constraint) {
         Type superclass = constraint.value;
@@ -7056,15 +7058,16 @@
       diag::superclass_redundancy_here);
 
   // Resolve any this-far-unresolved dependent types.
-  equivClass->superclass =
-    resolveDependentMemberTypes(*this, equivClass->superclass);
+  equivClass->superclass = resolvedSuperclass;
 
   // If we have a concrete type, check it.
   // FIXME: Substitute into the concrete type.
   if (equivClass->concreteType) {
+    Type resolvedConcreteType =
+      resolveDependentMemberTypes(*this, equivClass->concreteType);
     auto existing = equivClass->findAnyConcreteConstraintAsWritten();
     // Make sure the concrete type fulfills the superclass requirement.
-    if (!equivClass->superclass->isExactSuperclassOf(equivClass->concreteType)){
+    if (!equivClass->superclass->isExactSuperclassOf(resolvedConcreteType)){
       Impl->HadAnyError = true;
       if (existing) {
         Diags.diagnose(existing->source->getLoc(), diag::type_does_not_inherit,
@@ -7084,7 +7087,7 @@
                        diag::type_does_not_inherit,
                        representativeConstraint.getSubjectDependentType(
                                                               genericParams),
-                       equivClass->concreteType, equivClass->superclass);
+                       resolvedConcreteType, equivClass->superclass);
       }
     } else if (representativeConstraint.source->shouldDiagnoseRedundancy(true)
                && existing &&
diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp
index ddf5a00..cdb536c 100644
--- a/lib/AST/SubstitutionMap.cpp
+++ b/lib/AST/SubstitutionMap.cpp
@@ -275,6 +275,11 @@
 
     // Substitute into the replacement type.
     replacementType = concreteType.subst(*this);
+
+    // If the generic signature is canonical, canonicalize the replacement type.
+    if (getGenericSignature()->isCanonical())
+      replacementType = replacementType->getCanonicalType();
+
     return replacementType;
   }
 
@@ -290,6 +295,11 @@
   replacementType = ErrorType::get(type);
 
   replacementType = lookupSubstitution(cast<SubstitutableType>(canonicalType));
+
+  // If the generic signature is canonical, canonicalize the replacement type.
+  if (getGenericSignature()->isCanonical())
+    replacementType = replacementType->getCanonicalType();
+
   return replacementType;
 }
 
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index f2391a5..308b536 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2768,14 +2768,6 @@
   return FunctionType::get(input, result, getExtInfo());
 }
 
-FunctionType *
-GenericFunctionType::substGenericArgs(TypeSubstitutionFn subs,
-                                      LookupConformanceFn conformances) {
-  Type input = getInput().subst(subs, conformances);
-  Type result = getResult().subst(subs, conformances);
-  return FunctionType::get(input, result, getExtInfo());
-}
-
 static Type getMemberForBaseType(LookupConformanceFn lookupConformances,
                                  Type origBase,
                                  Type substBase,
diff --git a/lib/ClangImporter/ClangDiagnosticConsumer.cpp b/lib/ClangImporter/ClangDiagnosticConsumer.cpp
index e5f088f..bff677a 100644
--- a/lib/ClangImporter/ClangDiagnosticConsumer.cpp
+++ b/lib/ClangImporter/ClangDiagnosticConsumer.cpp
@@ -66,8 +66,18 @@
                                StringRef Message,
                                ArrayRef<clang::CharSourceRange> Ranges,
                                clang::DiagOrStoredDiag Info) override {
-      if (shouldSuppressDiagInSwiftBuffers(Info) && isInSwiftBuffers(Loc))
-        return;
+      if (isInSwiftBuffers(Loc)) {
+        // FIXME: Ideally, we'd report non-suppressed diagnostics on synthetic
+        // buffers, printing their names (eg. <swift-imported-modules>:...) but
+        // this risks printing _excerpts_ of those buffers to stderr too; at
+        // present the synthetic buffers are "large blocks of null bytes" which
+        // we definitely don't want to print out. So until we have some clever
+        // way to print the name but suppress printing excerpts, we just replace
+        // the Loc with an invalid one here, which suppresses both.
+        Loc = clang::FullSourceLoc();
+        if (shouldSuppressDiagInSwiftBuffers(Info))
+          return;
+      }
       callback(Loc, Level, Message);
     }
 
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 3fe2c0f..66cfd26 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -244,6 +244,10 @@
   validateDebugInfoArgs(diags, args);
   validateCompilationConditionArgs(diags, args);
   validateAutolinkingArgs(diags, args);
+
+  if (args.hasArg(options::OPT_emit_public_type_metadata_accessors))
+    diags.diagnose(SourceLoc(),
+                   diag::warn_emit_public_type_metadata_accessors_deprecated);
 }
 
 std::unique_ptr<ToolChain>
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 5caeb5e..d7adb87 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -183,8 +183,6 @@
                        options::OPT_warn_swift3_objc_inference_minimal,
                        options::OPT_warn_swift3_objc_inference_complete);
   inputArgs.AddLastArg(arguments, options::OPT_typo_correction_limit);
-  inputArgs.AddLastArg(arguments,
-                       options::OPT_emit_public_type_metadata_accessors);
   inputArgs.AddLastArg(arguments, options::OPT_enable_app_extension);
   inputArgs.AddLastArg(arguments, options::OPT_enable_testing);
   inputArgs.AddLastArg(arguments, options::OPT_g_Group);
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index fc1bad9..333a091 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -309,9 +309,6 @@
     }
   }
 
-  Opts.EmitPublicTypeMetadataAccessors =
-    Args.hasArg(OPT_emit_public_type_metadata_accessors);
-
   Opts.EnableNSKeyedArchiverDiagnostics =
       Args.hasFlag(OPT_enable_nskeyedarchiver_diagnostics,
                    OPT_disable_nskeyedarchiver_diagnostics,
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index e6904d6..20603e0 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -61,6 +61,7 @@
 #include "swift/SILOptimizer/PassManager/Passes.h"
 #include "swift/Syntax/Serialization/SyntaxSerialization.h"
 #include "swift/Syntax/SyntaxNodes.h"
+#include "swift/TBDGen/TBDGen.h"
 
 // FIXME: We're just using CompilerInstance::createOutputFile.
 // This API should be sunk down to LLVM.
@@ -764,20 +765,24 @@
 
 static bool writeTBDIfNeeded(CompilerInvocation &Invocation,
                              CompilerInstance &Instance) {
-  if (!Invocation.getFrontendOptions().InputsAndOutputs.hasTBDPath())
+  const auto &frontendOpts = Invocation.getFrontendOptions();
+  if (!frontendOpts.InputsAndOutputs.hasTBDPath())
     return false;
 
   const std::string &TBDPath = Invocation.getTBDPathForWholeModule();
   assert(!TBDPath.empty() &&
          "If not WMO, getTBDPathForWholeModule should have failed");
 
-  auto installName = Invocation.getFrontendOptions().TBDInstallName.empty()
+  auto installName = frontendOpts.TBDInstallName.empty()
                          ? "lib" + Invocation.getModuleName().str() + ".dylib"
-                         : Invocation.getFrontendOptions().TBDInstallName;
+                         : frontendOpts.TBDInstallName;
 
-  return writeTBD(Instance.getMainModule(),
-                  Invocation.getSILOptions().hasMultipleIGMs(), TBDPath,
-                  installName);
+  TBDGenOptions opts;
+  opts.InstallName = installName;
+  opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
+  opts.ModuleLinkName = frontendOpts.ModuleLinkName;
+
+  return writeTBD(Instance.getMainModule(), TBDPath, opts);
 }
 
 static std::deque<PostSILGenInputs>
@@ -1138,7 +1143,8 @@
       !inputFileKindCanHaveTBDValidated(Invocation.getInputKind()))
     return false;
 
-  const auto mode = Invocation.getFrontendOptions().ValidateTBDAgainstIR;
+  const auto &frontendOpts = Invocation.getFrontendOptions();
+  const auto mode = frontendOpts.ValidateTBDAgainstIR;
   // Ensure all cases are covered by using a switch here.
   switch (mode) {
   case FrontendOptions::TBDValidationMode::None:
@@ -1147,12 +1153,14 @@
   case FrontendOptions::TBDValidationMode::MissingFromTBD:
     break;
   }
-  const auto hasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
+  TBDGenOptions opts;
+  opts.HasMultipleIGMs = Invocation.getSILOptions().hasMultipleIGMs();
+  opts.ModuleLinkName = frontendOpts.ModuleLinkName;
+
   const bool allSymbols = mode == FrontendOptions::TBDValidationMode::All;
-  return MSF.is<SourceFile *>() ? validateTBD(MSF.get<SourceFile *>(), IRModule,
-                                              hasMultipleIGMs, allSymbols)
-                                : validateTBD(MSF.get<ModuleDecl *>(), IRModule,
-                                              hasMultipleIGMs, allSymbols);
+  return MSF.is<SourceFile *>()
+             ? validateTBD(MSF.get<SourceFile *>(), IRModule, opts, allSymbols)
+             : validateTBD(MSF.get<ModuleDecl *>(), IRModule, opts, allSymbols);
 }
 
 static bool generateCode(CompilerInvocation &Invocation,
diff --git a/lib/FrontendTool/TBD.cpp b/lib/FrontendTool/TBD.cpp
index 2c93389..0a634be 100644
--- a/lib/FrontendTool/TBD.cpp
+++ b/lib/FrontendTool/TBD.cpp
@@ -38,8 +38,8 @@
   return sorted;
 }
 
-bool swift::writeTBD(ModuleDecl *M, bool hasMultipleIGMs,
-                     StringRef OutputFilename, StringRef installName) {
+bool swift::writeTBD(ModuleDecl *M, StringRef OutputFilename,
+                     TBDGenOptions &Opts) {
   std::error_code EC;
   llvm::raw_fd_ostream OS(OutputFilename, EC, llvm::sys::fs::F_None);
   if (EC) {
@@ -48,7 +48,7 @@
     return true;
   }
 
-  writeTBDFile(M, OS, hasMultipleIGMs, installName);
+  writeTBDFile(M, OS, Opts);
 
   return false;
 }
@@ -117,18 +117,18 @@
 }
 
 bool swift::validateTBD(ModuleDecl *M, llvm::Module &IRModule,
-                        bool hasMultipleIGMs, bool diagnoseExtraSymbolsInTBD) {
+                        TBDGenOptions &opts, bool diagnoseExtraSymbolsInTBD) {
   llvm::StringSet<> symbols;
-  enumeratePublicSymbols(M, symbols, hasMultipleIGMs);
+  enumeratePublicSymbols(M, symbols, opts);
 
   return validateSymbolSet(M->getASTContext().Diags, symbols, IRModule,
                            diagnoseExtraSymbolsInTBD);
 }
 
 bool swift::validateTBD(FileUnit *file, llvm::Module &IRModule,
-                        bool hasMultipleIGMs, bool diagnoseExtraSymbolsInTBD) {
+                        TBDGenOptions &opts, bool diagnoseExtraSymbolsInTBD) {
   llvm::StringSet<> symbols;
-  enumeratePublicSymbols(file, symbols, hasMultipleIGMs);
+  enumeratePublicSymbols(file, symbols, opts);
 
   return validateSymbolSet(file->getParentModule()->getASTContext().Diags,
                            symbols, IRModule, diagnoseExtraSymbolsInTBD);
diff --git a/lib/FrontendTool/TBD.h b/lib/FrontendTool/TBD.h
index bda0922..c6e8610 100644
--- a/lib/FrontendTool/TBD.h
+++ b/lib/FrontendTool/TBD.h
@@ -23,13 +23,13 @@
 class ModuleDecl;
 class FileUnit;
 class FrontendOptions;
+struct TBDGenOptions;
 
-bool writeTBD(ModuleDecl *M, bool hasMultipleIGMs, StringRef OutputFilename,
-              llvm::StringRef installName);
+bool writeTBD(ModuleDecl *M, StringRef OutputFilename, TBDGenOptions &Opts);
 bool inputFileKindCanHaveTBDValidated(InputFileKind kind);
-bool validateTBD(ModuleDecl *M, llvm::Module &IRModule, bool hasMultipleIGMs,
+bool validateTBD(ModuleDecl *M, llvm::Module &IRModule, TBDGenOptions &opts,
                  bool diagnoseExtraSymbolsInTBD);
-bool validateTBD(FileUnit *M, llvm::Module &IRModule, bool hasMultipleIGMs,
+bool validateTBD(FileUnit *M, llvm::Module &IRModule, TBDGenOptions &opts,
                  bool diagnoseExtraSymbolsInTBD);
 }
 
diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp
index 01dd514..1c8e110 100644
--- a/lib/IDE/CodeCompletion.cpp
+++ b/lib/IDE/CodeCompletion.cpp
@@ -1318,7 +1318,7 @@
     if (!DC)
       return;
     auto *CD = DC->getAsClassOrClassExtensionContext();
-    if (CD == nullptr)
+    if (!CD)
       return;
     Type ST = CD->getSuperclass();
     if (ST.isNull() || ST->is<ErrorType>())
@@ -2838,23 +2838,29 @@
   }
 
   void addKeyword(StringRef Name, Type TypeAnnotation,
-                  SemanticContextKind SK = SemanticContextKind::None) {
+                  SemanticContextKind SK = SemanticContextKind::None,
+                  CodeCompletionKeywordKind KeyKind
+                    = CodeCompletionKeywordKind::None) {
     CodeCompletionResultBuilder Builder(
         Sink,
         CodeCompletionResult::ResultKind::Keyword, SK, ExpectedTypes);
     addLeadingDot(Builder);
     Builder.addTextChunk(Name);
+    Builder.setKeywordKind(KeyKind);
     if (!TypeAnnotation.isNull())
       addTypeAnnotation(Builder, TypeAnnotation);
   }
 
-  void addKeyword(StringRef Name, StringRef TypeAnnotation) {
+  void addKeyword(StringRef Name, StringRef TypeAnnotation,
+                  CodeCompletionKeywordKind KeyKind
+                    = CodeCompletionKeywordKind::None) {
     CodeCompletionResultBuilder Builder(
         Sink,
         CodeCompletionResult::ResultKind::Keyword,
         SemanticContextKind::None, ExpectedTypes);
     addLeadingDot(Builder);
     Builder.addTextChunk(Name);
+    Builder.setKeywordKind(KeyKind);
     if (!TypeAnnotation.empty())
       Builder.addTypeAnnotation(TypeAnnotation);
   }
@@ -3259,14 +3265,13 @@
     ExprType = ExprType->getRValueType();
     this->ExprType = ExprType;
     if (ExprType->hasTypeParameter()) {
-      DeclContext *DC;
-      if (VD) {
+      DeclContext *DC = nullptr;
+      if (VD)
         DC = VD->getInnermostDeclContext();
-        this->ExprType = DC->mapTypeIntoContext(ExprType);
-      } else if (auto NTD = ExprType->getRValueInstanceType()->getAnyNominal()) {
+      else if (auto NTD = ExprType->getRValueInstanceType()->getAnyNominal())
         DC = NTD;
-        this->ExprType = DC->mapTypeIntoContext(ExprType);
-      }
+      if (DC)
+        ExprType = DC->mapTypeIntoContext(ExprType);
     }
 
     // Handle special cases
@@ -5316,6 +5321,11 @@
     if (isDynamicLookup(*ExprType))
       Lookup.setIsDynamicLookup();
 
+    if (!ExprType.getValue()->getAs<ModuleType>())
+      Lookup.addKeyword("self", (*ExprType)->getRValueType(),
+                        SemanticContextKind::CurrentNominal,
+                        CodeCompletionKeywordKind::kw_self);
+
     if (isa<BindOptionalExpr>(ParsedExpr) || isa<ForceValueExpr>(ParsedExpr))
       Lookup.setIsUnwrappedOptional(true);
 
@@ -5364,6 +5374,11 @@
       Lookup.setIsDynamicLookup();
     Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
     Lookup.getOperatorCompletions(ParsedExpr, leadingSequenceExprs);
+
+    if (!ExprType.getValue()->getAs<ModuleType>())
+      Lookup.addKeyword("self", (*ExprType)->getRValueType(),
+                        SemanticContextKind::CurrentNominal,
+                        CodeCompletionKeywordKind::kw_self);
     break;
   }
 
diff --git a/lib/IDE/Refactoring.cpp b/lib/IDE/Refactoring.cpp
index 9d3974d..88a382e 100644
--- a/lib/IDE/Refactoring.cpp
+++ b/lib/IDE/Refactoring.cpp
@@ -908,6 +908,15 @@
     return ExtractCheckResult();
   }
 
+  // Disallow extracting certain kinds of statements.
+  if (RangeInfo.Kind == RangeKind::SingleStatement) {
+    Stmt *S = RangeInfo.ContainedNodes[0].get<Stmt *>();
+
+    // These aren't independent statement.
+    if (isa<BraceStmt>(S) || isa<CatchStmt>(S) || isa<CaseStmt>(S))
+      return ExtractCheckResult();
+  }
+
   // Disallow extracting literals.
   if (RangeInfo.Kind == RangeKind::SingleExpression) {
     Expr *E = RangeInfo.ContainedNodes[0].get<Expr*>();
@@ -1659,109 +1668,70 @@
   return false;
 }
 
-struct CollapsibleNestedIfInfo {
-  IfStmt *OuterIf;
-  IfStmt *InnerIf;
-  bool FinishedOuterIf;
-  bool FoundNonCollapsibleItem;
-  CollapsibleNestedIfInfo():
-    OuterIf(nullptr), InnerIf(nullptr),
-    FinishedOuterIf(false), FoundNonCollapsibleItem(false) {}
-  bool isValid() {
-    return OuterIf && InnerIf && FinishedOuterIf && !FoundNonCollapsibleItem;
-  }
-};
-
-static CollapsibleNestedIfInfo findCollapseNestedIfTarget(ResolvedCursorInfo CursorInfo) {
+static std::pair<IfStmt *, IfStmt *>
+findCollapseNestedIfTarget(ResolvedCursorInfo CursorInfo) {
   if (CursorInfo.Kind != CursorInfoKind::StmtStart)
-    return CollapsibleNestedIfInfo();
-  struct IfStmtFinder: public SourceEntityWalker {
-    SourceLoc StartLoc;
-    CollapsibleNestedIfInfo IfInfo;
-    IfStmtFinder(SourceLoc StartLoc): StartLoc(StartLoc), IfInfo() {}
-    bool finishedInnerIfButNotFinishedOuterIf() {
-      return IfInfo.InnerIf && !IfInfo.FinishedOuterIf;
-    }
-    bool walkToStmtPre(Stmt *S) {
-      if (finishedInnerIfButNotFinishedOuterIf()) {
-        IfInfo.FoundNonCollapsibleItem = true;
-        return false;
-      }
+    return {};
 
-      bool StmtIsOuterIfBrace =
-        IfInfo.OuterIf && !IfInfo.InnerIf && S->getKind() == StmtKind::Brace;
-      if (StmtIsOuterIfBrace) {
-        return true;
-      }
+  // Ensure the statement is 'if' statement. It must not have 'else' clause.
+  IfStmt *OuterIf = dyn_cast<IfStmt>(CursorInfo.TrailingStmt);
+  if (!OuterIf)
+    return {};
+  if (OuterIf->getElseStmt())
+    return {};
 
-      auto *IFS = dyn_cast<IfStmt>(S);
-      if (!IFS) {
-        return false;
-      }
-      if (!IfInfo.OuterIf) {
-        IfInfo.OuterIf = IFS;
-        return true;
-      } else {
-        IfInfo.InnerIf = IFS;
-        return false;
-      }
-    }
-    bool walkToStmtPost(Stmt *S) {
-      assert(S != IfInfo.InnerIf && "Should not traverse inner if statement");
-      if (S == IfInfo.OuterIf) {
-        IfInfo.FinishedOuterIf = true;
-      }
-      return true;
-    }
-    bool walkToDeclPre(Decl *D, CharSourceRange Range) {
-      if (finishedInnerIfButNotFinishedOuterIf()) {
-        IfInfo.FoundNonCollapsibleItem = true;
-        return false;
-      }
-      return true;
-    }
-    bool walkToExprPre(Expr *E) {
-      if (finishedInnerIfButNotFinishedOuterIf()) {
-        IfInfo.FoundNonCollapsibleItem = true;
-        return false;
-      }
-      return true;
-    }
+  // The body must contain a sole inner 'if' statement.
+  auto Body = dyn_cast_or_null<BraceStmt>(OuterIf->getThenStmt());
+  if (!Body || Body->getNumElements() != 1)
+    return {};
 
-  } Walker(CursorInfo.TrailingStmt->getStartLoc());
-  Walker.walk(CursorInfo.TrailingStmt);
-  return Walker.IfInfo;
+  IfStmt *InnerIf =
+      dyn_cast_or_null<IfStmt>(Body->getElement(0).dyn_cast<Stmt *>());
+  if (!InnerIf)
+    return {};
+
+  // Inner 'if' statement also cannot have 'else' clause.
+  if (InnerIf->getElseStmt())
+    return {};
+
+  return {OuterIf, InnerIf};
 }
 
-bool RefactoringActionCollapseNestedIfExpr::
-isApplicable(ResolvedCursorInfo Tok, DiagnosticEngine &Diag) {
-  return findCollapseNestedIfTarget(Tok).isValid();
+bool RefactoringActionCollapseNestedIfStmt::
+isApplicable(ResolvedCursorInfo CursorInfo, DiagnosticEngine &Diag) {
+  return findCollapseNestedIfTarget(CursorInfo).first;
 }
 
-bool RefactoringActionCollapseNestedIfExpr::performChange() {
+bool RefactoringActionCollapseNestedIfStmt::performChange() {
   auto Target = findCollapseNestedIfTarget(CursorInfo);
-  if (!Target.isValid())
+  if (!Target.first)
     return true;
-  auto OuterIfConds = Target.OuterIf->getCond().vec();
-  auto InnerIfConds = Target.InnerIf->getCond().vec();
+  auto OuterIf = Target.first;
+  auto InnerIf = Target.second;
 
-  EditorConsumerInsertStream OS(EditConsumer, SM,
-    Lexer::getCharSourceRangeFromSourceRange(
-    SM, Target.OuterIf->getSourceRange()));
+  EditorConsumerInsertStream OS(
+      EditConsumer, SM,
+      Lexer::getCharSourceRangeFromSourceRange(SM, OuterIf->getSourceRange()));
 
-  OS << tok::kw_if << " ";
-  for (auto CI = OuterIfConds.begin(); CI != OuterIfConds.end(); ++CI) {
-    OS << (CI != OuterIfConds.begin() ? ", " : "");
-    OS << Lexer::getCharSourceRangeFromSourceRange(
-      SM, CI->getSourceRange()).str();
+  OS << tok::kw_if << " "; 
+
+  // Emit conditions.
+  bool first = true;
+  for (auto &C : llvm::concat<StmtConditionElement>(OuterIf->getCond(),
+                                                    InnerIf->getCond())) {
+    if (first)
+      first = false;
+    else
+      OS << ", ";
+    OS << Lexer::getCharSourceRangeFromSourceRange(SM, C.getSourceRange())
+              .str();
   }
-  for (auto CI = InnerIfConds.begin(); CI != InnerIfConds.end(); ++CI) {
-    OS << ", " << Lexer::getCharSourceRangeFromSourceRange(
-      SM, CI->getSourceRange()).str();
-  }
-  auto ThenStatementText = Lexer::getCharSourceRangeFromSourceRange(
-    SM, Target.InnerIf->getThenStmt()->getSourceRange()).str();
-  OS << " " << ThenStatementText;
+
+  // Emit body.
+  OS << " ";
+  OS << Lexer::getCharSourceRangeFromSourceRange(
+            SM, InnerIf->getThenStmt()->getSourceRange())
+            .str();
   return false;
 }
 
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index 9176495..6f2520e 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -2751,10 +2751,10 @@
   StringRef sectionName;
   switch (TargetInfo.OutputObjectFormat) {
   case llvm::Triple::MachO:
-    sectionName = "__TEXT, __swift4_protos, regular, no_dead_strip";
+    sectionName = "__TEXT, __swift5_protos, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
-    sectionName = "swift4_protocols";
+    sectionName = "swift5_protocols";
     break;
   case llvm::Triple::COFF:
     sectionName = ".sw5prt$B";
@@ -2941,10 +2941,10 @@
   StringRef sectionName;
   switch (TargetInfo.OutputObjectFormat) {
   case llvm::Triple::MachO:
-    sectionName = "__TEXT, __swift4_proto, regular, no_dead_strip";
+    sectionName = "__TEXT, __swift5_proto, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
-    sectionName = "swift4_protocol_conformances";
+    sectionName = "swift5_protocol_conformances";
     break;
   case llvm::Triple::COFF:
     sectionName = ".sw5prtc$B";
@@ -2968,10 +2968,10 @@
   std::string sectionName;
   switch (TargetInfo.OutputObjectFormat) {
   case llvm::Triple::MachO:
-    sectionName = "__TEXT, __swift4_types, regular, no_dead_strip";
+    sectionName = "__TEXT, __swift5_types, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
-    sectionName = "swift4_type_metadata";
+    sectionName = "swift5_type_metadata";
     break;
   case llvm::Triple::COFF:
     sectionName = ".sw5tymd$B";
@@ -3035,13 +3035,13 @@
   std::string sectionName;
   switch (TargetInfo.OutputObjectFormat) {
   case llvm::Triple::MachO:
-    sectionName = "__TEXT, __swift4_fieldmd, regular, no_dead_strip";
+    sectionName = "__TEXT, __swift5_fieldmd, regular, no_dead_strip";
     break;
   case llvm::Triple::ELF:
-    sectionName = "swift4_fieldmd";
+    sectionName = "swift5_fieldmd";
     break;
   case llvm::Triple::COFF:
-    sectionName = ".swift4_fieldmd";
+    sectionName = ".swift5_fieldmd";
     break;
   default:
     llvm_unreachable("Don't know how to emit field records table for "
diff --git a/lib/IRGen/GenExistential.cpp b/lib/IRGen/GenExistential.cpp
index eadf01e..e7e5fb5 100644
--- a/lib/IRGen/GenExistential.cpp
+++ b/lib/IRGen/GenExistential.cpp
@@ -280,7 +280,7 @@
                             llvm::Type *ty, Size size, Alignment align)
     : super(protocols, ty, size,
             SpareBitVector::getConstant(size.getValueInBits(), false), align,
-            IsNotPOD, IsNotBitwiseTakable, IsFixedSize) {}
+            IsNotPOD, IsBitwiseTakable, IsFixedSize) {}
 
 public:
   OpaqueExistentialLayout getLayout() const {
@@ -343,16 +343,11 @@
   void initializeWithTake(IRGenFunction &IGF, Address dest, Address src,
                           SILType T, bool isOutlined) const override {
     if (isOutlined) {
-      llvm::Value *metadata = copyType(IGF, dest, src);
-
-      auto layout = getLayout();
-
-      // Project down to the buffers and ask the witnesses to do a
-      // take-initialize.
-      Address srcBuffer = layout.projectExistentialBuffer(IGF, src);
-      Address destBuffer = layout.projectExistentialBuffer(IGF, dest);
-      emitInitializeBufferWithTakeOfBufferCall(IGF, metadata, destBuffer,
-                                               srcBuffer);
+      // memcpy the existential container. This is safe because: either the
+      // value is stored inline and is therefore by convention bitwise takable
+      // or the value is stored in a reference counted heap buffer, in which
+      // case a memcpy of the reference is also correct.
+      IGF.emitMemCpy(dest, src, getLayout().getSize(IGF.IGM));
     } else {
       // Create an outlined function to avoid explosion
       OutliningMetadataCollector collector(IGF);
diff --git a/lib/IRGen/GenOpaque.cpp b/lib/IRGen/GenOpaque.cpp
index 536fa32..0c07429 100644
--- a/lib/IRGen/GenOpaque.cpp
+++ b/lib/IRGen/GenOpaque.cpp
@@ -66,9 +66,7 @@
   }
 
   // T *(*initializeBufferWithCopyOfBuffer)(B *dest, B *src, M *self);
-  // T *(*initializeBufferWithTakeOfBuffer)(B *dest, B *src, M *self);
-  case ValueWitness::InitializeBufferWithCopyOfBuffer:
-  case ValueWitness::InitializeBufferWithTakeOfBuffer: {
+  case ValueWitness::InitializeBufferWithCopyOfBuffer: {
     llvm::Type *bufPtrTy = IGM.getFixedBufferTy()->getPointerTo(0);
     llvm::Type *args[] = { bufPtrTy, bufPtrTy, IGM.TypeMetadataPtrTy };
     return llvm::FunctionType::get(IGM.OpaquePtrTy, args, /*isVarArg*/ false);
@@ -212,7 +210,6 @@
   // These have two arguments and they don't alias each other.
   case ValueWitness::AssignWithTake:
   case ValueWitness::InitializeBufferWithCopyOfBuffer:
-  case ValueWitness::InitializeBufferWithTakeOfBuffer:
   case ValueWitness::InitializeWithCopy:
   case ValueWitness::InitializeWithTake:
     return attrs.addAttribute(ctx, 1, llvm::Attribute::NoAlias)
@@ -259,8 +256,6 @@
     return "initializeWithCopy";
   case ValueWitness::InitializeWithTake:
     return "initializeWithTake";
-  case ValueWitness::InitializeBufferWithTakeOfBuffer:
-    return "initializeBufferWithTakeOfBuffer";
   case ValueWitness::Size:
     return "size";
   case ValueWitness::Flags:
@@ -417,31 +412,6 @@
   return call;
 }
 
-llvm::Value *
-irgen::emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
-                                                SILType T,
-                                                Address destBuffer,
-                                                Address srcBuffer) {
-  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
-  return emitInitializeBufferWithTakeOfBufferCall(IGF, metadata,
-                                                  destBuffer, srcBuffer);
-}
-
-/// Emit a call to do an 'initializeBufferWithTakeOfBuffer' operation.
-llvm::Value *
-irgen::emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
-                                                llvm::Value *metadata,
-                                                Address destBuffer,
-                                                Address srcBuffer) {
-  auto copyFn = emitLoadOfValueWitnessFunctionFromMetadata(IGF, metadata,
-                             ValueWitness::InitializeBufferWithTakeOfBuffer);
-  llvm::CallInst *call =
-    IGF.Builder.CreateCall(copyFn,
-      {destBuffer.getAddress(), srcBuffer.getAddress(), metadata});
-
-  return call;
-}
-
 /// Emit a dynamic alloca call to allocate enough memory to hold an object of
 /// type 'T' and an optional llvm.stackrestore point if 'isInEntryBlock' is
 /// false.
diff --git a/lib/IRGen/GenOpaque.h b/lib/IRGen/GenOpaque.h
index 0afcc4a..622bc59 100644
--- a/lib/IRGen/GenOpaque.h
+++ b/lib/IRGen/GenOpaque.h
@@ -58,18 +58,6 @@
                                                         Address destBuffer,
                                                         Address srcBuffer);
 
-  /// Emit a call to do an 'initializeBufferWithTakeOfBuffer' operation.
-  llvm::Value *emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
-                                                        llvm::Value *metadata,
-                                                        Address destBuffer,
-                                                        Address srcBuffer);
-
-  /// Emit a call to do an 'initializeBufferWithTakeOfBuffer' operation.
-  llvm::Value *emitInitializeBufferWithTakeOfBufferCall(IRGenFunction &IGF,
-                                                        SILType T,
-                                                        Address destBuffer,
-                                                        Address srcBuffer);
-
   /// Emit a call to do an 'initializeWithCopy' operation.
   void emitInitializeWithCopyCall(IRGenFunction &IGF,
                                   SILType T,
diff --git a/lib/IRGen/GenRecord.h b/lib/IRGen/GenRecord.h
index 90b9cfb..66b0e14 100644
--- a/lib/IRGen/GenRecord.h
+++ b/lib/IRGen/GenRecord.h
@@ -323,22 +323,6 @@
 public:
   using super::getStorageType;
 
-  Address initializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
-                                           Address destBuffer,
-                                           Address srcBuffer,
-                                           SILType type) const override {
-    if (auto field = getUniqueNonEmptyField()) {
-      auto &fieldTI = field->getTypeInfo();
-      Address fieldResult =
-        fieldTI.initializeBufferWithTakeOfBuffer(IGF, destBuffer, srcBuffer,
-                                                 field->getType(IGF.IGM, type));
-      return IGF.Builder.CreateElementBitCast(fieldResult, getStorageType());
-    } else {
-      return super::initializeBufferWithTakeOfBuffer(IGF, destBuffer,
-                                                     srcBuffer, type);
-    }
-  }
-
   Address initializeBufferWithCopyOfBuffer(IRGenFunction &IGF,
                                            Address destBuffer,
                                            Address srcBuffer,
diff --git a/lib/IRGen/GenReflection.cpp b/lib/IRGen/GenReflection.cpp
index d4167d6..876ddb0 100644
--- a/lib/IRGen/GenReflection.cpp
+++ b/lib/IRGen/GenReflection.cpp
@@ -247,7 +247,7 @@
 
     // Others, such as capture descriptors, do not have a name.
     } else {
-      var = B.finishAndCreateGlobal("\x01l__swift4_reflection_descriptor",
+      var = B.finishAndCreateGlobal("\x01l__swift5_reflection_descriptor",
                                     Alignment(4), /*isConstant*/ true,
                                     llvm::GlobalValue::PrivateLinkage);
     }
@@ -766,12 +766,12 @@
     OS << ".sw5" << FourCC << "$B";
     break;
   case llvm::Triple::ELF:
-    OS << "swift4_" << LongName;
+    OS << "swift5_" << LongName;
     break;
   case llvm::Triple::MachO:
     assert(LongName.size() <= 7 &&
            "Mach-O section name length must be <= 16 characters");
-    OS << "__TEXT,__swift4_" << LongName << ", regular, no_dead_strip";
+    OS << "__TEXT,__swift5_" << LongName << ", regular, no_dead_strip";
     break;
   case llvm::Triple::Wasm:
     llvm_unreachable("web assembly object format is not supported.");
diff --git a/lib/IRGen/GenValueWitness.cpp b/lib/IRGen/GenValueWitness.cpp
index d8f39d8..16c8fd8 100644
--- a/lib/IRGen/GenValueWitness.cpp
+++ b/lib/IRGen/GenValueWitness.cpp
@@ -56,7 +56,6 @@
   CASE(InitializeBufferWithCopyOfBuffer)
   CASE(InitializeWithCopy)
   CASE(InitializeWithTake)
-  CASE(InitializeBufferWithTakeOfBuffer)
   CASE(StoreExtraInhabitant)
   CASE(GetExtraInhabitantIndex)
   CASE(GetEnumTag)
@@ -331,47 +330,6 @@
   }
 }
 
-/// Emit an 'initializeBufferWithTakeOfBuffer' operation.
-/// Returns the address of the destination object.
-static Address
-emitDefaultInitializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
-                                            Address destBuffer,
-                                            Address srcBuffer,
-                                            SILType T,
-                                            const TypeInfo &type,
-                                            FixedPacking packing) {
-  switch (packing) {
-
-  case FixedPacking::Dynamic:
-    // Special-case dynamic packing in order to thread the jumps.
-    return emitForDynamicPacking(IGF,
-                                 &emitDefaultInitializeBufferWithTakeOfBuffer,
-                                 T, type, destBuffer, srcBuffer);
-
-  case FixedPacking::OffsetZero: {
-    // Both of these allocations/projections should be no-ops.
-    Address destObject =
-      emitDefaultAllocateBuffer(IGF, destBuffer, T, type, packing);
-    Address srcObject =
-      emitDefaultProjectBuffer(IGF, srcBuffer, T, type, packing);
-    type.initializeWithTake(IGF, destObject, srcObject, T, true);
-    return destObject;
-  }
-
-  case FixedPacking::Allocate: {
-    // Just copy the out-of-line storage pointers.
-    srcBuffer = IGF.Builder.CreateBitCast(
-        srcBuffer, IGF.IGM.RefCountedPtrTy->getPointerTo());
-    llvm::Value *addr = IGF.Builder.CreateLoad(srcBuffer);
-    destBuffer = IGF.Builder.CreateBitCast(
-        destBuffer, IGF.IGM.RefCountedPtrTy->getPointerTo());
-    IGF.Builder.CreateStore(addr, destBuffer);
-    return emitDefaultProjectBuffer(IGF, destBuffer, T, type, packing);
-  }
-  }
-  llvm_unreachable("bad fixed packing");
-}
-
 // Metaprogram some of the common boilerplate here:
 //   - the default implementation in TypeInfo
 //   - the value-witness emitter which tries to avoid some dynamic
@@ -392,8 +350,6 @@
 }
 DEFINE_BINARY_BUFFER_OP(initializeBufferWithCopyOfBuffer,
                         InitializeBufferWithCopyOfBuffer)
-DEFINE_BINARY_BUFFER_OP(initializeBufferWithTakeOfBuffer,
-                        InitializeBufferWithTakeOfBuffer)
 #undef DEFINE_BINARY_BUFFER_OP
 
 
@@ -532,19 +488,6 @@
     return;
   }
 
-  case ValueWitness::InitializeBufferWithTakeOfBuffer: {
-    Address dest = getArgAsBuffer(IGF, argv, "dest");
-    Address src = getArgAsBuffer(IGF, argv, "src");
-    getArgAsLocalSelfTypeMetadata(IGF, argv, abstractType);
-
-    Address result =
-      emitInitializeBufferWithTakeOfBuffer(IGF, dest, src, concreteType,
-                                           type, packing);
-    result = IGF.Builder.CreateBitCast(result, IGF.IGM.OpaquePtrTy);
-    IGF.Builder.CreateRet(result.getAddress());
-    return;
-  }
-
   case ValueWitness::InitializeWithCopy: {
     Address dest = getArgAs(IGF, argv, type, "dest");
     Address src = getArgAs(IGF, argv, type, "src");
@@ -805,38 +748,6 @@
   });
 }
 
-/// Return a function which takes two buffer arguments, copies
-/// a pointer from the second to the first, and returns the pointer.
-static llvm::Constant *
-getCopyOutOfLineBoxPointerFunction(IRGenModule &IGM,
-                                   const FixedTypeInfo &fixedTI) {
-  llvm::Type *argTys[] = { IGM.Int8PtrPtrTy, IGM.Int8PtrPtrTy,
-                           IGM.TypeMetadataPtrTy };
-  llvm::SmallString<40> name;
-  {
-    llvm::raw_svector_ostream nameStream(name);
-    nameStream << "__swift_copy_outline_existential_box_pointer";
-    nameStream << fixedTI.getFixedAlignment().getValue();
-  }
-  return IGM.getOrCreateHelperFunction(
-      name, IGM.Int8PtrTy, argTys, [&](IRGenFunction &IGF) {
-        auto it = IGF.CurFn->arg_begin();
-        Address dest(&*it++, IGM.getPointerAlignment());
-        Address src(&*it++, IGM.getPointerAlignment());
-        auto *ptr = IGF.Builder.CreateLoad(src);
-        IGF.Builder.CreateStore(ptr, dest);
-        auto *alignmentMask = fixedTI.getStaticAlignmentMask(IGM);
-        auto *heapHeaderSize = llvm::ConstantInt::get(
-            IGM.SizeTy, IGM.RefCountedStructSize.getValue());
-        auto *startOffset = IGF.Builder.CreateAnd(
-            IGF.Builder.CreateAdd(heapHeaderSize, alignmentMask),
-            IGF.Builder.CreateNot(alignmentMask));
-        auto *objectAddr =
-            IGF.emitByteOffsetGEP(ptr, startOffset, IGM.Int8Ty);
-        IGF.Builder.CreateRet(objectAddr);
-      });
-}
-
 /// Find a witness to the fact that a type is a value type.
 /// Always adds an i8*.
 static void addValueWitness(IRGenModule &IGM,
@@ -870,17 +781,6 @@
     }
     goto standard;
 
-  case ValueWitness::InitializeBufferWithTakeOfBuffer:
-    if (packing == FixedPacking::Allocate) {
-      return addFunction(getCopyOutOfLineBoxPointerFunction(
-          IGM, cast<FixedTypeInfo>(concreteTI)));
-    } else
-      if (packing == FixedPacking::OffsetZero &&
-               concreteTI.isBitwiseTakable(ResilienceExpansion::Maximal)) {
-      return addFunction(getMemCpyFunction(IGM, concreteTI));
-    }
-    goto standard;
-
   case ValueWitness::InitializeWithTake:
     if (concreteTI.isBitwiseTakable(ResilienceExpansion::Maximal)) {
       return addFunction(getMemCpyFunction(IGM, concreteTI));
@@ -927,13 +827,16 @@
     if (auto *fixedTI = dyn_cast<FixedTypeInfo>(&concreteTI)) {
       assert(packing == FixedPacking::OffsetZero ||
              packing == FixedPacking::Allocate);
+      bool isInline = packing == FixedPacking::OffsetZero;
+      bool isBitwiseTakable =
+          fixedTI->isBitwiseTakable(ResilienceExpansion::Maximal);
+      assert(isBitwiseTakable || !isInline);
       flags = flags.withAlignment(fixedTI->getFixedAlignment().getValue())
-                   .withPOD(fixedTI->isPOD(ResilienceExpansion::Maximal))
-                   .withInlineStorage(packing == FixedPacking::OffsetZero)
-                   .withExtraInhabitants(
+                  .withPOD(fixedTI->isPOD(ResilienceExpansion::Maximal))
+                  .withInlineStorage(isInline)
+                  .withExtraInhabitants(
                       fixedTI->getFixedExtraInhabitantCount(IGM) > 0)
-                   .withBitwiseTakable(
-                      fixedTI->isBitwiseTakable(ResilienceExpansion::Maximal));
+                  .withBitwiseTakable(isBitwiseTakable);
     } else {
       flags = flags.withIncomplete(true);
     }
@@ -1288,6 +1191,10 @@
   if (!fixedTI)
     return FixedPacking::Dynamic;
 
+  // By convention we only store bitwise takable values inline.
+  if (!fixedTI->isBitwiseTakable(ResilienceExpansion::Maximal))
+    return FixedPacking::Allocate;
+
   Size bufferSize = getFixedBufferSize(IGM);
   Size requiredSize = fixedTI->getFixedSize();
 
diff --git a/lib/IRGen/IRGenMangler.cpp b/lib/IRGen/IRGenMangler.cpp
index 40e7679..7c74e2b 100644
--- a/lib/IRGen/IRGenMangler.cpp
+++ b/lib/IRGen/IRGenMangler.cpp
@@ -45,7 +45,6 @@
     GET_MANGLING(AssignWithCopy) \
     GET_MANGLING(InitializeWithTake) \
     GET_MANGLING(AssignWithTake) \
-    GET_MANGLING(InitializeBufferWithTakeOfBuffer) \
     GET_MANGLING(GetEnumTagSinglePayload) \
     GET_MANGLING(StoreEnumTagSinglePayload) \
     GET_MANGLING(StoreExtraInhabitant) \
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index 61b36f5..3bc6000 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -793,8 +793,9 @@
   appendEncodedName(os, name);
 }
 
-static StringRef encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
-                                           StringRef name) {
+StringRef
+swift::irgen::encodeForceLoadSymbolName(llvm::SmallVectorImpl<char> &buf,
+                                        StringRef name) {
   llvm::raw_svector_ostream os{buf};
   os << "_swift_FORCE_LOAD_$";
   appendEncodedName(os, name);
diff --git a/lib/IRGen/MetadataRequest.cpp b/lib/IRGen/MetadataRequest.cpp
index 4fa1812..dd4410a 100644
--- a/lib/IRGen/MetadataRequest.cpp
+++ b/lib/IRGen/MetadataRequest.cpp
@@ -589,17 +589,6 @@
   return false;
 }
 
-/// Determine whether we should promote the type metadata access function
-/// for the given nominal type to "public".
-static bool promoteMetadataAccessFunctionToPublic(
-                                              const NominalTypeDecl *nominal) {
-  ASTContext &ctx = nominal->getASTContext();
-
-  // When -emit-public-type-metadata-accessors is provided, promote all
-  // of the metadata access functions to public.
-  return ctx.LangOpts.EmitPublicTypeMetadataAccessors;
-}
-
 /// Return the standard access strategy for getting a non-dependent
 /// type metadata object.
 MetadataAccessStrategy irgen::getTypeMetadataAccessStrategy(CanType type) {
@@ -632,12 +621,8 @@
     case FormalLinkage::PublicUnique:
       return MetadataAccessStrategy::PublicUniqueAccessor;
     case FormalLinkage::HiddenUnique:
-      if (promoteMetadataAccessFunctionToPublic(nominal))
-        return MetadataAccessStrategy::PublicUniqueAccessor;
       return MetadataAccessStrategy::HiddenUniqueAccessor;
     case FormalLinkage::Private:
-      if (promoteMetadataAccessFunctionToPublic(nominal))
-        return MetadataAccessStrategy::PublicUniqueAccessor;
       return MetadataAccessStrategy::PrivateAccessor;
 
     case FormalLinkage::PublicNonUnique:
diff --git a/lib/IRGen/ResilientTypeInfo.h b/lib/IRGen/ResilientTypeInfo.h
index 1672755..0e49503 100644
--- a/lib/IRGen/ResilientTypeInfo.h
+++ b/lib/IRGen/ResilientTypeInfo.h
@@ -88,13 +88,6 @@
     return this->getAddressForPointer(addr);
   }
 
-  Address initializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
-                                   Address dest, Address src,
-                                   SILType T) const override {
-    auto addr = emitInitializeBufferWithTakeOfBufferCall(IGF, T, dest, src);
-    return this->getAddressForPointer(addr);
-  }
-
   void initializeWithCopy(IRGenFunction &IGF, Address dest, Address src,
                           SILType T, bool isOutlined) const override {
     emitInitializeWithCopyCall(IGF, T, dest, src);
diff --git a/lib/IRGen/TypeInfo.h b/lib/IRGen/TypeInfo.h
index 1092b34..abf1b93 100644
--- a/lib/IRGen/TypeInfo.h
+++ b/lib/IRGen/TypeInfo.h
@@ -370,23 +370,6 @@
                                                    Address srcBuffer,
                                                    SILType T) const;
 
-  /// Perform a take-initialization from the given fixed-size buffer
-  /// into an uninitialized fixed-size buffer, allocating the buffer if
-  /// necessary and deallocating the destination buffer.  Returns the
-  /// address of the value inside the destination buffer.
-  ///
-  /// This is equivalent to:
-  ///   auto srcAddress = projectBuffer(IGF, srcBuffer, T);
-  ///   initializeBufferWithTake(IGF, destBuffer, srcAddress, T);
-  ///   deallocateBuffer(IGF, srcBuffer, T);
-  /// but may be able to re-use the buffer from the source buffer, and may
-  /// be more efficient for dynamic types, since it uses a single
-  /// value witness call.
-  virtual Address initializeBufferWithTakeOfBuffer(IRGenFunction &IGF,
-                                                   Address destBuffer,
-                                                   Address srcBuffer,
-                                                   SILType T) const;
-
   /// Take-initialize an address from a parameter explosion.
   virtual void initializeFromParams(IRGenFunction &IGF, Explosion &params,
                                     Address src, SILType T,
@@ -452,6 +435,9 @@
                                          SILType T) const = 0;
   
   /// Compute the packing of values of this type into a fixed-size buffer.
+  /// A value might not be stored in the fixed-size buffer because it does not
+  /// fit or because it is not bit-wise takable. Non bit-wise takable values are
+  /// not stored inline by convention.
   FixedPacking getFixedPacking(IRGenModule &IGM) const;
   
   /// Index into an array of objects of this type.
diff --git a/lib/Migrator/APIDiffMigratorPass.cpp b/lib/Migrator/APIDiffMigratorPass.cpp
index b23b46d..957ee92 100644
--- a/lib/Migrator/APIDiffMigratorPass.cpp
+++ b/lib/Migrator/APIDiffMigratorPass.cpp
@@ -260,21 +260,6 @@
       SF->getASTContext().SourceMgr, Range).str() == "nil";
   }
 
-  bool isDotMember(CharSourceRange Range) {
-    auto S = Range.str();
-    return S.startswith(".") && S.substr(1).find(".") == StringRef::npos;
-  }
-
-  bool isDotMember(SourceRange Range) {
-    return isDotMember(Lexer::getCharSourceRangeFromSourceRange(
-      SF->getASTContext().SourceMgr, Range));
-  }
-
-  bool isDotMember(Expr *E) {
-    auto Range = E->getSourceRange();
-    return Range.isValid() && isDotMember(Range);
-  }
-
   std::vector<APIDiffItem*> getRelatedDiffItems(ValueDecl *VD) {
     std::vector<APIDiffItem*> results;
     auto addDiffItems = [&](ValueDecl *VD) {
@@ -323,11 +308,11 @@
   }
 
 
-  bool isSimpleReplacement(APIDiffItem *Item, bool isDotMember, std::string &Text) {
+  bool isSimpleReplacement(APIDiffItem *Item, std::string &Text) {
     if (auto *MD = dyn_cast<TypeMemberDiffItem>(Item)) {
       if (MD->Subkind == TypeMemberDiffItemSubKind::SimpleReplacement) {
-        Text = (llvm::Twine(isDotMember ? "" : MD->newTypeName) + "." +
-          MD->getNewName().base()).str();
+        Text = (llvm::Twine(MD->newTypeName) + "." + MD->getNewName().base()).
+          str();
         return true;
       }
     }
@@ -390,7 +375,7 @@
                           Type T, ReferenceMetaData Data) override {
     for (auto *Item: getRelatedDiffItems(CtorTyRef ? CtorTyRef: D)) {
       std::string RepText;
-      if (isSimpleReplacement(Item, isDotMember(Range), RepText)) {
+      if (isSimpleReplacement(Item, RepText)) {
         Editor.replace(Range, RepText);
         return true;
       }
@@ -465,9 +450,8 @@
       for (auto *I: getRelatedDiffItems(VD)) {
         if (auto *Item = dyn_cast<TypeMemberDiffItem>(I)) {
           if (Item->Subkind == TypeMemberDiffItemSubKind::QualifiedReplacement) {
-            Editor.replace(ToReplace,
-              (llvm::Twine(isDotMember(ToReplace) ? "" : Item->newTypeName) + "." +
-               Item->getNewName().base()).str());
+            Editor.replace(ToReplace, (llvm::Twine(Item->newTypeName) + "." +
+              Item->getNewName().base()).str());
             return true;
           }
         }
@@ -741,7 +725,7 @@
     StringRef LeftComment;
     StringRef RightComment;
     for (auto *Item: getRelatedDiffItems(RD)) {
-      if (isSimpleReplacement(Item, isDotMember(Reference), Rename)) {
+      if (isSimpleReplacement(Item, Rename)) {
       } else if (auto *CI = dyn_cast<CommonDiffItem>(Item)) {
         if (CI->isStringRepresentableChange() &&
             CI->NodeKind == SDKNodeKind::DeclVar) {
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 5ba8140..d8c47bc 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2036,12 +2036,7 @@
           .fixItRemoveChars(end.getAdvancedLoc(-1), end);
     }
 
-    auto unescapedUnderscore = underscore && !escaped;
-    if (!unescapedUnderscore)
-      name = Context.getIdentifier(text);
-    if (!underscore)
-      Tok.setKind(tok::identifier);
-    loc = consumeToken();
+    loc = consumeArgumentLabel(name);
     consumeToken(tok::colon);
   }
 }
diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp
index 78e799a..95fea25 100644
--- a/lib/Parse/ParsePattern.cpp
+++ b/lib/Parse/ParsePattern.cpp
@@ -57,7 +57,7 @@
 }
 
 void Parser::DefaultArgumentInfo::setFunctionContext(
-    DeclContext *DC, MutableArrayRef<ParameterList *> paramList){
+    DeclContext *DC, ArrayRef<ParameterList *> paramList){
   for (auto context : ParsedContexts) {
     context->changeFunction(DC, paramList);
   }
@@ -240,23 +240,11 @@
 
     if (startsParameterName(*this, isClosure)) {
       // identifier-or-none for the first name
-      if (Tok.is(tok::kw__)) {
-        param.FirstNameLoc = consumeToken();
-      } else {
-        assert(Tok.canBeArgumentLabel() && "startsParameterName() lied");
-        Tok.setKind(tok::identifier);
-        param.FirstName = Context.getIdentifier(Tok.getText());
-        param.FirstNameLoc = consumeToken();
-      }
+      param.FirstNameLoc = consumeArgumentLabel(param.FirstName);
 
       // identifier-or-none? for the second name
-      if (Tok.canBeArgumentLabel()) {
-        if (!Tok.is(tok::kw__)) {
-          param.SecondName = Context.getIdentifier(Tok.getText());
-          Tok.setKind(tok::identifier);
-        }
-        param.SecondNameLoc = consumeToken();
-      }
+      if (Tok.canBeArgumentLabel())
+        param.SecondNameLoc = consumeArgumentLabel(param.SecondName);
 
       // Operators, closures, and enum elements cannot have API names.
       if ((paramContext == ParameterContextKind::Operator ||
diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp
index 350b17d..ad69d3f 100644
--- a/lib/Parse/ParseType.cpp
+++ b/lib/Parse/ParseType.cpp
@@ -878,16 +878,11 @@
         Backtracking->cancelBacktrack();
 
       // Consume a name.
-      if (!Tok.is(tok::kw__))
-        element.Name = Context.getIdentifier(Tok.getText());
-      element.NameLoc = consumeToken();
+      element.NameLoc = consumeArgumentLabel(element.Name);
 
       // If there is a second name, consume it as well.
-      if (Tok.canBeArgumentLabel()) {
-        if (!Tok.is(tok::kw__))
-          element.SecondName = Context.getIdentifier(Tok.getText());
-        element.SecondNameLoc = consumeToken();
-      }
+      if (Tok.canBeArgumentLabel())
+        element.SecondNameLoc = consumeArgumentLabel(element.SecondName);
 
       // Consume the ':'.
       if (!consumeIf(tok::colon, element.ColonLoc))
diff --git a/lib/SIL/MemAccessUtils.cpp b/lib/SIL/MemAccessUtils.cpp
index 5a8cc05..cb58844 100644
--- a/lib/SIL/MemAccessUtils.cpp
+++ b/lib/SIL/MemAccessUtils.cpp
@@ -599,3 +599,19 @@
     return;
   }
 }
+
+SILBasicBlock::iterator swift::removeBeginAccess(BeginAccessInst *beginAccess) {
+  while (!beginAccess->use_empty()) {
+    Operand *op = *beginAccess->use_begin();
+
+    // Delete any associated end_access instructions.
+    if (auto endAccess = dyn_cast<EndAccessInst>(op->getUser())) {
+      endAccess->eraseFromParent();
+
+      // Forward all other uses to the original address.
+    } else {
+      op->set(beginAccess->getSource());
+    }
+  }
+  return beginAccess->getParent()->erase(beginAccess);
+}
diff --git a/lib/SIL/SILVerifier.cpp b/lib/SIL/SILVerifier.cpp
index a16a62a..e8219fc 100644
--- a/lib/SIL/SILVerifier.cpp
+++ b/lib/SIL/SILVerifier.cpp
@@ -25,6 +25,7 @@
 #include "swift/SIL/DebugUtils.h"
 #include "swift/SIL/Dominance.h"
 #include "swift/SIL/DynamicCasts.h"
+#include "swift/SIL/MemAccessUtils.h"
 #include "swift/SIL/PostOrder.h"
 #include "swift/SIL/PrettyStackTrace.h"
 #include "swift/SIL/SILDebugScope.h"
@@ -1581,8 +1582,8 @@
   }
 
   void checkBeginAccessInst(BeginAccessInst *BAI) {
-    auto op = BAI->getOperand();
-    requireSameType(BAI->getType(), op->getType(),
+    auto sourceOper = BAI->getOperand();
+    requireSameType(BAI->getType(), sourceOper->getType(),
                     "result must be same type as operand");
     require(BAI->getType().isAddress(),
             "begin_access operand must have address type");
@@ -1603,6 +1604,11 @@
     case SILAccessKind::Modify:
       break;
     }
+
+    // For dynamic Read/Modify access, AccessEnforcementWMO assumes a valid
+    // AccessedStorage and runs very late in the optimizer pipeline.
+    // TODO: eventually, make this true for any kind of access.
+    findAccessedStorage(sourceOper);
   }
 
   void checkEndAccessInst(EndAccessInst *EAI) {
diff --git a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
index 0a98484..c9a3ea2 100644
--- a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
@@ -36,12 +36,14 @@
 //===----------------------------------------------------------------------===//
 
 bool swift::isRetainInstruction(SILInstruction *I) {
-  return isa<StrongRetainInst>(I) || isa<RetainValueInst>(I);
+  return isa<StrongRetainInst>(I) || isa<RetainValueInst>(I) ||
+         isa<UnownedRetainInst>(I);
 }
 
 
 bool swift::isReleaseInstruction(SILInstruction *I) {
-  return isa<StrongReleaseInst>(I) || isa<ReleaseValueInst>(I);
+  return isa<StrongReleaseInst>(I) || isa<ReleaseValueInst>(I) ||
+         isa<UnownedReleaseInst>(I);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/SILOptimizer/Analysis/AccessedStorageAnalysis.cpp b/lib/SILOptimizer/Analysis/AccessedStorageAnalysis.cpp
index aaeefc5..4948288 100644
--- a/lib/SILOptimizer/Analysis/AccessedStorageAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/AccessedStorageAnalysis.cpp
@@ -19,6 +19,52 @@
 
 using namespace swift;
 
+// -----------------------------------------------------------------------------
+// MARK: Accessing the results.
+// -----------------------------------------------------------------------------
+
+bool FunctionAccessedStorage::hasNoNestedConflict(
+    const AccessedStorage &otherStorage) const {
+  assert(otherStorage.isUniquelyIdentified());
+  assert(!hasUnidentifiedAccess());
+
+  return getStorageAccessInfo(otherStorage).hasNoNestedConflict();
+}
+
+bool FunctionAccessedStorage::mayConflictWith(
+    SILAccessKind otherAccessKind, const AccessedStorage &otherStorage) const {
+  if (hasUnidentifiedAccess()
+      && accessKindMayConflict(otherAccessKind,
+                               unidentifiedAccess.getValue())) {
+    return true;
+  }
+  for (auto &storageAccess : storageAccessSet) {
+    assert(storageAccess && "FunctionAccessedStorage mapped invalid storage.");
+
+    if (!accessKindMayConflict(otherAccessKind, storageAccess.getAccessKind()))
+      continue;
+
+    if (!otherStorage.isDistinctFrom(storageAccess))
+      return true;
+  }
+  return false;
+}
+
+StorageAccessInfo FunctionAccessedStorage::getStorageAccessInfo(
+    const AccessedStorage &otherStorage) const {
+  // Construct a fake StorageAccessInfo to do a hash lookup for the real
+  // StorageAccessInfo. The DenseSet key is limited to the AccessedStorage base
+  // class members.
+  StorageAccessInfo storageKey(otherStorage, SILAccessKind::Read, false);
+  auto iter = storageAccessSet.find(storageKey);
+  assert(iter != storageAccessSet.end());
+  return *iter;
+}
+
+// -----------------------------------------------------------------------------
+// MARK: Constructing the results.
+// -----------------------------------------------------------------------------
+
 static bool updateAccessKind(SILAccessKind &LHS, SILAccessKind RHS) {
   bool changed = false;
   // Assume we don't track Init/Deinit.
@@ -42,18 +88,23 @@
 }
 
 bool StorageAccessInfo::mergeFrom(const StorageAccessInfo &RHS) {
+  bool changed = false;
+  SILAccessKind accessKind = getAccessKind();
   assert(accessKind == SILAccessKind::Read
          || accessKind == SILAccessKind::Modify && "uninitialized info");
-  bool changed = updateAccessKind(accessKind, RHS.accessKind);
-  if (noNestedConflict && !RHS.noNestedConflict) {
-    noNestedConflict = false;
+  if (updateAccessKind(accessKind, RHS.getAccessKind())) {
+    setAccessKind(accessKind);
+    changed = true;
+  }
+  if (hasNoNestedConflict() && !RHS.hasNoNestedConflict()) {
+    setNoNestedConflict(false);
     changed = true;
   }
   return changed;
 }
 
 bool FunctionAccessedStorage::summarizeFunction(SILFunction *F) {
-  assert(storageAccessMap.empty() && "expected uninitialized results.");
+  assert(storageAccessSet.empty() && "expected uninitialized results.");
 
   if (F->isDefinition())
     return false;
@@ -81,7 +132,7 @@
     unidentifiedAccess = SILAccessKind::Read;
 
   // If function side effects is "readnone" then this result will have an empty
-  // storageAccessMap and unidentifiedAccess == None.
+  // storageAccessSet and unidentifiedAccess == None.
   return true;
 }
 
@@ -104,38 +155,43 @@
 // propagate and merge in that case in case arguments are recursively dependent.
 bool FunctionAccessedStorage::mergeAccesses(
     const FunctionAccessedStorage &other,
-    std::function<AccessedStorage(const AccessedStorage &)> transformStorage) {
+    std::function<StorageAccessInfo(const StorageAccessInfo &)>
+      transformStorage) {
 
   // Insertion in DenseMap invalidates the iterator in the rare case of
   // self-recursion (`this` == `other`) that passes accessed storage though an
   // argument. Rather than complicate the code, make a temporary copy of the
   // AccessedStorage.
-  SmallVector<std::pair<AccessedStorage, StorageAccessInfo>, 8> otherAccesses;
-  otherAccesses.reserve(other.storageAccessMap.size());
-  otherAccesses.append(other.storageAccessMap.begin(),
-                       other.storageAccessMap.end());
+  //
+  // Also note that the storageAccessIndex from otherStorage is relative to its
+  // original context and should not be copied into this context.
+  SmallVector<StorageAccessInfo, 8> otherStorageAccesses;
+  otherStorageAccesses.reserve(other.storageAccessSet.size());
+  otherStorageAccesses.append(other.storageAccessSet.begin(),
+                              other.storageAccessSet.end());
 
   bool changed = false;
-  for (auto &accessEntry : otherAccesses) {
-    const AccessedStorage &storage = transformStorage(accessEntry.first);
+  for (auto &rawStorageInfo : otherStorageAccesses) {
+    const StorageAccessInfo &otherStorageInfo =
+      transformStorage(rawStorageInfo);
     // transformStorage() returns invalid storage object for local storage
     // that should not be merged with the caller.
-    if (!storage)
+    if (!otherStorageInfo)
       continue;
 
-    if (storage.getKind() == AccessedStorage::Unidentified) {
-      changed |= updateUnidentifiedAccess(accessEntry.second.accessKind);
+    if (otherStorageInfo.getKind() == AccessedStorage::Unidentified) {
+      changed |= updateUnidentifiedAccess(otherStorageInfo.getAccessKind());
       continue;
     }
     // Attempt to add identified AccessedStorage to this map.
-    auto result = storageAccessMap.try_emplace(storage, accessEntry.second);
+    auto result = insertStorageAccess(otherStorageInfo);
     if (result.second) {
       // A new AccessedStorage key was added to this map.
       changed = true;
       continue;
     }
     // Merge StorageAccessInfo into already-mapped AccessedStorage.
-    changed |= result.first->second.mergeFrom(accessEntry.second);
+    changed |= result.first->mergeFrom(otherStorageInfo);
   }
   if (other.unidentifiedAccess != None)
     changed |= updateUnidentifiedAccess(other.unidentifiedAccess.getValue());
@@ -147,7 +203,7 @@
   // Merge accesses from other. Both `this` and `other` are either from the same
   // function or are both callees of the same call site, so their parameters
   // indices coincide. transformStorage is the identity function.
-  return mergeAccesses(other, [](const AccessedStorage &s) { return s; });
+  return mergeAccesses(other, [](const StorageAccessInfo &s) { return s; });
 }
 
 /// Returns the argument of the full apply or partial apply corresponding to the
@@ -175,13 +231,23 @@
 
 /// Transform AccessedStorage from a callee into the caller context. If this is
 /// uniquely identified local storage, then return an invalid storage object.
-static AccessedStorage transformCalleeStorage(const AccessedStorage &storage,
-                                              FullApplySite fullApply) {
+///
+/// For correctness, AccessEnforcementOpts relies on all Argument access to
+/// either be mapped into the caller's context or marked as an unidentified
+/// access at the call site.
+///
+/// Note: This does *not* map the storage index into the caller function's index
+/// range. (When the storage value doesn't need to be remapped, it returns the
+/// original storage value.) It's simpler to set the storage index later when it
+/// is actually added to the function's storageAccessSet.
+static StorageAccessInfo
+transformCalleeStorage(const StorageAccessInfo &storage,
+                       FullApplySite fullApply) {
   switch (storage.getKind()) {
   case AccessedStorage::Box:
   case AccessedStorage::Stack:
     // Do not merge local storage.
-    return AccessedStorage();
+    return StorageAccessInfo(AccessedStorage(), storage);
   case AccessedStorage::Global:
     // Global accesses is universal.
     return storage;
@@ -191,9 +257,11 @@
     SILValue obj = storage.getObjectProjection().getObject();
     if (auto *arg = dyn_cast<SILFunctionArgument>(obj)) {
       SILValue argVal = getCallerArg(fullApply, arg->getIndex());
-      if (argVal)
-        return AccessedStorage(argVal,
-                               storage.getObjectProjection().getProjection());
+      if (argVal) {
+        auto &proj = storage.getObjectProjection().getProjection();
+        // Remap the argument source value and inherit the old storage info.
+        return StorageAccessInfo(AccessedStorage(argVal, proj), storage);
+      }
     }
     // Otherwise, continue to reference the value in the callee because we don't
     // have any better placeholder for a callee-defined object.
@@ -202,12 +270,15 @@
   case AccessedStorage::Argument: {
     // Transitively search for the storage base in the caller.
     SILValue argVal = getCallerArg(fullApply, storage.getParamIndex());
-    if (argVal)
-      return findAccessedStorageNonNested(argVal);
-
+    if (argVal) {
+      // Remap the argument source value and inherit the old storage info.
+      return StorageAccessInfo(findAccessedStorageNonNested(argVal), storage);
+    }
     // If the argument can't be transformed, demote it to an unidentified
     // access.
-    return AccessedStorage(storage.getValue(), AccessedStorage::Unidentified);
+    return StorageAccessInfo(
+      AccessedStorage(storage.getValue(), AccessedStorage::Unidentified),
+      storage);
   }
   case AccessedStorage::Nested:
     llvm_unreachable("Unexpected nested access");
@@ -222,7 +293,7 @@
     const FunctionAccessedStorage &calleeAccess, FullApplySite fullApply) {
   // Merge accesses from calleeAccess. Transform any Argument type
   // AccessedStorage into the caller context to be added to `this` storage map.
-  return mergeAccesses(calleeAccess, [&fullApply](const AccessedStorage &s) {
+  return mergeAccesses(calleeAccess, [&fullApply](const StorageAccessInfo &s) {
     return transformCalleeStorage(s, fullApply);
   });
 }
@@ -236,13 +307,14 @@
       findAccessedStorageNonNested(beginAccess->getSource());
 
   if (storage.getKind() == AccessedStorage::Unidentified) {
+    // This also catches invalid storage.
     updateOptionalAccessKind(unidentifiedAccess, beginAccess->getAccessKind());
     return;
   }
-  StorageAccessInfo accessInfo(beginAccess);
-  auto result = storageAccessMap.try_emplace(storage, accessInfo);
+  StorageAccessInfo storageAccess(storage, beginAccess);
+  auto result = insertStorageAccess(storageAccess);
   if (!result.second)
-    result.first->second.mergeFrom(accessInfo);
+    result.first->mergeFrom(storageAccess);
 }
 
 void FunctionAccessedStorage::analyzeInstruction(SILInstruction *I) {
@@ -252,44 +324,26 @@
     visitBeginAccess(BUAI);
 }
 
-bool FunctionAccessedStorage::mayConflictWith(
-    SILAccessKind otherAccessKind, const AccessedStorage &otherStorage) {
-  if (unidentifiedAccess != None
-      && accessKindMayConflict(otherAccessKind,
-                               unidentifiedAccess.getValue())) {
-    return true;
-  }
-  for (auto &accessEntry : storageAccessMap) {
-
-    const AccessedStorage &storage = accessEntry.first;
-    assert(storage && "FunctionAccessedStorage mapped invalid storage.");
-
-    StorageAccessInfo accessInfo = accessEntry.second;
-    if (!accessKindMayConflict(otherAccessKind, accessInfo.accessKind))
-      continue;
-
-    if (!otherStorage.isDistinctFrom(storage))
-      return true;
-  }
-  return false;
+void StorageAccessInfo::print(raw_ostream &os) const {
+  os << "  [" << getSILAccessKindName(getAccessKind()) << "] ";
+  if (hasNoNestedConflict())
+    os << "[no_nested_conflict] ";
+  AccessedStorage::print(os);
 }
 
+void StorageAccessInfo::dump() const { print(llvm::dbgs()); }
+
 void FunctionAccessedStorage::print(raw_ostream &os) const {
-  for (auto &accessEntry : storageAccessMap) {
-    const AccessedStorage &storage = accessEntry.first;
-    const StorageAccessInfo &info = accessEntry.second;
-    os << "  [" << getSILAccessKindName(info.accessKind) << "] ";
-    if (info.noNestedConflict)
-      os << "[no_nested_conflict] ";
-    storage.print(os);
-  }
+  for (auto &storageAccess : storageAccessSet)
+    storageAccess.print(os);
+
   if (unidentifiedAccess != None) {
     os << "  unidentified accesses: "
        << getSILAccessKindName(unidentifiedAccess.getValue()) << "\n";
   }
 }
 
-void FunctionAccessedStorage::dump() const { print(llvm::errs()); }
+void FunctionAccessedStorage::dump() const { print(llvm::dbgs()); }
 
 SILAnalysis *swift::createAccessedStorageAnalysis(SILModule *) {
   return new AccessedStorageAnalysis();
diff --git a/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp b/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
index 6f353d3..7f1c121 100644
--- a/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
+++ b/lib/SILOptimizer/Mandatory/AccessMarkerElimination.cpp
@@ -29,6 +29,7 @@
 
 #define DEBUG_TYPE "access-marker-elim"
 #include "swift/Basic/Range.h"
+#include "swift/SIL/MemAccessUtils.h"
 #include "swift/SIL/SILFunction.h"
 #include "swift/SILOptimizer/PassManager/Transforms.h"
 #include "llvm/Support/CommandLine.h"
@@ -56,42 +57,27 @@
   AccessMarkerElimination(SILFunction *F)
       : Mod(&F->getModule()), F(F) {}
 
-  SILBasicBlock::iterator eraseInst(SILInstruction *inst) {
+  void notifyErased(SILInstruction *inst) {
     DEBUG(llvm::dbgs() << "Erasing access marker: " << *inst);
     removedAny = true;
+  }
+
+  SILBasicBlock::iterator eraseInst(SILInstruction *inst) {
+    notifyErased(inst);
     return inst->getParent()->erase(inst);
   };
 
-  void replaceBeginAccessUsers(BeginAccessInst *beginAccess);
-
   bool shouldPreserveAccess(SILAccessEnforcement enforcement);
 
   // Check if the instruction is a marker that should be eliminated. If so,
   // updated the SIL, short of erasing the marker itself, and return true.
-  bool checkAndEliminateMarker(SILInstruction *inst);
+  SILBasicBlock::iterator checkAndEliminateMarker(SILInstruction *inst);
 
   // Entry point called either by the pass by the same name
   // or as a utility (e.g. during deserialization).
   bool stripMarkers();
 };
 
-void AccessMarkerElimination::replaceBeginAccessUsers(
-    BeginAccessInst *beginAccess) {
-  // Handle all the uses:
-  while (!beginAccess->use_empty()) {
-    Operand *op = *beginAccess->use_begin();
-
-    // Delete any associated end_access instructions.
-    if (auto endAccess = dyn_cast<EndAccessInst>(op->getUser())) {
-      endAccess->eraseFromParent();
-
-      // Forward all other uses to the original address.
-    } else {
-      op->set(beginAccess->getSource());
-    }
-  }
-}
-
 bool AccessMarkerElimination::shouldPreserveAccess(
     SILAccessEnforcement enforcement) {
   if (!EnableOptimizedAccessMarkers)
@@ -107,22 +93,26 @@
   }
 }
 
-// Check if the instruction is a marker that should be eliminated. If so,
-// updated the SIL, short of erasing the marker itself, and return true.
-bool AccessMarkerElimination::checkAndEliminateMarker(SILInstruction *inst) {
+// Check if the instruction is a marker that should be eliminated. If so, delete
+// the begin_access along with all associated end_access and a valid instruction
+// iterator pointing to the first remaining instruction following the
+// begin_access. If the marker is not eliminated, return an iterator pointing to
+// the marker.
+SILBasicBlock::iterator
+AccessMarkerElimination::checkAndEliminateMarker(SILInstruction *inst) {
   if (auto beginAccess = dyn_cast<BeginAccessInst>(inst)) {
     // Builtins used by the standard library must emit markers regardless of the
     // current compiler options so that any user code that initiates access via
     // the standard library is fully enforced.
     if (beginAccess->isFromBuiltin())
-      return false;
+      return inst->getIterator();
 
     // Leave dynamic accesses in place, but delete all others.
     if (shouldPreserveAccess(beginAccess->getEnforcement()))
-      return false;
+      return inst->getIterator();
 
-    replaceBeginAccessUsers(beginAccess);
-    return true;
+    notifyErased(beginAccess);
+    return removeBeginAccess(beginAccess);
   }
 
   // end_access instructions will be handled when we process the
@@ -134,12 +124,12 @@
     // Builtins used by the standard library must emit markers regardless of the
     // current compiler options.
     if (BUA->isFromBuiltin())
-      return false;
+      return inst->getIterator();
 
     if (shouldPreserveAccess(BUA->getEnforcement()))
-      return false;
+      return inst->getIterator();
 
-    return true;
+    return eraseInst(BUA);
   }
   // end_unpaired_access instructions will be directly removed and
   // simply replaced with their operand.
@@ -147,14 +137,14 @@
     // Builtins used by the standard library must emit markers regardless of the
     // current compiler options.
     if (EUA->isFromBuiltin())
-      return false;
+      return inst->getIterator();
 
     if (shouldPreserveAccess(EUA->getEnforcement()))
-      return false;
+      return inst->getIterator();
 
-    return true;
+    return eraseInst(EUA);
   }
-  return false;
+  return inst->getIterator();
 }
 
 // Top-level per-function entry-point.
@@ -166,8 +156,9 @@
     // Don't cache the begin iterator since we're reverse iterating.
     for (auto II = BB.end(); II != BB.begin();) {
       SILInstruction *inst = &*(--II);
-      if (checkAndEliminateMarker(inst))
-        II = eraseInst(inst);
+      // checkAndEliminateMarker returns the next non-deleted instruction. The
+      // following iteration moves the iterator backward.
+      II = checkAndEliminateMarker(inst);
     }
   }
   return removedAny;
diff --git a/lib/SILOptimizer/Mandatory/CMakeLists.txt b/lib/SILOptimizer/Mandatory/CMakeLists.txt
index b4c29d5..8819fe1 100644
--- a/lib/SILOptimizer/Mandatory/CMakeLists.txt
+++ b/lib/SILOptimizer/Mandatory/CMakeLists.txt
@@ -16,4 +16,6 @@
   Mandatory/PredictableMemOpt.cpp
   Mandatory/SemanticARCOpts.cpp
   Mandatory/ClosureLifetimeFixup.cpp
+  Mandatory/RawSILInstLowering.cpp
+  Mandatory/MandatoryOptUtils.cpp
   PARENT_SCOPE)
diff --git a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
index 2df2d15..c8e83b9 100644
--- a/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
+++ b/lib/SILOptimizer/Mandatory/DIMemoryUseCollectorOwnership.cpp
@@ -1459,24 +1459,79 @@
 }
 
 //===----------------------------------------------------------------------===//
-//                     DelegatingInitElementUseCollector
+//                    DelegatingValueTypeInitUseCollector
+//===----------------------------------------------------------------------===//
+
+static void
+collectValueTypeDelegatingInitUses(const DIMemoryObjectInfo &TheMemory,
+                                   DIElementUseInfo &UseInfo,
+                                   SingleValueInstruction *I) {
+  for (auto *Op : I->getUses()) {
+    auto *User = Op->getUser();
+
+    // destroy_addr is a release of the entire value. This can result from an
+    // early release due to a conditional initializer.
+    if (isa<DestroyAddrInst>(User)) {
+      UseInfo.trackDestroy(User);
+      continue;
+    }
+
+    // For delegating initializers, we only track calls to self.init with
+    // specialized code. All other uses are modeled as escapes.
+    //
+    // *NOTE* This intentionally ignores all stores, which (if they got emitted
+    // as copyaddr or assigns) will eventually get rewritten as assignments (not
+    // initializations), which is the right thing to do.
+    DIUseKind Kind = DIUseKind::Escape;
+
+    // Stores *to* the allocation are writes.  If the value being stored is a
+    // call to self.init()... then we have a self.init call.
+    if (auto *AI = dyn_cast<AssignInst>(User)) {
+      if (AI->getDest() == I) {
+        UseInfo.trackStoreToSelf(AI);
+        Kind = DIUseKind::InitOrAssign;
+      }
+    }
+
+    if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
+      if (CAI->getDest() == I) {
+        UseInfo.trackStoreToSelf(CAI);
+        Kind = DIUseKind::InitOrAssign;
+      }
+    }
+
+    // Look through begin_access
+    if (auto *BAI = dyn_cast<BeginAccessInst>(User)) {
+      collectValueTypeDelegatingInitUses(TheMemory, UseInfo, BAI);
+      continue;
+    }
+
+    // Ignore end_access
+    if (isa<EndAccessInst>(User))
+      continue;
+
+    // We can safely handle anything else as an escape.  They should all happen
+    // after self.init is invoked.
+    UseInfo.trackUse(DIMemoryUse(User, Kind, 0, 1));
+  }
+}
+
+//===----------------------------------------------------------------------===//
+//                   DelegatingClassInitElementUseCollector
 //===----------------------------------------------------------------------===//
 
 namespace {
 
-class DelegatingInitElementUseCollector {
+class DelegatingClassInitElementUseCollector {
   const DIMemoryObjectInfo &TheMemory;
   DIElementUseInfo &UseInfo;
 
-  void collectValueTypeInitSelfUses(SingleValueInstruction *I);
-
 public:
-  DelegatingInitElementUseCollector(const DIMemoryObjectInfo &TheMemory,
-                                    DIElementUseInfo &UseInfo)
+  DelegatingClassInitElementUseCollector(const DIMemoryObjectInfo &TheMemory,
+                                         DIElementUseInfo &UseInfo)
       : TheMemory(TheMemory), UseInfo(UseInfo) {}
 
   void collectClassInitSelfUses();
-  void collectValueTypeInitSelfUses();
 
   // *NOTE* Even though this takes a SILInstruction it actually only accepts
   // load_borrow and load instructions. This is enforced via an assert.
@@ -1488,7 +1543,7 @@
 
 /// collectDelegatingClassInitSelfUses - Collect uses of the self argument in a
 /// delegating-constructor-for-a-class case.
-void DelegatingInitElementUseCollector::collectClassInitSelfUses() {
+void DelegatingClassInitElementUseCollector::collectClassInitSelfUses() {
   // When we're analyzing a delegating constructor, we aren't field sensitive at
   // all.  Just treat all members of self as uses of the single
   // non-field-sensitive value.
@@ -1631,70 +1686,9 @@
   }
 }
 
-void DelegatingInitElementUseCollector::collectValueTypeInitSelfUses(
-    SingleValueInstruction *I) {
-  for (auto Op : I->getUses()) {
-    auto *User = Op->getUser();
-
-    // destroy_addr is a release of the entire value. This can result from an
-    // early release due to a conditional initializer.
-    if (isa<DestroyAddrInst>(User)) {
-      UseInfo.trackDestroy(User);
-      continue;
-    }
-
-    // For delegating initializers, we only track calls to self.init with
-    // specialized code. All other uses are modeled as escapes.
-    //
-    // *NOTE* This intentionally ignores all stores, which (if they got emitted
-    // as copyaddr or assigns) will eventually get rewritten as assignments (not
-    // initializations), which is the right thing to do.
-    DIUseKind Kind = DIUseKind::Escape;
-
-    // Stores *to* the allocation are writes.  If the value being stored is a
-    // call to self.init()... then we have a self.init call.
-    if (auto *AI = dyn_cast<AssignInst>(User)) {
-      if (AI->getDest() == I) {
-        UseInfo.trackStoreToSelf(AI);
-        Kind = DIUseKind::InitOrAssign;
-      }
-    }
-
-    if (auto *CAI = dyn_cast<CopyAddrInst>(User)) {
-      if (CAI->getDest() == I) {
-        UseInfo.trackStoreToSelf(CAI);
-        Kind = DIUseKind::InitOrAssign;
-      }
-    }
-
-    // Look through begin_access
-    if (auto *BAI = dyn_cast<BeginAccessInst>(User)) {
-      collectValueTypeInitSelfUses(BAI);
-      continue;
-    }
-
-    // Ignore end_access
-    if (isa<EndAccessInst>(User))
-      continue;
-
-    // We can safely handle anything else as an escape.  They should all happen
-    // after self.init is invoked.
-    UseInfo.trackUse(DIMemoryUse(User, Kind, 0, 1));
-  }
-}
-
-void DelegatingInitElementUseCollector::collectValueTypeInitSelfUses() {
-  // When we're analyzing a delegating constructor, we aren't field sensitive at
-  // all.  Just treat all members of self as uses of the single
-  // non-field-sensitive value.
-  assert(TheMemory.NumElements == 1 && "delegating inits only have 1 bit");
-
-  auto *MUI = cast<MarkUninitializedInst>(TheMemory.MemoryInst);
-  collectValueTypeInitSelfUses(MUI);
-}
-
-void DelegatingInitElementUseCollector::collectDelegatingClassInitSelfLoadUses(
-    MarkUninitializedInst *MUI, SingleValueInstruction *LI) {
+void DelegatingClassInitElementUseCollector::
+collectDelegatingClassInitSelfLoadUses(MarkUninitializedInst *MUI,
+                                       SingleValueInstruction *LI) {
   assert(isa<LoadBorrowInst>(LI) || isa<LoadInst>(LI));
 
   // If we have a load, then this is a use of the box.  Look at the uses of
@@ -1775,31 +1769,38 @@
 //                            Top Level Entrypoint
 //===----------------------------------------------------------------------===//
 
+static bool shouldPerformClassInitSelf(const DIMemoryObjectInfo &MemoryInfo) {
+  if (MemoryInfo.isDelegatingInit()) {
+    assert(MemoryInfo.isClassInitSelf());
+    return true;
+  }
+
+  return MemoryInfo.isNonDelegatingInit() &&
+         MemoryInfo.getType()->getClassOrBoundGenericClass() != nullptr &&
+         MemoryInfo.isDerivedClassSelfOnly();
+}
+
 /// collectDIElementUsesFrom - Analyze all uses of the specified allocation
 /// instruction (alloc_box, alloc_stack or mark_uninitialized), classifying them
 /// and storing the information found into the Uses and Releases lists.
 void swift::ownership::collectDIElementUsesFrom(
     const DIMemoryObjectInfo &MemoryInfo, DIElementUseInfo &UseInfo,
     bool isDIFinished, bool TreatAddressToPointerAsInout) {
-  // If we have a delegating init, use the delegating init element use
-  // collector.
-  if (MemoryInfo.isDelegatingInit()) {
-    DelegatingInitElementUseCollector UseCollector(MemoryInfo, UseInfo);
-    if (MemoryInfo.isClassInitSelf()) {
-      UseCollector.collectClassInitSelfUses();
-    } else {
-      UseCollector.collectValueTypeInitSelfUses();
-    }
 
+  if (MemoryInfo.isDelegatingInit() && !MemoryInfo.isClassInitSelf()) {
+    // When we're analyzing a delegating constructor, we aren't field sensitive
+    // at all. Just treat all members of self as uses of the single
+    // non-field-sensitive value.
+    assert(MemoryInfo.NumElements == 1 && "delegating inits only have 1 bit");
+    auto *MUI = cast<MarkUninitializedInst>(MemoryInfo.MemoryInst);
+    collectValueTypeDelegatingInitUses(MemoryInfo, UseInfo, MUI);
     MemoryInfo.collectRetainCountInfo(UseInfo);
     return;
   }
 
-  if (MemoryInfo.isNonDelegatingInit() &&
-      MemoryInfo.getType()->getClassOrBoundGenericClass() != nullptr &&
-      MemoryInfo.isDerivedClassSelfOnly()) {
-    DelegatingInitElementUseCollector(MemoryInfo, UseInfo)
-        .collectClassInitSelfUses();
+  if (shouldPerformClassInitSelf(MemoryInfo)) {
+    DelegatingClassInitElementUseCollector UseCollector(MemoryInfo, UseInfo);
+    UseCollector.collectClassInitSelfUses();
     MemoryInfo.collectRetainCountInfo(UseInfo);
     return;
   }
diff --git a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
index 3402a9e..0ba46bb 100644
--- a/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
+++ b/lib/SILOptimizer/Mandatory/DefiniteInitialization.cpp
@@ -12,6 +12,7 @@
 
 #define DEBUG_TYPE "definite-init"
 #include "DIMemoryUseCollectorOwnership.h"
+#include "MandatoryOptUtils.h"
 #include "swift/AST/DiagnosticEngine.h"
 #include "swift/AST/DiagnosticsSIL.h"
 #include "swift/AST/Expr.h"
@@ -44,8 +45,6 @@
                    "Meant for debugging ONLY!"),
     llvm::cl::Hidden);
 
-STATISTIC(NumAssignRewritten, "Number of assigns rewritten");
-
 template<typename ...ArgTypes>
 static InFlightDiagnostic diagnose(SILModule &M, SILLocation loc,
                                    ArgTypes... args) {
@@ -56,83 +55,6 @@
   return diag;
 }
 
-enum class PartialInitializationKind {
-  /// The box contains a fully-initialized value.
-  IsNotInitialization,
-
-  /// The box contains a class instance that we own, but the instance has
-  /// not been initialized and should be freed with a special SIL
-  /// instruction made for this purpose.
-  IsReinitialization,
-
-  /// The box contains an undefined value that should be ignored.
-  IsInitialization,
-};
-
-/// Emit the sequence that an assign instruction lowers to once we know
-/// if it is an initialization or an assignment.  If it is an assignment,
-/// a live-in value can be provided to optimize out the reload.
-static void LowerAssignInstruction(SILBuilderWithScope &B, AssignInst *Inst,
-                                   PartialInitializationKind isInitialization) {
-  DEBUG(llvm::dbgs() << "  *** Lowering [isInit=" << unsigned(isInitialization)
-                     << "]: " << *Inst << "\n");
-
-  ++NumAssignRewritten;
-
-  SILValue Src = Inst->getSrc();
-  SILLocation Loc = Inst->getLoc();
-
-  if (isInitialization == PartialInitializationKind::IsInitialization ||
-      Inst->getDest()->getType().isTrivial(Inst->getModule())) {
-
-    // If this is an initialization, or the storage type is trivial, we
-    // can just replace the assignment with a store.
-    assert(isInitialization != PartialInitializationKind::IsReinitialization);
-    B.createTrivialStoreOr(Loc, Src, Inst->getDest(),
-                           StoreOwnershipQualifier::Init);
-    Inst->eraseFromParent();
-    return;
-  }
-
-  if (isInitialization == PartialInitializationKind::IsReinitialization) {
-    // We have a case where a convenience initializer on a class
-    // delegates to a factory initializer from a protocol extension.
-    // Factory initializers give us a whole new instance, so the existing
-    // instance, which has not been initialized and never will be, must be
-    // freed using dealloc_partial_ref.
-    SILValue Pointer =
-        B.createLoad(Loc, Inst->getDest(), LoadOwnershipQualifier::Take);
-    B.createStore(Loc, Src, Inst->getDest(), StoreOwnershipQualifier::Init);
-
-    auto MetatypeTy = CanMetatypeType::get(
-        Inst->getDest()->getType().getASTType(),
-        MetatypeRepresentation::Thick);
-    auto SILMetatypeTy = SILType::getPrimitiveObjectType(MetatypeTy);
-    SILValue Metatype = B.createValueMetatype(Loc, SILMetatypeTy, Pointer);
-
-    B.createDeallocPartialRef(Loc, Pointer, Metatype);
-    Inst->eraseFromParent();
-    return;
-  }
-
-  assert(isInitialization == PartialInitializationKind::IsNotInitialization);
-  // Otherwise, we need to replace the assignment with the full
-  // load/store/release dance. Note that the new value is already
-  // considered to be retained (by the semantics of the storage type),
-  // and we're transferring that ownership count into the destination.
-
-  // This is basically TypeLowering::emitStoreOfCopy, except that if we have
-  // a known incoming value, we can avoid the load.
-  SILValue IncomingVal =
-      B.createLoad(Loc, Inst->getDest(), LoadOwnershipQualifier::Take);
-  B.createStore(Inst->getLoc(), Src, Inst->getDest(),
-                StoreOwnershipQualifier::Init);
-
-  B.emitDestroyValueOperation(Loc, IncomingVal);
-  Inst->eraseFromParent();
-}
-
-
 /// Insert a CFG diamond at the position specified by the SILBuilder, with a
 /// conditional branch based on "Cond".
 ///
@@ -1912,7 +1834,7 @@
 
     SmallVector<SILInstruction*, 4> InsertedInsts;
     SILBuilderWithScope B(Inst, &InsertedInsts);
-    LowerAssignInstruction(B, AI, PartialInitKind);
+    lowerAssignInstruction(B, AI, PartialInitKind);
 
     // If lowering of the assign introduced any new loads or stores, keep track
     // of them.
@@ -2899,64 +2821,35 @@
   DEBUG(llvm::dbgs() << "*** Definite Init visiting function: "
                      <<  Fn.getName() << "\n");
   bool Changed = false;
-  for (auto &BB : Fn) {
-    for (auto I = BB.begin(), E = BB.end(); I != E; ++I) {
-      SILInstruction *Inst = &*I;
-      if (auto *MUI = dyn_cast<MarkUninitializedInst>(Inst))
-        Changed |= processMemoryObject(MUI);
-    }
-  }
-  return Changed;
-}
 
-/// lowerRawSILOperations - There are a variety of raw-sil instructions like
-/// 'assign' that are only used by this pass.  Now that definite initialization
-/// checking is done, remove them.
-static bool lowerRawSILOperations(SILFunction &Fn) {
-  bool Changed = false;
   for (auto &BB : Fn) {
-    auto I = BB.begin(), E = BB.end();
-    while (I != E) {
+    for (auto I = BB.begin(), E = BB.end(); I != E;) {
       SILInstruction *Inst = &*I;
+
+      auto *MUI = dyn_cast<MarkUninitializedInst>(Inst);
+      if (!MUI || !processMemoryObject(MUI)) {
+        ++I;
+        continue;
+      }
+
+      // Move off of the MUI only after we have processed memory objects. The
+      // lifetime checker may rewrite instructions, so it is important to not
+      // move onto the next element until after it runs.
       ++I;
-
-      // Unprocessed assigns just lower into assignments, not initializations.
-      if (auto *AI = dyn_cast<AssignInst>(Inst)) {
-        SILBuilderWithScope B(AI);
-        LowerAssignInstruction(B, AI,
-            PartialInitializationKind::IsNotInitialization);
-        // Assign lowering may split the block. If it did,
-        // reset our iteration range to the block after the insertion.
-        if (B.getInsertionBB() != &BB)
-          I = E;
-        Changed = true;
-        continue;
-      }
-
-      // mark_uninitialized just becomes a noop, resolving to its operand.
-      if (auto *MUI = dyn_cast<MarkUninitializedInst>(Inst)) {
-        MUI->replaceAllUsesWith(MUI->getOperand());
-        MUI->eraseFromParent();
-        Changed = true;
-        continue;
-      }
-      
-      // mark_function_escape just gets zapped.
-      if (isa<MarkFunctionEscapeInst>(Inst)) {
-        Inst->eraseFromParent();
-        Changed = true;
-        continue;
-      }
+      MUI->replaceAllUsesWith(MUI->getOperand());
+      MUI->eraseFromParent();
+      Changed = true;
     }
   }
+
   return Changed;
 }
 
 namespace {
+
 /// Perform definitive initialization analysis and promote alloc_box uses into
 /// SSA registers for later SSA-based dataflow passes.
 class DefiniteInitialization : public SILFunctionTransform {
-
   /// The entry point to the transformation.
   void run() override {
     // Don't rerun diagnostics on deserialized functions.
@@ -2967,16 +2860,9 @@
     if (checkDefiniteInitialization(*getFunction())) {
       invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
     }
-
-    DEBUG(getFunction()->verify());
-
-    // Lower raw-sil only instructions used by this pass, like "assign".
-    if (lowerRawSILOperations(*getFunction()))
-      invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
-
   }
-
 };
+
 } // end anonymous namespace
 
 SILTransform *swift::createDefiniteInitialization() {
diff --git a/lib/SILOptimizer/Mandatory/MandatoryOptUtils.cpp b/lib/SILOptimizer/Mandatory/MandatoryOptUtils.cpp
new file mode 100644
index 0000000..fb7716d
--- /dev/null
+++ b/lib/SILOptimizer/Mandatory/MandatoryOptUtils.cpp
@@ -0,0 +1,98 @@
+//===--- MandatoryOptUtils.cpp --------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "sil-mandatory-utils"
+#include "MandatoryOptUtils.h"
+#include "swift/AST/DiagnosticEngine.h"
+#include "swift/AST/DiagnosticsSIL.h"
+#include "swift/AST/Expr.h"
+#include "swift/ClangImporter/ClangModule.h"
+#include "swift/SIL/InstructionUtils.h"
+#include "swift/SIL/SILArgument.h"
+#include "swift/SIL/SILBuilder.h"
+#include "swift/SILOptimizer/PassManager/Passes.h"
+#include "swift/SILOptimizer/PassManager/Transforms.h"
+#include "swift/SILOptimizer/Utils/CFG.h"
+#include "swift/SILOptimizer/Utils/Local.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+
+STATISTIC(NumAssignRewritten, "Number of assigns rewritten");
+
+using namespace swift;
+
+/// Emit the sequence that an assign instruction lowers to once we know
+/// if it is an initialization or an assignment.  If it is an assignment,
+/// a live-in value can be provided to optimize out the reload.
+void swift::lowerAssignInstruction(SILBuilderWithScope &B, AssignInst *Inst,
+                                   PartialInitializationKind isInitialization) {
+  DEBUG(llvm::dbgs() << "  *** Lowering [isInit=" << unsigned(isInitialization)
+                     << "]: " << *Inst << "\n");
+
+  ++NumAssignRewritten;
+
+  SILValue Src = Inst->getSrc();
+  SILLocation Loc = Inst->getLoc();
+
+  if (isInitialization == PartialInitializationKind::IsInitialization ||
+      Inst->getDest()->getType().isTrivial(Inst->getModule())) {
+
+    // If this is an initialization, or the storage type is trivial, we
+    // can just replace the assignment with a store.
+    assert(isInitialization != PartialInitializationKind::IsReinitialization);
+    B.createTrivialStoreOr(Loc, Src, Inst->getDest(),
+                           StoreOwnershipQualifier::Init);
+    Inst->eraseFromParent();
+    return;
+  }
+
+  if (isInitialization == PartialInitializationKind::IsReinitialization) {
+    // We have a case where a convenience initializer on a class
+    // delegates to a factory initializer from a protocol extension.
+    // Factory initializers give us a whole new instance, so the existing
+    // instance, which has not been initialized and never will be, must be
+    // freed using dealloc_partial_ref.
+    SILValue Pointer =
+        B.createLoad(Loc, Inst->getDest(), LoadOwnershipQualifier::Take);
+    B.createStore(Loc, Src, Inst->getDest(), StoreOwnershipQualifier::Init);
+
+    auto MetatypeTy = CanMetatypeType::get(
+        Inst->getDest()->getType().getASTType(), MetatypeRepresentation::Thick);
+    auto SILMetatypeTy = SILType::getPrimitiveObjectType(MetatypeTy);
+    SILValue Metatype = B.createValueMetatype(Loc, SILMetatypeTy, Pointer);
+
+    B.createDeallocPartialRef(Loc, Pointer, Metatype);
+    Inst->eraseFromParent();
+    return;
+  }
+
+  assert(isInitialization == PartialInitializationKind::IsNotInitialization);
+  // Otherwise, we need to replace the assignment with the full
+  // load/store/release dance. Note that the new value is already
+  // considered to be retained (by the semantics of the storage type),
+  // and we're transferring that ownership count into the destination.
+
+  // This is basically TypeLowering::emitStoreOfCopy, except that if we have
+  // a known incoming value, we can avoid the load.
+  SILValue IncomingVal =
+      B.createLoad(Loc, Inst->getDest(), LoadOwnershipQualifier::Take);
+  B.createStore(Inst->getLoc(), Src, Inst->getDest(),
+                StoreOwnershipQualifier::Init);
+
+  B.emitDestroyValueOperation(Loc, IncomingVal);
+  Inst->eraseFromParent();
+}
diff --git a/lib/SILOptimizer/Mandatory/MandatoryOptUtils.h b/lib/SILOptimizer/Mandatory/MandatoryOptUtils.h
new file mode 100644
index 0000000..f9c02f4
--- /dev/null
+++ b/lib/SILOptimizer/Mandatory/MandatoryOptUtils.h
@@ -0,0 +1,46 @@
+//===--- MandatoryOptUtils.h ----------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+///
+/// Contains utility operations used by various mandatory passes.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef SWIFT_SILOPTIMIZER_MANDATORY_MANDATORYOOPTUTILS_H
+#define SWIFT_SILOPTIMIZER_MANDATORY_MANDATORYOOPTUTILS_H
+
+#include "llvm/Support/Compiler.h"
+
+namespace swift {
+
+class SILBuilderWithScope;
+class AssignInst;
+
+enum class PartialInitializationKind {
+  /// The box contains a fully-initialized value.
+  IsNotInitialization,
+
+  /// The box contains a class instance that we own, but the instance has
+  /// not been initialized and should be freed with a special SIL
+  /// instruction made for this purpose.
+  IsReinitialization,
+
+  /// The box contains an undefined value that should be ignored.
+  IsInitialization,
+};
+
+void lowerAssignInstruction(SILBuilderWithScope &B, AssignInst *Inst,
+                            PartialInitializationKind isInitialization)
+    LLVM_LIBRARY_VISIBILITY;
+
+} // namespace swift
+
+#endif
diff --git a/lib/SILOptimizer/Mandatory/RawSILInstLowering.cpp b/lib/SILOptimizer/Mandatory/RawSILInstLowering.cpp
new file mode 100644
index 0000000..235b504
--- /dev/null
+++ b/lib/SILOptimizer/Mandatory/RawSILInstLowering.cpp
@@ -0,0 +1,89 @@
+//===--- RawSILInstLowering.cpp -------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#include "MandatoryOptUtils.h"
+#include "swift/SIL/SILBuilder.h"
+#include "swift/SIL/SILFunction.h"
+#include "swift/SIL/SILInstruction.h"
+#include "swift/SILOptimizer/PassManager/Passes.h"
+#include "swift/SILOptimizer/PassManager/Transforms.h"
+
+using namespace swift;
+
+/// lowerRawSILOperations - There are a variety of raw-sil instructions like
+/// 'assign' that are only used by this pass.  Now that definite initialization
+/// checking is done, remove them.
+static bool lowerRawSILOperations(SILFunction &Fn) {
+  bool Changed = false;
+  for (auto &BB : Fn) {
+    auto I = BB.begin(), E = BB.end();
+    while (I != E) {
+      SILInstruction *Inst = &*I;
+      ++I;
+
+      // Unprocessed assigns just lower into assignments, not initializations.
+      if (auto *AI = dyn_cast<AssignInst>(Inst)) {
+        SILBuilderWithScope B(AI);
+        lowerAssignInstruction(B, AI,
+                               PartialInitializationKind::IsNotInitialization);
+        // Assign lowering may split the block. If it did,
+        // reset our iteration range to the block after the insertion.
+        if (B.getInsertionBB() != &BB)
+          I = E;
+        Changed = true;
+        continue;
+      }
+
+      // mark_uninitialized just becomes a noop, resolving to its operand.
+      if (auto *MUI = dyn_cast<MarkUninitializedInst>(Inst)) {
+        MUI->replaceAllUsesWith(MUI->getOperand());
+        MUI->eraseFromParent();
+        Changed = true;
+        continue;
+      }
+
+      // mark_function_escape just gets zapped.
+      if (isa<MarkFunctionEscapeInst>(Inst)) {
+        Inst->eraseFromParent();
+        Changed = true;
+        continue;
+      }
+    }
+  }
+  return Changed;
+}
+
+//===----------------------------------------------------------------------===//
+//                            Top Level Entrypoint
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class RawSILInstLowering : public SILFunctionTransform {
+  void run() override {
+    // Do not try to relower raw instructions in canonical SIL. There won't be
+    // any there.
+    if (getFunction()->wasDeserializedCanonical()) {
+      return;
+    }
+
+    // Lower raw-sil only instructions used by this pass, like "assign".
+    if (lowerRawSILOperations(*getFunction()))
+      invalidateAnalysis(SILAnalysis::InvalidationKind::FunctionBody);
+  }
+};
+
+} // end anonymous namespace
+
+SILTransform *swift::createRawSILInstLowering() {
+  return new RawSILInstLowering();
+}
diff --git a/lib/SILOptimizer/PassManager/PassPipeline.cpp b/lib/SILOptimizer/PassManager/PassPipeline.cpp
index 04b8955..3e6a280 100644
--- a/lib/SILOptimizer/PassManager/PassPipeline.cpp
+++ b/lib/SILOptimizer/PassManager/PassPipeline.cpp
@@ -71,6 +71,14 @@
   P.addOwnershipModelEliminator();
 }
 
+/// Passes for performing definite initialization. Must be run together in this
+/// order.
+static void addDefiniteInitialization(SILPassPipelinePlan &P) {
+  P.addMarkUninitializedFixup();
+  P.addDefiniteInitialization();
+  P.addRawSILInstLowering();
+}
+
 static void addMandatoryOptPipeline(SILPassPipelinePlan &P,
                                     const SILOptions &Options) {
   P.startPipeline("Guaranteed Passes");
@@ -86,8 +94,7 @@
 
   P.addAllocBoxToStack();
   P.addNoReturnFolding();
-  P.addMarkUninitializedFixup();
-  P.addDefiniteInitialization();
+  addDefiniteInitialization(P);
   P.addClosureLifetimeFixup();
   P.addOwnershipModelEliminator();
   P.addMandatoryInlining();
diff --git a/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp b/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
index 58ae94f..02502e0 100644
--- a/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
+++ b/lib/SILOptimizer/Transforms/AccessEnforcementOpts.cpp
@@ -30,42 +30,25 @@
 /// DiagnoseStaticExclusivity must be able to fully analyze all @inout_aliasable
 /// parameters because they aren't dynamically enforced. This optimization
 /// completely ignores @inout_aliasable paramters because it only cares about
-/// dynamic enforcement. This optimization also does not attempt to look at
-/// subaccess paths, because it should not weaken enforcement in any way--a
-/// program that traps at -Onone should also trap at -O.
+/// dynamic enforcement. This optimization also does not attempt to
+/// differentiate accesses on disjoint subaccess paths, because it should not
+/// weaken enforcement in any way--a program that traps at -Onone should also
+/// trap at -O.
 ///
-/// AccessFolding is a forward data flow analysis that tracks open accesses. If
+/// Access folding is a forward data flow analysis that tracks open accesses. If
 /// any path to an access' end of scope has a potentially conflicting access,
 /// then that access is marked as a nested conflict.
 ///
 /// Pass order dependencies:
-/// - Benefits from running after AccessEnforcementSelection.
+/// - Will benefit from running after AccessEnforcementSelection.
 ///
 /// TODO: Perform another run of AccessEnforcementSelection immediately before
 /// this pass. Currently, that pass only works well when run before
 /// AllocBox2Stack. Ideally all such closure analysis passes are combined into a
-/// shared anlysis with a set of associated optimizations that can be rerun at
+/// shared analysis with a set of associated optimizations that can be rerun at
 /// any point in the pipeline. Until then, we could settle for a partially
 /// working AccessEnforcementSelection, or expand it somewhat to handle
 /// alloc_stack.
-///
-/// TODO: Add test case. Use SideEffectAnalysis to ignore calls without global
-/// effects. Also scan the arguments to see if there are closure captures. If
-/// this isn't sufficient, add a bit to SideEffectAnalysis for NonlocalAccess.
-///
-/// TODO: Add test case. For Local variables. Ignore global side effects if
-/// none of the intervening calls can access the captured variable.
-///
-/// TODO: Add test case. For Class/Global variables. Ignore global side effects
-/// if callee analysis and interprocedural analysis tell us that none of the
-/// intervening calls access that variable.
-///
-/// TODO: As a separate module pass, find global/class accesses to properties
-/// that are never passed "reentrantly". That optmimization could make use of
-/// the no_nested_conflict flags set in this pass. If *none* of a module-private
-/// variable's accesses have nested conflict, then they can be downgraded to
-/// static checks en masse.
-///
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "access-enforcement-opts"
@@ -81,13 +64,23 @@
 using namespace swift;
 
 namespace swift {
+/// Represents the identity of a storage location being accessed.
+///
 /// A value-based subclass of AccessedStorage with identical layout. This
 /// provides access to pass-specific data in reserved bits.
 ///
-/// The fully-qualified class name allows for the declaration of bitfields in
-/// AccessedStorage. In this file, it is aliased to AccessInfo.
+/// The fully descriptive class name allows forward declaration in order to
+/// define bitfields in AccessedStorage.
+///
+/// Aliased to AccessInfo in this file.
 class AccessEnforcementOptsInfo : public AccessedStorage {
 public:
+  AccessEnforcementOptsInfo(const AccessedStorage &storage)
+    : AccessedStorage(storage) {
+    Bits.AccessEnforcementOptsInfo.beginAccessIndex = 0;
+    Bits.AccessEnforcementOptsInfo.seenNestedConflict = false;
+  }
+
   /// Get a unique index for this access within its function.
   unsigned getAccessIndex() const {
     return Bits.AccessEnforcementOptsInfo.beginAccessIndex;
@@ -114,19 +107,20 @@
                  << (seenNestedConflict() ? "" : "no ") << "conflict>\n";
   }
 };
+using AccessInfo = AccessEnforcementOptsInfo;
 } // namespace swift
 
-using AccessInfo = AccessEnforcementOptsInfo;
-
 namespace {
+// Sparse access sets are used temporarily for fast operations by local
+// reachability analysis. We don't care if they take more space.
 class SparseAccessSet;
 
-/// A dense set of begin_[unpaired_]access instructions... because very few
-/// accesses are typically in-progress at a particular program point,
-/// particularly at block boundaries.
+/// A dense set of begin_access instructions as a compact vector. Reachability
+/// results are stored here because very few accesses are typically in-progress
+/// at a particular program point, particularly at block boundaries.
 using DenseAccessSet = SmallVector<BeginAccessInst *, 4>;
 
-/// Perform the access folding optimization on a function.
+/// Analyze a function's formal access to determine nested conflicts.
 ///
 /// Maps each begin access instruction to its AccessInfo, which:
 /// - identifies the accessed memory for conflict detection
@@ -136,9 +130,9 @@
 ///
 /// If, after computing reachability, an access' conflict flag is still not set,
 /// then all paths in its scope are conflict free. Reachability begins at a
-/// begin_[unpaired_]access instruction and ends either at a potential conflict
-/// or at the end_[unpaired_]access instruction that is associated with the
-/// begin access.
+/// begin_access instruction and ends either at a potential conflict
+/// or at the end_access instruction that is associated with the
+/// begin_access.
 ///
 /// Forward data flow computes `blockOutAccess` for each block. At a control
 /// flow merge, this analysis forms an intersection of reachable accesses on
@@ -149,47 +143,60 @@
 /// when a block is first visited, blockOutAccess contains the maximal
 /// reachability set. Further iteration would only reduce this set.
 ///
-/// The only result of this analysis used by the optimization is the conflict
-/// flag in AccessInfo. Since reducing a reachability set cannot further
-/// detect conflicts, there is no need to iterate to a reachability fix point.
-class AccessFolding {
-  friend class SparseAccessSet;
+/// The only result of this analysis is the seenNestedConflict flags in
+/// AccessInfo. Since reducing a reachability set cannot further detect
+/// conflicts, there is no need to iterate to a reachability fix point.
+class AccessConflictAnalysis {
+public:
+  using AccessMap = llvm::SmallDenseMap<BeginAccessInst *, AccessInfo, 32>;
+  // This result of this analysis is a map from all BeginAccessInst in this
+  // function to AccessInfo.
+  struct Result {
+    /// Map each begin access to its AccessInfo with index, data, and flags.
+    /// Iterating over this map is nondeterministic. If it is necessary to order
+    /// the accesses, then AccessInfo::getAccessIndex() can be used.
+    AccessMap accessMap;
 
+    /// Convenience.
+    ///
+    /// Note: If AccessInfo has already been retrieved, get the index directly
+    /// from it instead of calling this to avoid additional hash lookup.
+    unsigned getAccessIndex(BeginAccessInst *beginAccess) const {
+      return getAccessInfo(beginAccess).getAccessIndex();
+    }
+
+    /// Get the AccessInfo for a BeginAccessInst within this function. All
+    /// accesses are mapped by identifyBeginAccesses().
+    AccessInfo &getAccessInfo(BeginAccessInst *beginAccess) {
+      auto iter = accessMap.find(beginAccess);
+      assert(iter != accessMap.end());
+      return iter->second;
+    }
+    const AccessInfo &getAccessInfo(BeginAccessInst *beginAccess) const {
+      return const_cast<Result &>(*this).getAccessInfo(beginAccess);
+    }
+  };
+
+private:
   SILFunction *F;
   PostOrderFunctionInfo *PO;
   AccessedStorageAnalysis *ASA;
 
-  /// Map each begin access to its index, data, and flags.
-  llvm::SmallDenseMap<BeginAccessInst *, AccessInfo, 32> beginAccessMap;
-
-  /// Tracks the in-progress accesses at the end of each block.
+  /// Tracks the in-scope accesses at the end of each block, for the purpose of
+  /// finding nested conflicts.  (Out-of-scope accesses are currently only
+  /// tracked locally for the purpose of merging access scopes.)
   llvm::SmallDenseMap<SILBasicBlock *, DenseAccessSet, 32> blockOutAccess;
 
+  Result result;
+
 public:
-  AccessFolding(SILFunction *F, PostOrderFunctionInfo *PO,
-                AccessedStorageAnalysis *ASA)
+  AccessConflictAnalysis(SILFunction *F, PostOrderFunctionInfo *PO,
+                         AccessedStorageAnalysis *ASA)
       : F(F), PO(PO), ASA(ASA) {}
 
-  void perform();
+  Result &&analyze() &&;
 
 protected:
-  /// Get the AccessInfo for a BeginAccessInst within this function. All
-  /// accesses are mapped by identifyBeginAccesses().
-  AccessInfo &getAccessInfo(BeginAccessInst *beginAccess) {
-    auto iter = beginAccessMap.find(beginAccess);
-    assert(iter != beginAccessMap.end());
-    return iter->second;
-  }
-  const AccessInfo &getAccessInfo(BeginAccessInst *beginAccess) const {
-    return const_cast<AccessFolding &>(*this).getAccessInfo(beginAccess);
-  }
-
-  /// Convenience. If AccessInfo has already been retrieved, get the index
-  /// directly from it instead of calling this to avoid additional hash lookup.
-  unsigned getAccessIndex(BeginAccessInst *beginAccess) const {
-    return getAccessInfo(beginAccess).getAccessIndex();
-  }
-
   void identifyBeginAccesses();
 
   void visitBeginAccess(BeginAccessInst *beginAccess,
@@ -203,8 +210,6 @@
                          SparseAccessSet &mergedAccesses);
 
   void visitBlock(SILBasicBlock *BB);
-
-  void foldNonNestedAccesses();
 };
 
 /// A sparse set of in-flight accesses.
@@ -212,96 +217,134 @@
 /// Explodes a DenseAccessSet into a temporary sparse set for comparison
 /// and membership.
 ///
-/// The AccessFolding pass provides the instruction to index mapping. Rather
-/// than having all instances of SparseAccessSet reference the pass, it is only
-/// passed in for the operations that require it.
+/// The AccessConflictAnalysis result provides the instruction to index
+/// mapping.
 class SparseAccessSet {
-  llvm::SmallBitVector bitmask; // Most functions have < 64 accesses.
-  DenseAccessSet denseVec;
+  AccessConflictAnalysis::Result &result;
+
+  // Mark the in-scope accesses.
+  // (Most functions have < 64 accesses.)
+  llvm::SmallBitVector inScopeBitmask;
+  // Mark a potential conflicts on each access since the last begin/end marker.
+  llvm::SmallBitVector conflictBitmask;
+  DenseAccessSet denseVec; // Hold all local accesses seen thus far.
 
 public:
-  /// Internally, the denseVec may contain entries that have been removed from
-  /// the bitmask. Iteration checks for membership in the bitmask.
-  class Iterator {
-    const AccessFolding &pass;
+  /// Iterate over in-scope, conflict free access.
+  class NoNestedConflictIterator {
     const SparseAccessSet &sparseSet;
     DenseAccessSet::const_iterator denseIter;
 
   public:
-    Iterator(const SparseAccessSet &set, const AccessFolding &pass)
-        : pass(pass), sparseSet(set), denseIter(set.denseVec.begin()) {}
+    NoNestedConflictIterator(const SparseAccessSet &set)
+        : sparseSet(set), denseIter(set.denseVec.begin()) {}
 
     BeginAccessInst *next() {
       auto end = sparseSet.denseVec.end();
       while (denseIter != end) {
         BeginAccessInst *beginAccess = *denseIter;
         ++denseIter;
-        unsigned sparseIndex = pass.getAccessIndex(beginAccess);
-        if (sparseSet.bitmask[sparseIndex])
+        unsigned sparseIndex = sparseSet.result.getAccessIndex(beginAccess);
+        if (sparseSet.inScopeBitmask[sparseIndex]
+            && !sparseSet.conflictBitmask[sparseIndex]) {
           return beginAccess;
+        }
       }
       return nullptr;
     }
   };
 
-  SparseAccessSet(AccessFolding &pass) : bitmask(pass.beginAccessMap.size()) {}
+  SparseAccessSet(AccessConflictAnalysis::Result &result)
+      : result(result), inScopeBitmask(result.accessMap.size()),
+        conflictBitmask(result.accessMap.size()) {}
 
-  SparseAccessSet(const DenseAccessSet &denseVec, AccessFolding &pass)
-      : bitmask(pass.beginAccessMap.size()), denseVec(denseVec) {
+  // All accessed in the given denseVec are presumed to be in-scope and conflict
+  // free.
+  SparseAccessSet(const DenseAccessSet &denseVec,
+                  AccessConflictAnalysis::Result &result)
+      : result(result), inScopeBitmask(result.accessMap.size()),
+        conflictBitmask(result.accessMap.size()), denseVec(denseVec) {
     for (BeginAccessInst *beginAccess : denseVec)
-      bitmask.set(pass.getAccessIndex(beginAccess));
+      inScopeBitmask.set(result.getAccessIndex(beginAccess));
   }
-
-  bool isEmpty(AccessFolding &pass) const {
-    Iterator iterator(*this, pass);
+  bool hasConflictFreeAccess() const {
+    NoNestedConflictIterator iterator(*this);
     return iterator.next() == nullptr;
   }
 
-  bool contains(unsigned index) const { return bitmask[index]; }
+  bool hasInScopeAccess() const {
+    return llvm::any_of(denseVec, [this](BeginAccessInst *beginAccess) {
+      unsigned sparseIndex = result.getAccessIndex(beginAccess);
+      return inScopeBitmask[sparseIndex];
+    });
+  }
+
+  bool isInScope(unsigned index) const { return inScopeBitmask[index]; }
 
   // Insert the given BeginAccessInst with its corresponding reachability index.
-  // Return true if the set was expanded.
-  bool insert(BeginAccessInst *beginAccess, unsigned index) {
-    if (bitmask[index])
-      return false;
-
-    bitmask.set(index);
+  // Set the in-scope bit and reset the conflict bit.
+  bool enterScope(BeginAccessInst *beginAccess, unsigned index) {
+    assert(!inScopeBitmask[index]
+           && "nested access should not be dynamically enforced.");
+    inScopeBitmask.set(index);
+    conflictBitmask.reset(index);
     denseVec.push_back(beginAccess);
     return true;
   }
 
-  /// Erase an access from this set based on the index provided by its mapped
-  /// AccessInfo.
-  ///
-  /// Does not invalidate Iterator.
-  void erase(unsigned index) { bitmask.reset(index); }
+  /// End the scope of the given access by marking it in-scope and clearing the
+  /// conflict bit. (The conflict bit only marks conflicts since the last begin
+  /// *or* end access).
+  void exitScope(unsigned index) { inScopeBitmask.reset(index); }
 
-  bool isEquivalent(const SparseAccessSet &other) const {
-    return bitmask == other.bitmask;
-  }
+  bool seenConflict(unsigned index) const { return conflictBitmask[index]; }
+
+  void setConflict(unsigned index) { conflictBitmask.set(index); }
 
   // Only merge accesses that are present on the `other` map. i.e. erase
   // all accesses in this map that are not present in `other`.
-  void merge(const SparseAccessSet &other) { bitmask &= other.bitmask; }
-
-  void copyInto(DenseAccessSet &other, AccessFolding &pass) {
-    other.clear();
-    Iterator iterator(*this, pass);
-    while (BeginAccessInst *beginAccess = iterator.next()) {
-      other.push_back(beginAccess);
-    }
+  void merge(const SparseAccessSet &other) {
+    inScopeBitmask &= other.inScopeBitmask;
+    // Currently only conflict free accesses are preserved across blocks by this
+    // analysis. Otherwise, taking the union of conflict bits would be valid.
+    assert(other.conflictBitmask.none());
   }
 
-  void dump(AccessFolding &pass) const {
-    Iterator iterator(*this, pass);
-    while (BeginAccessInst *beginAccess = iterator.next()) {
+  void copyNoNestedConflictInto(DenseAccessSet &other) {
+    other.clear();
+    NoNestedConflictIterator iterator(*this);
+    while (BeginAccessInst *beginAccess = iterator.next())
+      other.push_back(beginAccess);
+  }
+
+  // Dump only the accesses with no conflict up to this point.
+  void dump() const {
+    for (BeginAccessInst *beginAccess : denseVec) {
+      unsigned sparseIndex = result.getAccessIndex(beginAccess);
+      if (conflictBitmask[sparseIndex])
+        continue;
+
       llvm::dbgs() << *beginAccess << "  ";
-      pass.getAccessInfo(beginAccess).dump();
+      if (!inScopeBitmask[sparseIndex])
+        llvm::dbgs() << " [noscope]";
+      result.getAccessInfo(beginAccess).dump();
     }
   }
 };
 } // namespace
 
+// Top-level driver for AccessConflictAnalysis.
+AccessConflictAnalysis::Result &&AccessConflictAnalysis::analyze() && {
+  // Populate beginAccessMap.
+  identifyBeginAccesses();
+
+  // Perform data flow and set the conflict flags on AccessInfo.
+  for (auto *BB : PO->getReversePostOrder())
+    visitBlock(BB);
+
+  return std::move(result);
+}
+
 // Find all begin access operations in this function. Map each access to
 // AccessInfo, which includes its identified memory location, identifying
 // index, and analysis result flags.
@@ -310,30 +353,33 @@
 // isn't explicitly paired, it may be possible after devirtualization and
 // inlining to find all uses of the scratch buffer. However, this doesn't
 // currently happen in practice (rdar://40033735).
-void AccessFolding::identifyBeginAccesses() {
+void AccessConflictAnalysis::identifyBeginAccesses() {
   for (auto &BB : *F) {
     for (auto &I : BB) {
       auto *beginAccess = dyn_cast<BeginAccessInst>(&I);
       if (!beginAccess)
         continue;
 
+      if (beginAccess->getEnforcement() != SILAccessEnforcement::Dynamic)
+        continue;
+
       // The accessed base is expected to be valid for begin_access, but for
       // now, since this optimization runs at the end of the pipeline, we
-      // gracefully handle unrecognized source address patterns, which show up
+      // gracefully ignore unrecognized source address patterns, which show up
       // here as an invalid `storage` value.
       const AccessedStorage &storage =
           findAccessedStorageNonNested(beginAccess->getSource());
       if (!storage)
         continue;
 
-      auto iterAndSuccess = beginAccessMap.try_emplace(
+      auto iterAndSuccess = result.accessMap.try_emplace(
           beginAccess, static_cast<const AccessInfo &>(storage));
       (void)iterAndSuccess;
       assert(iterAndSuccess.second);
 
       // Add a pass-specific access index to the mapped storage object.
       AccessInfo &info = iterAndSuccess.first->second;
-      info.setAccessIndex(beginAccessMap.size()-1);
+      info.setAccessIndex(result.accessMap.size() - 1);
       assert(!info.seenNestedConflict());
     }
   }
@@ -344,7 +390,7 @@
 /// conflicts. Erasing from SparseAccessSet does not invalidate any iterators.
 static void recordConflict(AccessInfo &info, SparseAccessSet &accessSet) {
   info.setSeenNestedConflict();
-  accessSet.erase(info.getAccessIndex());
+  accessSet.setConflict(info.getAccessIndex());
 }
 
 // Given an "inner" access, check for potential conflicts with any outer access.
@@ -357,22 +403,22 @@
 //
 // Record the inner access in the accessSet.
 //
-void AccessFolding::visitBeginAccess(BeginAccessInst *innerBeginAccess,
-                                     SparseAccessSet &accessSet) {
+void AccessConflictAnalysis::visitBeginAccess(BeginAccessInst *innerBeginAccess,
+                                              SparseAccessSet &accessSet) {
   if (innerBeginAccess->getEnforcement() != SILAccessEnforcement::Dynamic)
     return;
 
-  const AccessInfo &innerAccess = getAccessInfo(innerBeginAccess);
+  const AccessInfo &innerAccess = result.getAccessInfo(innerBeginAccess);
   SILAccessKind innerAccessKind = innerBeginAccess->getAccessKind();
 
-  SparseAccessSet::Iterator accessIter(accessSet, *this);
+  SparseAccessSet::NoNestedConflictIterator accessIter(accessSet);
   while (BeginAccessInst *outerBeginAccess = accessIter.next()) {
     // If both are reads, keep the mapped access.
     if (!accessKindMayConflict(innerAccessKind,
                                outerBeginAccess->getAccessKind())) {
       continue;
     }
-    AccessInfo &outerAccess = getAccessInfo(outerBeginAccess);
+    AccessInfo &outerAccess = result.getAccessInfo(outerBeginAccess);
 
     // If there is no potential conflict, leave the outer access mapped.
     if (!outerAccess.isDistinctFrom(innerAccess))
@@ -389,38 +435,38 @@
   // Record the current access in the map. It can potentially be folded
   // regardless of whether it may conflict with an outer access.
   bool inserted =
-      accessSet.insert(innerBeginAccess, innerAccess.getAccessIndex());
+      accessSet.enterScope(innerBeginAccess, innerAccess.getAccessIndex());
   (void)inserted;
   assert(inserted && "the same begin_access cannot be seen twice.");
 }
 
-void AccessFolding::visitEndAccess(EndAccessInst *endAccess,
+void AccessConflictAnalysis::visitEndAccess(EndAccessInst *endAccess,
                                    SparseAccessSet &accessSet) {
   auto *beginAccess = endAccess->getBeginAccess();
   if (beginAccess->getEnforcement() != SILAccessEnforcement::Dynamic)
     return;
 
-  unsigned index = getAccessIndex(beginAccess);
-  DEBUG(if (accessSet.contains(index)) llvm::dbgs()
+  unsigned index = result.getAccessIndex(beginAccess);
+  DEBUG(if (accessSet.seenConflict(index)) llvm::dbgs()
         << "No conflict on one path from " << *beginAccess << " to "
         << *endAccess);
 
   // Erase this access from the sparse set. We only want to detect conflicts
   // within the access scope.
-  accessSet.erase(index);
+  accessSet.exitScope(index);
 }
 
-void AccessFolding::visitFullApply(FullApplySite fullApply,
+void AccessConflictAnalysis::visitFullApply(FullApplySite fullApply,
                                    SparseAccessSet &accessSet) {
   FunctionAccessedStorage callSiteAccesses;
   ASA->getCallSiteEffects(callSiteAccesses, fullApply);
 
-  SparseAccessSet::Iterator accessIter(accessSet, *this);
+  SparseAccessSet::NoNestedConflictIterator accessIter(accessSet);
   while (BeginAccessInst *outerBeginAccess = accessIter.next()) {
 
     // If there is no potential conflict, leave the outer access mapped.
     SILAccessKind accessKind = outerBeginAccess->getAccessKind();
-    AccessInfo &outerAccess = getAccessInfo(outerBeginAccess);
+    AccessInfo &outerAccess = result.getAccessInfo(outerBeginAccess);
     if (!callSiteAccesses.mayConflictWith(accessKind, outerAccess))
       continue;
 
@@ -436,7 +482,7 @@
 // accesses that are still present in all predecessors. The absence of a begin
 // access from a visited predecessor indicates the presence of a conflict. A
 // block has been visited if it has a map entry in blockOutAccess.
-void AccessFolding::mergePredAccesses(SILBasicBlock *succBB,
+void AccessConflictAnalysis::mergePredAccesses(SILBasicBlock *succBB,
                                       SparseAccessSet &mergedAccesses) {
   for (SILBasicBlock *predBB : succBB->getPredecessorBlocks()) {
     auto mapI = blockOutAccess.find(predBB);
@@ -444,14 +490,14 @@
       continue;
 
     const DenseAccessSet &predSet = mapI->second;
-    mergedAccesses.merge(SparseAccessSet(predSet, *this));
+    mergedAccesses.merge(SparseAccessSet(predSet, result));
   }
 }
 
 // Compute access reachability within the given block.
-void AccessFolding::visitBlock(SILBasicBlock *BB) {
+void AccessConflictAnalysis::visitBlock(SILBasicBlock *BB) {
   // Sparse set for tracking accesses with an individual block.
-  SparseAccessSet accessSet(*this);
+  SparseAccessSet accessSet(result);
   mergePredAccesses(BB, accessSet);
 
   for (auto &I : *BB) {
@@ -467,29 +513,38 @@
       visitFullApply(fullApply, accessSet);
     }
   }
-  if (BB->getTerminator()->isFunctionExiting())
-    assert(accessSet.isEquivalent(*this) && "no postdominating end_access");
-
-  DEBUG(if (!accessSet.isEmpty(*this)) {
-    llvm::dbgs() << "Initializing accesses out of bb" << BB->getDebugID()
-                 << "\n";
-    accessSet.dump(*this);
+  DEBUG(if (accessSet.hasConflictFreeAccess()) {
+    llvm::dbgs() << "Initializing no-conflict access out of bb"
+                 << BB->getDebugID() << "\n";
+    accessSet.dump();
   });
+  if (BB->getTerminator()->isFunctionExiting())
+    assert(!accessSet.hasInScopeAccess() && "no postdominating end_access");
 
   // Initialize blockOutAccess for this block with the current access set.
-  accessSet.copyInto(blockOutAccess[BB], *this);
+  accessSet.copyNoNestedConflictInto(blockOutAccess[BB]);
 }
 
-// Data-flow analysis is now complete. Any begin_access remaining in
-// nonNestedBeginAccessInstructions can be marked "non-nested".
-//
-// Note: If we later support marking begin_unpaired_access [no_nested_conflict],
-// then we also need to remove any corresponding end_unpaired_access. That can
-// be done either by recording the end_unpaired_access instructions during
-// analysis and deleting them here in the same order, or sorting them here by
-// their begin_unpaired_access index.
-void AccessFolding::foldNonNestedAccesses() {
-  for (auto &beginAccessAndInfo : beginAccessMap) {
+// -----------------------------------------------------------------------------
+// MARK: Access Enforcement Optimization
+// -----------------------------------------------------------------------------
+
+/// Perform access folding.
+///
+/// Data-flow analysis is now complete. Any begin_access that has seen a
+/// conflict can be given the [no_nested_conflict] instruction attribute.
+///
+/// Note: If we later support marking begin_unpaired_access
+/// [no_nested_conflict], then we also need to remove any corresponding
+/// end_unpaired_access. That can be done either by recording the
+/// end_unpaired_access instructions during analysis and deleting them here in
+/// the same order, or sorting them here by their begin_unpaired_access index.
+static bool
+foldNonNestedAccesses(AccessConflictAnalysis::AccessMap &accessMap) {
+  bool changed = false;
+  // Iteration over accessMap is nondeterministic. Setting the conflict flags
+  // can be done in any order.
+  for (auto &beginAccessAndInfo : accessMap) {
     BeginAccessInst *beginAccess = beginAccessAndInfo.first;
     AccessInfo &info = beginAccessAndInfo.second;
     if (info.seenNestedConflict())
@@ -497,20 +552,48 @@
 
     // Optimize this begin_access by setting [no_nested_conflict].
     beginAccess->setNoNestedConflict(true);
+    changed = true;
+    DEBUG(llvm::dbgs() << "Folding " << *beginAccess);
   }
+  return changed;
 }
 
-// Top-level driver for AccessFolding forward data flow optimization.
-void AccessFolding::perform() {
-  // Populate beginAccessMap.
-  identifyBeginAccesses();
+/// Eliminate accesses to uniquely identified local storage for which no
+/// accesses can have nested conflicts. This is only valid if the function's
+/// local storage cannot be potentially modified by unidentified access.
+///
+/// This simply invalidates the AccessMap result rather than erasing individual
+/// entries.
+static bool
+removeLocalNonNestedAccess(AccessConflictAnalysis::Result &&result,
+                           const FunctionAccessedStorage &functionAccess) {
+  if (functionAccess.hasUnidentifiedAccess())
+    return false;
 
-  // Perform data flow and set the conflict flags on AccessInfo.
-  for (auto *BB : PO->getReversePostOrder())
-    visitBlock(BB);
+  bool changed = false;
+  SmallVector<BeginAccessInst *, 8> deadAccesses;
+  for (auto &beginAccessAndInfo : result.accessMap) {
+    BeginAccessInst *beginAccess = beginAccessAndInfo.first;
+    AccessInfo &info = beginAccessAndInfo.second;
+    if (info.seenNestedConflict() || !info.isLocal())
+      continue;
 
-  // Fold any accesses that don't have nested conflicts.
-  foldNonNestedAccesses();
+    // This particular access to local storage is marked
+    // [no_nested_conflict]. Now check FunctionAccessedStorage to determine if
+    // that is true for all access to the same storage.
+    if (functionAccess.hasNoNestedConflict(info))
+      deadAccesses.push_back(beginAccess);
+  }
+  std::sort(deadAccesses.begin(), deadAccesses.end(),
+            [&result](BeginAccessInst *a, BeginAccessInst *b) {
+              return result.getAccessIndex(a) < result.getAccessIndex(b);
+            });
+  for (BeginAccessInst *beginAccess : deadAccesses) {
+    DEBUG(llvm::dbgs() << "Removing dead access " << *beginAccess);
+    changed = true;
+    removeBeginAccess(beginAccess);
+  }
+  return changed;
 }
 
 namespace {
@@ -520,15 +603,33 @@
     if (F->empty())
       return;
 
-    // Perform access folding. May mark begin_access with no_nested_conflict and
-    // may removed end_unpaired_access.
     PostOrderFunctionInfo *PO = getAnalysis<PostOrderAnalysis>()->get(F);
     AccessedStorageAnalysis *ASA = getAnalysis<AccessedStorageAnalysis>();
-    AccessFolding folding(F, PO, ASA);
-    folding.perform();
+    auto result = AccessConflictAnalysis(F, PO, ASA).analyze();
+
+    // Perform access folding by setting the [no_nested_conflict] flag on
+    // begin_access instructions.
+    if (!foldNonNestedAccesses(result.accessMap))
+      return;
+
+    // Recompute AccessStorageAnalysis, just for this function, to update the
+    // StorageAccessInfo::noNestedConflict status for each accessed storage.
+    invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
+
+    // Use the updated AccessedStorageAnalysis to find any uniquely identified
+    // local storage that has no nested conflict on any of its accesses within
+    // this function. These can be removed entirely.
+    //
+    // Note that the storage address may be passed as an argument and there may
+    // be nested conflicts within that call, but none of the accesses within
+    // this function will overlap.
+    const FunctionAccessedStorage &functionAccess = ASA->getEffects(F);
+    if (removeLocalNonNestedAccess(std::move(result), functionAccess))
+      invalidateAnalysis(SILAnalysis::InvalidationKind::Instructions);
+    // `result` is now invalid.
   }
 };
-}
+} // namespace
 
 SILTransform *swift::createAccessEnforcementOpts() {
   return new AccessEnforcementOpts();
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 993b651..1674ec3 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -2670,7 +2670,7 @@
         ApplyExpr *apply = CallExpr::create(
             tc.Context, result, arg, expr->getArgumentLabels(),
             expr->getArgumentLabelLocs(), expr->hasTrailingClosure(),
-            /*implicit=*/false, Type(), getType);
+            /*implicit=*/expr->isImplicit(), Type(), getType);
         result = finishApply(apply, Type(), cs.getConstraintLocator(expr));
       }
 
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 6f4651d..b6513af 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -1002,6 +1002,10 @@
 
   bool diagnoseSubscriptErrors(SubscriptExpr *SE, bool performingSet);
 
+  /// Diagnose the usage of 'subscript' instead of the operator when calling
+  /// a subscript and offer a fixit if the inputs are compatible.
+  bool diagnoseSubscriptMisuse(ApplyExpr *callExpr);
+
   bool visitExpr(Expr *E);
   bool visitIdentityExpr(IdentityExpr *E);
   bool visitTryExpr(TryExpr *E);
@@ -5434,6 +5438,144 @@
   return false;
 }
 
+bool FailureDiagnosis::diagnoseSubscriptMisuse(ApplyExpr *callExpr) {
+  auto UDE = dyn_cast<UnresolvedDotExpr>(callExpr->getFn());
+  if (!UDE)
+    return false;
+
+  auto baseExpr = UDE->getBase();
+  if (!baseExpr || UDE->getName().getBaseName() != getTokenText(tok::kw_subscript))
+    return false;
+
+  auto baseType = CS.getType(baseExpr);
+  // Look up subscript declarations.
+  auto lookup = CS.lookupMember(baseType->getRValueType(),
+                                DeclName(DeclBaseName::createSubscript()));
+  auto nonSubscrLookup = CS.lookupMember(baseType->getRValueType(),
+                                         UDE->getName());
+  // Make sure we only found subscript declarations. If not, the problem
+  // is different - return.
+  if (lookup.empty() || !nonSubscrLookup.empty())
+    return false;
+  // Try to resolve a type of the argument expression.
+  auto argExpr = typeCheckChildIndependently(callExpr->getArg(),
+                                             Type(), CTP_CallArgument);
+  if (!argExpr)
+    return CS.TC.Diags.hadAnyError();
+
+  SmallVector<Identifier, 2> scratch;
+  ArrayRef<Identifier> argLabels = callExpr->getArgumentLabels(scratch);
+  SmallVector<OverloadChoice, 2> choices;
+
+  for (auto candidate : lookup)
+    choices.push_back(OverloadChoice(baseType, candidate.getValueDecl(),
+                                     UDE->getFunctionRefKind()));
+  CalleeCandidateInfo candidateInfo(baseType, choices,
+                                    callArgHasTrailingClosure(argExpr),
+                                    CS, true);
+  struct TypeConvertibleChecker {
+    ConstraintSystem &CS;
+
+    TypeConvertibleChecker(ConstraintSystem &CS) : CS(CS) {}
+
+    // Checks whether type1 is implicitly convertible to type2
+    bool isImplicitlyConvertible(Type type1, Type type2) {
+      if (!type1 || !type2)
+        return false;
+
+      if (auto tup1 = type1->getAs<TupleType>()) {
+        if (auto tup2 = type2->getAs<TupleType>())
+          return isImplicitlyConvertibleTuple(tup1, tup2);
+        else
+          return false;
+      }
+      if (type1->isEqual(type2) || type2->is<GenericTypeParamType>() ||
+          CS.TC.isSubtypeOf(type1, type2, CS.DC))
+        return true;
+      return false;
+    }
+
+    bool isImplicitlyConvertibleTuple(TupleType *tup1, TupleType *tup2) {
+      if (tup1->getNumElements() != tup2->getNumElements())
+        return false;
+
+      for (unsigned i = 0, e = tup1->getNumElements(); i < e; i ++) {
+        auto element1 = tup1->getElement(i);
+        auto element2 = tup2->getElement(i);
+        if (element1.hasName()) {
+          if (!element2.hasName() || element1.getName() !=
+              element2.getName())
+            return false;
+        }
+        if (!isImplicitlyConvertible(element1.getType(),
+                                     element2.getType()))
+          return false;
+      }
+      return true;
+    }
+  } checker(CS);
+  auto params = swift::decomposeArgType(CS.getType(argExpr), argLabels);
+  using ClosenessPair = CalleeCandidateInfo::ClosenessResultTy;
+
+  candidateInfo.filterList([&](UncurriedCandidate cand) -> ClosenessPair {
+    auto candFuncType = cand.getUncurriedFunctionType();
+    if (!candFuncType)
+      return {CC_GeneralMismatch, {}};
+
+    auto candParams = candFuncType->getParams();
+    if (params.size() != candParams.size())
+      return {CC_GeneralMismatch, {}};
+
+    for (unsigned i = 0, e = params.size(); i < e; i ++) {
+      if (checker.isImplicitlyConvertible(params[i].getType(),
+                                          candParams[i].getType()))
+        continue;
+      return {CC_GeneralMismatch, {}};
+    }
+    return {CC_ExactMatch, {}};
+  });
+
+  auto *locator = CS.getConstraintLocator(UDE, ConstraintLocator::Member);
+  auto memberRange = baseExpr->getSourceRange();
+  if (locator)
+    locator = simplifyLocator(CS, locator, memberRange);
+  auto nameLoc = DeclNameLoc(memberRange.Start);
+
+  auto diag = diagnose(baseExpr->getLoc(),
+                       diag::could_not_find_subscript_member_did_you_mean,
+                       baseType);
+  diag.highlight(memberRange).highlight(nameLoc.getSourceRange());
+
+  auto showNote = [&]() {
+    diag.flush();
+    if (candidateInfo.size() == 1)
+      diagnose(candidateInfo.candidates.front().getDecl(),
+               diag::kind_declared_here, DescriptiveDeclKind::Subscript);
+  };
+  if (candidateInfo.closeness != CC_ExactMatch) {
+    showNote();
+    return true;
+  }
+  auto toCharSourceRange = Lexer::getCharSourceRangeFromSourceRange;
+  auto lastArgSymbol = toCharSourceRange(CS.TC.Context.SourceMgr,
+                                         argExpr->getEndLoc());
+
+  diag.fixItReplace(SourceRange(argExpr->getStartLoc()),
+                    getTokenText(tok::l_square));
+  diag.fixItRemove(nameLoc.getSourceRange());
+  diag.fixItRemove(SourceRange(UDE->getDotLoc()));
+  if (CS.TC.Context.SourceMgr.extractText(lastArgSymbol) ==
+      getTokenText(tok::r_paren))
+    diag.fixItReplace(SourceRange(argExpr->getEndLoc()),
+                      getTokenText(tok::r_square));
+  else
+    diag.fixItInsertAfter(argExpr->getEndLoc(),
+                          getTokenText(tok::r_square));
+  showNote();
+
+  return true;
+}
+
 // Check if there is a structural problem in the function expression
 // by performing type checking with the option to allow unresolved
 // type variables. If that is going to produce a function type with
@@ -5480,11 +5622,18 @@
   auto originalFnType = CS.getType(callExpr->getFn());
 
   if (shouldTypeCheckFunctionExpr(CS.TC, CS.DC, fnExpr)) {
+
+    // If we are misusing a subscript, diagnose that and provide a fixit.
+    // We diagnose this here to have enough context to offer an appropriate fixit.
+    if (diagnoseSubscriptMisuse(callExpr)) {
+      return CS.TC.Diags.hadAnyError();
+    }
     // Type check the function subexpression to resolve a type for it if
     // possible.
     fnExpr = typeCheckChildIndependently(callExpr->getFn());
-    if (!fnExpr)
-      return true;
+    if (!fnExpr) {
+      return CS.TC.Diags.hadAnyError();
+    }
   }
 
   SWIFT_DEFER {
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 1ac031c..4d04dc5 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -1592,8 +1592,8 @@
                         false)
               .highlight(SourceRange(expr->getLAngleLoc(),
                                      expr->getRAngleLoc()));
-            tc.diagnose(bgt->getDecl(), diag::generic_type_declared_here,
-                        bgt->getDecl()->getName());
+            tc.diagnose(bgt->getDecl(), diag::kind_identifier_declared_here,
+                        DescriptiveDeclKind::GenericType, bgt->getDecl()->getName());
             return Type();
           }
 
diff --git a/lib/Sema/CSSolver.cpp b/lib/Sema/CSSolver.cpp
index 83585f9..0c84f2a 100644
--- a/lib/Sema/CSSolver.cpp
+++ b/lib/Sema/CSSolver.cpp
@@ -1802,15 +1802,96 @@
   return false;
 }
 
+// Attempt to find a disjunction of bind constraints where all options
+// in the disjunction are binding the same type variable.
+//
+// Prefer disjunctions where the bound type variable is also the
+// right-hand side of a conversion constraint, since having a concrete
+// type that we're converting to can make it possible to split the
+// constraint system into multiple ones.
+static Constraint *selectBestBindingDisjunction(
+    ConstraintSystem &cs, SmallVectorImpl<Constraint *> &disjunctions) {
+
+  // Collect any disjunctions that simply attempt bindings for a
+  // type variable.
+  SmallVector<Constraint *, 8> bindingDisjunctions;
+  for (auto *disjunction : disjunctions) {
+    llvm::Optional<TypeVariableType *> commonTypeVariable;
+    if (llvm::all_of(
+            disjunction->getNestedConstraints(),
+            [&](Constraint *bindingConstraint) {
+              if (bindingConstraint->getKind() != ConstraintKind::Bind)
+                return false;
+
+              auto *tv =
+                  bindingConstraint->getFirstType()->getAs<TypeVariableType>();
+              // Only do this for simple type variable bindings, not for
+              // bindings like: ($T1) -> $T2 bind String -> Int
+              if (!tv)
+                return false;
+
+              if (!commonTypeVariable.hasValue())
+                commonTypeVariable = tv;
+
+              if (commonTypeVariable.getValue() != tv)
+                return false;
+
+              return true;
+            })) {
+      bindingDisjunctions.push_back(disjunction);
+    }
+  }
+
+  for (auto *disjunction : bindingDisjunctions) {
+    auto nested = disjunction->getNestedConstraints();
+    assert(!nested.empty());
+    auto *tv = cs.simplifyType(nested[0]->getFirstType())
+                   ->getRValueType()
+                   ->getAs<TypeVariableType>();
+    assert(tv);
+
+    SmallVector<Constraint *, 8> constraints;
+    cs.getConstraintGraph().gatherConstraints(
+        tv, constraints, ConstraintGraph::GatheringKind::EquivalenceClass);
+
+    for (auto *constraint : constraints) {
+      if (constraint->getKind() != ConstraintKind::Conversion)
+        continue;
+
+      auto toType =
+          cs.simplifyType(constraint->getSecondType())->getRValueType();
+      auto *toTV = toType->getAs<TypeVariableType>();
+      if (tv != toTV)
+        continue;
+
+      return disjunction;
+    }
+  }
+
+  // If we had any binding disjunctions, return the first of
+  // those. These ensure that we attempt to bind types earlier than
+  // trying the elements of other disjunctions, which can often mean
+  // we fail faster.
+  if (!bindingDisjunctions.empty())
+    return bindingDisjunctions[0];
+
+  return nullptr;
+}
+
 Constraint *ConstraintSystem::selectDisjunction(
     SmallVectorImpl<Constraint *> &disjunctions) {
   if (disjunctions.empty())
     return nullptr;
 
+  auto *disjunction =
+      selectBestBindingDisjunction(*this, disjunctions);
+  if (disjunction)
+    return disjunction;
+
   // Pick the smallest disjunction.
   // FIXME: This heuristic isn't great, but it helped somewhat for
   // overload sets.
-  auto disjunction = disjunctions[0];
+  disjunction = disjunctions[0];
   auto bestSize = disjunction->countActiveNestedConstraints();
   if (bestSize > 2) {
     for (auto contender : llvm::makeArrayRef(disjunctions).slice(1)) {
diff --git a/lib/Sema/CalleeCandidateInfo.cpp b/lib/Sema/CalleeCandidateInfo.cpp
index 1c31a5b..ef25107 100644
--- a/lib/Sema/CalleeCandidateInfo.cpp
+++ b/lib/Sema/CalleeCandidateInfo.cpp
@@ -835,7 +835,7 @@
     // the uncurry level is 1 if self has already been applied.
     unsigned uncurryLevel = 0;
     if (decl->getDeclContext()->isTypeContext() &&
-        selfAlreadyApplied)
+        selfAlreadyApplied && !isa<SubscriptDecl>(decl))
       uncurryLevel = 1;
     
     candidates.push_back({ decl, uncurryLevel });
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index ccdb26a..d28b0c5 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -1738,11 +1738,9 @@
             TC.diagnose(behavior->getLoc(),
                         diag::property_behavior_protocol_reqt_ambiguous,
                         TC.Context.Id_value);
-            TC.diagnose(valueProp->getLoc(),
-                        diag::property_behavior_protocol_reqt_here,
+            TC.diagnose(valueProp->getLoc(), diag::identifier_declared_here,
                         TC.Context.Id_value);
-            TC.diagnose(foundVar->getLoc(),
-                        diag::property_behavior_protocol_reqt_here,
+            TC.diagnose(foundVar->getLoc(), diag::identifier_declared_here,
                         TC.Context.Id_value);
             break;
           }
@@ -2026,6 +2024,12 @@
     }
   }
 
+  // Inherit the @discardableResult attribute.
+  if (superclassCtor->getAttrs().hasAttribute<DiscardableResultAttr>()) {
+    auto *clonedAttr = new (ctx) DiscardableResultAttr(/*implicit=*/true);
+    ctor->getAttrs().add(clonedAttr);
+  }
+
   // Make sure the constructor is only as available as its superclass's
   // constructor.
   AvailabilityInference::applyInferredAvailableAttrs(ctor, superclassCtor, ctx);
diff --git a/lib/Sema/DerivedConformances.cpp b/lib/Sema/DerivedConformances.cpp
index 223155e..b114d6b 100644
--- a/lib/Sema/DerivedConformances.cpp
+++ b/lib/Sema/DerivedConformances.cpp
@@ -402,7 +402,8 @@
     TC.diagnose(ConformanceDecl->getLoc(),
                 diag::cannot_synthesize_in_crossfile_extension,
                 getProtocolType());
-    TC.diagnose(Nominal->getLoc(), diag::type_declared_here);
+    TC.diagnose(Nominal->getLoc(), diag::kind_declared_here,
+                DescriptiveDeclKind::Type);
     return true;
   }
 
diff --git a/lib/Sema/TypeCheckCaptures.cpp b/lib/Sema/TypeCheckCaptures.cpp
index c9fe99c..20df65a 100644
--- a/lib/Sema/TypeCheckCaptures.cpp
+++ b/lib/Sema/TypeCheckCaptures.cpp
@@ -271,7 +271,8 @@
                         NTD->getDescriptiveKind(),
                         D->getBaseName().getIdentifier());
 
-            TC.diagnose(NTD->getLoc(), diag::type_declared_here);
+            TC.diagnose(NTD->getLoc(), diag::kind_declared_here,
+                        DescriptiveDeclKind::Type);
 
             TC.diagnose(D, diag::decl_declared_here, D->getFullName());
             return { false, DRE };
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 869657c..e1f3f93 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -707,7 +707,7 @@
 template<typename T>
 static void checkCircularity(TypeChecker &tc, T *decl,
                              Diag<StringRef> circularDiag,
-                             Diag<Identifier> declHereDiag,
+                             DescriptiveDeclKind declKind,
                              SmallVectorImpl<T *> &path) {
   switch (decl->getCircularityCheck()) {
   case CircularityCheck::Checked:
@@ -750,7 +750,8 @@
     // Diagnose the cycle.
     tc.diagnose(decl->getLoc(), circularDiag, pathStr);
     for (auto i = cycleStart + 1, iEnd = path.end(); i != iEnd; ++i) {
-      tc.diagnose(*i, declHereDiag, (*i)->getName());
+      tc.diagnose(*i, diag::kind_identifier_declared_here,
+                  declKind, (*i)->getName());
     }
 
     // Set this declaration as invalid, then break the cycle somehow.
@@ -766,7 +767,7 @@
     decl->setCircularityCheck(CircularityCheck::Checking);
     T *scratch = nullptr;
     for (auto inherited : getInheritedForCycleCheck(tc, decl, &scratch)) {
-      checkCircularity(tc, inherited, circularDiag, declHereDiag, path);
+      checkCircularity(tc, inherited, circularDiag, declKind, path);
     }
     decl->setCircularityCheck(CircularityCheck::Checked);
     path.pop_back();
@@ -1835,7 +1836,7 @@
 
   if (auto CITR = dyn_cast<ComponentIdentTypeRepr>(complainRepr)) {
     const ValueDecl *VD = CITR->getBoundDecl();
-    TC.diagnose(VD, diag::type_declared_here);
+    TC.diagnose(VD, diag::kind_declared_here, DescriptiveDeclKind::Type);
   }
 }
 
@@ -3428,11 +3429,9 @@
                       diag::property_behavior_protocol_reqt_ambiguous,
                       TC.Context.Id_initStorage);
           TC.diagnose(defaultInitStorageDecl->getLoc(),
-                      diag::property_behavior_protocol_reqt_here,
-                      TC.Context.Id_initStorage);
+                      diag::identifier_declared_here, TC.Context.Id_initStorage);
           TC.diagnose(parameterizedInitStorageDecl->getLoc(),
-                      diag::property_behavior_protocol_reqt_here,
-                      TC.Context.Id_initStorage);
+                      diag::identifier_declared_here, TC.Context.Id_initStorage);
           conformance->setInvalid();
           continue;
         }
@@ -3501,8 +3500,7 @@
           TC.diagnose(behavior->getLoc(),
                       diag::property_behavior_invalid_parameter_reqt,
                       behaviorProto->getName());
-          TC.diagnose(varReqt->getLoc(),
-                      diag::property_behavior_protocol_reqt_here,
+          TC.diagnose(varReqt->getLoc(), diag::identifier_declared_here,
                       TC.Context.Id_parameter);
           conformance->setInvalid();
           continue;
@@ -3772,7 +3770,8 @@
             == dc->getParentModule()) {
         if (!PGD->isInvalid()) {
           diagnose(rel.NameLoc, diag::precedence_group_lower_within_module);
-          diagnose(group->getNameLoc(), diag::precedence_group_declared_here);
+          diagnose(group->getNameLoc(), diag::kind_declared_here,
+                   DescriptiveDeclKind::PrecedenceGroup);
           isInvalid = true;
         }
       } else {
@@ -4476,7 +4475,7 @@
       SmallVector<EnumDecl *, 8> path;
       path.push_back(ED);
       checkCircularity(TC, ED, diag::circular_enum_inheritance,
-                       diag::enum_here, path);
+                       DescriptiveDeclKind::Enum, path);
     }
 
     for (Decl *member : ED->getMembers())
@@ -4636,7 +4635,7 @@
       SmallVector<ClassDecl *, 8> path;
       path.push_back(CD);
       checkCircularity(TC, CD, diag::circular_class_inheritance,
-                       diag::class_here, path);
+                       DescriptiveDeclKind::Class, path);
     }
 
     for (Decl *Member : CD->getMembers())
@@ -4760,7 +4759,7 @@
       SmallVector<ProtocolDecl *, 8> path;
       path.push_back(PD);
       checkCircularity(TC, PD, diag::circular_protocol_def,
-                       diag::protocol_here, path);
+                       DescriptiveDeclKind::Protocol, path);
 
       // Make sure the parent protocols have been fully validated.
       for (auto inherited : PD->getLocalProtocols()) {
@@ -6877,7 +6876,7 @@
         if (mentionsItself) {
           diagnose(defaultDefinition.getLoc(), diag::recursive_type_reference,
                    assocType->getDescriptiveKind(), assocType->getName());
-          diagnose(assocType, diag::type_declared_here);
+          diagnose(assocType, diag::kind_declared_here, DescriptiveDeclKind::Type);
         }
       }
     }
@@ -7007,8 +7006,8 @@
           diagnose(proto->getLoc(),
                    diag::objc_protocol_inherits_non_objc_protocol,
                    proto->getDeclaredType(), inherited->getDeclaredType());
-          diagnose(inherited->getLoc(), diag::protocol_here,
-                   inherited->getName());
+          diagnose(inherited->getLoc(), diag::kind_identifier_declared_here,
+                   DescriptiveDeclKind::Protocol, inherited->getName());
           isObjC = None;
         }
       }
diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp
index 33b36ee..a85f440 100644
--- a/lib/Sema/TypeCheckProtocol.cpp
+++ b/lib/Sema/TypeCheckProtocol.cpp
@@ -2732,9 +2732,9 @@
             }
           }
 
-          diags.diagnose(requirement, diag::protocol_requirement_here,
+          diags.diagnose(requirement, diag::kind_declname_declared_here,
+                         DescriptiveDeclKind::Requirement,
                          requirement->getFullName());
-
         });
     }
 
@@ -2835,7 +2835,8 @@
             }
           }
 
-          diags.diagnose(requirement, diag::protocol_requirement_here,
+          diags.diagnose(requirement, diag::kind_declname_declared_here,
+                         DescriptiveDeclKind::Requirement,
                          requirement->getFullName());
       });
       break;
@@ -2873,7 +2874,8 @@
                          witness->getFullName(),
                          conformance->getProtocol()->getFullName());
           emitDeclaredHereIfNeeded(diags, diagLoc, witness);
-          diags.diagnose(requirement, diag::protocol_requirement_here,
+          diags.diagnose(requirement, diag::kind_declname_declared_here,
+                         DescriptiveDeclKind::Requirement,
                          requirement->getFullName());
         });
       break;
@@ -3516,7 +3518,8 @@
                            "@nonobjc ");
           }
 
-          TC.diagnose(requirement, diag::protocol_requirement_here,
+          TC.diagnose(requirement, diag::kind_declname_declared_here,
+                      DescriptiveDeclKind::Requirement,
                       requirement->getFullName());
 
           Conformance->setInvalid();
@@ -4484,7 +4487,8 @@
       .fixItInsert(witness->getAttributeInsertionLoc(false), "@nonobjc ");
   }
 
-  tc.diagnose(req, diag::protocol_requirement_here, req->getFullName());
+  tc.diagnose(req, diag::kind_declname_declared_here,
+              DescriptiveDeclKind::Requirement, req->getFullName());
 }
 
 /// Whether the given protocol is "NSCoding".
diff --git a/lib/Sema/TypeCheckSwitchStmt.cpp b/lib/Sema/TypeCheckSwitchStmt.cpp
index b2fcbed..b2cf0c9 100644
--- a/lib/Sema/TypeCheckSwitchStmt.cpp
+++ b/lib/Sema/TypeCheckSwitchStmt.cpp
@@ -377,18 +377,14 @@
 
           // (_ : Ty1) <= (_ : Ty2) iff D(Ty1) == D(Ty2)
           if (canDecompose(this->getType(), DC)) {
-            SmallVector<Space, 4> disjuncts;
-            decompose(TC, DC, this->getType(), disjuncts);
-            Space or1Space = Space::forDisjunct(disjuncts);
+            Space or1Space = decompose(TC, DC, this->getType());
             if (or1Space.isSubspace(other, TC, DC)) {
               return true;
             }
           }
 
           if (canDecompose(other.getType(), DC)) {
-            SmallVector<Space, 4> disjuncts;
-            decompose(TC, DC, other.getType(), disjuncts);
-            Space or2Space = Space::forDisjunct(disjuncts);
+            Space or2Space = decompose(TC, DC, other.getType());
             return this->isSubspace(or2Space, TC, DC);
           }
 
@@ -406,17 +402,13 @@
           if (!canDecompose(this->getType(), DC)) {
             return false;
           }
-          SmallVector<Space, 4> disjuncts;
-          decompose(TC, DC, this->getType(), disjuncts);
-          Space or1Space = Space::forDisjunct(disjuncts);
+          Space or1Space = decompose(TC, DC, this->getType());
           return or1Space.isSubspace(other, TC, DC);
         }
         PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
           // (_ : Ty1) <= H(p1 | ... | pn) iff D(Ty1) <= H(p1 | ... | pn)
           if (canDecompose(this->getType(), DC)) {
-            SmallVector<Space, 4> disjuncts;
-            decompose(TC, DC, this->getType(), disjuncts);
-            Space or1Space = Space::forDisjunct(disjuncts);
+            Space or1Space = decompose(TC, DC, this->getType());
             return or1Space.isSubspace(other, TC, DC);
           }
           // An undecomposable type is always larger than its constructor space.
@@ -501,6 +493,11 @@
         }
       }
 
+      static Space intersect(const Space &a, const Space &b, TypeChecker &TC,
+                             const DeclContext *DC) {
+        return a.intersect(b, TC, DC).simplify(TC, DC);
+      }
+
       // Returns the intersection of this space with another.  The intersection
       // is the largest shared subspace occupied by both arguments.
       Space intersect(const Space &other, TypeChecker &TC,
@@ -519,11 +516,10 @@
         PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Disjunct): {
           // S & (S1 || ... || Sn) iff (S & S1) && ... && (S & Sn)
           SmallVector<Space, 4> intersectedCases;
-          std::transform(other.getSpaces().begin(), other.getSpaces().end(),
-                         std::back_inserter(intersectedCases),
-                         [&](const Space &s) {
-            return this->intersect(s, TC, DC);
-          });
+          std::transform(
+              other.getSpaces().begin(), other.getSpaces().end(),
+              std::back_inserter(intersectedCases),
+              [&](const Space &s) { return intersect(*this, s, TC, DC); });
           return Space::forDisjunct(intersectedCases);
         }
 
@@ -533,38 +529,26 @@
         PAIRCASE (SpaceKind::Disjunct, SpaceKind::BooleanConstant):
         PAIRCASE (SpaceKind::Disjunct, SpaceKind::UnknownCase): {
           // (S1 || ... || Sn) & S iff (S & S1) && ... && (S & Sn)
-          SmallVector<Space, 4> intersectedCases;
-          std::transform(this->getSpaces().begin(), this->getSpaces().end(),
-                         std::back_inserter(intersectedCases),
-                         [&](const Space &s) {
-            return s.intersect(other, TC, DC);
-          });
-          return Space::forDisjunct(intersectedCases);
+          return intersect(other, *this, TC, DC);
         }
         PAIRCASE (SpaceKind::Type, SpaceKind::Type): {
           // Optimization: The intersection of equal types is that type.
           if (this->getType()->isEqual(other.getType())) {
             return other;
           } else if (canDecompose(this->getType(), DC)) {
-            SmallVector<Space, 4> spaces;
-            decompose(TC, DC, this->getType(), spaces);
-            auto decomposition = Space::forDisjunct(spaces);
-            return decomposition.intersect(other, TC, DC);
+            auto decomposition = decompose(TC, DC, this->getType());
+            return intersect(decomposition, other, TC, DC);
           } else if (canDecompose(other.getType(), DC)) {
-            SmallVector<Space, 4> spaces;
-            decompose(TC, DC, other.getType(), spaces);
-            auto disjunctSp = Space::forDisjunct(spaces);
-            return this->intersect(disjunctSp, TC, DC);
+            auto decomposition = decompose(TC, DC, other.getType());
+            return intersect(*this, decomposition, TC, DC);
           } else {
             return other;
           }
         }
         PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
           if (canDecompose(this->getType(), DC)) {
-            SmallVector<Space, 4> spaces;
-            decompose(TC, DC, this->getType(), spaces);
-            auto decomposition = Space::forDisjunct(spaces);
-            return decomposition.intersect(other, TC, DC);
+            auto decomposition = decompose(TC, DC, this->getType());
+            return intersect(decomposition, other, TC, DC);
           } else {
             return other;
           }
@@ -582,10 +566,11 @@
 
         PAIRCASE (SpaceKind::Constructor, SpaceKind::UnknownCase): {
           SmallVector<Space, 4> newSubSpaces;
-          for (auto subSpace : this->getSpaces()) {
-            Space nextSpace = subSpace.intersect(other, TC, DC);
-            newSubSpaces.push_back(nextSpace.simplify(TC, DC));
-          }
+          std::transform(this->getSpaces().begin(), this->getSpaces().end(),
+                         std::back_inserter(newSubSpaces),
+                         [&](const Space &subSpace) {
+                           return intersect(subSpace, other, TC, DC);
+                         });
           return Space::forConstructor(this->getType(), this->getHead(),
                                        this->canDowngradeToWarning(),
                                        newSubSpaces);
@@ -609,13 +594,13 @@
           auto j = other.getSpaces().begin();
           for (; i != this->getSpaces().end() && j != other.getSpaces().end();
                ++i, ++j) {
-            auto intersection = (*i).intersect(*j, TC, DC).simplify(TC, DC);
+            auto result = intersect(*i, *j, TC, DC);
             // If at least one of the constructor sub-spaces is empty,
             // it makes the whole space empty as well.
-            if (intersection.isEmpty()) {
+            if (result.isEmpty()) {
               return Space();
             }
-            paramSpace.push_back(intersection);
+            paramSpace.push_back(result);
           }
 
           return Space::forDisjunct(paramSpace);
@@ -623,7 +608,7 @@
 
         PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Type):
         PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Constructor):
-          return other.intersect(*this, TC, DC);
+          return intersect(other, *this, TC, DC);
         PAIRCASE (SpaceKind::UnknownCase, SpaceKind::UnknownCase):
           if (other.isAllowedButNotRequired())
             return other;
@@ -638,10 +623,8 @@
           }
 
           if (canDecompose(other.getType(), DC)) {
-            SmallVector<Space, 4> spaces;
-            decompose(TC, DC, other.getType(), spaces);
-            auto disjunctSp = Space::forDisjunct(spaces);
-            return this->intersect(disjunctSp, TC, DC);
+            auto decomposition = decompose(TC, DC, other.getType());
+            return intersect(*this, decomposition, TC, DC);
           }
           return Space();
         }
@@ -651,14 +634,7 @@
           return Space();
 
         PAIRCASE (SpaceKind::Type, SpaceKind::BooleanConstant): {
-          if (canDecompose(this->getType(), DC)) {
-            SmallVector<Space, 4> spaces;
-            decompose(TC, DC, this->getType(), spaces);
-            auto disjunctSp = Space::forDisjunct(spaces);
-            return disjunctSp.intersect(other, TC, DC);
-          } else {
-            return Space();
-          }
+          return intersect(other, *this, TC, DC);
         }
 
         PAIRCASE (SpaceKind::Empty, SpaceKind::BooleanConstant):
@@ -701,23 +677,18 @@
           if (this->getType()->isEqual(other.getType())) {
             return Space();
           } else if (canDecompose(this->getType(), DC)) {
-            SmallVector<Space, 4> spaces;
-            this->decompose(TC, DC, this->getType(), spaces);
-            return Space::forDisjunct(spaces).intersect(other, TC, DC);
+            auto decomposition = decompose(TC, DC, this->getType());
+            return intersect(decomposition, other, TC, DC);
           } else if (canDecompose(other.getType(), DC)) {
-            SmallVector<Space, 4> spaces;
-            this->decompose(TC, DC, other.getType(), spaces);
-            auto decomp = Space::forDisjunct(spaces);
-            return this->intersect(decomp, TC, DC);
+            auto decomposition = decompose(TC, DC, other.getType());
+            return intersect(*this, decomposition, TC, DC);
           }
           return Space();
         }
         PAIRCASE (SpaceKind::Type, SpaceKind::Constructor): {
           if (canDecompose(this->getType(), DC)) {
-            SmallVector<Space, 4> spaces;
-            this->decompose(TC, DC, this->getType(), spaces);
-            auto decomp = Space::forDisjunct(spaces);
-            return decomp.minus(other, TC, DC, minusCount);
+            auto decomposition = decompose(TC, DC, this->getType());
+            return decomposition.minus(other, TC, DC, minusCount);
           } else {
             return *this;
           }
@@ -802,7 +773,7 @@
             auto &s2 = *j;
             // If the intersection of each subspace is ever empty then the
             // two spaces are disjoint and their difference is the first space.
-            if (s1.intersect(s2, TC, DC).simplify(TC, DC).isEmpty()) {
+            if (intersect(s1, s2, TC, DC).isEmpty()) {
               return *this;
             }
 
@@ -862,10 +833,8 @@
           }
 
           if (canDecompose(other.getType(), DC)) {
-            SmallVector<Space, 4> spaces;
-            this->decompose(TC, DC, other.getType(), spaces);
-            auto disjunctSp = Space::forDisjunct(spaces);
-            return this->minus(disjunctSp, TC, DC, minusCount);
+            auto decomposition = decompose(TC, DC, other.getType());
+            return this->minus(decomposition, TC, DC, minusCount);
           }
           return *this;
         }
@@ -876,9 +845,7 @@
 
         PAIRCASE (SpaceKind::Type, SpaceKind::BooleanConstant): {
           if (canDecompose(this->getType(), DC)) {
-            SmallVector<Space, 4> spaces;
-            this->decompose(TC, DC, this->getType(), spaces);
-            auto orSpace = Space::forDisjunct(spaces);
+            auto orSpace = decompose(TC, DC, this->getType());
             return orSpace.minus(other, TC, DC, minusCount);
           } else {
             return *this;
@@ -1117,6 +1084,13 @@
         }
       }
 
+      static Space decompose(TypeChecker &TC, const DeclContext *DC,
+                             Type type) {
+        SmallVector<Space, 4> spaces;
+        decompose(TC, DC, type, spaces);
+        return Space::forDisjunct(spaces);
+      }
+
       static bool canDecompose(Type tp, const DeclContext *DC) {
         return tp->is<TupleType>() || tp->isBool() ||
                tp->getEnumOrBoundGenericEnum();
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index ba411d2..3b23afd 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -460,8 +460,8 @@
              genericParams->size(), genericArgs.size(),
              genericArgs.size() < genericParams->size())
         .highlight(generic->getAngleBrackets());
-    diagnose(decl, diag::generic_type_declared_here,
-             decl->getName());
+    diagnose(decl, diag::kind_identifier_declared_here,
+             DescriptiveDeclKind::GenericType, decl->getName());
     return ErrorType::get(Context);
   }
 
@@ -495,7 +495,8 @@
   if (!genericDecl->hasValidSignature()) {
     diagnose(loc, diag::recursive_type_reference,
              genericDecl->getDescriptiveKind(), genericDecl->getName());
-    diagnose(genericDecl, diag::type_declared_here);
+    diagnose(genericDecl, diag::kind_declared_here,
+             DescriptiveDeclKind::Type);
     return ErrorType::get(Context);
   }
 
@@ -671,8 +672,8 @@
         diag.fixItInsertAfter(loc, genericArgsToAdd);
     }
   }
-  tc.diagnose(unbound->getDecl(), diag::generic_type_declared_here,
-              unbound->getDecl()->getName());
+  tc.diagnose(unbound->getDecl(), diag::kind_identifier_declared_here,
+              DescriptiveDeclKind::GenericType, unbound->getDecl()->getName());
 }
 
 // Produce a diagnostic if the type we referenced was an
@@ -730,7 +731,8 @@
     if (!typeDecl->hasInterfaceType()) {
       TC.diagnose(loc, diag::recursive_type_reference,
                   typeDecl->getDescriptiveKind(), typeDecl->getName());
-      TC.diagnose(typeDecl->getLoc(), diag::type_declared_here);
+      TC.diagnose(typeDecl->getLoc(), diag::kind_declared_here,
+                  DescriptiveDeclKind::Type);
       return ErrorType::get(TC.Context);
     }
   }
@@ -871,7 +873,8 @@
       // FIXME: If any of the candidates (usually just one) are in the same
       // module we could offer a fix-it.
       for (auto lookupResult : inaccessibleResults)
-        tc.diagnose(lookupResult.getValueDecl(), diag::type_declared_here);
+        tc.diagnose(lookupResult.getValueDecl(), diag::kind_declared_here,
+                    DescriptiveDeclKind::Type);
 
       // Don't try to recover here; we'll get more access-related diagnostics
       // downstream if we do.
@@ -937,7 +940,8 @@
     // FIXME: If any of the candidates (usually just one) are in the same module
     // we could offer a fix-it.
     for (auto lookupResult : inaccessibleMembers)
-      tc.diagnose(lookupResult.first, diag::type_declared_here);
+      tc.diagnose(lookupResult.first, diag::kind_declared_here,
+                  DescriptiveDeclKind::Type);
 
     // Don't try to recover here; we'll get more access-related diagnostics
     // downstream if we do.
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index 51714c3..831de7e 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -3943,7 +3943,9 @@
 
     unsigned abbrCode = DeclTypeAbbrCodes[UnboundGenericTypeLayout::Code];
     UnboundGenericTypeLayout::emitRecord(Out, ScratchRecord, abbrCode,
-                                         addDeclRef(generic->getDecl()),
+                                         addDeclRef(generic->getDecl(),
+                                                    /*forceSerialization*/false,
+                                                    /*allowTypeAliasXRef*/true),
                                          addTypeRef(generic->getParent()));
     break;
   }
diff --git a/lib/TBDGen/TBDGen.cpp b/lib/TBDGen/TBDGen.cpp
index 9a97e82..0e2aec9 100644
--- a/lib/TBDGen/TBDGen.cpp
+++ b/lib/TBDGen/TBDGen.cpp
@@ -92,28 +92,32 @@
 
     auto conformanceIsFixed = SILWitnessTable::conformanceIsSerialized(
         normalConformance);
-    auto addSymbolIfNecessary = [&](SILDeclRef declRef) {
-      auto witnessLinkage = declRef.getLinkage(ForDefinition);
+    auto addSymbolIfNecessary = [&](ValueDecl *requirementDecl,
+                                    ValueDecl *witnessDecl) {
+      auto witnessLinkage = SILDeclRef(witnessDecl).getLinkage(ForDefinition);
       if (conformanceIsFixed &&
           fixmeWitnessHasLinkageThatNeedsToBePublic(witnessLinkage)) {
         Mangle::ASTMangler Mangler;
-        addSymbol(Mangler.mangleWitnessThunk(normalConformance,
-                                             declRef.getDecl()));
+        addSymbol(
+            Mangler.mangleWitnessThunk(normalConformance, requirementDecl));
       }
     };
-    normalConformance->forEachValueWitness(nullptr, [&](ValueDecl *valueReq,
-                                                        Witness witness) {
-      if (isa<AbstractFunctionDecl>(valueReq)) {
-        addSymbolIfNecessary(SILDeclRef(valueReq));
-      } else if (auto *storage = dyn_cast<AbstractStorageDecl>(valueReq)) {
-        if (auto *getter = storage->getGetter())
-          addSymbolIfNecessary(SILDeclRef(getter));
-        if (auto *setter = storage->getGetter())
-          addSymbolIfNecessary(SILDeclRef(setter));
-        if (auto *materializeForSet = storage->getMaterializeForSetFunc())
-          addSymbolIfNecessary(SILDeclRef(materializeForSet));
-      }
-    });
+    normalConformance->forEachValueWitness(
+        nullptr, [&](ValueDecl *valueReq, Witness witness) {
+          auto witnessDecl = witness.getDecl();
+          if (isa<AbstractFunctionDecl>(valueReq)) {
+            addSymbolIfNecessary(valueReq, witnessDecl);
+          } else if (auto *storage = dyn_cast<AbstractStorageDecl>(valueReq)) {
+            auto witnessStorage = cast<AbstractStorageDecl>(witnessDecl);
+            if (auto *getter = storage->getGetter())
+              addSymbolIfNecessary(getter, witnessStorage->getGetter());
+            if (auto *setter = storage->getSetter())
+              addSymbolIfNecessary(setter, witnessStorage->getSetter());
+            if (auto *materializeForSet = storage->getMaterializeForSetFunc())
+              addSymbolIfNecessary(materializeForSet,
+                                   witnessStorage->getMaterializeForSetFunc());
+          }
+        });
   }
 }
 
@@ -146,6 +150,22 @@
   }
 }
 
+void TBDGenVisitor::visitAccessorDecl(AccessorDecl *AD) {
+  // Do nothing: accessors are always nested within the storage decl, but
+  // sometimes appear outside it too. To avoid double-walking them, we
+  // explicitly visit them as members of the storage and ignore them when we
+  // visit them as part of the main walk, here.
+}
+
+void TBDGenVisitor::visitAbstractStorageDecl(AbstractStorageDecl *ASD) {
+  // Explicitly look at each accessor here: see visitAccessorDecl.
+  SmallVector<Decl *, 8> accessors;
+  ASD->getAllAccessorFunctions(accessors);
+  for (auto accessor : accessors) {
+    visitAbstractFunctionDecl(cast<AbstractFunctionDecl>(accessor));
+  }
+}
+
 void TBDGenVisitor::visitVarDecl(VarDecl *VD) {
   // statically/globally stored variables have some special handling.
   if (VD->hasStorage() && isGlobalOrStaticVar(VD)) {
@@ -158,6 +178,8 @@
     if (!FileHasEntryPoint || VD->isStatic())
       addSymbol(SILDeclRef(VD, SILDeclRef::Kind::GlobalAccessor));
   }
+
+  visitAbstractStorageDecl(VD);
 }
 
 void TBDGenVisitor::visitNominalTypeDecl(NominalTypeDecl *NTD) {
@@ -332,18 +354,28 @@
   }
 }
 
+void TBDGenVisitor::addFirstFileSymbols() {
+  if (!Opts.ModuleLinkName.empty()) {
+    SmallString<32> buf;
+    addSymbol(irgen::encodeForceLoadSymbolName(buf, Opts.ModuleLinkName));
+  }
+}
+
 static void enumeratePublicSymbolsAndWrite(ModuleDecl *M, FileUnit *singleFile,
                                            StringSet &symbols,
-                                           bool hasMultipleIGMs,
                                            llvm::raw_ostream *os,
-                                           StringRef installName) {
+                                           TBDGenOptions &opts) {
   auto isWholeModule = singleFile == nullptr;
   const auto &target = M->getASTContext().LangOpts.Target;
-  UniversalLinkageInfo linkInfo(target, hasMultipleIGMs, isWholeModule);
+  UniversalLinkageInfo linkInfo(target, opts.HasMultipleIGMs, isWholeModule);
 
-  TBDGenVisitor visitor(symbols, target, linkInfo, M, installName);
+  TBDGenVisitor visitor(symbols, target, linkInfo, M, opts);
 
   auto visitFile = [&](FileUnit *file) {
+    if (file == M->getFiles()[0]) {
+      visitor.addFirstFileSymbols();
+    }
+
     SmallVector<Decl *, 16> decls;
     file->getTopLevelDecls(decls);
 
@@ -376,18 +408,16 @@
 }
 
 void swift::enumeratePublicSymbols(FileUnit *file, StringSet &symbols,
-                                   bool hasMultipleIGMs) {
+                                   TBDGenOptions &opts) {
   enumeratePublicSymbolsAndWrite(file->getParentModule(), file, symbols,
-                                 hasMultipleIGMs, nullptr, StringRef());
+                                 nullptr, opts);
 }
 void swift::enumeratePublicSymbols(ModuleDecl *M, StringSet &symbols,
-                                   bool hasMultipleIGMs) {
-  enumeratePublicSymbolsAndWrite(M, nullptr, symbols, hasMultipleIGMs, nullptr,
-                                 StringRef());
+                                   TBDGenOptions &opts) {
+  enumeratePublicSymbolsAndWrite(M, nullptr, symbols, nullptr, opts);
 }
 void swift::writeTBDFile(ModuleDecl *M, llvm::raw_ostream &os,
-                         bool hasMultipleIGMs, StringRef installName) {
+                         TBDGenOptions &opts) {
   StringSet symbols;
-  enumeratePublicSymbolsAndWrite(M, nullptr, symbols, hasMultipleIGMs, &os,
-                                 installName);
+  enumeratePublicSymbolsAndWrite(M, nullptr, symbols, &os, opts);
 }
diff --git a/lib/TBDGen/TBDGenVisitor.h b/lib/TBDGen/TBDGenVisitor.h
index 5cbc0d7..741e9c4 100644
--- a/lib/TBDGen/TBDGenVisitor.h
+++ b/lib/TBDGen/TBDGenVisitor.h
@@ -33,6 +33,9 @@
 using StringSet = llvm::StringSet<>;
 
 namespace swift {
+
+struct TBDGenOptions;
+
 namespace tbdgen {
 
 class TBDGenVisitor : public ASTVisitor<TBDGenVisitor> {
@@ -41,7 +44,7 @@
   const llvm::Triple &Triple;
   const UniversalLinkageInfo &UniversalLinkInfo;
   ModuleDecl *SwiftModule;
-  StringRef InstallName;
+  TBDGenOptions &Opts;
 
 private:
   bool FileHasEntryPoint = false;
@@ -73,9 +76,9 @@
 public:
   TBDGenVisitor(StringSet &symbols, const llvm::Triple &triple,
                 const UniversalLinkageInfo &universalLinkInfo,
-                ModuleDecl *swiftModule, StringRef installName)
+                ModuleDecl *swiftModule, TBDGenOptions &opts)
       : Symbols(symbols), Triple(triple), UniversalLinkInfo(universalLinkInfo),
-        SwiftModule(swiftModule), InstallName(installName) {}
+        SwiftModule(swiftModule), Opts(opts) {}
 
   void setFileHasEntryPoint(bool hasEntryPoint) {
     FileHasEntryPoint = hasEntryPoint;
@@ -84,10 +87,15 @@
       addSymbol("main");
   }
 
+  /// \brief Adds the global symbols associated with the first file.
+  void addFirstFileSymbols();
+
   void visitPatternBindingDecl(PatternBindingDecl *PBD);
 
   void visitAbstractFunctionDecl(AbstractFunctionDecl *AFD);
 
+  void visitAccessorDecl(AccessorDecl *AD);
+
   void visitNominalTypeDecl(NominalTypeDecl *NTD);
 
   void visitClassDecl(ClassDecl *CD);
@@ -98,6 +106,8 @@
 
   void visitProtocolDecl(ProtocolDecl *PD);
 
+  void visitAbstractStorageDecl(AbstractStorageDecl *ASD);
+
   void visitVarDecl(VarDecl *VD);
 
   void visitEnumDecl(EnumDecl *ED);
diff --git a/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift b/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift
index 2a717b1..ecb24b6 100644
--- a/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift
+++ b/stdlib/private/SwiftReflectionTest/SwiftReflectionTest.swift
@@ -107,12 +107,12 @@
 ///
 /// An image of interest must have the following sections in the __DATA
 /// segment:
-/// - __swift4_fieldmd
-/// - __swift4_assocty
-/// - __swift4_builtin
-/// - __swift4_capture
-/// - __swift4_typeref
-/// - __swift4_reflstr (optional, may have been stripped out)
+/// - __swift5_fieldmd
+/// - __swift5_assocty
+/// - __swift5_builtin
+/// - __swift5_capture
+/// - __swift5_typeref
+/// - __swift5_reflstr (optional, may have been stripped out)
 ///
 /// - Parameter i: The index of the loaded image as reported by Dyld.
 /// - Returns: A `ReflectionInfo` containing the locations of all of the
@@ -123,12 +123,12 @@
     to: UnsafePointer<MachHeader>.self)
 
   let imageName = _dyld_get_image_name(i)!
-  let fieldmd = getSectionInfo("__swift4_fieldmd", header)
-  let assocty = getSectionInfo("__swift4_assocty", header)
-  let builtin = getSectionInfo("__swift4_builtin", header)
-  let capture = getSectionInfo("__swift4_capture", header)
-  let typeref = getSectionInfo("__swift4_typeref", header)
-  let reflstr = getSectionInfo("__swift4_reflstr", header)
+  let fieldmd = getSectionInfo("__swift5_fieldmd", header)
+  let assocty = getSectionInfo("__swift5_assocty", header)
+  let builtin = getSectionInfo("__swift5_builtin", header)
+  let capture = getSectionInfo("__swift5_capture", header)
+  let typeref = getSectionInfo("__swift5_typeref", header)
+  let reflstr = getSectionInfo("__swift5_reflstr", header)
   return ReflectionInfo(imageName: String(validatingUTF8: imageName)!,
                         fieldmd: fieldmd,
                         assocty: assocty,
diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp
index fc98c18..9863468 100644
--- a/stdlib/public/runtime/Casting.cpp
+++ b/stdlib/public/runtime/Casting.cpp
@@ -1866,7 +1866,7 @@
   // .Some
   // Single payload enums are guaranteed layout compatible with their
   // payload. Only the source's payload needs to be taken or destroyed.
-  return {false, payloadType};
+  return checkDynamicCastFromOptional(dest, src, payloadType, targetType, flags);
 }
 
 /******************************************************************************/
diff --git a/stdlib/public/runtime/Enum.cpp b/stdlib/public/runtime/Enum.cpp
index b30a404..bcdf669 100644
--- a/stdlib/public/runtime/Enum.cpp
+++ b/stdlib/public/runtime/Enum.cpp
@@ -89,12 +89,14 @@
   auto vwtable = getMutableVWTableForInit(self, layoutFlags);
   
   size_t align = payloadLayout->flags.getAlignment();
+  bool isBT = payloadLayout->flags.isBitwiseTakable();
   TypeLayout layout;
   layout.size = size;
-  layout.flags = payloadLayout->flags
-    .withExtraInhabitants(unusedExtraInhabitants > 0)
-    .withEnumWitnesses(true)
-    .withInlineStorage(ValueWitnessTable::isValueInline(size, align));
+  layout.flags =
+      payloadLayout->flags.withExtraInhabitants(unusedExtraInhabitants > 0)
+          .withEnumWitnesses(true)
+          .withInlineStorage(
+              ValueWitnessTable::isValueInline(isBT, size, align));
   auto rawStride = llvm::alignTo(size, align);
   layout.stride = rawStride == 0 ? 1 : rawStride;
   
@@ -200,14 +202,14 @@
   TypeLayout layout;
   layout.size = totalSize;
   layout.flags = ValueWitnessFlags()
-    .withAlignmentMask(alignMask)
-    .withPOD(isPOD)
-    .withBitwiseTakable(isBT)
-    // TODO: Extra inhabitants
-    .withExtraInhabitants(false)
-    .withEnumWitnesses(true)
-    .withInlineStorage(ValueWitnessTable::isValueInline(totalSize, alignMask+1))
-    ;
+                     .withAlignmentMask(alignMask)
+                     .withPOD(isPOD)
+                     .withBitwiseTakable(isBT)
+                     // TODO: Extra inhabitants
+                     .withExtraInhabitants(false)
+                     .withEnumWitnesses(true)
+                     .withInlineStorage(ValueWitnessTable::isValueInline(
+                         isBT, totalSize, alignMask + 1));
   auto rawStride = (totalSize + alignMask) & ~alignMask;
   layout.stride = rawStride == 0 ? 1 : rawStride;
   
diff --git a/stdlib/public/runtime/ExistentialMetadataImpl.h b/stdlib/public/runtime/ExistentialMetadataImpl.h
index 3d849e3..3183b8a 100644
--- a/stdlib/public/runtime/ExistentialMetadataImpl.h
+++ b/stdlib/public/runtime/ExistentialMetadataImpl.h
@@ -107,20 +107,9 @@
   static Container *initializeWithTake(Container *dest, Container *src,
                                        A... args) {
     src->copyTypeInto(dest, args...);
-    auto *type = src->getType();
-    auto *vwt = type->getValueWitnesses();
-
-    if (vwt->isValueInline()) {
-      auto *destValue =
-          reinterpret_cast<OpaqueValue *>(dest->getBuffer(args...));
-      auto *srcValue =
-          reinterpret_cast<OpaqueValue *>(src->getBuffer(args...));
-
-      type->vw_initializeWithTake(destValue, srcValue);
-    } else {
-      // initWithTake of the reference to the cow box.
-      copyReference(dest, src, Dest::Init, Source::Take, args...);
-    }
+    auto from = src->getBuffer(args...);
+    auto to = dest->getBuffer(args...);
+    memcpy(to, from, sizeof(ValueBuffer));
     return dest;
   }
 
@@ -338,7 +327,7 @@
   static constexpr size_t alignment = alignof(Container);
   static constexpr size_t stride = sizeof(Container);
   static constexpr size_t isPOD = false;
-  static constexpr bool isBitwiseTakable = false;
+  static constexpr bool isBitwiseTakable = true;
   static constexpr unsigned numExtraInhabitants = 0;
 };
 
diff --git a/stdlib/public/runtime/ImageInspectionCOFF.cpp b/stdlib/public/runtime/ImageInspectionCOFF.cpp
index 915f827..29fec32 100644
--- a/stdlib/public/runtime/ImageInspectionCOFF.cpp
+++ b/stdlib/public/runtime/ImageInspectionCOFF.cpp
@@ -41,7 +41,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &protocols =
-      sections->swift4_protocols;
+      sections->swift5_protocols;
     if (protocols.length)
       addImageProtocolsBlockCallback(reinterpret_cast<void *>(protocols.start),
                                      protocols.length);
@@ -56,7 +56,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &conformances =
-        sections->swift4_protocol_conformances;
+        sections->swift5_protocol_conformances;
     if (conformances.length)
       addImageProtocolConformanceBlockCallback(reinterpret_cast<void *>(conformances.start),
                                                conformances.length);
@@ -71,7 +71,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &type_metadata =
-        sections->swift4_type_metadata;
+        sections->swift5_type_metadata;
     if (type_metadata.length)
       addImageTypeMetadataRecordBlockCallback(reinterpret_cast<void *>(type_metadata.start),
                                               type_metadata.length);
@@ -85,7 +85,7 @@
 void swift::initializeTypeFieldLookup() {
   const swift::MetadataSections *sections = registered;
   while (true) {
-    const swift::MetadataSections::Range &fields = sections->swift4_fieldmd;
+    const swift::MetadataSections::Range &fields = sections->swift5_fieldmd;
     if (fields.length)
       addImageTypeFieldDescriptorBlockCallback(
           reinterpret_cast<void *>(fields.start), fields.length);
@@ -103,20 +103,20 @@
 
   record(sections);
 
-  const auto &protocols_section = sections->swift4_protocols;
+  const auto &protocols_section = sections->swift5_protocols;
   const void *protocols =
       reinterpret_cast<void *>(protocols_section.start);
   if (protocols_section.length)
     addImageProtocolsBlockCallback(protocols, protocols_section.length);
 
-  const auto &protocol_conformances = sections->swift4_protocol_conformances;
+  const auto &protocol_conformances = sections->swift5_protocol_conformances;
   const void *conformances =
       reinterpret_cast<void *>(protocol_conformances.start);
   if (protocol_conformances.length)
     addImageProtocolConformanceBlockCallback(conformances,
                                              protocol_conformances.length);
 
-  const auto &type_metadata = sections->swift4_type_metadata;
+  const auto &type_metadata = sections->swift5_type_metadata;
   const void *metadata = reinterpret_cast<void *>(type_metadata.start);
   if (type_metadata.length)
     addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
diff --git a/stdlib/public/runtime/ImageInspectionCOFF.h b/stdlib/public/runtime/ImageInspectionCOFF.h
index 2ce5fa6..75e0266 100644
--- a/stdlib/public/runtime/ImageInspectionCOFF.h
+++ b/stdlib/public/runtime/ImageInspectionCOFF.h
@@ -45,13 +45,13 @@
     size_t length;
   };
 
-  Range swift4_protocols;
-  Range swift4_protocol_conformances;
-  Range swift4_type_metadata;
-  Range swift4_typeref;
-  Range swift4_reflstr;
-  Range swift4_fieldmd;
-  Range swift4_assocty;
+  Range swift5_protocols;
+  Range swift5_protocol_conformances;
+  Range swift5_type_metadata;
+  Range swift5_typeref;
+  Range swift5_reflstr;
+  Range swift5_fieldmd;
+  Range swift5_assocty;
 };
 } // namespace swift
 
diff --git a/stdlib/public/runtime/ImageInspectionELF.cpp b/stdlib/public/runtime/ImageInspectionELF.cpp
index 00340c5..3dfe95f 100644
--- a/stdlib/public/runtime/ImageInspectionELF.cpp
+++ b/stdlib/public/runtime/ImageInspectionELF.cpp
@@ -46,7 +46,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &protocols =
-        sections->swift4_protocols;
+        sections->swift5_protocols;
     if (protocols.length)
       addImageProtocolsBlockCallback(reinterpret_cast<void *>(protocols.start),
                                      protocols.length);
@@ -60,7 +60,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &conformances =
-        sections->swift4_protocol_conformances;
+        sections->swift5_protocol_conformances;
     if (conformances.length)
       addImageProtocolConformanceBlockCallback(reinterpret_cast<void *>(conformances.start),
                                                conformances.length);
@@ -75,7 +75,7 @@
   const swift::MetadataSections *sections = registered;
   while (true) {
     const swift::MetadataSections::Range &type_metadata =
-        sections->swift4_type_metadata;
+        sections->swift5_type_metadata;
     if (type_metadata.length)
       addImageTypeMetadataRecordBlockCallback(reinterpret_cast<void *>(type_metadata.start),
                                               type_metadata.length);
@@ -89,7 +89,7 @@
 void swift::initializeTypeFieldLookup() {
   const swift::MetadataSections *sections = registered;
   while (true) {
-    const swift::MetadataSections::Range &fields = sections->swift4_fieldmd;
+    const swift::MetadataSections::Range &fields = sections->swift5_fieldmd;
     if (fields.length)
       addImageTypeFieldDescriptorBlockCallback(
           reinterpret_cast<void *>(fields.start), fields.length);
@@ -111,20 +111,20 @@
 
   record(sections);
 
-  const auto &protocols_section = sections->swift4_protocols;
+  const auto &protocols_section = sections->swift5_protocols;
   const void *protocols =
       reinterpret_cast<void *>(protocols_section.start);
   if (protocols_section.length)
     addImageProtocolsBlockCallback(protocols, protocols_section.length);
 
-  const auto &protocol_conformances = sections->swift4_protocol_conformances;
+  const auto &protocol_conformances = sections->swift5_protocol_conformances;
   const void *conformances =
       reinterpret_cast<void *>(protocol_conformances.start);
   if (protocol_conformances.length)
     addImageProtocolConformanceBlockCallback(conformances,
                                              protocol_conformances.length);
 
-  const auto &type_metadata = sections->swift4_type_metadata;
+  const auto &type_metadata = sections->swift5_type_metadata;
   const void *metadata = reinterpret_cast<void *>(type_metadata.start);
   if (type_metadata.length)
     addImageTypeMetadataRecordBlockCallback(metadata, type_metadata.length);
diff --git a/stdlib/public/runtime/ImageInspectionELF.h b/stdlib/public/runtime/ImageInspectionELF.h
index b88be22..9505360 100644
--- a/stdlib/public/runtime/ImageInspectionELF.h
+++ b/stdlib/public/runtime/ImageInspectionELF.h
@@ -45,13 +45,13 @@
     size_t length;
   };
 
-  Range swift4_protocols;
-  Range swift4_protocol_conformances;
-  Range swift4_type_metadata;
-  Range swift4_typeref;
-  Range swift4_reflstr;
-  Range swift4_fieldmd;
-  Range swift4_assocty;
+  Range swift5_protocols;
+  Range swift5_protocol_conformances;
+  Range swift5_type_metadata;
+  Range swift5_typeref;
+  Range swift5_reflstr;
+  Range swift5_fieldmd;
+  Range swift5_assocty;
 };
 } // namespace swift
 
diff --git a/stdlib/public/runtime/ImageInspectionMachO.cpp b/stdlib/public/runtime/ImageInspectionMachO.cpp
index 2972a8d..f8c86d2 100644
--- a/stdlib/public/runtime/ImageInspectionMachO.cpp
+++ b/stdlib/public/runtime/ImageInspectionMachO.cpp
@@ -31,16 +31,16 @@
 namespace {
 /// The Mach-O section name for the section containing protocol descriptor
 /// references. This lives within SEG_TEXT.
-constexpr const char ProtocolsSection[] = "__swift4_protos";
+constexpr const char ProtocolsSection[] = "__swift5_protos";
 /// The Mach-O section name for the section containing protocol conformances.
 /// This lives within SEG_TEXT.
-constexpr const char ProtocolConformancesSection[] = "__swift4_proto";
+constexpr const char ProtocolConformancesSection[] = "__swift5_proto";
 /// The Mach-O section name for the section containing type references.
 /// This lives within SEG_TEXT.
-constexpr const char TypeMetadataRecordSection[] = "__swift4_types";
+constexpr const char TypeMetadataRecordSection[] = "__swift5_types";
 /// The Mach-O section name for the section containing type field references.
 /// This lives within SEG_TEXT.
-constexpr const char TypeFieldRecordSection[] = "__swift4_fieldmd";
+constexpr const char TypeFieldRecordSection[] = "__swift5_fieldmd";
 
 #if __POINTER_WIDTH__ == 64
 using mach_header_platform = mach_header_64;
@@ -57,7 +57,7 @@
   assert(mh->magic == MH_MAGIC_64 && "loaded non-64-bit image?!");
 #endif
   
-  // Look for a __swift4_proto section.
+  // Look for a __swift5_proto section.
   unsigned long size;
   const uint8_t *section =
   getsectiondata(reinterpret_cast<const mach_header_platform *>(mh),
diff --git a/stdlib/public/runtime/Metadata.cpp b/stdlib/public/runtime/Metadata.cpp
index 2a7a72f..83c0622 100644
--- a/stdlib/public/runtime/Metadata.cpp
+++ b/stdlib/public/runtime/Metadata.cpp
@@ -1057,23 +1057,6 @@
   return tuple_projectBuffer<IsPOD, IsInline>(dest, metatype);
 }
 
-/// Generic tuple value witness for 'initializeBufferWithTakeOfBuffer'.
-template <bool IsPOD, bool IsInline>
-static OpaqueValue *tuple_initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
-                                                           ValueBuffer *src,
-                                                     const Metadata *metatype) {
-  assert(IsPOD == tuple_getValueWitnesses(metatype)->isPOD());
-  assert(IsInline == tuple_getValueWitnesses(metatype)->isValueInline());
-  if (IsInline) {
-    return tuple_initializeWithTake<IsPOD, IsInline>(
-        tuple_projectBuffer<IsPOD, IsInline>(dest, metatype),
-        tuple_projectBuffer<IsPOD, IsInline>(src, metatype), metatype);
-  }
-  auto *srcReference = *reinterpret_cast<HeapObject**>(src);
-  *reinterpret_cast<HeapObject**>(dest) = srcReference;
-  return tuple_projectBuffer<IsPOD, IsInline>(dest, metatype);
-}
-
 template <bool IsPOD, bool IsInline>
 static unsigned tuple_getEnumTagSinglePayload(const OpaqueValue *enumAddr,
                                               unsigned numEmptyCases,
@@ -1215,13 +1198,15 @@
     if (!eltLayout->flags.isPOD()) isPOD = false;
     if (!eltLayout->flags.isBitwiseTakable()) isBitwiseTakable = false;
   }
-  bool isInline = ValueWitnessTable::isValueInline(size, alignMask + 1);
+  bool isInline =
+      ValueWitnessTable::isValueInline(isBitwiseTakable, size, alignMask + 1);
 
   layout.size = size;
-  layout.flags = ValueWitnessFlags().withAlignmentMask(alignMask)
-                                    .withPOD(isPOD)
-                                    .withBitwiseTakable(isBitwiseTakable)
-                                    .withInlineStorage(isInline);
+  layout.flags = ValueWitnessFlags()
+                     .withAlignmentMask(alignMask)
+                     .withPOD(isPOD)
+                     .withBitwiseTakable(isBitwiseTakable)
+                     .withInlineStorage(isInline);
   layout.stride = std::max(size_t(1), roundUpToAlignMask(size, alignMask));
 }
 
@@ -1558,20 +1543,6 @@
   return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
 }
 
-static OpaqueValue *pod_indirect_initializeBufferWithTakeOfBuffer(
-                    ValueBuffer *dest, ValueBuffer *src, const Metadata *self) {
-  auto wtable = self->getValueWitnesses();
-  auto *srcReference = *reinterpret_cast<HeapObject**>(src);
-  *reinterpret_cast<HeapObject**>(dest) = srcReference;
-
-  // Project the address of the value in the buffer.
-  unsigned alignMask = wtable->getAlignmentMask();
-  // Compute the byte offset of the object in the box.
-  unsigned byteOffset = (sizeof(HeapObject) + alignMask) & ~alignMask;
-  auto *bytePtr = reinterpret_cast<char *>(srcReference);
-  return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
-}
-
 static void pod_noop(void *object, const Metadata *self) {
 }
 #define pod_direct_destroy \
@@ -1588,9 +1559,6 @@
 #define pod_direct_initializeBufferWithCopyOfBuffer \
   pointer_function_cast<value_witness_types::initializeBufferWithCopyOfBuffer> \
     (pod_direct_initializeWithCopy)
-#define pod_direct_initializeBufferWithTakeOfBuffer \
-  pointer_function_cast<value_witness_types::initializeBufferWithTakeOfBuffer> \
-    (pod_direct_initializeWithCopy)
 #define pod_direct_assignWithCopy pod_direct_initializeWithCopy
 #define pod_indirect_assignWithCopy pod_direct_initializeWithCopy
 #define pod_direct_initializeWithTake pod_direct_initializeWithCopy
@@ -1703,23 +1671,12 @@
     // Use POD value witnesses for operations that do an initializeWithTake.
     if (flags.isInlineStorage()) {
       vwtable->initializeWithTake = pod_direct_initializeWithTake;
-      vwtable->initializeBufferWithTakeOfBuffer
-        = pod_direct_initializeBufferWithTakeOfBuffer;
     } else {
       vwtable->initializeWithTake = pod_indirect_initializeWithTake;
-      vwtable->initializeBufferWithTakeOfBuffer
-        = pod_indirect_initializeBufferWithTakeOfBuffer;
     }
     return;
   }
 
-  if (!flags.isInlineStorage()) {
-    // For values stored out-of-line, initializeBufferWithTakeOfBuffer is
-    // always a memcpy.
-    vwtable->initializeBufferWithTakeOfBuffer
-      = pod_indirect_initializeBufferWithTakeOfBuffer;
-    return;
-  }
 }
 
 /***************************************************************************/
@@ -2569,7 +2526,7 @@
   Data.flags = ValueWitnessFlags()
     .withAlignment(Box::Container::getAlignment(numWitnessTables))
     .withPOD(false)
-    .withBitwiseTakable(false)
+    .withBitwiseTakable(true)
     .withInlineStorage(false)
     .withExtraInhabitants(false);
   Data.stride = Box::Container::getStride(numWitnessTables);
diff --git a/stdlib/public/runtime/MetadataImpl.h b/stdlib/public/runtime/MetadataImpl.h
index bcd562f..a52a8f4 100644
--- a/stdlib/public/runtime/MetadataImpl.h
+++ b/stdlib/public/runtime/MetadataImpl.h
@@ -620,31 +620,28 @@
   Allocate,
   OffsetZero
 };
-constexpr FixedPacking getFixedPacking(size_t size, size_t alignment) {
-  return (canBeInline(size, alignment) ? FixedPacking::OffsetZero
-                                       : FixedPacking::Allocate);
+constexpr FixedPacking getFixedPacking(bool isBitwiseTakable, size_t size,
+                                       size_t alignment) {
+  return (canBeInline(isBitwiseTakable, size, alignment)
+              ? FixedPacking::OffsetZero
+              : FixedPacking::Allocate);
 }
 
 /// A CRTP base class which provides default implementations of a
 /// number of value witnesses.
-template <class Impl, size_t Size, size_t Alignment,
-          FixedPacking Packing = getFixedPacking(Size, Alignment)>
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment,
+          FixedPacking Packing =
+              getFixedPacking(isBitwiseTakable, Size, Alignment)>
 struct BufferValueWitnesses;
 
 /// An implementation of ValueBase suitable for classes that can be
 /// allocated inline.
-template <class Impl, size_t Size, size_t Alignment>
-struct BufferValueWitnesses<Impl, Size, Alignment, FixedPacking::OffsetZero>
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment>
+struct BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
+                            FixedPacking::OffsetZero>
     : BufferValueWitnessesBase<Impl> {
   static constexpr bool isInline = true;
 
-  static OpaqueValue *initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
-                                                       ValueBuffer *src,
-                                                       const Metadata *self) {
-    return Impl::initializeWithTake(reinterpret_cast<OpaqueValue*>(dest),
-                                    reinterpret_cast<OpaqueValue*>(src),
-                                    self);
-  }
   static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
                                                        ValueBuffer *src,
                                                        const Metadata *self) {
@@ -655,26 +652,12 @@
 
 /// An implementation of BufferValueWitnesses suitable for types that
 /// cannot be allocated inline.
-template <class Impl, size_t Size, size_t Alignment>
-struct BufferValueWitnesses<Impl, Size, Alignment, FixedPacking::Allocate>
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment>
+struct BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
+                            FixedPacking::Allocate>
     : BufferValueWitnessesBase<Impl> {
   static constexpr bool isInline = false;
 
-  static OpaqueValue *initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
-                                                       ValueBuffer *src,
-                                                       const Metadata *self) {
-    auto wtable = self->getValueWitnesses();
-    auto *srcReference = *reinterpret_cast<HeapObject **>(src);
-    *reinterpret_cast<HeapObject **>(dest) = srcReference;
-
-    // Project the address of the value in the buffer.
-    unsigned alignMask = wtable->getAlignmentMask();
-    // Compute the byte offset of the object in the box.
-    unsigned byteOffset = (sizeof(HeapObject) + alignMask) & ~alignMask;
-    auto *bytePtr = reinterpret_cast<char *>(srcReference);
-    return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
-  }
-
   static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
                                                        ValueBuffer *src,
                                                        const Metadata *self) {
@@ -695,26 +678,6 @@
 /// fixed in size.
 template <class Impl, bool IsKnownAllocated>
 struct NonFixedBufferValueWitnesses : BufferValueWitnessesBase<Impl> {
-  static OpaqueValue *initializeBufferWithTakeOfBuffer(ValueBuffer *dest,
-                                                       ValueBuffer *src,
-                                                       const Metadata *self) {
-    auto vwtable = self->getValueWitnesses();
-    (void)vwtable;
-    if (!IsKnownAllocated && vwtable->isValueInline()) {
-      return Impl::initializeWithTake(reinterpret_cast<OpaqueValue *>(dest),
-                                      reinterpret_cast<OpaqueValue *>(src),
-                                      self);
-    } else {
-      auto reference = src->PrivateData[0];
-      dest->PrivateData[0] = reference;
-      // Project the address of the value in the buffer.
-      unsigned alignMask = vwtable->getAlignmentMask();
-      // Compute the byte offset of the object in the box.
-      unsigned byteOffset = (sizeof(HeapObject) + alignMask) & ~alignMask;
-      auto *bytePtr = reinterpret_cast<char *>(reference);
-      return reinterpret_cast<OpaqueValue *>(bytePtr + byteOffset);
-    }
-  }
 
   static OpaqueValue *initializeBufferWithCopyOfBuffer(ValueBuffer *dest,
                                                        ValueBuffer *src,
@@ -741,15 +704,16 @@
 
 /// Provides implementations for
 /// getEnumTagSinglePayload/storeEnumTagSinglePayload.
-template<class Impl, size_t Size, size_t Alignment, bool hasExtraInhabitants>
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment,
+          bool hasExtraInhabitants>
 struct FixedSizeBufferValueWitnesses;
 
 /// A fixed size buffer value witness that can rely on the presents of the extra
 /// inhabitant functions.
-template <class Impl, size_t Size, size_t Alignment>
-struct FixedSizeBufferValueWitnesses<Impl, Size, Alignment,
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment>
+struct FixedSizeBufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
                                      true /*hasExtraInhabitants*/>
-    : BufferValueWitnesses<Impl, Size, Alignment> {
+    : BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment> {
 
   static unsigned getEnumTagSinglePayload(const OpaqueValue *enumAddr,
                                           unsigned numEmptyCases,
@@ -771,10 +735,10 @@
 
 /// A fixed size buffer value witness that cannot rely on the presents of the
 /// extra inhabitant functions.
-template <class Impl, size_t Size, size_t Alignment>
-struct FixedSizeBufferValueWitnesses<Impl, Size, Alignment,
+template <class Impl, bool isBitwiseTakable, size_t Size, size_t Alignment>
+struct FixedSizeBufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment,
                                      false /*hasExtraInhabitants*/>
-    : BufferValueWitnesses<Impl, Size, Alignment> {
+    : BufferValueWitnesses<Impl, isBitwiseTakable, Size, Alignment> {
 
   static unsigned getEnumTagSinglePayload(const OpaqueValue *enumAddr,
                                           unsigned numEmptyCases,
@@ -801,11 +765,12 @@
 /// The box type has to provide a numExtraInhabitants member, but as
 /// long as it's zero, the rest is fine.
 template <class Box>
-struct ValueWitnesses : FixedSizeBufferValueWitnesses<
-                            ValueWitnesses<Box>, Box::size, Box::alignment,
-                            hasExtraInhabitants(Box::numExtraInhabitants)> {
+struct ValueWitnesses
+    : FixedSizeBufferValueWitnesses<
+          ValueWitnesses<Box>, Box::isBitwiseTakable, Box::size, Box::alignment,
+          hasExtraInhabitants(Box::numExtraInhabitants)> {
   using Base = FixedSizeBufferValueWitnesses<
-      ValueWitnesses<Box>, Box::size, Box::alignment,
+      ValueWitnesses<Box>, Box::isBitwiseTakable, Box::size, Box::alignment,
       hasExtraInhabitants(Box::numExtraInhabitants)>;
 
   static constexpr size_t size = Box::size;
@@ -817,7 +782,7 @@
   static constexpr bool hasExtraInhabitants = (numExtraInhabitants != 0);
   static constexpr ValueWitnessFlags flags =
     ValueWitnessFlags().withAlignmentMask(alignment - 1)
-                       .withInlineStorage(Base::isInline)
+                       .withInlineStorage(Base::isInline && isBitwiseTakable)
                        .withPOD(isPOD)
                        .withBitwiseTakable(isBitwiseTakable)
                        .withExtraInhabitants(hasExtraInhabitants);
diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp
index 7efbc04..07ce6c8 100644
--- a/stdlib/public/runtime/MetadataLookup.cpp
+++ b/stdlib/public/runtime/MetadataLookup.cpp
@@ -23,7 +23,6 @@
 #include "swift/Runtime/Concurrent.h"
 #include "swift/Runtime/HeapObject.h"
 #include "swift/Runtime/Metadata.h"
-#include "swift/Runtime/Mutex.h"
 #include "swift/Strings.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Optional.h"
@@ -106,11 +105,9 @@
 
 struct TypeMetadataPrivateState {
   ConcurrentMap<NominalTypeDescriptorCacheEntry> NominalCache;
-  std::vector<TypeMetadataSection> SectionsToScan;
-  Mutex SectionsToScanLock;
+  ConcurrentReadableArray<TypeMetadataSection> SectionsToScan;
 
   TypeMetadataPrivateState() {
-    SectionsToScan.reserve(16);
     initializeTypeMetadataRecordLookup();
   }
 
@@ -122,7 +119,6 @@
 _registerTypeMetadataRecords(TypeMetadataPrivateState &T,
                              const TypeMetadataRecord *begin,
                              const TypeMetadataRecord *end) {
-  ScopedLock guard(T.SectionsToScanLock);
   T.SectionsToScan.push_back(TypeMetadataSection{begin, end});
 }
 
@@ -296,12 +292,9 @@
 
 // returns the nominal type descriptor for the type named by typeName
 static const TypeContextDescriptor *
-_searchTypeMetadataRecords(const TypeMetadataPrivateState &T,
+_searchTypeMetadataRecords(TypeMetadataPrivateState &T,
                            Demangle::NodePointer node) {
-  unsigned sectionIdx = 0;
-  unsigned endSectionIdx = T.SectionsToScan.size();
-  for (; sectionIdx < endSectionIdx; ++sectionIdx) {
-    auto &section = T.SectionsToScan[sectionIdx];
+  for (auto &section : T.SectionsToScan.snapshot()) {
     for (const auto &record : section) {
       if (auto ntd = record.getTypeContextDescriptor()) {
         if (_contextDescriptorMatchesMangling(ntd, node)) {
@@ -342,9 +335,7 @@
     return Value->getDescription();
 
   // Check type metadata records
-  T.SectionsToScanLock.withLock([&] {
-    foundNominal = _searchTypeMetadataRecords(T, node);
-  });
+  foundNominal = _searchTypeMetadataRecords(T, node);
 
   // Check protocol conformances table. Note that this has no support for
   // resolving generic types yet.
@@ -395,11 +386,9 @@
 
   struct ProtocolMetadataPrivateState {
     ConcurrentMap<ProtocolDescriptorCacheEntry> ProtocolCache;
-    std::vector<ProtocolSection> SectionsToScan;
-    Mutex SectionsToScanLock;
+    ConcurrentReadableArray<ProtocolSection> SectionsToScan;
 
     ProtocolMetadataPrivateState() {
-      SectionsToScan.reserve(16);
       initializeProtocolLookup();
     }
   };
@@ -411,7 +400,6 @@
 _registerProtocols(ProtocolMetadataPrivateState &C,
                    const ProtocolRecord *begin,
                    const ProtocolRecord *end) {
-  ScopedLock guard(C.SectionsToScanLock);
   C.SectionsToScan.push_back(ProtocolSection{begin, end});
 }
 
@@ -439,12 +427,9 @@
 }
 
 static const ProtocolDescriptor *
-_searchProtocolRecords(const ProtocolMetadataPrivateState &C,
+_searchProtocolRecords(ProtocolMetadataPrivateState &C,
                        const llvm::StringRef protocolName){
-  unsigned sectionIdx = 0;
-  unsigned endSectionIdx = C.SectionsToScan.size();
-  for (; sectionIdx < endSectionIdx; ++sectionIdx) {
-    auto &section = C.SectionsToScan[sectionIdx];
+  for (auto &section : C.SectionsToScan.snapshot()) {
     for (const auto &record : section) {
       if (auto protocol = record.Protocol.getPointer()) {
         // Drop the "S$" prefix from the protocol record. It's not used in
@@ -472,9 +457,7 @@
     return Value->getDescription();
 
   // Check type metadata records
-  T.SectionsToScanLock.withLock([&] {
-    foundProtocol = _searchProtocolRecords(T, mangledName);
-  });
+  foundProtocol = _searchProtocolRecords(T, mangledName);
 
   if (foundProtocol) {
     T.ProtocolCache.getOrInsert(mangledName, foundProtocol);
@@ -534,7 +517,7 @@
   DynamicFieldSection(const FieldDescriptor **fields, size_t size)
       : Begin(fields), End(fields + size) {}
 
-  const FieldDescriptor **begin() { return Begin; }
+  const FieldDescriptor **begin() const { return Begin; }
 
   const FieldDescriptor **end() const { return End; }
 };
@@ -542,13 +525,10 @@
 struct FieldCacheState {
   ConcurrentMap<FieldDescriptorCacheEntry> FieldCache;
 
-  Mutex SectionsLock;
-  std::vector<StaticFieldSection> StaticSections;
-  std::vector<DynamicFieldSection> DynamicSections;
+  ConcurrentReadableArray<StaticFieldSection> StaticSections;
+  ConcurrentReadableArray<DynamicFieldSection> DynamicSections;
 
   FieldCacheState() {
-    StaticSections.reserve(16);
-    DynamicSections.reserve(8);
     initializeTypeFieldLookup();
   }
 };
@@ -559,7 +539,6 @@
 void swift::swift_registerFieldDescriptors(const FieldDescriptor **records,
                                            size_t size) {
   auto &cache = FieldCache.get();
-  ScopedLock guard(cache.SectionsLock);
   cache.DynamicSections.push_back({records, size});
 }
 
@@ -570,7 +549,6 @@
 
   // Field cache should always be sufficiently initialized by this point.
   auto &cache = FieldCache.unsafeGetAlreadyInitialized();
-  ScopedLock guard(cache.SectionsLock);
   cache.StaticSections.push_back({recordsBegin, recordsEnd});
 }
 
@@ -1216,16 +1194,15 @@
     return;
   }
 
-  ScopedLock guard(cache.SectionsLock);
   // Otherwise let's try to find it in one of the sections.
-  for (auto &section : cache.DynamicSections) {
+  for (auto &section : cache.DynamicSections.snapshot()) {
     for (const auto *descriptor : section) {
       if (isRequestedDescriptor(*descriptor))
         return;
     }
   }
 
-  for (const auto &section : cache.StaticSections) {
+  for (const auto &section : cache.StaticSections.snapshot()) {
     for (auto &descriptor : section) {
       if (isRequestedDescriptor(descriptor))
         return;
diff --git a/stdlib/public/runtime/ProtocolConformance.cpp b/stdlib/public/runtime/ProtocolConformance.cpp
index 703e334..0877082 100644
--- a/stdlib/public/runtime/ProtocolConformance.cpp
+++ b/stdlib/public/runtime/ProtocolConformance.cpp
@@ -326,14 +326,11 @@
   // Iterate over all of the sections and verify all of the protocol
   // descriptors.
   auto &Self = const_cast<ConformanceState &>(*this);
-  Self.SectionsToScan.read([](const ConformanceSection *ptr, size_t count) -> char {
-    for (size_t i = 0; i < count; i++) {
-      for (const auto &Record : ptr[i]) {
-        Record.get()->verify();
-      }
+  for (const auto &Section : Self.SectionsToScan.snapshot()) {
+    for (const auto &Record : Section) {
+      Record.get()->verify();
     }
-    return 0;
-  });
+  }
 }
 #endif
 
@@ -445,7 +442,7 @@
       }
 
       // Check if the negative cache entry is up-to-date.
-      if (Value->getFailureGeneration() == C.SectionsToScan.count()) {
+      if (Value->getFailureGeneration() == C.SectionsToScan.snapshot().count()) {
         // Negative cache entry is up-to-date. Return failure along with
         // the original query type's own cache entry, if we found one.
         // (That entry may be out of date but the caller still has use for it.)
@@ -546,100 +543,94 @@
   auto failureEntry = FoundConformance.failureEntry;
 
   // Prepare to scan conformance records.
-  size_t scannedCount;
-  auto returnNull = C.SectionsToScan
-    .read([&](const ConformanceSection *ptr, size_t count) -> bool {
-    scannedCount = count;
-    // Scan only sections that were not scanned yet.
-    // If we found an out-of-date negative cache entry,
-    // we need not to re-scan the sections that it covers.
-    auto startIndex = failureEntry ? failureEntry->getFailureGeneration() : 0;
-    auto endIndex = count;
+  auto snapshot = C.SectionsToScan.snapshot();
   
-    // If there are no unscanned sections outstanding
-    // then we can cache failure and give up now.
-    if (startIndex == endIndex) {
-      C.cacheFailure(type, protocol, count);
-      return true;
+  // Scan only sections that were not scanned yet.
+  // If we found an out-of-date negative cache entry,
+  // we need not to re-scan the sections that it covers.
+  auto startIndex = failureEntry ? failureEntry->getFailureGeneration() : 0;
+  auto endIndex = snapshot.count();
+
+  // If there are no unscanned sections outstanding
+  // then we can cache failure and give up now.
+  if (startIndex == endIndex) {
+    C.cacheFailure(type, protocol, snapshot.count());
+    return nullptr;
+  }
+
+  /// Local function to retrieve the witness table and record the result.
+  auto recordWitnessTable = [&](const ProtocolConformanceDescriptor &descriptor,
+                                const Metadata *type) {
+    switch (descriptor.getConformanceKind()) {
+    case ConformanceFlags::ConformanceKind::WitnessTable:
+      // If the record provides a nondependent witness table for all
+      // instances of a generic type, cache it for the generic pattern.
+      C.cacheSuccess(type, protocol, descriptor.getStaticWitnessTable());
+      return;
+
+    case ConformanceFlags::ConformanceKind::WitnessTableAccessor:
+      // If the record provides a dependent witness table accessor,
+      // cache the result for the instantiated type metadata.
+      C.cacheSuccess(type, protocol, descriptor.getWitnessTable(type));
+      return;
+
+    case ConformanceFlags::ConformanceKind::ConditionalWitnessTableAccessor: {
+      auto witnessTable = descriptor.getWitnessTable(type);
+      if (witnessTable)
+        C.cacheSuccess(type, protocol, witnessTable);
+      else
+        C.cacheFailure(type, protocol, snapshot.count());
+      return;
+    }
     }
 
-    /// Local function to retrieve the witness table and record the result.
-    auto recordWitnessTable = [&](const ProtocolConformanceDescriptor &descriptor,
-                                  const Metadata *type) {
-      switch (descriptor.getConformanceKind()) {
-      case ConformanceFlags::ConformanceKind::WitnessTable:
-        // If the record provides a nondependent witness table for all
-        // instances of a generic type, cache it for the generic pattern.
-        C.cacheSuccess(type, protocol, descriptor.getStaticWitnessTable());
-        return;
+    // Always fail, because we cannot interpret a future conformance
+    // kind.
+    C.cacheFailure(type, protocol, snapshot.count());
+  };
 
-      case ConformanceFlags::ConformanceKind::WitnessTableAccessor:
-        // If the record provides a dependent witness table accessor,
-        // cache the result for the instantiated type metadata.
-        C.cacheSuccess(type, protocol, descriptor.getWitnessTable(type));
-        return;
+  // Really scan conformance records.
+  for (size_t i = startIndex; i < endIndex; i++) {
+    auto &section = snapshot.Start[i];
+    // Eagerly pull records for nondependent witnesses into our cache.
+    for (const auto &record : section) {
+      auto &descriptor = *record.get();
 
-      case ConformanceFlags::ConformanceKind::ConditionalWitnessTableAccessor: {
-        auto witnessTable = descriptor.getWitnessTable(type);
-        if (witnessTable)
-          C.cacheSuccess(type, protocol, witnessTable);
-        else
-          C.cacheFailure(type, protocol, count);
-        return;
-      }
-      }
+      // If the record applies to a specific type, cache it.
+      if (auto metadata = descriptor.getCanonicalTypeMetadata()) {
+        auto P = descriptor.getProtocol();
 
-      // Always fail, because we cannot interpret a future conformance
-      // kind.
-      C.cacheFailure(type, protocol, count);
-    };
+        // Look for an exact match.
+        if (protocol != P)
+          continue;
 
-    // Really scan conformance records.
-    for (size_t i = startIndex; i < endIndex; i++) {
-      auto &section = ptr[i];
-      // Eagerly pull records for nondependent witnesses into our cache.
-      for (const auto &record : section) {
-        auto &descriptor = *record.get();
+        if (!isRelatedType(type, metadata, /*candidateIsMetadata=*/true))
+          continue;
 
-        // If the record applies to a specific type, cache it.
-        if (auto metadata = descriptor.getCanonicalTypeMetadata()) {
-          auto P = descriptor.getProtocol();
+        // Record the witness table.
+        recordWitnessTable(descriptor, metadata);
 
-          // Look for an exact match.
-          if (protocol != P)
-            continue;
+      // TODO: "Nondependent witness table" probably deserves its own flag.
+      // An accessor function might still be necessary even if the witness table
+      // can be shared.
+      } else if (descriptor.getTypeKind()
+                   == TypeMetadataRecordKind::DirectNominalTypeDescriptor ||
+                 descriptor.getTypeKind()
+                  == TypeMetadataRecordKind::IndirectNominalTypeDescriptor) {
+        auto R = descriptor.getTypeContextDescriptor();
+        auto P = descriptor.getProtocol();
 
-          if (!isRelatedType(type, metadata, /*candidateIsMetadata=*/true))
-            continue;
+        // Look for an exact match.
+        if (protocol != P)
+          continue;
 
-          // Record the witness table.
-          recordWitnessTable(descriptor, metadata);
+        if (!isRelatedType(type, R, /*candidateIsMetadata=*/false))
+          continue;
 
-        // TODO: "Nondependent witness table" probably deserves its own flag.
-        // An accessor function might still be necessary even if the witness table
-        // can be shared.
-        } else if (descriptor.getTypeKind()
-                     == TypeMetadataRecordKind::DirectNominalTypeDescriptor ||
-                   descriptor.getTypeKind()
-                    == TypeMetadataRecordKind::IndirectNominalTypeDescriptor) {
-          auto R = descriptor.getTypeContextDescriptor();
-          auto P = descriptor.getProtocol();
-
-          // Look for an exact match.
-          if (protocol != P)
-            continue;
-
-          if (!isRelatedType(type, R, /*candidateIsMetadata=*/false))
-            continue;
-
-          recordWitnessTable(descriptor, type);
-        }
+        recordWitnessTable(descriptor, type);
       }
     }
-    return false;
-  });
-  
-  if (returnNull) return nullptr;
+  }
   
   // Conformance scan is complete.
   // Search the cache once more, and this time update the cache if necessary.
@@ -648,7 +639,7 @@
   if (FoundConformance.isAuthoritative) {
     return FoundConformance.witnessTable;
   } else {
-    C.cacheFailure(type, protocol, scannedCount);
+    C.cacheFailure(type, protocol, snapshot.count());
     return nullptr;
   }
 }
@@ -657,19 +648,15 @@
 swift::_searchConformancesByMangledTypeName(Demangle::NodePointer node) {
   auto &C = Conformances.get();
 
-  return C.SectionsToScan
-    .read([&](const ConformanceSection *ptr, size_t count) -> const TypeContextDescriptor * {
-    for (size_t i = 0; i < count; i++) {
-      auto &section = ptr[i];
-      for (const auto &record : section) {
-        if (auto ntd = record->getTypeContextDescriptor()) {
-          if (_contextDescriptorMatchesMangling(ntd, node))
-            return ntd;
-        }
+  for (auto &section : C.SectionsToScan.snapshot()) {
+    for (const auto &record : section) {
+      if (auto ntd = record->getTypeContextDescriptor()) {
+        if (_contextDescriptorMatchesMangling(ntd, node))
+          return ntd;
       }
     }
-    return nullptr;
-  });
+  }
+  return nullptr;
 }
 
 /// Resolve a reference to a generic parameter to type metadata.
diff --git a/stdlib/public/runtime/SwiftRT-ELF.cpp b/stdlib/public/runtime/SwiftRT-ELF.cpp
index 47ba9a7..56074d2 100644
--- a/stdlib/public/runtime/SwiftRT-ELF.cpp
+++ b/stdlib/public/runtime/SwiftRT-ELF.cpp
@@ -24,14 +24,14 @@
   __attribute__((__visibility__("hidden"))) extern const char __stop_##name;
 
 extern "C" {
-DECLARE_SWIFT_SECTION(swift4_protocols)
-DECLARE_SWIFT_SECTION(swift4_protocol_conformances)
-DECLARE_SWIFT_SECTION(swift4_type_metadata)
+DECLARE_SWIFT_SECTION(swift5_protocols)
+DECLARE_SWIFT_SECTION(swift5_protocol_conformances)
+DECLARE_SWIFT_SECTION(swift5_type_metadata)
 
-DECLARE_SWIFT_SECTION(swift4_typeref)
-DECLARE_SWIFT_SECTION(swift4_reflstr)
-DECLARE_SWIFT_SECTION(swift4_fieldmd)
-DECLARE_SWIFT_SECTION(swift4_assocty)
+DECLARE_SWIFT_SECTION(swift5_typeref)
+DECLARE_SWIFT_SECTION(swift5_reflstr)
+DECLARE_SWIFT_SECTION(swift5_fieldmd)
+DECLARE_SWIFT_SECTION(swift5_assocty)
 }
 
 #undef DECLARE_SWIFT_SECTION
@@ -53,14 +53,14 @@
       nullptr,
       nullptr,
 
-      SWIFT_SECTION_RANGE(swift4_protocols),
-      SWIFT_SECTION_RANGE(swift4_protocol_conformances),
-      SWIFT_SECTION_RANGE(swift4_type_metadata),
+      SWIFT_SECTION_RANGE(swift5_protocols),
+      SWIFT_SECTION_RANGE(swift5_protocol_conformances),
+      SWIFT_SECTION_RANGE(swift5_type_metadata),
 
-      SWIFT_SECTION_RANGE(swift4_typeref),
-      SWIFT_SECTION_RANGE(swift4_reflstr),
-      SWIFT_SECTION_RANGE(swift4_fieldmd),
-      SWIFT_SECTION_RANGE(swift4_assocty),
+      SWIFT_SECTION_RANGE(swift5_typeref),
+      SWIFT_SECTION_RANGE(swift5_reflstr),
+      SWIFT_SECTION_RANGE(swift5_fieldmd),
+      SWIFT_SECTION_RANGE(swift5_assocty),
   };
 
 #undef SWIFT_SECTION_RANGE
diff --git a/test/ClangImporter/Inputs/custom-modules/ConditionallyFoo.h b/test/ClangImporter/Inputs/custom-modules/ConditionallyFoo.h
new file mode 100644
index 0000000..598a0ba
--- /dev/null
+++ b/test/ClangImporter/Inputs/custom-modules/ConditionallyFoo.h
@@ -0,0 +1,3 @@
+#ifdef WANT_FOO
+int foo();
+#endif
diff --git a/test/ClangImporter/Inputs/custom-modules/module.map b/test/ClangImporter/Inputs/custom-modules/module.map
index f7c389a..1f4c987 100644
--- a/test/ClangImporter/Inputs/custom-modules/module.map
+++ b/test/ClangImporter/Inputs/custom-modules/module.map
@@ -212,3 +212,8 @@
 module Warnings7 { header "Warnings7.h" }
 module Warnings8 { header "Warnings8.h" }
 module Warnings9 { header "Warnings9.h" }
+
+module ConditionallyFoo {
+  header "ConditionallyFoo.h"
+  config_macros [exhaustive] WANT_FOO
+}
\ No newline at end of file
diff --git a/test/ClangImporter/Inputs/no-fake-source-buffer-excerpts.h b/test/ClangImporter/Inputs/no-fake-source-buffer-excerpts.h
new file mode 100644
index 0000000..5254c40
--- /dev/null
+++ b/test/ClangImporter/Inputs/no-fake-source-buffer-excerpts.h
@@ -0,0 +1,2 @@
+#define WANT_FOO
+@import ConditionallyFoo;
diff --git a/test/ClangImporter/no-fake-source-buffer-excerpts.swift b/test/ClangImporter/no-fake-source-buffer-excerpts.swift
new file mode 100644
index 0000000..7a88953
--- /dev/null
+++ b/test/ClangImporter/no-fake-source-buffer-excerpts.swift
@@ -0,0 +1,11 @@
+// REQUIRES: OS=macosx
+//
+// This triggers a warning about ignored configuration macros; the warning then
+// attempts to emit an excerpt from one of the clang importer's fake buffers
+// (<swift-imported-modules>) which is full of 250kb of nulls. We want to check
+// that we do not emit a gigantic block of nulls to stderr.
+//
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -typecheck -I %S/Inputs/custom-modules -import-objc-header %S/Inputs/no-fake-source-buffer-excerpts.h %s 2>%t/errors
+// RUN: od -a < %t/errors | %FileCheck %s
+// CHECK-NOT: nul nul nul nul
diff --git a/test/Driver/dump-parse.swift b/test/Driver/dump-parse.swift
index a782033..30cdf5c 100644
--- a/test/Driver/dump-parse.swift
+++ b/test/Driver/dump-parse.swift
@@ -1,8 +1,8 @@
 // RUN: not %target-swift-frontend -dump-parse %s 2>&1 | %FileCheck %s
 // RUN: not %target-swift-frontend -dump-ast %s 2>&1 | %FileCheck %s -check-prefix=CHECK-AST
 
-// CHECK-LABEL: (func_decl "foo(_:)"
-// CHECK-AST-LABEL: (func_decl "foo(_:)"
+// CHECK-LABEL: (func_decl{{.*}}"foo(_:)"
+// CHECK-AST-LABEL: (func_decl{{.*}}"foo(_:)"
 func foo(_ n: Int) -> Int {
   // CHECK:   (brace_stmt
   // CHECK:     (return_stmt
@@ -15,8 +15,8 @@
 }
 
 // -dump-parse should print an AST even though this code is invalid.
-// CHECK-LABEL: (func_decl "bar()"
-// CHECK-AST-LABEL: (func_decl "bar()"
+// CHECK-LABEL: (func_decl{{.*}}"bar()"
+// CHECK-AST-LABEL: (func_decl{{.*}}"bar()"
 func bar() {
   // CHECK: (brace_stmt
   // CHECK-NEXT:   (unresolved_decl_ref_expr type='{{[^']+}}' name=foo
@@ -29,34 +29,34 @@
   foo foo foo
 }
 
-// CHECK-LABEL: (enum_decl trailing_semi "TrailingSemi"
+// CHECK-LABEL: (enum_decl{{.*}}trailing_semi "TrailingSemi"
 enum TrailingSemi {
 
-  // CHECK-LABEL: (enum_case_decl trailing_semi
+  // CHECK-LABEL: (enum_case_decl{{.*}}trailing_semi
   // CHECK-NOT:   (enum_element_decl{{.*}}trailing_semi
-  // CHECK:       (enum_element_decl "A")
-  // CHECK:       (enum_element_decl "B")
+  // CHECK:       (enum_element_decl{{.*}}"A")
+  // CHECK:       (enum_element_decl{{.*}}"B")
   case A,B;
 
-  // CHECK-LABEL: (subscript_decl trailing_semi
-  // CHECK-NOT:   (func_decl trailing_semi 'anonname={{.*}}' getter_for=subscript(_:)
-  // CHECK:       (accessor_decl 'anonname={{.*}}' getter_for=subscript(_:)
+  // CHECK-LABEL: (subscript_decl{{.*}}trailing_semi
+  // CHECK-NOT:   (func_decl{{.*}}trailing_semi 'anonname={{.*}}' getter_for=subscript(_:)
+  // CHECK:       (accessor_decl{{.*}}'anonname={{.*}}' getter_for=subscript(_:)
   subscript(x: Int) -> Int {
-    // CHECK-LABEL: (pattern_binding_decl trailing_semi
-    // CHECK-NOT:   (var_decl trailing_semi "y"
-    // CHECK:       (var_decl "y"
+    // CHECK-LABEL: (pattern_binding_decl{{.*}}trailing_semi
+    // CHECK-NOT:   (var_decl{{.*}}trailing_semi "y"
+    // CHECK:       (var_decl{{.*}}"y"
     var y = 1;
 
     // CHECK-LABEL: (sequence_expr {{.*}} trailing_semi
     y += 1;
 
-    // CHECK-LABEL: (return_stmt trailing_semi
+    // CHECK-LABEL: (return_stmt{{.*}}trailing_semi
     return y;
   };
 };
 
 // The substitution map for a declref should be relatively unobtrustive.
-// CHECK-AST-LABEL:   (func_decl "generic(_:)" <T : Hashable> interface type='<T where T : Hashable> (T) -> ()' access=internal captures=(<generic> )
+// CHECK-AST-LABEL:   (func_decl{{.*}}"generic(_:)" <T : Hashable> interface type='<T where T : Hashable> (T) -> ()' access=internal captures=(<generic> )
 func generic<T: Hashable>(_: T) {}
 // CHECK-AST:       (pattern_binding_decl
 // CHECK-AST:         (declref_expr type='(Int) -> ()' location={{.*}} range={{.*}} decl=main.(file).generic@{{.*}} [with (substitution_map generic_signature=<T where T : Hashable> (substitution T -> Int))] function_ref=unapplied))
diff --git a/test/Driver/emit_public_type_metadata_accessors.swift b/test/Driver/emit_public_type_metadata_accessors.swift
new file mode 100644
index 0000000..123c136
--- /dev/null
+++ b/test/Driver/emit_public_type_metadata_accessors.swift
@@ -0,0 +1,3 @@
+// RUN: %target-build-swift %s -emit-public-type-metadata-accessors 2>&1 | %FileCheck %s
+
+// CHECK: the option '-emit-public-type-metadata-accessors' is no longer needed and is deprecated; consider removing it
diff --git a/test/Generics/same_type_constraints.swift b/test/Generics/same_type_constraints.swift
index 9dca6b0..2d8b5cd 100644
--- a/test/Generics/same_type_constraints.swift
+++ b/test/Generics/same_type_constraints.swift
@@ -378,3 +378,19 @@
 extension X11 where NotAnInt == Int { }
 // expected-warning@-1{{neither type in same-type constraint ('NotAnInt' (aka 'Double') or 'Int') refers to a generic parameter or associated type}}
 // expected-error@-2{{generic signature requires types 'NotAnInt' (aka 'Double') and 'Int' to be the same}}
+
+
+struct X12<T> { }
+
+protocol P12 {
+  associatedtype A
+  associatedtype B
+}
+
+func testP12a<T: P12>(_: T) where T.A == X12<Int>, T.A == X12<T.B>, T.B == Int { }
+// expected-warning@-1{{redundant same-type constraint 'T.B' == 'Int'}}
+// expected-note@-2{{same-type constraint 'T.B' == 'Int' written here}}
+
+func testP12b<T: P12>(_: T) where T.B == Int, T.A == X12<T.B>, X12<T.B> == T.A { }
+// expected-warning@-1{{redundant same-type constraint 'T.A' == 'X12<Int>'}}
+// expected-note@-2{{same-type constraint 'T.A' == 'X12<Int>' written here}}
diff --git a/test/IDE/complete_after_self.swift b/test/IDE/complete_after_self.swift
index fe4afbe..b5a3744 100644
--- a/test/IDE/complete_after_self.swift
+++ b/test/IDE/complete_after_self.swift
@@ -166,7 +166,7 @@
 
   init() {
     self#^CONSTRUCTOR_SELF_NO_DOT_1^#
-// CONSTRUCTOR_SELF_NO_DOT_1: Begin completions, 23 items
+// CONSTRUCTOR_SELF_NO_DOT_1: Begin completions, 24 items
 // CONSTRUCTOR_SELF_NO_DOT_1-DAG: Decl[Constructor]/CurrNominal: .init()[#ThisDerived1#];
 // CONSTRUCTOR_SELF_NO_DOT_1-DAG: Decl[Constructor]/CurrNominal: .init({#a: Int#})[#ThisDerived1#];
 // CONSTRUCTOR_SELF_NO_DOT_1: End completions
@@ -177,9 +177,10 @@
 
   init(a : Int) {
     self.#^CONSTRUCTOR_SELF_DOT_1^#
-// CONSTRUCTOR_SELF_DOT_1: Begin completions, 18 items
+// CONSTRUCTOR_SELF_DOT_1: Begin completions, 19 items
 // CONSTRUCTOR_SELF_DOT_1-DAG: Decl[Constructor]/CurrNominal: init()[#ThisDerived1#];
 // CONSTRUCTOR_SELF_DOT_1-DAG: Decl[Constructor]/CurrNominal: init({#a: Int#})[#ThisDerived1#];
+
 // CONSTRUCTOR_SELF_DOT_1: End completions
     let d: ThisDerived1
     d.#^CONSTRUCTOR_NONSELF_DOT_1^#
@@ -187,23 +188,23 @@
 
   deinit {
     self#^DESTRUCTOR_SELF_NO_DOT_1^#
-// DESTRUCTOR_SELF_NO_DOT_1: Begin completions, 20 items
+// DESTRUCTOR_SELF_NO_DOT_1: Begin completions, 21 items
 // DESTRUCTOR_SELF_NO_DOT_1: End completions
 
     self.#^DESTRUCTOR_SELF_DOT_1^#
-// DESTRUCTOR_SELF_DOT_1: Begin completions, 15 items
+// DESTRUCTOR_SELF_DOT_1: Begin completions, 16 items
 // DESTRUCTOR_SELF_DOT_1: End completions
   }
 
   func test1() {
     self#^FUNC_SELF_NO_DOT_1^#
-// FUNC_SELF_NO_DOT_1: Begin completions, 20 items
+// FUNC_SELF_NO_DOT_1: Begin completions, 21 items
 // FUNC_SELF_NO_DOT_1: End completions
   }
 
   func test2() {
     self.#^FUNC_SELF_DOT_1^#
-// FUNC_SELF_DOT_1: Begin completions, 15 items
+// FUNC_SELF_DOT_1: Begin completions, 16 items
 // FUNC_SELF_DOT_1: End completions
   }
 
@@ -236,12 +237,14 @@
 // FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[Class]/Super:                  .BaseExtNestedClass[#ThisBase1.BaseExtNestedClass#]
 // FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[Enum]/Super:                   .BaseExtNestedEnum[#ThisBase1.BaseExtNestedEnum#]
 // FUNC_STATIC_SELF_NO_DOT_1-NEXT: Decl[TypeAlias]/Super:              .BaseExtNestedTypealias[#Int#]
+// FUNC_STATIC_SELF_NO_DOT_1-NEXT: Keyword[self]/CurrNominal: .self[#ThisDerived1.Type#]; name=self
 // FUNC_STATIC_SELF_NO_DOT_1-NEXT: End completions
   }
 
   class func staticTest2() {
     self.#^FUNC_STATIC_SELF_DOT_1^#
 // FUNC_STATIC_SELF_DOT_1: Begin completions
+// FUNC_STATIC_SELF_DOT_1-NEXT: Keyword[self]/CurrNominal: self[#ThisDerived1.Type#]; name=self
 // FUNC_STATIC_SELF_DOT_1-NEXT: Decl[InstanceMethod]/CurrNominal:   derivedFunc0({#self: ThisDerived1#})[#() -> Void#]
 // FUNC_STATIC_SELF_DOT_1-NEXT: Decl[StaticVar]/CurrNominal:        derivedStaticVar[#Int#]
 // FUNC_STATIC_SELF_DOT_1-NEXT: Decl[StaticMethod]/CurrNominal:     derivedStaticFunc0()[#Void#]
@@ -307,7 +310,8 @@
   init() {}
   init(x: Int) {
     self.#^STRUCT_CONSTRUCTOR_SELF_DOT_1^#
-// STRUCT_CONSTRUCTOR_SELF_DOT_1: Begin completions, 3 items
+// STRUCT_CONSTRUCTOR_SELF_DOT_1: Begin completions, 4 items
+// STRUCT_CONSTRUCTOR_SELF_DOT_1-DAG: Keyword[self]/CurrNominal:          self[#S1#]; name=self
 // STRUCT_CONSTRUCTOR_SELF_DOT_1-DAG: Decl[Constructor]/CurrNominal:      init()[#S1#];
 // STRUCT_CONSTRUCTOR_SELF_DOT_1-DAG: Decl[Constructor]/CurrNominal:      init({#x: Int#})[#S1#];
 // STRUCT_CONSTRUCTOR_SELF_DOT_1-DAG: Decl[InstanceMethod]/CurrNominal:   f()[#Void#];
diff --git a/test/IDE/complete_associated_types.swift b/test/IDE/complete_associated_types.swift
index fad21e7..dfa0eee 100644
--- a/test/IDE/complete_associated_types.swift
+++ b/test/IDE/complete_associated_types.swift
@@ -179,7 +179,7 @@
 }
 // STRUCT_TYPE_COUNT: Begin completions, 26 items
 
-// STRUCT_INSTANCE: Begin completions, 14 items
+// STRUCT_INSTANCE: Begin completions, 15 items
 // STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal:   deduceCommonA()[#Int#]
 // STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal:   deduceCommonB()[#Int#]
 // STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal:   deduceCommonC()[#Int#]
@@ -194,6 +194,7 @@
 // STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal:   deduceBarBaseC()[#Int#]
 // STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal:   deduceBarBaseD()[#Int#]
 // STRUCT_INSTANCE-DAG: Decl[InstanceMethod]/CurrNominal:   deduceBarD()[#Int#]
+// STRUCT_INSTANCE-DAG: Keyword[self]/CurrNominal: self[#StructWithAssociatedTypes#]; name=self
 // STRUCT_INSTANCE: End completions
 
 // STRUCT_TYPES: Begin completions
@@ -266,7 +267,7 @@
 func testBrokenConformances1() {
   StructWithBrokenConformance.#^BROKEN_CONFORMANCE_1^#
 }
-// BROKEN_CONFORMANCE_1: Begin completions, 34 items
+// BROKEN_CONFORMANCE_1: Begin completions, 35 items
 // BROKEN_CONFORMANCE_1-DAG: Decl[TypeAlias]/CurrNominal:        DefaultedTypeCommonA[#StructWithBrokenConformance.DefaultedTypeCommonA#]; name=DefaultedTypeCommonA
 // BROKEN_CONFORMANCE_1-DAG: Decl[TypeAlias]/CurrNominal:        DefaultedTypeCommonB[#StructWithBrokenConformance.DefaultedTypeCommonB#]; name=DefaultedTypeCommonB
 // BROKEN_CONFORMANCE_1-DAG: Decl[TypeAlias]/CurrNominal:        FooBaseDefaultedTypeB[#StructWithBrokenConformance.FooBaseDefaultedTypeB#]; name=FooBaseDefaultedTypeB
diff --git a/test/IDE/complete_at_top_level.swift b/test/IDE/complete_at_top_level.swift
index 0ec1446..6879375 100644
--- a/test/IDE/complete_at_top_level.swift
+++ b/test/IDE/complete_at_top_level.swift
@@ -178,7 +178,8 @@
 // TYPE_CHECKED_EXPR_1: Begin completions
 // TYPE_CHECKED_EXPR_1-NEXT: Decl[InstanceVar]/CurrNominal:      .instanceVar[#Int#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_1-NEXT: Decl[InstanceMethod]/CurrNominal:   .instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
-// TYPE_CHECKED_EXPR_1-NEXT:BuiltinOperator/None:                = {#FooStruct#}[#Void#]; name== FooStruct
+// TYPE_CHECKED_EXPR_1-NEXT: BuiltinOperator/None:               = {#FooStruct#}[#Void#]; name== FooStruct
+// TYPE_CHECKED_EXPR_1-NEXT: Keyword[self]/CurrNominal:          .self[#FooStruct#]; name=self
 // TYPE_CHECKED_EXPR_1-NEXT: End completions
 
 func resyncParser2() {}
@@ -191,6 +192,7 @@
 // TYPE_CHECKED_EXPR_2-NEXT: Decl[InstanceVar]/CurrNominal: .instanceVar[#Int#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_2-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_2-NEXT: BuiltinOperator/None:                     = {#FooStruct#}[#Void#]; name== FooStruct
+// TYPE_CHECKED_EXPR_2-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct#]; name=self
 // TYPE_CHECKED_EXPR_2-NEXT: End completions
 
 func resyncParser3() {}
@@ -200,12 +202,14 @@
 // TYPE_CHECKED_EXPR_3-NEXT: Decl[InstanceVar]/CurrNominal: .instanceVar[#Int#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_3-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_3-NEXT: BuiltinOperator/None:                     = {#FooStruct#}[#Void#]; name== FooStruct
+// TYPE_CHECKED_EXPR_3-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct#]; name=self
 // TYPE_CHECKED_EXPR_3-NEXT: End completions
 
 func resyncParser4() {}
 
 fooObject.#^TYPE_CHECKED_EXPR_4^#
 // TYPE_CHECKED_EXPR_4: Begin completions
+// TYPE_CHECKED_EXPR_4-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // TYPE_CHECKED_EXPR_4-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_4-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_4-NEXT: End completions
@@ -214,6 +218,7 @@
 
 fooObject.#^TYPE_CHECKED_EXPR_5^#.bar
 // TYPE_CHECKED_EXPR_5: Begin completions
+// TYPE_CHECKED_EXPR_5-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // TYPE_CHECKED_EXPR_5-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_5-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_5-NEXT: End completions
@@ -236,6 +241,7 @@
 
 fooObjectWithErrorInInit.#^TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1^#
 // TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1: Begin completions
+// TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc({#(a): Int#})[#Void#]{{; name=.+$}}
 // TYPE_CHECKED_EXPR_WITH_ERROR_IN_INIT_1-NEXT: End completions
@@ -259,6 +265,7 @@
 // TOP_LEVEL_VAR_INIT_2-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#self: FooStruct#})[#(Int) -> Void#]{{; name=.+$}}
 // TOP_LEVEL_VAR_INIT_2-NEXT: Decl[Constructor]/CurrNominal: ({#instanceVar: Int#})[#FooStruct#]{{; name=.+$}}
 // TOP_LEVEL_VAR_INIT_2-NEXT: Decl[Constructor]/CurrNominal: ()[#FooStruct#]{{; name=.+$}}
+// TOP_LEVEL_VAR_INIT_2-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct.Type#]; name=self
 // TOP_LEVEL_VAR_INIT_2-NEXT: End completions
 
 func resyncParser8() {}
diff --git a/test/IDE/complete_call_arg.swift b/test/IDE/complete_call_arg.swift
index 51bacbf..2bfe9ff 100644
--- a/test/IDE/complete_call_arg.swift
+++ b/test/IDE/complete_call_arg.swift
@@ -413,7 +413,8 @@
     self.collectionView? .#^BOUND_IUO^#x
     self.collectionView! .#^FORCED_IUO^#x
   }
-  // MEMBEROF_IUO: Begin completions, 1 items
+  // MEMBEROF_IUO: Begin completions, 2 items
+  // MEMBEROF_IUO: Keyword[self]/CurrNominal: self[#Foo#]; name=self
   // MEMBEROF_IUO: Decl[InstanceVar]/CurrNominal: x[#Int#]; name=x
   // MEMBEROF_IUO: End completions
 }
diff --git a/test/IDE/complete_constructor.swift b/test/IDE/complete_constructor.swift
index b84176e..f0de365 100644
--- a/test/IDE/complete_constructor.swift
+++ b/test/IDE/complete_constructor.swift
@@ -43,8 +43,9 @@
 
 func testImplicitConstructors1() {
   ImplicitConstructors1#^IMPLICIT_CONSTRUCTORS_1^#
-// IMPLICIT_CONSTRUCTORS_1: Begin completions, 1 items
+// IMPLICIT_CONSTRUCTORS_1: Begin completions, 2 items
 // IMPLICIT_CONSTRUCTORS_1-DAG: Decl[Constructor]/CurrNominal: ()[#ImplicitConstructors1#]{{; name=.+$}}
+// IMPLICIT_CONSTRUCTORS_1-DAG: Keyword[self]/CurrNominal:     .self[#ImplicitConstructors1.Type#]; name=self
 // IMPLICIT_CONSTRUCTORS_1: End completions
 }
 func testImplicitConstructors1P() {
@@ -58,9 +59,10 @@
 
 func testImplicitConstructors2() {
   ImplicitConstructors2#^IMPLICIT_CONSTRUCTORS_2^#
-// IMPLICIT_CONSTRUCTORS_2: Begin completions, 2 items
+// IMPLICIT_CONSTRUCTORS_2: Begin completions, 3 items
 // IMPLICIT_CONSTRUCTORS_2-DAG: Decl[Constructor]/CurrNominal: ({#instanceVar: Int#})[#ImplicitConstructors2#]{{; name=.+$}}
 // IMPLICIT_CONSTRUCTORS_2-DAG: Decl[Constructor]/CurrNominal: ()[#ImplicitConstructors2#]{{; name=.+$}}
+// IMPLICIT_CONSTRUCTORS_2-DAG: Keyword[self]/CurrNominal:     .self[#ImplicitConstructors2.Type#]; name=self
 // IMPLICIT_CONSTRUCTORS_2: End completions
 }
 func testImplicitConstructors2P() {
@@ -78,10 +80,11 @@
 
 func testExplicitConstructors1() {
   ExplicitConstructors1#^EXPLICIT_CONSTRUCTORS_1^#
-// EXPLICIT_CONSTRUCTORS_1: Begin completions, 3 items
+// EXPLICIT_CONSTRUCTORS_1: Begin completions, 4 items
 // EXPLICIT_CONSTRUCTORS_1-DAG: Decl[Constructor]/CurrNominal: ()[#ExplicitConstructors1#]{{; name=.+$}}
 // EXPLICIT_CONSTRUCTORS_1-DAG: Decl[Constructor]/CurrNominal: ({#a: Int#})[#ExplicitConstructors1#]{{; name=.+$}}
 // EXPLICIT_CONSTRUCTORS_1-DAG: Decl[Constructor]/CurrNominal: ({#a: Int#}, {#b: Float#})[#ExplicitConstructors1#]{{; name=.+$}}
+// EXPLICIT_CONSTRUCTORS_1-DAG: Keyword[self]/CurrNominal: .self[#ExplicitConstructors1.Type#]; name=self
 // EXPLICIT_CONSTRUCTORS_1: End completions
 }
 func testExplicitConstructors1P() {
@@ -94,10 +97,11 @@
 
 ExplicitConstructors1#^EXPLICIT_CONSTRUCTORS_2^#
 
-// EXPLICIT_CONSTRUCTORS_2: Begin completions, 3 items
+// EXPLICIT_CONSTRUCTORS_2: Begin completions, 4 items
 // EXPLICIT_CONSTRUCTORS_2-DAG: Decl[Constructor]/CurrNominal: ()[#ExplicitConstructors1#]
 // EXPLICIT_CONSTRUCTORS_2-DAG: Decl[Constructor]/CurrNominal: ({#a: Int#})[#ExplicitConstructors1#]
 // EXPLICIT_CONSTRUCTORS_2-DAG: Decl[Constructor]/CurrNominal: ({#a: Int#}, {#b: Float#})[#ExplicitConstructors1#]
+// EXPLICIT_CONSTRUCTORS_2-DAG: Keyword[self]/CurrNominal:     .self[#ExplicitConstructors1.Type#]; name=self
 // EXPLICIT_CONSTRUCTORS_2: End completions
 
 ExplicitConstructors1(#^EXPLICIT_CONSTRUCTORS_2P^#
@@ -130,9 +134,10 @@
 
 func testExplicitConstructorsSelector1() {
   ExplicitConstructorsSelector1#^EXPLICIT_CONSTRUCTORS_SELECTOR_1^#
-// EXPLICIT_CONSTRUCTORS_SELECTOR_1: Begin completions, 2 items
+// EXPLICIT_CONSTRUCTORS_SELECTOR_1: Begin completions, 3 items
 // EXPLICIT_CONSTRUCTORS_SELECTOR_1-DAG: Decl[Constructor]/CurrNominal: ({#int: Int#})[#ExplicitConstructorsSelector1#]{{; name=.+$}}
 // EXPLICIT_CONSTRUCTORS_SELECTOR_1-DAG: Decl[Constructor]/CurrNominal: ({#int: Int#}, {#andFloat: Float#})[#ExplicitConstructorsSelector1#]{{; name=.+$}}
+// EXPLICIT_CONSTRUCTORS_SELECTOR_1-DAG: Keyword[self]/CurrNominal:     .self[#ExplicitConstructorsSelector1.Type#]; name=self
 // EXPLICIT_CONSTRUCTORS_SELECTOR_1: End completions
 }
 
@@ -145,11 +150,12 @@
 
 func testExplicitConstructorsSelector2() {
   ExplicitConstructorsSelector2#^EXPLICIT_CONSTRUCTORS_SELECTOR_2^#
-// EXPLICIT_CONSTRUCTORS_SELECTOR_2: Begin completions, 4 items
+// EXPLICIT_CONSTRUCTORS_SELECTOR_2: Begin completions, 5 items
 // EXPLICIT_CONSTRUCTORS_SELECTOR_2-DAG: Decl[Constructor]/CurrNominal: ({#noArgs: ()#})[#ExplicitConstructorsSelector2#]{{; name=.+$}}
 // EXPLICIT_CONSTRUCTORS_SELECTOR_2-DAG: Decl[Constructor]/CurrNominal: ({#Int#})[#ExplicitConstructorsSelector2#]{{; name=.+$}}
 // EXPLICIT_CONSTRUCTORS_SELECTOR_2-DAG: Decl[Constructor]/CurrNominal: ({#Int#}, {#withFloat: Float#})[#ExplicitConstructorsSelector2#]{{; name=.+$}}
 // EXPLICIT_CONSTRUCTORS_SELECTOR_2-DAG: Decl[Constructor]/CurrNominal: ({#int: Int#}, {#Float#})[#ExplicitConstructorsSelector2#]{{; name=.+$}}
+// EXPLICIT_CONSTRUCTORS_SELECTOR_2-DAG: Keyword[self]/CurrNominal:     .self[#ExplicitConstructorsSelector2.Type#]; name=self
 // EXPLICIT_CONSTRUCTORS_SELECTOR_2: End completions
 }
 
@@ -174,9 +180,10 @@
 func testExplicitConstructorsBaseDerived1() {
   ExplicitConstructorsDerived1#^EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1^#
 }
-// EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1: Begin completions, 2 items
+// EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1: Begin completions, 3 items
 // EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1-DAG: Decl[Constructor]/CurrNominal:  ()[#ExplicitConstructorsDerived1#]{{; name=.+$}}
 // EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1-DAG: Decl[Constructor]/CurrNominal:  ({#a: Int#})[#ExplicitConstructorsDerived1#]{{; name=.+$}}
+// EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1-DAG: Keyword[self]/CurrNominal:     .self[#ExplicitConstructorsDerived1.Type#]; name=self
 // EXPLICIT_CONSTRUCTORS_BASE_DERIVED_1: End completions
 
 func testGetInitFromMetatype1() {
@@ -184,6 +191,7 @@
 }
 
 // INIT_FROM_METATYPE1: Begin completions
+// INIT_FROM_METATYPE1-NEXT: Keyword[self]/CurrNominal: self[#ExplicitConstructorsBase1.Type#]; name=self
 // INIT_FROM_METATYPE1-NEXT: Decl[Constructor]/CurrNominal:      init()[#ExplicitConstructorsBase1#]{{; name=.+$}}
 // INIT_FROM_METATYPE1-NEXT: Decl[Constructor]/CurrNominal:      init({#a: Int#})[#ExplicitConstructorsBase1#]{{; name=.+$}}
 // INIT_FROM_METATYPE1-NEXT: End completions
diff --git a/test/IDE/complete_crashes.swift b/test/IDE/complete_crashes.swift
index 8549d0e..4cfcfa9 100644
--- a/test/IDE/complete_crashes.swift
+++ b/test/IDE/complete_crashes.swift
@@ -30,9 +30,10 @@
 func badMembers2(_ a: BadMembers2) {
   a#^BAD_MEMBERS_2^#
 }
-// BAD_MEMBERS_2: Begin completions, 2 items
+// BAD_MEMBERS_2: Begin completions, 3 items
 // BAD_MEMBERS_2-NEXT: Decl[InstanceVar]/CurrNominal: .prop[#Int#]{{; name=.+$}}
 // BAD_MEMBERS_2-NEXT: Decl[Subscript]/CurrNominal:   [{#Int#}][#Double#]{{; name=.+$}}
+// BAD_MEMBERS_2-NEXT: Keyword[self]/CurrNominal:     .self[#BadMembers2#]; name=self
 // BAD_MEMBERS_2-NEXT: End completions
 
 func globalFunc() {}
@@ -220,10 +221,11 @@
 func foo_38149042(bar: Bar_38149042) {
   _ = bar.foo? #^RDAR_38149042^# .x
 }
-// RDAR_38149042: Begin completions, 3 items
+// RDAR_38149042: Begin completions, 4 items
 // RDAR_38149042-DAG: Decl[InstanceVar]/CurrNominal:                  .x[#Int#]; name=x
 // RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']=== {#AnyObject?#}[#Bool#]; name==== AnyObject?
 // RDAR_38149042-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: [' ']!== {#AnyObject?#}[#Bool#]; name=!== AnyObject?
+// RDAR_38149042-DAG: Keyword[self]/CurrNominal: .self[#Baz_38149042#]; name=self
 // RDAR_38149042: End completions
 
 // rdar://problem/38272904
diff --git a/test/IDE/complete_doc_keyword.swift b/test/IDE/complete_doc_keyword.swift
index 7ed141c..318a461 100644
--- a/test/IDE/complete_doc_keyword.swift
+++ b/test/IDE/complete_doc_keyword.swift
@@ -93,6 +93,7 @@
   let c = C1()
   c.#^MEMBER1^#
 // MEMBER1: Begin completions
+// MEMBER1-NEXT: Keyword[self]/CurrNominal: self[#C1#]; name=self
 // MEMBER1-NEXT: Decl[InstanceVar]/CurrNominal/keyword[v1, Int]/recommended[v2]: v1[#Int#]
 // MEMBER1-NEXT: Decl[InstanceVar]/CurrNominal/keyword[v2, Int]/recommendedover[v1]: v2[#Int#]
 // MEMBER1-NEXT: Decl[InstanceMethod]/CurrNominal/keyword[f1, func]/recommended[f2]: f1()[#Void#]
@@ -103,6 +104,7 @@
   let s = S3()
   s.#^MEMBER2^#
 // MEMBER2: Begin completions
+// MEMBER2-NEXT: Keyword[self]/CurrNominal: self[#S3#]; name=self
 // MEMBER2-NEXT: Decl[InstanceMethod]/CurrNominal/nonmutatingvariant[fooing]: foo()[#Void#]
 // MEMBER2-NEXT: Decl[InstanceMethod]/CurrNominal/mutatingvariant[foo]: fooing()[#S3#]
 }
diff --git a/test/IDE/complete_dynamic_lookup.swift b/test/IDE/complete_dynamic_lookup.swift
index 9d6a060..d0419fe 100644
--- a/test/IDE/complete_dynamic_lookup.swift
+++ b/test/IDE/complete_dynamic_lookup.swift
@@ -234,9 +234,11 @@
 // TLOC_MEMBERS_NO_DOT-NEXT: Decl[InstanceVar]/CurrNominal:    .topLevelObjcClass_Property1[#Int#]{{; name=.+$}}
 // TLOC_MEMBERS_NO_DOT-NEXT: Decl[InfixOperatorFunction]/OtherModule[Swift]: === {#AnyObject?#}[#Bool#];
 // TLOC_MEMBERS_NO_DOT-NEXT: Decl[InfixOperatorFunction]/OtherModule[Swift]: !== {#AnyObject?#}[#Bool#];
+// TLOC_MEMBERS_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#TopLevelObjcClass#]; name=self
 // TLOC_MEMBERS_NO_DOT-NEXT: End completions
 
 // TLOC_MEMBERS_DOT: Begin completions
+// TLOC_MEMBERS_DOT-NEXT: Keyword[self]/CurrNominal: self[#TopLevelObjcClass#]; name=self
 // TLOC_MEMBERS_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: returnsObjcClass({#(i): Int#})[#TopLevelObjcClass#]{{; name=.+$}}
 // TLOC_MEMBERS_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: topLevelObjcClass_InstanceFunc1()[#Void#]{{; name=.+$}}
 // TLOC_MEMBERS_DOT-NEXT: Decl[InstanceVar]/CurrNominal:    topLevelObjcClass_Property1[#Int#]{{; name=.+$}}
@@ -474,6 +476,7 @@
 }
 // DL_FUNC_NAME_BANG_1: Begin completions
 // DL_FUNC_NAME_BANG_1-NEXT: Pattern/CurrModule: ({#Int#})[#TopLevelObjcClass#]
+// DL_FUNC_NAME_BANG_1-NEXT: Keyword[self]/CurrNominal: .self[#(Int) -> TopLevelObjcClass#]; name=self
 // DL_FUNC_NAME_BANG_1-NEXT: End completions
 
 func testAnyObject14() {
diff --git a/test/IDE/complete_enum_elements.swift b/test/IDE/complete_enum_elements.swift
index 94b3126..b8e0152 100644
--- a/test/IDE/complete_enum_elements.swift
+++ b/test/IDE/complete_enum_elements.swift
@@ -91,9 +91,11 @@
 // FOO_ENUM_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .hash({#self: FooEnum#})[#(into: inout Hasher) -> Void#]; name=hash(FooEnum)
 // FOO_ENUM_NO_DOT-NEXT: Decl[TypeAlias]/CurrNominal: .AllCases[#[FooEnum]#]{{; name=.+$}}
 // FOO_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal: .allCases[#[FooEnum]#]{{; name=.+$}}
+// FOO_ENUM_NO_DOT-NEXT: Keyword[self]/CurrNominal:   .self[#FooEnum.Type#]; name=self
 // FOO_ENUM_NO_DOT-NEXT: End completions
 
 // FOO_ENUM_DOT: Begin completions
+// FOO_ENUM_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooEnum.Type#]; name=self
 // FOO_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Foo1[#FooEnum#]{{; name=.+$}}
 // FOO_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal: Foo2[#FooEnum#]{{; name=.+$}}
 // FOO_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: hash({#self: FooEnum#})[#(into: inout Hasher) -> Void#]; name=hash(FooEnum)
@@ -102,6 +104,7 @@
 // FOO_ENUM_DOT-NEXT: End completions
 
 // FOO_ENUM_DOT_INVALID: Begin completions
+// FOO_ENUM_DOT_INVALID-NEXT: Keyword[self]/CurrNominal: self[#FooEnum.Type#]; name=self
 // FOO_ENUM_DOT_INVALID-NEXT: Decl[EnumElement]/CurrNominal: Foo1[#FooEnum#]{{; name=.+$}}
 // FOO_ENUM_DOT_INVALID-NEXT: Decl[EnumElement]/CurrNominal: Foo2[#FooEnum#]{{; name=.+$}}
 // FOO_ENUM_DOT_INVALID-NEXT: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: hash({#self: FooEnum#})[#(into: inout Hasher) -> Void#]; name=hash(FooEnum)
@@ -165,9 +168,11 @@
 // BAR_ENUM_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal:   .barInstanceFunc({#self: &BarEnum#})[#() -> Void#]{{; name=.+$}}
 // BAR_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal:        .staticVar[#Int#]{{; name=.+$}}
 // BAR_ENUM_NO_DOT-NEXT: Decl[StaticMethod]/CurrNominal:     .barStaticFunc()[#Void#]{{; name=.+$}}
+// BAR_ENUM_NO_DOT-NEXT: Keyword[self]/CurrNominal:          .self[#BarEnum.Type#]; name=self
 // BAR_ENUM_NO_DOT-NEXT: End completions
 
 // BAR_ENUM_DOT: Begin completions
+// BAR_ENUM_DOT-NEXT: Keyword[self]/CurrNominal:          self[#BarEnum.Type#]; name=self
 // BAR_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:      Bar1[#BarEnum#]{{; name=.+$}}
 // BAR_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:      Bar2()[#() -> BarEnum#]{{; name=.+$}}
 // BAR_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:      Bar3({#Int#})[#(Int) -> BarEnum#]{{; name=.+$}}
@@ -201,13 +206,14 @@
 // BAZ_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/ExprSpecific: .Baz2({#T#})[#(T) -> BazEnum<T>#]{{; name=.+$}}
 // BAZ_ENUM_TYPE_CONTEXT: End completions
 
-// BAZ_INT_ENUM_NO_DOT: Begin completions, 6 items
+// BAZ_INT_ENUM_NO_DOT: Begin completions, 7 items
 // BAZ_INT_ENUM_NO_DOT-NEXT: Decl[EnumElement]/CurrNominal:    .Baz1[#BazEnum<T>#]{{; name=.+$}}
 // BAZ_INT_ENUM_NO_DOT-NEXT: Decl[EnumElement]/CurrNominal:    .Baz2({#T#})[#(T) -> BazEnum<T>#]{{; name=.+$}}
 // BAZ_INT_ENUM_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .bazInstanceFunc({#self: &BazEnum<Int>#})[#() -> Void#]{{; name=.+$}}
 // BAZ_INT_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal:      .staticVar[#Int#]{{; name=.+$}}
 // BAZ_INT_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal:      .staticVarT[#Int#]{{; name=.+$}}
 // BAZ_INT_ENUM_NO_DOT-NEXT: Decl[StaticMethod]/CurrNominal:   .bazStaticFunc()[#Void#]{{; name=.+$}}
+// BAZ_INT_ENUM_NO_DOT-NEXT: Keyword[self]/CurrNominal:        .self[#BazEnum<Int>.Type#]; name=self
 // BAZ_INT_ENUM_NO_DOT-NEXT: End completions
 
 // BAZ_T_ENUM_NO_DOT: Begin completions
@@ -217,9 +223,11 @@
 // BAZ_T_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal:      .staticVar[#Int#]{{; name=.+$}}
 // BAZ_T_ENUM_NO_DOT-NEXT: Decl[StaticVar]/CurrNominal:      .staticVarT[#_#]{{; name=.+$}}
 // BAZ_T_ENUM_NO_DOT-NEXT: Decl[StaticMethod]/CurrNominal:   .bazStaticFunc()[#Void#]{{; name=.+$}}
+// BAZ_T_ENUM_NO_DOT-NEXT: Keyword[self]/CurrNominal:        .self[#BazEnum<_>.Type#]; name=self
 // BAZ_T_ENUM_NO_DOT-NEXT: End completions
 
-// BAZ_INT_ENUM_DOT: Begin completions, 6 items
+// BAZ_INT_ENUM_DOT: Begin completions, 7 items
+// BAZ_INT_ENUM_DOT-NEXT: Keyword[self]/CurrNominal:        self[#BazEnum<Int>.Type#]; name=self
 // BAZ_INT_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:    Baz1[#BazEnum<T>#]{{; name=.+$}}
 // BAZ_INT_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:    Baz2({#T#})[#(T) -> BazEnum<T>#]{{; name=.+$}}
 // BAZ_INT_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: bazInstanceFunc({#self: &BazEnum<Int>#})[#() -> Void#]{{; name=.+$}}
@@ -228,7 +236,8 @@
 // BAZ_INT_ENUM_DOT-NEXT: Decl[StaticMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]:   bazStaticFunc()[#Void#]{{; name=.+$}}
 // BAZ_INT_ENUM_DOT-NEXT: End completions
 
-// BAZ_T_ENUM_DOT: Begin completions, 6 items
+// BAZ_T_ENUM_DOT: Begin completions, 7 items
+// BAZ_T_ENUM_DOT-NEXT: Keyword[self]/CurrNominal:        self[#BazEnum<_>.Type#]; name=self
 // BAZ_T_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:    Baz1[#BazEnum<T>#]{{; name=.+$}}
 // BAZ_T_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:    Baz2({#T#})[#(T) -> BazEnum<T>#]{{; name=.+$}}
 // BAZ_T_ENUM_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: bazInstanceFunc({#self: &BazEnum<_>#})[#() -> Void#]{{; name=.+$}}
@@ -247,15 +256,17 @@
 // QUX_ENUM_TYPE_CONTEXT-DAG: Decl[EnumElement]/ExprSpecific: .Qux2[#QuxEnum#]{{; name=.+$}}
 // QUX_ENUM_TYPE_CONTEXT: End completions
 
-// QUX_ENUM_NO_DOT: Begin completions, 5 items
+// QUX_ENUM_NO_DOT: Begin completions, 6 items
 // QUX_ENUM_NO_DOT-NEXT: Decl[EnumElement]/CurrNominal:    .Qux1[#QuxEnum#]{{; name=.+$}}
 // QUX_ENUM_NO_DOT-NEXT: Decl[EnumElement]/CurrNominal:    .Qux2[#QuxEnum#]{{; name=.+$}}
 // QUX_ENUM_NO_DOT-NEXT: Decl[TypeAlias]/CurrNominal:      .RawValue[#Int#]{{; name=.+$}}
 // QUX_ENUM_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .hash({#self: QuxEnum#})[#(into: inout Hasher) -> Void#]; name=hash(QuxEnum)
 // QUX_ENUM_NO_DOT-NEXT: Decl[Constructor]/CurrNominal:    ({#rawValue: Int#})[#QuxEnum?#]{{; name=.+$}}
+// QUX_ENUM_NO_DOT-NEXT: Keyword[self]/CurrNominal:        .self[#QuxEnum.Type#]; name=self
 // QUX_ENUM_NO_DOT-NEXT: End completions
 
-// QUX_ENUM_DOT: Begin completions, 5 items
+// QUX_ENUM_DOT: Begin completions, 6 items
+// QUX_ENUM_DOT-NEXT: Keyword[self]/CurrNominal:        self[#QuxEnum.Type#]; name=self
 // QUX_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:    Qux1[#QuxEnum#]{{; name=.+$}}
 // QUX_ENUM_DOT-NEXT: Decl[EnumElement]/CurrNominal:    Qux2[#QuxEnum#]{{; name=.+$}}
 // QUX_ENUM_DOT-NEXT: Decl[TypeAlias]/CurrNominal:      RawValue[#Int#]{{; name=.+$}}
diff --git a/test/IDE/complete_exception.swift b/test/IDE/complete_exception.swift
index f810cf1..e3aadfb 100644
--- a/test/IDE/complete_exception.swift
+++ b/test/IDE/complete_exception.swift
@@ -196,8 +196,9 @@
   } catch {
     error.#^INSIDE_CATCH_ERR_DOT1^#
   }
-// ERROR_DOT-NOT: Begin completions
 }
+// ERROR_DOT: Begin completions
+// ERROR_DOT: Keyword[self]/CurrNominal: self[#Error#]; name=self
 func test013() {
   do {
   } catch let e {
diff --git a/test/IDE/complete_expr_tuple.swift b/test/IDE/complete_expr_tuple.swift
index b2bfb9f..c5d712d 100644
--- a/test/IDE/complete_expr_tuple.swift
+++ b/test/IDE/complete_expr_tuple.swift
@@ -27,7 +27,7 @@
   var t = (1, 2.0)
   t#^TUPLE_NO_DOT_1^#
 }
-// TUPLE_NO_DOT_1: Begin completions, 9 items
+// TUPLE_NO_DOT_1: Begin completions, 10 items
 // TUPLE_NO_DOT_1-DAG: Pattern/CurrNominal: .0[#Int#]{{; name=.+$}}
 // TUPLE_NO_DOT_1-DAG: Pattern/CurrNominal: .1[#Double#]{{; name=.+$}}
 // TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#(Int, Double)#}[#Bool#]{{; name=.+$}}
@@ -37,13 +37,14 @@
 // TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#(Int, Double)#}[#Bool#]{{; name=.+$}}
 // TUPLE_NO_DOT_1-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: > {#(Int, Double)#}[#Bool#]{{; name=.+$}}
 // TUPLE_NO_DOT_1-DAG: BuiltinOperator/None:                                   = {#(Int, Double)#}[#Void#]{{; name=.+$}}
+// TUPLE_NO_DOT_1-NEXT: Keyword[self]/CurrNominal: .self[#(Int, Double)#]; name=self
 // TUPLE_NO_DOT_1-NEXT: End completions
 
 func testTupleNoDot2() {
   var t = (foo: 1, bar: 2.0)
   t#^TUPLE_NO_DOT_2^#
 }
-// TUPLE_NO_DOT_2: Begin completions, 9 items
+// TUPLE_NO_DOT_2: Begin completions, 10 items
 // TUPLE_NO_DOT_2-DAG: Pattern/CurrNominal: .foo[#Int#]{{; name=.+$}}
 // TUPLE_NO_DOT_2-DAG: Pattern/CurrNominal: .bar[#Double#]{{; name=.+$}}
 // TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#(Int, Double)#}[#Bool#]{{; name=.+$}}
@@ -53,13 +54,14 @@
 // TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#(Int, Double)#}[#Bool#]{{; name=.+$}}
 // TUPLE_NO_DOT_2-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: > {#(Int, Double)#}[#Bool#]{{; name=.+$}}
 // TUPLE_NO_DOT_2-DAG: BuiltinOperator/None:                                   = {#(foo: Int, bar: Double)#}[#Void#]{{; name=.+$}}
+// TUPLE_NO_DOT_2-DAG: Keyword[self]/CurrNominal: .self[#(foo: Int, bar: Double)#]; name=self
 // TUPLE_NO_DOT_2-NEXT: End completions
 
 func testTupleNoDot3() {
   var t = (foo: 1, 2.0)
   t#^TUPLE_NO_DOT_3^#
 }
-// TUPLE_NO_DOT_3: Begin completions, 9 items
+// TUPLE_NO_DOT_3: Begin completions, 10 items
 // TUPLE_NO_DOT_3-DAG: Pattern/CurrNominal: .foo[#Int#]{{; name=.+$}}
 // TUPLE_NO_DOT_3-DAG: Pattern/CurrNominal: .1[#Double#]{{; name=.+$}}
 // TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: == {#(Int, Double)#}[#Bool#]{{; name=.+$}}
@@ -69,13 +71,15 @@
 // TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: != {#(Int, Double)#}[#Bool#]{{; name=.+$}}
 // TUPLE_NO_DOT_3-DAG: Decl[InfixOperatorFunction]/OtherModule[Swift]: > {#(Int, Double)#}[#Bool#]{{; name=.+$}}
 // TUPLE_NO_DOT_3-DAG: BuiltinOperator/None:                                   = {#(foo: Int, Double)#}[#Void#]{{; name=.+$}}
+// TUPLE_NO_DOT_3-DAG: Keyword[self]/CurrNominal: .self[#(foo: Int, Double)#]; name=self
 // TUPLE_NO_DOT_3-NEXT: End completions
 
 func testTupleDot1() {
   var t = (1, 2.0)
   t.#^TUPLE_DOT_1^#
 }
-// TUPLE_DOT_1: Begin completions, 2 items
+// TUPLE_DOT_1: Begin completions, 3 items
+// TUPLE_DOT_1-NEXT: Keyword[self]/CurrNominal: self[#(Int, Double)#]; name=self
 // TUPLE_DOT_1-NEXT: Pattern/CurrNominal: 0[#Int#]{{; name=.+$}}
 // TUPLE_DOT_1-NEXT: Pattern/CurrNominal: 1[#Double#]{{; name=.+$}}
 // TUPLE_DOT_1-NEXT: End completions
@@ -84,7 +88,8 @@
   var t = (foo: 1, bar: 2.0)
   t.#^TUPLE_DOT_2^#
 }
-// TUPLE_DOT_2: Begin completions, 2 items
+// TUPLE_DOT_2: Begin completions, 3 items
+// TUPLE_DOT_2-NEXT: Keyword[self]/CurrNominal: self[#(foo: Int, bar: Double)#]; name=self
 // TUPLE_DOT_2-NEXT: Pattern/CurrNominal: foo[#Int#]{{; name=.+$}}
 // TUPLE_DOT_2-NEXT: Pattern/CurrNominal: bar[#Double#]{{; name=.+$}}
 // TUPLE_DOT_2-NEXT: End completions
@@ -93,7 +98,8 @@
   var t = (foo: 1, 2.0)
   t.#^TUPLE_DOT_3^#
 }
-// TUPLE_DOT_3: Begin completions, 2 items
+// TUPLE_DOT_3: Begin completions, 3 items
+// TUPLE_DOT_3-NEXT: Keyword[self]/CurrNominal: self[#(foo: Int, Double)#]; name=self
 // TUPLE_DOT_3-NEXT: Pattern/CurrNominal: foo[#Int#]{{; name=.+$}}
 // TUPLE_DOT_3-NEXT: Pattern/CurrNominal: 1[#Double#]{{; name=.+$}}
 // TUPLE_DOT_3-NEXT: End completions
@@ -107,7 +113,8 @@
   var t = (foo: FooStruct(), i: Int)
   t.foo.#^TUPLE_NESTED_1^#
 }
-// TUPLE_NESTED_1: Begin completions, 2 items
+// TUPLE_NESTED_1: Begin completions, 3 items
+// TUPLE_NESTED_1-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // TUPLE_NESTED_1-NEXT: Decl[InstanceVar]/CurrNominal: fooInstanceVar[#Int#]{{; name=.+$}}
 // TUPLE_NESTED_1-NEXT: Decl[InstanceVar]/CurrNominal: barInstanceVar[#Double#]{{; name=.+$}}
 // TUPLE_NESTED_1-NEXT: End completions
diff --git a/test/IDE/complete_from_clang_framework.swift b/test/IDE/complete_from_clang_framework.swift
index 0ff5e6a..e580884 100644
--- a/test/IDE/complete_from_clang_framework.swift
+++ b/test/IDE/complete_from_clang_framework.swift
@@ -44,6 +44,7 @@
 func testSwiftCompletions(foo: SwiftStruct) {
   foo.#^SWIFT_COMPLETIONS^#
 // SWIFT_COMPLETIONS: Begin completions
+// SWIFT_COMPLETIONS-NEXT: Keyword[self]/CurrNominal: self[#SwiftStruct#]; name=self
 // SWIFT_COMPLETIONS-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
 // SWIFT_COMPLETIONS-NEXT: End completions
 }
@@ -227,6 +228,7 @@
   fooFunc1#^FUNCTION_CALL_1^#
 // FUNCTION_CALL_1: Begin completions
 // FUNCTION_CALL_1-NEXT: Pattern/CurrModule: ({#(a): Int32#})[#Int32#]{{; name=.+$}}
+// FUNCTION_CALL_1-NEXT: Keyword[self]/CurrNominal: .self[#(Int32) -> Int32#]; name=self
 // FUNCTION_CALL_1-NEXT: End completions
 }
 
@@ -234,6 +236,7 @@
   fooFunc1AnonymousParam#^FUNCTION_CALL_2^#
 // FUNCTION_CALL_2: Begin completions
 // FUNCTION_CALL_2-NEXT: Pattern/CurrModule: ({#Int32#})[#Int32#]{{; name=.+$}}
+// FUNCTION_CALL_2-NEXT: Keyword[self]/CurrNominal: .self[#(Int32) -> Int32#]; name=self
 // FUNCTION_CALL_2-NEXT: End completions
 }
 
@@ -242,6 +245,7 @@
 // CLANG_STRUCT_MEMBERS_1: Begin completions
 // CLANG_STRUCT_MEMBERS_1-NEXT: Decl[Constructor]/CurrNominal: ()[#FooStruct1#]{{; name=.+$}}
 // CLANG_STRUCT_MEMBERS_1-NEXT: Decl[Constructor]/CurrNominal: ({#x: Int32#}, {#y: Double#})[#FooStruct1#]{{; name=.+$}}
+// CLANG_STRUCT_MEMBERS_1-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct1.Type#]; name=self
 // CLANG_STRUCT_MEMBERS_1-NEXT: End completions
 }
 
@@ -267,6 +271,7 @@
 // CLANG_CLASS_MEMBERS_1-NEXT: Decl[InstanceMethod]/CurrNominal:   .nonInternalMeth({#self: FooClassBase#})[#() -> Any?#]
 // CLANG_CLASS_MEMBERS_1-NEXT: Decl[StaticMethod]/CurrNominal:     ._internalMeth1()[#Any!#]
 // CLANG_CLASS_MEMBERS_1-NEXT: Decl[InstanceMethod]/CurrNominal:   ._internalMeth1({#self: FooClassBase#})[#() -> Any?#]
+// CLANG_CLASS_MEMBERS_1-NEXT: Keyword[self]/CurrNominal: .self[#FooClassBase.Type#]; name=self
 // CLANG_CLASS_MEMBERS_1-NEXT: End completions
 }
 
@@ -299,6 +304,7 @@
 // CLANG_CLASS_MEMBERS_2-NEXT: Decl[InstanceMethod]/Super:         .nonInternalMeth({#self: FooClassBase#})[#() -> Any?#]
 // CLANG_CLASS_MEMBERS_2-NEXT: Decl[StaticMethod]/Super:           ._internalMeth1()[#Any!#]
 // CLANG_CLASS_MEMBERS_2-NEXT: Decl[InstanceMethod]/Super:         ._internalMeth1({#self: FooClassBase#})[#() -> Any?#]
+// CLANG_CLASS_MEMBERS_2-NEXT: Keyword[self]/CurrNominal: .self[#FooClassDerived.Type#]; name=self
 // CLANG_CLASS_MEMBERS_2-NEXT: End completions
 }
 
diff --git a/test/IDE/complete_from_clang_importer_framework.swift b/test/IDE/complete_from_clang_importer_framework.swift
index 3979d7b..1a4fe14 100644
--- a/test/IDE/complete_from_clang_importer_framework.swift
+++ b/test/IDE/complete_from_clang_importer_framework.swift
@@ -59,7 +59,8 @@
 func testClangMember1() {
 	var FS = FooStruct1()
 	FS.#^CLANG_MEMBER1^#
-// CLANG_MEMBERS1: Begin completions, 2 items
+// CLANG_MEMBERS1: Begin completions, 3 items
 // CLANG_MEMBERS1-DAG: Decl[InstanceVar]/CurrNominal/keyword[x, Struct1]/recommended[y]: x[#Int32#]{{; name=.+$}}
 // CLANG_MEMBERS1-DAG: Decl[InstanceVar]/CurrNominal/keyword[y, Struct1]/recommendedover[x]: y[#Double#]{{; name=.+$}}
+// CLANG_MEMBERS1-DAG: Keyword[self]/CurrNominal: self[#FooStruct1#]; name=self
 }
diff --git a/test/IDE/complete_from_constraint_extensions.swift b/test/IDE/complete_from_constraint_extensions.swift
index 1b91f54..52b91f9 100644
--- a/test/IDE/complete_from_constraint_extensions.swift
+++ b/test/IDE/complete_from_constraint_extensions.swift
@@ -22,7 +22,8 @@
   I1.#^CONSTRAINT1^#
 }
 
-// CONSTRAINT1: 	 Begin completions, 1 items
+// CONSTRAINT1: 	 Begin completions, 2 items
+// CONSTRAINT1-NEXT: Keyword[self]/CurrNominal: self[#Example<S1>#]; name=self
 // CONSTRAINT1-NEXT: Decl[InstanceMethod]/CurrNominal:   P1Method()[#Void#]; name=P1Method()
 // CONSTRAINT1-NEXT: End completions
 
@@ -31,7 +32,8 @@
   I2.#^CONSTRAINT2^#
 }
 
-// CONSTRAINT2:      Begin completions, 1 items
+// CONSTRAINT2:      Begin completions, 2 items
+// CONSTRAINT2-NEXT: Keyword[self]/CurrNominal: self[#Example<S2>#]; name=self
 // CONSTRAINT2-NEXT: Decl[InstanceMethod]/CurrNominal:   P2Method()[#Void#]; name=P2Method()
 // CONSTRAINT2-NEXT: End completions
 
@@ -48,6 +50,7 @@
 func foo3() {
   ConcreteCollection<Int>().#^CONSTRAINT3^#
 }
-// CONSTRAINT3:      Begin completions, 1 items
+// CONSTRAINT3:      Begin completions, 2 items
+// CONSTRAINT3-NEXT: Keyword[self]/CurrNominal: self[#ConcreteCollection<Int>#]; name=self
 // CONSTRAINT3-NEXT: Decl[InstanceVar]/Super:            indices[#MyDefaultIndices<ConcreteCollection<Int>>#]; name=indices
 // CONSTRAINT3-NEXT: End completions
diff --git a/test/IDE/complete_from_swift_module.swift b/test/IDE/complete_from_swift_module.swift
index 77794ed..5763610 100644
--- a/test/IDE/complete_from_swift_module.swift
+++ b/test/IDE/complete_from_swift_module.swift
@@ -54,6 +54,7 @@
   foo_swift_module.FooSwiftStruct.#^MODULE_QUALIFIED_2^#
 }
 // MODULE_QUALIFIED_2: Begin completions
+// MODULE_QUALIFIED_2-NEXT: Keyword[self]/CurrNominal: self[#FooSwiftStruct.Type#]; name=self
 // MODULE_QUALIFIED_2-NEXT: Decl[InstanceMethod]/CurrNominal: fooInstanceFunc({#self: FooSwiftStruct#})[#() -> Void#]{{; name=.+$}}
 // MODULE_QUALIFIED_2-NEXT: Decl[Constructor]/CurrNominal: init()[#FooSwiftStruct#]{{; name=.+$}}
 // MODULE_QUALIFIED_2-NEXT: End completions
@@ -72,6 +73,7 @@
 // MODULE_QUALIFIED_4: Begin completions
 // MODULE_QUALIFIED_4-NEXT: Decl[Constructor]/CurrNominal: ({#t: _#}, {#u: _#})[#BarGenericSwiftStruct2<_, _>#]; name=(t: _, u: _)
 // MODULE_QUALIFIED_4-NEXT: Decl[InstanceMethod]/CurrNominal: .bar2InstanceFunc({#self: BarGenericSwiftStruct2<_, _>#})[#() -> Void#]; name=bar2InstanceFunc(BarGenericSwiftStruct2<_, _>)
+// MODULE_QUALIFIED_4-NEXT: Keyword[self]/CurrNominal: .self[#BarGenericSwiftStruct2<_, _>.Type#]; name=self
 // MODULE_QUALIFIED_4-NEXT: End completions
 
 func testCompleteModuleQualified5() {
diff --git a/test/IDE/complete_func_body_typechecking.swift b/test/IDE/complete_func_body_typechecking.swift
index 7c4d1d1..8856a9d 100644
--- a/test/IDE/complete_func_body_typechecking.swift
+++ b/test/IDE/complete_func_body_typechecking.swift
@@ -40,6 +40,7 @@
 }
 
 // FOO_STRUCT_COMMON: Begin completions
+// FOO_STRUCT_COMMON-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // FOO_STRUCT_COMMON-NEXT: Decl[InstanceVar]/CurrNominal:    instanceVar[#Int#]{{; name=.+$}}
 // FOO_STRUCT_COMMON-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
 // FOO_STRUCT_COMMON-NEXT: Decl[InstanceMethod]/CurrNominal: builderFunc1()[#FooStruct#]{{; name=.+$}}
diff --git a/test/IDE/complete_generic_optional.swift b/test/IDE/complete_generic_optional.swift
index 588760c..b2f7f47 100644
--- a/test/IDE/complete_generic_optional.swift
+++ b/test/IDE/complete_generic_optional.swift
@@ -11,6 +11,7 @@
 // SR-642 Code completion does not instantiate generic arguments of a type wrapped in an optional
 let x: Foo<Bar>? = Foo<Bar>()
 x.#^FOO_OPTIONAL_1^#
-// FOO_OPTIONAL_1: Begin completions, 6 items
+// FOO_OPTIONAL_1: Begin completions, 7 items
 // FOO_OPTIONAL_1-DAG: Decl[InstanceMethod]/CurrNominal/Erase[1]: ?.myFunction({#(foobar): Bar#})[#Void#]; name=myFunction(foobar: Bar)
+// FOO_OPTIONAL_1-DAG: Keyword[self]/CurrNominal: self[#Foo<Bar>?#]; name=self
 // FOO_OPTIONAL_1: End completions
diff --git a/test/IDE/complete_in_accessors.swift b/test/IDE/complete_in_accessors.swift
index 99ea62a..dd08693 100644
--- a/test/IDE/complete_in_accessors.swift
+++ b/test/IDE/complete_in_accessors.swift
@@ -125,6 +125,7 @@
 func returnsInt() -> Int {}
 
 // FOO_OBJECT_DOT: Begin completions
+// FOO_OBJECT_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // FOO_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal:    instanceVar[#Int#]{{; name=.+$}}
 // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
 // FOO_OBJECT_DOT-NEXT: End completions
diff --git a/test/IDE/complete_in_closures.swift b/test/IDE/complete_in_closures.swift
index 9e4d43c..e41f910 100644
--- a/test/IDE/complete_in_closures.swift
+++ b/test/IDE/complete_in_closures.swift
@@ -64,6 +64,7 @@
 }
 
 // FOO_OBJECT_DOT: Begin completions
+// FOO_OBJECT_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // FOO_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal:    instanceVar[#Int#]{{; name=.+$}}
 // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
 // FOO_OBJECT_DOT-NEXT: End completions
diff --git a/test/IDE/complete_init_inherited.swift b/test/IDE/complete_init_inherited.swift
index f661695..62d650c 100644
--- a/test/IDE/complete_init_inherited.swift
+++ b/test/IDE/complete_init_inherited.swift
@@ -15,6 +15,7 @@
 // TEST_A-NEXT: Decl[Constructor]/CurrNominal:      ({#int: Int#})[#A#]{{; name=.+$}}
 // TEST_A-NEXT: Decl[Constructor]/CurrNominal:      ({#double: Double#})[#A#]{{; name=.+$}}
 // TEST_A-NEXT: Decl[Constructor]/CurrNominal:      ({#float: Float#})[#A#]{{; name=.+$}}
+// TEST_A-NEXT: Keyword[self]/CurrNominal:          .self[#A.Type#]; name=self
 // TEST_A-NEXT: End completions
 
 class B : A {
@@ -27,6 +28,7 @@
 // TEST_B-NEXT: Decl[Constructor]/CurrNominal:      ({#int: Int#})[#B#]{{; name=.+$}}
 // TEST_B-NEXT: Decl[Constructor]/CurrNominal:      ({#double: Double#})[#B#]{{; name=.+$}}
 // TEST_B-NEXT: Decl[Constructor]/Super:            ({#float: Float#})[#A#]{{; name=.+$}}
+// TEST_B-NEXT: Keyword[self]/CurrNominal:          .self[#B.Type#]; name=self
 // TEST_B-NEXT: End completions
 
 class C : B {
@@ -42,6 +44,7 @@
 // TEST_C: Begin completions
 // TEST_C-NEXT: Decl[Constructor]/CurrNominal:      ({#int: Int#})[#C#]{{; name=.+$}}
 // TEST_C-NEXT: Decl[Constructor]/CurrNominal:      ({#c: C#})[#C#]{{; name=.+$}}
+// TEST_C-NEXT: Keyword[self]/CurrNominal:          .self[#C.Type#]; name=self
 // TEST_C-NEXT: End completions
 
 class D : C {
@@ -59,6 +62,7 @@
 // TEST_D-NEXT: Decl[Constructor]/CurrNominal:      ({#d: D#})[#D#]{{; name=.+$}}
 // TEST_D-NEXT: Decl[Constructor]/CurrNominal:      ({#int: Int#})[#D#]{{; name=.+$}}
 // TEST_D-NEXT: Decl[Constructor]/Super:            ({#c: C#})[#C#]{{; name=.+$}}
+// TEST_D-NEXT: Keyword[self]/CurrNominal:          .self[#D.Type#]; name=self
 // TEST_D-NEXT: End completions
 
 func testA() {
diff --git a/test/IDE/complete_lazy_initialized_var.swift b/test/IDE/complete_lazy_initialized_var.swift
index b287a40..d77b6f6 100644
--- a/test/IDE/complete_lazy_initialized_var.swift
+++ b/test/IDE/complete_lazy_initialized_var.swift
@@ -8,6 +8,7 @@
 }
 
 // This test checks that we don't include extra hidden declarations into code completion results.  If you add more declarations to the type, update this test properly.
-// LAZYVAR1:       Begin completions, 1 items
+// LAZYVAR1:       Begin completions, 2 items
+// LAZYVAR1-NEXT:  Keyword[self]/CurrNominal:          self[#FooClass1#]; name=self
 // LAZYVAR1-NEXT:  Decl[InstanceVar]/CurrNominal:      lazyVar1[#Int#]{{; name=.+$}}
 // LAZYVAR1-NEXT:  End completions
diff --git a/test/IDE/complete_member_decls_from_parent_decl_context.swift b/test/IDE/complete_member_decls_from_parent_decl_context.swift
index 9d3ffb8..fa70353 100644
--- a/test/IDE/complete_member_decls_from_parent_decl_context.swift
+++ b/test/IDE/complete_member_decls_from_parent_decl_context.swift
@@ -324,11 +324,12 @@
 // NESTED_NOMINAL_DECL_A_4: End completions
 
     NestedInnerA(aInstanceVar: 42)#^NESTED_NOMINAL_DECL_A_5^#
-// NESTED_NOMINAL_DECL_A_5: Begin completions, 4 items
+// NESTED_NOMINAL_DECL_A_5: Begin completions, 5 items
 // NESTED_NOMINAL_DECL_A_5-NEXT: Decl[InstanceMethod]/CurrNominal: .aTestInstanceFunc()[#Void#]{{; name=.+$}}
 // NESTED_NOMINAL_DECL_A_5-NEXT: Decl[InstanceVar]/CurrNominal:    .aInstanceVar[#Int#]{{; name=.+$}}
 // NESTED_NOMINAL_DECL_A_5-NEXT: Decl[InstanceMethod]/CurrNominal: .aInstanceFunc()[#Void#]{{; name=.+$}}
 // NESTED_NOMINAL_DECL_A_5-NEXT: Decl[Subscript]/CurrNominal:      [{#Int#}][#Double#]{{; name=.+$}}
+// NESTED_NOMINAL_DECL_A_5-NEXT: Keyword[self]/CurrNominal:        .self[#NestedInnerA#]; name=self
 // NESTED_NOMINAL_DECL_A_5-NEXT: End completions
   }
 
@@ -433,11 +434,12 @@
 // NESTED_NOMINAL_DECL_B_4: End completions
 
     NestedInnerB(bInstanceVar: 42)#^NESTED_NOMINAL_DECL_B_5^#
-// NESTED_NOMINAL_DECL_B_5: Begin completions, 4 items
+// NESTED_NOMINAL_DECL_B_5: Begin completions, 5 items
 // NESTED_NOMINAL_DECL_B_5-DAG: Decl[InstanceMethod]/CurrNominal: .bTestInstanceFunc()[#Void#]{{; name=.+$}}
 // NESTED_NOMINAL_DECL_B_5-DAG: Decl[InstanceVar]/CurrNominal:    .bInstanceVar[#Int#]{{; name=.+$}}
 // NESTED_NOMINAL_DECL_B_5-DAG: Decl[InstanceMethod]/CurrNominal: .bInstanceFunc()[#Void#]{{; name=.+$}}
 // NESTED_NOMINAL_DECL_B_5-DAG: Decl[Subscript]/CurrNominal:      [{#Int#}][#Double#]{{; name=.+$}}
+// NESTED_NOMINAL_DECL_B_5-DAG: Keyword[self]/CurrNominal:        .self[#NestedInnerB#]; name=self
 // NESTED_NOMINAL_DECL_B_5: End completions
   }
 
@@ -524,11 +526,12 @@
 // NESTED_NOMINAL_DECL_C_4: End completions
 
   NestedInnerC(cInstanceVar: 42)#^NESTED_NOMINAL_DECL_C_5^#
-// NESTED_NOMINAL_DECL_C_5: Begin completions, 4 items
+// NESTED_NOMINAL_DECL_C_5: Begin completions, 5 items
 // NESTED_NOMINAL_DECL_C_5-NEXT: Decl[InstanceMethod]/CurrNominal: .cTestInstanceFunc()[#Void#]{{; name=.+$}}
 // NESTED_NOMINAL_DECL_C_5-NEXT: Decl[InstanceVar]/CurrNominal:    .cInstanceVar[#Int#]{{; name=.+$}}
 // NESTED_NOMINAL_DECL_C_5-NEXT: Decl[InstanceMethod]/CurrNominal: .cInstanceFunc()[#Void#]{{; name=.+$}}
 // NESTED_NOMINAL_DECL_C_5-NEXT: Decl[Subscript]/CurrNominal:      [{#Int#}][#Double#]{{; name=.+$}}
+// NESTED_NOMINAL_DECL_C_5-NEXT: Keyword[self]/CurrNominal:        .self[#NestedInnerC#]; name=self
 // NESTED_NOMINAL_DECL_C_5-NEXT: End completions
 }
 
diff --git a/test/IDE/complete_members_optional.swift b/test/IDE/complete_members_optional.swift
index f03b539..2cf8ba4 100644
--- a/test/IDE/complete_members_optional.swift
+++ b/test/IDE/complete_members_optional.swift
@@ -28,16 +28,18 @@
 func optionalMembers1(_ a: HasOptionalMembers1) {
   a.#^OPTIONAL_MEMBERS_1^#
 }
-// OPTIONAL_MEMBERS_1: Begin completions, 2 items
+// OPTIONAL_MEMBERS_1: Begin completions, 3 items
 // OPTIONAL_MEMBERS_1-DAG: Decl[InstanceMethod]/CurrNominal:   optionalInstanceFunc!()[#Int#]{{; name=.+$}}
 // OPTIONAL_MEMBERS_1-DAG: Decl[InstanceVar]/CurrNominal:      optionalInstanceProperty[#Int?#]{{; name=.+$}}
+// OPTIONAL_MEMBERS_1-DAG: Keyword[self]/CurrNominal: self[#HasOptionalMembers1#]; name=self
 // OPTIONAL_MEMBERS_1: End completions
 
 func optionalMembers2<T : HasOptionalMembers1>(_ a: T) {
   T.#^OPTIONAL_MEMBERS_2^#
 }
-// OPTIONAL_MEMBERS_2: Begin completions, 3 items
+// OPTIONAL_MEMBERS_2: Begin completions, 4 items
 // OPTIONAL_MEMBERS_2-DAG: Decl[InstanceMethod]/Super:         optionalInstanceFunc!({#self: HasOptionalMembers1#})[#() -> Int#]{{; name=.+$}}
 // OPTIONAL_MEMBERS_2-DAG: Decl[StaticMethod]/Super:           optionalClassFunc!()[#Int#]{{; name=.+$}}
 // OPTIONAL_MEMBERS_2-DAG: Decl[StaticVar]/Super:              optionalClassProperty[#Int?#]{{; name=.+$}}
+// OPTIONAL_MEMBERS_2-DAG: Keyword[self]/CurrNominal: self[#T.Type#]; name=self
 // OPTIONAL_MEMBERS_2: End completions
diff --git a/test/IDE/complete_multiple_files.swift b/test/IDE/complete_multiple_files.swift
index 484edc7..8ee8999 100644
--- a/test/IDE/complete_multiple_files.swift
+++ b/test/IDE/complete_multiple_files.swift
@@ -13,6 +13,7 @@
   fooObject.#^T1^#
 }
 // T1: Begin completions
+// T1-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // T1-NEXT: Decl[InstanceVar]/CurrNominal:    instanceVar[#Int#]{{; name=.+$}}
 // T1-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
 //
@@ -24,6 +25,7 @@
   genericFooObject.#^T2^#
 }
 // T2: Begin completions
+// T2-NEXT: Keyword[self]/CurrNominal: self[#GenericFooStruct<Void>#]; name=self
 // T2-NEXT: Decl[InstanceVar]/CurrNominal:    instanceVar[#Int#]{{; name=.+$}}
 // T2-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
 //
diff --git a/test/IDE/complete_name_lookup.swift b/test/IDE/complete_name_lookup.swift
index 3319439..c900379 100644
--- a/test/IDE/complete_name_lookup.swift
+++ b/test/IDE/complete_name_lookup.swift
@@ -15,6 +15,7 @@
   var instanceProperty: Int { return 0 }
 }
 // FOO_OBJECT_DOT: Begin completions
+// FOO_OBJECT_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // FOO_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal:      instanceProperty[#Int#]
 // FOO_OBJECT_DOT-NEXT: End completions
 
@@ -22,6 +23,7 @@
   var instanceProperty: Int { return 0 }
 }
 // BAR_OBJECT_DOT: Begin completions
+// BAR_OBJECT_DOT-NEXT: Keyword[self]/CurrNominal: self[#BarStruct#]; name=self
 // BAR_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal:      instanceProperty[#Int#]
 // BAR_OBJECT_DOT-NEXT: End completions
 
diff --git a/test/IDE/complete_not_recommended.swift b/test/IDE/complete_not_recommended.swift
index e90b7e4..a8d0697 100644
--- a/test/IDE/complete_not_recommended.swift
+++ b/test/IDE/complete_not_recommended.swift
@@ -1,5 +1,6 @@
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=MEMBER | %FileCheck %s -check-prefix=CHECK1
-// CHECK1: Begin completions, 2 items
+// CHECK1: Begin completions, 3 items
+// CHECK1: Keyword[self]/CurrNominal:          self[#A.Type#]; name=self
 // CHECK1: Decl[InstanceMethod]/CurrNominal:   foo({#self: A#})[#() -> Void#]
 // CHECK1: Decl[Constructor]/CurrNominal:      init()[#A#]; name=init(){{$}}
 // CHECK1: End completions
diff --git a/test/IDE/complete_operators.swift b/test/IDE/complete_operators.swift
index 0aec8db..a4c2159 100644
--- a/test/IDE/complete_operators.swift
+++ b/test/IDE/complete_operators.swift
@@ -119,7 +119,8 @@
 func testPostfix8(x: S) {
   x#^POSTFIX_8^#
 }
-// POSTFIX_8-NOT: ***
+// POSTFIX_8: Begin completions
+// POSTFIX_8: Keyword[self]/CurrNominal: .self[#S#]; name=self
 
 protocol P {
   associatedtype T
@@ -250,16 +251,18 @@
   S2#^INFIX_11^#
 }
 
-// INFIX_11: Begin completions, 1 items
+// INFIX_11: Begin completions, 2 items
 // INFIX_11-DAG: Decl[Constructor]/CurrNominal:      ()[#S2#]; name=()
+// INFIX_11-DAG: Keyword[self]/CurrNominal:          .self[#S2.Type#]; name=self
 // INFIX_11: End completions
 
 func testInfix12() {
   P#^INFIX_12^#
 }
-// INFIX_12: Begin completions, 2 items
+// INFIX_12: Begin completions, 3 items
 // INFIX_12-NEXT: Decl[AssociatedType]/CurrNominal:   .T; name=T
 // INFIX_12-NEXT: Decl[InstanceMethod]/CurrNominal:   .foo({#self: P#})[#() -> P.T#]; name=foo(P)
+// INFIX_12-NEXT: Keyword[self]/CurrNominal:          .self[#P.Protocol#]; name=self
 // INFIX_12: End completions
 
 func testInfix13() {
@@ -273,17 +276,19 @@
 func testInfix15<T: P where T.T == S2>() {
   T#^INFIX_15^#
 }
-// INFIX_15: Begin completions, 2 items
+// INFIX_15: Begin completions, 3 items
 // INFIX_15-NEXT: Decl[AssociatedType]/Super:         .T; name=T
 // INFIX_15-NEXT: Decl[InstanceMethod]/Super:         .foo({#self: P#})[#() -> S2#]; name=foo(P)
+// INFIX_15-NEXT: Keyword[self]/CurrNominal:          .self[#T.Type#]; name=self
 // INFIX_15: End completions
 
 func testInfix16<T: P where T.T == S2>() {
   T.foo#^INFIX_16^#
 }
 
-// INFIX_16: Begin completions, 1 items
+// INFIX_16: Begin completions, 2 items
 // INFIX_16-NEXT: Pattern/CurrModule:               ({#(self): T#})[#() -> S2#]; name=(self: T)
+// INFIX_16-NEXT: Keyword[self]/CurrNominal:         .self[#(T) -> () -> S2#]; name=self
 // INFIX_16: End completions
 
 func testInfix17(x: Void) {
@@ -325,7 +330,7 @@
 func testInfix22() {
   E.B#^INFIX_22^#
 }
-// INFIX_22: Begin completions, 1 items
+// INFIX_22: Begin completions, 2 items
 // INFIX_22-NEXT: Pattern/CurrModule:               ({#S2#})[#E#]; name=(S2)
 // INFIX_22: End completions
 
diff --git a/test/IDE/complete_overridden_decls.swift b/test/IDE/complete_overridden_decls.swift
index 6927e4c..1decf28 100644
--- a/test/IDE/complete_overridden_decls.swift
+++ b/test/IDE/complete_overridden_decls.swift
@@ -54,6 +54,7 @@
   b.#^OVER_BASE_1^#
 }
 // OVER_BASE_1: Begin completions
+// OVER_BASE_1-NEXT: Keyword[self]/CurrNominal: self[#TestABase#]; name=self
 // OVER_BASE_1-NEXT: Decl[InstanceVar]/CurrNominal:    baseInstanceVar[#FooBase#]{{; name=.+$}}
 // OVER_BASE_1-NEXT: Decl[InstanceVar]/CurrNominal:    baseOverInstanceVar[#FooBase#]{{; name=.+$}}
 // OVER_BASE_1-NEXT: Decl[InstanceMethod]/CurrNominal: baseOverFunc()[#Void#]{{; name=.+$}}
@@ -65,6 +66,7 @@
   d.#^OVER_DERIVED_1^#
 }
 // OVER_DERIVED_1: Begin completions
+// OVER_DERIVED_1-NEXT: Keyword[self]/CurrNominal: self[#TestADerived#]; name=self
 // OVER_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal:    derivedInstanceVar[#FooBase#]{{; name=.+$}}
 // OVER_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal:    baseOverInstanceVar[#FooDerived#]{{; name=.+$}}
 // OVER_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal:    derivedOverInstanceVar[#FooBase#]{{; name=.+$}}
@@ -78,6 +80,7 @@
   md.#^OVER_MORE_DERIVED_1^#
 }
 // OVER_MORE_DERIVED_1: Begin completions
+// OVER_MORE_DERIVED_1-NEXT: Keyword[self]/CurrNominal: self[#TestAMoreDerived#]; name=self
 // OVER_MORE_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal:    moreDerivedInstanceVar[#FooBase#]{{; name=.+$}}
 // OVER_MORE_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal:    baseOverInstanceVar[#FooMoreDerived#]{{; name=.+$}}
 // OVER_MORE_DERIVED_1-NEXT: Decl[InstanceVar]/CurrNominal:    derivedOverInstanceVar[#FooDerived#]{{; name=.+$}}
diff --git a/test/IDE/complete_return.swift b/test/IDE/complete_return.swift
index 8252086..bc33e3a 100644
--- a/test/IDE/complete_return.swift
+++ b/test/IDE/complete_return.swift
@@ -54,6 +54,7 @@
 func testReturnInt2(_ fooObject: FooStruct) {
   return fooObject.#^RETURN_INT_2^#
 // RETURN_INT_2: Begin completions
+// RETURN_INT_2-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // RETURN_INT_2-NEXT: Decl[InstanceVar]/CurrNominal: instanceVar[#Int#]{{; name=.+$}}
 // RETURN_INT_2-NEXT: End completions
 }
diff --git a/test/IDE/complete_stdlib_optional.swift b/test/IDE/complete_stdlib_optional.swift
index 6712c74..22c12aa 100644
--- a/test/IDE/complete_stdlib_optional.swift
+++ b/test/IDE/complete_stdlib_optional.swift
@@ -135,9 +135,11 @@
 // OBJCCLASS_MEMBERS_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc()[#ObjcClass#]
 // OBJCCLASS_MEMBERS_NO_DOT-NEXT: Decl[InfixOperatorFunction]/OtherModule[Swift]: === {#AnyObject?#}[#Bool#]
 // OBJCCLASS_MEMBERS_NO_DOT-NEXT: Decl[InfixOperatorFunction]/OtherModule[Swift]: !== {#AnyObject?#}[#Bool#]
+// OBJCCLASS_MEMBERS_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#ObjcClass#]; name=self
 // OBJCCLASS_MEMBERS_NO_DOT-NEXT: End completions
 
 // OBJCCLASS_MEMBERS_DOT: Begin completions
+// OBJCCLASS_MEMBERS_DOT-NEXT: Keyword[self]/CurrNominal: self[#ObjcClass#]; name=self
 // OBJCCLASS_MEMBERS_DOT-NEXT: Decl[InstanceVar]/CurrNominal:    instanceVar[#Int#]
 // OBJCCLASS_MEMBERS_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc()[#ObjcClass#]
 // OBJCCLASS_MEMBERS_DOT-NEXT: End completions
diff --git a/test/IDE/complete_unicode.swift b/test/IDE/complete_unicode.swift
index c5228d5..560dbee 100644
--- a/test/IDE/complete_unicode.swift
+++ b/test/IDE/complete_unicode.swift
@@ -15,6 +15,7 @@
   Unicode1().#^UNICODE_1^#
 }
 // UNICODE_1: Begin completions
+// UNICODE_1-NEXT: Keyword[self]/CurrNominal: self[#Unicode1#]; name=self
 // UNICODE_1-NEXT: Decl[InstanceMethod]/CurrNominal: Идентификаторы_с_кириллицей_допустимы()[#Void#]{{; name=.+$}}
 // UNICODE_1-NEXT: Decl[InstanceMethod]/CurrNominal: Ідентіфікатори_українською_також_працюють()[#Void#]{{; name=.+$}}
 // UNICODE_1-NEXT: Decl[InstanceMethod]/CurrNominal: 識別子は()[#Void#]{{; name=.+$}}
diff --git a/test/IDE/complete_value_expr.swift b/test/IDE/complete_value_expr.swift
index 3295371..fbfbbdb 100644
--- a/test/IDE/complete_value_expr.swift
+++ b/test/IDE/complete_value_expr.swift
@@ -295,6 +295,7 @@
 var fooObject: FooStruct
 
 // FOO_OBJECT_DOT: Begin completions
+// FOO_OBJECT_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // FOO_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal:    lazyInstanceVar[#Int#]{{; name=.+$}}
 // FOO_OBJECT_DOT-NEXT: Decl[InstanceVar]/CurrNominal:    instanceVar[#Int#]{{; name=.+$}}
 // FOO_OBJECT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0()[#Void#]{{; name=.+$}}
@@ -361,9 +362,11 @@
 // FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceVar]/CurrNominal:    .extProp[#Int#]{{; name=.+$}}
 // FOO_OBJECT_NO_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: .extFunc0()[#Void#]{{; name=.+$}}
 // FOO_OBJECT_NO_DOT-NEXT: BuiltinOperator/None:                     = {#Foo
+// FOO_OBJECT_NO_DOT-NEXT: Keyword[self]/CurrNominal: .self[#FooStruct#]; name=self
 // FOO_OBJECT_NO_DOT-NEXT: End completions
 
 // FOO_STRUCT_DOT: Begin completions
+// FOO_STRUCT_DOT-NEXT: Keyword[self]/CurrNominal: self[#FooStruct.Type#]; name=self
 // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc0({#self: &FooStruct#})[#() -> Void#]{{; name=.+$}}
 // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc1({#self: &FooStruct#})[#(Int) -> Void#]{{; name=.+$}}
 // FOO_STRUCT_DOT-NEXT: Decl[InstanceMethod]/CurrNominal: instanceFunc2({#self: &FooStruct#})[#(Int, b: inout Double) -> Void#]{{; name=.+$}}
@@ -455,6 +458,7 @@
 // FOO_STRUCT_NO_DOT-NEXT: Decl[Class]/CurrNominal:          .ExtNestedClass[#FooStruct.ExtNestedClass#]{{; name=.+$}}
 // FOO_STRUCT_NO_DOT-NEXT: Decl[Enum]/CurrNominal:           .ExtNestedEnum[#FooStruct.ExtNestedEnum#]{{; name=.+$}}
 // FOO_STRUCT_NO_DOT-NEXT: Decl[TypeAlias]/CurrNominal:      .ExtNestedTypealias[#Int#]{{; name=.+$}}
+// FOO_STRUCT_NO_DOT-NEXT: Keyword[self]/CurrNominal:        .self[#FooStruct.Type#]; name=self
 // FOO_STRUCT_NO_DOT-NEXT: End completions
 
 func testObjectExpr() {
@@ -501,31 +505,37 @@
   FooStruct.instanceFunc0(&fs)#^IMPLICITLY_CURRIED_FUNC_0^#
 // IMPLICITLY_CURRIED_FUNC_0: Begin completions
 // IMPLICITLY_CURRIED_FUNC_0-NEXT: Pattern/CurrModule: ()[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_FUNC_0-NEXT: Keyword[self]/CurrNominal: .self[#() -> ()#]; name=self
 // IMPLICITLY_CURRIED_FUNC_0-NEXT: End completions
 
   FooStruct.instanceFunc1(&fs)#^IMPLICITLY_CURRIED_FUNC_1^#
 // IMPLICITLY_CURRIED_FUNC_1: Begin completions
 // IMPLICITLY_CURRIED_FUNC_1-NEXT: Pattern/CurrModule: ({#(a): Int#})[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_FUNC_1-NEXT: Keyword[self]/CurrNominal: .self[#(Int) -> ()#]; name=self
 // IMPLICITLY_CURRIED_FUNC_1-NEXT: End completions
 
   FooStruct.instanceFunc2(&fs)#^IMPLICITLY_CURRIED_FUNC_2^#
 // IMPLICITLY_CURRIED_FUNC_2: Begin completions
 // IMPLICITLY_CURRIED_FUNC_2-NEXT: Pattern/CurrModule: ({#(a): Int#}, {#b: &Double#})[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_FUNC_2-NEXT: Keyword[self]/CurrNominal: .self[#(Int, inout Double) -> ()#]; name=self
 // IMPLICITLY_CURRIED_FUNC_2-NEXT: End completions
 
   FooStruct.varargInstanceFunc0(&fs)#^IMPLICITLY_CURRIED_VARARG_FUNC_0^#
 // IMPLICITLY_CURRIED_VARARG_FUNC_0: Begin completions
 // IMPLICITLY_CURRIED_VARARG_FUNC_0-NEXT: Pattern/CurrModule: ({#(v): Int...#})[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_VARARG_FUNC_0-NEXT: Keyword[self]/CurrNominal: .self[#(Int...) -> ()#]; name=self
 // IMPLICITLY_CURRIED_VARARG_FUNC_0-NEXT: End completions
 
   FooStruct.varargInstanceFunc1(&fs)#^IMPLICITLY_CURRIED_VARARG_FUNC_1^#
 // IMPLICITLY_CURRIED_VARARG_FUNC_1: Begin completions
 // IMPLICITLY_CURRIED_VARARG_FUNC_1-NEXT: Pattern/CurrModule: ({#(a): Float#}, {#v: Int...#})[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_VARARG_FUNC_1-NEXT: Keyword[self]/CurrNominal: .self[#(Float, Int...) -> ()#]; name=self
 // IMPLICITLY_CURRIED_VARARG_FUNC_1-NEXT: End completions
 
   FooStruct.varargInstanceFunc2(&fs)#^IMPLICITLY_CURRIED_VARARG_FUNC_2^#
 // IMPLICITLY_CURRIED_VARARG_FUNC_2: Begin completions
 // IMPLICITLY_CURRIED_VARARG_FUNC_2-NEXT: Pattern/CurrModule: ({#(a): Float#}, {#b: Double#}, {#v: Int...#})[#Void#]{{; name=.+$}}
+// IMPLICITLY_CURRIED_VARARG_FUNC_2-NEXT: Keyword[self]/CurrNominal: .self[#(Float, Double, Int...) -> ()#]; name=self
 // IMPLICITLY_CURRIED_VARARG_FUNC_2-NEXT: End completions
 
   // This call is ambiguous, and the expression is invalid.
@@ -798,12 +808,14 @@
 // VF1: Begin completions
 // VF1-NEXT: Pattern/CurrModule: ()[#Double#]{{; name=.+$}}
 // VF1-NEXT: BuiltinOperator/None:         = {#() -> Double##() -> Double#}[#Void#]
+// VF1-NEXT: Keyword[self]/CurrNominal:    .self[#() -> Double#]; name=self
 // VF1-NEXT: End completions
 
   funcTypeVarsObject.funcVar2#^VF2^#
 // VF2: Begin completions
 // VF2-NEXT: Pattern/CurrModule: ({#Int#})[#Double#]{{; name=.+$}}
 // VF2-NEXT: BuiltinOperator/None:         = {#(Int) -> Double##(Int) -> Double#}[#Void#]
+// VF2-NEXT: Keyword[self]/CurrNominal:    .self[#(Int) -> Double#]; name=self
 // VF2-NEXT: End completions
 }
 
@@ -825,6 +837,7 @@
 func testLookInBase() {
   membersDerived.#^BASE_MEMBERS^#
 // BASE_MEMBERS: Begin completions
+// BASE_MEMBERS-DAG: Keyword[self]/CurrNominal: self[#MembersDerived#]; name=self
 // BASE_MEMBERS-NEXT: Decl[InstanceVar]/CurrNominal:    derivedVar[#Int#]{{; name=.+$}}
 // BASE_MEMBERS-NEXT: Decl[InstanceMethod]/CurrNominal: derivedInstanceFunc()[#Void#]{{; name=.+$}}
 // BASE_MEMBERS-NEXT: Decl[InstanceVar]/Super:          baseVar[#Int#]{{; name=.+$}}
@@ -835,6 +848,7 @@
 func testLookInBaseStatic() {
   MembersDerived.#^BASE_MEMBERS_STATIC^#
 // BASE_MEMBERS_STATIC: Begin completions
+// BASE_MEMBERS_STATIC-NEXT: Keyword[self]/CurrNominal: self[#MembersDerived.Type#]; name=self
 // BASE_MEMBERS_STATIC-NEXT: Decl[InstanceMethod]/CurrNominal: derivedInstanceFunc({#self: MembersDerived#})[#() -> Void#]{{; name=.+$}}
 // BASE_MEMBERS_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   derivedStaticFunc()[#Void#]{{; name=.+$}}
 // BASE_MEMBERS_STATIC-NEXT: Decl[Constructor]/CurrNominal:    init()[#MembersDerived#]; name=init(){{$}}
@@ -853,6 +867,7 @@
 // PROTO_MEMBERS_NO_DOT_1-NEXT: Decl[InstanceMethod]/CurrNominal: .fooInstanceFunc0()[#Double#]{{; name=.+$}}
 // PROTO_MEMBERS_NO_DOT_1-NEXT: Decl[InstanceMethod]/CurrNominal: .fooInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
 // PROTO_MEMBERS_NO_DOT_1-NEXT: Decl[Subscript]/CurrNominal:      [{#Int#}][#Double#]{{; name=.+$}}
+// PROTO_MEMBERS_NO_DOT_1-NEXT: Keyword[self]/CurrNominal:        .self[#FooProtocol#]; name=self
 // PROTO_MEMBERS_NO_DOT_1-NEXT: End completions
 }
 
@@ -867,6 +882,7 @@
 // PROTO_MEMBERS_NO_DOT_2-NEXT: Decl[InstanceMethod]/CurrNominal: .fooInstanceFunc0()[#Double#]{{; name=.+$}}
 // PROTO_MEMBERS_NO_DOT_2-NEXT: Decl[InstanceMethod]/CurrNominal: .fooInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
 // PROTO_MEMBERS_NO_DOT_2-NEXT: Decl[Subscript]/CurrNominal:      [{#Int#}][#Double#]{{; name=.+$}}
+// PROTO_MEMBERS_NO_DOT_2-NEXT: Keyword[self]/CurrNominal: .self[#BarProtocol & FooProtocol#]; name=self
 // PROTO_MEMBERS_NO_DOT_2-NEXT: End completions
 }
 
@@ -883,12 +899,14 @@
 // PROTO_MEMBERS_NO_DOT_3-NEXT: Decl[InstanceMethod]/Super:       .fooInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
 // PROTO_MEMBERS_NO_DOT_3-NEXT: Decl[Subscript]/Super:            [{#Int#}][#Double#]{{; name=.+$}}
 // PROTO_MEMBERS_NO_DOT_3-NEXT: Decl[InstanceMethod]/CurrNominal: .fooExInstanceFunc0()[#Double#]{{; name=.+$}}
+// PROTO_MEMBERS_NO_DOT_3-NEXT: Keyword[self]/CurrNominal: .self[#BarExProtocol & FooExProtocol#]; name=self
 // PROTO_MEMBERS_NO_DOT_3-NEXT: End completions
 }
 
 func testLookInProto1() {
   fooProtocolInstance.#^PROTO_MEMBERS_1^#
 // PROTO_MEMBERS_1: Begin completions
+// PROTO_MEMBERS_1-NEXT: Keyword[self]/CurrNominal: self[#FooProtocol#]; name=self
 // PROTO_MEMBERS_1-NEXT: Decl[InstanceVar]/CurrNominal:    fooInstanceVar1[#Int#]{{; name=.+$}}
 // PROTO_MEMBERS_1-NEXT: Decl[InstanceVar]/CurrNominal:    fooInstanceVar2[#Int#]{{; name=.+$}}
 // PROTO_MEMBERS_1-NEXT: Decl[InstanceMethod]/CurrNominal: fooInstanceFunc0()[#Double#]{{; name=.+$}}
@@ -899,6 +917,7 @@
 func testLookInProto2() {
   fooBarProtocolInstance.#^PROTO_MEMBERS_2^#
 // PROTO_MEMBERS_2: Begin completions
+// PROTO_MEMBERS_2-NEXT: Keyword[self]/CurrNominal: self[#BarProtocol & FooProtocol#]; name=self
 // PROTO_MEMBERS_2-NEXT: Decl[InstanceVar]/CurrNominal:    barInstanceVar[#Int#]{{; name=.+$}}
 // PROTO_MEMBERS_2-NEXT: Decl[InstanceMethod]/CurrNominal: barInstanceFunc0()[#Double#]{{; name=.+$}}
 // PROTO_MEMBERS_2-NEXT: Decl[InstanceMethod]/CurrNominal: barInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
@@ -912,6 +931,7 @@
 func testLookInProto3() {
   fooExBarExProtocolInstance.#^PROTO_MEMBERS_3^#
 // PROTO_MEMBERS_3: Begin completions
+// PROTO_MEMBERS_3-NEXT: Keyword[self]/CurrNominal: self[#BarExProtocol & FooExProtocol#]; name=self
 // PROTO_MEMBERS_3-NEXT: Decl[InstanceVar]/Super:          barInstanceVar[#Int#]{{; name=.+$}}
 // PROTO_MEMBERS_3-NEXT: Decl[InstanceMethod]/Super:       barInstanceFunc0()[#Double#]{{; name=.+$}}
 // PROTO_MEMBERS_3-NEXT: Decl[InstanceMethod]/Super:       barInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
@@ -948,6 +968,7 @@
 func testResolveFuncParam3<Foo : FooProtocol>(_ foo: Foo) {
   foo.#^RESOLVE_FUNC_PARAM_3^#
 // RESOLVE_FUNC_PARAM_3: Begin completions
+// RESOLVE_FUNC_PARAM_3-NEXT: Keyword[self]/CurrNominal: self[#Foo#]; name=self
 // RESOLVE_FUNC_PARAM_3-NEXT: Decl[InstanceVar]/Super:    fooInstanceVar1[#Int#]{{; name=.+$}}
 // RESOLVE_FUNC_PARAM_3-NEXT: Decl[InstanceVar]/Super:    fooInstanceVar2[#Int#]{{; name=.+$}}
 // RESOLVE_FUNC_PARAM_3-NEXT: Decl[InstanceMethod]/Super: fooInstanceFunc0()[#Double#]{{; name=.+$}}
@@ -958,6 +979,7 @@
 func testResolveFuncParam4<FooBar : FooProtocol & BarProtocol>(_ fooBar: FooBar) {
   fooBar.#^RESOLVE_FUNC_PARAM_4^#
 // RESOLVE_FUNC_PARAM_4: Begin completions
+// RESOLVE_FUNC_PARAM_4-NEXT: Keyword[self]/CurrNominal: self[#FooBar#]; name=self
 // RESOLVE_FUNC_PARAM_4-NEXT: Decl[InstanceVar]/Super:    barInstanceVar[#Int#]{{; name=.+$}}
 // RESOLVE_FUNC_PARAM_4-NEXT: Decl[InstanceMethod]/Super: barInstanceFunc0()[#Double#]{{; name=.+$}}
 // RESOLVE_FUNC_PARAM_4-NEXT: Decl[InstanceMethod]/Super: barInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
@@ -971,6 +993,7 @@
 func testResolveFuncParam5<FooExBarEx : FooExProtocol & BarExProtocol>(_ a: FooExBarEx) {
   a.#^RESOLVE_FUNC_PARAM_5^#
 // RESOLVE_FUNC_PARAM_5: Begin completions
+// RESOLVE_FUNC_PARAM_5-NEXT: Keyword[self]/CurrNominal: self[#FooExBarEx#]; name=self
 // RESOLVE_FUNC_PARAM_5-NEXT: Decl[InstanceVar]/Super:    barInstanceVar[#Int#]{{; name=.+$}}
 // RESOLVE_FUNC_PARAM_5-NEXT: Decl[InstanceMethod]/Super: barInstanceFunc0()[#Double#]{{; name=.+$}}
 // RESOLVE_FUNC_PARAM_5-NEXT: Decl[InstanceMethod]/Super: barInstanceFunc1({#(a): Int#})[#Double#]{{; name=.+$}}
@@ -986,6 +1009,7 @@
 func testResolveFuncParam6<Foo : FooProtocol where Foo : FooClass>(_ foo: Foo) {
   foo.#^RESOLVE_FUNC_PARAM_6^#
 // RESOLVE_FUNC_PARAM_6: Begin completions
+// RESOLVE_FUNC_PARAM_6-NEXT: Keyword[self]/CurrNominal: self[#Foo#]; name=self
 // RESOLVE_FUNC_PARAM_6-NEXT: Decl[InstanceVar]/Super:    fooInstanceVar1[#Int#]{{; name=.+$}}
 // RESOLVE_FUNC_PARAM_6-NEXT: Decl[InstanceVar]/Super:    fooInstanceVar2[#Int#]{{; name=.+$}}
 // RESOLVE_FUNC_PARAM_6-NEXT: Decl[InstanceMethod]/Super: fooInstanceFunc0()[#Double#]{{; name=.+$}}
@@ -1006,6 +1030,7 @@
   init<Foo : FooProtocol>(foo: Foo) {
     foo.#^RESOLVE_CONSTRUCTOR_PARAM_2^#
 // RESOLVE_CONSTRUCTOR_PARAM_2: Begin completions
+// RESOLVE_CONSTRUCTOR_PARAM_2-NEXT: Keyword[self]/CurrNominal: self[#Foo#]; name=self
 // RESOLVE_CONSTRUCTOR_PARAM_2-NEXT: Decl[InstanceVar]/Super:    fooInstanceVar1[#Int#]{{; name=.+$}}
 // RESOLVE_CONSTRUCTOR_PARAM_2-NEXT: Decl[InstanceVar]/Super:    fooInstanceVar2[#Int#]{{; name=.+$}}
 // RESOLVE_CONSTRUCTOR_PARAM_2-NEXT: Decl[InstanceMethod]/Super: fooInstanceFunc0()[#Double#]{{; name=.+$}}
@@ -1018,6 +1043,7 @@
   init(foo: Foo) {
     foo.#^RESOLVE_CONSTRUCTOR_PARAM_3^#
 // RESOLVE_CONSTRUCTOR_PARAM_3: Begin completions
+// RESOLVE_CONSTRUCTOR_PARAM_3-NEXT: Keyword[self]/CurrNominal: self[#Foo#]; name=self
 // RESOLVE_CONSTRUCTOR_PARAM_3-NEXT: Decl[InstanceVar]/Super:    fooInstanceVar1[#Int#]{{; name=.+$}}
 // RESOLVE_CONSTRUCTOR_PARAM_3-NEXT: Decl[InstanceVar]/Super:    fooInstanceVar2[#Int#]{{; name=.+$}}
 // RESOLVE_CONSTRUCTOR_PARAM_3-NEXT: Decl[InstanceMethod]/Super: fooInstanceFunc0()[#Double#]{{; name=.+$}}
@@ -1047,6 +1073,7 @@
 // FUNC_PAREN_PATTERN_1: Begin completions
 // FUNC_PAREN_PATTERN_1-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#Int#})[#Void#]{{; name=.+$}}
 // FUNC_PAREN_PATTERN_1-NEXT: Decl[Subscript]/CurrNominal: [{#Int#}][#Int#]{{; name=.+$}}
+// FUNC_PAREN_PATTERN_1-NEXT: Keyword[self]/CurrNominal: .self[#FuncParenPattern#]; name=self
 // FUNC_PAREN_PATTERN_1-NEXT: End completions
 }
 
@@ -1056,6 +1083,7 @@
 // FUNC_PAREN_PATTERN_2-NEXT: Decl[Constructor]/CurrNominal: ({#Int#})[#FuncParenPattern#]{{; name=.+$}}
 // FUNC_PAREN_PATTERN_2-NEXT: Decl[Constructor]/CurrNominal: ({#(Int, Int)#})[#FuncParenPattern#]{{; name=.+$}}
 // FUNC_PAREN_PATTERN_2-NEXT: Decl[InstanceMethod]/CurrNominal: .instanceFunc({#self: &FuncParenPattern#})[#(Int) -> Void#]{{; name=.+$}}
+// FUNC_PAREN_PATTERN_2-NEXT: Keyword[self]/CurrNominal: .self[#FuncParenPattern.Type#]; name=self
 // FUNC_PAREN_PATTERN_2-NEXT: End completions
 }
 
@@ -1063,6 +1091,7 @@
   fpp.instanceFunc#^FUNC_PAREN_PATTERN_3^#
 // FUNC_PAREN_PATTERN_3: Begin completions
 // FUNC_PAREN_PATTERN_3-NEXT: Pattern/CurrModule: ({#Int#})[#Void#]{{; name=.+$}}
+// FUNC_PAREN_PATTERN_3-NEXT: Keyword[self]/CurrNominal: .self[#(Int) -> ()#]; name=self
 // FUNC_PAREN_PATTERN_3-NEXT: End completions
 }
 
@@ -1081,6 +1110,7 @@
 // CHAINED_CALLS_1-DAG: Decl[InstanceMethod]/CurrNominal: .doFoo()[#SomeBuilder#]{{; name=.+$}}
 // CHAINED_CALLS_1-DAG: Decl[InstanceMethod]/CurrNominal: .doBar()[#SomeBuilder#]{{; name=.+$}}
 // CHAINED_CALLS_1-DAG: Decl[InstanceMethod]/CurrNominal: .doBaz({#(z): Double#})[#SomeBuilder#]{{; name=.+$}}
+// CHAINED_CALLS_1-DAG: Keyword[self]/CurrNominal: .self[#SomeBuilder#]; name=self
 // CHAINED_CALLS_1: End completions
 }
 
@@ -1090,6 +1120,7 @@
 // CHAINED_CALLS_2-DAG: Decl[InstanceMethod]/CurrNominal: .doFoo()[#SomeBuilder#]{{; name=.+$}}
 // CHAINED_CALLS_2-DAG: Decl[InstanceMethod]/CurrNominal: .doBar()[#SomeBuilder#]{{; name=.+$}}
 // CHAINED_CALLS_2-DAG: Decl[InstanceMethod]/CurrNominal: .doBaz({#(z): Double#})[#SomeBuilder#]{{; name=.+$}}
+// CHAINED_CALLS_2-DAG: Keyword[self]/CurrNominal: .self[#SomeBuilder#]; name=self
 // CHAINED_CALLS_2: End completions
 }
 
@@ -1100,6 +1131,7 @@
 // CHAINED_CALLS_3-DAG: Decl[InstanceMethod]/CurrNominal: .doFoo()[#SomeBuilder#]{{; name=.+$}}
 // CHAINED_CALLS_3-DAG: Decl[InstanceMethod]/CurrNominal: .doBar()[#SomeBuilder#]{{; name=.+$}}
 // CHAINED_CALLS_3-DAG: Decl[InstanceMethod]/CurrNominal: .doBaz({#z: Double#})[#SomeBuilder#]{{; name=.+$}}
+// CHAINED_CALLS_3-DAG: Keyword[self]/CurrNominal: .self[#SomeBuilder#]; name=self
 // CHAINED_CALLS_3: End completions
 }
 
@@ -1113,6 +1145,7 @@
 // RESOLVE_GENERIC_PARAMS_1-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#(a): FooStruct#})[#Void#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_1-NEXT: Decl[InstanceMethod]/CurrNominal: .fooTInstanceFunc1({#(a): FooStruct#})[#FooStruct#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_1-NEXT: Decl[InstanceMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_1-NEXT: Keyword[self]/CurrNominal:        .self[#FooGenericStruct<FooStruct>#]; name=self
 // RESOLVE_GENERIC_PARAMS_1-NEXT: End completions
 
   FooGenericStruct<FooStruct>#^RESOLVE_GENERIC_PARAMS_1_STATIC^#
@@ -1127,6 +1160,7 @@
 // RESOLVE_GENERIC_PARAMS_1_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooVoidStaticFunc1({#(a): FooStruct#})[#Void#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_1_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooTStaticFunc1({#(a): FooStruct#})[#FooStruct#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_1_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_1_STATIC-NEXT: Keyword[self]/CurrNominal:        .self[#FooGenericStruct<FooStruct>.Type#]; name=self
 // RESOLVE_GENERIC_PARAMS_1_STATIC-NEXT: End completions
 }
 
@@ -1138,6 +1172,7 @@
 // RESOLVE_GENERIC_PARAMS_2-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#(a): FooProtocol#})[#Void#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_2-NEXT: Decl[InstanceMethod]/CurrNominal: .fooTInstanceFunc1({#(a): FooProtocol#})[#FooProtocol#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_2-NEXT: Decl[InstanceMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_2-NEXT: Keyword[self]/CurrNominal:        .self[#FooGenericStruct<Foo>#]; name=self
 // RESOLVE_GENERIC_PARAMS_2-NEXT: End completions
 
   FooGenericStruct<Foo>#^RESOLVE_GENERIC_PARAMS_2_STATIC^#
@@ -1152,6 +1187,7 @@
 // RESOLVE_GENERIC_PARAMS_2_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooVoidStaticFunc1({#(a): FooProtocol#})[#Void#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_2_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooTStaticFunc1({#(a): FooProtocol#})[#FooProtocol#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_2_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_2_STATIC-NEXT: Keyword[self]/CurrNominal:        .self[#FooGenericStruct<Foo>.Type#]; name=self
 // RESOLVE_GENERIC_PARAMS_2_STATIC-NEXT: End completions
 }
 
@@ -1164,10 +1200,11 @@
 // RESOLVE_GENERIC_PARAMS_3-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#(a): FooStruct#})[#Void#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_3-NEXT: Decl[InstanceMethod]/CurrNominal: .fooTInstanceFunc1({#(a): FooStruct#})[#FooStruct#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_3-NEXT: Decl[InstanceMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_3-NEXT: Keyword[self]/CurrNominal:        .self[#FooGenericStruct<FooStruct>#]; name=self
 // RESOLVE_GENERIC_PARAMS_3-NEXT: End completions
 
     FooGenericStruct<FooStruct>#^RESOLVE_GENERIC_PARAMS_3_STATIC^#
-// RESOLVE_GENERIC_PARAMS_3_STATIC: Begin completions, 10 items
+// RESOLVE_GENERIC_PARAMS_3_STATIC: Begin completions, 11 items
 // RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[Constructor]/CurrNominal:    ()[#FooGenericStruct<FooStruct>#]; name=()
 // RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[Constructor]/CurrNominal:    ({#t: FooStruct#})[#FooGenericStruct<FooStruct>#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#self: &FooGenericStruct<FooStruct>#})[#(FooStruct) -> Void#]{{; name=.+$}}
@@ -1178,6 +1215,7 @@
 // RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooVoidStaticFunc1({#(a): FooStruct#})[#Void#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooTStaticFunc1({#(a): FooStruct#})[#FooStruct#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: Keyword[self]/CurrNominal:        .self[#FooGenericStruct<FooStruct>.Type#]; name=self
 // RESOLVE_GENERIC_PARAMS_3_STATIC-NEXT: End completions
   }
 
@@ -1189,6 +1227,7 @@
 // RESOLVE_GENERIC_PARAMS_4-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#(a): T#})[#Void#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_4-NEXT: Decl[InstanceMethod]/CurrNominal: .fooTInstanceFunc1({#(a): T#})[#T#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_4-NEXT: Decl[InstanceMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_4-NEXT: Keyword[self]/CurrNominal:        .self[#FooGenericStruct<T>#]; name=self
 // RESOLVE_GENERIC_PARAMS_4-NEXT: End completions
 
     FooGenericStruct<T>#^RESOLVE_GENERIC_PARAMS_4_STATIC^#
@@ -1203,6 +1242,7 @@
 // RESOLVE_GENERIC_PARAMS_4_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooVoidStaticFunc1({#(a): T#})[#Void#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_4_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooTStaticFunc1({#(a): T#})[#T#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_4_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_4_STATIC-NEXT: Keyword[self]/CurrNominal:        .self[#FooGenericStruct<T>.Type#]; name=self
 // RESOLVE_GENERIC_PARAMS_4_STATIC-NEXT: End completions
   }
 
@@ -1214,6 +1254,7 @@
 // RESOLVE_GENERIC_PARAMS_5-NEXT: Decl[InstanceMethod]/CurrNominal: .fooVoidInstanceFunc1({#(a): U#})[#Void#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_5-NEXT: Decl[InstanceMethod]/CurrNominal: .fooTInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_5-NEXT: Decl[InstanceMethod]/CurrNominal: .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_5-NEXT: Keyword[self]/CurrNominal:        .self[#FooGenericStruct<U>#]; name=self
 // RESOLVE_GENERIC_PARAMS_5-NEXT: End completions
 
     FooGenericStruct<U>#^RESOLVE_GENERIC_PARAMS_5_STATIC^#
@@ -1228,6 +1269,7 @@
 // RESOLVE_GENERIC_PARAMS_5_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooVoidStaticFunc1({#(a): U#})[#Void#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_5_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooTStaticFunc1({#(a): U#})[#U#]{{; name=.+$}}
 // RESOLVE_GENERIC_PARAMS_5_STATIC-NEXT: Decl[StaticMethod]/CurrNominal:   .fooUInstanceFunc1({#(a): U#})[#U#]{{; name=.+$}}
+// RESOLVE_GENERIC_PARAMS_5_STATIC-NEXT: Keyword[self]/CurrNominal:        .self[#FooGenericStruct<U>.Type#]; name=self
 // RESOLVE_GENERIC_PARAMS_5_STATIC-NEXT: End completions
   }
 }
@@ -1263,6 +1305,7 @@
   BuilderStyle().#^TC_UNSOLVED_VARIABLES_1^#
 }
 // TC_UNSOLVED_VARIABLES_1: Begin completions
+// TC_UNSOLVED_VARIABLES_1-NEXT: Keyword[self]/CurrNominal: self[#BuilderStyle<_>#]; name=self
 // TC_UNSOLVED_VARIABLES_1-NEXT: Decl[InstanceVar]/CurrNominal: count[#Int#]{{; name=.+$}}
 // TC_UNSOLVED_VARIABLES_1-NEXT: Decl[InstanceMethod]/CurrNominal: addString({#(s): String#})[#BuilderStyle<_>#]{{; name=.+$}}
 // TC_UNSOLVED_VARIABLES_1-NEXT: Decl[InstanceMethod]/CurrNominal: add({#(t): _#})[#BuilderStyle<_>#]{{; name=.+$}}
@@ -1273,6 +1316,7 @@
   BuilderStyle().addString("abc").#^TC_UNSOLVED_VARIABLES_2^#
 }
 // TC_UNSOLVED_VARIABLES_2: Begin completions
+// TC_UNSOLVED_VARIABLES_2-NEXT: Keyword[self]/CurrNominal: self[#BuilderStyle<_>#]; name=self
 // TC_UNSOLVED_VARIABLES_2-NEXT: Decl[InstanceVar]/CurrNominal:    count[#Int#]{{; name=.+$}}
 // TC_UNSOLVED_VARIABLES_2-NEXT: Decl[InstanceMethod]/CurrNominal: addString({#(s): String#})[#BuilderStyle<_>#]{{; name=.+$}}
 // TC_UNSOLVED_VARIABLES_2-NEXT: Decl[InstanceMethod]/CurrNominal: add({#(t): _#})[#BuilderStyle<_>#]{{; name=.+$}}
@@ -1283,6 +1327,7 @@
   BuilderStyle().addString("abc").add(42).#^TC_UNSOLVED_VARIABLES_3^#
 }
 // TC_UNSOLVED_VARIABLES_3: Begin completions
+// TC_UNSOLVED_VARIABLES_3-NEXT: Keyword[self]/CurrNominal: self[#BuilderStyle<Int>#]; name=self
 // TC_UNSOLVED_VARIABLES_3-NEXT: Decl[InstanceVar]/CurrNominal:    count[#Int#]{{; name=.+$}}
 // TC_UNSOLVED_VARIABLES_3-NEXT: Decl[InstanceMethod]/CurrNominal: addString({#(s): String#})[#BuilderStyle<Int>#]{{; name=.+$}}
 // TC_UNSOLVED_VARIABLES_3-NEXT: Decl[InstanceMethod]/CurrNominal: add({#(t): Int#})[#BuilderStyle<Int>#]{{; name=.+$}}
@@ -1648,26 +1693,29 @@
 func testDeDuped(_ x: dedupS) {
   x#^PROTOCOL_EXT_DEDUP_1^#
 // FIXME: Should produce 3 items (?)
-// PROTOCOL_EXT_DEDUP_1: Begin completions, 6 items
+// PROTOCOL_EXT_DEDUP_1: Begin completions, 7 items
 // PROTOCOL_EXT_DEDUP_1: Decl[InstanceMethod]/CurrNominal:   .foo()[#Int#]; name=foo()
 // PROTOCOL_EXT_DEDUP_1: Decl[InstanceVar]/CurrNominal:      .bar[#Int#]; name=bar
 // PROTOCOL_EXT_DEDUP_1: Decl[Subscript]/CurrNominal:        [{#Int#}][#Int#]; name=[Int]
+// PROTOCOL_EXT_DEDUP_1: Keyword[self]/CurrNominal:          .self[#dedupS#]; name=self
 // PROTOCOL_EXT_DEDUP_1: End completions
 }
 func testDeDuped2(_ x: dedupP) {
   x#^PROTOCOL_EXT_DEDUP_2^#
-// PROTOCOL_EXT_DEDUP_2: Begin completions, 3 items
+// PROTOCOL_EXT_DEDUP_2: Begin completions, 4 items
 // PROTOCOL_EXT_DEDUP_2: Decl[InstanceMethod]/CurrNominal:   .foo()[#dedupP.T#]; name=foo()
 // PROTOCOL_EXT_DEDUP_2: Decl[InstanceVar]/CurrNominal:      .bar[#dedupP.T#]; name=bar
 // PROTOCOL_EXT_DEDUP_2: Decl[Subscript]/CurrNominal:        [{#Self.T#}][#Self.T#]; name=[Self.T]
+// PROTOCOL_EXT_DEDUP_2: Keyword[self]/CurrNominal:          .self[#dedupP#]; name=self
 // PROTOCOL_EXT_DEDUP_2: End completions
 }
 func testDeDuped3<T : dedupP where T.T == Int>(_ x: T) {
   x#^PROTOCOL_EXT_DEDUP_3^#
-// PROTOCOL_EXT_DEDUP_3: Begin completions, 3 items
+// PROTOCOL_EXT_DEDUP_3: Begin completions, 4 items
 // PROTOCOL_EXT_DEDUP_3: Decl[InstanceMethod]/Super:   .foo()[#Int#]; name=foo()
 // PROTOCOL_EXT_DEDUP_3: Decl[InstanceVar]/Super:      .bar[#Int#]; name=bar
 // PROTOCOL_EXT_DEDUP_3: Decl[Subscript]/Super:        [{#Self.T#}][#Self.T#]; name=[Self.T]
+// PROTOCOL_EXT_DEDUP_3: Keyword[self]/CurrNominal:    .self[#T#]; name=self
 // PROTOCOL_EXT_DEDUP_3: End completions
 }
 
@@ -1778,6 +1826,7 @@
   func test1() {
     let person = Person(firstName: otherField.#^DOT_EXPR_NON_NOMINAL_1^#)
 // DOT_EXPR_NON_NOMINAL_1-NOT: Instance
+// DOT_EXPR_NON_NOMINAL_1: Keyword[self]/CurrNominal:          self[#Other#]; name=self
 // DOT_EXPR_NON_NOMINAL_1: Decl[InstanceVar]/CurrNominal:      nameFromOther[#Int#];
 // DOT_EXPR_NON_NOMINAL_1-NOT: Instance
   }
@@ -1785,6 +1834,7 @@
     let person = Person(firstName: 1.#^DOT_EXPR_NON_NOMINAL_2^#)
 // DOT_EXPR_NON_NOMINAL_2-NOT: otherField
 // DOT_EXPR_NON_NOMINAL_2-NOT: firstName
+// DOT_EXPR_NON_NOMINAL_2: Keyword[self]/CurrNominal:          self[#Int#]; name=self
 // DOT_EXPR_NON_NOMINAL_2: Decl[InstanceVar]/CurrNominal:      hashValue[#Int#];
 // DOT_EXPR_NON_NOMINAL_2-NOT: otherField
 // DOT_EXPR_NON_NOMINAL_2-NOT: firstName
diff --git a/test/IDE/complete_with_closure_param.swift b/test/IDE/complete_with_closure_param.swift
index 43f86bd..4e144b9 100644
--- a/test/IDE/complete_with_closure_param.swift
+++ b/test/IDE/complete_with_closure_param.swift
@@ -15,7 +15,7 @@
 
 FooStruct().#^COMPLETE^#
 
-// CHECK: Begin completions, 7 items
+// CHECK: Begin completions, 8 items
 // CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod1({#(callback): (Int, Int) -> Void##(Int, Int) -> Void#})[#Void#]; name=instanceMethod1(callback: (Int, Int) -> Void){{$}}
 // CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod2({#(callback): ((Int, Int) -> Void)?##(Int, Int) -> Void#})[#Void#]{{; name=.+$}}
 // CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod3({#(callback): ((Int, Int) -> Void)??##(Int, Int) -> Void#})[#Void#]{{; name=.+$}}
@@ -23,4 +23,5 @@
 // CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod5({#(callback): (Int, Int) -> Bool##(Int, Int) -> Bool#})[#Void#]{{; name=.+$}}
 // CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod6({#(callback): FunctionTypealias?##(Int, Int) -> Bool#})[#Void#]{{; name=.+$}}
 // CHECK-DAG: Decl[InstanceMethod]/CurrNominal: instanceMethod7({#(callback): OptionalFunctionTypealias##(Int, Int) -> Bool#})[#Void#]{{; name=.+$}}
+// CHECK-DAG: Keyword[self]/CurrNominal: self[#FooStruct#]; name=self
 // CHECK: End completions
diff --git a/test/IRGen/Inputs/emit_public_type_metadata_accessors_other.swift b/test/IRGen/Inputs/emit_public_type_metadata_accessors_other.swift
deleted file mode 100644
index 0d52c92..0000000
--- a/test/IRGen/Inputs/emit_public_type_metadata_accessors_other.swift
+++ /dev/null
@@ -1,3 +0,0 @@
-func foo() -> Any {
-  return Wrapper()
-}
diff --git a/test/IRGen/builtins.swift b/test/IRGen/builtins.swift
index bc07d9f..bf70c20 100644
--- a/test/IRGen/builtins.swift
+++ b/test/IRGen/builtins.swift
@@ -225,12 +225,12 @@
 
 // CHECK: define hidden {{.*}}void @"$S8builtins27generic_sizeof_alignof_testyyxlF"
 func generic_sizeof_alignof_test<T>(_: T) {
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 9
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 8
   // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
   // CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to i64
   // CHECK-NEXT: store i64 [[SIZE]], i64* [[S:%.*]]
   var s = Builtin.sizeof(T.self)
-  // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 10
+  // CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 9
   // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
   // CHECK-NEXT: [[T2:%.*]] = ptrtoint i8* [[T1]] to i64
   // CHECK-NEXT: [[T3:%.*]] = and i64 [[T2]], 65535
@@ -241,7 +241,7 @@
 
 // CHECK: define hidden {{.*}}void @"$S8builtins21generic_strideof_testyyxlF"
 func generic_strideof_test<T>(_: T) {
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 11
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 10
   // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
   // CHECK-NEXT: [[STRIDE:%.*]] = ptrtoint i8* [[T1]] to i64
   // CHECK-NEXT: store i64 [[STRIDE]], i64* [[S:%.*]]
@@ -771,7 +771,7 @@
 
 // CHECK-LABEL: define {{.*}} @{{.*}}generic_ispod_test
 func generic_ispod_test<T>(_: T) {
-  // CHECK:      [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 10
+  // CHECK:      [[T0:%.*]] = getelementptr inbounds i8*, i8** [[T:%.*]], i32 9
   // CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]]
   // CHECK-NEXT: [[FLAGS:%.*]] = ptrtoint i8* [[T1]] to i64
   // CHECK-NEXT: [[ISNOTPOD:%.*]] = and i64 [[FLAGS]], 65536
diff --git a/test/IRGen/closure.swift b/test/IRGen/closure.swift
index 826f354..ddc1fa7 100644
--- a/test/IRGen/closure.swift
+++ b/test/IRGen/closure.swift
@@ -4,7 +4,7 @@
 
 // -- partial_apply context metadata
 
-// CHECK: [[METADATA:@.*]] = private constant %swift.full_boxmetadata { void (%swift.refcounted*)* @objectdestroy, i8** null, %swift.type { i64 64 }, i32 16, i8* bitcast ({ i32, i32, i32, i32 }* @"\01l__swift4_reflection_descriptor" to i8*) }
+// CHECK: [[METADATA:@.*]] = private constant %swift.full_boxmetadata { void (%swift.refcounted*)* @objectdestroy, i8** null, %swift.type { i64 64 }, i32 16, i8* bitcast ({ i32, i32, i32, i32 }* @"\01l__swift5_reflection_descriptor" to i8*) }
 
 func a(i i: Int) -> (Int) -> Int {
   return { x in i }
diff --git a/test/IRGen/emit_public_type_metadata_accessors.swift b/test/IRGen/emit_public_type_metadata_accessors.swift
deleted file mode 100644
index 0cefc03..0000000
--- a/test/IRGen/emit_public_type_metadata_accessors.swift
+++ /dev/null
@@ -1,17 +0,0 @@
-// RUN: %swift -module-name test -target x86_64-apple-macosx10.9  -emit-ir -parse-stdlib -emit-public-type-metadata-accessors -primary-file %s %S/Inputs/emit_public_type_metadata_accessors_other.swift | %FileCheck --check-prefix=CHECK-PUBLIC %s
-
-// RUN: %swift -module-name test -target x86_64-apple-macosx10.9  -emit-ir -parse-stdlib -primary-file %s %S/Inputs/emit_public_type_metadata_accessors_other.swift | %FileCheck --check-prefix=CHECK-NONPUBLIC %s
-
-private class C { }
-
-// CHECK-PUBLIC: define swiftcc %swift.metadata_response @"$S4test3Foo33_DEC9477CC6E8E6E7A9CE422B1DBE7EA4LLVMa"
-// CHECK-NONPUBLIC: define internal swiftcc %swift.metadata_response @"$S4test3Foo33_DEC9477CC6E8E6E7A9CE422B1DBE7EA4LLVMa"
-private struct Foo {
-  private let c: C = C()
-}
-
-public struct Wrapper {
-  private let foo: Foo = Foo()
-}
-
-
diff --git a/test/IRGen/enum.sil b/test/IRGen/enum.sil
index d5a6e50..83cc36d 100644
--- a/test/IRGen/enum.sil
+++ b/test/IRGen/enum.sil
@@ -127,11 +127,11 @@
 
 // CHECK: @"$S4enum16DynamicSingletonOMP" = internal constant <{ {{.*}} }> <{
 // CHECK-SAME:   @"$S4enum16DynamicSingletonOMi"
-// CHECK-SAME:   [18 x i8*]* @"$S4enum16DynamicSingletonOWV"
+// CHECK-SAME:   [17 x i8*]* @"$S4enum16DynamicSingletonOWV"
 
 // -- No-payload enums have extra inhabitants in
 //    their value witness table.
-// CHECK: @"$S4enum10NoPayloadsOWV" = internal constant [18 x i8*] [
+// CHECK: @"$S4enum10NoPayloadsOWV" = internal constant [17 x i8*] [
 // -- ...
 // -- size
 // CHECK-SAME:   i8* inttoptr ([[WORD:i32|i64]] 1 to i8*),
@@ -149,7 +149,7 @@
 
 // -- Single-payload enums take unused extra inhabitants from their payload
 //    as their own.
-// CHECK: @"$S4enum19SinglePayloadNestedOWV" = internal constant [18 x i8*] [
+// CHECK: @"$S4enum19SinglePayloadNestedOWV" = internal constant [17 x i8*] [
 // -- ...
 // -- size
 // CHECK-SAME:   i8* inttoptr ([[WORD]] 1 to i8*),
@@ -165,16 +165,16 @@
 // CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$S4enum19SinglePayloadNestedOwxg" to i8*)
 // CHECK-SAME: ]
 
-// CHECK: @"$S4enum20DynamicSinglePayloadOWV" = internal constant [18 x i8*] [
+// CHECK: @"$S4enum20DynamicSinglePayloadOWV" = internal constant [17 x i8*] [
 // CHECK-SAME:   i8* null
 // CHECK-SAME:   i8* bitcast (void (%swift.opaque*, i32, %swift.type*)* @"$S4enum20DynamicSinglePayloadOwxs" to i8*)
 // CHECK-SAME:   i8* bitcast (i32 (%swift.opaque*, %swift.type*)* @"$S4enum20DynamicSinglePayloadOwxg" to i8*)
 
 // CHECK: @"$S4enum20DynamicSinglePayloadOMP" = internal constant <{ {{.*}} }> <{
 // CHECK-SAME:   @"$S4enum20DynamicSinglePayloadOMi"
-// CHECK-SAME:   [18 x i8*]* @"$S4enum20DynamicSinglePayloadOWV"
+// CHECK-SAME:   [17 x i8*]* @"$S4enum20DynamicSinglePayloadOWV"
 
-// CHECK: @"$S4enum18MultiPayloadNestedOWV" = internal constant [18 x i8*] [
+// CHECK: @"$S4enum18MultiPayloadNestedOWV" = internal constant [17 x i8*] [
 // -- size
 // CHECK-32-SAME:   i8* inttoptr ([[WORD]] 5 to i8*),
 // CHECK-64-SAME:   i8* inttoptr ([[WORD]] 9 to i8*),
@@ -1209,7 +1209,7 @@
 // CHECK:   [[TMP:%.*]] = bitcast %swift.type* %T to i8***
 // CHECK:   [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
-// CHECK:   [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 7
+// CHECK:   [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 6
 // CHECK:   [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
 // CHECK:   %getEnumTagSinglePayload = bitcast i8* [[WITNESS]] to i32 (%swift.opaque*, i32, %swift.type*)*
 // CHECK:   [[CASE_INDEX:%.*]] = call i32 %getEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 3, %swift.type* %T)
@@ -1240,7 +1240,7 @@
 // CHECK:   [[TMP:%.*]] = bitcast %swift.type* %T to i8***
 // CHECK:   [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
-// CHECK:   [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
+// CHECK:   [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 7
 // CHECK:   [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
 // CHECK:   %storeEnumTagSinglePayload = bitcast i8* [[WITNESS]] to void (%swift.opaque*, i32, i32, %swift.type*)*
 // CHECK:   call void %storeEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 0, i32 3, %swift.type* %T)
@@ -1256,7 +1256,7 @@
 // CHECK:   [[TMP:%.*]] = bitcast %swift.type* %T to i8***
 // CHECK:   [[TMP2:%.*]] = getelementptr inbounds i8**, i8*** [[TMP]], i{{.*}} -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[TMP2]]
-// CHECK:   [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
+// CHECK:   [[ENUMADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 7
 // CHECK:   [[WITNESS:%.*]] = load i8*, i8** [[ENUMADDR]]
 // CHECK:   %storeEnumTagSinglePayload = bitcast i8* [[WITNESS]] to void (%swift.opaque*, i32, i32, %swift.type*)*
 // CHECK:   call void %storeEnumTagSinglePayload(%swift.opaque* noalias [[OPAQUE_ENUM]], i32 1, i32 3, %swift.type* %T)
@@ -2640,7 +2640,7 @@
 // CHECK:   [[T_VWTS:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
 // CHECK:   [[T_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[T_VWTS]], [[WORD]] -1
 // CHECK:   [[T_VWT:%.*]] = load i8**, i8*** [[T_VWT_ADDR]]
-// CHECK:   [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 9
+// CHECK:   [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 8
 // CHECK:   call void @swift_initEnumMetadataSingleCase(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]])
 // CHECK:   ret %swift.metadata_response
 
@@ -2659,7 +2659,7 @@
 // CHECK:   [[T_VWTS:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
 // CHECK:   [[T_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[T_VWTS]], [[WORD]] -1
 // CHECK:   [[T_VWT:%.*]] = load i8**, i8*** [[T_VWT_ADDR]]
-// CHECK:   [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 9
+// CHECK:   [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VWT]], i32 8
 // CHECK:   call void @swift_initEnumMetadataSinglePayload(%swift.type* [[METADATA]], [[WORD]] 0, i8** [[T_LAYOUT]], i32 3)
 
 // CHECK-64-LABEL: define linkonce_odr hidden void @"$S4enum17StructWithWeakVarVwxs"(%swift.opaque* noalias %dest, i32 %index, %swift.type* %StructWithWeakVar)
diff --git a/test/IRGen/enum_dynamic_multi_payload.sil b/test/IRGen/enum_dynamic_multi_payload.sil
index 514fd58..331f184 100644
--- a/test/IRGen/enum_dynamic_multi_payload.sil
+++ b/test/IRGen/enum_dynamic_multi_payload.sil
@@ -433,7 +433,7 @@
 // CHECK:      [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]]
 // CHECK-NEXT: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
-// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
+// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
 // CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF0]]
 
 // CHECK:      [[BUF1:%.*]] = getelementptr {{.*}} [[BUF]], i32 0, i32 1
@@ -445,7 +445,7 @@
 // CHECK:      [[T0:%.*]] = bitcast %swift.type* [[U_CHECKED]] to i8***
 // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]]
 // CHECK-NEXT: [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
-// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
+// CHECK-NEXT: [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
 // CHECK-NEXT: store i8** [[LAYOUT]], {{.*}} [[BUF1]]
 
 // CHECK:   call void @swift_initEnumMetadataMultiPayload(%swift.type* [[METADATA]], {{i(32|64)}} 0, {{i(32|64)}} 2, i8*** [[BUF0]])
diff --git a/test/IRGen/enum_resilience.swift b/test/IRGen/enum_resilience.swift
index 3a7585b..692f7c6 100644
--- a/test/IRGen/enum_resilience.swift
+++ b/test/IRGen/enum_resilience.swift
@@ -119,7 +119,7 @@
 // CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
 // CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
 
-// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 17
+// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 16
 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK-NEXT: [[WITNESS_FN:%.*]] = bitcast i8* [[WITNESS]]
 // CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 [[TAG]], %swift.type* [[METADATA]])
@@ -148,7 +148,7 @@
 // CHECK-NEXT: [[VWT_ADDR2:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR2]], [[INT]] -1
 // CHECK-NEXT: [[VWT2:%.*]] = load i8**, i8*** [[VWT_ADDR2]]
 
-// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 17
+// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 16
 // CHECK-NEXT: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK-NEXT: [[WITNESS_FN:%destructiveInjectEnumTag]] = bitcast i8* [[WITNESS]]
 // CHECK-NEXT: call void [[WITNESS_FN]](%swift.opaque* noalias %0, i32 [[TAG]], %swift.type* [[METADATA2]])
@@ -165,7 +165,7 @@
 // CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
 // CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
 
-// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
 // CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK: [[WITNESS_FOR_SIZE:%size]] = ptrtoint i8* [[WITNESS]]
 // CHECK: [[ALLOCA:%.*]] = alloca i8, {{.*}} [[WITNESS_FOR_SIZE]], align 16
@@ -177,7 +177,7 @@
 // CHECK: [[WITNESS_FN:%initializeWithCopy]] = bitcast i8* [[WITNESS]]
 // CHECK: [[ENUM_COPY:%.*]] = call %swift.opaque* [[WITNESS_FN]](%swift.opaque* noalias [[ENUM_STORAGE]], %swift.opaque* noalias %0, %swift.type* [[METADATA]])
 
-// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 15
+// CHECK: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 14
 // CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK: [[WITNESS_FN:%getEnumTag]] = bitcast i8* [[WITNESS]]
 // CHECK: [[TAG:%.*]] = call i32 [[WITNESS_FN]](%swift.opaque* noalias [[ENUM_STORAGE]], %swift.type* [[METADATA]])
diff --git a/test/IRGen/enum_value_semantics.sil b/test/IRGen/enum_value_semantics.sil
index 4de87f8..e5a6417 100644
--- a/test/IRGen/enum_value_semantics.sil
+++ b/test/IRGen/enum_value_semantics.sil
@@ -94,14 +94,13 @@
 }
 
 
-// CHECK-LABEL: @"$S20enum_value_semantics20SinglePayloadTrivialOWV" = internal constant [18 x i8*] [
+// CHECK-LABEL: @"$S20enum_value_semantics20SinglePayloadTrivialOWV" = internal constant [17 x i8*] [
 // CHECK:   i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
 // CHECK:   i8* bitcast (void (i8*, %swift.type*)* @__swift_noop_void_return to i8*),
 // CHECK:   i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
 // CHECK:   i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
 // CHECK:   i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
 // CHECK:   i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
-// CHECK:   i8* bitcast (i8* (i8*, i8*, %swift.type*)* @__swift_memcpy9_8 to i8*),
 // CHECK:   i8* bitcast (i32 (%swift.opaque*, i32, %swift.type*)* @"$S20enum_value_semantics20SinglePayloadTrivialOwet" to i8*),
 // CHECK:   i8* bitcast (void (%swift.opaque*, i32, i32, %swift.type*)* @"$S20enum_value_semantics20SinglePayloadTrivialOwst" to i8*),
 // CHECK:   i8* inttoptr (i64 9 to i8*),
@@ -118,13 +117,13 @@
 
 // CHECK-LABEL: @"$S20enum_value_semantics20SinglePayloadTrivialOMf" =
 // CHECK-SAME:   internal constant <{ {{.*}} }> <{
-// CHECK-SAME:   i8** getelementptr inbounds ([18 x i8*], [18 x i8*]* @"$S20enum_value_semantics20SinglePayloadTrivialOWV", i32 0, i32 0),
+// CHECK-SAME:   i8** getelementptr inbounds ([17 x i8*], [17 x i8*]* @"$S20enum_value_semantics20SinglePayloadTrivialOWV", i32 0, i32 0),
 // CHECK-SAME:   i64 2,
 // CHECK-SAME:   {{.*}}* @"$S20enum_value_semantics20SinglePayloadTrivialOMn"
 // CHECK-SAME: }>
 
 
-// CHECK-LABEL: @"$S20enum_value_semantics23SinglePayloadNontrivialOWV" = internal constant [18 x i8*] [
+// CHECK-LABEL: @"$S20enum_value_semantics23SinglePayloadNontrivialOWV" = internal constant [17 x i8*] [
 // CHECK:   i8* bitcast (%swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwCP" to i8*),
 // CHECK:   i8* bitcast (void (%swift.opaque*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwxx" to i8*),
 // CHECK:   i8* bitcast (%swift.opaque* (%swift.opaque*, %swift.opaque*, %swift.type*)* @"$S20enum_value_semantics23SinglePayloadNontrivialOwcp" to i8*),
@@ -148,7 +147,7 @@
 
 // CHECK-LABEL: @"$S20enum_value_semantics23SinglePayloadNontrivialOMf" =
 // CHECK-SAME: internal constant <{ {{.*}} }> <{
-// CHECK-SAME:   i8** getelementptr inbounds ([18 x i8*], [18 x i8*]* @"$S20enum_value_semantics23SinglePayloadNontrivialOWV", i32 0, i32 0),
+// CHECK-SAME:   i8** getelementptr inbounds ([17 x i8*], [17 x i8*]* @"$S20enum_value_semantics23SinglePayloadNontrivialOWV", i32 0, i32 0),
 // CHECK-SAME:   i64 2,
 // CHECK-SAME:   {{.*}}* @"$S20enum_value_semantics23SinglePayloadNontrivialOMn"
 // CHECK-SAME: }>
@@ -166,7 +165,7 @@
 //   Pattern flags.  0x400000 == (MetadataKind::Enum << 21).
 // CHECK-SAME:    i32 4194304,
 //   Value witness table.
-// CHECK-SAME:    i32 trunc (i64 sub (i64 ptrtoint ([18 x i8*]* @"$S20enum_value_semantics18GenericFixedLayoutOWV" to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32, i32 }>, <{ i32, i32, i32, i32 }>* @"$S20enum_value_semantics18GenericFixedLayoutOMP", i32 0, i32 3) to i64)) to i32)
+// CHECK-SAME:    i32 trunc (i64 sub (i64 ptrtoint ([17 x i8*]* @"$S20enum_value_semantics18GenericFixedLayoutOWV" to i64), i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32, i32, i32 }>, <{ i32, i32, i32, i32 }>* @"$S20enum_value_semantics18GenericFixedLayoutOMP", i32 0, i32 3) to i64)) to i32)
 // CHECK-SAME:  }>
 
 sil @single_payload_nontrivial_copy_destroy : $(@owned SinglePayloadNontrivial) -> () {
diff --git a/test/IRGen/existentials.sil b/test/IRGen/existentials.sil
index 20ee97c..d376d57 100644
--- a/test/IRGen/existentials.sil
+++ b/test/IRGen/existentials.sil
@@ -5,6 +5,14 @@
 sil_stage canonical
 
 import Swift
+protocol P {}
+
+// NonBitwiseTakableBit = 0x00100000. This struct is bitwise takable because
+// 0x30007 = 196615.
+// CHECK: @"$S12existentials14BitwiseTakableVWV" = internal constant [11 x i8*] {{.*}} i8* inttoptr (i64 196615 to i8*)
+struct BitwiseTakable {
+  var p: P
+}
 
 protocol CP: class {}
 
diff --git a/test/IRGen/existentials_objc.sil b/test/IRGen/existentials_objc.sil
index 02569f64..2f001e0 100644
--- a/test/IRGen/existentials_objc.sil
+++ b/test/IRGen/existentials_objc.sil
@@ -42,20 +42,11 @@
 // CHECK: call %Any* @"$SypWOb"(%Any* %1, %Any* %0)
 // CHECK-NEXT:    ret void
 
-// CHECK-DAG:   define linkonce_odr hidden %Any* @"$SypWOb"([[ANY:%Any]]*, %Any*)
-// CHECK:         [[T0:%.*]] = getelementptr inbounds [[ANY]], [[ANY]]* [[SRC:%0]], i32 0, i32 1
-// CHECK-NEXT:    [[TYPE:%.*]] = load %swift.type*, %swift.type** [[T0]], align 8
-// CHECK-NEXT:    [[T0:%.*]] = getelementptr inbounds [[ANY]], [[ANY]]* [[DEST:%1]], i32 0, i32 1
-// CHECK-NEXT:    store %swift.type* [[TYPE]], %swift.type** [[T0]], align 8
-// CHECK-NEXT: [[FROM_BUFFER_ADDR:%.*]] = getelementptr inbounds %Any, %Any* %0, i32 0, i32 0
-// CHECK-NEXT: [[TO_BUFFER_ADDR:%.*]] = getelementptr inbounds %Any, %Any* %1, i32 0, i32 0
-// CHECK-NEXT: [[CAST:%.*]] = bitcast %swift.type* [[TYPE]] to i8***
-// CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], i64 -1
-// CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK-NEXT: [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 6
-// CHECK-NEXT: [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
-// CHECK-NEXT: [[INITWITHTAKEBUFFER:%.*]] = bitcast i8* [[VW]]
-// CHECK-NEXT: call %swift.opaque* [[INITWITHTAKEBUFFER]]({{.*}} [[TO_BUFFER_ADDR]], {{.*}} [[FROM_BUFFER_ADDR]], %swift.type* [[TYPE]])
+// CHECK-DAG:   define linkonce_odr hidden %Any* @"$SypWOb"(%Any*, %Any*)
+// CHECK:       %2 = bitcast %Any* %1 to i8*
+// CHECK-NEXT:  %3 = bitcast %Any* %0 to i8*
+// CHECK-NEXT:  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %3, i64 32, i32 8, i1 false)
+// CHECK-NEXT:  ret %Any* %1
 
 // rdar://problem/19035529
 @objc protocol OP {}
diff --git a/test/IRGen/existentials_opaque_boxed.sil b/test/IRGen/existentials_opaque_boxed.sil
index 2f02228..cf5b22b 100644
--- a/test/IRGen/existentials_opaque_boxed.sil
+++ b/test/IRGen/existentials_opaque_boxed.sil
@@ -41,7 +41,7 @@
 // CHECK:  [[CAST:%.*]] = bitcast %swift.type* [[METATYPE]]
 // CHECK:  [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
 // CHECK:  [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK:  [[FLAG_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK:  [[FLAG_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
 // CHECK:  [[FLAG_WITNESS:%.*]] = load i8*, i8** [[FLAG_WITNESS_ADDR]]
 // CHECK:  [[FLAGS:%.*]] = ptrtoint i8* [[FLAG_WITNESS]]
 // CHECK:  [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -115,7 +115,7 @@
 // CHECK:   [[CAST:%.*]] = bitcast %swift.type* [[META]] to i8***
 // CHECK:   [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** %3, {{(i64|i32)}} -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
 // CHECK:   [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
 // CHECK:   [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
 // CHECK:   [[MASKED:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -132,7 +132,7 @@
 // CHECK:   [[CAST:%.*]] = bitcast %swift.type* [[META]] to i8***
 // CHECK:   [[VWT_ADDR2:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
 // CHECK:   [[VWT2:%.*]] = load i8**, i8*** [[VWT_ADDR2]]
-// CHECK:   [[VW_ADDR2:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 9
+// CHECK:   [[VW_ADDR2:%.*]] = getelementptr inbounds i8*, i8** [[VWT2]], i32 8
 // CHECK:   [[VW2:%.*]] = load i8*, i8** [[VW_ADDR2]]
 // CHECK:   [[SIZE:%.*]] = ptrtoint i8* [[VW2]] to {{(i64|i32)}}
 // CHECK:   [[ALIGNMASK:%.*]] = and {{(i64|i32)}} [[FLAGS]], 65535
@@ -164,7 +164,7 @@
 // CHECK:   [[CAST:%.*]] = bitcast %swift.type* %1 to i8***
 // CHECK:   [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
 // CHECK:   [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
 // CHECK:   [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
 // CHECK:   [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -207,7 +207,7 @@
 // CHECK:   [[CAST:%.*]] = bitcast %swift.type* %1 to i8***
 // CHECK:   [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
 // CHECK:   [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
 // CHECK:   [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
 // CHECK:   [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -244,7 +244,7 @@
 // CHECK:  [[CAST:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
 // CHECK:  [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
 // CHECK:  [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK:  [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK:  [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
 // CHECK:  [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
 // CHECK:  [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
 // CHECK:  [[ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -301,7 +301,7 @@
 // CHECK:   [[CAST:%.*]] = bitcast %swift.type* [[DEST_TYPE]] to i8***
 // CHECK:   [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 10
+// CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
 // CHECK:   [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
 // CHECK:   [[FLAGS:%.*]] = ptrtoint i8* [[VW]] to {{(i64|i32)}}
 // CHECK:   [[MASKED:%.*]] = and {{(i64|i32)}} [[FLAGS]], 131072
@@ -339,7 +339,7 @@
 // CHECK:   [[CAST:%.*]] = bitcast %swift.type* [[DEST_TYPE]] to i8***
 // CHECK:   [[DEST_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
 // CHECK:   [[DEST_VWT:%.*]] = load i8**, i8*** [[DEST_VWT_ADDR]]
-// CHECK:   [[DEST_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[DEST_VWT]], i32 10
+// CHECK:   [[DEST_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[DEST_VWT]], i32 9
 // CHECK:   [[DEST_VW:%.*]] = load i8*, i8** [[DEST_VW_ADDR]]
 // CHECK:   [[DEST_FLAGS:%.*]] = ptrtoint i8* [[DEST_VW]] to {{(i64|i32)}}
 // CHECK:   [[DEST_ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[DEST_FLAGS]], 131072
@@ -347,7 +347,7 @@
 // CHECK:   [[CAST:%.*]] = bitcast %swift.type* [[SRC_TYPE]] to i8***
 // CHECK:   [[SRC_VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{(i64|i32)}} -1
 // CHECK:   [[SRC_VWT:%.*]] = load i8**, i8*** [[SRC_VWT_ADDR]]
-// CHECK:   [[SRC_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SRC_VWT]], i32 10
+// CHECK:   [[SRC_VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[SRC_VWT]], i32 9
 // CHECK:   [[SRC_VW:%.*]] = load i8*, i8** [[SRC_VW_ADDR]]
 // CHECK:   [[SRC_FLAGS:%.*]] = ptrtoint i8* [[SRC_VW]] to {{(i64|i32)}}
 // CHECK:   [[SRC_ISNOTINLINE:%.*]] = and {{(i64|i32)}} [[SRC_FLAGS]], 131072
@@ -443,25 +443,11 @@
   return %t : $()
 }
 
-// CHECK: define linkonce_odr hidden %T25existentials_opaque_boxed11ExistentialP* @"$S25existentials_opaque_boxed11Existential_pWOb"(%T25existentials_opaque_boxed11ExistentialP*, %T25existentials_opaque_boxed11ExistentialP*)
-// CHECK:   [[METADATA_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %0, i32 0, i32 1
-// CHECK:   [[METADATA:%.*]] = load %swift.type*, %swift.type** [[METADATA_ADDR]]
-// CHECK:   [[LOCAL_METADATA_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %1, i32 0, i32 1
-// CHECK:   store %swift.type* [[METADATA]], %swift.type** [[LOCAL_METADATA_ADDR]]
-// CHECK:   [[PWT_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %0, i32 0, i32 2
-// CHECK:   [[PWT:%.*]] = load i8**, i8*** [[PWT_ADDR]]
-// CHECK:   [[LOCAL_PWT_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %1, i32 0, i32 2
-// CHECK:   store i8** [[PWT]], i8*** [[LOCAL_PWT_ADDR]]
-// CHECK:   [[BUFFER_ARG_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %0, i32 0, i32 0
-// CHECK:   [[BUFFER_LOCAL_ADDR:%.*]] = getelementptr inbounds %T25existentials_opaque_boxed11ExistentialP, %T25existentials_opaque_boxed11ExistentialP* %1, i32 0, i32 0
-// CHECK:   [[CAST_ADDR:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
-// CHECK:   [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST_ADDR]], {{(i64|i32)}} -1
-// CHECK:   [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK:   [[VW_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 6
-// CHECK:   [[VW:%.*]] = load i8*, i8** [[VW_ADDR]]
-// CHECK:   [[INITWITHTAKEBUFFER:%.*]] = bitcast i8* [[VW]]
-// CHECK:     call %swift.opaque* [[INITWITHTAKEBUFFER]]({{.*}} [[BUFFER_LOCAL_ADDR]], {{.*}} [[BUFFER_ARG_ADDR]], %swift.type* [[METADATA]])
-// CHECK:   ret %T25existentials_opaque_boxed11ExistentialP* %1
+// CHECK-LABEL: define linkonce_odr hidden %T25existentials_opaque_boxed11ExistentialP* @"$S25existentials_opaque_boxed11Existential_pWOb"(%T25existentials_opaque_boxed11ExistentialP*, %T25existentials_opaque_boxed11ExistentialP*)
+// CHECK:  %2 = bitcast %T25existentials_opaque_boxed11ExistentialP* %1 to i8*
+// CHECK:  %3 = bitcast %T25existentials_opaque_boxed11ExistentialP* %0 to i8*
+// CHECK:  call void @llvm.memcpy.p0i8.p0i8.{{(i64|i32)}}(i8* %2, i8* %3, {{(i64 40|i32 20)}}, {{(i32 8|i32 4)}}, i1 false)
+// CHECK:  ret %T25existentials_opaque_boxed11ExistentialP* %1
 
 // CHECK: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_initWithTake_existential_addr(%T25existentials_opaque_boxed11ExistentialP*
 // CHECK:   [[LOCAL:%.*]] = alloca %T25existentials_opaque_boxed11ExistentialP
diff --git a/test/IRGen/generic_casts.swift b/test/IRGen/generic_casts.swift
index 19d6fce..a8ea816 100644
--- a/test/IRGen/generic_casts.swift
+++ b/test/IRGen/generic_casts.swift
@@ -38,7 +38,7 @@
 	// CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
   // CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], i64 -1
   // CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-  // CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+  // CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
   // CHECK: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
   // CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
   // CHECK: [[T_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
diff --git a/test/IRGen/generic_classes.sil b/test/IRGen/generic_classes.sil
index c6d89f8..5468524 100644
--- a/test/IRGen/generic_classes.sil
+++ b/test/IRGen/generic_classes.sil
@@ -389,7 +389,7 @@
 // CHECK:   [[T0:%.*]] = bitcast %swift.type* [[B_CHECKED]] to i8***
 // CHECK:   [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[T1]], align 8
-// CHECK:   [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK:   [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
 // CHECK:   [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[FIELDS_ADDR]], i32 0
 // CHECK:   store i8** [[T0]], i8*** [[T1]], align 8
 // CHECK:   call void @swift_initClassMetadata(%swift.type* [[METADATA]], i64 0, i64 1, i8*** [[FIELDS_ADDR]], i64* [[OFFSETS]])
diff --git a/test/IRGen/generic_structs.sil b/test/IRGen/generic_structs.sil
index 6b5a754..14bc524 100644
--- a/test/IRGen/generic_structs.sil
+++ b/test/IRGen/generic_structs.sil
@@ -228,20 +228,6 @@
 // CHECK-NEXT: ret %swift.opaque* [[T2]]
 
 
-//   initializeBufferWithTakeOfBuffer
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S15generic_structs13SingleDynamicVwTK"([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %"SingleDynamic<T>") {{.*}} {
-// CHECK:      %T = load %swift.type*,
-// CHECK-NEXT: [[T0:%.*]] = bitcast %swift.type* %T to i8***
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
-// CHECK-NEXT: %T.valueWitnesses = load i8**, i8*** [[T1]]
-// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 6
-// CHECK-NEXT: [[T1:%.*]] = load i8*, i8** [[T0]],
-// CHECK-NEXT: [[FN:%.*]] = bitcast i8* [[T1]] to %swift.opaque* ([24 x i8]*, [24 x i8]*, %swift.type*)*
-// CHECK-NEXT: [[T0:%.*]] = call %swift.opaque* [[FN]]([24 x i8]* noalias %dest, [24 x i8]* noalias %src, %swift.type* %T)
-// CHECK-NEXT: [[T1:%.*]] = bitcast %swift.opaque* [[T0]] to {{.*}}
-// CHECK-NEXT: [[T2:%.*]] = bitcast {{.*}} [[T1]] to %swift.opaque*
-// CHECK-NEXT: ret %swift.opaque* [[T2]]
-
 protocol HasAssociatedType {
   associatedtype Assoc
 }
diff --git a/test/IRGen/generic_tuples.swift b/test/IRGen/generic_tuples.swift
index c94739b..b2fc7f4 100644
--- a/test/IRGen/generic_tuples.swift
+++ b/test/IRGen/generic_tuples.swift
@@ -18,7 +18,7 @@
 // CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
 // CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], i64 -1
 // CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
 // CHECK: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
 // CHECK: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
 // CHECK: [[X_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
diff --git a/test/IRGen/global_resilience.sil b/test/IRGen/global_resilience.sil
index 200a217..e02d869 100644
--- a/test/IRGen/global_resilience.sil
+++ b/test/IRGen/global_resilience.sil
@@ -125,7 +125,7 @@
 // CHECK:   [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
 // CHECK:   [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK:   [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 10
+// CHECK:   [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 9
 // CHECK:   [[FLAGSWITNESS:%.*]] = load i8*, i8** [[FLAGS_ADDR]]
 // CHECK:   [[FLAGS:%.*]] = ptrtoint i8* [[FLAGSWITNESS]] to i{{.*}}
 // CHECK:   [[ISNOTINLINE:%.*]] = and {{.*}} [[FLAGS]], 131072
@@ -136,7 +136,7 @@
 // CHECK:   [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
 // CHECK:   [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK:   [[SIZE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK:   [[SIZE_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
 // CHECK:   [[SIZEWITNESS:%.*]] = load i8*, i8** [[SIZE_ADDR]]
 // CHECK:   [[SIZE:%.*]] = ptrtoint i8* [[SIZEWITNESS]]
 // CHECK:   [[ALIGN:%.*]] = and {{.*}} [[FLAGS]], 65535
@@ -155,7 +155,7 @@
 // CHECK:   [[CAST:%.*]] = bitcast %swift.type* %0 to i8***
 // CHECK:   [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[CAST]], {{.*}} -1
 // CHECK:   [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK:   [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 10
+// CHECK:   [[FLAGS_ADDR:%.*]] = getelementptr inbounds i8*, i8** %.valueWitnesses, i32 9
 // CHECK:   [[FLAGSWITNESS:%.*]] = load i8*, i8** [[FLAGS_ADDR]]
 // CHECK:   [[FLAGS:%.*]] = ptrtoint i8* [[FLAGSWITNESS]] to i{{.*}}
 // CHECK:   [[ISNOTINLINE:%.*]] = and {{.*}} [[FLAGS]], 131072
diff --git a/test/IRGen/indexing.sil b/test/IRGen/indexing.sil
index 14bbd17..d8153fe 100644
--- a/test/IRGen/indexing.sil
+++ b/test/IRGen/indexing.sil
@@ -45,7 +45,7 @@
 // CHECK:        %3 = bitcast %swift.type* %T to i8***
 // CHECK-NEXT:   %4 = getelementptr inbounds i8**, i8*** %3, i64 -1
 // CHECK-NEXT:   %T.valueWitnesses = load i8**, i8*** %4, align 8
-// CHECK-NEXT:   %5 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 11
+// CHECK-NEXT:   %5 = getelementptr inbounds i8*, i8** %T.valueWitnesses, i32 10
 // CHECK-NEXT:   %6 = load i8*, i8** %5, align 8
 // CHECK-NEXT:   %stride = ptrtoint i8* %6 to i64
 // CHECK-NEXT:   %7 = mul nsw i64 %1, %stride
diff --git a/test/IRGen/lifetime.sil b/test/IRGen/lifetime.sil
index 91b1a7d..365302c 100644
--- a/test/IRGen/lifetime.sil
+++ b/test/IRGen/lifetime.sil
@@ -22,7 +22,7 @@
 // CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
 // CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], {{(i32|i64)}} -1
 // CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
 // CHECK-NEXT: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
 // CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
 // CHECK-NEXT: [[Y_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
@@ -61,7 +61,7 @@
 // CHECK: [[TYPE_ADDR:%.*]] = bitcast %swift.type* %T to i8***
 // CHECK-NEXT: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[TYPE_ADDR]], {{(i32|i64)}} -1
 // CHECK-NEXT: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
-// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK-NEXT: [[SIZE_WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
 // CHECK-NEXT: [[SIZE_WITNESS:%.*]] = load i8*, i8** [[SIZE_WITNESS_ADDR]]
 // CHECK-NEXT: [[SIZE:%.*]] = ptrtoint i8* [[SIZE_WITNESS]]
 // CHECK-NEXT: [[Y_ALLOCA:%.*]] = alloca i8, {{.*}} [[SIZE]], align 16
diff --git a/test/IRGen/multi_file_resilience.swift b/test/IRGen/multi_file_resilience.swift
index 02aef2c..aeedb66 100644
--- a/test/IRGen/multi_file_resilience.swift
+++ b/test/IRGen/multi_file_resilience.swift
@@ -16,7 +16,7 @@
 // CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
 // CHECK: [[VWT:%.*]] = load i8**,
 //   Allocate 'copy'.
-// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
 // CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
 // CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
 // CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
diff --git a/test/IRGen/multi_module_resilience.swift b/test/IRGen/multi_module_resilience.swift
index cfd146a..ed3411f 100644
--- a/test/IRGen/multi_module_resilience.swift
+++ b/test/IRGen/multi_module_resilience.swift
@@ -20,7 +20,7 @@
 // CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
 // CHECK: [[VWT:%.*]] = load i8**,
 //   Allocate 'copy'.
-// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
 // CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
 // CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
 // CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
@@ -49,7 +49,7 @@
 // CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0
 // CHECK: [[VWT:%.*]] = load i8**,
 //   Allocate 'copy'.
-// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
 // CHECK: [[T1:%.*]] = load i8*, i8** [[T0]],
 // CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to [[INT]]
 // CHECK: [[ALLOCA:%.*]] = alloca i8, [[INT]] [[SIZE]],
diff --git a/test/IRGen/partial_apply.sil b/test/IRGen/partial_apply.sil
index 2d1a8c3..67c8e6f 100644
--- a/test/IRGen/partial_apply.sil
+++ b/test/IRGen/partial_apply.sil
@@ -233,7 +233,7 @@
 // CHECK:         [[T_METADATA_BASE:%.*]] = bitcast %swift.type* %T to i8***
 // CHECK:         [[T_VWTABLE_ADDR:%.*]] = getelementptr {{.*}} [[T_METADATA_BASE]], [[WORD:i[0-9]+]] -1
 // CHECK:         [[T_VWTABLE:%.*]] = load {{.*}} [[T_VWTABLE_ADDR]]
-// CHECK:         [[T_FLAGS_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 10
+// CHECK:         [[T_FLAGS_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 9
 // CHECK:         [[T_FLAGS_PTR:%.*]] = load {{.*}} [[T_FLAGS_ADDR]]
 // CHECK:         [[T_FLAGS:%.*]] = ptrtoint {{.*}} [[T_FLAGS_PTR]] to [[WORD]]
 // CHECK:         [[T_ALIGN_MASK:%.*]] = and [[WORD]] [[T_FLAGS]], 65535
@@ -245,7 +245,7 @@
 // CHECK:         [[T_OFFSET:%.*]] = and [[WORD]] [[T_UP_TO_ALIGN_1]], [[T_ALIGN_MASK_NOT]]
 
 // -- Add the size of T to start the Int field.
-// CHECK:         [[T_SIZE_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 9
+// CHECK:         [[T_SIZE_ADDR:%.*]] = getelementptr {{.*}} [[T_VWTABLE]], i32 8
 // CHECK:         [[T_SIZE_PTR:%.*]] = load {{.*}} [[T_SIZE_ADDR]]
 // CHECK:         [[T_SIZE:%.*]] = ptrtoint {{.*}} [[T_SIZE_PTR]] to [[WORD]]
 // CHECK:         [[T_END:%.*]] = add [[WORD]] [[T_OFFSET]], [[T_SIZE]]
diff --git a/test/IRGen/reflection_metadata.swift b/test/IRGen/reflection_metadata.swift
index 0065eae..0664561 100644
--- a/test/IRGen/reflection_metadata.swift
+++ b/test/IRGen/reflection_metadata.swift
@@ -2,51 +2,51 @@
 // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -disable-reflection-names -emit-ir %s | %FileCheck %s --check-prefix=STRIP_REFLECTION_NAMES
 // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -disable-reflection-metadata -emit-ir %s | %FileCheck %s --check-prefix=STRIP_REFLECTION_METADATA
 
-// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift4_reflect
-// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift4_fieldmd
-// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift4_assocty
-// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift4_capture
-// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift4_typeref
-// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift4_reflstr
-// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift4_builtin
+// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift5_reflect
+// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift5_fieldmd
+// STRIP_REFLECTION_NAMES_DAG: {{.*}}swift5_assocty
+// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift5_capture
+// STRIP_REFLECTION_NAMES-DAG: {{.*}}swift5_typeref
+// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift5_reflstr
+// STRIP_REFLECTION_NAMES-NOT: {{.*}}swift5_builtin
 
-// STRIP_REFLECTION_NAMES-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift4_fieldmd
+// STRIP_REFLECTION_NAMES-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift5_fieldmd
 
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_reflect
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_fieldmd
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_assocty
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_capture
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_typeref
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_reflstr
-// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift4_builtin
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_reflect
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_fieldmd
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_assocty
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_capture
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_typeref
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_reflstr
+// STRIP_REFLECTION_METADATA-NOT: {{.*}}swift5_builtin
 
 // CHECK-DAG: @__swift_reflection_version = linkonce_odr hidden constant i16 {{[0-9]+}}
-// CHECK-DAG: private constant [2 x i8] c"i\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"ms\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"me\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"mc\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"C\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"S\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"E\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"I\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [2 x i8] c"t\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [4 x i8] c"mgs\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [4 x i8] c"mge\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [4 x i8] c"mgc\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"GC\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"GS\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
-// CHECK-DAG: private constant [3 x i8] c"GE\00", section "{{[^"]*}}swift4_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"i\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"ms\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"me\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"mc\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"C\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"S\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"E\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"I\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [2 x i8] c"t\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [4 x i8] c"mgs\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [4 x i8] c"mge\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [4 x i8] c"mgc\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"GC\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"GS\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
+// CHECK-DAG: private constant [3 x i8] c"GE\00", section "{{[^"]*}}swift5_reflstr{{[^"]*}}"
 
-// CHECK-DAG: @"\01l__swift4_reflection_descriptor" = private constant { {{.*}} } { i32 1, i32 1, i32 2, {{.*}} }
+// CHECK-DAG: @"\01l__swift5_reflection_descriptor" = private constant { {{.*}} } { i32 1, i32 1, i32 2, {{.*}} }
 
-// CHECK-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata7MyClassCMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata11ConformanceVAA10MyProtocolAAMA" = internal constant {{.*}}swift4_assocty
-// CHECK-DAG: @"$S19reflection_metadata8MyStructVMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata6MyEnumOMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata14MyGenericClassCMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata15MyGenericStructVMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$S19reflection_metadata13MyGenericEnumOMF" = internal constant {{.*}}swift4_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata10MyProtocol_pMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata7MyClassCMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata11ConformanceVAA10MyProtocolAAMA" = internal constant {{.*}}swift5_assocty
+// CHECK-DAG: @"$S19reflection_metadata8MyStructVMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata6MyEnumOMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata14MyGenericClassCMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata15MyGenericStructVMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$S19reflection_metadata13MyGenericEnumOMF" = internal constant {{.*}}swift5_fieldmd
 
 public protocol MyProtocol {
   associatedtype Inner
diff --git a/test/IRGen/reflection_metadata_imported.swift b/test/IRGen/reflection_metadata_imported.swift
index 4af3fd7..f8a61b1 100644
--- a/test/IRGen/reflection_metadata_imported.swift
+++ b/test/IRGen/reflection_metadata_imported.swift
@@ -4,10 +4,10 @@
 
 // CHECK-DAG: @__swift_reflection_version = linkonce_odr hidden constant i16 {{[0-9]+}}
 
-// CHECK-DAG: @"$S28reflection_metadata_imported15HasImportedTypeVMF" = internal constant {{.*}}swift4_fieldmd
-// CHECK-DAG: @"$SSo1AVMB" = linkonce_odr hidden constant {{.*}}swift4_builtin
-// CHECK-DAG: @"$SSo11CrappyColorVMB" = linkonce_odr hidden constant {{.*}}swift4_builtin
-// CHECK-DAG: @"$SSo11CrappyColorVs16RawRepresentableSCMA" = linkonce_odr hidden constant {{.*}}swift4_assocty
+// CHECK-DAG: @"$S28reflection_metadata_imported15HasImportedTypeVMF" = internal constant {{.*}}swift5_fieldmd
+// CHECK-DAG: @"$SSo1AVMB" = linkonce_odr hidden constant {{.*}}swift5_builtin
+// CHECK-DAG: @"$SSo11CrappyColorVMB" = linkonce_odr hidden constant {{.*}}swift5_builtin
+// CHECK-DAG: @"$SSo11CrappyColorVs16RawRepresentableSCMA" = linkonce_odr hidden constant {{.*}}swift5_assocty
 
 struct HasImportedType {
   let a: A
diff --git a/test/IRGen/struct_resilience.swift b/test/IRGen/struct_resilience.swift
index a3b6bb1..34c081d 100644
--- a/test/IRGen/struct_resilience.swift
+++ b/test/IRGen/struct_resilience.swift
@@ -25,7 +25,7 @@
 // CHECK: [[VWT_ADDR:%.*]] = getelementptr inbounds i8**, i8*** [[METADATA_ADDR]], [[INT]] -1
 // CHECK: [[VWT:%.*]] = load i8**, i8*** [[VWT_ADDR]]
 
-// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 9
+// CHECK-NEXT: [[WITNESS_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 8
 // CHECK: [[WITNESS:%.*]] = load i8*, i8** [[WITNESS_ADDR]]
 // CHECK: [[WITNESS_FOR_SIZE:%.*]] = ptrtoint i8* [[WITNESS]]
 // CHECK: [[ALLOCA:%.*]] = alloca i8, {{.*}} [[WITNESS_FOR_SIZE]], align 16
@@ -170,6 +170,24 @@
   _ = s.method
 }
 
+public func wantsAny(_ any: Any) {}
+
+public func resilientAny(s : ResilientWeakRef) {
+  wantsAny(s)
+}
+
+// CHECK-LABEL: define{{.*}} swiftcc void @"$S17struct_resilience12resilientAny1sy0c1_A016ResilientWeakRefV_tF"(%swift.opaque* noalias nocapture)
+// CHECK: entry:
+// CHECK: [[ANY:%.*]] = alloca %Any
+// CHECK: [[META:%.*]] = call swiftcc %swift.metadata_response @"$S16resilient_struct16ResilientWeakRefVMa"([[INT]] 0)
+// CHECK: [[META2:%.*]] = extractvalue %swift.metadata_response %3, 0
+// CHECK: [[TYADDR:%.*]] = getelementptr inbounds %Any, %Any* %1, i32 0, i32 1
+// CHECK:  store %swift.type* [[META2]], %swift.type** [[TYADDR]]
+// CHECK:  call %swift.opaque* @__swift_allocate_boxed_opaque_existential_0(%Any* [[ANY]])
+// CHECK:  call swiftcc void @"$S17struct_resilience8wantsAnyyyypF"(%Any* noalias nocapture dereferenceable({{(32|16)}}) [[ANY]])
+// CHECK:  call void @__swift_destroy_boxed_opaque_existential_0(%Any* [[ANY]])
+// CHECK:  ret void
+
 // Public metadata accessor for our resilient struct
 
 // CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc %swift.metadata_response @"$S17struct_resilience6MySizeVMa"
diff --git a/test/IRGen/swift3-metadata-coff.swift b/test/IRGen/swift3-metadata-coff.swift
index 38d0887..15441b7 100644
--- a/test/IRGen/swift3-metadata-coff.swift
+++ b/test/IRGen/swift3-metadata-coff.swift
@@ -25,7 +25,7 @@
   return { gg = s }
 }
 
-// CHECK-DAG: @"\01l__swift4_reflection_descriptor" = private constant {{.*}}, section ".sw5cptr$B"
+// CHECK-DAG: @"\01l__swift5_reflection_descriptor" = private constant {{.*}}, section ".sw5cptr$B"
 // CHECK-DAG: @"{{.*}}" = {{.*}} c"Sq", {{.*}} section ".sw5tyrf$B"
 // CHECK-DAG: @{{[0-9]+}} = {{.*}} c"none\00", section ".sw5rfst$B"
 // CHECK-DAG: @{{[0-9]+}} = {{.*}} c"some\00", section ".sw5rfst$B"
diff --git a/test/IRGen/type_layout.swift b/test/IRGen/type_layout.swift
index a97a86c..b9fd828 100644
--- a/test/IRGen/type_layout.swift
+++ b/test/IRGen/type_layout.swift
@@ -34,14 +34,14 @@
   // CHECK:       [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
   // CHECK:       [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
   // CHECK:       [[T_VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
-  // CHECK:       [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
+  // CHECK:       [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
   // CHECK:       store i8** [[T_LAYOUT]]
   var z: T
   // -- native class, use standard NativeObject value witness
-  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 9)
+  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 8)
   var a: C
   // -- Single-element struct, shares layout of its field (Builtin.Int64)
-  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
+  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
   var c: SSing
   // -- Multi-element structs use open-coded layouts
   // CHECK:    store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_16_8_0_pod, i32 0, i32 0)
@@ -53,13 +53,13 @@
   // CHECK-32:    store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_[[REF_XI]]_bt, i32 0, i32 0)
   var f: SMult3
   // -- Single-case enum, shares layout of its field (Builtin.Int64)
-  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
+  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
   var g: ESing
   // -- Multi-case enum, open-coded layout
   // CHECK:    store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_9_8_0_pod, i32 0, i32 0)
   var h: EMult
   // -- Single-element generic struct, shares layout of its field (T)
-  // CHECK:       [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
+  // CHECK:       [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
   // CHECK:       store i8** [[T_LAYOUT]]
   var i: GSing<T>
   // -- Multi-element generic struct, need to derive from metadata
@@ -71,13 +71,13 @@
   // CHECK:       [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
   // CHECK:       [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
   // CHECK:       [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
-  // CHECK:       [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
+  // CHECK:       [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
   // CHECK:       store i8** [[LAYOUT]]
   var j: GMult<T>
   // -- Common layout, reuse common value witness table layout
-  // CHECK:       store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 9)
+  // CHECK:       store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 8)
   var k: CommonLayout
   // -- Single-field aggregate with alignment
-  // CHECK:       store i8** getelementptr (i8*, i8** @"$SBi128_WV", i32 9)
+  // CHECK:       store i8** getelementptr (i8*, i8** @"$SBi128_WV", i32 8)
   var l: AlignedFourInts
 }
diff --git a/test/IRGen/type_layout_objc.swift b/test/IRGen/type_layout_objc.swift
index 4e42668..976eb19 100644
--- a/test/IRGen/type_layout_objc.swift
+++ b/test/IRGen/type_layout_objc.swift
@@ -33,17 +33,17 @@
   // CHECK:       [[T0:%.*]] = bitcast %swift.type* [[T_CHECKED]] to i8***
   // CHECK:       [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
   // CHECK:       [[T_VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
-  // CHECK:       [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
+  // CHECK:       [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
   // CHECK:       store i8** [[T_LAYOUT]]
   var z: T
   // -- native class, use standard NativeObject value witness
-  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 9)
+  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBoWV", i32 8)
   var a: C
   // -- ObjC class, use standard UnknownObject value witness
-  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBOWV", i32 9)
+  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBOWV", i32 8)
   var b: O
   // -- Single-element struct, shares layout of its field (Builtin.Int64)
-  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
+  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
   var c: SSing
   // -- Multi-element structs use open-coded layouts
   // CHECK:    store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_16_8_0_pod, i32 0, i32 0)
@@ -55,13 +55,13 @@
   // CHECK-32:    store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_8_4_1000_bt, i32 0, i32 0)
   var f: SMult3
   // -- Single-case enum, shares layout of its field (Builtin.Int64)
-  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 9)
+  // CHECK:       store i8** getelementptr inbounds (i8*, i8** @"$SBi64_WV", i32 8)
   var g: ESing
   // -- Multi-case enum, open-coded layout
   // CHECK:    store i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @type_layout_9_8_0_pod, i32 0, i32 0)
   var h: EMult
   // -- Single-element generic struct, shares layout of its field (T)
-  // CHECK:       [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 9
+  // CHECK:       [[T_LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[T_VALUE_WITNESSES]], i32 8
   // CHECK:       store i8** [[T_LAYOUT]]
   var i: GSing<T>
   // -- Multi-element generic struct, need to derive from metadata
@@ -73,10 +73,10 @@
   // CHECK:       [[T0:%.*]] = bitcast %swift.type* [[METADATA]] to i8***
   // CHECK:       [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], {{i32|i64}} -1
   // CHECK:       [[VALUE_WITNESSES:%.*]] = load i8**, i8*** [[T1]]
-  // CHECK:       [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 9
+  // CHECK:       [[LAYOUT:%.*]] = getelementptr inbounds i8*, i8** [[VALUE_WITNESSES]], i32 8
   // CHECK:       store i8** [[LAYOUT]]
   var j: GMult<T>
   // -- Common layout, reuse common value witness table layout
-  // CHECK:       store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 9)
+  // CHECK:       store i8** getelementptr (i8*, i8** @"$SBi32_WV", i32 8)
   var k: CommonLayout
 }
diff --git a/test/IRGen/type_layout_reference_storage.swift b/test/IRGen/type_layout_reference_storage.swift
index 4128fae..9b545e5 100644
--- a/test/IRGen/type_layout_reference_storage.swift
+++ b/test/IRGen/type_layout_reference_storage.swift
@@ -10,23 +10,23 @@
   var z: T
 
   // -- Known-Swift-refcounted type
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 8)
   unowned(safe)   var cs:  C
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
   unowned(unsafe) var cu:  C
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
   weak            var cwo: C?
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
   weak            var cwi: C!
 
   // -- Known-Swift-refcounted archetype
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 8)
   unowned(safe)   var nc:  Native
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
   unowned(unsafe) var nu:  Native
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
   weak            var nwo: Native?
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
   weak            var nwi: Native!
 
   // -- Open-code layout for protocol types with witness tables.
@@ -72,23 +72,23 @@
   weak            var pqcwi: (P & Q & C)!
 
   // -- Unknown-refcounted existential without witness tables.
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 8)
   unowned(safe)   var aos:  AnyObject
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
   unowned(unsafe) var aou:  AnyObject
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
   weak            var aowo: AnyObject?
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
   weak            var aowi: AnyObject!
 
   // -- Unknown-refcounted archetype
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN:B[Oo]]]XoWV", i32 8)
   unowned(safe)   var us:  Unknown
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
   unowned(unsafe) var uu:  Unknown
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
   weak            var uwo: Unknown?
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$S[[UNKNOWN]]SgXwWV", i32 8)
   weak            var uwi: Unknown!
 }
 
diff --git a/test/IRGen/type_layout_reference_storage_objc.swift b/test/IRGen/type_layout_reference_storage_objc.swift
index bdc4a55..f92974c 100644
--- a/test/IRGen/type_layout_reference_storage_objc.swift
+++ b/test/IRGen/type_layout_reference_storage_objc.swift
@@ -15,52 +15,52 @@
   var z: T
 
   // -- ObjC-refcounted class
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
   unowned(safe)   var cs:  C
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
   unowned(unsafe) var cu:  C
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
   weak            var cwo: C?
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
   weak            var cwi: C!
 
   // -- ObjC-refcounted archetype
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
   unowned(safe)   var os:  ObjC
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
   unowned(unsafe) var ou:  ObjC
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
   weak            var owo: ObjC?
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
   weak            var owi: ObjC!
 
   // -- Pure ObjC protocols are unknown-refcounted
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
   unowned(safe)   var ps:  P
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
   unowned(unsafe) var pu:  P
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
   weak            var pwo: P?
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
   weak            var pwi: P!
 
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOXoWV", i32 8)
   unowned(safe)   var pqs:  P & Q
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
   unowned(unsafe) var pqu:  P & Q
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
   weak            var pqwo: (P & Q)?
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBOSgXwWV", i32 8)
   weak            var pqwi: (P & Q)!
 
   // -- Composition with ObjC protocol and native class is native-refcounted
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoXoWV", i32 8)
   unowned(safe)   var pncs:  (P & NativeClass)
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBomWV", i32 8)
   unowned(unsafe) var pncu:  (P & NativeClass)
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
   weak            var pncwo: (P & NativeClass)?
-  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 9)
+  // CHECK: store i8** getelementptr inbounds (i8*, i8** @"$SBoSgXwWV", i32 8)
   weak            var pncwi: (P & NativeClass)!
 
   // -- Open-code layouts when there are witness tables.
diff --git a/test/IRGen/weak.sil b/test/IRGen/weak.sil
index be03eec..0493b6d 100644
--- a/test/IRGen/weak.sil
+++ b/test/IRGen/weak.sil
@@ -28,9 +28,9 @@
 }
 
 // size 8
-// flags 0x1100007 == 1114119 (non-POD, non-inline, non-bitwise-takable)
+// flags 0x130007 == 1245191 (non-POD, non-inline, non-bitwise-takable)
 // stride 8
-// CHECK: @"$S4weak1AVWV" = {{.*}} i8* inttoptr (i64 8 to i8*), i8* inttoptr (i64 1114119 to i8*), i8* inttoptr (i64 8 to i8*)]
+// CHECK: @"$S4weak1AVWV" = {{.*}} i8* inttoptr (i64 8 to i8*), i8* inttoptr (i64 1245191 to i8*), i8* inttoptr (i64 8 to i8*)]
 
 sil @test_weak_load_store : $@convention(thin) (@inout A, Optional<C>) -> () {
 bb0(%0 : $*A, %1 : $Optional<C>):
@@ -104,16 +104,19 @@
 
 //   initializeBufferWithCopyOfBuffer
 // CHECK:    define linkonce_odr hidden [[OPAQUE]]* @"$S4weak1AVwCP"([[BUFFER:\[24 x i8\]]]* noalias [[DESTBUF:%.*]], [[BUFFER]]* noalias [[SRCBUF:%.*]], [[TYPE]]*
-// CHECK:      [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to [[A]]*
-// CHECK-NEXT: [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to [[A]]*
-// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[DEST]], i32 0, i32 0
-// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[SRC]], i32 0, i32 0
-// CHECK-NEXT: call [[WEAK]]* @swift_weakCopyInit([[WEAK]]* returned [[T0]], [[WEAK]]* [[T1]])
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[DEST]] to [[OPAQUE]]*
-// CHECK-NEXT: ret [[OPAQUE]]* [[T0]]
-
-// TAILCALL: {{_?}}$S4weak1AVwCP:
-// TAILCALL:  jmp     {{_?}}swift_weakCopyInit
+// CHECK:  [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to %swift.refcounted**
+// CHECK:  [[SRC:%.*]] = bitcast [[BUFFER]]* [[SRCBUF]] to %swift.refcounted**
+// CHECK:  [[REF:%.*]] = load %swift.refcounted*, %swift.refcounted** [[SRC]]
+// CHECK:  call %swift.refcounted* @swift_retain(%swift.refcounted* returned [[REF]])
+// CHECK:  store %swift.refcounted* [[REF]], %swift.refcounted** [[DEST]]
+// CHECK:  [[DEST:%.*]] = bitcast [[BUFFER]]* [[DESTBUF]] to %swift.refcounted**
+// CHECK:  [[REF:%.*]] = load %swift.refcounted*, %swift.refcounted** [[DEST]]
+// CHECK:  [[PTR:%.*]] = bitcast %swift.refcounted* [[REF]] to i8*
+// CHECK:  [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[PTR]], {{(i64|i32)}} {{(16|8)}}
+// CHECK:  [[CAST:%.*]] = bitcast i8* [[PTR2]] to %swift.opaque*
+// CHECK:  [[CAST2:%.*]] = bitcast %swift.opaque* [[CAST]] to %T4weak1AV*
+// CHECK:  [[CAST3:%.*]] = bitcast %T4weak1AV* [[CAST2]] to %swift.opaque*
+// CHECK:  ret %swift.opaque* [[CAST3]]
 
 //   destroy
 // CHECK:    define linkonce_odr hidden void @"$S4weak1AVwxx"([[OPAQUE]]* noalias [[ARG:%.*]], [[TYPE]]*
@@ -166,6 +169,3 @@
 
 // TAILCALL: {{_?}}$S4weak1AVwta:
 // TAILCALL:  jmp     {{_?}}swift_weakTakeAssign
-
-// TAILCALL: {{_?}}$S4weak1AVwTK:
-// TAILCALL:  jmp     {{_?}}swift_weakTakeInit
diff --git a/test/IRGen/weak_value_witnesses.sil b/test/IRGen/weak_value_witnesses.sil
index 872cf7d..a3fbbd0 100644
--- a/test/IRGen/weak_value_witnesses.sil
+++ b/test/IRGen/weak_value_witnesses.sil
@@ -25,36 +25,38 @@
   var y: T
 }
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8JustWeakVwTK"(
-// CHECK:      [[DEST:%.*]] = bitcast [24 x i8]* %dest to %T20weak_value_witnesses8JustWeakV*
-// CHECK-NEXT: [[SRC:%.*]] = bitcast [24 x i8]* %src to %T20weak_value_witnesses8JustWeakV*
-// CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds %T20weak_value_witnesses8JustWeakV, %T20weak_value_witnesses8JustWeakV* [[DEST]], i32 0, i32 0
-// CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds %T20weak_value_witnesses8JustWeakV, %T20weak_value_witnesses8JustWeakV* [[SRC]], i32 0, i32 0
-// CHECK-NEXT: call %swift.weak* @swift_weakTakeInit(%swift.weak* returned [[DEST_X]], %swift.weak* [[SRC_X]])
-// CHECK-NEXT: [[T0:%.*]] = bitcast %T20weak_value_witnesses8JustWeakV* [[DEST]] to %swift.opaque*
-// CHECK-NEXT: ret %swift.opaque* [[T0]]
+// CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8JustWeakVwTK"(
 
 // The default memcpy-ing witness is good enough for NoWeak.
 // CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses6NoWeakVwtk"(%swift.opaque* %dest, %swift.opaque* %src, %swift.type* %Self)
 
 // CHECK-NOT: @"$S20weak_value_witnesses6NoWeakVwTK"
 
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8JustWeakVwCP"
+// CHECK: entry:
+// CHECK:  load %swift.refcounted*, %swift.refcounted**
+// CHECK:  call %swift.refcounted* @swift_retain
+// CHECK:  store %swift.refcounted*
+// CHECK:  load %swift.refcounted*
+// CHECK:  getelementptr inbounds i8
+// CHECK:  ret %swift.opaque
+// CHECK:}
+
+// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8SomeWeakVwCP"
+// CHECK:entry:
+// CHECK:  load %swift.refcounted*, %swift.refcounted**
+// CHECK:  call %swift.refcounted* @swift_retain
+// CHECK:  store %swift.refcounted*
+// CHECK:  load %swift.refcounted*
+// CHECK:  getelementptr inbounds i8
+// CHECK:  ret %swift.opaque
+// CHECK:}
+
 // Weak references must be taken by swift_weakTakeInit.
 // CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8SomeWeakVwtk"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %SomeWeak)
 // CHECK:         call %swift.weak* @swift_weakTakeInit
 
-// CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8SomeWeakVwTK"(
-// CHECK:      [[DEST:%.*]] = bitcast [24 x i8]* %dest to %T20weak_value_witnesses8SomeWeakV*
-// CHECK-NEXT: [[SRC:%.*]] = bitcast [24 x i8]* %src to %T20weak_value_witnesses8SomeWeakV*
-// CHECK-NEXT: [[DEST_X:%.*]] = getelementptr inbounds %T20weak_value_witnesses8SomeWeakV, %T20weak_value_witnesses8SomeWeakV* [[DEST]], i32 0, i32 0
-// CHECK-NEXT: [[SRC_X:%.*]] = getelementptr inbounds %T20weak_value_witnesses8SomeWeakV, %T20weak_value_witnesses8SomeWeakV* [[SRC]], i32 0, i32 0
-// CHECK-NEXT: [[T0:%.*]] = load %T20weak_value_witnesses1CC*, %T20weak_value_witnesses1CC** [[SRC_X]], align 8
-// CHECK-NEXT: store %T20weak_value_witnesses1CC* [[T0]], %T20weak_value_witnesses1CC** [[DEST_X]], align 8
-// CHECK-NEXT: [[DEST_Y:%.*]] = getelementptr inbounds %T20weak_value_witnesses8SomeWeakV, %T20weak_value_witnesses8SomeWeakV* [[DEST]], i32 0, i32 1
-// CHECK-NEXT: [[SRC_Y:%.*]] = getelementptr inbounds %T20weak_value_witnesses8SomeWeakV, %T20weak_value_witnesses8SomeWeakV* [[SRC]], i32 0, i32 1
-// CHECK-NEXT: call %swift.weak* @swift_weakTakeInit(%swift.weak* returned [[DEST_Y]], %swift.weak* [[SRC_Y]])
-// CHECK-NEXT: [[T0:%.*]] = bitcast %T20weak_value_witnesses8SomeWeakV* [[DEST]] to %swift.opaque*
-// CHECK-NEXT: ret %swift.opaque* [[T0]]
+// CHECK-NOT: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses8SomeWeakVwTK"(
 
 // Generic types must be taken using their value witness.
 // CHECK-LABEL: define linkonce_odr hidden %swift.opaque* @"$S20weak_value_witnesses3GenVwtk"(%swift.opaque* noalias %dest, %swift.opaque* noalias %src, %swift.type* %"Gen<T>")
diff --git a/test/Inputs/resilient_struct.swift b/test/Inputs/resilient_struct.swift
index 01982d4..902e25e 100644
--- a/test/Inputs/resilient_struct.swift
+++ b/test/Inputs/resilient_struct.swift
@@ -77,3 +77,13 @@
     self.d = d
   }
 }
+
+public class Referent {}
+
+public struct ResilientWeakRef {
+  public weak var ref: Referent?
+
+  public init (_ r: Referent) {
+    ref = r
+  }
+}
diff --git a/test/Interpreter/Inputs/enum-nonexhaustivity.h b/test/Interpreter/Inputs/enum-nonexhaustivity.h
index 2bfc08a..47b9602 100644
--- a/test/Interpreter/Inputs/enum-nonexhaustivity.h
+++ b/test/Interpreter/Inputs/enum-nonexhaustivity.h
@@ -4,10 +4,10 @@
   NonExhaustiveEnumC = 2,
 } __attribute__((enum_extensibility(open)));
 
-enum NonExhaustiveEnum getExpectedValue(void) {
+static enum NonExhaustiveEnum getExpectedValue(void) {
   return NonExhaustiveEnumB;
 }
-enum NonExhaustiveEnum getUnexpectedValue(void) {
+static enum NonExhaustiveEnum getUnexpectedValue(void) {
   return (enum NonExhaustiveEnum)3;
 }
 
@@ -17,9 +17,9 @@
   LyingExhaustiveEnumC = 2,
 } __attribute__((enum_extensibility(closed)));
 
-enum LyingExhaustiveEnum getExpectedLiarValue(void) {
+static enum LyingExhaustiveEnum getExpectedLiarValue(void) {
   return LyingExhaustiveEnumB;
 }
-enum LyingExhaustiveEnum getUnexpectedLiarValue(void) {
+static enum LyingExhaustiveEnum getUnexpectedLiarValue(void) {
   return (enum LyingExhaustiveEnum)3;
 }
diff --git a/test/Interpreter/Inputs/unions-and-bitfields.h b/test/Interpreter/Inputs/unions-and-bitfields.h
index 596603b..e870061 100644
--- a/test/Interpreter/Inputs/unions-and-bitfields.h
+++ b/test/Interpreter/Inputs/unions-and-bitfields.h
@@ -50,12 +50,12 @@
   };
 };
 
-void populate(void *memory) {
+static void populate(void *memory) {
   const uint32_t value = 0x11223344;
   memcpy(memory, &value, sizeof(value));
 }
 
-void populateAtOffset(void *memory) {
+static void populateAtOffset(void *memory) {
   const uint32_t value = 0x11223344;
   memcpy((char *)memory + sizeof(uint32_t), &value, sizeof(value));
 }
diff --git a/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h b/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h
index d07687e..7339685 100644
--- a/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h
+++ b/test/Migrator/mock-sdk/Bar.framework/Headers/Bar.h
@@ -4,9 +4,9 @@
 
 int barGlobalFunc(int a);
 
-int barGlobalVariable = 1;
+extern int barGlobalVariable;
 
-int barGlobalVariableOldEnumElement = 1;
+extern int barGlobalVariableOldEnumElement;
 
 int barGlobalFuncOldName(int a);
 
diff --git a/test/Migrator/qualified-replacement.swift b/test/Migrator/qualified-replacement.swift
index a8e68b3..47bb412 100644
--- a/test/Migrator/qualified-replacement.swift
+++ b/test/Migrator/qualified-replacement.swift
@@ -14,8 +14,6 @@
   _ = Cities.CityKind.Town
   _ = ToplevelType()
   _ = ToplevelType(recordName: "")
-  bar(.orderedSame)
 }
 
 func foo(_: ToplevelType) {}
-func bar(_ : FooComparisonResult) {}
diff --git a/test/Migrator/qualified-replacement.swift.expected b/test/Migrator/qualified-replacement.swift.expected
index 7b1344c..b3ec305 100644
--- a/test/Migrator/qualified-replacement.swift.expected
+++ b/test/Migrator/qualified-replacement.swift.expected
@@ -10,12 +10,10 @@
   _ = NewPropertyUserInterface.newFieldPlus
   NewPropertyUserInterface.newMethodPlus(1)
   _ = NewFooComparisonResult.NewFooOrderedSame
-  let _ : FooComparisonResult = .NewFooOrderedSame
+  let _ : FooComparisonResult = NewFooComparisonResult.NewFooOrderedSame
   _ = NewCityKind.NewTown
   _ = ToplevelWrapper.internalType()
   _ = ToplevelWrapper.internalType(recordName: "")
-  bar(.NewFooOrderedSame)
 }
 
 func foo(_: ToplevelWrapper.internalType) {}
-func bar(_ : FooComparisonResult) {}
diff --git a/test/NameBinding/import-resolution-overload.swift b/test/NameBinding/import-resolution-overload.swift
index 0e8bcd3..e453a7e 100644
--- a/test/NameBinding/import-resolution-overload.swift
+++ b/test/NameBinding/import-resolution-overload.swift
@@ -55,7 +55,7 @@
   var foo: Int { return 0 }
 }
 
-// CHECK-LABEL: func_decl "testHasFooSub(_:)"
+// CHECK-LABEL: func_decl{{.*}}"testHasFooSub(_:)"
 func testHasFooSub(_ hfs: HasFooSub) -> Int {
   // CHECK: return_stmt
   // CHECK-NOT: func_decl
@@ -67,7 +67,7 @@
   var bar: Int { return 0 }
 }
 
-// CHECK-LABEL: func_decl "testHasBar(_:)"
+// CHECK-LABEL: func_decl{{.*}}"testHasBar(_:)"
 func testHasBar(_ hb: HasBar) -> Int {
   // CHECK: return_stmt
   // CHECK-NOT: func_decl
diff --git a/test/Parse/if_expr.swift b/test/Parse/if_expr.swift
index aa20ad4..3378ba7 100644
--- a/test/Parse/if_expr.swift
+++ b/test/Parse/if_expr.swift
@@ -1,6 +1,6 @@
 // RUN: %target-swift-frontend -dump-ast %s 2>&1 | %FileCheck %s
 
-// CHECK: (func_decl "r13756261(_:_:)"
+// CHECK: (func_decl{{.*}}"r13756261(_:_:)"
 func r13756261(_ x: Bool, _ y: Int) -> Int {
   // CHECK: (if_expr
   // CHECK:   (call_expr
@@ -15,7 +15,7 @@
   return (x) ? y : (x) ? y : (x) ? y : y
 }
 
-// CHECK: (func_decl "r13756221(_:_:)"
+// CHECK: (func_decl{{.*}}"r13756221(_:_:)"
 func r13756221(_ x: Bool, _ y: Int) -> Int {
   // CHECK: (if_expr
   // CHECK:   (call_expr
@@ -33,7 +33,7 @@
        : y
 }
 
-// CHECK: (func_decl "telescoping_if(_:_:)"
+// CHECK: (func_decl{{.*}}"telescoping_if(_:_:)"
 func telescoping_if(_ x: Bool, _ y: Int) -> Int {
   // CHECK: (if_expr
   // CHECK:   (call_expr
@@ -69,7 +69,7 @@
 func +<< (x: Bool, y: Bool) -> Bool {}
 func +== (x: Bool, y: Bool) -> Bool {}
 
-// CHECK: (func_decl "prec_above(_:_:_:)"
+// CHECK: (func_decl{{.*}}"prec_above(_:_:_:)"
 func prec_above(_ x: Bool, _ y: Bool, _ z: Bool) -> Bool {
   // (x +>> y) ? (y +>> z) : ((x +>> y) ? (y +>> z) : (x +>> y))
   // CHECK: (if_expr
@@ -82,7 +82,7 @@
   return x +>> y ? y +>> z : x +>> y ? y +>> z : x +>> y
 }
 
-// CHECK: (func_decl "prec_below(_:_:_:)"
+// CHECK: (func_decl{{.*}}"prec_below(_:_:_:)"
 func prec_below(_ x: Bool, _ y: Bool, _ z: Bool) -> Bool {
   // The middle arm of the ternary is max-munched, so this is:
   // ((x +<< (y ? (y +<< z) : x)) +<< (y ? (y +<< z) : x)) +<< y
@@ -102,7 +102,7 @@
   return x +<< y ? y +<< z : x +<< y ? y +<< z : x +<< y
 }
 
-// CHECK: (func_decl "prec_equal(_:_:_:)"
+// CHECK: (func_decl{{.*}}"prec_equal(_:_:_:)"
 func prec_equal(_ x: Bool, _ y: Bool, _ z: Bool) -> Bool {
   // The middle arm of the ternary is max-munched, so this is:
   // x +== (y ? (y +== z) : (x +== (y ? (y +== z) : (x +== y))))
diff --git a/test/SILOptimizer/access_enforcement_opts.sil b/test/SILOptimizer/access_enforcement_opts.sil
index 0ab5dcc..c5dc155 100644
--- a/test/SILOptimizer/access_enforcement_opts.sil
+++ b/test/SILOptimizer/access_enforcement_opts.sil
@@ -32,9 +32,6 @@
   return %6 : $X
 }
 
-// Preserve begin/end scope for nested conflicts,
-// after inlining (read|modify)AndPerform.
-//
 // func testNestedAccess() {
 //   readAndPerform(&globalX) {
 //     globalX = X()
@@ -47,6 +44,9 @@
 //     globalX.i = 12
 //   }
 // }
+// Preserve begin/end scope for nested conflicts,
+// after inlining (read|modify)AndPerform.
+//
 // CHECK-LABEL: sil hidden @testNestedAccess : $@convention(thin) () -> () {
 // CHECK: [[F1:%.*]] = function_ref @testNestedAccessClosure1 : $@convention(thin) () -> ()
 // CHECK: [[C1:%.*]] = convert_function [[F1]] : $@convention(thin) () -> () to $@convention(thin) @noescape () -> ()
@@ -144,13 +144,13 @@
   return %7 : $()
 }
 
-// Demote disjoint global access to non-nested access.
-//
 // func testDisjointAccess() {
 //   modifyAndPerform(&globalOtherX) {
 //     globalX.i = 12 // no-trap
 //   }
 // }
+// Demote disjoint global access to non-nested access.
+//
 // CHECK-LABEL: sil hidden @testDisjointAccess : $@convention(thin) () -> () {
 // CHECK: bb0:
 // CHECK:   [[GLOBALX:%.*]] = global_addr @globalOtherX : $*X
@@ -194,6 +194,11 @@
 //     _blackHole(x.i) // no-trap
 //   }
 // }
+// Demote both read accesses to non_nested, then remove the local outer access.
+//
+// CHECK-LABEL: sil @testCaptureReadRead : $@convention(thin) () -> () {
+// CHECK-NOT: begin_access
+// CHECK-LABEL: } // end sil function 'testCaptureReadRead'
 sil @testCaptureReadRead : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_stack $X, var, name "x"
@@ -215,6 +220,9 @@
   return %18 : $()
 }
 
+// CHECK-LABEL: sil private @testCaptureReadReadClosure1 : $@convention(thin) (@inout_aliasable X) -> () {
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] %0 : $*X
+// CHECK-LABEL: } // end sil function 'testCaptureReadReadClosure1'
 sil private @testCaptureReadReadClosure1 : $@convention(thin) (@inout_aliasable X) -> () {
 bb0(%0 : $*X):
   %2 = begin_access [read] [dynamic] %0 : $*X
@@ -228,13 +236,18 @@
   return %11 : $()
 }
 
-// Without allocBoxtoStack:
+// Without allocBoxToStack:
 // public func testCaptureBoxReadRead() {
 //   var x = X()
 //   readAndPerform(&x) {
 //     _blackHole(x.i) // no-trap
 //   }
 // }
+// Demote both read accesses to non_nested, and remove the local outer access.
+//
+// CHECK-LABEL: sil @testCaptureBoxReadRead : $@convention(thin) () -> () {
+// CHECK-NOT: begin_access
+// CHECK-LABEL: } // end sil function 'testCaptureBoxReadRead'
 sil @testCaptureBoxReadRead : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_box ${ var X }, var, name "x"
@@ -255,6 +268,10 @@
   return %17 : $()
 }
 
+// CHECK-LABEL: sil private @testCaptureBoxReadReadClosure1 : $@convention(thin) (@guaranteed { var X }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var X }, 0
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] %1 : $*X
+// CHECK-LABEL: } // end sil function 'testCaptureBoxReadReadClosure1'
 sil private @testCaptureBoxReadReadClosure1 : $@convention(thin) (@guaranteed { var X }) -> () {
 bb0(%0 : ${ var X }):
   %1 = project_box %0 : ${ var X }, 0
@@ -277,6 +294,7 @@
 //   // Inside never-escape closure: [modify] [dynamic]
 //   doTwo(c, { x = 42 })
 // }
+// Demote each closure access to non_nested.
 sil @testDoubleCapture : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_box ${ var Int64 }, var, name "x"
@@ -304,6 +322,10 @@
   return %24 : $()
 }
 
+// CHECK-LABEL: sil private @testDoubleCaptureClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function 'testDoubleCaptureClosure1'
 sil private @testDoubleCaptureClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
 bb0(%0 : ${ var Int64 }):
   %1 = project_box %0 : ${ var Int64 }, 0
@@ -316,6 +338,9 @@
   return %8 : $()
 }
 
+// CHECK-LABEL: sil private @testDoubleCaptureClosure2 : $@convention(thin) (@inout_aliasable Int64) -> () {
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] %0 : $*Int64
+// CHECK-LABEL: } // end sil function 'testDoubleCaptureClosure2'
 sil private @testDoubleCaptureClosure2 : $@convention(thin) (@inout_aliasable Int64) -> () {
 bb0(%0 : $*Int64):
   %2 = integer_literal $Builtin.Int64, 42
@@ -327,14 +352,17 @@
   return %7 : $()
 }
 
-// Demote read/read access to [no_nested_conflict].
-//
 // public func testInoutReadEscapeRead() {
 //   var x = 3
 //   let c = { let y = x; _blackHole(y) }
 //   readAndPerform(&x, closure: c)
 //   _blackHole(x)
 // }
+// Demote read/read access to [no_nested_conflict].
+//
+// CHECK-LABEL: sil @testInoutReadEscapeRead : $@convention(thin) () -> () {
+// CHECK-NOT: begin_access
+// CHECK-LABEL: } // end sil function 'testInoutReadEscapeRead'
 sil @testInoutReadEscapeRead : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_box ${ var Int64 }, var, name "x"
@@ -365,6 +393,10 @@
   return %30 : $()
 }
 
+// CHECK-LABEL: sil private @testInoutReadEscapeReadClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] [[BOXADR]] : $*Int64
+// CHECK-LABEL: } // end sil function 'testInoutReadEscapeReadClosure1'
 sil private @testInoutReadEscapeReadClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
 bb0(%0 : ${ var Int64 }):
   %1 = project_box %0 : ${ var Int64 }, 0
@@ -385,6 +417,15 @@
 //   readAndPerform(&x, closure: c) 
 //   _blackHole(x)
 // }
+// Preserve the scope of the outer inout access. Runtime trap expected.
+//
+// CHECK-LABEL: sil @testInoutReadEscapeWrite : $@convention(thin) () -> () {
+// CHECK: [[BOX:%.*]] = alloc_box ${ var Int64 }, var, name "x"
+// CHECK: [[BOXADR:%.*]] = project_box [[BOX]] : ${ var Int64 }, 0
+// CHECK: begin_access [read] [dynamic] [[BOXADR]] : $*Int64
+// CHECK: apply
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] [[BOXADR]] : $*Int64
+// CHECK-LABEL: } // end sil function 'testInoutReadEscapeWrite'
 sil @testInoutReadEscapeWrite : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_box ${ var Int64 }, var, name "x"
@@ -417,6 +458,10 @@
   return %30 : $()
 }
 
+// CHECK-LABEL: sil private @testInoutReadEscapeWriteClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function 'testInoutReadEscapeWriteClosure1'
 sil private @testInoutReadEscapeWriteClosure1 : $@convention(thin) (@guaranteed { var Int64 }) -> () {
 bb0(%0 : ${ var Int64 }):
   %1 = project_box %0 : ${ var Int64 }, 0
@@ -429,7 +474,21 @@
   return %8 : $()
 }
 
-// testInoutWriteEscapeRead()
+// public func testInoutWriteEscapeRead() {
+//   var x = 3
+//   let c = { let y = x; _blackHole(y) }
+//   modifyAndPerform(&x, closure: c)
+//   _blackHole(x)
+// }
+// Preserve the scope of the outer inout access. Runtime trap expected.
+//
+// CHECK-LABEL: sil @$S17enforce_with_opts24testInoutWriteEscapeReadyyF : $@convention(thin) () -> () {
+// CHECK: [[BOX:%.*]] = alloc_box ${ var Int64 }, var, name "x"
+// CHECK: [[BOXADR:%.*]] = project_box [[BOX]] : ${ var Int64 }, 0
+// CHECK: begin_access [modify] [dynamic] [[BOXADR]] : $*Int64
+// CHECK: apply
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function '$S17enforce_with_opts24testInoutWriteEscapeReadyyF'
 sil @$S17enforce_with_opts24testInoutWriteEscapeReadyyF : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_box ${ var Int64 }, var, name "x"
@@ -466,6 +525,10 @@
 }
 
 // closure #1 in testInoutWriteEscapeRead()
+// CHECK-LABEL: sil private @$S17enforce_with_opts24testInoutWriteEscapeReadyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] %1
+// CHECK-LABEL: } // end sil function '$S17enforce_with_opts24testInoutWriteEscapeReadyyFyycfU_'
 sil private @$S17enforce_with_opts24testInoutWriteEscapeReadyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
 // %0
 bb0(%0 : ${ var Int64 }):
@@ -482,7 +545,21 @@
   return %12 : $()
 }
 
-// testInoutWriteEscapeWrite()
+// public func testInoutWriteEscapeWrite() {
+//   var x = 3
+//   let c = { x = 42 }
+//   modifyAndPerform(&x, closure: c)
+//   _blackHole(x)
+// }
+// Preserve the scope of the outer inout access. Runtime trap expected.
+//
+// CHECK-LABEL: sil @$S17enforce_with_opts020testInoutWriteEscapeF0yyF : $@convention(thin) () -> () {
+// CHECK: [[BOX:%.*]] = alloc_box ${ var Int64 }, var, name "x"
+// CHECK: [[BOXADR:%.*]] = project_box [[BOX]] : ${ var Int64 }, 0
+// CHECK: begin_access [modify] [dynamic] [[BOXADR]] : $*Int64
+// CHECK: apply
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] [[BOXADR]] : $*Int64
+// CHECK-LABEL: } // end sil function '$S17enforce_with_opts020testInoutWriteEscapeF0yyF'
 sil @$S17enforce_with_opts020testInoutWriteEscapeF0yyF : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_box ${ var Int64 }, var, name "x"
@@ -518,7 +595,10 @@
   return %30 : $()
 }
 
-// closure #1 in testInoutWriteEscapeWrite()
+// CHECK-LABEL: sil private @$S17enforce_with_opts020testInoutWriteEscapeF0yyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] [[BOXADR]] : $*Int64
+// CHECK-LABEL: } // end sil function '$S17enforce_with_opts020testInoutWriteEscapeF0yyFyycfU_'
 sil private @$S17enforce_with_opts020testInoutWriteEscapeF0yyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
 // %0
 bb0(%0 : ${ var Int64 }):
@@ -534,6 +614,13 @@
 }
 
 // testInoutReadNoescapeRead()
+// public func testInoutReadNoescapeRead() {
+//   var x = 3
+//   let c = { let y = x; _blackHole(y) }
+//   doOne { readAndPerform(&x, closure: c) }
+// }
+// The outer inout access is not folded because we the optimizer can't resolve
+// the call to the inner closure from the outer closure.
 sil @$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyF : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_box ${ var Int64 }, var, name "x"
@@ -563,6 +650,10 @@
 }
 
 // closure #1 in testInoutReadNoescapeRead()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: [[BOXADR:%.*]] = project_box %0 : ${ var Int64 }, 0
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] [[BOXADR]] : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyycfU_'
 sil private @$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
 // %0
 bb0(%0 : ${ var Int64 }):
@@ -580,6 +671,9 @@
 }
 
 // closure #2 in testInoutReadNoescapeRead()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
+// CHECK: begin_access [read] [dynamic] %0 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyyXEfU0_'
 sil private @$S23enforce_with_opts_nob2s021testInoutReadNoescapeG0yyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
 // %0
 // %1
@@ -597,6 +691,13 @@
 }
 
 // testInoutReadNoescapeWrite()
+// public func testInoutReadNoescapeWrite() {
+//   var x = 3
+//   let c = { x = 7 }
+//   doOne { readAndPerform(&x, closure: c) }
+// }
+// The outer inout access scope (closure #2) must be preserved.
+// Expected to trap at runtime.
 sil @$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyF : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_box ${ var Int64 }, var, name "x"
@@ -626,6 +727,9 @@
 }
 
 // closure #1 in testInoutReadNoescapeWrite()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyycfU_'
 sil private @$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
 // %0
 bb0(%0 : ${ var Int64 }):
@@ -641,9 +745,10 @@
 }
 
 // closure #2 in testInoutReadNoescapeWrite()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
+// CHECK: begin_access [read] [dynamic] %0 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyyXEfU0_'
 sil private @$S23enforce_with_opts_nob2s26testInoutReadNoescapeWriteyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
-// %0
-// %1
 bb0(%0 : $*Int64, %1 : $@callee_guaranteed () -> ()):
   debug_value_addr %0 : $*Int64, var, name "x", argno 1
   debug_value %1 : $@callee_guaranteed () -> (), let, name "c", argno 2
@@ -658,20 +763,27 @@
 }
 
 // testInoutWriteEscapeReadClosure()
-sil @$S23enforce_with_opts_nob2s31testInoutWriteEscapeReadClosureyyF : $@convention(thin) () -> () {
+// public func testInoutWriteNoescapeReadClosure() {
+//   var x = 3
+//   let c = { let y = x; _blackHole(y) }
+//   doOne { modifyAndPerform(&x, closure: c) }
+// }
+// The outer inout access scope (closure #2) must be preserved.
+// Expected to trap at runtime.
+sil @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyF : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_box ${ var Int64 }, var, name "x"
   %1 = project_box %0 : ${ var Int64 }, 0
   %2 = integer_literal $Builtin.Int64, 3
   %3 = struct $Int64 (%2 : $Builtin.Int64)
   store %3 to %1 : $*Int64
-  // function_ref closure #1 in testInoutWriteEscapeReadClosure()
-  %5 = function_ref @$S23enforce_with_opts_nob2s31testInoutWriteEscapeReadClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> ()
+  // function_ref closure #1 in testInoutWriteNoescapeReadClosure()
+  %5 = function_ref @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> ()
   strong_retain %0 : ${ var Int64 }
   %7 = partial_apply [callee_guaranteed] %5(%0) : $@convention(thin) (@guaranteed { var Int64 }) -> ()
   debug_value %7 : $@callee_guaranteed () -> (), let, name "c"
-  // function_ref closure #2 in testInoutWriteEscapeReadClosure()
-  %9 = function_ref @$S23enforce_with_opts_nob2s31testInoutWriteEscapeReadClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
+  // function_ref closure #2 in testInoutWriteNoescapeReadClosure()
+  %9 = function_ref @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
   strong_retain %7 : $@callee_guaranteed () -> ()
   %11 = partial_apply [callee_guaranteed] %9(%1, %7) : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
   strong_retain %11 : $@callee_guaranteed () -> ()
@@ -686,8 +798,11 @@
   return %20 : $()
 }
 
-// closure #1 in testInoutWriteEscapeReadClosure()
-sil private @$S23enforce_with_opts_nob2s31testInoutWriteEscapeReadClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// closure #1 in testInoutWriteNoescapeReadClosure()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: begin_access [read] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyycfU_'
+sil private @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
 // %0
 bb0(%0 : ${ var Int64 }):
   %1 = project_box %0 : ${ var Int64 }, 0
@@ -703,8 +818,11 @@
   return %12 : $()
 }
 
-// closure #2 in testInoutWriteEscapeReadClosure()
-sil private @$S23enforce_with_opts_nob2s31testInoutWriteEscapeReadClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
+// closure #2 in testInoutWriteNoescapeReadClosure()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
+// CHECK: begin_access [modify] [dynamic] %0 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyyXEfU0_'
+sil private @$S23enforce_with_opts_nob2s33testInoutWriteNoescapeReadClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
 // %0
 // %1
 bb0(%0 : $*Int64, %1 : $@callee_guaranteed () -> ()):
@@ -720,21 +838,26 @@
   return %10 : $()
 }
 
-// testInoutWriteEscapeWriteClosure()
-sil @$S23enforce_with_opts_nob2s020testInoutWriteEscapeG7ClosureyyF : $@convention(thin) () -> () {
+// testInoutWriteNoescapeWriteClosure()
+// public func testInoutWriteNoescapeWriteClosure() {
+//   var x = 3
+//   let c = { x = 7 }
+//   doOne { modifyAndPerform(&x, closure: c) }
+// }
+sil @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyF : $@convention(thin) () -> () {
 bb0:
   %0 = alloc_box ${ var Int64 }, var, name "x"
   %1 = project_box %0 : ${ var Int64 }, 0
   %2 = integer_literal $Builtin.Int64, 3
   %3 = struct $Int64 (%2 : $Builtin.Int64)
   store %3 to %1 : $*Int64
-  // function_ref closure #1 in testInoutWriteEscapeWriteClosure()
-  %5 = function_ref @$S23enforce_with_opts_nob2s020testInoutWriteEscapeG7ClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> ()
+  // function_ref closure #1 in testInoutWriteNoescapeWriteClosure()
+  %5 = function_ref @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> ()
   strong_retain %0 : ${ var Int64 }
   %7 = partial_apply [callee_guaranteed] %5(%0) : $@convention(thin) (@guaranteed { var Int64 }) -> ()
   debug_value %7 : $@callee_guaranteed () -> (), let, name "c"
-  // function_ref closure #2 in testInoutWriteEscapeWriteClosure()
-  %9 = function_ref @$S23enforce_with_opts_nob2s020testInoutWriteEscapeG7ClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
+  // function_ref closure #2 in testInoutWriteNoescapeWriteClosure()
+  %9 = function_ref @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
   strong_retain %7 : $@callee_guaranteed () -> ()
   %11 = partial_apply [callee_guaranteed] %9(%1, %7) : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> ()
   strong_retain %11 : $@callee_guaranteed () -> ()
@@ -749,8 +872,11 @@
   return %20 : $()
 }
 
-// closure #1 in testInoutWriteEscapeWriteClosure()
-sil private @$S23enforce_with_opts_nob2s020testInoutWriteEscapeG7ClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// closure #1 in testInoutWriteNoescapeWriteClosure()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
+// CHECK: begin_access [modify] [dynamic] [no_nested_conflict] %1 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyycfU_'
+sil private @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyycfU_ : $@convention(thin) (@guaranteed { var Int64 }) -> () {
 // %0
 bb0(%0 : ${ var Int64 }):
   %1 = project_box %0 : ${ var Int64 }, 0
@@ -764,10 +890,11 @@
   return %8 : $()
 }
 
-// closure #2 in testInoutWriteEscapeWriteClosure()
-sil private @$S23enforce_with_opts_nob2s020testInoutWriteEscapeG7ClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
-// %0
-// %1
+// closure #2 in testInoutWriteNoescapeWriteClosure()
+// CHECK-LABEL: sil private @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
+// CHECK: begin_access [modify] [dynamic] %0 : $*Int64
+// CHECK-LABEL: } // end sil function '$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyyXEfU0_'
+sil private @$S23enforce_with_opts_nob2s022testInoutWriteNoescapeG7ClosureyyFyyXEfU0_ : $@convention(thin) (@inout_aliasable Int64, @guaranteed @callee_guaranteed () -> ()) -> () {
 bb0(%0 : $*Int64, %1 : $@callee_guaranteed () -> ()):
   debug_value_addr %0 : $*Int64, var, name "x", argno 1
   debug_value %1 : $@callee_guaranteed () -> (), let, name "c", argno 2
diff --git a/test/SILOptimizer/definite-init-wrong-scope2.swift b/test/SILOptimizer/definite-init-wrong-scope2.swift
index 4e05133..5dec46c 100644
--- a/test/SILOptimizer/definite-init-wrong-scope2.swift
+++ b/test/SILOptimizer/definite-init-wrong-scope2.swift
@@ -1,5 +1,5 @@
 // RUN: %target-swift-frontend -emit-sil %s -Onone -Xllvm -sil-print-debuginfo \
-// RUN:   -o /dev/null -Xllvm -sil-print-after=definite-init \
+// RUN:   -o /dev/null -Xllvm -sil-print-after=raw-sil-inst-lowering \
 // RUN:   -Xllvm -sil-print-only-functions=$S8patatino4BearC6before7before26during5afterACSb_S3btKcfc \
 // RUN:   2>&1 | %FileCheck %s
 // REQUIRES: executable_test
diff --git a/test/SILOptimizer/definite-init-wrongscope.swift b/test/SILOptimizer/definite-init-wrongscope.swift
index aeabae3..98b241f 100644
--- a/test/SILOptimizer/definite-init-wrongscope.swift
+++ b/test/SILOptimizer/definite-init-wrongscope.swift
@@ -1,5 +1,5 @@
 // RUN: %target-swift-frontend -primary-file %s -Onone -emit-sil -Xllvm \
-// RUN:   -sil-print-after=definite-init -Xllvm \
+// RUN:   -sil-print-after=raw-sil-inst-lowering -Xllvm \
 // RUN:   -sil-print-only-functions=$S3del1MC4fromAcA12WithDelegate_p_tKcfc \
 // RUN:   -Xllvm -sil-print-debuginfo -o /dev/null 2>&1 | %FileCheck %s
 
diff --git a/test/SILOptimizer/definite_init_crashes.sil b/test/SILOptimizer/definite_init_crashes.sil
index b7bce94..e848ce1 100644
--- a/test/SILOptimizer/definite_init_crashes.sil
+++ b/test/SILOptimizer/definite_init_crashes.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering | %FileCheck %s
 
 // These are all regression tests to ensure that the memory promotion pass
 // doesn't crash.
diff --git a/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil b/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
index 8127e47..f767856 100644
--- a/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
+++ b/test/SILOptimizer/definite_init_markuninitialized_delegatingself.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -verify | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering -verify | %FileCheck %s
 
 // This test only tests mark_uninitialized [delegatingself]
 
diff --git a/test/SILOptimizer/definite_init_markuninitialized_derivedself.sil b/test/SILOptimizer/definite_init_markuninitialized_derivedself.sil
index 65934f0..d4c630e 100644
--- a/test/SILOptimizer/definite_init_markuninitialized_derivedself.sil
+++ b/test/SILOptimizer/definite_init_markuninitialized_derivedself.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -verify | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering -verify | %FileCheck %s
 
 // This test only tests mark_uninitialized [derivedself]
 
diff --git a/test/SILOptimizer/definite_init_markuninitialized_rootself.sil b/test/SILOptimizer/definite_init_markuninitialized_rootself.sil
index 4c86e67..2cfd26f 100644
--- a/test/SILOptimizer/definite_init_markuninitialized_rootself.sil
+++ b/test/SILOptimizer/definite_init_markuninitialized_rootself.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -verify | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering -verify | %FileCheck %s
 
 // This file tests mark_uninitialized [rootself]
 
diff --git a/test/SILOptimizer/definite_init_markuninitialized_var.sil b/test/SILOptimizer/definite_init_markuninitialized_var.sil
index f1eef16..31cf09e 100644
--- a/test/SILOptimizer/definite_init_markuninitialized_var.sil
+++ b/test/SILOptimizer/definite_init_markuninitialized_var.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -verify | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering -verify | %FileCheck %s
 
 // This file contains tests that test diagnostics emitted for var initialization
 // by DI.
diff --git a/test/SILOptimizer/definite_init_scalarization_test.sil b/test/SILOptimizer/definite_init_scalarization_test.sil
index d79d250..e1699fb 100644
--- a/test/SILOptimizer/definite_init_scalarization_test.sil
+++ b/test/SILOptimizer/definite_init_scalarization_test.sil
@@ -1,4 +1,4 @@
-// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init | %FileCheck %s
+// RUN: %target-sil-opt -enable-sil-ownership -enable-sil-verify-all %s -definite-init -raw-sil-inst-lowering | %FileCheck %s
 //
 // Make sure that we properly scalarize tuples.
 //
diff --git a/test/SILOptimizer/di-conditional-destroy-scope.swift b/test/SILOptimizer/di-conditional-destroy-scope.swift
index 4b6bee9..2e015b3 100644
--- a/test/SILOptimizer/di-conditional-destroy-scope.swift
+++ b/test/SILOptimizer/di-conditional-destroy-scope.swift
@@ -1,5 +1,5 @@
 // RUN: %target-swift-frontend -emit-sil %s -Onone -Xllvm \
-// RUN:   -sil-print-after=definite-init -Xllvm \
+// RUN:   -sil-print-after=raw-sil-inst-lowering -Xllvm \
 // RUN:   -sil-print-only-functions=$S2fs36RecursibleDirectoryContentsGeneratorC4path10fileSystemAcA12AbsolutePathV_AA04FileH0_ptKc33_F8B132991B28208F48606E87DC165393Llfc \
 // RUN:   -Xllvm -sil-print-debuginfo -o /dev/null 2>&1 | %FileCheck %s
 
diff --git a/test/SILOptimizer/retain_release_code_motion.sil b/test/SILOptimizer/retain_release_code_motion.sil
index e10fe72..c2b2e28 100644
--- a/test/SILOptimizer/retain_release_code_motion.sil
+++ b/test/SILOptimizer/retain_release_code_motion.sil
@@ -1,4 +1,5 @@
 // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -retain-sinking -late-release-hoisting %s | %FileCheck %s
+// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -release-hoisting %s | %FileCheck --check-prefix=CHECK-RELEASE-HOISTING %s
 // RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all -retain-sinking -retain-sinking -late-release-hoisting %s | %FileCheck --check-prefix=CHECK-MULTIPLE-RS-ROUNDS %s
 
 import Builtin
@@ -60,6 +61,10 @@
   case some(T)
 }
 
+struct Unowned {
+  @sil_stored unowned let x: @sil_unowned Builtin.NativeObject
+}
+
 sil @createS : $@convention(thin) () -> @owned S
 
 sil @use_C2 : $@convention(thin) (C2) -> ()
@@ -620,3 +625,44 @@
   return %10 : $()
 }
 
+// CHECK-LABEL: sil @test_unowned
+// CHECK:      bb0(%0 : $Builtin.NativeObject):
+// CHECK-NEXT:   br bb1    
+// CHECK:      bb1:
+// CHECK-NEXT:   tuple
+// CHECK-NEXT:   return
+sil @test_unowned : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+  %1 = ref_to_unowned %0 : $Builtin.NativeObject to $@sil_unowned Builtin.NativeObject
+  %2 = struct $Unowned (%1 : $@sil_unowned Builtin.NativeObject)
+  retain_value %2: $Unowned
+  br bb1
+
+bb1:
+  release_value %2: $Unowned
+  %5 = tuple()
+  return %5 : $()
+}
+
+// CHECK-RELEASE-HOISTING-LABEL: sil @dont_eliminate_strong_retain_and_unowned_release_pair
+// CHECK-RELEASE-HOISTING:       = function_ref @blocker
+// CHECK-RELEASE-HOISTING-NEXT:  apply
+// CHECK-RELEASE-HOISTING-NEXT:  strong_retain %0 : $Builtin.NativeObject
+// CHECK-RELEASE-HOISTING-NEXT:  unowned_release %1 : $@sil_unowned Builtin.NativeObject
+sil @dont_eliminate_strong_retain_and_unowned_release_pair : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
+bb0(%0 : $Builtin.NativeObject):
+  %1 = ref_to_unowned %0 : $Builtin.NativeObject to $@sil_unowned Builtin.NativeObject
+  %2 = struct $Unowned (%1 : $@sil_unowned Builtin.NativeObject)
+  retain_value %2: $Unowned
+  %b = function_ref @blocker : $@convention(thin) () -> ()
+  apply %b() : $@convention(thin) () -> ()
+  strong_retain %0: $Builtin.NativeObject
+  br bb1
+
+bb1:
+  release_value %2: $Unowned
+  apply %b() : $@convention(thin) () -> ()
+  strong_release %0: $Builtin.NativeObject
+  %5 = tuple()
+  return %5 : $()
+}
diff --git a/test/Serialization/Inputs/alias.swift b/test/Serialization/Inputs/alias.swift
index 730d15e..a94128f 100644
--- a/test/Serialization/Inputs/alias.swift
+++ b/test/Serialization/Inputs/alias.swift
@@ -36,3 +36,6 @@
 public typealias GG = Outer.G
 
 public typealias GInt = Outer.G<Int>
+
+public struct UnboundStruct<T> {}
+public typealias UnboundAlias<T: Comparable> = UnboundStruct<T>
diff --git a/test/Serialization/typealias.swift b/test/Serialization/typealias.swift
index a97201b..4b5c787 100644
--- a/test/Serialization/typealias.swift
+++ b/test/Serialization/typealias.swift
@@ -1,5 +1,6 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-build-swift -module-name alias -emit-module -o %t %S/Inputs/alias.swift
+// RUN: %target-build-swift -I %t %s -module-name typealias -emit-module-path %t/typealias.swiftmodule -o %t/typealias.o
 // RUN: llvm-bcanalyzer %t/alias.swiftmodule | %FileCheck %s
 // RUN: %target-build-swift -I %t %s -o %t/a.out
 // RUN: %target-run %t/a.out | %FileCheck -check-prefix=OUTPUT %s
@@ -53,3 +54,5 @@
 
 let x: GG<Int> = 0
 let x2: GInt = 1
+
+public typealias TestUnbound = UnboundAlias
diff --git a/test/SourceKit/CodeComplete/complete_filter.swift b/test/SourceKit/CodeComplete/complete_filter.swift
index 3836c23..63e2d3f 100644
--- a/test/SourceKit/CodeComplete/complete_filter.swift
+++ b/test/SourceKit/CodeComplete/complete_filter.swift
@@ -70,6 +70,7 @@
 // CHECK-NEXT:   abc()
 // CHECK-NEXT:   b()
 // CHECK-NEXT:   c()
+// CHECK-NEXT:   self
 // CHECK-NEXT: ]
 // CHECK-LABEL: Results for filterText: a [
 // CHECK-NEXT:   aaa()
diff --git a/test/SourceKit/CodeComplete/complete_group_overloads.swift b/test/SourceKit/CodeComplete/complete_group_overloads.swift
index a3414a0..b964f7b 100644
--- a/test/SourceKit/CodeComplete/complete_group_overloads.swift
+++ b/test/SourceKit/CodeComplete/complete_group_overloads.swift
@@ -85,10 +85,11 @@
 }
 // Inline a lonely group
 // RUN: %complete-test -group=overloads -add-inner-results -no-inner-operators -tok=BAR_INIT_0 %s | %FileCheck -check-prefix=BAR_INIT_0 %s
-// BAR_INIT_0-NOT: (:
+// BAR_INIT_0-LABEL: (:
 // BAR_INIT_0: ()
 // BAR_INIT_0-NEXT: (x: A)
 // BAR_INIT_0-NEXT: (x: B)
+// BAR_INIT_0-NEXT: .self
 
 extension Bar {
   func foo()
diff --git a/test/SourceKit/CodeComplete/complete_inner.swift b/test/SourceKit/CodeComplete/complete_inner.swift
index 9f41f4d..5bc1057 100644
--- a/test/SourceKit/CodeComplete/complete_inner.swift
+++ b/test/SourceKit/CodeComplete/complete_inner.swift
@@ -59,8 +59,10 @@
 
 // TOP_LEVEL_0-LABEL: Results for filterText: foo [
 // TOP_LEVEL_0-NEXT:   Foo
+// TOP_LEVEL_0-NEXT:   Foo.
 // TOP_LEVEL_0-NEXT:   Foo(
 // TOP_LEVEL_0-NEXT:   FooBar
+// TOP_LEVEL_0-NEXT:   Foo.self
 // TOP_LEVEL_0-NEXT:   Foo()
 // TOP_LEVEL_0-NEXT: ]
 
@@ -72,6 +74,7 @@
 // TOP_LEVEL_0-NEXT:   FooBar
 // TOP_LEVEL_0-NEXT:   FooBar.
 // TOP_LEVEL_0-NEXT:   FooBar(
+// TOP_LEVEL_0-NEXT:   FooBar.self
 // TOP_LEVEL_0-NEXT:   FooBar()
 // TOP_LEVEL_0-NEXT:   FooBar(x: Foo)
 // TOP_LEVEL_0-NEXT:   FooBar.fooBar()
@@ -92,6 +95,7 @@
 // TOP_LEVEL_1-NEXT:   abc.
 // TOP_LEVEL_1-NEXT:   abc===
 // TOP_LEVEL_1-NEXT:   abc!==
+// TOP_LEVEL_1-NEXT:   abc.self
 // TOP_LEVEL_1-NEXT:   abc.method()
 // TOP_LEVEL_1-NEXT:   abc.prop
 // TOP_LEVEL_1-NEXT: ]
@@ -101,6 +105,7 @@
 // TOP_LEVEL_1-NEXT:   abd.
 // TOP_LEVEL_1-NEXT:   abd===
 // TOP_LEVEL_1-NEXT:   abd!==
+// TOP_LEVEL_1-NEXT:   abd.self
 // TOP_LEVEL_1-NEXT:   abd.base()
 // TOP_LEVEL_1-NEXT: ]
 
@@ -138,12 +143,14 @@
 // FOOBAR_QUALIFIED_NOOP-NEXT: ]
 // FOOBAR_QUALIFIED_NOOP-LABEL: Results for filterText: prop [
 // FOOBAR_QUALIFIED_NOOP-NEXT:   prop
+// FOOBAR_QUALIFIED_NOOP-NEXT:   prop.self
 // FOOBAR_QUALIFIED_NOOP-NEXT:   prop.method()
 // FOOBAR_QUALIFIED_NOOP-NEXT:   prop.prop
 // FOOBAR_QUALIFIED_NOOP-NEXT: ]
 
 // RUN: %complete-test %s -group=none -no-include-exact-match -add-inner-results -no-inner-operators -tok=FOOBAR_QUALIFIED | %FileCheck %s -check-prefix=FOOBAR_QUALIFIED_NOEXACT
 // FOOBAR_QUALIFIED_NOEXACT-LABEL: Results for filterText: prop [
+// FOOBAR_QUALIFIED_NOEXACT-NEXT:   prop.self
 // FOOBAR_QUALIFIED_NOEXACT-NEXT:   prop.method()
 // FOOBAR_QUALIFIED_NOEXACT-NEXT:   prop.prop
 // FOOBAR_QUALIFIED_NOEXACT-NEXT: ]
diff --git a/test/SourceKit/CodeComplete/complete_member.swift.response b/test/SourceKit/CodeComplete/complete_member.swift.response
index b4977f8..8f4a9ec 100644
--- a/test/SourceKit/CodeComplete/complete_member.swift.response
+++ b/test/SourceKit/CodeComplete/complete_member.swift.response
@@ -33,6 +33,15 @@
       key.num_bytes_to_erase: 0,
       key.associated_usrs: "s:15complete_member11FooProtocolP14fooInstanceVarSivp",
       key.modulename: "complete_member"
+    },
+    {
+      key.kind: source.lang.swift.keyword,
+      key.name: "self",
+      key.sourcetext: "self",
+      key.description: "self",
+      key.typename: "FooProtocol",
+      key.context: source.codecompletion.context.thisclass,
+      key.num_bytes_to_erase: 0
     }
   ]
 }
diff --git a/test/SourceKit/CodeComplete/complete_requestlimit.swift b/test/SourceKit/CodeComplete/complete_requestlimit.swift
index ce191b4..2c5bba5 100644
--- a/test/SourceKit/CodeComplete/complete_requestlimit.swift
+++ b/test/SourceKit/CodeComplete/complete_requestlimit.swift
@@ -63,6 +63,7 @@
 // B_INSTANCE_0_ALL: a
 // B_INSTANCE_0_ALL-NEXT: b
 // B_INSTANCE_0_ALL-NEXT: c
+// B_INSTANCE_0_ALL-NEXT: self
 
 // B_INSTANCE_0_1: a
 // B_INSTANCE_0_1-NOT: b
@@ -107,6 +108,7 @@
 // OVERLOADS_ALL-NEXT:   aaa(x: A)
 // OVERLOADS_ALL-NEXT:   aaa(x: B)
 // OVERLOADS_ALL-NEXT: aab()
+// OVERLOADS_ALL-NEXT: self
 
 // limit applies to top-level, not to subgroups
 // OVERLOADS_1: aaa:
@@ -121,11 +123,11 @@
 // If we return all the results, nextrequeststart == 0
 // RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw | %FileCheck -check-prefix=NEXT-END %s
 // RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -limit=5 | %FileCheck -check-prefix=NEXT-END %s
-// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -limit=2 | %FileCheck -check-prefix=NEXT-END %s
+// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -limit=3 | %FileCheck -check-prefix=NEXT-END %s
 // NEXT-END: key.nextrequeststart: 0
 
 // If we return the last result, nextrequeststart == 0
-// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -start=1 -limit=1 | %FileCheck -check-prefix=NEXT-END %s
+// RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -start=2 -limit=1 | %FileCheck -check-prefix=NEXT-END %s
 
 // Otherwise, it's the next result
 // RUN: %complete-test -group=overloads -tok=D_INSTANCE_0 %s -raw -limit=1 | %FileCheck -check-prefix=NEXT1 %s
diff --git a/test/SourceKit/SyntaxMapData/Inputs/syntaxmap.swift b/test/SourceKit/SyntaxMapData/Inputs/syntaxmap.swift
index 29c1681..4ba4859 100644
--- a/test/SourceKit/SyntaxMapData/Inputs/syntaxmap.swift
+++ b/test/SourceKit/SyntaxMapData/Inputs/syntaxmap.swift
@@ -49,3 +49,8 @@
 // unknownprotocol://awesomeguy.com
 
 _ = -123
+
+func testArgumentLabels(in class: Int, _ case: (_ default: Int) -> Void) -> (in: Int, String) {
+  let result: (in: Int, String) = (0, "test")
+  return something ? result : (in: 2, "foo")
+}
diff --git a/test/SourceKit/SyntaxMapData/syntaxmap.swift.response b/test/SourceKit/SyntaxMapData/syntaxmap.swift.response
index 3e3e5e8..f8e4e84 100644
--- a/test/SourceKit/SyntaxMapData/syntaxmap.swift.response
+++ b/test/SourceKit/SyntaxMapData/syntaxmap.swift.response
@@ -1,6 +1,6 @@
 {
   key.offset: 0,
-  key.length: 859,
+  key.length: 1049,
   key.diagnostic_stage: source.diagnostic.stage.swift.parse,
   key.syntaxmap: [
     {
@@ -432,6 +432,141 @@
       key.kind: source.lang.swift.syntaxtype.number,
       key.offset: 854,
       key.length: 4
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.keyword,
+      key.offset: 860,
+      key.length: 4
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 865,
+      key.length: 18
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 884,
+      key.length: 2
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 887,
+      key.length: 5
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.typeidentifier,
+      key.offset: 894,
+      key.length: 3
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.keyword,
+      key.offset: 899,
+      key.length: 1
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 901,
+      key.length: 4
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.keyword,
+      key.offset: 908,
+      key.length: 1
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 910,
+      key.length: 7
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.typeidentifier,
+      key.offset: 919,
+      key.length: 3
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.typeidentifier,
+      key.offset: 927,
+      key.length: 4
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 937,
+      key.length: 2
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.typeidentifier,
+      key.offset: 941,
+      key.length: 3
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.typeidentifier,
+      key.offset: 946,
+      key.length: 6
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.keyword,
+      key.offset: 958,
+      key.length: 3
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 962,
+      key.length: 6
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 971,
+      key.length: 2
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.typeidentifier,
+      key.offset: 975,
+      key.length: 3
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.typeidentifier,
+      key.offset: 980,
+      key.length: 6
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.number,
+      key.offset: 991,
+      key.length: 1
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.string,
+      key.offset: 994,
+      key.length: 6
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.keyword,
+      key.offset: 1004,
+      key.length: 6
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 1011,
+      key.length: 9
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 1023,
+      key.length: 6
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.identifier,
+      key.offset: 1033,
+      key.length: 2
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.number,
+      key.offset: 1037,
+      key.length: 1
+    },
+    {
+      key.kind: source.lang.swift.syntaxtype.string,
+      key.offset: 1040,
+      key.length: 5
     }
   ]
 }
diff --git a/test/TBD/Inputs/extension_types.swift b/test/TBD/Inputs/extension_types.swift
index f60ac6e..938526c 100644
--- a/test/TBD/Inputs/extension_types.swift
+++ b/test/TBD/Inputs/extension_types.swift
@@ -1,4 +1,20 @@
-public protocol Foreign {}
+public protocol Foreign {
+    func foreignMethod()
+    var foreignGet: Int { get }
+    var foreignGetSet: Int { get set }
+}
+public protocol ForeignInherit: Foreign {}
+extension ForeignInherit {
+    public func foreignMethod() {}
+    public var foreignGet: Int { return 0 }
+    public var foreignGetSet: Int {
+        get { return 0 }
+        set {}
+    }
+}
+
 
 public struct ForeignStruct {}
-public struct ForeignStruct2 {}
+public struct ForeignStructInherit {}
+public struct ForeignStructInheritNoDefault {}
+public struct ForeignStructOneExtension {}
diff --git a/test/TBD/extension.swift b/test/TBD/extension.swift
deleted file mode 100644
index 35f1316..0000000
--- a/test/TBD/extension.swift
+++ /dev/null
@@ -1,40 +0,0 @@
-// RUN: %empty-directory(%t)
-// RUN: %target-build-swift %S/Inputs/extension_types.swift -module-name ExtensionTypes -emit-module -emit-module-path %t/ExtensionTypes.swiftmodule
-// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t %s
-
-import ExtensionTypes
-
-public protocol Public {}
-internal protocol Internal {}
-private protocol Private {}
-
-extension ForeignStruct: Foreign {}
-extension ForeignStruct: Public {}
-extension ForeignStruct: Internal {}
-extension ForeignStruct: Private {}
-extension ForeignStruct2: Foreign, Public, Internal, Private {}
-
-public struct PublicStruct {}
-public struct PublicStruct2 {}
-internal struct InternalStruct {}
-internal struct InternalStruct2 {}
-private struct PrivateStruct {}
-private struct PrivateStruct2 {}
-
-extension PublicStruct: Foreign {}
-extension PublicStruct: Public {}
-extension PublicStruct: Internal {}
-extension PublicStruct: Private {}
-extension PublicStruct2: Foreign, Public, Internal, Private {}
-
-extension InternalStruct: Foreign {}
-extension InternalStruct: Public {}
-extension InternalStruct: Internal {}
-extension InternalStruct: Private {}
-extension InternalStruct2: Foreign, Public, Internal, Private {}
-
-extension PrivateStruct: Foreign {}
-extension PrivateStruct: Public {}
-extension PrivateStruct: Internal {}
-extension PrivateStruct: Private {}
-extension PrivateStruct2: Foreign, Public, Internal, Private {}
diff --git a/test/TBD/extension.swift.gyb b/test/TBD/extension.swift.gyb
new file mode 100644
index 0000000..49ad01a
--- /dev/null
+++ b/test/TBD/extension.swift.gyb
@@ -0,0 +1,94 @@
+// RUN: %empty-directory(%t)
+// RUN: %gyb %s > %t/main.swift
+
+// Other module is not resilient:
+// RUN: %empty-directory(%t/types)
+// RUN: %target-build-swift %S/Inputs/extension_types.swift -module-name ExtensionTypes -emit-module -emit-module-path %t/types/ExtensionTypes.swiftmodule
+// This module is both not resilient:
+// RUN: %target-swift-frontend -emit-ir -o%t/not_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift
+// ... and resilient:
+// RUN: %target-swift-frontend -emit-ir -o%t/not_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=all -I %t/types %t/main.swift -enable-resilience
+
+// Other module is resilient:
+// RUN: %empty-directory(%t/types)
+// RUN: %target-build-swift %S/Inputs/extension_types.swift -module-name ExtensionTypes -emit-module -emit-module-path %t/types/ExtensionTypes.swiftmodule -Xfrontend -enable-resilience
+// This module is both not resilient:
+// RUN: %target-swift-frontend -emit-ir -o%t/resilient_not.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift
+// ... and resilient:
+// RUN: %target-swift-frontend -emit-ir -o%t/resilient_resilient.ll -parse-as-library -module-name test -validate-tbd-against-ir=missing -I %t/types %t/main.swift -enable-resilience
+
+
+import ExtensionTypes
+
+// This generates all combinations of a public/internal/private struct
+// (plus a public one from another module) being extended to conform
+// to a public/internal/private protocol (plus a public one from
+// another module), both with and without inheritance/defaulting.
+
+%{
+local_decl_names = ["Public", "Internal", "Private"]
+all_decl_names = ["Foreign"] + local_decl_names
+decl_name_to_access = {
+    "Foreign": "public",
+    "Public": "public",
+    "Internal": "internal",
+    "Private": "fileprivate"
+}
+def conformanceBody(protocol):
+    return """
+    {access} func {name}Method() {{}}
+    {access} var {name}Get: Int {{ return 0 }}
+    {access} var {name}GetSet: Int {{
+        get {{ return 0 }}
+        set {{}}
+    }}
+    """.format(access = decl_name_to_access[protocol],
+               name = protocol.lower())
+}%
+
+% for name in local_decl_names:
+% access = name.lower()
+
+${access} protocol ${name} {
+    func ${access}Method()
+    var ${access}Get: Int { get }
+    var ${access}GetSet: Int { get set }
+}
+
+// Defaulted methods:
+${access} protocol ${name}Inherit: Foreign {}
+extension ${name}Inherit {
+    ${conformanceBody(name)}
+}
+
+${access} struct ${name}Struct {}
+${access} struct ${name}StructInherit {}
+${access} struct ${name}StructInheritNoDefault {}
+${access} struct ${name}StructOneExtension {}
+% end
+
+% for sname in all_decl_names:
+% access = sname.lower()
+
+% for pname in all_decl_names:
+// e.g. extension PublicStruct: Private { ... }
+extension ${sname}Struct: ${pname} {
+    ${conformanceBody(pname)}
+}
+
+// e.g. extension PublicStructInherit: PrivateInherit {}
+extension ${sname}StructInherit: ${pname}Inherit {}
+
+// e.g. extension PublicStructInheritNoDefault: PrivateInherit { ... }
+extension ${sname}StructInheritNoDefault: ${pname}Inherit {
+    ${conformanceBody(pname)}
+}
+% end
+
+// e.g. extension PublicStructOneExtension: Foreign, Public, Internal, Private { ... }
+extension ${sname}StructOneExtension: ${", ".join(p for p in all_decl_names)} {
+% for pname in all_decl_names:
+    ${conformanceBody(pname)}
+% end
+}
+% end
diff --git a/test/TBD/global.swift b/test/TBD/global.swift
index af400bf..3a3e6dd 100644
--- a/test/TBD/global.swift
+++ b/test/TBD/global.swift
@@ -1,4 +1,5 @@
 // RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing -enable-resilience %s
 
 public let publicLet: Int = 0
 internal let internalLet: Int = 0
diff --git a/test/TBD/struct.swift b/test/TBD/struct.swift
index 9bd42bb..b3a9bb2 100644
--- a/test/TBD/struct.swift
+++ b/test/TBD/struct.swift
@@ -1,4 +1,5 @@
 // RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s
+// RUN: %target-swift-frontend -emit-ir -o- -parse-as-library -module-name test -validate-tbd-against-ir=missing %s -enable-resilience
 
 public struct PublicNothing {}
 
@@ -44,6 +45,25 @@
     }
 }
 
+public struct PublicSubscripts {
+    public subscript(publicGet _: Int) -> Int { return 0 }
+    internal subscript(internalGet _: Int) -> Int { return 0 }
+    private subscript(privateGet _: Int) -> Int { return 0 }
+
+    public subscript(publicGetSet _: Int) -> Int {
+        get {return 0 }
+        set {}
+    }
+    internal subscript(internalGetSet _: Int) -> Int {
+        get {return 0 }
+        set {}
+    }
+    private subscript(privateGetSet _: Int) -> Int {
+        get {return 0 }
+        set {}
+    }
+}
+
 public struct PublicStatics {
     public static func publicStaticFunc() {}
     internal static func internalStaticFunc() {}
@@ -135,6 +155,20 @@
     }
 }
 
+internal struct InternalSubscripts {
+    internal subscript(internalGet _: Int) -> Int { return 0 }
+    private subscript(privateGet _: Int) -> Int { return 0 }
+
+    internal subscript(internalGetSet _: Int) -> Int {
+        get {return 0 }
+        set {}
+    }
+    private subscript(privateGetSet _: Int) -> Int {
+        get {return 0 }
+        set {}
+    }
+}
+
 internal struct InternalStatics {
     internal static func internalStaticFunc() {}
     private static func privateStaticFunc() {}
@@ -203,6 +237,15 @@
     }
 }
 
+private struct PrivateSubscripts {
+    private subscript(privateGet _: Int) -> Int { return 0 }
+
+    private subscript(privateGetSet _: Int) -> Int {
+        get {return 0 }
+        set {}
+    }
+}
+
 private struct PrivateStatics {
     private static func privateStaticFunc() {}
 
diff --git a/test/api-digester/Inputs/APINotesLeft/APINotesTest.h b/test/api-digester/Inputs/APINotesLeft/APINotesTest.h
index 653c8d1..d7be123 100644
--- a/test/api-digester/Inputs/APINotesLeft/APINotesTest.h
+++ b/test/api-digester/Inputs/APINotesLeft/APINotesTest.h
@@ -28,3 +28,5 @@
 @end
 
 extern NSString *globalAttributeName;
+
+typedef NSString * CatAttributeName;
\ No newline at end of file
diff --git a/test/api-digester/Inputs/APINotesRight/APINotesTest.h b/test/api-digester/Inputs/APINotesRight/APINotesTest.h
index ddd4963..29e4572 100644
--- a/test/api-digester/Inputs/APINotesRight/APINotesTest.h
+++ b/test/api-digester/Inputs/APINotesRight/APINotesTest.h
@@ -28,3 +28,5 @@
 @end
 
 extern AnimalAttributeName globalAttributeName;
+
+typedef NSString * CatAttributeName NS_STRING_ENUM;
diff --git a/test/api-digester/Outputs/apinotes-diags.txt b/test/api-digester/Outputs/apinotes-diags.txt
index 01c7951..fa8e23c 100644
--- a/test/api-digester/Outputs/apinotes-diags.txt
+++ b/test/api-digester/Outputs/apinotes-diags.txt
@@ -1,5 +1,6 @@
 
 /* RawRepresentable Changes */
+APINotesTest(APINotesTest.h): TypeAlias CatAttributeName(NSString) is now String representable
 
 /* Removed Decls */
 APINotesTest(APINotesTest.h): Func ObjcProt.protMemberFunc2() has been removed
diff --git a/test/api-digester/Outputs/apinotes-migrator-gen-revert.json b/test/api-digester/Outputs/apinotes-migrator-gen-revert.json
index 97c463a..6025fa4 100644
--- a/test/api-digester/Outputs/apinotes-migrator-gen-revert.json
+++ b/test/api-digester/Outputs/apinotes-migrator-gen-revert.json
@@ -2,9 +2,9 @@
   {
     "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
+    "NodeAnnotation": "RevertSimpleStringRepresentableUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
     "LeftComment": "AnimalAttributeName",
     "RightUsr": "",
     "RightComment": "String",
@@ -13,174 +13,9 @@
   {
     "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
-    "NodeAnnotation": "RevertDictionaryKeyUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
-    "LeftComment": "",
-    "RightUsr": "",
-    "RightComment": "",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
     "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
-    "LeftComment": "AnimalAttributeName",
-    "RightUsr": "",
-    "RightComment": "String",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "RevertDictionaryKeyUpdate",
     "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
-    "LeftComment": "",
-    "RightUsr": "",
-    "RightComment": "",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
-    "LeftComment": "AnimalAttributeName",
-    "RightUsr": "",
-    "RightComment": "String",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "RevertOptionalDictionaryKeyUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
-    "LeftComment": "",
-    "RightUsr": "",
-    "RightComment": "",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
-    "LeftComment": "AnimalAttributeName",
-    "RightUsr": "",
-    "RightComment": "String",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "RevertOptionalDictionaryKeyUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
-    "LeftComment": "",
-    "RightUsr": "",
-    "RightComment": "",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
-    "LeftComment": "AnimalAttributeName",
-    "RightUsr": "",
-    "RightComment": "String",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "RevertArrayMemberUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
-    "LeftComment": "",
-    "RightUsr": "",
-    "RightComment": "",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
-    "LeftComment": "AnimalAttributeName",
-    "RightUsr": "",
-    "RightComment": "String",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "RevertArrayMemberUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
-    "LeftComment": "",
-    "RightUsr": "",
-    "RightComment": "",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
-    "LeftComment": "AnimalAttributeName",
-    "RightUsr": "",
-    "RightComment": "String",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "RevertOptionalArrayMemberUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
-    "LeftComment": "",
-    "RightUsr": "",
-    "RightComment": "",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
-    "LeftComment": "AnimalAttributeName",
-    "RightUsr": "",
-    "RightComment": "String",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "RevertOptionalArrayMemberUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
-    "LeftComment": "",
-    "RightUsr": "",
-    "RightComment": "",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleOptionalAttribute:",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
     "LeftComment": "AnimalAttributeName",
     "RightUsr": "",
     "RightComment": "String",
@@ -192,28 +27,105 @@
     "NodeAnnotation": "RevertSimpleOptionalStringRepresentableUpdate",
     "ChildIndex": "1",
     "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleOptionalAttribute:",
-    "LeftComment": "",
+    "LeftComment": "AnimalAttributeName",
     "RightUsr": "",
-    "RightComment": "",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "RevertSimpleStringRepresentableUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
-    "LeftComment": "",
-    "RightUsr": "",
-    "RightComment": "",
+    "RightComment": "String",
     "ModuleName": "APINotesTest"
   },
   {
     "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
     "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "1:0",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleOptionalAttribute:",
+    "LeftComment": "AnimalAttributeName",
+    "RightUsr": "",
+    "RightComment": "String",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "RevertDictionaryKeyUpdate",
     "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
+    "LeftComment": "AnimalAttributeName",
+    "RightUsr": "",
+    "RightComment": "String",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "1:0",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
+    "LeftComment": "AnimalAttributeName",
+    "RightUsr": "",
+    "RightComment": "String",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "RevertArrayMemberUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
+    "LeftComment": "AnimalAttributeName",
+    "RightUsr": "",
+    "RightComment": "String",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "1:0",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
+    "LeftComment": "AnimalAttributeName",
+    "RightUsr": "",
+    "RightComment": "String",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "RevertOptionalDictionaryKeyUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
+    "LeftComment": "AnimalAttributeName",
+    "RightUsr": "",
+    "RightComment": "String",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "1:0:0",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
+    "LeftComment": "AnimalAttributeName",
+    "RightUsr": "",
+    "RightComment": "String",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "RevertOptionalArrayMemberUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
+    "LeftComment": "AnimalAttributeName",
+    "RightUsr": "",
+    "RightComment": "String",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "1:0:0",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
     "LeftComment": "AnimalAttributeName",
     "RightUsr": "",
     "RightComment": "String",
diff --git a/test/api-digester/Outputs/apinotes-migrator-gen.json b/test/api-digester/Outputs/apinotes-migrator-gen.json
index 73ca26d..5e0810d 100644
--- a/test/api-digester/Outputs/apinotes-migrator-gen.json
+++ b/test/api-digester/Outputs/apinotes-migrator-gen.json
@@ -1,10 +1,10 @@
 [
   {
     "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
+    "NodeKind": "Var",
+    "NodeAnnotation": "SimpleStringRepresentableUpdate",
+    "ChildIndex": "0",
+    "LeftUsr": "c:@globalAttributeName",
     "LeftComment": "String",
     "RightUsr": "",
     "RightComment": "AnimalAttributeName",
@@ -12,10 +12,21 @@
   },
   {
     "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "TypeAlias",
+    "NodeAnnotation": "TypeAliasDeclToRawRepresentable",
+    "ChildIndex": "0",
+    "LeftUsr": "c:APINotesTest.h@T@CatAttributeName",
+    "LeftComment": "NSString",
+    "RightUsr": "",
+    "RightComment": "String",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
-    "NodeAnnotation": "DictionaryKeyUpdate",
+    "NodeAnnotation": "SimpleStringRepresentableUpdate",
     "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
     "LeftComment": "String",
     "RightUsr": "",
     "RightComment": "AnimalAttributeName",
@@ -25,162 +36,8 @@
     "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
     "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "DictionaryKeyUpdate",
     "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "OptionalDictionaryKeyUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "OptionalDictionaryKeyUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "ArrayMemberUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "ArrayMemberUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "OptionalArrayMemberUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "OptionalArrayMemberUpdate",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
-    "ModuleName": "APINotesTest"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1:0",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleOptionalAttribute:",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
     "LeftComment": "String",
     "RightUsr": "",
     "RightComment": "AnimalAttributeName",
@@ -200,9 +57,20 @@
   {
     "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
-    "NodeAnnotation": "SimpleStringRepresentableUpdate",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "1:0",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleOptionalAttribute:",
+    "LeftComment": "String",
+    "RightUsr": "",
+    "RightComment": "AnimalAttributeName",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "DictionaryKeyUpdate",
     "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
     "LeftComment": "String",
     "RightUsr": "",
     "RightComment": "AnimalAttributeName",
@@ -212,8 +80,8 @@
     "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
     "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "1",
-    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(cm)animalStatusSingleAttribute:",
+    "ChildIndex": "1:0",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributes:",
     "LeftComment": "String",
     "RightUsr": "",
     "RightComment": "AnimalAttributeName",
@@ -222,12 +90,67 @@
   {
     "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
-    "NodeAnnotation": "GetterToProperty",
-    "ChildIndex": "0",
-    "LeftUsr": "c:objc(pl)TypeWithMethod(im)getPropertyA",
-    "LeftComment": "",
+    "NodeAnnotation": "ArrayMemberUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
+    "LeftComment": "String",
     "RightUsr": "",
-    "RightComment": "propertyA",
+    "RightComment": "AnimalAttributeName",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "1:0",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingAttributesArray:",
+    "LeftComment": "String",
+    "RightUsr": "",
+    "RightComment": "AnimalAttributeName",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "OptionalDictionaryKeyUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
+    "LeftComment": "String",
+    "RightUsr": "",
+    "RightComment": "AnimalAttributeName",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "1:0:0",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributes:",
+    "LeftComment": "String",
+    "RightUsr": "",
+    "RightComment": "AnimalAttributeName",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "OptionalArrayMemberUpdate",
+    "ChildIndex": "1",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
+    "LeftComment": "String",
+    "RightUsr": "",
+    "RightComment": "AnimalAttributeName",
+    "ModuleName": "APINotesTest"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "1:0:0",
+    "LeftUsr": "c:objc(cs)AnimalStatusDescriptor(im)animalStatusDescriptorByAddingOptionalAttributesArray:",
+    "LeftComment": "String",
+    "RightUsr": "",
+    "RightComment": "AnimalAttributeName",
     "ModuleName": "APINotesTest"
   },
   {
@@ -243,25 +166,17 @@
   },
   {
     "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Var",
-    "NodeAnnotation": "SimpleStringRepresentableUpdate",
+    "NodeKind": "Function",
+    "NodeAnnotation": "GetterToProperty",
     "ChildIndex": "0",
-    "LeftUsr": "c:@globalAttributeName",
-    "LeftComment": "String",
+    "LeftUsr": "c:objc(pl)TypeWithMethod(im)getPropertyA",
+    "LeftComment": "",
     "RightUsr": "",
-    "RightComment": "AnimalAttributeName",
+    "RightComment": "propertyA",
     "ModuleName": "APINotesTest"
   },
   {
     "DiffItemKind": "TypeMemberDiffItem",
-    "Usr": "c:@globalAttributeName",
-    "OldPrintedName": "globalAttributeName",
-    "OldTypeName": "",
-    "NewPrintedName": "globalAttributeName",
-    "NewTypeName": "AnimalAttributeName"
-  },
-  {
-    "DiffItemKind": "TypeMemberDiffItem",
     "Usr": "c:@ANTGlobalValue",
     "OldPrintedName": "oldMember",
     "OldTypeName": "OldType",
@@ -270,6 +185,14 @@
   },
   {
     "DiffItemKind": "TypeMemberDiffItem",
+    "Usr": "c:@globalAttributeName",
+    "OldPrintedName": "globalAttributeName",
+    "OldTypeName": "",
+    "NewPrintedName": "globalAttributeName",
+    "NewTypeName": "AnimalAttributeName"
+  },
+  {
+    "DiffItemKind": "TypeMemberDiffItem",
     "Usr": "c:objc(pl)TypeWithMethod(cm)plusPrint",
     "OldPrintedName": "plusPrint()",
     "OldTypeName": "SwiftTypeWithMethodLeft",
diff --git a/test/api-digester/Outputs/macro-gen.json b/test/api-digester/Outputs/macro-gen.json
index 876f7cf..5f7ffd4 100644
--- a/test/api-digester/Outputs/macro-gen.json
+++ b/test/api-digester/Outputs/macro-gen.json
@@ -1,13 +1,35 @@
 [
   {
     "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Constructor",
+    "NodeKind": "Function",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "0",
+    "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
+    "LeftComment": "String",
+    "RightUsr": "",
+    "RightComment": "Int",
+    "ModuleName": "macrogenleft"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
     "NodeAnnotation": "TypeRewritten",
     "ChildIndex": "1",
-    "LeftUsr": "s:12macrogenleft2S1VyACSicfc",
+    "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
     "LeftComment": "Int",
     "RightUsr": "",
-    "RightComment": "Double",
+    "RightComment": "() -> ()",
+    "ModuleName": "macrogenleft"
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "TypeRewritten",
+    "ChildIndex": "2",
+    "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
+    "LeftComment": "Int",
+    "RightUsr": "",
+    "RightComment": "String",
     "ModuleName": "macrogenleft"
   },
   {
@@ -90,8 +112,8 @@
   {
     "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
-    "NodeAnnotation": "UnwrapOptional",
-    "ChildIndex": "1:0:1",
+    "NodeAnnotation": "WrapOptional",
+    "ChildIndex": "2:0",
     "LeftUsr": "s:12macrogenleft2S1V4foo91x1yySays10DictionaryVySiSSSgGG_SaySiGtF",
     "LeftComment": "",
     "RightUsr": "",
@@ -101,8 +123,8 @@
   {
     "DiffItemKind": "CommonDiffItem",
     "NodeKind": "Function",
-    "NodeAnnotation": "WrapOptional",
-    "ChildIndex": "2:0",
+    "NodeAnnotation": "UnwrapOptional",
+    "ChildIndex": "1:0:1",
     "LeftUsr": "s:12macrogenleft2S1V4foo91x1yySays10DictionaryVySiSSSgGG_SaySiGtF",
     "LeftComment": "",
     "RightUsr": "",
@@ -144,35 +166,13 @@
   },
   {
     "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "0",
-    "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
-    "LeftComment": "String",
-    "RightUsr": "",
-    "RightComment": "Int",
-    "ModuleName": "macrogenleft"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
+    "NodeKind": "Constructor",
     "NodeAnnotation": "TypeRewritten",
     "ChildIndex": "1",
-    "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
+    "LeftUsr": "s:12macrogenleft2S1VyACSicfc",
     "LeftComment": "Int",
     "RightUsr": "",
-    "RightComment": "() -> ()",
-    "ModuleName": "macrogenleft"
-  },
-  {
-    "DiffItemKind": "CommonDiffItem",
-    "NodeKind": "Function",
-    "NodeAnnotation": "TypeRewritten",
-    "ChildIndex": "2",
-    "LeftUsr": "s:12macrogenleft2C1C4foo2ySSSi_SitF",
-    "LeftComment": "Int",
-    "RightUsr": "",
-    "RightComment": "String",
+    "RightComment": "Double",
     "ModuleName": "macrogenleft"
   }
 ]
\ No newline at end of file
diff --git a/test/attr/attr_discardableResult.swift b/test/attr/attr_discardableResult.swift
index 8ed2e24..e63ee90 100644
--- a/test/attr/attr_discardableResult.swift
+++ b/test/attr/attr_discardableResult.swift
@@ -185,3 +185,12 @@
   return closure
 }
 SR2948({}) // okay
+
+class SR7562_A {
+    @discardableResult required init(input: Int) { }
+}
+
+class SR7562_B : SR7562_A {}
+
+SR7562_A(input: 10) // okay
+SR7562_B(input: 10) // okay
diff --git a/test/attr/attr_fixed_layout.swift b/test/attr/attr_fixed_layout.swift
index ee08959..47ff4c7 100644
--- a/test/attr/attr_fixed_layout.swift
+++ b/test/attr/attr_fixed_layout.swift
@@ -7,14 +7,14 @@
 // Public types with @_fixed_layout are always fixed layout
 //
 
-// RESILIENCE-ON: struct_decl "Point" interface type='Point.Type' access=public non-resilient
-// RESILIENCE-OFF: struct_decl "Point" interface type='Point.Type' access=public non-resilient
+// RESILIENCE-ON: struct_decl{{.*}}"Point" interface type='Point.Type' access=public non-resilient
+// RESILIENCE-OFF: struct_decl{{.*}}"Point" interface type='Point.Type' access=public non-resilient
 @_fixed_layout public struct Point {
   let x, y: Int
 }
 
-// RESILIENCE-ON: enum_decl "ChooseYourOwnAdventure" interface type='ChooseYourOwnAdventure.Type' access=public non-resilient
-// RESILIENCE-OFF: enum_decl "ChooseYourOwnAdventure" interface type='ChooseYourOwnAdventure.Type' access=public non-resilient
+// RESILIENCE-ON: enum_decl{{.*}}"ChooseYourOwnAdventure" interface type='ChooseYourOwnAdventure.Type' access=public non-resilient
+// RESILIENCE-OFF: enum_decl{{.*}}"ChooseYourOwnAdventure" interface type='ChooseYourOwnAdventure.Type' access=public non-resilient
 @_frozen public enum ChooseYourOwnAdventure {
   case JumpIntoRabbitHole
   case EatMushroom
@@ -24,14 +24,14 @@
 // Public types are resilient when -enable-resilience is on
 //
 
-// RESILIENCE-ON: struct_decl "Size" interface type='Size.Type' access=public resilient
-// RESILIENCE-OFF: struct_decl "Size" interface type='Size.Type' access=public non-resilient
+// RESILIENCE-ON: struct_decl{{.*}}"Size" interface type='Size.Type' access=public resilient
+// RESILIENCE-OFF: struct_decl{{.*}}"Size" interface type='Size.Type' access=public non-resilient
 public struct Size {
   let w, h: Int
 }
 
-// RESILIENCE-ON: enum_decl "TaxCredit" interface type='TaxCredit.Type' access=public resilient
-// RESILIENCE-OFF: enum_decl "TaxCredit" interface type='TaxCredit.Type' access=public non-resilient
+// RESILIENCE-ON: enum_decl{{.*}}"TaxCredit" interface type='TaxCredit.Type' access=public resilient
+// RESILIENCE-OFF: enum_decl{{.*}}"TaxCredit" interface type='TaxCredit.Type' access=public non-resilient
 public enum TaxCredit {
   case EarnedIncome
   case MortgageDeduction
@@ -41,8 +41,8 @@
 // Internal types are always fixed layout
 //
 
-// RESILIENCE-ON: struct_decl "Rectangle" interface type='Rectangle.Type' access=internal non-resilient
-// RESILIENCE-OFF: struct_decl "Rectangle" interface type='Rectangle.Type' access=internal non-resilient
+// RESILIENCE-ON: struct_decl{{.*}}"Rectangle" interface type='Rectangle.Type' access=internal non-resilient
+// RESILIENCE-OFF: struct_decl{{.*}}"Rectangle" interface type='Rectangle.Type' access=internal non-resilient
 struct Rectangle {
   let topLeft: Point
   let bottomRight: Size
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index 86f6b59..0e50ee7 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -2038,14 +2038,14 @@
 }
 
 
-// CHECK-DUMP-LABEL: class_decl "ImplicitClassThrows1"
+// CHECK-DUMP-LABEL: class_decl{{.*}}"ImplicitClassThrows1"
 @objc class ImplicitClassThrows1 {
   // CHECK: @objc func methodReturnsVoid() throws
-  // CHECK-DUMP: func_decl "methodReturnsVoid()"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+  // CHECK-DUMP: func_decl{{.*}}"methodReturnsVoid()"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
   func methodReturnsVoid() throws { }
 
   // CHECK: @objc func methodReturnsObjCClass() throws -> Class_ObjC1
-  // CHECK-DUMP: func_decl "methodReturnsObjCClass()" {{.*}}foreign_error=NilResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>
+  // CHECK-DUMP: func_decl{{.*}}"methodReturnsObjCClass()" {{.*}}foreign_error=NilResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>
   func methodReturnsObjCClass() throws -> Class_ObjC1 {
     return Class_ObjC1()
   }
@@ -2060,11 +2060,11 @@
   func methodReturnsOptionalObjCClass() throws -> Class_ObjC1? { return nil }
 
   // CHECK: @objc func methodWithTrailingClosures(_ s: String, fn1: @escaping ((Int) -> Int), fn2: @escaping (Int) -> Int, fn3: @escaping (Int) -> Int)
-  // CHECK-DUMP: func_decl "methodWithTrailingClosures(_:fn1:fn2:fn3:)"{{.*}}foreign_error=ZeroResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+  // CHECK-DUMP: func_decl{{.*}}"methodWithTrailingClosures(_:fn1:fn2:fn3:)"{{.*}}foreign_error=ZeroResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
   func methodWithTrailingClosures(_ s: String, fn1: (@escaping (Int) -> Int), fn2: @escaping (Int) -> Int, fn3: @escaping (Int) -> Int) throws { }
 
   // CHECK: @objc init(degrees: Double) throws
-  // CHECK-DUMP: constructor_decl "init(degrees:)"{{.*}}foreign_error=NilResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>
+  // CHECK-DUMP: constructor_decl{{.*}}"init(degrees:)"{{.*}}foreign_error=NilResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>
   init(degrees: Double) throws { }
 
   // CHECK: {{^}} func methodReturnsBridgedValueType() throws -> NSRange
@@ -2086,10 +2086,10 @@
   }
 }
 
-// CHECK-DUMP-LABEL: class_decl "SubclassImplicitClassThrows1"
+// CHECK-DUMP-LABEL: class_decl{{.*}}"SubclassImplicitClassThrows1"
 @objc class SubclassImplicitClassThrows1 : ImplicitClassThrows1 {
   // CHECK: @objc override func methodWithTrailingClosures(_ s: String, fn1: @escaping ((Int) -> Int), fn2: @escaping ((Int) -> Int), fn3: @escaping ((Int) -> Int))
-  // CHECK-DUMP: func_decl "methodWithTrailingClosures(_:fn1:fn2:fn3:)"{{.*}}foreign_error=ZeroResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+  // CHECK-DUMP: func_decl{{.*}}"methodWithTrailingClosures(_:fn1:fn2:fn3:)"{{.*}}foreign_error=ZeroResult,unowned,param=1,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
   override func methodWithTrailingClosures(_ s: String, fn1: (@escaping (Int) -> Int), fn2: (@escaping (Int) -> Int), fn3: (@escaping (Int) -> Int)) throws { }
 }
 
@@ -2122,20 +2122,20 @@
 
   @objc(method7) func method7(x: Int) throws { } // expected-error{{@objc' method name provides names for 0 arguments, but method has 2 parameters (including the error parameter)}}
 
-  // CHECK-DUMP: func_decl "method8(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=2,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+  // CHECK-DUMP: func_decl{{.*}}"method8(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=2,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
   @objc(method8:fn1:error:fn2:)
   func method8(_ s: String, fn1: (@escaping (Int) -> Int), fn2: @escaping (Int) -> Int) throws { }
 
-  // CHECK-DUMP: func_decl "method9(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+  // CHECK-DUMP: func_decl{{.*}}"method9(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
   @objc(method9AndReturnError:s:fn1:fn2:)
   func method9(_ s: String, fn1: (@escaping (Int) -> Int), fn2: @escaping (Int) -> Int) throws { }
 }
 
 class SubclassThrowsObjCName : ThrowsObjCName {
-  // CHECK-DUMP: func_decl "method8(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=2,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+  // CHECK-DUMP: func_decl{{.*}}"method8(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=2,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
   override func method8(_ s: String, fn1: (@escaping (Int) -> Int), fn2: @escaping (Int) -> Int) throws { }
 
-  // CHECK-DUMP: func_decl "method9(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
+  // CHECK-DUMP: func_decl{{.*}}"method9(_:fn1:fn2:)"{{.*}}foreign_error=ZeroResult,unowned,param=0,paramtype=Optional<AutoreleasingUnsafeMutablePointer<Optional<NSError>>>,resulttype=ObjCBool
   override func method9(_ s: String, fn1: (@escaping (Int) -> Int), fn2: @escaping (Int) -> Int) throws { }
 }
 
diff --git a/test/decl/protocol/associated_type_overrides.swift b/test/decl/protocol/associated_type_overrides.swift
index 99e8eaf..002d4bf 100644
--- a/test/decl/protocol/associated_type_overrides.swift
+++ b/test/decl/protocol/associated_type_overrides.swift
@@ -4,8 +4,8 @@
   associatedtype A
 }
 
-// CHECK-LABEL: protocol "P2"
-// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P1))
+// CHECK-LABEL: (protocol{{.*}}"P2"
+// CHECK-NEXT: (associated_type_decl{{.*}}"A" {{.*}} overridden=P1))
 protocol P2 : P1 {
   associatedtype A
 }
@@ -14,14 +14,14 @@
   associatedtype A
 }
 
-// CHECK-LABEL: protocol "P4"
-// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P2, P3))
+// CHECK-LABEL: (protocol{{.*}}"P4"
+// CHECK-NEXT: (associated_type_decl{{.*}}"A" {{.*}} overridden=P2, P3))
 protocol P4 : P2, P3 {
   associatedtype A
 }
 
-// CHECK-LABEL: protocol "P5"
-// CHECK-NEXT: (associated_type_decl "A" {{.*}} overridden=P4))
+// CHECK-LABEL: (protocol{{.*}}"P5"
+// CHECK-NEXT: (associated_type_decl{{.*}}"A" {{.*}} overridden=P4))
 protocol P5 : P4, P2 {
   associatedtype A
 }
diff --git a/test/decl/protocol/conforms/nscoding.swift b/test/decl/protocol/conforms/nscoding.swift
index ff9ab0f..a53f9df 100644
--- a/test/decl/protocol/conforms/nscoding.swift
+++ b/test/decl/protocol/conforms/nscoding.swift
@@ -12,7 +12,7 @@
 import Foundation
 
 // Top-level classes
-// CHECK-NOT: class_decl "CodingA"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"CodingA"{{.*}}@_staticInitializeObjCMetadata
 class CodingA : NSObject, NSCoding {
   required init(coder: NSCoder) { }
   func encode(coder: NSCoder) { }
@@ -21,7 +21,7 @@
 
 // Nested classes
 extension CodingA {
-  // CHECK-NOT: class_decl "NestedA"{{.*}}@_staticInitializeObjCMetadata
+  // CHECK-NOT: class_decl{{.*}}"NestedA"{{.*}}@_staticInitializeObjCMetadata
   class NestedA : NSObject, NSCoding { // expected-error{{nested class 'CodingA.NestedA' has an unstable name when archiving via 'NSCoding'}}
     // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{3-3=@objc(_TtCC8nscoding7CodingA7NestedA)}}
     // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{3-3=@objc(<#prefixed Objective-C class name#>)}}
@@ -36,14 +36,14 @@
     func encode(coder: NSCoder) { }
   }
 
-  // CHECK-NOT: class_decl "NestedC"{{.*}}@_staticInitializeObjCMetadata
+  // CHECK-NOT: class_decl{{.*}}"NestedC"{{.*}}@_staticInitializeObjCMetadata
   @objc(CodingA_NestedC)
   class NestedC : NSObject, NSCoding {
     required init(coder: NSCoder) { }
     func encode(coder: NSCoder) { }
   }
 
-  // CHECK-NOT: class_decl "NestedD"{{.*}}@_staticInitializeObjCMetadata
+  // CHECK-NOT: class_decl{{.*}}"NestedD"{{.*}}@_staticInitializeObjCMetadata
   @objc(CodingA_NestedD)
   class NestedD : NSObject {
     required init(coder: NSCoder) { }
@@ -58,7 +58,7 @@
 }
 
 // Generic classes
-// CHECK-NOT: class_decl "CodingB"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"CodingB"{{.*}}@_staticInitializeObjCMetadata
 class CodingB<T> : NSObject, NSCoding {
   required init(coder: NSCoder) { }
   func encode(coder: NSCoder) { }
@@ -72,7 +72,7 @@
 }
 
 // Fileprivate classes.
-// CHECK-NOT: class_decl "CodingC"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"CodingC"{{.*}}@_staticInitializeObjCMetadata
 fileprivate class CodingC : NSObject, NSCoding { // expected-error{{fileprivate class 'CodingC' has an unstable name when archiving via 'NSCoding'}}
   // expected-note@-1{{for compatibility with existing archives, use '@objc' to record the Swift 3 runtime name}}{{1-1=@objc(_TtC8nscodingP33_0B4E7641C0BD1F170280EEDD0D0C1F6C7CodingC)}}
   // expected-note@-2{{for new classes, use '@objc' to specify a unique, prefixed Objective-C runtime name}}{{1-1=@objc(<#prefixed Objective-C class name#>)}}
@@ -99,7 +99,7 @@
 }
 
 // Inherited conformances.
-// CHECK-NOT: class_decl "CodingE"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"CodingE"{{.*}}@_staticInitializeObjCMetadata
 class CodingE<T> : CodingB<T> {
   required init(coder: NSCoder) { super.init(coder: coder) }
   override func encode(coder: NSCoder) { }
@@ -119,24 +119,24 @@
 }
 
 extension CodingB {
-  // CHECK-NOT: class_decl "GenericViaScope"{{.*}}@_staticInitializeObjCMetadata
+  // CHECK-NOT: class_decl{{.*}}"GenericViaScope"{{.*}}@_staticInitializeObjCMetadata
   @objc(GenericViaScope) // expected-error {{generic subclasses of '@objc' classes cannot have an explicit '@objc' because they are not directly visible from Objective-C}}
   class GenericViaScope : NSObject { }
 }
 
 // Inference of @_staticInitializeObjCMetadata.
-// CHECK-NOT: class_decl "SubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"SubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
 class SubclassOfCodingA : CodingA { }
 
-// CHECK: class_decl "SubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
+// CHECK: class_decl{{.*}}"SubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
 class SubclassOfCodingE : CodingE<Int> { }
 
 // Do not warn when simply inheriting from classes that conform to NSCoding.
 // The subclass may never be serialized. But do still infer static
 // initialization, just in case.
-// CHECK-NOT: class_decl "PrivateSubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
+// CHECK-NOT: class_decl{{.*}}"PrivateSubclassOfCodingA"{{.*}}@_staticInitializeObjCMetadata
 private class PrivateSubclassOfCodingA : CodingA { }
-// CHECK: class_decl "PrivateSubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
+// CHECK: class_decl{{.*}}"PrivateSubclassOfCodingE"{{.*}}@_staticInitializeObjCMetadata
 private class PrivateSubclassOfCodingE : CodingE<Int> { }
 
 // But do warn when inherited through a protocol.
diff --git a/test/decl/protocol/conforms/nscoding_availability_osx.swift b/test/decl/protocol/conforms/nscoding_availability_osx.swift
index 91337e7..46ecacb 100644
--- a/test/decl/protocol/conforms/nscoding_availability_osx.swift
+++ b/test/decl/protocol/conforms/nscoding_availability_osx.swift
@@ -17,6 +17,6 @@
 
 @available(OSX 10.51, *)
 class OuterCodingJ {
-  // CHECK-NOT: class_decl "NestedJ"{{.*}}@_staticInitializeObjCMetadata
+  // CHECK-NOT: class_decl{{.*}}"NestedJ"{{.*}}@_staticInitializeObjCMetadata
   class NestedJ : CodingI { }
 }
diff --git a/test/decl/subscript/subscripting.swift b/test/decl/subscript/subscripting.swift
index 294f2a4..d02f414 100644
--- a/test/decl/subscript/subscripting.swift
+++ b/test/decl/subscript/subscripting.swift
@@ -246,33 +246,82 @@
   }
 }
 
+protocol Protocol {}
+protocol RefinedProtocol: Protocol {}
+class SuperClass {}
+class SubClass: SuperClass {}
+class SubSubClass: SubClass {}
+class ClassConformingToProtocol: Protocol {}
+class ClassConformingToRefinedProtocol: RefinedProtocol {}
+
+struct GenSubscriptFixitTest {
+  subscript<T>(_ arg: T) -> Bool { return true } // expected-note {{declared here}}
+}
+
+func testGenSubscriptFixit(_ s0: GenSubscriptFixitTest) {
+
+  _ = s0.subscript("hello")
+  // expected-error@-1 {{value of type 'GenSubscriptFixitTest' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{27-28=]}}
+}
+
 struct SubscriptTest1 {
   subscript(keyword:String) -> Bool { return true }  // expected-note 2 {{found this candidate}}
   subscript(keyword:String) -> String? {return nil }  // expected-note 2 {{found this candidate}}
+
+  subscript(arg: SubClass) -> Bool { return true } // expected-note {{declared here}}
+  subscript(arg: Protocol) -> Bool { return true } // expected-note 2 {{declared here}}
+
+  subscript(arg: (foo: Bool, bar: (Int, baz: SubClass)), arg2: String) -> Bool { return true }
+  // expected-note@-1 2 {{declared here}}
 }
 
 func testSubscript1(_ s1 : SubscriptTest1) {
   let _ : Int = s1["hello"]  // expected-error {{ambiguous subscript with base type 'SubscriptTest1' and index type 'String'}}
-  
+
   if s1["hello"] {}
-  
-  
-  let _ = s1["hello"]  // expected-error {{ambiguous use of 'subscript'}}
+
+  _ = s1.subscript((true, (5, SubClass())), "hello")
+  // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{52-53=]}}
+  _ = s1.subscript((true, (5, baz: SubSubClass())), "hello")
+  // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{60-61=]}}
+  _ = s1.subscript((fo: true, (5, baz: SubClass())), "hello")
+  // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
+  _ = s1.subscript(SubSubClass())
+  // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{33-34=]}}
+  _ = s1.subscript(ClassConformingToProtocol())
+  // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{47-48=]}}
+  _ = s1.subscript(ClassConformingToRefinedProtocol())
+  // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{54-55=]}}
+  _ = s1.subscript(true)
+  // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
+  _ = s1.subscript(SuperClass())
+  // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}}
+  _ = s1.subscript("hello")
+  // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{27-28=]}}
+  _ = s1.subscript("hello"
+  // expected-error@-1 {{value of type 'SubscriptTest1' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{27-27=]}}
+  // expected-note@-2 {{to match this opening '('}}
+
+  let _ = s1["hello"]
+  // expected-error@-1 {{ambiguous use of 'subscript'}}
+  // expected-error@-2 {{expected ')' in expression list}}
 }
 
 struct SubscriptTest2 {
   subscript(a : String, b : Int) -> Int { return 0 }
+  // expected-note@-1 {{declared here}}
   subscript(a : String, b : String) -> Int { return 0 }
 }
 
 func testSubscript1(_ s2 : SubscriptTest2) {
   _ = s2["foo"] // expected-error {{cannot subscript a value of type 'SubscriptTest2' with an index of type 'String'}}
   // expected-note @-1 {{overloads for 'subscript' exist with these partially matching parameter lists: (String, Int), (String, String)}}
-  
+
   let a = s2["foo", 1.0] // expected-error {{cannot subscript a value of type 'SubscriptTest2' with an index of type '(String, Double)'}}
   // expected-note @-1 {{overloads for 'subscript' exist with these partially matching parameter lists: (String, Int), (String, String)}}
-  
-  
+
+  _ = s2.subscript("hello", 6)
+  // expected-error@-1 {{value of type 'SubscriptTest2' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{30-31=]}}
   let b = s2[1, "foo"] // expected-error {{cannot convert value of type 'Int' to expected argument type 'String'}}
 
   // rdar://problem/27449208
@@ -313,9 +362,10 @@
 
 // SR-2575
 struct SR2575 {
-  subscript() -> Int {
+  subscript() -> Int { // expected-note {{declared here}}
     return 1
   }
 }
 
-SR2575().subscript() // expected-error{{type 'SR2575' has no member 'subscript'}}
+SR2575().subscript()
+// expected-error@-1 {{value of type 'SR2575' has no property or method named 'subscript'; did you mean to use the subscript operator?}} {{9-10=}} {{10-19=}} {{19-20=[}} {{20-21=]}}
diff --git a/test/expr/capture/dynamic_self.swift b/test/expr/capture/dynamic_self.swift
index b2c45a2..c37fbf3 100644
--- a/test/expr/capture/dynamic_self.swift
+++ b/test/expr/capture/dynamic_self.swift
@@ -1,6 +1,6 @@
 // RUN: %target-swift-frontend -dump-ast %s 2>&1 | %FileCheck %s
 
-// CHECK: func_decl "clone()" interface type='(Android) -> () -> Self'
+// CHECK: func_decl{{.*}}"clone()" interface type='(Android) -> () -> Self'
 
 class Android {
   func clone() -> Self {
diff --git a/test/expr/capture/generic_params.swift b/test/expr/capture/generic_params.swift
index 27c07cd..ee6590e 100644
--- a/test/expr/capture/generic_params.swift
+++ b/test/expr/capture/generic_params.swift
@@ -2,7 +2,7 @@
 
 func doSomething<T>(_ t: T) {}
 
-// CHECK: func_decl "outerGeneric(t:x:)" <T> interface type='<T> (t: T, x: AnyObject) -> ()'
+// CHECK: func_decl{{.*}}"outerGeneric(t:x:)" <T> interface type='<T> (t: T, x: AnyObject) -> ()'
 
 func outerGeneric<T>(t: T, x: AnyObject) {
   // Simple case -- closure captures outer generic parameter
@@ -20,14 +20,14 @@
 
   // Nested generic functions always capture outer generic parameters, even if
   // they're not mentioned in the function body
-  // CHECK: func_decl "innerGeneric(u:)" <U> interface type='<T, U> (u: U) -> ()' {{.*}} captures=(<generic> )
+  // CHECK: func_decl{{.*}}"innerGeneric(u:)" <U> interface type='<T, U> (u: U) -> ()' {{.*}} captures=(<generic> )
   func innerGeneric<U>(u: U) {}
 
   // Make sure we look through typealiases
   typealias TT = (a: T, b: T)
 
   // FIXME: Losing some type sugar here.
-  // CHECK: func_decl "localFunction(tt:)" interface type='<T> (tt: (a: T, b: T)) -> ()' {{.*}} captures=(<generic> )
+  // CHECK: func_decl{{.*}}"localFunction(tt:)" interface type='<T> (tt: (a: T, b: T)) -> ()' {{.*}} captures=(<generic> )
   func localFunction(tt: TT) {}
 
   // CHECK: closure_expr type='((a: T, b: T)) -> ()' {{.*}} captures=(<generic> )
diff --git a/test/expr/capture/nested.swift b/test/expr/capture/nested.swift
index eee92e2..6d4790a 100644
--- a/test/expr/capture/nested.swift
+++ b/test/expr/capture/nested.swift
@@ -1,6 +1,6 @@
 // RUN: %target-swift-frontend -dump-ast %s 2>&1 | %FileCheck %s
 
-// CHECK: func_decl "foo2(_:)"
+// CHECK: func_decl{{.*}}"foo2(_:)"
 func foo2(_ x: Int) -> (Int) -> (Int) -> Int {
   // CHECK: closure_expr type='(Int) -> (Int) -> Int' {{.*}} discriminator=0 captures=(x)
   return {(bar: Int) -> (Int) -> Int in
diff --git a/test/expr/capture/top-level-guard.swift b/test/expr/capture/top-level-guard.swift
index 45ad1d0..744c896 100644
--- a/test/expr/capture/top-level-guard.swift
+++ b/test/expr/capture/top-level-guard.swift
@@ -15,7 +15,7 @@
 // CHECK: (top_level_code_decl
 _ = 0 // intervening code
 
-// CHECK-LABEL: (func_decl "function()" interface type='() -> ()' access=internal captures=(x<direct>)
+// CHECK-LABEL: (func_decl{{.*}}"function()" interface type='() -> ()' access=internal captures=(x<direct>)
 func function() {
   _ = x
 }
@@ -23,7 +23,7 @@
 // CHECK-LABEL: (closure_expr
 // CHECK: location={{.*}}top-level-guard.swift:[[@LINE+3]]
 // CHECK: captures=(x<direct>)
-// CHECK: (var_decl "closure"
+// CHECK: (var_decl{{.*}}"closure"
 let closure: () -> Void = {
   _ = x
 }
@@ -33,13 +33,13 @@
 // CHECK: (closure_expr
 // CHECK: location={{.*}}top-level-guard.swift:[[@LINE+3]]
 // CHECK: captures=(x)
-// CHECK: (var_decl "closureCapture"
+// CHECK: (var_decl{{.*}}"closureCapture"
 let closureCapture: () -> Void = { [x] in
   _ = x
 }
 
 // CHECK-LABEL: (defer_stmt
-// CHECK-NEXT: (func_decl implicit "$defer()" interface type='() -> ()' access=fileprivate captures=(x<direct><noescape>)
+// CHECK-NEXT: (func_decl{{.*}}implicit "$defer()" interface type='() -> ()' access=fileprivate captures=(x<direct><noescape>)
 defer {
   _ = x
 }
diff --git a/test/expr/primary/literal/collection_upcast_opt.swift b/test/expr/primary/literal/collection_upcast_opt.swift
index d105716..78cb647 100644
--- a/test/expr/primary/literal/collection_upcast_opt.swift
+++ b/test/expr/primary/literal/collection_upcast_opt.swift
@@ -11,7 +11,7 @@
   init(_: [(T) -> Void]) { }
 }
 
-// CHECK-LABEL: func_decl "arrayUpcast(_:_:)"
+// CHECK-LABEL: func_decl{{.*}}"arrayUpcast(_:_:)"
 // CHECK: assign_expr
 // CHECK-NOT: collection_upcast_expr
 // CHECK: array_expr type='[(X) -> Void]'
@@ -27,7 +27,7 @@
   init(_: [Int : (T) -> Void]) { }
 }
 
-// CHECK-LABEL: func_decl "dictionaryUpcast(_:_:)"
+// CHECK-LABEL: func_decl{{.*}}"dictionaryUpcast(_:_:)"
 // CHECK: assign_expr
 // CHECK-NOT: collection_upcast_expr
 // CHECK: paren_expr type='([Int : (X) -> Void])'
diff --git a/test/refactoring/RefactoringKind/basic.swift b/test/refactoring/RefactoringKind/basic.swift
index 436c4f9..e434eeb 100644
--- a/test/refactoring/RefactoringKind/basic.swift
+++ b/test/refactoring/RefactoringKind/basic.swift
@@ -174,21 +174,21 @@
   return "abc"
 }
 
-func testCollapseNestedIf() {
+func testCollapseNestedIf1() {
   let a = 3
   if a > 2 {
     if a < 10 {}
   }
 }
 
-func testMultiConditionalNestedIf() {
+func testCollapseNestedIf2() {
   let a = 3
   if a > 2, a != 4 {
     if a < 10 {}
   }
 }
 
-func testExtraDeclNestedIf() {
+func testCollapseNestedIf3() {
   let a = 3
   if a > 2 {
     if a < 10 {}
@@ -196,11 +196,31 @@
   }
 }
 
-func testExtraIfNestedIf() {
+func testCollapseNestedIf4() {
+  let a = 3
+  if a > 2 {
+    let b = 0
+    if a < 10 {}
+  }
+}
+
+func testCollapseNestedIf5() {
   let a = 3
   if a > 2 {
     if a < 10 {}
-    let b = 0
+  } else {
+    print("else")
+  }
+}
+
+func testCollapseNestedIf6() {
+  let a = 3
+  if a > 2 {
+    if a < 10 {
+      print("if")
+    } else if a < 5 {
+      print("else")
+    }
   }
 }
 
@@ -313,25 +333,27 @@
 
 // RUN: %refactor -source-filename %s -pos=173:3 -end-pos=173:27| %FileCheck %s -check-prefix=CHECK-EXTRCT-METHOD
 
-// RUN: %refactor -source-filename %s -pos=179:3 | %FileCheck %s -check-prefix=CHECK-COLLAPSE-NESTED-IF-EXPRESSION
-// RUN: %refactor -source-filename %s -pos=186:3 | %FileCheck %s -check-prefix=CHECK-COLLAPSE-NESTED-IF-EXPRESSION
+// RUN: %refactor -source-filename %s -pos=179:3 | %FileCheck %s -check-prefix=CHECK-COLLAPSE-NESTED-IF
+// RUN: %refactor -source-filename %s -pos=186:3 | %FileCheck %s -check-prefix=CHECK-COLLAPSE-NESTED-IF
 // RUN: %refactor -source-filename %s -pos=193:3 | %FileCheck %s -check-prefix=CHECK-NONE
 // RUN: %refactor -source-filename %s -pos=201:3 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=209:3 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=218:3 | %FileCheck %s -check-prefix=CHECK-NONE
 
-// RUN: %refactor -source-filename %s -pos=210:11 -end-pos=210:24 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
-// RUN: %refactor -source-filename %s -pos=211:11 -end-pos=211:26 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
-// RUN: %refactor -source-filename %s -pos=212:11 -end-pos=212:21 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
+// RUN: %refactor -source-filename %s -pos=230:11 -end-pos=230:24 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
+// RUN: %refactor -source-filename %s -pos=231:11 -end-pos=231:26 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
+// RUN: %refactor -source-filename %s -pos=232:11 -end-pos=232:21 | %FileCheck %s -check-prefix=CHECK-STRINGS-INTERPOLATION
 
-// RUN: %refactor -source-filename %s -pos=217:11 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
-// RUN: %refactor -source-filename %s -pos=217:12 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
-// RUN: %refactor -source-filename %s -pos=217:13 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
-// RUN: %refactor -source-filename %s -pos=217:14 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
+// RUN: %refactor -source-filename %s -pos=237:11 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
+// RUN: %refactor -source-filename %s -pos=237:12 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
+// RUN: %refactor -source-filename %s -pos=237:13 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
+// RUN: %refactor -source-filename %s -pos=237:14 | %FileCheck %s -check-prefix=CHECK-TRY-CATCH
 
-// RUN: %refactor -source-filename %s -pos=225:3 | %FileCheck %s -check-prefix=CHECK-EXPAND-SWITCH
+// RUN: %refactor -source-filename %s -pos=245:3 | %FileCheck %s -check-prefix=CHECK-EXPAND-SWITCH
 
-// RUN: %refactor -source-filename %s -pos=231:3 -end-pos=231:24 | %FileCheck %s -check-prefix=CHECK-EXPAND-TERNARY-EXPRESSEXPRESSION
+// RUN: %refactor -source-filename %s -pos=251:3 -end-pos=251:24 | %FileCheck %s -check-prefix=CHECK-EXPAND-TERNARY-EXPRESSEXPRESSION
 
-// RUN: %refactor -source-filename %s -pos=237:3 -end-pos=242:4 | %FileCheck %s -check-prefix=CHECK-CONVERT-TO-TERNARY-EXPRESSEXPRESSION
+// RUN: %refactor -source-filename %s -pos=257:3 -end-pos=262:4 | %FileCheck %s -check-prefix=CHECK-CONVERT-TO-TERNARY-EXPRESSEXPRESSION
 
 // CHECK1: Action begins
 // CHECK1-NEXT: Extract Method
@@ -368,7 +390,7 @@
 
 // CHECK-LOCALIZE-STRING: Localize String
 
-// CHECK-COLLAPSE-NESTED-IF-EXPRESSION: Collapse Nested If Expression
+// CHECK-COLLAPSE-NESTED-IF: Collapse Nested If Statements
 
 // CHECK-STRINGS-INTERPOLATION: Convert to String Interpolation
 
diff --git a/test/refactoring/RefactoringKind/extract.swift b/test/refactoring/RefactoringKind/extract.swift
index 1a93f25..f8592c6 100644
--- a/test/refactoring/RefactoringKind/extract.swift
+++ b/test/refactoring/RefactoringKind/extract.swift
@@ -6,6 +6,45 @@
   }
 }
 
+func testIf(bool: Bool) {
+  if bool {
+    print(1)
+  } else {
+    print(1)
+  }
+}
+
+func testDoCatch(canThrow: () throws -> Void) {
+  do {
+    try canThrow()
+  } catch {
+    print(error)
+  }
+}
+
+func testSwitchCase(x: Int) {
+  switch x {
+    case 1:
+      print(1)
+    default:
+      print(2)
+  }
+}
+
+
 // RUN: %refactor -source-filename %s -pos=4:13 -end-pos=6:4 | %FileCheck %s -check-prefix=CHECK-NONE
+
+// RUN: %refactor -source-filename %s -pos=10:11 -end-pos=12:4 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=12:5 -end-pos=14:4 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=12:10 -end-pos=14:4 | %FileCheck %s -check-prefix=CHECK-NONE
+
+// RUN: %refactor -source-filename %s -pos=18:6 -end-pos=20:4 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=20:5 -end-pos=22:4 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=20:11 -end-pos=22:4 | %FileCheck %s -check-prefix=CHECK-NONE
+
+// RUN: %refactor -source-filename %s -pos=26:12 -end-pos=31:4 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=27:5 -end-pos=28:15 | %FileCheck %s -check-prefix=CHECK-NONE
+// RUN: %refactor -source-filename %s -pos=29:5 -end-pos=30:15 | %FileCheck %s -check-prefix=CHECK-NONE
+
 // CHECK-NONE: Action begins
 // CHECK-NONE-NEXT: Action ends
diff --git a/test/stdlib/Casts.swift b/test/stdlib/Casts.swift
index a7e44b9..e713720 100644
--- a/test/stdlib/Casts.swift
+++ b/test/stdlib/Casts.swift
@@ -50,6 +50,26 @@
 
 extension Int : P {}
 
+// Test for SR-7664: Inconsistent optional casting behaviour with generics
+// Runtime failed to unwrap multiple levels of Optional when casting.
+CastsTests.test("Multi-level optionals can be casted") {
+  func testSuccess<From, To>(_ x: From, from: From.Type, to: To.Type) {
+    expectNotNil(x as? To)
+  }
+  func testFailure<From, To>(_ x: From, from: From.Type, to: To.Type) {
+    expectNil(x as? To)
+  }
+  testSuccess(42, from: Int?.self, to: Int.self)
+  testSuccess(42, from: Int??.self, to: Int.self)
+  testSuccess(42, from: Int???.self, to: Int.self)
+  testSuccess(42, from: Int???.self, to: Int?.self)
+  testSuccess(42, from: Int???.self, to: Int??.self)
+  testSuccess(42, from: Int???.self, to: Int???.self)
+  testFailure(42, from: Int?.self, to: String.self)
+  testFailure(42, from: Int??.self, to: String.self)
+  testFailure(42, from: Int???.self, to: String.self)
+}
+
 #if _runtime(_ObjC)
 extension CFBitVector : P {
   static func makeImmutable(from values: Array<UInt8>) -> CFBitVector {
diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp
index 1d5ab13..d8221ce 100644
--- a/tools/swift-api-digester/swift-api-digester.cpp
+++ b/tools/swift-api-digester/swift-api-digester.cpp
@@ -2704,7 +2704,8 @@
 
   bool detectTypeRewritten(SDKNodeType *Node, SDKNodeType *Counter) {
     if (IsVisitingLeft &&
-        (Node->getName() != Counter->getName()||
+        Node->getPrintedName() != Counter->getPrintedName() &&
+        (Node->getName() != Counter->getName() ||
         Node->getChildrenCount() != Counter->getChildrenCount())) {
       Node->annotate(NodeAnnotation::TypeRewritten);
       Node->annotate(NodeAnnotation::TypeRewrittenLeft, Node->getPrintedName());
@@ -2794,6 +2795,8 @@
         R->annotate(HasOptional ?
                     NodeAnnotation::RevertOptionalDictionaryKeyUpdate :
                     NodeAnnotation::RevertDictionaryKeyUpdate);
+        R->annotate(NodeAnnotation::RawTypeLeft, KeyChangedTo);
+        R->annotate(NodeAnnotation::RawTypeRight, Raw);
       }
       return true;
     }
@@ -2843,6 +2846,8 @@
         R->annotate(HasOptional ?
                     NodeAnnotation::RevertOptionalArrayMemberUpdate :
                     NodeAnnotation::RevertArrayMemberUpdate);
+        R->annotate(NodeAnnotation::RawTypeLeft, KeyChangedTo);
+        R->annotate(NodeAnnotation::RawTypeRight, Raw);
       }
       return true;
     }
@@ -2874,6 +2879,8 @@
                     NodeAnnotation::SimpleOptionalStringRepresentableUpdate:
                     NodeAnnotation::SimpleStringRepresentableUpdate);
       } else {
+        R->annotate(NodeAnnotation::RawTypeLeft, KeyChangedTo);
+        R->annotate(NodeAnnotation::RawTypeRight, Raw);
         R->annotate(HasOptional ?
                     NodeAnnotation::RevertSimpleOptionalStringRepresentableUpdate:
                     NodeAnnotation::RevertSimpleStringRepresentableUpdate);
@@ -2987,8 +2994,8 @@
 }
 
 namespace {
-template<typename T>
 
+template<typename T>
 void removeRedundantAndSort(std::vector<T> &Diffs) {
   std::set<T> DiffSet(Diffs.begin(), Diffs.end());
   Diffs.assign(DiffSet.begin(), DiffSet.end());
@@ -2997,7 +3004,6 @@
 
 template<typename T>
 void serializeDiffs(llvm::raw_ostream &Fs, std::vector<T> &Diffs) {
-  removeRedundantAndSort(Diffs);
   if (Diffs.empty())
     return;
   Fs << "\n";
@@ -3052,6 +3058,12 @@
       case NodeAnnotation::OptionalDictionaryKeyUpdate:
       case NodeAnnotation::SimpleStringRepresentableUpdate:
       case NodeAnnotation::SimpleOptionalStringRepresentableUpdate:
+      case NodeAnnotation::RevertArrayMemberUpdate:
+      case NodeAnnotation::RevertOptionalArrayMemberUpdate:
+      case NodeAnnotation::RevertDictionaryKeyUpdate:
+      case NodeAnnotation::RevertOptionalDictionaryKeyUpdate:
+      case NodeAnnotation::RevertSimpleStringRepresentableUpdate:
+      case NodeAnnotation::RevertSimpleOptionalStringRepresentableUpdate:
         return Node->getAnnotateComment(NodeAnnotation::RawTypeLeft);
       case NodeAnnotation::TypeRewritten:
         return Node->getAnnotateComment(NodeAnnotation::TypeRewrittenLeft);
@@ -3070,6 +3082,12 @@
       case NodeAnnotation::OptionalDictionaryKeyUpdate:
       case NodeAnnotation::SimpleStringRepresentableUpdate:
       case NodeAnnotation::SimpleOptionalStringRepresentableUpdate:
+      case NodeAnnotation::RevertArrayMemberUpdate:
+      case NodeAnnotation::RevertOptionalArrayMemberUpdate:
+      case NodeAnnotation::RevertDictionaryKeyUpdate:
+      case NodeAnnotation::RevertOptionalDictionaryKeyUpdate:
+      case NodeAnnotation::RevertSimpleStringRepresentableUpdate:
+      case NodeAnnotation::RevertSimpleOptionalStringRepresentableUpdate:
         return Node->getAnnotateComment(NodeAnnotation::RawTypeRight);
       case NodeAnnotation::TypeRewritten:
         return Node->getAnnotateComment(NodeAnnotation::TypeRewrittenRight);
@@ -3807,6 +3825,22 @@
   RefinementPass.pass(LeftModule, RightModule);
   DiffVector AllItems;
   DiffItemEmitter::collectDiffItems(LeftModule, AllItems);
+
+  auto &AliasMap = Ctx.getTypeAliasUpdateMap();
+  // Find type alias change first.
+  TypeAliasDiffFinder(LeftModule, RightModule, AliasMap).search();
+
+  for (auto Pair: AliasMap) {
+    auto Left = Pair.first->getAs<SDKNodeDeclTypeAlias>()->getUnderlyingType()->
+      getPrintedName();
+    auto Right = AliasMap[(SDKNode*)Pair.first]->getAs<SDKNodeDeclType>()->
+      getRawValueType()->getPrintedName();
+    auto *D = Pair.first->getAs<SDKNodeDecl>();
+    AllItems.emplace_back(SDKNodeKind::DeclTypeAlias,
+      NodeAnnotation::TypeAliasDeclToRawRepresentable, "0",
+      D->getUsr(), "", Left, Right, D->getModuleName());
+  }
+
   AllItems.erase(std::remove_if(AllItems.begin(), AllItems.end(),
                                 [&](CommonDiffItem &Item) {
     return Item.DiffKind == NodeAnnotation::RemovedDecl &&
@@ -3823,6 +3857,10 @@
   auto &typeMemberDiffs = Ctx.getTypeMemberDiffs();
   std::error_code EC;
   llvm::raw_fd_ostream Fs(DiffPath, EC, llvm::sys::fs::F_None);
+  removeRedundantAndSort(AllItems);
+  removeRedundantAndSort(typeMemberDiffs);
+  removeRedundantAndSort(AllNoEscapingFuncs);
+  removeRedundantAndSort(Overloads);
   if (options::OutputInJson) {
     std::vector<APIDiffItem*> TotalItems;
     std::transform(AllItems.begin(), AllItems.end(),
diff --git a/tools/swift-refactor/swift-refactor.cpp b/tools/swift-refactor/swift-refactor.cpp
index eeceb52..6c9f6b6 100644
--- a/tools/swift-refactor/swift-refactor.cpp
+++ b/tools/swift-refactor/swift-refactor.cpp
@@ -41,7 +41,7 @@
                       "expand-switch-cases", "Perform switch cases expand refactoring"),
            clEnumValN(RefactoringKind::LocalizeString,
                       "localize-string", "Perform string localization refactoring"),
-           clEnumValN(RefactoringKind::CollapseNestedIfExpr,
+           clEnumValN(RefactoringKind::CollapseNestedIfStmt,
                       "collapse-nested-if", "Perform collapse nested if statements"),
            clEnumValN(RefactoringKind::ConvertToDoCatch,
                       "convert-to-do-catch", "Perform force try to do try catch refactoring"),
diff --git a/tools/swift-reflection-dump/swift-reflection-dump.cpp b/tools/swift-reflection-dump/swift-reflection-dump.cpp
index 8827e50..fea516d 100644
--- a/tools/swift-reflection-dump/swift-reflection-dump.cpp
+++ b/tools/swift-reflection-dump/swift-reflection-dump.cpp
@@ -122,17 +122,17 @@
 
 static ReflectionInfo findReflectionInfo(const ObjectFile *objectFile) {
   auto fieldSection = findReflectionSection<FieldSection>(
-      objectFile, {"__swift4_fieldmd", ".swift4_fieldmd", "swift4_fieldmd"});
+      objectFile, {"__swift5_fieldmd", ".swift5_fieldmd", "swift5_fieldmd"});
   auto associatedTypeSection = findReflectionSection<AssociatedTypeSection>(
-      objectFile, {"__swift4_assocty", ".swift4_assocty", "swift4_assocty"});
+      objectFile, {"__swift5_assocty", ".swift5_assocty", "swift5_assocty"});
   auto builtinTypeSection = findReflectionSection<BuiltinTypeSection>(
-      objectFile, {"__swift4_builtin", ".swift4_builtin", "swift4_builtin"});
+      objectFile, {"__swift5_builtin", ".swift5_builtin", "swift5_builtin"});
   auto captureSection = findReflectionSection<CaptureSection>(
-      objectFile, {"__swift4_capture", ".swift4_capture", "swift4_capture"});
+      objectFile, {"__swift5_capture", ".swift5_capture", "swift5_capture"});
   auto typeRefSection = findReflectionSection<GenericSection>(
-      objectFile, {"__swift4_typeref", ".swift4_typeref", "swift4_typeref"});
+      objectFile, {"__swift5_typeref", ".swift5_typeref", "swift5_typeref"});
   auto reflectionStringsSection = findReflectionSection<GenericSection>(
-      objectFile, {"__swift4_reflstr", ".swift4_reflstr", "swift4_reflstr"});
+      objectFile, {"__swift5_reflstr", ".swift5_reflstr", "swift5_reflstr"});
 
   // The entire object file is mapped into this process's memory, so the
   // local/remote mapping is identity.
diff --git a/unittests/runtime/CMakeLists.txt b/unittests/runtime/CMakeLists.txt
index 653486d..69a1c3f 100644
--- a/unittests/runtime/CMakeLists.txt
+++ b/unittests/runtime/CMakeLists.txt
@@ -35,6 +35,7 @@
   add_swift_unittest(SwiftRuntimeTests
     Array.cpp
     CompatibilityOverride.cpp
+    Concurrent.cpp
     Exclusivity.cpp
     Metadata.cpp
     Mutex.cpp
diff --git a/unittests/runtime/Concurrent.cpp b/unittests/runtime/Concurrent.cpp
new file mode 100644
index 0000000..3f78805
--- /dev/null
+++ b/unittests/runtime/Concurrent.cpp
@@ -0,0 +1,44 @@
+//===--- Concurrent.cpp - Concurrent data structure tests -----------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#include "swift/Runtime/Concurrent.h"
+#include "gtest/gtest.h"
+
+using namespace swift;
+
+TEST(ConcurrentReadableArrayTest, SingleThreaded) {
+  ConcurrentReadableArray<size_t> array;
+  
+  auto add = [&](size_t limit) {
+    for (size_t i = array.snapshot().count(); i < limit; i++)
+      array.push_back(i);
+  };
+  auto check = [&]{
+    size_t i = 0;
+    for (auto element : array.snapshot()) {
+      ASSERT_EQ(element, i);
+      i++;
+    }
+  };
+  
+  check();
+  add(1);
+  check();
+  add(16);
+  check();
+  add(100);
+  check();
+  add(1000);
+  check();
+  add(1000000);
+  check();
+}
diff --git a/unittests/runtime/Metadata.cpp b/unittests/runtime/Metadata.cpp
index c77c203..60d2419 100644
--- a/unittests/runtime/Metadata.cpp
+++ b/unittests/runtime/Metadata.cpp
@@ -507,7 +507,7 @@
       EXPECT_EQ(5 * sizeof(void*), ex1->getValueWitnesses()->getSize());
       EXPECT_EQ(alignof(void*), ex1->getValueWitnesses()->getAlignment());
       EXPECT_FALSE(ex1->getValueWitnesses()->isPOD());
-      EXPECT_FALSE(ex1->getValueWitnesses()->isBitwiseTakable());
+      EXPECT_TRUE(ex1->getValueWitnesses()->isBitwiseTakable());
       EXPECT_EQ(nullptr,
                 ex1->getSuperclassConstraint());
       return ex1;
@@ -525,7 +525,7 @@
       EXPECT_EQ(6 * sizeof(void*), ex2->getValueWitnesses()->getSize());
       EXPECT_EQ(alignof(void*), ex2->getValueWitnesses()->getAlignment());
       EXPECT_FALSE(ex2->getValueWitnesses()->isPOD());
-      EXPECT_FALSE(ex2->getValueWitnesses()->isBitwiseTakable());
+      EXPECT_TRUE(ex2->getValueWitnesses()->isBitwiseTakable());
       EXPECT_EQ(nullptr,
                 ex2->getSuperclassConstraint());
       return ex2;
@@ -543,7 +543,7 @@
       EXPECT_EQ(7 * sizeof(void*), ex3->getValueWitnesses()->getSize());
       EXPECT_EQ(alignof(void*), ex3->getValueWitnesses()->getAlignment());
       EXPECT_FALSE(ex3->getValueWitnesses()->isPOD());
-      EXPECT_FALSE(ex3->getValueWitnesses()->isBitwiseTakable());
+      EXPECT_TRUE(ex3->getValueWitnesses()->isBitwiseTakable());
       EXPECT_EQ(nullptr,
                 ex3->getSuperclassConstraint());
       return ex3;
@@ -658,48 +658,6 @@
                                    ValueWitnessTable *vwtable);
 } // namespace swift
 
-
-TEST(MetadataTest, installCommonValueWitnesses_pod_indirect) {
-  ValueWitnessTable testTable;
-  FullMetadata<Metadata> testMetadata{{&testTable}, {MetadataKind::Opaque}};
-
-  // rdar://problem/21375421 - pod_indirect_initializeBufferWithTakeOfBuffer
-  // should move ownership of a fixed-size buffer.
-
-  testTable.size = sizeof(ValueBuffer) + 1;
-  testTable.flags = ValueWitnessFlags()
-    .withAlignment(alignof(ValueBuffer))
-    .withPOD(true)
-    .withBitwiseTakable(true)
-    .withInlineStorage(false);
-  testTable.stride = sizeof(ValueBuffer) + alignof(ValueBuffer);
-
-  installCommonValueWitnesses(*testTable.getTypeLayout(), &testTable);
-
-  // Replace allocateBuffer and destroyBuffer with logging versions.
-  struct {
-    ValueBuffer buffer;
-    uintptr_t canary;
-  } buf1{{}, 0x5A5A5A5AU}, buf2{{}, 0xA5A5A5A5U};
-  testMetadata.allocateBoxForExistentialIn(&buf1.buffer);
-
-  testTable.initializeBufferWithTakeOfBuffer(&buf2.buffer, &buf1.buffer,
-                                             &testMetadata);
-
-  // The existential's box reference should be copied.
-  EXPECT_EQ(buf1.buffer.PrivateData[0], buf2.buffer.PrivateData[0]);
-
-  // Ownership of the box should have been transferred.
-  auto *reference = reinterpret_cast<HeapObject *>(buf2.buffer.PrivateData[0]);
-  EXPECT_TRUE(swift_isUniquelyReferencedOrPinned_nonNull_native(reference));
-
-  EXPECT_EQ(buf1.canary, (uintptr_t)0x5A5A5A5AU);
-  EXPECT_EQ(buf2.canary, (uintptr_t)0xA5A5A5A5U);
-
-  // Release the buffer.
-  swift_release(reference);
-}
-
 // We cannot construct RelativeDirectPointer instances, so define
 // a "shadow" struct for that purpose
 struct GenericWitnessTableStorage {
diff --git a/utils/cmpcodesize/cmpcodesize/compare.py b/utils/cmpcodesize/cmpcodesize/compare.py
index 598b353..51ea7d7 100644
--- a/utils/cmpcodesize/cmpcodesize/compare.py
+++ b/utils/cmpcodesize/cmpcodesize/compare.py
@@ -232,7 +232,7 @@
         compare_sizes(old_sizes, new_sizes, "__objc_const", section_title,
                       csv=csv)
         compare_sizes(old_sizes, new_sizes, "__data", section_title, csv=csv)
-        compare_sizes(old_sizes, new_sizes, "__swift4_proto", section_title,
+        compare_sizes(old_sizes, new_sizes, "__swift5_proto", section_title,
                       csv=csv)
         compare_sizes(old_sizes, new_sizes, "__common", section_title, csv=csv)
         compare_sizes(old_sizes, new_sizes, "__bss", section_title, csv=csv)
diff --git a/validation-test/Evolution/Inputs/bitwise_takable.swift b/validation-test/Evolution/Inputs/bitwise_takable.swift
new file mode 100644
index 0000000..35381eb
--- /dev/null
+++ b/validation-test/Evolution/Inputs/bitwise_takable.swift
@@ -0,0 +1,73 @@
+public protocol Reporter  {
+  func report() -> String;
+}
+public class Subject {
+  public var value = 1
+  public init(_ v: Int) {
+    value = v
+  }
+}
+public var s2 = Subject(2)
+public var s3 = Subject(3)
+public var s4 = Subject(4)
+public var s5 = Subject(5)
+
+public struct Container : Reporter {
+#if BEFORE
+  public var v : Subject
+#else
+  weak public var v : Subject?
+#endif
+  public init(_ s: Subject) {
+    v = s
+  }
+
+  public func report() -> String{
+#if BEFORE
+    return "Container(\(v.value))"
+#else
+    return "Container(\(v!.value))"
+#endif
+  }
+}
+public func createContainerReporter() -> Reporter {
+  return Container(s2)
+}
+
+public struct PairContainer: Reporter {
+  public var pair : (Container, Container)
+
+  public init(_ p : (Container, Container)) {
+    pair = p
+  }
+
+  public func report() -> String {
+    return "PairContainer(\(pair.0.report()), \(pair.1.report()))"
+  }
+}
+
+public func createPairContainerReporter() -> Reporter {
+  return PairContainer((Container(s3), Container(s4)))
+}
+
+public enum EnumContainer : Reporter {
+  case Empty
+  case Some(Container)
+
+  public func report() -> String {
+    switch self {
+      case .Empty:
+         return "EnumContainer Empty"
+      case .Some(let c):
+        return "EnumContainer(\(c.report()))"
+    }
+  }
+}
+
+public func createEnumContainerReporter() -> Reporter {
+  return EnumContainer.Some(Container(s5))
+}
+
+public func report(_ r: Reporter) -> String {
+  return r.report()
+}
diff --git a/validation-test/Evolution/test_bitwise_takable.swift b/validation-test/Evolution/test_bitwise_takable.swift
new file mode 100644
index 0000000..638e000
--- /dev/null
+++ b/validation-test/Evolution/test_bitwise_takable.swift
@@ -0,0 +1,29 @@
+// RUN: %target-resilience-test
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import bitwise_takable
+
+
+var BitwiseTakable = TestSuite("BitwiseTakable")
+
+BitwiseTakable.test("test") {
+  let c = createContainerReporter()
+  expectEqual("Container(2)", c.report())
+  let p = createPairContainerReporter()
+  expectEqual("PairContainer(Container(3), Container(4))", p.report())
+  let e = createEnumContainerReporter()
+  expectEqual("EnumContainer(Container(5))", e.report())
+
+  let r : Reporter = Container(s2)
+  expectEqual("Container(2)", report(r))
+
+  let r2 : Reporter = PairContainer((Container(s3), Container(s4)))
+  expectEqual("PairContainer(Container(3), Container(4))", report(r2))
+
+  let r3 : Reporter = EnumContainer.Some(Container(s5))
+  expectEqual("EnumContainer(Container(5))", report(r3))
+
+}
+
+runAllTests()
diff --git a/validation-test/Sema/type_checker_perf/fast/rdar40344044.swift.gyb b/validation-test/Sema/type_checker_perf/fast/rdar40344044.swift.gyb
new file mode 100644
index 0000000..6fcc704
--- /dev/null
+++ b/validation-test/Sema/type_checker_perf/fast/rdar40344044.swift.gyb
@@ -0,0 +1,23 @@
+// RUN: %scale-test --begin 3 --end 20  --step 1 --select incrementScopeCounter %s
+// REQUIRES: OS=macosx
+// REQUIRES: asserts
+
+protocol P {}
+class C : P {}
+class D : P {}
+
+class Test {
+  let c: C! = C()
+  let d: D! = D()
+  var a: [P]! = []
+
+  func test() {
+    a = [
+      c,
+%for i in range(0, N):
+      c,
+%end
+      d
+    ]
+  }
+}