Merge pull request #11193 from xwu/lossless-integers

[stdlib] Conform fixed-width integer types to LosslessStringConvertible
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 26f4590..c0306cc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -783,7 +783,7 @@
 endif()
 
 # Set the CMAKE_OSX_* variables in a way that minimizes conflicts.
-if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING)
   set(CMAKE_OSX_SYSROOT "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_PATH}")
   set(CMAKE_OSX_ARCHITECTURES "")
   set(CMAKE_OSX_DEPLOYMENT_TARGET "")
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 9dad070..9cceaff 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -1553,9 +1553,17 @@
         endif()
 
         # Add PrivateFrameworks, rdar://28466433
+        set(swiftlib_link_flags_all ${SWIFTLIB_LINK_FLAGS})
         if(SWIFTLIB_IS_SDK_OVERLAY)
           list(APPEND swiftlib_swift_compile_flags_all "-Fsystem" "${SWIFT_SDK_${sdk}_PATH}/System/Library/PrivateFrameworks/")
         endif()
+       
+       if("${sdk}" STREQUAL "IOS_SIMULATOR")
+         if("${name}" STREQUAL "swiftMediaPlayer")
+           message("DISABLING AUTOLINK FOR swiftMediaPlayer")
+           list(APPEND swiftlib_link_flags_all "-Xlinker" "-ignore_auto_link")
+         endif()
+       endif()
 
         # Add this library variant.
         _add_swift_library_single(
@@ -1576,7 +1584,7 @@
           FILE_DEPENDS ${SWIFTLIB_FILE_DEPENDS} ${swiftlib_module_dependency_targets}
           C_COMPILE_FLAGS ${SWIFTLIB_C_COMPILE_FLAGS}
           SWIFT_COMPILE_FLAGS ${swiftlib_swift_compile_flags_all}
-          LINK_FLAGS ${SWIFTLIB_LINK_FLAGS}
+          LINK_FLAGS ${swiftlib_link_flags_all}
           PRIVATE_LINK_LIBRARIES ${swiftlib_private_link_libraries_targets}
           INCORPORATE_OBJECT_LIBRARIES ${SWIFTLIB_INCORPORATE_OBJECT_LIBRARIES}
           INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY ${SWIFTLIB_INCORPORATE_OBJECT_LIBRARIES_SHARED_ONLY}
diff --git a/cmake/modules/AddSwiftTableGen.cmake b/cmake/modules/AddSwiftTableGen.cmake
index d8d80f0..4b7e3e0 100644
--- a/cmake/modules/AddSwiftTableGen.cmake
+++ b/cmake/modules/AddSwiftTableGen.cmake
@@ -3,7 +3,7 @@
 # This needs to be a macro since tablegen (which is a function) needs to set
 # variables in its parent scope.
 macro(swift_tablegen)
-  tablegen(SWIFT ${ARGN})
+  tablegen(LLVM ${ARGN})
 endmacro()
 
 # This needs to be a macro since add_public_tablegen_target (which is a
diff --git a/cmake/modules/SwiftSharedCMakeConfig.cmake b/cmake/modules/SwiftSharedCMakeConfig.cmake
index 1c38d21..2dc78ba 100644
--- a/cmake/modules/SwiftSharedCMakeConfig.cmake
+++ b/cmake/modules/SwiftSharedCMakeConfig.cmake
@@ -68,9 +68,9 @@
     set(${product}_NATIVE_LLVM_TOOLS_PATH "${LLVM_TOOLS_BINARY_DIR}")
   endif()
 
-  find_program(SWIFT_TABLEGEN_EXE "llvm-tblgen" "${${product}_NATIVE_LLVM_TOOLS_PATH}"
+  find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" "${${product}_NATIVE_LLVM_TOOLS_PATH}"
     NO_DEFAULT_PATH)
-  if ("${SWIFT_TABLEGEN_EXE}" STREQUAL "SWIFT_TABLEGEN_EXE-NOTFOUND")
+  if ("${LLVM_TABLEGEN_EXE}" STREQUAL "LLVM_TABLEGEN_EXE-NOTFOUND")
     message(FATAL_ERROR "Failed to find tablegen in ${${product}_NATIVE_LLVM_TOOLS_PATH}")
   endif()
 
@@ -219,7 +219,6 @@
   set(${product}_NATIVE_LLVM_TOOLS_PATH "${CMAKE_BINARY_DIR}/bin")
   set(${product}_NATIVE_CLANG_TOOLS_PATH "${CMAKE_BINARY_DIR}/bin")
   set(LLVM_PACKAGE_VERSION ${PACKAGE_VERSION})
-  set(SWIFT_TABLEGEN_EXE llvm-tblgen)
   set(LLVM_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake/modules")
 
   # If cmark was checked out into tools/cmark, expect to build it as
diff --git a/docs/ABIStabilityManifesto.md b/docs/ABIStabilityManifesto.md
index 01b6e47..6985aa4 100644
--- a/docs/ABIStabilityManifesto.md
+++ b/docs/ABIStabilityManifesto.md
@@ -8,10 +8,13 @@
 
 One of the top priorities for Swift right now is compatibility across future Swift versions. Compatibility aims at accomplishing two goals:
 
-1. *Source compatibility* means that newer compilers can compile code written in an older version of Swift. This aims to reduce the migration pain that Swift developers face when migrating to a newer Swift version. Without source compatibility, projects face version-lock where all source code in a project and its packages must be written in the same version of Swift. With source compatibility, package authors will be able to maintain a single code base across multiple Swift versions while allowing their users to use a newer version of Swift.
-2. *Binary framework & runtime compatibility* enables the distribution of frameworks in a binary form that works across multiple Swift versions. Binary frameworks include both a *Swift module file*, which communicates source-level information of the framework's API, and a *shared library*, which provides the compiled implementation that is loaded at runtime. Thus, there are two necessary goals for binary framework compatibility:
-    * *Module format stability* stabilizes the module file, which is the compiler's representation of the public interfaces of a framework. This includes API declarations and inlineable code. The module file is used by the compiler for necessary tasks such as type checking and code generation when compiling client code using a framework.
-    * *ABI stability* enables binary compatibility between applications and libraries compiled with different Swift versions. It is the focus of the rest of this document.
+1. **Source compatibility** means that newer compilers can compile code written in an older version of Swift. This aims to reduce the migration pain that Swift developers face when migrating to a newer Swift version. Without source compatibility, projects face version-lock where all source code in a project and its packages must be written in the same version of Swift. With source compatibility, package authors will be able to maintain a single code base across multiple Swift versions while allowing their users to use a newer version of Swift.
+
+2. **Binary framework & runtime compatibility** enables the distribution of frameworks in a binary form that works across multiple Swift versions. Binary frameworks include both a *Swift module file*, which communicates source-level information of the framework's API, and a *shared library*, which provides the compiled implementation that is loaded at runtime. Thus, there are two necessary goals for binary framework compatibility:
+
+    * **Module format stability** stabilizes the module file, which is the compiler's representation of the public interfaces of a framework. This includes API declarations and inlineable code. The module file is used by the compiler for necessary tasks such as type checking and code generation when compiling client code using a framework.
+
+    * **ABI stability** enables binary compatibility between applications and libraries compiled with different Swift versions. It is the focus of the rest of this document.
 
 This document is an exploration and explanation of Swift's ABI alongside the goals and investigations needed before declaring Swift's ABI stable. It is meant to be a resource to the community as well as a declaration of the direction of Swift's ABI.
 
diff --git a/docs/OwnershipManifesto.md b/docs/OwnershipManifesto.md
index fc3065b..ea75767 100644
--- a/docs/OwnershipManifesto.md
+++ b/docs/OwnershipManifesto.md
@@ -1574,6 +1574,8 @@
   - DI enforcement
   - `moveonly` contexts
 
+### Priorities for ABI stability
+
 The single most important goal for the upcoming releases is
 ABI stability.  The prioritization and analysis of these
 features must center around their impact on the ABI.  With
diff --git a/include/swift/AST/DiagnosticsParse.def b/include/swift/AST/DiagnosticsParse.def
index 9f46521..f648036 100644
--- a/include/swift/AST/DiagnosticsParse.def
+++ b/include/swift/AST/DiagnosticsParse.def
@@ -142,6 +142,8 @@
       "should match %select{space|tab}0 here", (unsigned))
 NOTE(lex_multiline_string_indent_change_line,none,
       "change indentation of %select{this line|these lines}0 to match closing delimiter", (bool))
+ERROR(lex_escaped_newline_at_lastline,none,
+      "escaped newline at the last line is not allowed", ())
 
 ERROR(lex_invalid_character,none,
        "invalid character in source file", ())
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 85c9c27..cc677b0c 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -1378,6 +1378,14 @@
 ERROR(types_not_equal,none,
       "%0 requires the types %1 and %2 be equivalent",
       (Type, Type, Type))
+NOTE(candidate_types_equal_requirement,none,
+     "candidate requires that the types %0 and %1 be equivalent "
+     "(requirement specified as %2 == %3%4)",
+     (Type, Type, Type, Type, StringRef))
+NOTE(candidate_types_inheritance_requirement,none,
+     "candidate requires that %1 inherit from %2 "
+     "(requirement specified as %2 : %3%4)",
+     (Type, Type, Type, Type, StringRef))
 NOTE(types_not_equal_requirement,none,
      "requirement specified as %0 == %1%2", (Type, Type, StringRef))
 ERROR(non_class_cannot_conform_to_class_protocol,none,
@@ -1668,8 +1676,6 @@
       (Type))
 ERROR(recursive_type_reference,none,
       "%0 %1 references itself", (DescriptiveDeclKind, Identifier))
-ERROR(recursive_requirement_reference,none,
-      "type may not reference itself as a requirement",())
 ERROR(recursive_same_type_constraint,none,
       "same-type constraint %0 == %1 is recursive", (Type, Type))
 ERROR(recursive_superclass_constraint,none,
diff --git a/include/swift/AST/GenericSignatureBuilder.h b/include/swift/AST/GenericSignatureBuilder.h
index c2ade71..f426f7d 100644
--- a/include/swift/AST/GenericSignatureBuilder.h
+++ b/include/swift/AST/GenericSignatureBuilder.h
@@ -89,6 +89,7 @@
 
   using UnresolvedType = llvm::PointerUnion<PotentialArchetype *, Type>;
   struct ResolvedType;
+  class ResolveResult;
 
   using RequirementRHS =
       llvm::PointerUnion3<Type, PotentialArchetype *, LayoutConstraint>;
@@ -174,6 +175,10 @@
     /// only the derived same-type constraints in the graph.
     std::vector<DerivedSameTypeComponent> derivedSameTypeComponents;
 
+    /// Delayed requirements that could be resolved by a change to this
+    /// equivalence class.
+    std::vector<DelayedRequirement> delayedRequirements;
+
     /// Whether we have detected recursion during the substitution of
     /// the concrete type.
     unsigned recursiveConcreteType : 1;
@@ -189,6 +194,9 @@
     /// potential archetype (which represents itself).
     EquivalenceClass(PotentialArchetype *representative);
 
+    /// Note that this equivalence class has been modified.
+    void modified(GenericSignatureBuilder &builder);
+
     /// Find a source of the same-type constraint that maps a potential
     /// archetype in this equivalence class to a concrete type along with
     /// that concrete type as written.
@@ -252,9 +260,9 @@
     /// "resolved" at this point.
     GenerateConstraints = 0,
 
-    /// Do not generate a new constraint; rather, return
-    /// \c ConstraintResult::Unresolved and let the caller handle it.
-    ReturnUnresolved = 1,
+    /// Generate an unresolved constraint but still return
+    /// \c ConstraintResult::Unresolved so the caller knows what happened.
+    GenerateUnresolved = 1,
   };
 
 private:
@@ -280,6 +288,7 @@
                                    UnresolvedType lhs,
                                    RequirementRHS rhs,
                                    FloatingRequirementSource source,
+                                   EquivalenceClass *unresolvedEquivClass,
                                    UnresolvedHandlingKind unresolvedHandling);
 
   /// Resolve the conformance of the given potential archetype to
@@ -417,10 +426,6 @@
   template<typename F>
   void visitPotentialArchetypes(F f);
 
-  void markPotentialArchetypeRecursive(PotentialArchetype *pa,
-                                       ProtocolDecl *proto,
-                                       const RequirementSource *source);
-
 public:
   /// Construct a new generic signature builder.
   ///
@@ -559,9 +564,6 @@
   void processDelayedRequirements();
 
 private:
-  /// Bump the generation count due to a change.
-  void bumpGeneration();
-
   /// Describes the relationship between a given constraint and
   /// the canonical constraint of the equivalence class.
   enum class ConstraintRelation {
@@ -658,6 +660,21 @@
                             ArrayRef<GenericTypeParamType *> genericParams,
                             PotentialArchetype *pa);
 
+  /// \brief Resolve the given type to the potential archetype it names.
+  ///
+  /// The \c resolutionKind parameter describes how resolution should be
+  /// performed. If the potential archetype named by the given dependent type
+  /// already exists, it will be always returned. If it doesn't exist yet,
+  /// the \c resolutionKind dictates whether the potential archetype will
+  /// be created or whether null will be returned.
+  ///
+  /// For any type that cannot refer to an archetype, this routine returns the
+  /// equivalence class that would have to change to make the potential
+  /// archetype resolvable.
+  llvm::PointerUnion<PotentialArchetype *, EquivalenceClass *>
+  resolvePotentialArchetype(Type type,
+                            ArchetypeResolutionKind resolutionKind);
+
 public:
   /// \brief Resolve the given type to the potential archetype it names.
   ///
@@ -676,9 +693,9 @@
   /// If successful, this returns either a non-typealias potential archetype
   /// or a Type, if \c type is concrete.
   /// If the type cannot be resolved, e.g., because it is "too" recursive
-  /// given the source, returns \c None.
-  Optional<ResolvedType> resolve(UnresolvedType type,
-                                 FloatingRequirementSource source);
+  /// given the source, returns an unresolved result containing the equivalence
+  /// class that would need to change to resolve this type.
+  ResolveResult resolve(UnresolvedType type, FloatingRequirementSource source);
 
   /// \brief Dump all of the requirements, both specified and inferred.
   LLVM_ATTRIBUTE_DEPRECATED(
@@ -1079,11 +1096,17 @@
   bool isSelfDerivedSource(PotentialArchetype *pa,
                            bool &derivedViaConcrete) const;
 
-  /// Determine whether a requirement \c pa: proto, when formed from this
-  /// requirement source, is dependent on itself.
-  bool isSelfDerivedConformance(PotentialArchetype *pa,
-                                ProtocolDecl *proto,
-                                bool &derivedViaConcrete) const;
+  /// For a requirement source that describes the requirement \c pa:proto,
+  /// retrieve the minimal subpath of this requirement source that will
+  /// compute that requirement.
+  ///
+  /// When the result is different from (i.e., a subpath of) \c this or is
+  /// nullptr (indicating an embedded, distinct self-derived subpath), the
+  /// conformance requirement is considered to be "self-derived".
+  const RequirementSource *getMinimalConformanceSource(
+                                            PotentialArchetype *pa,
+                                            ProtocolDecl *proto,
+                                            bool &derivedViaConcrete) const;
 
   /// Retrieve a source location that corresponds to the requirement.
   SourceLoc getLoc() const;
@@ -1337,23 +1360,20 @@
   /// that share a name.
   llvm::MapVector<Identifier, StoredNestedType> NestedTypes;
 
-  /// \brief Recursively conforms to itself.
-  unsigned IsRecursive : 1;
-
   /// \brief Construct a new potential archetype for an unresolved
   /// associated type.
   PotentialArchetype(PotentialArchetype *parent, Identifier name);
 
   /// \brief Construct a new potential archetype for an associated type.
   PotentialArchetype(PotentialArchetype *parent, AssociatedTypeDecl *assocType)
-    : parentOrBuilder(parent), identifier(assocType), IsRecursive(false)
+    : parentOrBuilder(parent), identifier(assocType)
   {
     assert(parent != nullptr && "Not an associated type?");
   }
 
   /// \brief Construct a new potential archetype for a concrete declaration.
   PotentialArchetype(PotentialArchetype *parent, TypeDecl *concreteDecl)
-    : parentOrBuilder(parent), identifier(concreteDecl), IsRecursive(false)
+    : parentOrBuilder(parent), identifier(concreteDecl)
   {
     assert(parent != nullptr && "Not an associated type?");
   }
@@ -1361,8 +1381,7 @@
   /// \brief Construct a new potential archetype for a generic parameter.
   PotentialArchetype(GenericSignatureBuilder *builder,
                      GenericParamKey genericParam)
-    : parentOrBuilder(builder), identifier(genericParam),
-      IsRecursive(false)
+    : parentOrBuilder(builder), identifier(genericParam)
   {
   }
 
@@ -1605,9 +1624,6 @@
     return Type();
   }
 
-  void setIsRecursive() { IsRecursive = true; }
-  bool isRecursive() const { return IsRecursive; }
-
   LLVM_ATTRIBUTE_DEPRECATED(
       void dump() const,
       "only for use within the debugger");
diff --git a/include/swift/Basic/ExternalUnion.h b/include/swift/Basic/ExternalUnion.h
index 3c07c29..d8b1544 100644
--- a/include/swift/Basic/ExternalUnion.h
+++ b/include/swift/Basic/ExternalUnion.h
@@ -29,20 +29,10 @@
 
 namespace swift {
 
-template <size_t... Values>
-struct static_max;
+namespace ExternalUnionImpl {
 
-template <size_t Value>
-struct static_max<Value> {
-  static const size_t value = Value;
-};
-
-template <size_t Head, size_t... Tail>
-struct static_max<Head, Tail...> {
-  static const size_t value =
-    (Head > static_max<Tail...>::value ? Head : static_max<Tail...>::value);
-};
-
+/// A helper class for finding the index of a type in a parameter pack.
+/// 'indexOf<T, List...>::value' will either be the index or -1.
 template <class T, class... Members>
 struct indexOf;
 
@@ -61,31 +51,75 @@
      indexInTail != -1 ? indexInTail + 1 : -1);
 };
 
+/// A helper class for deriving information and rule-of-five operations
+/// for the storage of a union.
 template <class... Members>
-struct SpecialMembers;
+struct MembersHelper;
 
-/// An external union whose discriminator is just a position in
-/// the template arguments.
+} // end namespace ExternalUnionImpl
+
+/// A class used to define the list of member types which need to be
+/// stored in an ExternalUnion.  As a special case, you may use 'void'
+/// to indicate that an empty state is required in the union.
+template <class... Members>
+struct ExternalUnionMembers {
+  // (private to the implementation)
+  using Info = ExternalUnionImpl::MembersHelper<Members...>;
+
+  /// The type of indices into the union member type list.
+  enum Index : unsigned {};
+
+  /// Return the index for the given type, asserting that it is a member
+  /// of the list.
+  template <class T>
+  static constexpr Index indexOf() {
+    static_assert(ExternalUnionImpl::indexOf<T, Members...>::value != -1,
+                  "type not registered in union");
+    return Index(ExternalUnionImpl::indexOf<T, Members...>::value);
+  }
+
+  /// Return the index for the given type or -1 if it is not a member
+  /// of the list.  If it is not -1, it may be safely converted to an Index.
+  template <class T>
+  static constexpr int maybeIndexOf() {
+    return ExternalUnionImpl::indexOf<T, Members...>::value;
+  }
+};
+
+/// An external union that uses the member-list index as the user-facing
+/// discriminator kind.
+///
+/// This type can be used directly, but it's generally better to use
+/// ExternalUnion instead.  If nothing else, it's not a good idea to
+/// cement the assumption that you won't have two cases that need the
+/// same storage.
 ///
 /// The external union itself is a trivial type, and it is the
 /// responsibility of the client to call the "special member functions"
 /// at the appropriate time.
-template <class... Members>
+template <class Members>
 class BasicExternalUnion {
+
   /// The value storage.
-  LLVM_ALIGNAS(static_max<alignof(Members)...>::value)
-  char Storage[static_max<sizeof(Members)...>::value];
+  LLVM_ALIGNAS(Members::Info::alignment)
+  char Storage[Members::Info::size];
+
+  template <class T>
+  static constexpr int maybeIndexOfMember() {
+    return Members::template maybeIndexOf<T>();
+  }
 
 public:
   enum : bool {
-    union_is_trivially_copyable =
-      SpecialMembers<Members...>::is_trivially_copyable
+    union_is_trivially_copyable = Members::Info::is_trivially_copyable
   };
 
+  using Index = typename Members::Index;
+
   /// Construct a union member in-place.
   template <class T, class... Args>
   T &emplaceWithoutIndex(Args &&... args) {
-    constexpr int typeIndex = indexOf<T, Members...>::value;
+    constexpr int typeIndex = maybeIndexOfMember<T>();
     static_assert(typeIndex != -1, "type not in union");
 
     return *(::new ((void*) &Storage) T(std::forward<Args>(args)...));
@@ -93,10 +127,10 @@
 
   /// Construct a union member in-place.
   template <class T, class... Args>
-  T &emplace(int index, Args &&... args) {
-    constexpr int typeIndex = indexOf<T, Members...>::value;
+  T &emplace(Index index, Args &&... args) {
+    constexpr int typeIndex = maybeIndexOfMember<T>();
     static_assert(typeIndex != -1, "type not in union");
-    assert(index == typeIndex && "current kind is wrong for value");
+    assert(index == Index(typeIndex) && "current kind is wrong for value");
 
     return *(::new ((void*) &Storage) T(std::forward<Args>(args)...));
   }
@@ -104,7 +138,7 @@
   /// Construct a union member in-place using list-initialization ({}).
   template <class T, class... Args>
   T &emplaceAggregateWithoutIndex(Args &&... args) {
-    constexpr int typeIndex = indexOf<T, Members...>::value;
+    constexpr int typeIndex = maybeIndexOfMember<T>();
     static_assert(typeIndex != -1, "type not in union");
 
     return *(::new ((void*) &Storage) T{std::forward<Args>(args)...});
@@ -112,10 +146,10 @@
 
   /// Construct a union member in-place using list-initialization ({}).
   template <class T, class... Args>
-  T &emplaceAggregate(int index, Args &&... args) {
-    constexpr int typeIndex = indexOf<T, Members...>::value;
+  T &emplaceAggregate(Index index, Args &&... args) {
+    constexpr int typeIndex = maybeIndexOfMember<T>();
     static_assert(typeIndex != -1, "type not in union");
-    assert(index == typeIndex && "current kind is wrong for value");
+    assert(index == Index(typeIndex) && "current kind is wrong for value");
 
     return *(::new ((void*) &Storage) T{std::forward<Args>(args)...});
   }
@@ -123,7 +157,7 @@
   /// Return a reference to a union member.
   template <class T>
   T &getWithoutIndex() {
-    constexpr int typeIndex = indexOf<T, Members...>::value;
+    constexpr int typeIndex = maybeIndexOfMember<T>();
     static_assert(typeIndex != -1, "type not in union");
 
     return reinterpret_cast<T &>(Storage);
@@ -132,7 +166,7 @@
   /// Return a reference to a union member.
   template <class T>
   const T &getWithoutIndex() const {
-    constexpr int typeIndex = indexOf<T, Members...>::value;
+    constexpr int typeIndex = maybeIndexOfMember<T>();
     static_assert(typeIndex != -1, "type not in union");
 
     return reinterpret_cast<const T &>(Storage);
@@ -141,10 +175,10 @@
   /// Return a reference to a union member, asserting that the current
   /// kind matches the type being extracted.
   template <class T>
-  T &get(int index) {
-    constexpr int typeIndex = indexOf<T, Members...>::value;
+  T &get(Index index) {
+    constexpr int typeIndex = maybeIndexOfMember<T>();
     static_assert(typeIndex != -1, "type not in union");
-    assert(index == typeIndex && "current kind is wrong for access");
+    assert(index == Index(typeIndex) && "current kind is wrong for access");
 
     return reinterpret_cast<T &>(Storage);
   }
@@ -152,10 +186,10 @@
   /// Return a reference to a union member, asserting that the current
   /// kind matches the type being extracted.
   template <class T>
-  const T &get(int index) const {
-    constexpr int typeIndex = indexOf<T, Members...>::value;
+  const T &get(Index index) const {
+    constexpr int typeIndex = maybeIndexOfMember<T>();
     static_assert(typeIndex != -1, "type not in union");
-    assert(index == typeIndex && "current kind is wrong for access");
+    assert(index == Index(typeIndex) && "current kind is wrong for access");
 
     return reinterpret_cast<const T &>(Storage);
   }
@@ -163,7 +197,7 @@
   /// Destruct the current union member.
   template <class T>
   void resetToEmptyWithoutIndex() {
-    constexpr int typeIndex = indexOf<T, Members...>::value;
+    constexpr int typeIndex = maybeIndexOfMember<T>();
     static_assert(typeIndex != -1, "type not in union");
 
     reinterpret_cast<T&>(Storage).T::~T();
@@ -171,39 +205,35 @@
 
   /// Destroy the current union member.
   template <class T>
-  void resetToEmpty(int oldIndex, int newIndex) {
-    constexpr int typeIndex = indexOf<T, Members...>::value;
+  void resetToEmpty(Index oldIndex, Index newIndex) {
+    constexpr int typeIndex = maybeIndexOfMember<T>();
     static_assert(typeIndex != -1, "type not in union");
-    assert(oldIndex == typeIndex && "current kind is wrong for value");
-    assert(newIndex == -1 && "new kind is not in union");
+    constexpr int voidTypeIndex = maybeIndexOfMember<void>();
+    static_assert(voidTypeIndex != -1, "union has not empty storage");
+    assert(oldIndex == Index(typeIndex) && "current kind is wrong for value");
+    assert(newIndex == Index(voidTypeIndex) && "new kind is not in union");
 
     reinterpret_cast<T&>(Storage).T::~T();
   }
 
   /// Copy-construct the union from another union.
-  void copyConstruct(int index, const BasicExternalUnion &other) {
-    if (index != -1) {
-      SpecialMembers<Members...>::copyConstruct(Storage, index, other.Storage);
-    }
+  void copyConstruct(Index index, const BasicExternalUnion &other) {
+    Members::Info::copyConstruct(Storage, unsigned(index), other.Storage);
   }
 
   /// Move-construct the union from another union.
-  void moveConstruct(int index, BasicExternalUnion &&other) {
-    if (index != -1) {
-      SpecialMembers<Members...>::moveConstruct(Storage, index, other.Storage);
-    }
+  void moveConstruct(Index index, BasicExternalUnion &&other) {
+    Members::Info::moveConstruct(Storage, unsigned(index), other.Storage);
   }
 
   /// Copy-assign the union from another union.
-  void copyAssign(int thisIndex, int otherIndex,
+  void copyAssign(Index thisIndex, Index otherIndex,
                   const BasicExternalUnion &other) {
     if (this == &other) {
       // do nothing
     } else if (thisIndex == otherIndex) {
-      if (thisIndex != -1) {
-        SpecialMembers<Members...>::copyAssignSame(thisIndex, Storage,
-                                                   other.Storage);  
-      }
+      Members::Info::copyAssignSame(unsigned(thisIndex),
+                                    Storage, other.Storage);
     } else {
       destruct(thisIndex, Storage);
       copyConstruct(otherIndex, other);
@@ -211,15 +241,13 @@
   }
 
   /// Move-assign the union from another union.
-  void moveAssign(int thisIndex, int otherIndex,
+  void moveAssign(Index thisIndex, Index otherIndex,
                   BasicExternalUnion &&other) {
     assert(this != &other && "move-constructing value into itself?");
 
     if (thisIndex == otherIndex) {
-      if (thisIndex != -1) {
-        SpecialMembers<Members...>::moveAssignSame(thisIndex, Storage,
-                                                   other.Storage);  
-      }
+      Members::Info::moveAssignSame(unsigned(thisIndex),
+                                    Storage, other.Storage);
     } else {
       destruct(thisIndex);
       moveConstruct(otherIndex, std::move(other));
@@ -227,10 +255,8 @@
   }
 
   /// Destroy the union from another union.
-  void destruct(int index) {
-    if (index != -1) {
-      SpecialMembers<Members...>::destruct(index, Storage);
-    }    
+  void destruct(Index index) {
+    Members::Info::destruct(unsigned(index), Storage);
   }
 };
 
@@ -238,11 +264,26 @@
 /// whose members are not necessarily 1-1 with the members of the union.
 ///
 /// Clients must provide a function which translates the kind type
-/// into an index into the union's Members list, or -1 for kind values
-/// which do not require data in the union.
-template <class Kind, int (&GetIndexForKind)(Kind), class... Members>
+/// into an index into the union's members list.  The expected pattern
+/// here is something like this:
+///
+///   using Members = ExternalUnionMembers<void, int, std::string>;
+///   static Members::Index getIndexForKind(Kind kind) {
+///     switch (kind) {
+///     case Kind::Nothing: return Members::indexOf<void>();
+///     case Kind::Happy: return Members::indexOf<int>();
+///     case Kind::Sad: return Members::indexOf<int>();
+///     case Kind::Funny: return Members::indexOf<std::string>();
+///     case Kind::Angry: return Members::indexOf<std::string>();
+///     }
+///     llvm_unreachable("bad kind");
+///   }
+///   ExternalUnion<Kind, Members, getIndexForKind> Storage;
+///
+template <class Kind, class Members,
+          typename Members::Index (&GetIndexForKind)(Kind)>
 class ExternalUnion {
-  BasicExternalUnion<Members...> Union;
+  BasicExternalUnion<Members> Union;
 
 public:
   enum : bool {
@@ -334,93 +375,183 @@
   }
 };
 
-/// A helper class for defining special members.
+namespace ExternalUnionImpl {
+
+/// The MembersHelper base case.
 template <>
-struct SpecialMembers<> {
+struct MembersHelper<> {
   enum : bool {
     is_trivially_copyable = true
   };
 
-  LLVM_ATTRIBUTE_ALWAYS_INLINE
-  static void copyConstruct(void *self, int index, const void *other) {
-    llvm_unreachable("bad index");
-  }
-
-  LLVM_ATTRIBUTE_ALWAYS_INLINE
-  static void moveConstruct(void *self, int index, void *other) {
-    llvm_unreachable("bad index");
-  }
-
-  LLVM_ATTRIBUTE_ALWAYS_INLINE
-  static void copyAssignSame(int index, void *self, const void *other) {
-    llvm_unreachable("bad index");
-  }
-
-  LLVM_ATTRIBUTE_ALWAYS_INLINE
-  static void moveAssignSame(int index, void *self, void *other) {
-    llvm_unreachable("bad index");
-  }
-
-  LLVM_ATTRIBUTE_ALWAYS_INLINE
-  static void destruct(int index, void *self) {
-    llvm_unreachable("bad index");
-  }
-};
-
-template <class T, class... Others>
-struct SpecialMembers<T, Others...> {
-  enum : bool {
-    is_trivially_copyable =
-      IsTriviallyCopyable<T>::value &&
-      SpecialMembers<Others...>::is_trivially_copyable
+  enum : size_t {
+    size = 1,
+    alignment = 1
   };
 
   LLVM_ATTRIBUTE_ALWAYS_INLINE
   static void copyConstruct(void *self, int index, const void *other) {
-    if (index == 0) {
-      ::new (self) T(*static_cast<const T *>(other));
-    } else {
-      SpecialMembers<Others...>::copyConstruct(self, index - 1, other);
-    }
+    llvm_unreachable("bad index");
   }
 
   LLVM_ATTRIBUTE_ALWAYS_INLINE
   static void moveConstruct(void *self, int index, void *other) {
-    if (index == 0) {
-      ::new (self) T(std::move(*static_cast<T *>(other)));
-    } else {
-      SpecialMembers<Others...>::moveConstruct(self, index - 1, other);
-    }
+    llvm_unreachable("bad index");
   }
 
   LLVM_ATTRIBUTE_ALWAYS_INLINE
   static void copyAssignSame(int index, void *self, const void *other) {
-    if (index == 0) {
-      *static_cast<T*>(self) = *static_cast<const T *>(other);
-    } else {
-      SpecialMembers<Others...>::copyAssignSame(index - 1, self, other);
-    }
+    llvm_unreachable("bad index");
   }
 
   LLVM_ATTRIBUTE_ALWAYS_INLINE
   static void moveAssignSame(int index, void *self, void *other) {
+    llvm_unreachable("bad index");
+  }
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void destruct(int index, void *self) {
+    llvm_unreachable("bad index");
+  }
+};
+
+template <class T>
+struct UnionMemberInfo;
+
+/// The  helper class for defining special members.
+template <class H, class... T>
+struct MembersHelper<H, T...> {
+private:
+  using Member = UnionMemberInfo<H>;
+  using Others = MembersHelper<T...>;
+
+public:
+  enum : bool {
+    is_trivially_copyable =
+      Member::is_trivially_copyable && Others::is_trivially_copyable
+  };
+
+  enum : size_t {
+    size = Member::size > Others::size
+         ? Member::size : Others::size,
+    alignment = Member::alignment > Others::alignment
+              ? Member::alignment : Others::alignment
+  };
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void copyConstruct(void *self, unsigned index, const void *other) {
     if (index == 0) {
-      *static_cast<T*>(self) = std::move(*static_cast<T *>(other));
+      Member::copyConstruct(self, other);
     } else {
-      SpecialMembers<Others...>::moveAssignSame(index - 1, self, other);
+      Others::copyConstruct(self, index - 1, other);
+    }
+  }
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void moveConstruct(void *self, unsigned index, void *other) {
+    if (index == 0) {
+      Member::moveConstruct(self, other);
+    } else {
+      Others::moveConstruct(self, index - 1, other);
+    }
+  }
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void copyAssignSame(unsigned index, void *self, const void *other) {
+    if (index == 0) {
+      Member::copyAssignSame(self, other);
+    } else {
+      Others::copyAssignSame(index - 1, self, other);
+    }
+  }
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void moveAssignSame(unsigned index, void *self, void *other) {
+    if (index == 0) {
+      Member::moveAssignSame(self, other);
+    } else {
+      Others::moveAssignSame(index - 1, self, other);
     }
   }
 
   LLVM_ATTRIBUTE_ALWAYS_INLINE
   static void destruct(int index, void *self) {
     if (index == 0) {
-      static_cast<T*>(self)->T::~T();
+      Member::destruct(self);
     } else {
-      SpecialMembers<Others...>::destruct(index - 1, self);
+      Others::destruct(index - 1, self);
     }
   }
 };
 
+/// The standard implementation of UnionMemberInfo.
+template <class T>
+struct UnionMemberInfo {
+  enum : bool {
+    is_trivially_copyable = IsTriviallyCopyable<T>::value
+  };
+
+  enum : size_t {
+    size = sizeof(T),
+    alignment = alignof(T)
+  };
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void copyConstruct(void *self, const void *other) {
+    ::new (self) T(*static_cast<const T *>(other));
+  }
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void moveConstruct(void *self, void *other) {
+    ::new (self) T(std::move(*static_cast<T *>(other)));
+  }
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void copyAssignSame(void *self, const void *other) {
+    *static_cast<T*>(self) = *static_cast<const T *>(other);
+  }
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void moveAssignSame(void *self, void *other) {
+    *static_cast<T*>(self) = std::move(*static_cast<T *>(other));
+  }
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void destruct(void *self) {
+    static_cast<T*>(self)->T::~T();
+  }
+};
+
+/// An explicit specialization of UnionMemberInfo for 'void', which
+/// represents the empty state.
+template <>
+struct UnionMemberInfo<void> {
+  enum : bool {
+    is_trivially_copyable = true
+  };
+
+  enum : size_t {
+    size = 0,
+    alignment = 1
+  };
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void copyConstruct(void *self, const void *other) {}
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void moveConstruct(void *self, void *other) {}
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void copyAssignSame(void *self, const void *other) {}
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void moveAssignSame(void *self, void *other) {}
+
+  LLVM_ATTRIBUTE_ALWAYS_INLINE
+  static void destruct(void *self) {}
+};
+
+} // end namespace ExternalUnionImpl
 } // end namespace swift
 
 #endif // SWIFT_BASIC_CLUSTEREDBITVECTOR_H
diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h
index 8462866..bbb9b5e 100644
--- a/include/swift/Basic/LangOptions.h
+++ b/include/swift/Basic/LangOptions.h
@@ -210,9 +210,6 @@
     /// Should we use \c ASTScope-based resolution for unqualified name lookup?
     bool EnableASTScopeLookup = false;
 
-    /// Enable SE-0157: Recursive Protocol Constraints.
-    bool EnableRecursiveConstraints = false;
-
     /// Whether to use the import as member inference system
     ///
     /// When importing a global, try to infer whether we can import it as a
diff --git a/include/swift/ClangImporter/ClangImporterOptions.h b/include/swift/ClangImporter/ClangImporterOptions.h
index b3da68c..9084770 100644
--- a/include/swift/ClangImporter/ClangImporterOptions.h
+++ b/include/swift/ClangImporter/ClangImporterOptions.h
@@ -47,6 +47,10 @@
   /// header, place it in this directory.
   std::string PrecompiledHeaderOutputDir;
 
+  /// The optimizaton setting.  This doesn't typically matter for
+  /// import, but it can affect Clang's IR generation of static functions.
+  std::string Optimization;
+
   /// Disable validating the persistent PCH.
   bool PCHDisableValidation = false;
 
diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h
index c3b9857..f7d9774 100644
--- a/include/swift/Frontend/FrontendOptions.h
+++ b/include/swift/Frontend/FrontendOptions.h
@@ -179,6 +179,7 @@
     EmitSIL, ///< Emit canonical SIL
 
     EmitModuleOnly, ///< Emit module only
+    MergeModules, ///< Merge modules only
 
     EmitSIBGen, ///< Emit serialized AST + raw SIL
     EmitSIB, ///< Emit serialized AST + canonical SIL
diff --git a/include/swift/IDE/SyntaxModel.h b/include/swift/IDE/SyntaxModel.h
index b181b1c..a8de327 100644
--- a/include/swift/IDE/SyntaxModel.h
+++ b/include/swift/IDE/SyntaxModel.h
@@ -92,6 +92,7 @@
   ClassVariable,
   EnumCase,
   EnumElement,
+  TypeAlias,
 
   ForEachStatement,
   ForStatement,
diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td
index 4f102c6f4..8e9d1ba 100644
--- a/include/swift/Option/FrontendOptions.td
+++ b/include/swift/Option/FrontendOptions.td
@@ -40,6 +40,10 @@
   : Separate<["-"], "emit-module-doc-path">, MetaVarName<"<path>">,
     HelpText<"Output module documentation file <path>">;
 
+def merge_modules
+  : Flag<["-"], "merge-modules">, ModeOpt,
+    HelpText<"Merge the input modules without otherwise processing them">;
+
 def emit_dependencies_path
   : Separate<["-"], "emit-dependencies-path">, MetaVarName<"<path>">,
     HelpText<"Output basic Make-compatible dependencies file to <path>">;
@@ -109,9 +113,6 @@
 def enable_astscope_lookup : Flag<["-"], "enable-astscope-lookup">,
   HelpText<"Enable ASTScope-based unqualified name lookup">;
 
-def enable_recursive_constraints : Flag<["-"], "enable-recursive-constraints">,
-  HelpText<"Enable SE-0157: Recursive Protocol Constraints">;
-
 def print_clang_stats : Flag<["-"], "print-clang-stats">,
   HelpText<"Print Clang importer statistics">;
 
diff --git a/include/swift/Runtime/RuntimeFunctions.def b/include/swift/Runtime/RuntimeFunctions.def
index 3f2815b..bb65bb5 100644
--- a/include/swift/Runtime/RuntimeFunctions.def
+++ b/include/swift/Runtime/RuntimeFunctions.def
@@ -1000,7 +1000,7 @@
          RETURNS(Int1Ty),
          ARGS(OpaquePtrTy, OpaquePtrTy, TypeMetadataPtrTy, TypeMetadataPtrTy,
               SizeTy),
-         ATTRS(NoUnwind, ReadOnly))
+         ATTRS(ZExt, NoUnwind))
 
 // type* swift_dynamicCastTypeToObjCProtocolUnconditional(type* object,
 //                                               size_t numProtocols,
@@ -1064,14 +1064,14 @@
          swift_isClassType, DefaultCC,
          RETURNS(Int1Ty),
          ARGS(TypeMetadataPtrTy),
-         ATTRS(NoUnwind, ReadNone))
+         ATTRS(ZExt, NoUnwind, ReadNone))
 
 // bool swift_isOptionalType(type*);
 FUNCTION(IsOptionalType,
          swift_isOptionalType, DefaultCC,
          RETURNS(Int1Ty),
          ARGS(TypeMetadataPtrTy),
-         ATTRS(NoUnwind, ReadNone))
+         ATTRS(ZExt, NoUnwind, ReadNone))
 
 // void swift_once(swift_once_t *predicate,
 //                 void (*function_code)(RefCounted*),
diff --git a/include/swift/SIL/SILFunction.h b/include/swift/SIL/SILFunction.h
index e5b2dc1..71e3c17 100644
--- a/include/swift/SIL/SILFunction.h
+++ b/include/swift/SIL/SILFunction.h
@@ -671,7 +671,17 @@
                           return isa<ThrowInst>(TI);
                         });
   }
-    
+
+  /// Loop over all blocks in this function and add all function exiting blocks
+  /// to output.
+  void findExitingBlocks(llvm::SmallVectorImpl<SILBasicBlock *> &output) const {
+    for (auto &Block : const_cast<SILFunction &>(*this)) {
+      if (Block.getTerminator()->isFunctionExiting()) {
+        output.emplace_back(&Block);
+      }
+    }
+  }
+
   //===--------------------------------------------------------------------===//
   // Argument Helper Methods
   //===--------------------------------------------------------------------===//
diff --git a/include/swift/SIL/SILInstruction.h b/include/swift/SIL/SILInstruction.h
index f5d07aa..b04e96c 100644
--- a/include/swift/SIL/SILInstruction.h
+++ b/include/swift/SIL/SILInstruction.h
@@ -1057,7 +1057,7 @@
   
 public:
   /// The operand number of the first argument.
-  static unsigned getArgumentOperandNumber() { return 1; }
+  static unsigned getArgumentOperandNumber() { return NumStaticOperands; }
 
   SILValue getCallee() const { return Operands[Callee].get(); }
 
@@ -1115,8 +1115,6 @@
     return {getSubstitutionsStorage(), NumSubstitutions};
   }
 
-  static unsigned getOperandIndexOfFirstArgument() { return NumStaticOperands; }
-
   /// The arguments passed to this instruction.
   MutableArrayRef<Operand> getArgumentOperands() {
     return Operands.getDynamicAsArray().slice(0, getNumCallArguments());
@@ -6444,7 +6442,7 @@
   }
 
   unsigned getOperandIndexOfFirstArgument() {
-    FOREACH_IMPL_RETURN(getOperandIndexOfFirstArgument());
+    FOREACH_IMPL_RETURN(getArgumentOperandNumber());
   }
 
 #undef FOREACH_IMPL_RETURN
@@ -6482,7 +6480,7 @@
 
   // Translate the index of the argument to the full apply or partial_apply into
   // to the corresponding index into the arguments of the called function.
-  unsigned getCalleeArgIndex(Operand &oper) {
+  unsigned getCalleeArgIndex(const Operand &oper) {
     assert(oper.getUser() == Inst);
     assert(oper.getOperandNumber() >= getOperandIndexOfFirstArgument());
 
diff --git a/include/swift/Syntax/RawSyntax.h b/include/swift/Syntax/RawSyntax.h
index edd65ba..d5ea0fb 100644
--- a/include/swift/Syntax/RawSyntax.h
+++ b/include/swift/Syntax/RawSyntax.h
@@ -46,7 +46,7 @@
 #define syntax_assert_child_kind(Raw, Cursor, ExpectedKind)                    \
   (assert(Raw->getChild(Cursor)->Kind == ExpectedKind));
 #else
-#define syntax_assert_child_kind(Raw, Cursor, Kind) ({});
+#define syntax_assert_child_kind(Raw, Cursor, ExpectedKind) ({});
 #endif
 
 #ifndef NDEBUG
@@ -66,7 +66,7 @@
     }                                                                          \
   })
 #else
-#define syntax_assert_child_token(Raw, Cursor, ...) ({});
+#define syntax_assert_child_token(Raw, CursorName, ...) ({});
 #endif
 
 #ifndef NDEBUG
@@ -87,7 +87,7 @@
     }                                                                          \
   })
 #else
-#define syntax_assert_child_token_text(Raw, Cursor, TokenKind, Text) ({});
+#define syntax_assert_child_token_text(Raw, CursorName, TokenKind, ...) ({});
 #endif
 
 #ifndef NDEBUG
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 04bf012..716c14b 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2704,7 +2704,16 @@
     if (!eltTy) continue;
     
     properties |= eltTy->getRecursiveProperties();
-    hasInOut |= Elt.getParameterFlags().isInOut();
+    // Recur into paren types and canonicalized paren types.  'inout' in nested
+    // non-paren tuples are malformed and will be diagnosed later.
+    if (auto *TTy = Elt.getType()->getAs<TupleType>()) {
+      if (TTy->getNumElements() == 1)
+        hasInOut |= TTy->hasInOutElement();
+    } else if (auto *Pty = dyn_cast<ParenType>(Elt.getType().getPointer())) {
+      hasInOut |= Pty->getParameterFlags().isInOut();
+    } else {
+      hasInOut |= Elt.getParameterFlags().isInOut();
+    }
   }
 
   auto arena = getArena(properties);
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 630fb7f..010b22f 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -296,6 +296,17 @@
   // If it's not a derived requirement, it's not self-derived.
   if (!isDerivedRequirement()) return false;
 
+  /// Keep track of all of the protocol requirements we've seen along the way.
+  /// If we see the same requirement twice, we have a self-derived source.
+  llvm::DenseSet<std::pair<PotentialArchetype *, ProtocolDecl *>>
+    constraintsSeen;
+
+  // Note that we've now seen a new conformance constraint, returning true if
+  // we've seen it before.
+  auto addConstraint = [&](PotentialArchetype *pa, ProtocolDecl *proto) {
+    return !constraintsSeen.insert({pa->getRepresentative(), proto}).second;
+  };
+
   return visitPotentialArchetypesAlongPath(
            [&](PotentialArchetype *currentPA, const RequirementSource *source) {
     switch (source->kind) {
@@ -319,7 +330,8 @@
       // Note whether we saw derivation through a concrete type.
       if (currentPA->isConcreteType())
         derivedViaConcrete = true;
-      return false;
+
+      return addConstraint(currentPA, source->getProtocolDecl());
 
     case RequirementSource::NestedTypeNameMatch:
     case RequirementSource::Concrete:
@@ -391,12 +403,12 @@
   return selfPA;
 }
 
-bool RequirementSource::isSelfDerivedConformance(
+const RequirementSource *RequirementSource::getMinimalConformanceSource(
                                              PotentialArchetype *currentPA,
                                              ProtocolDecl *proto,
                                              bool &derivedViaConcrete) const {
   /// Keep track of all of the requirements we've seen along the way. If
-  /// we see the same requirement twice, it's a self-derived conformance.
+  /// we see the same requirement twice, we have found a shorter path.
   llvm::DenseSet<std::pair<PotentialArchetype *, ProtocolDecl *>>
     constraintsSeen;
 
@@ -413,17 +425,13 @@
   bool sawProtocolRequirement = false;
 
   PotentialArchetype *rootPA = nullptr;
+  const RequirementSource *minimalSource = nullptr;
   auto resultPA = visitPotentialArchetypesAlongPath(
                     [&](PotentialArchetype *parentPA,
                         const RequirementSource *source) {
     switch (source->kind) {
     case ProtocolRequirement:
     case InferredProtocolRequirement: {
-      // For a requirement signature, we ignore the 'Self: P' requirement
-      // for the purposes of the self-derived check.
-      if (source->parent->kind == RequirementSource::RequirementSignatureSelf)
-        return false;
-
       // Note that we've seen a protocol requirement.
       sawProtocolRequirement = true;
 
@@ -432,8 +440,14 @@
         derivedViaConcrete = true;
 
       // The parent potential archetype must conform to the protocol in which
-      // this requirement resides.
-      return addConstraint(parentPA, source->getProtocolDecl());
+      // this requirement resides. Add this constraint.
+      if (!addConstraint(parentPA, source->getProtocolDecl())) return false;
+
+      // We found the shortest source to derive this information; record it
+      // and stop the algorithm.
+      if (source->getProtocolDecl() == proto)
+        minimalSource = source->parent;
+      return true;
     }
 
     case Concrete:
@@ -452,21 +466,21 @@
   });
 
   // If we saw a constraint twice, it's self-derived.
-  if (!resultPA) return true;
+  if (!resultPA) return minimalSource;
 
   // If we haven't seen a protocol requirement, we're done.
-  if (!sawProtocolRequirement) return false;
+  if (!sawProtocolRequirement) return this;
 
   // The root archetype might be a nested type, which implies constraints
   // for each of the protocols of the associated types referenced (if any).
   for (auto pa = rootPA; pa->getParent(); pa = pa->getParent()) {
     if (auto assocType = pa->getResolvedAssociatedType()) {
       if (addConstraint(pa->getParent(), assocType->getProtocol()))
-        return true;
+        return nullptr;
     }
   }
 
-  return false;
+  return this;
 }
 
 #define REQUIREMENT_SOURCE_FACTORY_BODY(ProfileArgs, ConstructorArgs,      \
@@ -1249,29 +1263,37 @@
                                    UnresolvedType lhs,
                                    RequirementRHS rhs,
                                    FloatingRequirementSource source,
+                                   EquivalenceClass *unresolvedEquivClass,
                                    UnresolvedHandlingKind unresolvedHandling) {
-  switch (unresolvedHandling) {
-  case UnresolvedHandlingKind::GenerateConstraints: {
-    DelayedRequirement::Kind delayedKind;
-    switch (kind) {
-    case RequirementKind::Conformance:
-    case RequirementKind::Superclass:
-      delayedKind = DelayedRequirement::Type;
-      break;
+  // Record the delayed requirement.
+  DelayedRequirement::Kind delayedKind;
+  switch (kind) {
+  case RequirementKind::Conformance:
+  case RequirementKind::Superclass:
+    delayedKind = DelayedRequirement::Type;
+    break;
 
-    case RequirementKind::Layout:
-      delayedKind = DelayedRequirement::Layout;
-      break;
+  case RequirementKind::Layout:
+    delayedKind = DelayedRequirement::Layout;
+    break;
 
-    case RequirementKind::SameType:
-      delayedKind = DelayedRequirement::SameType;
-      break;
-    }
-    Impl->DelayedRequirements.push_back({delayedKind, lhs, rhs, source});
-    return ConstraintResult::Resolved;
+  case RequirementKind::SameType:
+    delayedKind = DelayedRequirement::SameType;
+    break;
   }
 
-  case UnresolvedHandlingKind::ReturnUnresolved:
+  if (unresolvedEquivClass) {
+    unresolvedEquivClass->delayedRequirements.push_back(
+                                          {delayedKind, lhs, rhs, source});
+  } else {
+    Impl->DelayedRequirements.push_back({delayedKind, lhs, rhs, source});
+  }
+
+  switch (unresolvedHandling) {
+  case UnresolvedHandlingKind::GenerateConstraints:
+    return ConstraintResult::Resolved;
+
+  case UnresolvedHandlingKind::GenerateUnresolved:
     return ConstraintResult::Unresolved;
   }
 }
@@ -1372,6 +1394,46 @@
   bool isType() const { return paOrT.is<Type>(); }
 };
 
+class GenericSignatureBuilder::ResolveResult {
+  union {
+    ResolvedType type;
+    EquivalenceClass *equivClass;
+  };
+
+  const bool resolved;
+
+public:
+  /// Form a resolved result with the given type.
+  ResolveResult(ResolvedType type) : resolved(true) {
+    this->type = type;
+  }
+
+  /// Form an unresolved result dependent on the given equivalence class.
+  ResolveResult(EquivalenceClass *equivClass) : resolved(false) {
+    this->equivClass = equivClass;
+  }
+
+  /// Determine whether this result was resolved.
+  explicit operator bool() const { return resolved; }
+
+  /// Retrieve the resolved result.
+  ResolvedType operator*() const {
+    assert(*this);
+    return type;
+  }
+
+  const ResolvedType *operator->() const {
+    assert(*this);
+    return &type;
+  }
+
+  /// Retrieve the unresolved result.
+  EquivalenceClass *getUnresolvedEquivClass() const {
+    assert(!*this);
+    return equivClass;
+  }
+};
+
 /// If there is a same-type requirement to be added for the given nested type
 /// due to a superclass constraint on the parent type, add it now.
 static void maybeAddSameTypeRequirementForNestedType(
@@ -1425,10 +1487,9 @@
     return false;
   }
 
-  builder.bumpGeneration();
-
   // Add the conformance along with this constraint.
   equivClass->conformsTo[proto].push_back({this, proto, source});
+  equivClass->modified(builder);
   ++NumConformanceConstraints;
   ++NumConformances;
 
@@ -1898,9 +1959,7 @@
   // If we were asked for a complete, well-formed archetype, make sure we
   // process delayed requirements if anything changed.
   SWIFT_DEFER {
-    ASTContext &ctx = assocType ? assocType->getASTContext()
-                                : concreteDecl->getASTContext();
-    if (ctx.LangOpts.EnableRecursiveConstraints)
+    if (kind == ArchetypeResolutionKind::CompleteWellFormed)
       getBuilder()->processDelayedRequirements();
   };
 
@@ -1938,7 +1997,9 @@
     switch (kind) {
     case ArchetypeResolutionKind::CompleteWellFormed:
     case ArchetypeResolutionKind::WellFormed: {
-      builder.bumpGeneration();
+      // Creating a new potential archetype in an equivalence class is a
+      // modification.
+      getOrCreateEquivalenceClass()->modified(builder);
 
       if (assocType)
         resultPA = new PotentialArchetype(this, assocType);
@@ -2359,6 +2420,16 @@
   members.push_back(representative);
 }
 
+void EquivalenceClass::modified(GenericSignatureBuilder &builder) {
+  builder.Impl->Generation++;
+
+  // Transfer any delayed requirements to the primary queue, because they
+  // might be resolvable now.
+  builder.Impl->DelayedRequirements.append(delayedRequirements.begin(),
+                                           delayedRequirements.end());
+  delayedRequirements.clear();
+}
+
 GenericSignatureBuilder::GenericSignatureBuilder(
                                ASTContext &ctx,
                                std::function<GenericFunction> lookupConformance)
@@ -2394,38 +2465,66 @@
   return Context.getLazyResolver();
 }
 
-PotentialArchetype *GenericSignatureBuilder::resolveArchetype(
+auto GenericSignatureBuilder::resolvePotentialArchetype(
                                      Type type,
-                                     ArchetypeResolutionKind resolutionKind) {
+                                     ArchetypeResolutionKind resolutionKind)
+  -> llvm::PointerUnion<PotentialArchetype *, EquivalenceClass *>
+{
   if (auto genericParam = type->getAs<GenericTypeParamType>()) {
     unsigned index = GenericParamKey(genericParam).findIndexIn(
                                                            Impl->GenericParams);
     if (index < Impl->GenericParams.size())
       return Impl->PotentialArchetypes[index];
 
-    return nullptr;
+    return (EquivalenceClass *)nullptr;
   }
 
   if (auto dependentMember = type->getAs<DependentMemberType>()) {
-    auto base = resolveArchetype(dependentMember->getBase(), resolutionKind);
-    if (!base)
-      return nullptr;
+    auto base = resolvePotentialArchetype(
+                  dependentMember->getBase(), resolutionKind);
+    auto basePA = base.dyn_cast<PotentialArchetype *>();
+    if (!basePA)
+      return base;
 
     // If we know the associated type already, get that specific type.
-    if (auto assocType = dependentMember->getAssocType())
-      return base->updateNestedTypeForConformance(assocType, resolutionKind);
+    PotentialArchetype *nestedPA;
+    if (auto assocType = dependentMember->getAssocType()) {
+      nestedPA =
+        basePA->updateNestedTypeForConformance(assocType, resolutionKind);
+    } else {
+      // Resolve based on name alone.
+      auto name = dependentMember->getName();
+      nestedPA = basePA->getNestedArchetypeAnchor(name, *this, resolutionKind);
+    }
 
-    // Resolve based on name alone.
-    auto name = dependentMember->getName();
-    return base->getNestedArchetypeAnchor(name, *this, resolutionKind);
+    // If we found a nested potential archetype, return it.
+    if (nestedPA)
+      return nestedPA;
+
+    // Otherwise, get/create an equivalence class for the base potential
+    // archetype.
+    return basePA->getOrCreateEquivalenceClass();
   }
 
+  return (EquivalenceClass *)nullptr;
+}
+
+PotentialArchetype *GenericSignatureBuilder::resolveArchetype(
+                                      Type type,
+                                      ArchetypeResolutionKind resolutionKind) {
+  if (!type->isTypeParameter())
+    return nullptr;
+
+  auto result = resolvePotentialArchetype(type, resolutionKind);
+  if (auto pa = result.dyn_cast<PotentialArchetype *>())
+    return pa;
+
   return nullptr;
 }
 
 auto GenericSignatureBuilder::resolve(UnresolvedType paOrT,
                                       FloatingRequirementSource source)
-    -> Optional<ResolvedType> {
+    -> ResolveResult {
   auto pa = paOrT.dyn_cast<PotentialArchetype *>();
   if (auto type = paOrT.dyn_cast<Type>()) {
     // If it's not a type parameter,
@@ -2440,8 +2539,9 @@
 
     // Attempt to resolve the type parameter to a potential archetype. If this
     // fails, it's because we weren't allowed to resolve anything now.
-    pa = resolveArchetype(type, resolutionKind);
-    if (!pa) return None;
+    auto resolved = resolvePotentialArchetype(type, resolutionKind);
+    pa = resolved.dyn_cast<PotentialArchetype *>();
+      if (!pa) return resolved.get<EquivalenceClass *>();
   }
 
   return ResolvedType::forPotentialArchetype(pa);
@@ -2814,6 +2914,7 @@
 
   // Record this layout constraint.
   equivClass->layoutConstraints.push_back({PAT, Layout, Source});
+  equivClass->modified(*this);
   ++NumLayoutConstraints;
 
   // Update the layout in the equivalence class, if we didn't have one already.
@@ -2837,8 +2938,11 @@
   // Resolve the subject.
   auto resolvedSubject = resolve(subject, source);
   if (!resolvedSubject) {
-    return handleUnresolvedRequirement(RequirementKind::Layout, subject,
-                                       layout, source, unresolvedHandling);
+    return handleUnresolvedRequirement(
+                                   RequirementKind::Layout, subject,
+                                   layout, source,
+                                   resolvedSubject.getUnresolvedEquivClass(),
+                                   unresolvedHandling);
   }
 
   // If this layout constraint applies to a concrete type, we can fully
@@ -2858,8 +2962,6 @@
     return ConstraintResult::Resolved;
   }
 
-  bumpGeneration();
-
   auto pa = resolvedSubject->getPotentialArchetype();
   return addLayoutRequirementDirect(pa, layout, source.getSource(pa));
 }
@@ -2940,12 +3042,12 @@
                                             Type superclass,
                                             const RequirementSource *source) {
   // Record the constraint.
-  T->getOrCreateEquivalenceClass()->superclassConstraints
-    .push_back(ConcreteConstraint{T, superclass, source});
+  auto equivClass = T->getOrCreateEquivalenceClass();
+  equivClass->superclassConstraints.push_back(
+                                    ConcreteConstraint{T, superclass, source});
+  equivClass->modified(*this);
   ++NumSuperclassConstraints;
 
-  bumpGeneration();
-
   // Update the equivalence class with the constraint.
   updateSuperclass(T, superclass, source);
   return ConstraintResult::Resolved;
@@ -2968,9 +3070,11 @@
   // Resolve the constraint.
   auto resolvedConstraint = resolve(constraint, source);
   if (!resolvedConstraint) {
-    return handleUnresolvedRequirement(RequirementKind::Conformance, subject,
-                                       toRequirementRHS(constraint), source,
-                                       unresolvedHandling);
+    return handleUnresolvedRequirement(
+                                 RequirementKind::Conformance, subject,
+                                 toRequirementRHS(constraint), source,
+                                 resolvedConstraint.getUnresolvedEquivClass(),
+                                 unresolvedHandling);
   }
 
   // The right-hand side needs to be concrete.
@@ -3011,8 +3115,11 @@
       constraintType->isExistentialType()
         ? RequirementKind::Conformance
         : RequirementKind::Superclass;
-    return handleUnresolvedRequirement(recordedKind, subject, constraintType,
-                                       source, unresolvedHandling);
+    return handleUnresolvedRequirement(
+                                     recordedKind, subject, constraintType,
+                                     source,
+                                     resolvedSubject.getUnresolvedEquivClass(),
+                                     unresolvedHandling);
   }
 
   // If the resolved subject is a type, we can probably perform diagnostics
@@ -3105,8 +3212,6 @@
   if (T1 == T2)
     return ConstraintResult::Resolved;
 
-  bumpGeneration();
-
   unsigned nestingDepth1 = T1->getNestingDepth();
   unsigned nestingDepth2 = T2->getNestingDepth();
 
@@ -3120,6 +3225,8 @@
 
   // Merge the equivalence classes.
   auto equivClass = T1->getOrCreateEquivalenceClass();
+  equivClass->modified(*this);
+
   auto equivClass1Members = equivClass->members;
   auto equivClass2Members = T2->getEquivalenceClassMembers();
   for (auto equiv : equivClass2Members)
@@ -3131,6 +3238,10 @@
     delete equivClass2;
   };
 
+  // Consider the second equivalence class to be modified.
+  if (equivClass2)
+    equivClass->modified(*this);
+
   // Same-type requirements.
   if (equivClass2) {
     for (auto &paSameTypes : equivClass2->sameTypeConstraints) {
@@ -3240,10 +3351,9 @@
   // Record the concrete type and its source.
   equivClass->concreteTypeConstraints.push_back(
                                       ConcreteConstraint{T, Concrete, Source});
+  equivClass->modified(*this);
   ++NumConcreteTypeConstraints;
 
-  bumpGeneration();
-
   // If we've already been bound to a type, match that type.
   if (equivClass->concreteType) {
     return addSameTypeRequirement(equivClass->concreteType, Concrete, Source,
@@ -3337,6 +3447,7 @@
   if (!resolved1) {
     return handleUnresolvedRequirement(RequirementKind::SameType, paOrT1,
                                        toRequirementRHS(paOrT2), source,
+                                       resolved1.getUnresolvedEquivClass(),
                                        unresolvedHandling);
   }
 
@@ -3344,6 +3455,7 @@
   if (!resolved2) {
     return handleUnresolvedRequirement(RequirementKind::SameType, paOrT1,
                                        toRequirementRHS(paOrT2), source,
+                                       resolved2.getUnresolvedEquivClass(),
                                        unresolvedHandling);
   }
 
@@ -3374,28 +3486,6 @@
   }
 }
 
-// Local function to mark the given associated type as recursive,
-// diagnosing it if this is the first such occurrence.
-void GenericSignatureBuilder::markPotentialArchetypeRecursive(
-    PotentialArchetype *pa, ProtocolDecl *proto, const RequirementSource *source) {
-  if (pa->isRecursive())
-    return;
-  pa->setIsRecursive();
-
-  pa->addConformance(proto, source, *this);
-  if (!pa->getParent())
-    return;
-
-  auto assocType = pa->getResolvedAssociatedType();
-  if (!assocType || assocType->isInvalid())
-    return;
-
-  Diags.diagnose(assocType->getLoc(), diag::recursive_requirement_reference);
-
-  // Silence downstream errors referencing this associated type.
-  assocType->setInvalid();
-}
-
 ConstraintResult GenericSignatureBuilder::addInheritedRequirements(
                              TypeDecl *decl,
                              UnresolvedType type,
@@ -3446,26 +3536,6 @@
                         getFloatingSource(typeRepr, /*forInferred=*/true));
     }
 
-    if (!decl->getASTContext().LangOpts.EnableRecursiveConstraints) {
-      // Check for direct recursion.
-      if (auto assocType = dyn_cast<AssociatedTypeDecl>(decl)) {
-        auto proto = assocType->getProtocol();
-        if (auto inheritedProto = inheritedType->getAs<ProtocolType>()) {
-          if (inheritedProto->getDecl() == proto ||
-              inheritedProto->getDecl()->inheritsFrom(proto)) {
-            auto source = getFloatingSource(typeRepr, /*forInferred=*/false);
-            if (auto resolved = resolve(type, source)) {
-              if (auto pa = resolved->getPotentialArchetype()) {
-                markPotentialArchetypeRecursive(pa, proto,
-                                                source.getSource(pa));
-                return ConstraintResult::Conflicting;
-              }
-            }
-          }
-        }
-      }
-    }
-
     return addTypeRequirement(type, inheritedType,
                               getFloatingSource(typeRepr,
                                                 /*forInferred=*/false),
@@ -4060,19 +4130,19 @@
       case DelayedRequirement::Type:
         reqResult = addTypeRequirement(
                        req.lhs, asUnresolvedType(req.rhs), req.source,
-                       UnresolvedHandlingKind::ReturnUnresolved);
+                       UnresolvedHandlingKind::GenerateUnresolved);
         break;
 
       case DelayedRequirement::Layout:
         reqResult = addLayoutRequirement(
                            req.lhs, req.rhs.get<LayoutConstraint>(), req.source,
-                           UnresolvedHandlingKind::ReturnUnresolved);
+                           UnresolvedHandlingKind::GenerateUnresolved);
         break;
 
       case DelayedRequirement::SameType:
         reqResult = addSameTypeRequirement(
                                req.lhs, asUnresolvedType(req.rhs), req.source,
-                               UnresolvedHandlingKind::ReturnUnresolved);
+                               UnresolvedHandlingKind::GenerateUnresolved);
         break;
       }
 
@@ -4095,7 +4165,6 @@
       case ConstraintResult::Unresolved:
         // Add the requirement back.
         ++NumDelayedRequirementUnresolved;
-        Impl->DelayedRequirements.push_back(req);
         break;
       }
     }
@@ -4106,10 +4175,6 @@
   } while (anySolved);
 }
 
-void GenericSignatureBuilder::bumpGeneration() {
-  ++Impl->Generation;
-}
-
 template<typename T>
 Constraint<T> GenericSignatureBuilder::checkConstraintList(
                            ArrayRef<GenericTypeParamType *> genericParams,
@@ -4346,30 +4411,69 @@
   for (auto &entry : equivClass->conformsTo) {
     // Remove self-derived constraints.
     assert(!entry.second.empty() && "No constraints to work with?");
+
+    // Local function to establish whether a conformance constraint is
+    // self-derived.
     Optional<Constraint<ProtocolDecl *>> remainingConcrete;
+    SmallVector<Constraint<ProtocolDecl *>, 4> minimalSources;
+    auto isSelfDerived =
+      [&](const Constraint<ProtocolDecl *> &constraint) {
+        // Determine whether there is a subpath of this requirement source that
+        // derives the same conformance.
+        bool derivedViaConcrete;
+        auto minimalSource =
+          constraint.source->getMinimalConformanceSource(constraint.archetype,
+                                                         entry.first,
+                                                         derivedViaConcrete);
+        if (minimalSource != constraint.source) {
+          // The minimal source is smaller than the original source, so the
+          // original source is self-derived.
+          ++NumSelfDerived;
+
+          if (minimalSource) {
+            // Record a constraint with a minimized source.
+            minimalSources.push_back(
+                             {minimalSource->getAffectedPotentialArchetype(),
+                              constraint.value,
+                              minimalSource});
+          }
+
+          return true;
+        }
+
+        if (!derivedViaConcrete)
+          return false;
+
+        // Drop derived-via-concrete requirements.
+        if (!remainingConcrete)
+          remainingConcrete = constraint;
+
+        ++NumSelfDerived;
+        return true;
+      };
+
+    // Erase all self-derived constraints.
     entry.second.erase(
-      std::remove_if(entry.second.begin(), entry.second.end(),
-                     [&](const Constraint<ProtocolDecl *> &constraint) {
-                       bool derivedViaConcrete;
-                       if (constraint.source->isSelfDerivedConformance(
-                                constraint.archetype, entry.first,
-                                derivedViaConcrete)) {
-                         ++NumSelfDerived;
-                         return true;
-                       }
-
-                       if (!derivedViaConcrete)
-                         return false;
-
-                       // Drop derived-via-concrete requirements.
-                       if (!remainingConcrete)
-                         remainingConcrete = constraint;
-
-                       ++NumSelfDerived;
-                       return true;
-                     }),
+      std::remove_if(entry.second.begin(), entry.second.end(), isSelfDerived),
       entry.second.end());
 
+    // If we found any mininal sources, add them now, avoiding introducing any
+    // redundant sources.
+    if (!minimalSources.empty()) {
+      // Collect the sources we already know about.
+      SmallPtrSet<const RequirementSource *, 4> sources;
+      for (const auto &constraint : entry.second) {
+        sources.insert(constraint.source);
+      }
+
+      // Add any minimal sources we didn't know about.
+      for (const auto &minimalSource : minimalSources) {
+        if (sources.insert(minimalSource.source).second) {
+          entry.second.push_back(minimalSource);
+        }
+      }
+    }
+
     // If we only had concrete conformances, put one back.
     if (entry.second.empty() && remainingConcrete)
       entry.second.push_back(*remainingConcrete);
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index bb10842..3a41a47 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -686,6 +686,10 @@
     invocationArgStrs.push_back("-march=z196");
   }
 
+  if (!importerOpts.Optimization.empty()) {
+    invocationArgStrs.push_back(importerOpts.Optimization);
+  }
+
   const std::string &overrideResourceDir = importerOpts.OverrideResourceDir;
   if (overrideResourceDir.empty()) {
     llvm::SmallString<128> resourceDir(searchPathOpts.RuntimeResourcePath);
@@ -868,6 +872,7 @@
   }
 
   std::vector<const char *> invocationArgs;
+  invocationArgs.reserve(invocationArgStrs.size());
   for (auto &argStr : invocationArgStrs)
     invocationArgs.push_back(argStr.c_str());
 
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 9b4867b..6d6c3bb 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -7103,8 +7103,13 @@
       return;
     }
 
-    // Map Clang's swift_objc_members attribute to @objcMembers.
-    if (ID->hasAttr<clang::SwiftObjCMembersAttr>()) {
+    // Map Clang's swift_objc_members attribute to @objcMembers. Also handle
+    // inheritance of @objcMembers by looking at the superclass.
+    if (ID->hasAttr<clang::SwiftObjCMembersAttr>() ||
+        (isa<ClassDecl>(MappedDecl) &&
+         cast<ClassDecl>(MappedDecl)->hasSuperclass() &&
+         cast<ClassDecl>(MappedDecl)->getSuperclassDecl()
+           ->getAttrs().hasAttribute<ObjCMembersAttr>())) {
       if (!MappedDecl->getAttrs().hasAttribute<ObjCMembersAttr>()) {
         auto attr = new (C) ObjCMembersAttr(/*IsImplicit=*/true);
         MappedDecl->getAttrs().add(attr);
diff --git a/lib/ClangImporter/ImportEnumInfo.cpp b/lib/ClangImporter/ImportEnumInfo.cpp
index c0e6d0b..ad56f5f 100644
--- a/lib/ClangImporter/ImportEnumInfo.cpp
+++ b/lib/ClangImporter/ImportEnumInfo.cpp
@@ -36,6 +36,8 @@
 /// Classify the given Clang enumeration to describe how to import it.
 void EnumInfo::classifyEnum(ASTContext &ctx, const clang::EnumDecl *decl,
                             clang::Preprocessor &pp) {
+  assert(decl->isThisDeclarationADefinition());
+
   // Anonymous enumerations simply get mapped to constants of the
   // underlying type of the enum, because there is no way to conjure up a
   // name for the Swift type.
diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp
index 4506c95..47530ec 100644
--- a/lib/ClangImporter/ImportName.cpp
+++ b/lib/ClangImporter/ImportName.cpp
@@ -587,6 +587,13 @@
 const clang::SwiftNameAttr *
 importer::findSwiftNameAttr(const clang::Decl *decl,
                             ImportNameVersion version) {
+#ifndef NDEBUG
+  if (Optional<const clang::Decl *> def = getDefinitionForClangTypeDecl(decl)) {
+    assert((*def == nullptr || *def == decl) &&
+           "swift_name should only appear on the definition");
+  }
+#endif
+
   if (version == ImportNameVersion::Raw)
     return nullptr;
 
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 3d67b45..f83b5a8 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -153,6 +153,7 @@
   inputArgs.AddLastArg(arguments, options::OPT_stats_output_dir);
   inputArgs.AddLastArg(arguments,
                        options::OPT_solver_shrink_unsolved_threshold);
+  inputArgs.AddLastArg(arguments, options::OPT_O_Group);
 
   // Pass on any build config options
   inputArgs.AddAllArgs(arguments, options::OPT_D);
@@ -384,9 +385,6 @@
     }
   }
 
-  // Pass the optimization level down to the frontend.
-  context.Args.AddLastArg(Arguments, options::OPT_O_Group);
-
   if (context.Args.hasArg(options::OPT_parse_as_library) ||
       context.Args.hasArg(options::OPT_emit_library))
     Arguments.push_back("-parse-as-library");
@@ -503,9 +501,6 @@
                         Arguments);
   context.Args.AddLastArg(Arguments, options::OPT_import_objc_header);
 
-  // Pass the optimization level down to the frontend.
-  context.Args.AddLastArg(Arguments, options::OPT_O_Group);
-
   context.Args.AddLastArg(Arguments, options::OPT_parse_sil);
 
   Arguments.push_back("-module-name");
@@ -633,9 +628,6 @@
 
   context.Args.AddLastArg(Arguments, options::OPT_parse_stdlib);
 
-  // Pass the optimization level down to the frontend.
-  context.Args.AddLastArg(Arguments, options::OPT_O_Group);
-
   Arguments.push_back("-module-name");
   Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName));
 
@@ -663,8 +655,7 @@
 
   Arguments.push_back("-frontend");
 
-  // We just want to emit a module, so pass -emit-module without any other
-  // mode options.
+  Arguments.push_back("-merge-modules");
   Arguments.push_back("-emit-module");
 
   if (context.Args.hasArg(options::OPT_driver_use_filelists) ||
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 51b7e4e..d2cb4cc 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -322,6 +322,8 @@
       Action = FrontendOptions::DumpAST;
     } else if (Opt.matches(OPT_emit_syntax)) {
       Action = FrontendOptions::EmitSyntax;
+    } else if (Opt.matches(OPT_merge_modules)) {
+      Action = FrontendOptions::MergeModules;
     } else if (Opt.matches(OPT_dump_scope_maps)) {
       Action = FrontendOptions::DumpScopeMaps;
 
@@ -559,6 +561,7 @@
       Suffix = SIB_EXTENSION;
       break;
 
+    case FrontendOptions::MergeModules:
     case FrontendOptions::EmitModuleOnly:
       Suffix = SERIALIZED_MODULE_EXTENSION;
       break;
@@ -724,7 +727,9 @@
     Opts.RequestedAction == FrontendOptions::EmitSIB ||
     Opts.RequestedAction == FrontendOptions::EmitSIBGen;
   bool canUseMainOutputForModule =
-    Opts.RequestedAction == FrontendOptions::EmitModuleOnly || IsSIB;
+    Opts.RequestedAction == FrontendOptions::MergeModules ||
+    Opts.RequestedAction == FrontendOptions::EmitModuleOnly ||
+    IsSIB;
   auto ext = IsSIB ? SIB_EXTENSION : SERIALIZED_MODULE_EXTENSION;
   auto sibOpt = Opts.RequestedAction == FrontendOptions::EmitSIB ?
     OPT_emit_sib : OPT_emit_sibgen;
@@ -756,6 +761,7 @@
       return true;
     case FrontendOptions::Parse:
     case FrontendOptions::Typecheck:
+    case FrontendOptions::MergeModules:
     case FrontendOptions::EmitModuleOnly:
     case FrontendOptions::EmitPCH:
     case FrontendOptions::EmitSILGen:
@@ -789,6 +795,7 @@
       return true;
     case FrontendOptions::Parse:
     case FrontendOptions::Typecheck:
+    case FrontendOptions::MergeModules:
     case FrontendOptions::EmitModuleOnly:
     case FrontendOptions::EmitSILGen:
     case FrontendOptions::EmitSIL:
@@ -821,6 +828,7 @@
                      diag::error_mode_cannot_emit_loaded_module_trace);
       return true;
     case FrontendOptions::Typecheck:
+    case FrontendOptions::MergeModules:
     case FrontendOptions::EmitModuleOnly:
     case FrontendOptions::EmitPCH:
     case FrontendOptions::EmitSILGen:
@@ -859,6 +867,7 @@
       else
         Diags.diagnose(SourceLoc(), diag::error_mode_cannot_emit_module_doc);
       return true;
+    case FrontendOptions::MergeModules:
     case FrontendOptions::EmitModuleOnly:
     case FrontendOptions::EmitSIL:
     case FrontendOptions::EmitSIBGen:
@@ -1014,8 +1023,6 @@
   }
   
   Opts.EnableASTScopeLookup |= Args.hasArg(OPT_enable_astscope_lookup);
-  Opts.EnableRecursiveConstraints |=
-    Args.hasArg(OPT_enable_recursive_constraints);
   Opts.DebugConstraintSolver |= Args.hasArg(OPT_debug_constraints);
   Opts.EnableConstraintPropagation |= Args.hasArg(OPT_propagate_constraints);
   Opts.IterativeTypeChecker |= Args.hasArg(OPT_iterative_type_checker);
@@ -1352,7 +1359,8 @@
                          IRGenOptions &IRGenOpts,
                          FrontendOptions &FEOpts,
                          DiagnosticEngine &Diags,
-                         const llvm::Triple &Triple) {
+                         const llvm::Triple &Triple,
+                         ClangImporterOptions &ClangOpts) {
   using namespace options;
 
   if (const Arg *A = Args.getLastArg(OPT_sil_inline_threshold)) {
@@ -1408,6 +1416,10 @@
       IRGenOpts.Optimize = true;
       Opts.Optimization = SILOptions::SILOptMode::Optimize;
     }
+
+    if (IRGenOpts.Optimize) {
+      ClangOpts.Optimization = "-Os";
+    }
   }
 
   if (Args.getLastArg(OPT_AssumeSingleThreaded)) {
@@ -1799,7 +1811,7 @@
   }
 
   if (ParseSILArgs(SILOpts, ParsedArgs, IRGenOpts, FrontendOpts, Diags,
-                   LangOpts.Target)) {
+                   LangOpts.Target, ClangImporterOpts)) {
     return true;
   }
 
diff --git a/lib/Frontend/FrontendOptions.cpp b/lib/Frontend/FrontendOptions.cpp
index 1a4bf95..fdbe325 100644
--- a/lib/Frontend/FrontendOptions.cpp
+++ b/lib/Frontend/FrontendOptions.cpp
@@ -35,6 +35,7 @@
   case EmitSIBGen:
   case EmitSIB:
   case EmitModuleOnly:
+  case MergeModules:
     return true;
   case Immediate:
   case REPL:
@@ -68,6 +69,7 @@
   case EmitSIBGen:
   case EmitSIB:
   case EmitModuleOnly:
+  case MergeModules:
     return false;
   case Immediate:
   case REPL:
@@ -85,7 +87,8 @@
 
 void FrontendOptions::forAllOutputPaths(
     std::function<void(const std::string &)> fn) const {
-  if (RequestedAction != FrontendOptions::EmitModuleOnly) {
+  if (RequestedAction != FrontendOptions::EmitModuleOnly &&
+      RequestedAction != FrontendOptions::MergeModules) {
     for (const std::string &OutputFileName : OutputFilenames) {
       fn(OutputFileName);
     }
diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp
index d53203c..18b0071 100644
--- a/lib/FrontendTool/FrontendTool.cpp
+++ b/lib/FrontendTool/FrontendTool.cpp
@@ -816,7 +816,9 @@
   }
 
   // Perform "stable" optimizations that are invariant across compiler versions.
-  if (!Invocation.getDiagnosticOptions().SkipDiagnosticPasses) {
+  if (Action == FrontendOptions::MergeModules) {
+    // Don't run diagnostic passes at all.
+  } else if (!Invocation.getDiagnosticOptions().SkipDiagnosticPasses) {
     if (runSILDiagnosticPasses(*SM))
       return true;
 
@@ -846,8 +848,9 @@
   // These may change across compiler versions.
   {
     SharedTimer timer("SIL optimization");
-    if (Invocation.getSILOptions().Optimization >
-        SILOptions::SILOptMode::None) {
+    if (Action != FrontendOptions::MergeModules &&
+        Invocation.getSILOptions().Optimization >
+          SILOptions::SILOptMode::None) {
 
       runSILOptPreparePasses(*SM);
 
@@ -936,7 +939,8 @@
       serialize(DC, serializationOpts, SM.get());
     }
 
-    if (Action == FrontendOptions::EmitModuleOnly) {
+    if (Action == FrontendOptions::MergeModules ||
+        Action == FrontendOptions::EmitModuleOnly) {
       if (shouldIndex) {
         if (emitIndexData(PrimarySourceFile, Invocation, Instance))
           return true;
diff --git a/lib/IDE/ModuleInterfacePrinting.cpp b/lib/IDE/ModuleInterfacePrinting.cpp
index 4077d41..00be9e0 100644
--- a/lib/IDE/ModuleInterfacePrinting.cpp
+++ b/lib/IDE/ModuleInterfacePrinting.cpp
@@ -494,7 +494,7 @@
   });
 
   // If the group name is specified, we sort them according to their source order,
-  // which is the order preserved by getTopLeveDecls.
+  // which is the order preserved by getTopLevelDecls.
   if (GroupNames.empty()) {
     std::sort(SwiftDecls.begin(), SwiftDecls.end(),
       [&](Decl *LHS, Decl *RHS) -> bool {
diff --git a/lib/IDE/SyntaxModel.cpp b/lib/IDE/SyntaxModel.cpp
index 78e9511..932f3f6 100644
--- a/lib/IDE/SyntaxModel.cpp
+++ b/lib/IDE/SyntaxModel.cpp
@@ -954,6 +954,16 @@
         popStructureNode();
       }
     }
+  } else if (auto *TypeAliasD = dyn_cast<TypeAliasDecl>(D)) {
+    SyntaxStructureNode SN;
+    SN.Dcl = TypeAliasD;
+    SN.Kind = SyntaxStructureKind::TypeAlias;
+    SN.Range = charSourceRangeFromSourceRange(SM,
+                                              TypeAliasD->getSourceRange());
+    SN.NameRange = CharSourceRange(TypeAliasD->getNameLoc(),
+                                   TypeAliasD->getName().getLength());
+    SN.Attrs = TypeAliasD->getAttrs();
+    pushStructureNode(SN, TypeAliasD);
   }
 
   return true;
diff --git a/lib/IRGen/GenFunc.cpp b/lib/IRGen/GenFunc.cpp
index f8fe4a3..f8c545a 100644
--- a/lib/IRGen/GenFunc.cpp
+++ b/lib/IRGen/GenFunc.cpp
@@ -705,6 +705,41 @@
   }
 }
 
+static bool isABIIgnoredParameterWithoutStorage(IRGenModule &IGM,
+                                                IRGenFunction &IGF,
+                                                CanSILFunctionType substType,
+                                                unsigned paramIdx) {
+  auto param = substType->getParameters()[paramIdx];
+  SILType argType = IGM.silConv.getSILType(param);
+  auto argLoweringTy =
+    getArgumentLoweringType(argType.getSwiftRValueType(), param);
+  auto &ti = IGF.getTypeInfoForLowered(argLoweringTy);
+  // Empty values don't matter.
+  return ti.getSchema().size() == 0 && !param.isFormalIndirect();
+}
+
+/// Find the parameter index for the one (assuming there was only one) partially
+/// applied argument ignoring empty types that are not passed as part of the
+/// ABI.
+static unsigned findSinglePartiallyAppliedParameterIndexIgnoringEmptyTypes(
+    IRGenFunction &IGF, CanSILFunctionType substType,
+    CanSILFunctionType outType) {
+  auto substParameters = substType->getParameters();
+  auto outParamters = outType->getParameters();
+  unsigned firstNonEmpty = -1U;
+  for (unsigned paramIdx = outParamters.size() ; paramIdx != substParameters.size(); ++paramIdx) {
+    bool isEmpty =
+        isABIIgnoredParameterWithoutStorage(IGF.IGM, IGF, substType, paramIdx);
+    assert((isEmpty || firstNonEmpty == -1U) && "Expect at most one partially "
+                                                "applied that is passed as an "
+                                                "ABI argument");
+    if (!isEmpty)
+      firstNonEmpty = paramIdx;
+  }
+  assert(firstNonEmpty != -1U);
+  return firstNonEmpty;
+}
+
 /// Emit the forwarding stub function for a partial application.
 ///
 /// If 'layout' is null, there is a single captured value of
@@ -924,11 +959,9 @@
     // care for the former for the purpose of reconstructing polymorphic
     // parameters from regular arguments.
     if (!calleeHasContext) {
-      unsigned paramI = substType->getParameters().size() - 1;
-      assert(substType->getParameters().size() -
-                     outType->getParameters().size() ==
-                 1 &&
-             "Expect one partially applied argument");
+      unsigned paramI =
+          findSinglePartiallyAppliedParameterIndexIgnoringEmptyTypes(
+              subIGF, substType, outType);
       auto paramInfo = substType->getParameters()[paramI];
       auto &ti = IGM.getTypeInfoForLowered(paramInfo.getType());
       Explosion param;
@@ -1097,13 +1130,8 @@
 
       // Skip empty parameters.
       while (origParamI < origType->getParameters().size()) {
-        auto param = substType->getParameters()[origParamI];
-        SILType argType = IGM.silConv.getSILType(param);
-        auto argLoweringTy =
-            getArgumentLoweringType(argType.getSwiftRValueType(), param);
-        auto &ti = subIGF.getTypeInfoForLowered(argLoweringTy);
-        // Empty values don't matter.
-        if (ti.getSchema().size() != 0 || param.isFormalIndirect())
+        if (!isABIIgnoredParameterWithoutStorage(IGM, subIGF, substType,
+                                                 origParamI))
           break;
         origParamI++;
       }
diff --git a/lib/IRGen/IRGenModule.cpp b/lib/IRGen/IRGenModule.cpp
index 8f4aa70..7718bd8 100644
--- a/lib/IRGen/IRGenModule.cpp
+++ b/lib/IRGen/IRGenModule.cpp
@@ -466,20 +466,16 @@
       else
         buildFnAttr.addAttribute(Attr);
     }
-    // FIXME: getting attributes here without setting them does
-    // nothing. This cannot be fixed until the attributes are correctly specified.
-    fn->getAttributes().
-      addAttributes(Module.getContext(),
-                    llvm::AttributeSet::FunctionIndex,
-                    llvm::AttributeSet::get(Module.getContext(),
-                                            llvm::AttributeSet::FunctionIndex,
-                                            buildFnAttr));
-    fn->getAttributes().
-      addAttributes(Module.getContext(),
-                    llvm::AttributeSet::ReturnIndex,
-                    llvm::AttributeSet::get(Module.getContext(),
-                                            llvm::AttributeSet::ReturnIndex,
-                                            buildRetAttr));
+    fn->setAttributes(fn->getAttributes().addAttributes(
+        Module.getContext(), llvm::AttributeSet::FunctionIndex,
+        llvm::AttributeSet::get(Module.getContext(),
+                                llvm::AttributeSet::FunctionIndex,
+                                buildFnAttr)));
+    fn->setAttributes(fn->getAttributes().addAttributes(
+        Module.getContext(), llvm::AttributeSet::ReturnIndex,
+        llvm::AttributeSet::get(Module.getContext(),
+                                llvm::AttributeSet::ReturnIndex,
+                                buildRetAttr)));
   }
 
   return cache;
diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp
index 1dcf8dc..e522f37 100644
--- a/lib/IRGen/IRGenSIL.cpp
+++ b/lib/IRGen/IRGenSIL.cpp
@@ -143,30 +143,32 @@
 private:
   using ExplosionVector = SmallVector<llvm::Value *, 4>;
   using SingletonExplosion = llvm::Value*;
+
+  using Members = ExternalUnionMembers<ContainedAddress,
+                                       StackAddress,
+                                       OwnedAddress,
+                                       DynamicallyEnforcedAddress,
+                                       ExplosionVector,
+                                       SingletonExplosion,
+                                       FunctionPointer,
+                                       ObjCMethod,
+                                       void>;
   
-  static int getStorageTypeForKind(Kind kind) {
+  static Members::Index getMemberIndexForKind(Kind kind) {
     switch (kind) {
-    case Kind::ContainedAddress: return 0;
-    case Kind::StackAddress: return 1;
-    case Kind::OwnedAddress: return 2;
-    case Kind::DynamicallyEnforcedAddress: return 3;
-    case Kind::ExplosionVector: return 4;
-    case Kind::SingletonExplosion: return 5;
-    case Kind::FunctionPointer: return 6;
-    case Kind::ObjCMethod: return 7;
-    case Kind::EmptyExplosion: return -1;
+    case Kind::ContainedAddress: return Members::indexOf<ContainedAddress>();
+    case Kind::StackAddress: return Members::indexOf<StackAddress>();
+    case Kind::OwnedAddress: return Members::indexOf<OwnedAddress>();
+    case Kind::DynamicallyEnforcedAddress: return Members::indexOf<DynamicallyEnforcedAddress>();
+    case Kind::ExplosionVector: return Members::indexOf<ExplosionVector>();
+    case Kind::SingletonExplosion: return Members::indexOf<SingletonExplosion>();
+    case Kind::FunctionPointer: return Members::indexOf<FunctionPointer>();
+    case Kind::ObjCMethod: return Members::indexOf<ObjCMethod>();
+    case Kind::EmptyExplosion: return Members::indexOf<void>();
     }
     llvm_unreachable("bad kind");
   }
-  ExternalUnion<Kind, getStorageTypeForKind,
-                ContainedAddress,
-                StackAddress,
-                OwnedAddress,
-                DynamicallyEnforcedAddress,
-                ExplosionVector,
-                SingletonExplosion,
-                FunctionPointer,
-                ObjCMethod> Storage;
+  ExternalUnion<Kind, Members, getMemberIndexForKind> Storage;
 
 public:
 
diff --git a/lib/IRGen/LoadableByAddress.cpp b/lib/IRGen/LoadableByAddress.cpp
index 427a950..7073ce7 100644
--- a/lib/IRGen/LoadableByAddress.cpp
+++ b/lib/IRGen/LoadableByAddress.cpp
@@ -82,13 +82,7 @@
 }
 
 static bool modifiableFunction(CanSILFunctionType funcType) {
-  if (funcType->getRepresentation() ==
-      SILFunctionTypeRepresentation::ObjCMethod) {
-    // ObjC functions should use the old ABI
-    return false;
-  }
-  if (funcType->getRepresentation() ==
-      SILFunctionTypeRepresentation::CFunctionPointer) {
+  if (funcType->getLanguage() == SILFunctionLanguage::C) {
     // C functions should use the old ABI
     return false;
   }
@@ -113,8 +107,6 @@
                         Mod)) {
         return true;
       }
-    } else if (isa<SILBlockStorageType>(currCanType.getPointer())) {
-      continue;
     } else {
       switch (param.getConvention()) {
       case ParameterConvention::Indirect_In_Guaranteed:
@@ -193,7 +185,9 @@
 getNewSILFunctionTypePtr(GenericEnvironment *GenericEnv,
                          SILFunctionType *currSILFunctionType,
                          irgen::IRGenModule &Mod) {
-  assert(modifiableFunction(CanSILFunctionType(currSILFunctionType)));
+  if (!modifiableFunction(CanSILFunctionType(currSILFunctionType))) {
+    return currSILFunctionType;
+  }
   SmallVector<SILParameterInfo, 4> newArgTys =
       getNewArgTys(GenericEnv, currSILFunctionType, Mod);
   SILFunctionType *newSILFunctionType = SILFunctionType::get(
@@ -350,9 +344,6 @@
     return newSILType;
   }
   CanType currCanType = storageType.getSwiftRValueType();
-  if (isa<SILBlockStorageType>(currCanType.getPointer())) {
-    return storageType;
-  }
   if (SILFunctionType *currSILFunctionType =
           dyn_cast<SILFunctionType>(currCanType.getPointer())) {
     if (containsLargeLoadable(GenericEnv, currSILFunctionType->getParameters(),
@@ -561,23 +552,9 @@
 
 static bool modifiableApply(ApplySite applySite, irgen::IRGenModule &Mod) {
   // If the callee is a method then use the old ABI
-  if (applySite.getSubstCalleeType()->getRepresentation() ==
-      SILFunctionTypeRepresentation::ObjCMethod) {
+  if (applySite.getSubstCalleeType()->getLanguage() == SILFunctionLanguage::C) {
     return false;
   }
-  if (applySite.getSubstCalleeType()->getRepresentation() ==
-      SILFunctionTypeRepresentation::CFunctionPointer) {
-    return false;
-  }
-  auto callee = applySite.getCallee();
-  if (isa<ProjectBlockStorageInst>(callee)) {
-    return false;
-  } else if (auto *instr = dyn_cast<LoadInst>(callee)) {
-    auto loadedSrcValue = instr->getOperand();
-    if (isa<ProjectBlockStorageInst>(loadedSrcValue)) {
-      return false;
-    }
-  }
   return true;
 }
 
@@ -629,12 +606,8 @@
   for (auto *user : instr->getUses()) {
     if (ApplySite::isa(user->getUser())) {
       ApplySite applySite = ApplySite(user->getUser());
-      if (applySite.getSubstCalleeType()->getRepresentation() ==
-          SILFunctionTypeRepresentation::ObjCMethod) {
-        return true;
-      }
-      if (applySite.getSubstCalleeType()->getRepresentation() ==
-          SILFunctionTypeRepresentation::CFunctionPointer) {
+      if (applySite.getSubstCalleeType()->getLanguage() ==
+          SILFunctionLanguage::C) {
         return true;
       }
     }
@@ -1158,7 +1131,13 @@
     genEnv = getGenericEnvironment(pass.F->getModule(), loweredTy);
   }
   auto singleResult = loweredTy->getSingleResult();
-  auto resultStorageType = singleResult.getSILStorageType();
+  SILType resultStorageType = singleResult.getSILStorageType();
+  auto canType = resultStorageType.getSwiftRValueType();
+  if (canType->hasTypeParameter()) {
+    assert(genEnv && "Expected a GenericEnv");
+    canType = genEnv->mapTypeIntoContext(canType)->getCanonicalType();
+  }
+  resultStorageType = SILType::getPrimitiveObjectType(canType);
 
   auto &ctx = pass.F->getModule().getASTContext();
   auto var = new (ctx) ParamDecl(
@@ -1283,10 +1262,7 @@
       genEnv = getGenericEnvironment(pass.F->getModule(), loweredTy);
     }
     SILType newSILType = getNewSILType(genEnv, storageType, pass.Mod);
-    // We only care about function signatures that are not block storage
     if (!isLargeLoadableType(genEnv, storageType, pass.Mod) &&
-        !dyn_cast<SILBlockStorageType>(
-            storageType.getSwiftRValueType().getPointer()) &&
         (newSILType != storageType)) {
       auto *castInstr = argBuilder.createUncheckedBitCast(
           RegularLocation(const_cast<ValueDecl *>(arg->getDecl())), arg,
@@ -1336,8 +1312,15 @@
         dyn_cast<SILInstruction>(pass.allocToApplyRetMap[allocInstr]);
     assert(applyInst && "Value is not an apply");
     auto II = applyInst->getIterator();
-    ++II;
     SILBuilder loadBuilder(II);
+    if (auto *tryApply = dyn_cast<TryApplyInst>(applyInst)) {
+      auto *tgtBB = tryApply->getNormalBB();
+      assert(tgtBB && "Could not find try apply's target BB");
+      loadBuilder.setInsertionPoint(tgtBB->begin());
+    } else {
+      ++II;
+      loadBuilder.setInsertionPoint(II);
+    }
     if (pass.F->hasUnqualifiedOwnership()) {
       load = loadBuilder.createLoad(applyInst->getLoc(), value,
                                     LoadOwnershipQualifier::Unqualified);
@@ -2367,6 +2350,9 @@
     IRGenModule *currIRMod =
         getIRGenModule()->IRGen.getGenModule(convInstr->getFunction());
     SILType currSILType = convInstr->getType();
+    if (auto *thinToPointer = dyn_cast<ThinFunctionToPointerInst>(convInstr)) {
+      currSILType = thinToPointer->getOperand()->getType();
+    }
     CanType currCanType = currSILType.getSwiftRValueType();
     SILFunctionType *currSILFunctionType =
         dyn_cast<SILFunctionType>(currCanType.getPointer());
@@ -2395,6 +2381,15 @@
           instr->getLoc(), instr->getOperand(), newType);
       break;
     }
+    case ValueKind::ThinFunctionToPointerInst: {
+      ThinFunctionToPointerInst *instr =
+          dyn_cast<ThinFunctionToPointerInst>(convInstr);
+      assert(instr && "Unexpected conversion instruction");
+      newType = getNewSILType(genEnv, instr->getType(), *getIRGenModule());
+      newInstr = convBuilder.createThinFunctionToPointer(
+          instr->getLoc(), instr->getOperand(), newType);
+      break;
+    }
     case ValueKind::ConvertFunctionInst: {
       auto *instr = dyn_cast<ConvertFunctionInst>(convInstr);
       assert(instr && "Unexpected conversion instruction");
@@ -2486,6 +2481,7 @@
                 }
                 break;
               }
+              case ValueKind::ThinFunctionToPointerInst:
               case ValueKind::ThinToThickFunctionInst: {
                 conversionInstrs.insert(currInstr);
                 break;
@@ -2495,6 +2491,10 @@
                 builtinInstrs.insert(instr);
                 break;
               }
+              case ValueKind::DebugValueAddrInst:
+              case ValueKind::DebugValueInst: {
+                break;
+              }
               default:
                 llvm_unreachable("Unhandled use of FunctionRefInst");
               }
diff --git a/lib/Parse/Lexer.cpp b/lib/Parse/Lexer.cpp
index 633e6c4..6e8edae 100644
--- a/lib/Parse/Lexer.cpp
+++ b/lib/Parse/Lexer.cpp
@@ -1491,13 +1491,28 @@
       continue;
     case '\n':
     case '\r': {
-      auto bytes = start + 1;
-      auto length = end-(start+1);
-      
-      auto bytesLoc = Lexer::getSourceLoc(bytes);
-      auto string = StringRef(bytes, length);
-      
-      return std::make_tuple(string, bytesLoc);
+      start++;
+      auto startLoc = Lexer::getSourceLoc(start);
+      auto string = StringRef(start, end - start);
+
+      // Disallow escaped newline in the last line.
+      if (Diags) {
+        auto *Ptr = start - 1;
+        if (*Ptr == '\n') --Ptr;
+        if (*Ptr == '\r') --Ptr;
+        auto *LineEnd = Ptr + 1;
+        while (Ptr > begin && (*Ptr == ' ' || *Ptr == '\t')) --Ptr;
+        if (*Ptr == '\\') {
+          auto escapeLoc = Lexer::getSourceLoc(Ptr);
+          bool invalid = true;
+          while (*--Ptr == '\\') invalid = !invalid;
+          if (invalid)
+            Diags->diagnose(escapeLoc, diag::lex_escaped_newline_at_lastline)
+              .fixItRemoveChars(escapeLoc, Lexer::getSourceLoc(LineEnd));
+        }
+      }
+
+      return std::make_tuple(string, startLoc);
     }
     default:
       sawNonWhitespace = true;
diff --git a/lib/Parse/ParseIfConfig.cpp b/lib/Parse/ParseIfConfig.cpp
index 2f13a7b..a9c56dc 100644
--- a/lib/Parse/ParseIfConfig.cpp
+++ b/lib/Parse/ParseIfConfig.cpp
@@ -583,7 +583,7 @@
         isActive = false;
         isVersionCondition = false;
       } else if (!foundActive) {
-        // Evaludate the condition only if we haven't found any active one.
+        // Evaluate the condition only if we haven't found any active one.
         isActive = evaluateIfConfigCondition(Condition, Context);
         isVersionCondition = isVersionIfConfigCondition(Condition);
       }
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index c73a332..f3f897b 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -1277,7 +1277,7 @@
               diag::expected_expr_conditional;
         auto BoolExpr = parseExprBasic(diagID);
         Status |= BoolExpr;
-        if (BoolExpr.isNull() || BoolExpr.hasCodeCompletion())
+        if (BoolExpr.isNull())
           return Status;
         result.push_back(BoolExpr.get());
         BindingKindStr = StringRef();
@@ -1361,7 +1361,7 @@
       ParserResult<Expr> InitExpr
         = parseExprBasic(diag::expected_expr_conditional_var);
       Status |= InitExpr;
-      if (InitExpr.isNull() || InitExpr.hasCodeCompletion())
+      if (InitExpr.isNull())
         return Status;
       Init = InitExpr.get();
       
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index dace3f7..9440bbb 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -477,8 +477,8 @@
       }
     }
 
-    void visitSelfType(AbstractionPattern origType, CanType substType,
-                       SILFunctionTypeRepresentation rep) {
+    void visitSharedType(AbstractionPattern origType, CanType substType,
+                         SILFunctionTypeRepresentation rep) {
       NextOrigParamIndex++;
 
       auto &substTL =
@@ -548,16 +548,29 @@
                                                    /*canonicalVararg*/true)
                         ->getCanonicalType();
         CanTupleType tty = dyn_cast<TupleType>(ty);
-        if (!tty || (origType.isTypeParameter() && !tty->hasInOutElement())) {
-          visit(origType, ty);
-          return;
-        }
-        
         // If the abstraction pattern is opaque, and the tuple type is
         // materializable -- if it doesn't contain an l-value type -- then it's
         // a valid target for substitution and we should not expand it.
+        if (!tty || (origType.isTypeParameter() && !tty->hasInOutElement())) {
+          auto flags = (params.size() == 1)
+                     ? params.front().getParameterFlags()
+                     : ParameterTypeFlags();
+          if (flags.isShared()) {
+            visitSharedType(origType, ty, extInfo.getSILRepresentation());
+          } else {
+            visit(origType, ty);
+          }
+          return;
+        }
+
         for (auto i : indices(tty.getElementTypes())) {
-          visit(origType.getTupleElementType(i), tty.getElementType(i));
+          if (tty->getElement(i).getParameterFlags().isShared()) {
+            visitSharedType(origType.getTupleElementType(i),
+                            tty.getElementType(i),
+                            extInfo.getSILRepresentation());
+          } else {
+            visit(origType.getTupleElementType(i), tty.getElementType(i));
+          }
         }
         return;
       }
@@ -569,15 +582,19 @@
         CanType ty =  params[i].getType();
         CanTupleType tty = dyn_cast<TupleType>(ty);
         AbstractionPattern eltPattern = origType.getTupleElementType(i);
+        // If the abstraction pattern is opaque, and the tuple type is
+        // materializable -- if it doesn't contain an l-value type -- then it's
+        // a valid target for substitution and we should not expand it.
         if (!tty || (eltPattern.isTypeParameter() && !tty->hasInOutElement())) {
-          visit(eltPattern, ty);
+          if (params[i].getParameterFlags().isShared()) {
+            visitSharedType(eltPattern, ty, extInfo.getSILRepresentation());
+          } else {
+            visit(eltPattern, ty);
+          }
           continue;
         }
         
         assert(eltPattern.isTuple());
-        // If the abstraction pattern is opaque, and the tuple type is
-        // materializable -- if it doesn't contain an l-value type -- then it's
-        // a valid target for substitution and we should not expand it.
         for (unsigned j = 0; j < eltPattern.getNumTupleElements(); ++j) {
           visit(eltPattern.getTupleElementType(j), tty.getElementType(j));
         }
@@ -586,9 +603,9 @@
       // Process the self parameter.  Note that we implicitly drop self
       // if this is a static foreign-self import.
       if (!Foreign.Self.isImportAsMember()) {
-        visitSelfType(origType.getTupleElementType(numNonSelfParams),
-                      params[numNonSelfParams].getType(),
-                      extInfo.getSILRepresentation());
+        visitSharedType(origType.getTupleElementType(numNonSelfParams),
+                        params[numNonSelfParams].getType(),
+                        extInfo.getSILRepresentation());
       }
 
       // Clear the foreign-self handler for safety.
diff --git a/lib/SIL/SILOpenedArchetypesTracker.cpp b/lib/SIL/SILOpenedArchetypesTracker.cpp
index 77cead0..7876a56 100644
--- a/lib/SIL/SILOpenedArchetypesTracker.cpp
+++ b/lib/SIL/SILOpenedArchetypesTracker.cpp
@@ -123,7 +123,12 @@
   assert(I->getFunction() == &F &&
          "Instruction does not belong to a proper SILFunction");
   auto Archetype = getOpenedArchetypeOf(I);
-  if (Archetype)
+  // Remove the archetype definition if it was registered before.
+  // It may happen that this archetype was not registered in the
+  // SILOpenedArchetypesTracker, because the tracker was created
+  // without scanning the whole function and thus may not aware
+  // of all opened archetypes of the function.
+  if (Archetype && getOpenedArchetypeDef(Archetype))
     removeOpenedArchetypeDef(Archetype, I);
 }
 
diff --git a/lib/SIL/SILOwnershipVerifier.cpp b/lib/SIL/SILOwnershipVerifier.cpp
index d2a4452..b3dd8f9 100644
--- a/lib/SIL/SILOwnershipVerifier.cpp
+++ b/lib/SIL/SILOwnershipVerifier.cpp
@@ -195,6 +195,7 @@
   case ValueKind::StructInst:
   case ValueKind::EnumInst:
   case ValueKind::OpenExistentialRefInst:
+  case ValueKind::OpenExistentialValueInst:
   case ValueKind::UpcastInst:
   case ValueKind::UncheckedRefCastInst:
   case ValueKind::ConvertFunctionInst:
@@ -345,9 +346,11 @@
   OwnershipUseCheckerResult visitTransformingTerminatorInst(TermInst *TI);
 
   OwnershipUseCheckerResult
-  visitApplyArgument(ValueOwnershipKind RequiredConvention, bool ShouldCheck);
-  OwnershipUseCheckerResult
   visitNonTrivialEnum(EnumDecl *E, ValueOwnershipKind RequiredConvention);
+  OwnershipUseCheckerResult
+  visitApplyParameter(ValueOwnershipKind RequiredConvention, bool ShouldCheck);
+  OwnershipUseCheckerResult
+  visitFullApply(FullApplySite apply);
 
   /// Check if \p User as compatible ownership with the SILValue that we are
   /// checking.
@@ -449,7 +452,6 @@
 CONSTANT_OWNERSHIP_INST(Owned, true, StrongUnpin)
 CONSTANT_OWNERSHIP_INST(Owned, true, UnownedRelease)
 CONSTANT_OWNERSHIP_INST(Owned, true, InitExistentialRef)
-CONSTANT_OWNERSHIP_INST(Owned, true, OpenExistentialValue)
 CONSTANT_OWNERSHIP_INST(Owned, true, EndLifetime)
 CONSTANT_OWNERSHIP_INST(Trivial, false, AddressToPointer)
 CONSTANT_OWNERSHIP_INST(Trivial, false, BeginAccess)
@@ -649,6 +651,7 @@
 FORWARD_ANY_OWNERSHIP_INST(Struct)
 FORWARD_ANY_OWNERSHIP_INST(Enum)
 FORWARD_ANY_OWNERSHIP_INST(OpenExistentialRef)
+FORWARD_ANY_OWNERSHIP_INST(OpenExistentialValue)
 FORWARD_ANY_OWNERSHIP_INST(Upcast)
 FORWARD_ANY_OWNERSHIP_INST(UncheckedRefCast)
 FORWARD_ANY_OWNERSHIP_INST(ConvertFunction)
@@ -988,8 +991,8 @@
 // non-trivial argument positions. This fits with modeling of a
 // SILFunctionArgument as a phi in a global program graph.
 OwnershipUseCheckerResult
-OwnershipCompatibilityUseChecker::visitApplyArgument(ValueOwnershipKind Kind,
-                                                     bool ShouldCheck) {
+OwnershipCompatibilityUseChecker::visitApplyParameter(ValueOwnershipKind Kind,
+                                                      bool ShouldCheck) {
   // Check if we have an enum. If not, then we just check against the passed in
   // convention.
   EnumDecl *E = getType().getEnumOrBoundGenericEnum();
@@ -999,64 +1002,47 @@
   return visitNonTrivialEnum(E, Kind);
 }
 
-OwnershipUseCheckerResult
-OwnershipCompatibilityUseChecker::visitApplyInst(ApplyInst *I) {
+// Handle Apply and TryApply.
+OwnershipUseCheckerResult OwnershipCompatibilityUseChecker::
+visitFullApply(FullApplySite apply) {
   // If we are visiting the callee, handle it specially.
   if (getOperandIndex() == 0)
-    return visitCallee(I->getSubstCalleeType());
+    return visitCallee(apply.getSubstCalleeType());
 
-  switch (I->getArgumentConvention(getOperandIndex() - 1)) {
-  case SILArgumentConvention::Indirect_In:
-  case SILArgumentConvention::Indirect_In_Constant:
-  case SILArgumentConvention::Indirect_In_Guaranteed:
-  case SILArgumentConvention::Indirect_Inout:
-  case SILArgumentConvention::Indirect_InoutAliasable:
-  case SILArgumentConvention::Indirect_Out:
+  // Indirect return arguments are address types.
+  if (isAddressOrTrivialType())
     return {compatibleWithOwnership(ValueOwnershipKind::Trivial), false};
-  case SILArgumentConvention::Direct_Owned:
-    return visitApplyArgument(ValueOwnershipKind::Owned, true);
-  case SILArgumentConvention::Direct_Unowned:
-    if (isAddressOrTrivialType())
-      return {compatibleWithOwnership(ValueOwnershipKind::Trivial), false};
+
+  unsigned argIndex = apply.getCalleeArgIndex(Op);
+  SILParameterInfo paramInfo =
+    apply.getSubstCalleeConv().getParamInfoForSILArg(argIndex);
+
+  switch (paramInfo.getConvention()) {
+  case ParameterConvention::Indirect_In:
+  case ParameterConvention::Direct_Owned:
+    return visitApplyParameter(ValueOwnershipKind::Owned, true);
+  case ParameterConvention::Indirect_In_Constant:
+  case ParameterConvention::Direct_Unowned:
     // We accept unowned, owned, and guaranteed in unowned positions.
     return {true, false};
-  case SILArgumentConvention::Direct_Guaranteed:
-    return visitApplyArgument(ValueOwnershipKind::Guaranteed, false);
-  case SILArgumentConvention::Direct_Deallocating:
-    llvm_unreachable("No ownership associated with deallocating");
+  case ParameterConvention::Indirect_In_Guaranteed:
+  case ParameterConvention::Direct_Guaranteed:
+    return visitApplyParameter(ValueOwnershipKind::Guaranteed, false);
+  // The following conventions should take address types.
+  case ParameterConvention::Indirect_Inout:
+  case ParameterConvention::Indirect_InoutAliasable:
+    llvm_unreachable("Unexpected non-trivial parameter convention.");
   }
+}
 
-  llvm_unreachable("Unhandled SILArgumentConvention in switch.");
+OwnershipUseCheckerResult
+OwnershipCompatibilityUseChecker::visitApplyInst(ApplyInst *I) {
+  return visitFullApply(I);
 }
 
 OwnershipUseCheckerResult
 OwnershipCompatibilityUseChecker::visitTryApplyInst(TryApplyInst *I) {
-  // If we are visiting the callee, handle it specially.
-  if (getOperandIndex() == 0)
-    return visitCallee(I->getSubstCalleeType());
-
-  switch (I->getArgumentConvention(getOperandIndex() - 1)) {
-  case SILArgumentConvention::Indirect_In:
-  case SILArgumentConvention::Indirect_In_Constant:
-  case SILArgumentConvention::Indirect_In_Guaranteed:
-  case SILArgumentConvention::Indirect_Inout:
-  case SILArgumentConvention::Indirect_InoutAliasable:
-  case SILArgumentConvention::Indirect_Out:
-    return {compatibleWithOwnership(ValueOwnershipKind::Trivial), false};
-  case SILArgumentConvention::Direct_Owned:
-    return visitApplyArgument(ValueOwnershipKind::Owned, true);
-  case SILArgumentConvention::Direct_Unowned:
-    if (isAddressOrTrivialType())
-      return {compatibleWithOwnership(ValueOwnershipKind::Trivial), false};
-    // We accept unowned, owned, and guaranteed in unowned positions.
-    return {true, false};
-  case SILArgumentConvention::Direct_Guaranteed:
-    return visitApplyArgument(ValueOwnershipKind::Guaranteed, false);
-  case SILArgumentConvention::Direct_Deallocating:
-    llvm_unreachable("No ownership associated with deallocating");
-  }
-
-  llvm_unreachable("Unhandled SILArgumentConvention in switch.");
+  return visitFullApply(I);
 }
 
 OwnershipUseCheckerResult
@@ -1150,7 +1136,7 @@
 
 } // end anonymous namespace
 
-// This is correct today since we do not ahve any builtins which return
+// This is correct today since we do not have any builtins which return
 // @guaranteed parameters. This means that we can only have a lifetime ending
 // use with our builtins if it is owned.
 #define CONSTANT_OWNERSHIP_BUILTIN(OWNERSHIP, LIFETIME_ENDING_USE, ID)         \
diff --git a/lib/SIL/TypeLowering.cpp b/lib/SIL/TypeLowering.cpp
index cae5559..d521768 100644
--- a/lib/SIL/TypeLowering.cpp
+++ b/lib/SIL/TypeLowering.cpp
@@ -118,8 +118,9 @@
       // If this is a non-address-only stored 'let' constant, we can capture it
       // by value.  If it is address-only, then we can't load it, so capture it
       // by its address (like a var) instead.
-      if (var->isLet() && (!SILModuleConventions(M).useLoweredAddresses() ||
-                           !getTypeLowering(var->getType()).isAddressOnly()))
+      if ((var->isLet() || var->isShared())
+          && (!SILModuleConventions(M).useLoweredAddresses() ||
+              !getTypeLowering(var->getType()).isAddressOnly()))
         return CaptureKind::Constant;
 
       // In-out parameters are captured by address.
diff --git a/lib/SILGen/ArgumentSource.h b/lib/SILGen/ArgumentSource.h
index 30dbcc5..783c59b 100644
--- a/lib/SILGen/ArgumentSource.h
+++ b/lib/SILGen/ArgumentSource.h
@@ -81,21 +81,22 @@
     }
   };
 
-  static int getStorageIndexForKind(Kind kind) {
+  using StorageMembers =
+    ExternalUnionMembers<void, RValueStorage, LValueStorage,
+                         Expr*, TupleStorage>;
+
+  static StorageMembers::Index getStorageIndexForKind(Kind kind) {
     switch (kind) {
-    case Kind::Invalid: return -1;
-    case Kind::RValue: return 0;
-    case Kind::LValue: return 1;
-    case Kind::Expr: return 2;
-    case Kind::Tuple: return 3;
+    case Kind::Invalid: return StorageMembers::indexOf<void>();
+    case Kind::RValue: return StorageMembers::indexOf<RValueStorage>();
+    case Kind::LValue: return StorageMembers::indexOf<LValueStorage>();
+    case Kind::Expr: return StorageMembers::indexOf<Expr*>();
+    case Kind::Tuple: return StorageMembers::indexOf<TupleStorage>();
     }
     llvm_unreachable("bad kind");
   }
 
-  using StorageType =
-    ExternalUnion<Kind, getStorageIndexForKind,
-                  RValueStorage, LValueStorage, Expr*, TupleStorage>;
-  StorageType Storage;
+  ExternalUnion<Kind, StorageMembers, getStorageIndexForKind> Storage;
   Kind StoredKind;
 
 public:
diff --git a/lib/SILGen/Conversion.h b/lib/SILGen/Conversion.h
index 754cdcd..2dca705 100644
--- a/lib/SILGen/Conversion.h
+++ b/lib/SILGen/Conversion.h
@@ -73,24 +73,25 @@
     CanType SubstType;
   };
 
-  static int getStorageIndexForKind(KindTy kind) {
+  using Members = ExternalUnionMembers<BridgingTypes, ReabstractionTypes>;
+
+  static Members::Index getStorageIndexForKind(KindTy kind) {
     switch (kind) {
     case BridgeToObjC:
     case ForceAndBridgeToObjC:
     case BridgeFromObjC:
     case BridgeResultFromObjC:
     case AnyErasure:
-      return 0;
+      return Members::indexOf<BridgingTypes>();
 
     case OrigToSubst:
     case SubstToOrig:
-      return 1;
+      return Members::indexOf<ReabstractionTypes>();
     }
     llvm_unreachable("bad kind");
   }
 
-  ExternalUnion<KindTy, getStorageIndexForKind,
-                BridgingTypes, ReabstractionTypes> Types;
+  ExternalUnion<KindTy, Members, getStorageIndexForKind> Types;
   static_assert(decltype(Types)::union_is_trivially_copyable,
                 "define the special members if this changes");
 
diff --git a/lib/SILGen/ManagedValue.cpp b/lib/SILGen/ManagedValue.cpp
index 266c758..d270ded 100644
--- a/lib/SILGen/ManagedValue.cpp
+++ b/lib/SILGen/ManagedValue.cpp
@@ -23,7 +23,7 @@
 using namespace Lowering;
 
 /// Emit a copy of this value with independent ownership.
-ManagedValue ManagedValue::copy(SILGenFunction &SGF, SILLocation loc) {
+ManagedValue ManagedValue::copy(SILGenFunction &SGF, SILLocation loc) const {
   auto &lowering = SGF.getTypeLowering(getType());
   if (lowering.isTrivial())
     return *this;
diff --git a/lib/SILGen/ManagedValue.h b/lib/SILGen/ManagedValue.h
index 1937345..30e1735 100644
--- a/lib/SILGen/ManagedValue.h
+++ b/lib/SILGen/ManagedValue.h
@@ -236,7 +236,7 @@
   }
 
   /// Emit a copy of this value with independent ownership.
-  ManagedValue copy(SILGenFunction &SGF, SILLocation loc);
+  ManagedValue copy(SILGenFunction &SGF, SILLocation loc) const;
 
   /// Emit a copy of this value with independent ownership into the current
   /// formal evaluation scope.
diff --git a/lib/SILGen/RValue.cpp b/lib/SILGen/RValue.cpp
index 3dc72b2..705fa84 100644
--- a/lib/SILGen/RValue.cpp
+++ b/lib/SILGen/RValue.cpp
@@ -21,6 +21,7 @@
 #include "Initialization.h"
 #include "SILGenFunction.h"
 #include "swift/AST/CanTypeVisitor.h"
+#include "swift/Basic/STLExtras.h"
 #include "swift/SIL/AbstractionPattern.h"
 #include "swift/SIL/SILArgument.h"
 
@@ -429,6 +430,7 @@
     return;
   }
 
+  verifyConsistentOwnership();
 }
 
 RValue RValue::withPreExplodedElements(ArrayRef<ManagedValue> values,
@@ -450,6 +452,7 @@
 
   ExplodeTupleValue(values, SGF, l).visit(formalType, v);
   assert(values.size() == getRValueSize(type));
+  verifyConsistentOwnership();
 }
 
 RValue::RValue(SILGenFunction &SGF, Expr *expr, ManagedValue v)
@@ -464,6 +467,7 @@
   assert(v && "creating r-value with consumed value");
   ExplodeTupleValue(values, SGF, expr).visit(type, v);
   assert(values.size() == getRValueSize(type));
+  verifyConsistentOwnership();
 }
 
 RValue::RValue(CanType type)
@@ -485,6 +489,7 @@
   element.makeUsed();
 
   assert(!isComplete() || values.size() == getRValueSize(type));
+  verifyConsistentOwnership();
 }
 
 void RValue::addElement(SILGenFunction &SGF, ManagedValue element,
@@ -498,6 +503,7 @@
   ExplodeTupleValue(values, SGF, l).visit(formalType, element);
 
   assert(!isComplete() || values.size() == getRValueSize(type));
+  verifyConsistentOwnership();
 }
 
 SILValue RValue::forwardAsSingleValue(SILGenFunction &SGF, SILLocation l) && {
@@ -672,16 +678,26 @@
   makeUsed();
 }
 
-RValue::RValue(const RValue &copied, SILGenFunction &SGF, SILLocation l)
-  : type(copied.type),
-    elementsToBeAdded(copied.elementsToBeAdded)
-{
-  assert((copied.isComplete() || copied.isInSpecialState())
-         && "can't copy incomplete rvalue");
-  values.reserve(copied.values.size());
-  for (ManagedValue value : copied.values) {
-    values.push_back(value.copy(SGF, l));
+RValue RValue::copy(SILGenFunction &SGF, SILLocation loc) const & {
+  assert((isComplete() || isInSpecialState()) &&
+         "can't copy an incomplete rvalue");
+  std::vector<ManagedValue> copiedValues;
+  copiedValues.reserve(values.size());
+  for (ManagedValue v : values) {
+    copiedValues.emplace_back(v.copy(SGF, loc));
   }
+  return RValue(std::move(copiedValues), type, elementsToBeAdded);
+}
+
+RValue RValue::borrow(SILGenFunction &SGF, SILLocation loc) const & {
+  assert((isComplete() || isInSpecialState()) &&
+         "can't borrow incomplete rvalue");
+  std::vector<ManagedValue> borrowedValues;
+  borrowedValues.reserve(values.size());
+  for (ManagedValue v : values) {
+    borrowedValues.emplace_back(v.borrow(SGF, loc));
+  }
+  return RValue(std::move(borrowedValues), type, elementsToBeAdded);
 }
 
 ManagedValue RValue::materialize(SILGenFunction &SGF, SILLocation loc) && {
@@ -731,6 +747,7 @@
 void RValue::dump() const {
   dump(llvm::errs());
 }
+
 void RValue::dump(raw_ostream &OS, unsigned indent) const {
   if (isInContext()) {
     OS.indent(indent) << "InContext\n";
@@ -742,3 +759,46 @@
     value.dump(OS, indent + 2);
   }
 }
+
+void RValue::verifyConsistentOwnership() const {
+// This is a no-op in non-assert builds.
+#ifndef NDEBUG
+  auto result = Optional<ValueOwnershipKind>(ValueOwnershipKind::Any);
+  Optional<bool> sameHaveCleanups;
+  for (ManagedValue v : values) {
+    ValueOwnershipKind kind = v.getOwnershipKind();
+    if (kind == ValueOwnershipKind::Trivial)
+      continue;
+
+    // Merge together whether or not the RValue has cleanups.
+    if (!sameHaveCleanups.hasValue()) {
+      sameHaveCleanups = v.hasCleanup();
+    } else {
+      assert(*sameHaveCleanups == v.hasCleanup());
+    }
+
+    // This variable is here so that if the assert below fires, the current
+    // reduction value is still available.
+    auto newResult = result.getValue().merge(kind);
+    assert(newResult.hasValue());
+    result = newResult;
+  }
+#endif
+}
+
+bool RValue::isPlusOne(SILGenFunction &SGF) const & {
+  return llvm::all_of(values, [&SGF](ManagedValue mv) -> bool {
+    // Ignore trivial values and objects with trivial value ownership kind.
+    if (mv.getType().isTrivial(SGF.F.getModule()) ||
+        (mv.getType().isObject() &&
+         mv.getOwnershipKind() == ValueOwnershipKind::Trivial))
+      return true;
+    return mv.hasCleanup();
+  });
+}
+
+bool RValue::isPlusZero(SILGenFunction &SGF) const & {
+  return llvm::none_of(values, [&SGF](ManagedValue mv) -> bool {
+    return mv.hasCleanup();
+  });
+}
diff --git a/lib/SILGen/RValue.h b/lib/SILGen/RValue.h
index 1a03c13..bcc71b8 100644
--- a/lib/SILGen/RValue.h
+++ b/lib/SILGen/RValue.h
@@ -33,8 +33,10 @@
 class SILGenFunction;
 
 /// An "exploded" SIL rvalue, in which tuple values are recursively
-/// destructured. (In SILGen we don't try to explode structs, because doing so
-/// would require considering resilience, a job we want to delegate to IRGen).
+/// destructured.
+///
+/// *NOTE* In SILGen we don't try to explode structs, because doing so would
+/// require considering resilience, a job we want to delegate to IRGen.
 class RValue {
   std::vector<ManagedValue> values;
   CanType type;
@@ -60,12 +62,20 @@
     elementsToBeAdded = Used;
     values = {};
   }
-  
-  /// Private constructor used by copy().
-  RValue(const RValue &copied, SILGenFunction &SGF, SILLocation l);
-  
-  /// Construct an RValue from a pre-exploded set of
-  /// ManagedValues. Used to implement the extractElement* methods.
+
+  /// Private constructor used by copy() and borrow().
+  RValue(std::vector<ManagedValue> &&values, CanType type,
+         unsigned elementsToBeAdded)
+      : values(std::move(values)), type(type),
+        elementsToBeAdded(elementsToBeAdded) {
+    verifyConsistentOwnership();
+  }
+
+  /// Construct an RValue from a pre-exploded set of ManagedValues.
+  ///
+  /// Used to implement the extractElement* methods. *NOTE* This constructor
+  /// assumes that the constructed RValue is fully formed and thus has
+  /// elementsToBeAdded set to zero.
   RValue(ArrayRef<ManagedValue> values, CanType type);
 
   RValue(unsigned state) : elementsToBeAdded(state) {
@@ -75,15 +85,14 @@
 public:
   RValue() : elementsToBeAdded(Null) {}
   
-  RValue(RValue &&rv)
-    : values(std::move(rv.values)),
-      type(rv.type),
-      elementsToBeAdded(rv.elementsToBeAdded)
-  {
+  RValue(RValue &&rv) : values(std::move(rv.values)),
+                        type(rv.type),
+                        elementsToBeAdded(rv.elementsToBeAdded) {
     assert((rv.isComplete() || rv.isInSpecialState())
            && "moving rvalue that wasn't complete?!");
     rv.elementsToBeAdded = Used;
   }
+
   RValue &operator=(RValue &&rv) {
     assert((isNull() || isUsed()) && "reassigning an valid rvalue?!");
     
@@ -107,8 +116,9 @@
   /// will be exploded.
   RValue(SILGenFunction &SGF, SILLocation l, CanType type, ManagedValue v);
 
-  /// Construct an RValue from a pre-exploded set of
-  /// ManagedValues. Used to implement the extractElement* methods.
+  /// Construct an RValue from a pre-exploded set of ManagedValues.
+  ///
+  /// This is used to implement the extractElement* methods.
   static RValue withPreExplodedElements(ArrayRef<ManagedValue> values,
                                         CanType type);
 
@@ -194,6 +204,30 @@
     return value;
   }
 
+  /// Returns true if this is an rvalue that can be used safely as a +1 rvalue.
+  ///
+  /// This returns true iff:
+  ///
+  /// 1. All sub-values are trivially typed.
+  /// 2. There exists at least one non-trivial typed sub-value and all such
+  /// sub-values all have cleanups.
+  ///
+  /// *NOTE* Due to 1. isPlusOne and isPlusZero both return true for rvalues
+  /// consisting of only trivial values.
+  bool isPlusOne(SILGenFunction &SGF) const &;
+
+  /// Returns true if this is an rvalue that can be used safely as a +0 rvalue.
+  ///
+  /// Specifically, we return true if:
+  ///
+  /// 1. All sub-values are trivially typed.
+  /// 2. At least 1 subvalue is non-trivial and all such non-trivial values do
+  /// not have a cleanup.
+  ///
+  /// *NOTE* Due to 1. isPlusOne and isPlusZero both return true for rvalues
+  /// consisting of only trivial values.
+  bool isPlusZero(SILGenFunction &SGF) const &;
+
   /// Use this rvalue to initialize an Initialization.
   void forwardInto(SILGenFunction &SGF, SILLocation loc, Initialization *I) &&;
 
@@ -260,15 +294,23 @@
   }
   
   /// Emit an equivalent value with independent ownership.
-  RValue copy(SILGenFunction &SGF, SILLocation l) const & {
-    return RValue(*this, SGF, l);
-  }
+  RValue copy(SILGenFunction &SGF, SILLocation loc) const &;
+
+  /// Borrow all subvalues of the rvalue.
+  RValue borrow(SILGenFunction &SGF, SILLocation loc) const &;
 
   static bool areObviouslySameValue(SILValue lhs, SILValue rhs);
   bool isObviouslyEqual(const RValue &rhs) const;
 
   void dump() const;
   void dump(raw_ostream &OS, unsigned indent = 0) const;
+
+private:
+  /// Assert that all non-trivial ManagedValues in this RValue either all have a
+  /// cleanup or all do not have a cleanup.
+  ///
+  /// *NOTE* This is a no-op in non-assert builds.
+  void verifyConsistentOwnership() const;
 };
 
 } // end namespace Lowering
diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp
index 62ab032..4ca22b5 100644
--- a/lib/SILGen/SILGenApply.cpp
+++ b/lib/SILGen/SILGenApply.cpp
@@ -1988,13 +1988,14 @@
     RValueStorage(ManagedValue rv) : RV(rv) {}
   };
 
-  static int getUnionIndexForValue(KindTy kind) {
-    return (kind <= LastLVKind ? 0 : 1);
+  using ValueMembers = ExternalUnionMembers<RValueStorage, LValueStorage>;
+  static ValueMembers::Index getValueMemberIndexForKind(KindTy kind) {
+    return (kind <= LastLVKind ? ValueMembers::indexOf<LValueStorage>()
+                               : ValueMembers::indexOf<RValueStorage>());
   }
 
   /// Storage for either the l-value or the r-value.
-  ExternalUnion<KindTy, getUnionIndexForValue,
-                LValueStorage, RValueStorage> Value;
+  ExternalUnion<KindTy, ValueMembers, getValueMemberIndexForKind> Value;
 
   LValueStorage &LV() { return Value.get<LValueStorage>(Kind); }
   const LValueStorage &LV() const { return Value.get<LValueStorage>(Kind); }
@@ -2007,19 +2008,22 @@
 
   using PointerAccessInfo = SILGenFunction::PointerAccessInfo;
   using ArrayAccessInfo = SILGenFunction::ArrayAccessInfo;
-  static int getUnionIndexForExtra(KindTy kind) {
+
+  using ExtraMembers =
+    ExternalUnionMembers<void, ArrayAccessInfo, PointerAccessInfo>;
+  static ExtraMembers::Index getExtraMemberIndexForKind(KindTy kind) {
     switch (kind) {
     case LValueToPointer:
-      return 0;
+      return ExtraMembers::indexOf<PointerAccessInfo>();
     case LValueArrayToPointer:
     case RValueArrayToPointer:
-      return 1;
+      return ExtraMembers::indexOf<ArrayAccessInfo>();
     default:
-      return -1;
+      return ExtraMembers::indexOf<void>();
     }
   }
-  ExternalUnion<KindTy, getUnionIndexForExtra,
-                PointerAccessInfo, ArrayAccessInfo> Extra;
+
+  ExternalUnion<KindTy, ExtraMembers, getExtraMemberIndexForKind> Extra;
 
 public:
   DelayedArgument(KindTy kind, LValue &&lv, SILLocation loc)
diff --git a/lib/SILGen/SILGenPoly.cpp b/lib/SILGen/SILGenPoly.cpp
index b849c18..8061364 100644
--- a/lib/SILGen/SILGenPoly.cpp
+++ b/lib/SILGen/SILGenPoly.cpp
@@ -1433,7 +1433,7 @@
       continue;
     }
 
-    if (argTy.getConvention() == ParameterConvention::Direct_Guaranteed) {
+    if (isGuaranteedParameter(argTy.getConvention())) {
       forwardedArgs.push_back(
           gen.emitManagedBeginBorrow(loc, arg.getValue()).getValue());
       continue;
diff --git a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
index 99788a0..05d5735 100644
--- a/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
+++ b/lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp
@@ -134,16 +134,16 @@
 
 /// Returns true on success.
 bool PartialApplyCombiner::allocateTemporaries() {
-  // Copy the original arguments of the partial_apply into
-  // newly created temporaries and use these temporaries instead of
-  // the original arguments afterwards.
-  // This is done to "extend" the life-time of original partial_apply
-  // arguments, as they may be destroyed/deallocated before the last
-  // use by one of the apply instructions.
-  // TODO:
-  // Copy arguments of the partial_apply into new temporaries
-  // only if the lifetime of arguments ends before their uses
-  // by apply instructions.
+  // Copy the original arguments of the partial_apply into newly created
+  // temporaries and use these temporaries instead of the original arguments
+  // afterwards.
+  //
+  // This is done to "extend" the life-time of original partial_apply arguments,
+  // as they may be destroyed/deallocated before the last use by one of the
+  // apply instructions.
+  //
+  // TODO: Copy arguments of the partial_apply into new temporaries only if the
+  // lifetime of arguments ends before their uses by apply instructions.
   bool needsReleases = false;
   CanSILFunctionType PAITy =
     PAI->getCallee()->getType().getAs<SILFunctionType>();
@@ -151,14 +151,15 @@
   // Emit a destroy value for each captured closure argument.
   ArrayRef<SILParameterInfo> Params = PAITy->getParameters();
   auto Args = PAI->getArguments();
-  unsigned Delta = Params.size() - Args.size();
+  Params = Params.drop_front(Params.size() - Args.size());
 
   llvm::SmallVector<std::pair<SILValue, unsigned>, 8> ArgsToHandle;
-  for (unsigned AI = 0, AE = Args.size(); AI != AE; ++AI) {
-    SILValue Arg = Args[AI];
-    SILParameterInfo Param = Params[AI + Delta];
+  for (unsigned i : indices(Args)) {
+    SILValue Arg = Args[i];
+    SILParameterInfo Param = Params[i];
     if (Param.isIndirectMutating())
       continue;
+
     // Create a temporary and copy the argument into it, if:
     // - the argument stems from an alloc_stack
     // - the argument is consumed by the callee and is indirect
@@ -166,10 +167,18 @@
     if (isa<AllocStackInst>(Arg)
         || (Param.isConsumed()
             && PAI->getSubstCalleeConv().isSILIndirect(Param))) {
+      // If the argument has a dependent type, then we can not create a
+      // temporary for it at the beginning of the function, so we must bail.
+      //
+      // TODO: This is because we are inserting alloc_stack at the beginning/end
+      // of functions where the dependent type may not exist yet.
+      if (Arg->getType().hasOpenedExistential())
+        return false;
+
       // If the temporary is non-trivial, we need to release it later.
       if (!Arg->getType().isTrivial(PAI->getModule()))
         needsReleases = true;
-      ArgsToHandle.push_back(std::make_pair(Arg, AI));
+      ArgsToHandle.push_back(std::make_pair(Arg, i));
     }
   }
 
diff --git a/lib/SILOptimizer/Utils/Local.cpp b/lib/SILOptimizer/Utils/Local.cpp
index fedbb0e..686ccc0 100644
--- a/lib/SILOptimizer/Utils/Local.cpp
+++ b/lib/SILOptimizer/Utils/Local.cpp
@@ -9,6 +9,7 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 //
 //===----------------------------------------------------------------------===//
+
 #include "swift/SILOptimizer/Utils/Local.h"
 #include "swift/SILOptimizer/Utils/CFG.h"
 #include "swift/SILOptimizer/Analysis/Analysis.h"
@@ -892,6 +893,55 @@
   }
 }
 
+static SILValue createLifetimeExtendedAllocStack(
+    SILBuilder &Builder, SILLocation Loc, SILValue Arg,
+    ArrayRef<SILBasicBlock *> ExitingBlocks, InstModCallbacks Callbacks) {
+  AllocStackInst *ASI = nullptr;
+  {
+    // Save our insert point and create a new alloc_stack in the initial BB and
+    // dealloc_stack in all exit blocks.
+    auto *OldInsertPt = &*Builder.getInsertionPoint();
+    Builder.setInsertionPoint(Builder.getFunction().begin()->begin());
+    ASI = Builder.createAllocStack(Loc, Arg->getType());
+    Callbacks.CreatedNewInst(ASI);
+
+    for (auto *BB : ExitingBlocks) {
+      Builder.setInsertionPoint(BB->getTerminator());
+      Callbacks.CreatedNewInst(Builder.createDeallocStack(Loc, ASI));
+    }
+    Builder.setInsertionPoint(OldInsertPt);
+  }
+  assert(ASI != nullptr);
+
+  // Then perform a copy_addr [take] [init] right after the partial_apply from
+  // the original address argument to the new alloc_stack that we have
+  // created.
+  Callbacks.CreatedNewInst(
+      Builder.createCopyAddr(Loc, Arg, ASI, IsTake, IsInitialization));
+
+  // Return the new alloc_stack inst that has the appropriate live range to
+  // destroy said values.
+  return ASI;
+}
+
+static bool shouldDestroyPartialApplyCapturedArg(SILValue Arg,
+                                                 SILParameterInfo PInfo,
+                                                 SILModule &M) {
+  // If we have a non-trivial type and the argument is passed in @inout, we do
+  // not need to destroy it here. This is something that is implicit in the
+  // partial_apply design that will be revisited when partial_apply is
+  // redesigned.
+  if (PInfo.isIndirectMutating())
+    return false;
+
+  // If we have a trivial type, we do not need to put in any extra releases.
+  if (Arg->getType().isTrivial(M))
+    return false;
+
+  // We handle all other cases.
+  return true;
+}
+
 // *HEY YOU, YES YOU, PLEASE READ*. Even though a textual partial apply is
 // printed with the convention of the closed over function upon it, all
 // non-inout arguments to a partial_apply are passed at +1. This includes
@@ -902,20 +952,14 @@
 void swift::releasePartialApplyCapturedArg(SILBuilder &Builder, SILLocation Loc,
                                            SILValue Arg, SILParameterInfo PInfo,
                                            InstModCallbacks Callbacks) {
-  // If we have a non-trivial type and the argument is passed in @inout, we do
-  // not need to destroy it here. This is something that is implicit in the
-  // partial_apply design that will be revisited when partial_apply is
-  // redesigned.
-  if (PInfo.isIndirectMutating())
+  if (!shouldDestroyPartialApplyCapturedArg(Arg, PInfo, Builder.getModule()))
     return;
 
-  // If we have a trivial type, we do not need to put in any extra releases.
-  if (Arg->getType().isTrivial(Builder.getModule()))
-    return;
-
-  // Otherwise, we need to destroy the argument. If we have an address, just
-  // emit a destroy_addr.
+  // Otherwise, we need to destroy the argument. If we have an address, we
+  // insert a destroy_addr and return. Any live range issues must have been
+  // dealt with by our caller.
   if (Arg->getType().isAddress()) {
+    // Then emit the destroy_addr for this arg
     SILInstruction *NewInst = Builder.emitDestroyAddrAndFold(Loc, Arg);
     Callbacks.CreatedNewInst(NewInst);
     return;
@@ -959,7 +1003,7 @@
 /// For each captured argument of PAI, decrement the ref count of the captured
 /// argument as appropriate at each of the post dominated release locations
 /// found by Tracker.
-static void releaseCapturedArgsOfDeadPartialApply(PartialApplyInst *PAI,
+static bool releaseCapturedArgsOfDeadPartialApply(PartialApplyInst *PAI,
                                                   ReleaseTracker &Tracker,
                                                   InstModCallbacks Callbacks) {
   SILBuilderWithScope Builder(PAI);
@@ -967,22 +1011,60 @@
   CanSILFunctionType PAITy =
       PAI->getCallee()->getType().getAs<SILFunctionType>();
 
-  // Emit a destroy value for each captured closure argument.
   ArrayRef<SILParameterInfo> Params = PAITy->getParameters();
-  auto Args = PAI->getArguments();
+  llvm::SmallVector<SILValue, 8> Args;
+  for (SILValue v : PAI->getArguments()) {
+    // If any of our arguments contain open existentials, bail. We do not
+    // support this for now so that we can avoid having to re-order stack
+    // locations (a larger change).
+    if (v->getType().hasOpenedExistential())
+      return false;
+    Args.emplace_back(v);
+  }
   unsigned Delta = Params.size() - Args.size();
   assert(Delta <= Params.size() && "Error, more Args to partial apply than "
                                    "params in its interface.");
+  Params = Params.drop_front(Delta);
 
+  llvm::SmallVector<SILBasicBlock *, 2> ExitingBlocks;
+  PAI->getFunction()->findExitingBlocks(ExitingBlocks);
+
+  // Go through our argument list and create new alloc_stacks for each
+  // non-trivial address value. This ensures that the memory location that we
+  // are cleaning up has the same live range as the partial_apply. Otherwise, we
+  // may be inserting destroy_addr of alloc_stack that have already been passed
+  // to a dealloc_stack.
+  for (unsigned i : reversed(indices(Args))) {
+    SILValue Arg = Args[i];
+    SILParameterInfo PInfo = Params[i];
+
+    // If we are not going to destroy this partial_apply, continue.
+    if (!shouldDestroyPartialApplyCapturedArg(Arg, PInfo, Builder.getModule()))
+      continue;
+
+    // If we have an object, we will not have live range issues, just continue.
+    if (Arg->getType().isObject())
+      continue;
+
+    // Now that we know that we have a non-argument address, perform a take-init
+    // of Arg into a lifetime extended alloc_stack
+    Args[i] = createLifetimeExtendedAllocStack(Builder, Loc, Arg, ExitingBlocks,
+                                               Callbacks);
+  }
+
+  // Emit a destroy for each captured closure argument at each final release
+  // point.
   for (auto *FinalRelease : Tracker.getFinalReleases()) {
     Builder.setInsertionPoint(FinalRelease);
-    for (unsigned AI = 0, AE = Args.size(); AI != AE; ++AI) {
-      SILValue Arg = Args[AI];
-      SILParameterInfo Param = Params[AI + Delta];
+    for (unsigned i : indices(Args)) {
+      SILValue Arg = Args[i];
+      SILParameterInfo Param = Params[i];
 
       releasePartialApplyCapturedArg(Builder, Loc, Arg, Param, Callbacks);
     }
   }
+
+  return true;
 }
 
 /// TODO: Generalize this to general objects.
@@ -1007,8 +1089,12 @@
 
   // If we have a partial_apply, release each captured argument at each one of
   // the final release locations of the partial apply.
-  if (auto *PAI = dyn_cast<PartialApplyInst>(Closure))
-    releaseCapturedArgsOfDeadPartialApply(PAI, Tracker, Callbacks);
+  if (auto *PAI = dyn_cast<PartialApplyInst>(Closure)) {
+    // If we can not decrement the ref counts of the dead partial apply for any
+    // reason, bail.
+    if (!releaseCapturedArgsOfDeadPartialApply(PAI, Tracker, Callbacks))
+      return false;
+  }
 
   // Then delete all user instructions.
   for (auto *User : Tracker.getTrackedUsers()) {
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index cc1506f..f3fd510 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -2143,8 +2143,8 @@
 
   /// Produce diagnostic for failures related to unfulfilled requirements
   /// of the generic parameters used as arguments.
-  bool diagnoseArgumentGenericRequirements(TypeChecker &TC, Expr *fnExpr,
-                                           Expr *argExpr,
+  bool diagnoseArgumentGenericRequirements(TypeChecker &TC, Expr *callExpr,
+                                           Expr *fnExpr, Expr *argExpr,
                                            CalleeCandidateInfo &candidates,
                                            ArrayRef<Identifier> argLabels);
 
@@ -3737,8 +3737,9 @@
   // Wrap in String.init
   if (fromType->isEqual(Substring)) {
     if (toType->isEqual(String)) {
-      diag.fixItInsert(expr->getLoc(), "String(");
-      diag.fixItInsertAfter(expr->getSourceRange().End, ")");
+      auto range = expr->getSourceRange();
+      diag.fixItInsert(range.Start, "String(");
+      diag.fixItInsertAfter(range.End, ")");
       return true;
     }
   }
@@ -4597,7 +4598,10 @@
     if (!elExpr) return nullptr; // already diagnosed.
     
     resultElts.push_back(elExpr);
-    resultEltTys.push_back({CS.getType(elExpr), TE->getElementName(i)});
+    auto resFlags =
+        ParameterTypeFlags().withInOut(elExpr->isSemanticallyInOutExpr());
+    resultEltTys.push_back({CS.getType(elExpr)->getInOutObjectType(),
+                            TE->getElementName(i), resFlags});
   }
 
   auto TT = TupleType::get(resultEltTys, CS.getASTContext());
@@ -5914,16 +5918,18 @@
 }
 
 bool FailureDiagnosis::diagnoseArgumentGenericRequirements(
-    TypeChecker &TC, Expr *fnExpr, Expr *argExpr,
+    TypeChecker &TC, Expr *callExpr, Expr *fnExpr, Expr *argExpr,
     CalleeCandidateInfo &candidates, ArrayRef<Identifier> argLabels) {
   if (candidates.closeness != CC_ExactMatch || candidates.size() != 1)
     return false;
 
-  auto DRE = dyn_cast<DeclRefExpr>(fnExpr);
-  if (!DRE)
-    return false;
+  AbstractFunctionDecl *AFD = nullptr;
+  if (auto *DRE = dyn_cast<DeclRefExpr>(fnExpr)) {
+    AFD = dyn_cast<AbstractFunctionDecl>(DRE->getDecl());
+  } else if (auto *candidate = candidates[0].getDecl()) {
+    AFD = dyn_cast<AbstractFunctionDecl>(candidate);
+  }
 
-  auto AFD = dyn_cast<AbstractFunctionDecl>(DRE->getDecl());
   if (!AFD || !AFD->isGeneric() || !AFD->hasInterfaceType())
     return false;
 
@@ -5952,14 +5958,19 @@
   // requirements e.g. <A, B where A.Element == B.Element>.
   for (unsigned i = 0, e = bindings.size(); i != e; ++i) {
     auto param = params[i];
-    auto archetype = param.getType()->getAs<ArchetypeType>();
+    auto paramType = param.getType()->getInOutObjectType();
+
+    auto archetype = paramType->getAs<ArchetypeType>();
     if (!archetype)
       continue;
 
     // Bindings specify the arguments that source the parameter. The only case
     // this returns a non-singular value is when there are varargs in play.
     for (auto argNo : bindings[i]) {
-      auto argType = args[argNo].getType()->getWithoutSpecifierType();
+      auto argType = args[argNo]
+                         .getType()
+                         ->getWithoutSpecifierType()
+                         ->getRValueObjectType();
 
       if (argType->is<ArchetypeType>()) {
         diagnoseUnboundArchetype(archetype, fnExpr);
@@ -5980,18 +5991,89 @@
     return false;
 
   class RequirementsListener : public GenericRequirementsCheckListener {
+    ConstraintSystem &CS;
+    AbstractFunctionDecl *Candidate;
+    TypeSubstitutionFn Substitutions;
+
+    Expr *CallExpr;
+    Expr *FnExpr;
+    Expr *ArgExpr;
+
   public:
+    RequirementsListener(ConstraintSystem &cs, AbstractFunctionDecl *AFD,
+                         TypeSubstitutionFn subs,
+                         Expr *callExpr, Expr *fnExpr, Expr *argExpr)
+        : CS(cs), Candidate(AFD), Substitutions(subs), CallExpr(callExpr),
+          FnExpr(fnExpr), ArgExpr(argExpr) {}
+
     bool shouldCheck(RequirementKind kind, Type first, Type second) override {
       // This means that we have encountered requirement which references
       // generic parameter not used in the arguments, we can't diagnose it here.
       return !(first->hasTypeParameter() || first->isTypeVariableOrMember());
     }
+
+    bool diagnoseUnsatisfiedRequirement(const Requirement &req, Type first,
+                                        Type second) override {
+      Diag<Type, Type, Type, Type, StringRef> note;
+      switch (req.getKind()) {
+      case RequirementKind::Conformance:
+      case RequirementKind::Layout:
+        return false;
+
+      case RequirementKind::Superclass:
+        note = diag::candidate_types_inheritance_requirement;
+        break;
+
+      case RequirementKind::SameType:
+        note = diag::candidate_types_equal_requirement;
+        break;
+      }
+
+      TypeChecker &TC = CS.TC;
+      SmallVector<char, 8> scratch;
+      auto overloadName = Candidate->getFullName().getString(scratch);
+
+      if (isa<BinaryExpr>(CallExpr) && isa<TupleExpr>(ArgExpr)) {
+        auto argTuple = cast<TupleExpr>(ArgExpr);
+        auto lhsExpr = argTuple->getElement(0),
+             rhsExpr = argTuple->getElement(1);
+        auto lhsType = CS.getType(lhsExpr)->getRValueType();
+        auto rhsType = CS.getType(rhsExpr)->getRValueType();
+
+        TC.diagnose(FnExpr->getLoc(), diag::cannot_apply_binop_to_args,
+                    overloadName, lhsType, rhsType)
+            .highlight(lhsExpr->getSourceRange())
+            .highlight(rhsExpr->getSourceRange());
+      } else if (isa<PrefixUnaryExpr>(CallExpr) ||
+                 isa<PostfixUnaryExpr>(CallExpr)) {
+        TC.diagnose(ArgExpr->getLoc(), diag::cannot_apply_unop_to_arg,
+                    overloadName, CS.getType(ArgExpr));
+      } else {
+        bool isInitializer = isa<ConstructorDecl>(Candidate);
+        TC.diagnose(ArgExpr->getLoc(), diag::cannot_call_with_params,
+                    overloadName, getTypeListString(CS.getType(ArgExpr)),
+                    isInitializer);
+      }
+
+      auto rawFirstType = req.getFirstType();
+      auto rawSecondType = req.getSecondType();
+      auto *genericSig = Candidate->getGenericSignature();
+
+      TC.diagnose(Candidate, note, first, second,
+                  rawFirstType, rawSecondType,
+                  genericSig->gatherGenericParamBindingsText(
+                                 {rawFirstType, rawSecondType}, Substitutions));
+      return true;
+    }
   };
 
-  auto dc = env->getOwningDeclContext();
-  RequirementsListener genericReqListener;
+  auto *dc = env->getOwningDeclContext();
+  auto substitutionFn = QueryTypeSubstitutionMap{substitutions};
+  RequirementsListener genericReqListener(CS, AFD, substitutionFn,
+                                          callExpr, fnExpr, argExpr);
+
   auto result = TC.checkGenericArguments(
-      dc, argExpr->getLoc(), AFD->getLoc(), AFD->getInterfaceType(),
+      dc, callExpr->getLoc(), fnExpr->getLoc(), AFD->getInterfaceType(),
       env->getGenericSignature(), QueryTypeSubstitutionMap{substitutions},
       LookUpConformanceInModule{dc->getParentModule()}, nullptr,
       ConformanceCheckFlags::SuppressDependencyTracking, &genericReqListener);
@@ -6682,6 +6764,10 @@
       }
     }
 
+    if (diagnoseArgumentGenericRequirements(CS.TC, callExpr, fnExpr, argExpr,
+                                            calleeInfo, argLabels))
+      return true;
+
     if (isContextualConversionFailure(argTuple))
       return false;
 
@@ -6715,13 +6801,13 @@
     return true;
   }
 
-  // If all of the arguments are a perfect match, so let's check if there
+  // If all of the arguments are a perfect match, let's check if there
   // are problems with requirements placed on generic parameters, because
   // CalleeCandidateInfo validates only conformance of the parameters
   // to their protocol types (if any) but it doesn't check additional
   // requirements placed on e.g. nested types or between parameters.
-  if (diagnoseArgumentGenericRequirements(CS.TC, fnExpr, argExpr, calleeInfo,
-                                          argLabels))
+  if (diagnoseArgumentGenericRequirements(CS.TC, callExpr, fnExpr, argExpr,
+                                          calleeInfo, argLabels))
     return true;
 
   if (isContextualConversionFailure(argExpr))
@@ -8443,7 +8529,7 @@
   }
 
   if (result.UnviableCandidates.empty() && isInitializer &&
-      !baseObjTy->is<MetatypeType>()) {
+      !baseObjTy->is<AnyMetatypeType>()) {
     if (auto ctorRef = dyn_cast<UnresolvedDotExpr>(E)) {
       // Diagnose 'super.init', which can only appear inside another
       // initializer, specially.
diff --git a/lib/Sema/CSRanking.cpp b/lib/Sema/CSRanking.cpp
index 5ee2585..71f9f57 100644
--- a/lib/Sema/CSRanking.cpp
+++ b/lib/Sema/CSRanking.cpp
@@ -155,57 +155,6 @@
   llvm_unreachable("Unhandled OverloadChoiceKind in switch.");
 }
 
-/// Compare two declarations to determine whether one is a witness of the other.
-static Comparison compareWitnessAndRequirement(TypeChecker &tc, DeclContext *dc,
-                                               ValueDecl *decl1,
-                                               ValueDecl *decl2) {
-  // We only have a witness/requirement pair if exactly one of the declarations
-  // comes from a protocol.
-  auto proto1 = dyn_cast<ProtocolDecl>(decl1->getDeclContext());
-  auto proto2 = dyn_cast<ProtocolDecl>(decl2->getDeclContext());
-  if ((bool)proto1 == (bool)proto2)
-    return Comparison::Unordered;
-
-  // Figure out the protocol, requirement, and potential witness.
-  ProtocolDecl *proto;
-  ValueDecl *req;
-  ValueDecl *potentialWitness;
-  if (proto1) {
-    proto = proto1;
-    req = decl1;
-    potentialWitness = decl2;
-  } else {
-    proto = proto2;
-    req = decl2;
-    potentialWitness = decl1;
-  }
-
-  // Cannot compare type declarations this way.
-  // FIXME: Use the same type-substitution approach as lookupMemberType.
-  if (isa<TypeDecl>(req))
-    return Comparison::Unordered;
-
-  if (!potentialWitness->getDeclContext()->isTypeContext())
-    return Comparison::Unordered;
-
-  // Determine whether the type of the witness's context conforms to the
-  // protocol.
-  auto owningType
-    = potentialWitness->getDeclContext()->getDeclaredInterfaceType();
-  auto conformance = tc.conformsToProtocol(owningType, proto, dc,
-                                           ConformanceCheckFlags::InExpression);
-  if (!conformance || conformance->isAbstract())
-    return Comparison::Unordered;
-
-  // If the witness and the potential witness are not the same, there's no
-  // ordering here.
-  if (conformance->getConcrete()->getWitnessDecl(req, &tc) != potentialWitness)
-    return Comparison::Unordered;
-
-  // We have a requirement/witness match.
-  return proto1? Comparison::Worse : Comparison::Better;
-}
-
 namespace {
   /// Describes the relationship between the context types for two declarations.
   enum class SelfTypeRelationship {
@@ -504,18 +453,6 @@
           return subscript2->isGeneric();
       }
 
-      // A witness is always more specialized than the requirement it satisfies.
-      switch (compareWitnessAndRequirement(tc, dc, decl1, decl2)) {
-      case Comparison::Unordered:
-        break;
-
-      case Comparison::Better:
-        return true;
-
-      case Comparison::Worse:
-        return false;
-      }
-
       // Members of protocol extensions have special overloading rules.
       ProtocolDecl *inProtocolExtension1 = outerDC1
                                              ->getAsProtocolExtensionContext();
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 803326b..cd89720 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -1167,7 +1167,7 @@
     SmallVector<LocatorPathElt, 4> path;
     locator.getLocatorParts(path);
 
-    // Find the last path element, skipping OptioanlPayload elements
+    // Find the last path element, skipping OptionalPayload elements
     // so that we allow this exception in cases of optional injection.
     auto last = std::find_if(
         path.rbegin(), path.rend(), [](LocatorPathElt &elt) -> bool {
@@ -3092,11 +3092,6 @@
     if (includeInaccessibleMembers)
       lookupOptions |= NameLookupFlags::IgnoreAccessibility;
 
-    // If a constructor is only visible as a witness for a protocol
-    // requirement, it must be an invalid override. Also, protocol
-    // extensions cannot yet define designated initializers.
-    lookupOptions -= NameLookupFlags::PerformConformanceCheck;
-
     LookupResult ctors = TC.lookupConstructors(DC, instanceTy, lookupOptions);
     if (!ctors)
       return result;    // No result.
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index 5df8a1a..40e5346 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -1644,6 +1644,11 @@
                                           ProtocolConformanceRef conformance) {
 }
 
+bool GenericRequirementsCheckListener::diagnoseUnsatisfiedRequirement(
+    const Requirement &req, Type first, Type second) {
+  return false;
+}
+
 bool TypeChecker::
 solveForExpression(Expr *&expr, DeclContext *dc, Type convertType,
                    FreeTypeVariableBinding allowFreeTypeVariables,
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 40eceac..6573668 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -8505,7 +8505,7 @@
     auto argumentName = argumentNames.front();
     if (baseName.getIdentifier() == Context.Id_init &&
         argumentName == Context.Id_from) {
-      // init(from:) may be synthesized as part of derived confromance to the
+      // init(from:) may be synthesized as part of derived conformance to the
       // Decodable protocol.
       // If the target should conform to the Decodable protocol, check the
       // conformance here to attempt synthesis.
@@ -8513,7 +8513,7 @@
       (void)evaluateTargetConformanceTo(decodableProto);
     } else if (baseName.getIdentifier() == Context.Id_encode &&
                argumentName == Context.Id_to) {
-      // encode(to:) may be synthesized as part of derived confromance to the
+      // encode(to:) may be synthesized as part of derived conformance to the
       // Encodable protocol.
       // If the target should conform to the Encodable protocol, check the
       // conformance here to attempt synthesis.
diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp
index cd4a8f7..270298e 100644
--- a/lib/Sema/TypeCheckGeneric.cpp
+++ b/lib/Sema/TypeCheckGeneric.cpp
@@ -190,7 +190,7 @@
     return DependentMemberType::get(baseTy, assocType);
   }
 
-  // Otherwise, the nested type comes from a concrete tpye. Substitute the
+  // Otherwise, the nested type comes from a concrete type. Substitute the
   // base type into it.
   auto concrete = ref->getBoundDecl();
   TC.validateDeclForNameLookup(concrete);
@@ -1231,9 +1231,13 @@
       secondType = req->getSecondType();
     }
 
+    bool requirementFailure = false;
     if (listener && !listener->shouldCheck(kind, firstType, secondType))
       continue;
 
+    Diag<Type, Type, Type> diagnostic;
+    Diag<Type, Type, StringRef> diagnosticNote;
+
     switch (kind) {
     case RequirementKind::Conformance: {
       // Protocol conformance requirements.
@@ -1242,6 +1246,8 @@
       // or non-private dependency.
       // FIXME: Do we really need "used" at this point?
       // FIXME: Poor location information. How much better can we do here?
+      // FIXME: This call should support listener to be able to properly
+      //        diagnose problems with conformances.
       auto result =
           conformsToProtocol(firstType, proto->getDecl(), dc,
                              conformanceOptions, loc, unsatisfiedDependency);
@@ -1274,37 +1280,37 @@
     case RequirementKind::Superclass:
       // Superclass requirements.
       if (!isSubclassOf(firstType, secondType, dc)) {
-        if (loc.isValid()) {
-          // FIXME: Poor source-location information.
-          diagnose(loc, diag::type_does_not_inherit, owner, firstType,
-                   secondType);
-
-          diagnose(noteLoc, diag::type_does_not_inherit_requirement,
-                   rawFirstType, rawSecondType,
-                   genericSig->gatherGenericParamBindingsText(
-                       {rawFirstType, rawSecondType}, substitutions));
-        }
-
-        return RequirementCheckResult::Failure;
+        diagnostic = diag::type_does_not_inherit;
+        diagnosticNote = diag::type_does_not_inherit_requirement;
+        requirementFailure = true;
       }
-      continue;
+      break;
 
     case RequirementKind::SameType:
       if (!firstType->isEqual(secondType)) {
-        if (loc.isValid()) {
-          // FIXME: Better location info for both diagnostics.
-          diagnose(loc, diag::types_not_equal, owner, firstType, secondType);
-
-          diagnose(noteLoc, diag::types_not_equal_requirement, rawFirstType,
-                   rawSecondType,
-                   genericSig->gatherGenericParamBindingsText(
-                       {rawFirstType, rawSecondType}, substitutions));
-        }
-
-        return RequirementCheckResult::Failure;
+        diagnostic = diag::types_not_equal;
+        diagnosticNote = diag::types_not_equal_requirement;
+        requirementFailure = true;
       }
-      continue;
+      break;
     }
+
+    if (!requirementFailure)
+      continue;
+
+    if (listener &&
+        listener->diagnoseUnsatisfiedRequirement(rawReq, firstType, secondType))
+      return RequirementCheckResult::Failure;
+
+    if (loc.isValid()) {
+      // FIXME: Poor source-location information.
+      diagnose(loc, diagnostic, owner, firstType, secondType);
+      diagnose(noteLoc, diagnosticNote, rawFirstType, rawSecondType,
+               genericSig->gatherGenericParamBindingsText(
+                   {rawFirstType, rawSecondType}, substitutions));
+    }
+
+    return RequirementCheckResult::Failure;
   }
 
   if (valid)
diff --git a/lib/Sema/TypeCheckNameLookup.cpp b/lib/Sema/TypeCheckNameLookup.cpp
index fc12558..88a0981 100644
--- a/lib/Sema/TypeCheckNameLookup.cpp
+++ b/lib/Sema/TypeCheckNameLookup.cpp
@@ -16,6 +16,7 @@
 //
 //===----------------------------------------------------------------------===//
 #include "TypeChecker.h"
+#include "swift/AST/ExistentialLayout.h"
 #include "swift/AST/Initializer.h"
 #include "swift/AST/NameLookup.h"
 #include "swift/AST/ProtocolConformance.h"
@@ -121,52 +122,70 @@
       if (!Options.contains(NameLookupFlags::ProtocolMembers) ||
           !isa<ProtocolDecl>(foundDC) ||
           isa<GenericTypeParamDecl>(found) ||
-          (isa<FuncDecl>(found) && cast<FuncDecl>(found)->isOperator()) ||
-          foundInType->isAnyExistentialType()) {
+          (isa<FuncDecl>(found) && cast<FuncDecl>(found)->isOperator())) {
         addResult(found);
         return;
       }
 
       assert(isa<ProtocolDecl>(foundDC));
 
+      if (!Options.contains(NameLookupFlags::PerformConformanceCheck))
+        return;
+
       // If we found something within the protocol itself, and our
       // search began somewhere that is not in a protocol or extension
       // thereof, remap this declaration to the witness.
-      if (foundInType->is<ArchetypeType>() ||
-          Options.contains(NameLookupFlags::PerformConformanceCheck)) {
-        // Dig out the protocol conformance.
-        auto conformance = TC.conformsToProtocol(foundInType, foundProto, DC,
+      auto conformingType = foundInType;
+
+      // When performing a lookup on a subclass existential, we might
+      // find a member of the class that witnesses a requirement on a
+      // protocol that the class conforms to.
+      //
+      // Since subclass existentials don't normally conform to protocols,
+      // pull out the superclass instead, and use that below.
+      if (foundInType->isExistentialType()) {
+        auto layout = foundInType->getExistentialLayout();
+        if (layout.superclass)
+          conformingType = layout.superclass;
+      }
+
+      // Dig out the protocol conformance.
+      auto conformance = TC.conformsToProtocol(conformingType, foundProto, DC,
                                                  conformanceOptions);
-        if (!conformance)
-          return;
-
-        if (conformance->isAbstract()) {
-          assert(foundInType->is<ArchetypeType>());
-          addResult(found);
-          return;
-        }
-
-        // If we're validating the protocol recursively, bail out.
-        if (!foundProto->hasValidSignature())
-          return;
-
-        // Dig out the witness.
-        ValueDecl *witness = nullptr;
-        auto concrete = conformance->getConcrete();
-        if (auto assocType = dyn_cast<AssociatedTypeDecl>(found)) {
-          witness = concrete->getTypeWitnessAndDecl(assocType, &TC)
-            .second;
-        } else if (found->isProtocolRequirement()) {
-          witness = concrete->getWitnessDecl(found, &TC);
-        }
-
-        // FIXME: the "isa<ProtocolDecl>()" check will be wrong for
-        // default implementations in protocols.
-        if (witness && !isa<ProtocolDecl>(witness->getDeclContext()))
-          addResult(witness);
-
+      if (!conformance) {
+        // If there's no conformance, we have an existential
+        // and we found a member from one of the protocols, and
+        // not a class constraint if any.
+        assert(foundInType->isExistentialType());
+        addResult(found);
         return;
       }
+
+      if (conformance->isAbstract()) {
+        assert(foundInType->is<ArchetypeType>() ||
+               foundInType->isExistentialType());
+        addResult(found);
+        return;
+      }
+
+      // Dig out the witness.
+      ValueDecl *witness = nullptr;
+      auto concrete = conformance->getConcrete();
+      if (auto assocType = dyn_cast<AssociatedTypeDecl>(found)) {
+        witness = concrete->getTypeWitnessAndDecl(assocType, &TC)
+          .second;
+      } else if (found->isProtocolRequirement()) {
+        witness = concrete->getWitnessDecl(found, &TC);
+      }
+
+      // FIXME: the "isa<ProtocolDecl>()" check will be wrong for
+      // default implementations in protocols.
+      //
+      // If we have an imported conformance or the witness could
+      // not be deserialized, getWitnessDecl() will just return
+      // the requirement, so just drop the lookup result here.
+      if (witness && !isa<ProtocolDecl>(witness->getDeclContext()))
+        addResult(witness);
     }
   };
 } // end anonymous namespace
@@ -256,8 +275,6 @@
   if (options.contains(NameLookupFlags::IgnoreAccessibility))
     subOptions |= NL_IgnoreAccessibility;
 
-  NominalTypeDecl *nominalLookupType = type->getAnyNominal();
-
   if (options.contains(NameLookupFlags::ProtocolMembers))
     subOptions |= NL_ProtocolMembers;
 
@@ -265,40 +282,13 @@
   subOptions &= ~NL_RemoveOverridden;
   subOptions &= ~NL_RemoveNonVisible;
 
-  // Local function that performs lookup.
-  auto doLookup = [&]() {
-    result.clear();
+  LookupResultBuilder builder(*this, result, dc, options,
+                              /*memberLookup*/true);
+  SmallVector<ValueDecl *, 4> lookupResults;
+  dc->lookupQualified(type, name, subOptions, this, lookupResults);
 
-    LookupResultBuilder builder(*this, result, dc, options,
-                                /*memberLookup*/true);
-    SmallVector<ValueDecl *, 4> lookupResults;
-    dc->lookupQualified(type, name, subOptions, this, lookupResults);
-
-    for (auto found : lookupResults) {
-      // FIXME: This should pass in 'dc'
-      builder.add(found, nominalLookupType, type);
-    }
-  };
-
-  doLookup();
-
-  if (result.empty()) {
-    // If we didn't find anything, /and/ this is a nominal type, check to see
-    // if any of the nominal's protocols are derivable and contain the
-    // name we're looking for. (Note that we are not including extensions
-    // here -- default derivation doesn't apply in extensions.)
-    if (!nominalLookupType)
-      return result;
-    
-    // Force the creation of any delayed members, to ensure proper member
-    // lookup.
-    this->forceExternalDeclMembers(nominalLookupType);
-
-    // Perform the lookup again.
-    // FIXME: This is only because forceExternalDeclMembers() might do something
-    // interesting.
-    doLookup();
-  }
+  for (auto found : lookupResults)
+    builder.add(found, nullptr, type);
 
   return result;
 }
diff --git a/lib/Sema/TypeCheckPattern.cpp b/lib/Sema/TypeCheckPattern.cpp
index 477b431..5267319 100644
--- a/lib/Sema/TypeCheckPattern.cpp
+++ b/lib/Sema/TypeCheckPattern.cpp
@@ -74,7 +74,7 @@
 /// an arbitrary property to an enum element using extractEnumElement.
 static EnumElementDecl *
 filterForEnumElement(TypeChecker &TC, DeclContext *DC, SourceLoc UseLoc,
-                     LookupResult foundElements) {
+                     bool unqualifiedLookup, LookupResult foundElements) {
   EnumElementDecl *foundElement = nullptr;
   VarDecl *foundConstant = nullptr;
 
@@ -85,9 +85,11 @@
       continue;
     }
     // Skip if the enum element was referenced as an instance member
-    if (!result.getBaseDecl() ||
-        !result.getBaseDecl()->getInterfaceType()->is<MetatypeType>()) {
-      continue;
+    if (unqualifiedLookup) {
+      if (!result.getBaseDecl() ||
+          !result.getBaseDecl()->getInterfaceType()->is<MetatypeType>()) {
+        continue;
+      }
     }
 
     if (auto *oe = dyn_cast<EnumElementDecl>(e)) {
@@ -116,20 +118,24 @@
   auto lookupOptions = defaultUnqualifiedLookupOptions;
   lookupOptions |= NameLookupFlags::KnownPrivate;
   auto lookup = TC.lookupUnqualified(DC, name, SourceLoc(), lookupOptions);
-  return filterForEnumElement(TC, DC, UseLoc, lookup);
+  return filterForEnumElement(TC, DC, UseLoc,
+                              /*unqualifiedLookup=*/true, lookup);
 }
 
 /// Find an enum element in an enum type.
 static EnumElementDecl *
 lookupEnumMemberElement(TypeChecker &TC, DeclContext *DC, Type ty,
                         Identifier name, SourceLoc UseLoc) {
-  assert(ty->getAnyNominal());
+  if (!ty->mayHaveMembers())
+    return nullptr;
+
   // Look up the case inside the enum.
   // FIXME: We should be able to tell if this is a private lookup.
   NameLookupOptions lookupOptions
     = defaultMemberLookupOptions - NameLookupFlags::DynamicLookup;
   LookupResult foundElements = TC.lookupMember(DC, ty, name, lookupOptions);
-  return filterForEnumElement(TC, DC, UseLoc, foundElements);
+  return filterForEnumElement(TC, DC, UseLoc,
+                              /*unqualifiedLookup=*/false, foundElements);
 }
 
 namespace {
@@ -1311,10 +1317,8 @@
     
     Type enumTy;
     if (!elt) {
-      if (type->getAnyNominal()) {
-        elt = lookupEnumMemberElement(*this, dc, type, EEP->getName(),
-                                      EEP->getLoc());
-      }
+      elt = lookupEnumMemberElement(*this, dc, type, EEP->getName(),
+                                    EEP->getLoc());
       if (!elt) {
         if (!type->hasError()) {
           // Lowercasing of Swift.Optional's cases is handled in the
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index b80eb73..acc9164 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -3034,7 +3034,7 @@
   if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(member)) {
     // FIXME: If this is a protocol typealias and we haven't built the
     // protocol's generic environment yet, do so now, to ensure the
-    // typealias's underlying type has fully resoved dependent
+    // typealias's underlying type has fully resolved dependent
     // member types.
     if (auto *protoDecl = dyn_cast<ProtocolDecl>(aliasDecl->getDeclContext()))
       if (protoDecl->getGenericEnvironment() == nullptr)
diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h
index f30ae90..639ec65 100644
--- a/lib/Sema/TypeChecker.h
+++ b/lib/Sema/TypeChecker.h
@@ -375,6 +375,20 @@
   /// \param conformance The conformance itself.
   virtual void satisfiedConformance(Type depTy, Type replacementTy,
                                     ProtocolConformanceRef conformance);
+
+  /// Callback to diagnose problem with unsatisfied generic requirement.
+  ///
+  /// \param req The unsatisfied generic requirement.
+  ///
+  /// \param first The left-hand side type assigned to the requirement,
+  /// possibly represented by its generic substitute.
+  ///
+  /// \param second The right-hand side type assigned to the requirement,
+  /// possibly represented by its generic substitute.
+  ///
+  /// \returns true if problem has been diagnosed, false otherwise.
+  virtual bool diagnoseUnsatisfiedRequirement(const Requirement &req,
+                                              Type first, Type second);
 };
 
 /// The result of `checkGenericRequirement`.
@@ -835,7 +849,7 @@
   /// Intended for debugging purposes only.
   unsigned WarnLongFunctionBodies = 0;
 
-  /// If non-zero, warn when type-chcking an expression takes longer
+  /// If non-zero, warn when type-checking an expression takes longer
   /// than this many milliseconds.
   ///
   /// Intended for debugging purposes only.
@@ -914,7 +928,7 @@
     ExpressionTimeoutThreshold = timeInSeconds;
   }
 
-  /// Return the current settting for the threshold that determines
+  /// Return the current setting for the threshold that determines
   /// the upper bound for the number of seconds we'll let the
   /// expression type checker run before considering an expression
   /// "too complex".
diff --git a/stdlib/private/StdlibUnicodeUnittest/Collation.swift b/stdlib/private/StdlibUnicodeUnittest/Collation.swift
index 0080995..d1e04ee 100644
--- a/stdlib/private/StdlibUnicodeUnittest/Collation.swift
+++ b/stdlib/private/StdlibUnicodeUnittest/Collation.swift
@@ -338,13 +338,13 @@
 
 public func sortKey(forCollationElements ces: [UInt64]) -> ([UInt16], [UInt16], [UInt16]) {
   func L1(_ ce: UInt64) -> UInt16 {
-    return UInt16(extendingOrTruncating: ce &>> 32)
+    return UInt16(truncatingIfNeeded: ce &>> 32)
   }
   func L2(_ ce: UInt64) -> UInt16 {
-    return UInt16(extendingOrTruncating: ce &>> 16)
+    return UInt16(truncatingIfNeeded: ce &>> 16)
   }
   func L3(_ ce: UInt64) -> UInt16 {
-    return UInt16(extendingOrTruncating: ce)
+    return UInt16(truncatingIfNeeded: ce)
   }
 
   var result1: [UInt16] = []
diff --git a/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb b/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb
index f2d357b..5c391f3 100644
--- a/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb
+++ b/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb
@@ -28,6 +28,19 @@
 import ObjectiveC
 #endif
 
+extension String {
+  /// Returns the lines in `self`.
+  public var _lines : [String] {
+    return _split(separator: "\n")
+  }
+
+  /// Splits `self` at occurrences of `separator`.
+  public func _split(separator: Unicode.Scalar) -> [String] {
+    let scalarSlices = unicodeScalars.split { $0 == separator }
+    return scalarSlices.map { String(String.UnicodeScalarView($0)) }
+  }
+}
+
 public struct SourceLoc {
   public let file: String
   public let line: UInt
diff --git a/stdlib/public/SDK/ARKit/ARKit.swift b/stdlib/public/SDK/ARKit/ARKit.swift
index c0189f8..83b4b25 100644
--- a/stdlib/public/SDK/ARKit/ARKit.swift
+++ b/stdlib/public/SDK/ARKit/ARKit.swift
@@ -19,6 +19,9 @@
      */
     public enum TrackingState {
         public enum Reason {
+            /** Tracking is limited due to initialization in progress. */
+            case initializing
+            
             /** Tracking is limited due to a excessive motion of the camera. */
             case excessiveMotion
             
@@ -47,6 +50,7 @@
             let reason: TrackingState.Reason
             
             switch __trackingStateReason {
+            case .initializing: reason = .initializing
             case .excessiveMotion: reason = .excessiveMotion
             default: reason = .insufficientFeatures
             }
diff --git a/stdlib/public/SDK/AVFoundation/AVCaptureDevice.swift b/stdlib/public/SDK/AVFoundation/AVCaptureDevice.swift
new file mode 100644
index 0000000..c531176
--- /dev/null
+++ b/stdlib/public/SDK/AVFoundation/AVCaptureDevice.swift
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 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
+//
+//===----------------------------------------------------------------------===//
+
+@_exported import AVFoundation // Clang module
+import Foundation
+
+
+#if os(iOS)
+
+internal protocol _AVCaptureDeviceFormatSupportedColorSpaces {
+  @available(iOS, introduced: 10.0)
+  var __supportedColorSpaces: [NSNumber] { get }
+}
+
+extension _AVCaptureDeviceFormatSupportedColorSpaces {
+  @available(swift, obsoleted: 4.0)
+  @available(iOS, introduced: 10.0)
+  @nonobjc
+  public var supportedColorSpaces: [NSNumber]! {
+    return __supportedColorSpaces
+  }
+  
+  @available(swift, introduced: 4.0)
+  @available(iOS, introduced: 10.0)
+  @nonobjc
+  public var supportedColorSpaces: [AVCaptureColorSpace] {
+    return __supportedColorSpaces.map { AVCaptureColorSpace(rawValue: $0.intValue)! }
+  }
+}
+
+@available(iOS, introduced: 10.0)
+extension AVCaptureDevice.Format : _AVCaptureDeviceFormatSupportedColorSpaces {
+}
+  
+#endif
+
diff --git a/stdlib/public/SDK/AVFoundation/AVCapturePhotoOutput.swift b/stdlib/public/SDK/AVFoundation/AVCapturePhotoOutput.swift
new file mode 100644
index 0000000..705d949
--- /dev/null
+++ b/stdlib/public/SDK/AVFoundation/AVCapturePhotoOutput.swift
@@ -0,0 +1,98 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 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
+//
+//===----------------------------------------------------------------------===//
+
+@_exported import AVFoundation // Clang module
+import Foundation
+
+
+#if os(iOS)
+
+internal protocol _AVCapturePhotoOutputSwiftNativeTypes {
+  var __supportedFlashModes: [NSNumber] { get }
+  var __availablePhotoPixelFormatTypes: [NSNumber] { get }
+  var __availableRawPhotoPixelFormatTypes: [NSNumber] { get }
+}
+
+extension _AVCapturePhotoOutputSwiftNativeTypes {
+  @available(swift, obsoleted: 4.0)
+  @available(iOS, introduced: 10.0)
+  @nonobjc
+  public var supportedFlashModes: [NSNumber] {
+    return __supportedFlashModes
+  }
+  
+  @available(swift, introduced: 4.0)
+  @available(iOS, introduced: 10.0)
+  @nonobjc
+  public var supportedFlashModes: [AVCaptureDevice.FlashMode] {
+    return __supportedFlashModes.map { AVCaptureDevice.FlashMode(rawValue: $0.intValue)! }
+  }
+  
+  @available(swift, obsoleted: 4.0)
+  @available(iOS, introduced: 10.0)
+  @nonobjc
+  public var availablePhotoPixelFormatTypes: [NSNumber] {
+    return __availablePhotoPixelFormatTypes
+  }
+  
+  @available(swift, introduced: 4.0)
+  @available(iOS, introduced: 10.0)
+  @nonobjc
+  public var availablePhotoPixelFormatTypes: [OSType] {
+    return __availablePhotoPixelFormatTypes.map { $0.uint32Value } as [OSType]
+  }
+  
+  @available(swift, obsoleted: 4.0)
+  @available(iOS, introduced: 10.0)
+  @nonobjc
+  public var availableRawPhotoPixelFormatTypes: [NSNumber] {
+    return __availableRawPhotoPixelFormatTypes
+  }
+  
+  @available(swift, introduced: 4.0)
+  @available(iOS, introduced: 10.0)
+  @nonobjc
+  public var availableRawPhotoPixelFormatTypes: [OSType] {
+    return __availableRawPhotoPixelFormatTypes.map { $0.uint32Value } as [OSType]
+  }
+}
+
+@available(iOS, introduced: 10.0)
+extension AVCapturePhotoOutput : _AVCapturePhotoOutputSwiftNativeTypes {
+}
+
+
+internal protocol _AVCapturePhotoSettingsSwiftNativeTypes {
+  var __availablePreviewPhotoPixelFormatTypes: [NSNumber] { get }
+}
+
+extension _AVCapturePhotoSettingsSwiftNativeTypes {
+  @available(swift, obsoleted: 4.0)
+  @available(iOS, introduced: 10.0)
+  @nonobjc
+  public var availablePreviewPhotoPixelFormatTypes: [NSNumber] {
+    return __availablePreviewPhotoPixelFormatTypes
+  }
+
+  @available(swift, introduced: 4.0)
+  @available(iOS, introduced: 10.0)
+  @nonobjc
+  public var availablePreviewPhotoPixelFormatTypes: [OSType] {
+    return __availablePreviewPhotoPixelFormatTypes.map { $0.uint32Value } as [OSType]
+  }
+}
+
+@available(iOS, introduced: 10.0)
+extension AVCapturePhotoSettings : _AVCapturePhotoSettingsSwiftNativeTypes {
+}
+
+#endif
diff --git a/stdlib/public/SDK/AVFoundation/AVCaptureSynchronizedDataCollection.swift b/stdlib/public/SDK/AVFoundation/AVCaptureSynchronizedDataCollection.swift
index 3839c10..a17beb1 100644
--- a/stdlib/public/SDK/AVFoundation/AVCaptureSynchronizedDataCollection.swift
+++ b/stdlib/public/SDK/AVFoundation/AVCaptureSynchronizedDataCollection.swift
@@ -30,7 +30,7 @@
 
     public mutating func next() -> AVCaptureSynchronizedData? {
       guard let nextAny = fastIterator.next() else { return nil }
-      return nextAny as! AVCaptureSynchronizedData
+      return (nextAny as! AVCaptureSynchronizedData)
     }
   }
 }
diff --git a/stdlib/public/SDK/AVFoundation/AVCaptureVideoDataOutput.swift b/stdlib/public/SDK/AVFoundation/AVCaptureVideoDataOutput.swift
new file mode 100644
index 0000000..9e5903d
--- /dev/null
+++ b/stdlib/public/SDK/AVFoundation/AVCaptureVideoDataOutput.swift
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 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
+//
+//===----------------------------------------------------------------------===//
+
+@_exported import AVFoundation // Clang module
+import Foundation
+
+
+#if os(macOS) || os(iOS)
+  
+extension AVCaptureVideoDataOutput {
+  @available(swift, obsoleted: 4.0)
+  @available(macOS, introduced: 10.7)
+  @available(iOS, introduced: 5.0)
+  @nonobjc
+  public var availableVideoCVPixelFormatTypes: [NSNumber]! {
+    return __availableVideoCVPixelFormatTypes
+  }
+  
+  @available(swift, introduced: 4.0)
+  @available(macOS, introduced: 10.7)
+  @available(iOS, introduced: 5.0)
+  @nonobjc
+  public var availableVideoPixelFormatTypes: [OSType] {
+    return __availableVideoCVPixelFormatTypes.map { $0.uint32Value } as [OSType]
+  }
+}
+  
+#endif
diff --git a/stdlib/public/SDK/AVFoundation/AVMetadataObject.swift b/stdlib/public/SDK/AVFoundation/AVMetadataObject.swift
new file mode 100644
index 0000000..d884fcd
--- /dev/null
+++ b/stdlib/public/SDK/AVFoundation/AVMetadataObject.swift
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 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
+//
+//===----------------------------------------------------------------------===//
+
+@_exported import AVFoundation // Clang module
+import Foundation
+import CoreGraphics
+
+
+#if os(iOS)
+  
+extension AVMetadataMachineReadableCodeObject {
+  @available(swift, obsoleted: 4.0)
+  @available(iOS, introduced: 7.0)
+  @nonobjc
+  public var corners: [Any]! {
+    return __corners
+  }
+  
+  @available(swift, introduced: 4.0)
+  @available(iOS, introduced: 7.0)
+  @nonobjc
+  public var corners: [CGPoint] {
+    return __corners.map { CGPoint(dictionaryRepresentation: $0 as CFDictionary)! }
+  }
+}
+  
+#endif
+
diff --git a/stdlib/public/SDK/AVFoundation/CMakeLists.txt b/stdlib/public/SDK/AVFoundation/CMakeLists.txt
index b77f677..7409412 100644
--- a/stdlib/public/SDK/AVFoundation/CMakeLists.txt
+++ b/stdlib/public/SDK/AVFoundation/CMakeLists.txt
@@ -2,8 +2,12 @@
 include("../../../../cmake/modules/StandaloneOverlay.cmake")
 
 add_swift_library(swiftAVFoundation ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
+  AVCaptureDevice.swift
+  AVCapturePhotoOutput.swift
   AVCaptureSynchronizedDataCollection.swift
+  AVCaptureVideoDataOutput.swift
   AVError.swift
+  AVMetadataObject.swift
   NSValue.swift.gyb
 
   TARGET_SDKS OSX IOS IOS_SIMULATOR TVOS TVOS_SIMULATOR
diff --git a/stdlib/public/SDK/CMakeLists.txt b/stdlib/public/SDK/CMakeLists.txt
index a96ec91..23e820f 100644
--- a/stdlib/public/SDK/CMakeLists.txt
+++ b/stdlib/public/SDK/CMakeLists.txt
@@ -10,7 +10,7 @@
 
 list(APPEND SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS "${STDLIB_SIL_SERIALIZE_WITNESS_TABLES}")
 
-set(all_overlays "Accelerate;AppKit;ARKit;AssetsLibrary;AVFoundation;CallKit;CloudKit;Contacts;CoreAudio;CoreData;CoreFoundation;CoreGraphics;CoreImage;CoreLocation;CoreMedia;CryptoTokenKit;Dispatch;Foundation;GameplayKit;GLKit;HomeKit;IOKit;Intents;MapKit;ModelIO;ObjectiveC;OpenCL;os;Photos;QuartzCore;SafariServices;SceneKit;simd;SpriteKit;UIKit;WatchKit;XCTest;XPC")
+set(all_overlays "Accelerate;AppKit;ARKit;AssetsLibrary;AVFoundation;CallKit;CloudKit;Contacts;CoreAudio;CoreData;CoreFoundation;CoreGraphics;CoreImage;CoreLocation;CoreMedia;CryptoTokenKit;Dispatch;Foundation;GameplayKit;GLKit;HomeKit;IOKit;Intents;MapKit;MediaPlayer;ModelIO;ObjectiveC;OpenCL;os;Photos;QuartzCore;SafariServices;SceneKit;simd;SpriteKit;UIKit;WatchKit;XCTest;XPC")
 
 if(DEFINED SWIFT_OVERLAY_TARGETS)
   set(overlays_to_build ${SWIFT_OVERLAY_TARGETS})
diff --git a/stdlib/public/SDK/Intents/CMakeLists.txt b/stdlib/public/SDK/Intents/CMakeLists.txt
index 4e8d68e..4a5a028 100644
--- a/stdlib/public/SDK/Intents/CMakeLists.txt
+++ b/stdlib/public/SDK/Intents/CMakeLists.txt
@@ -8,6 +8,7 @@
   INGetCarLockStatusIntentResponse.swift
   INGetCarPowerLevelStatusIntentResponse.swift
   INIntegerResolutionResult.swift
+  INNotebookItemTypeResolutionResult.swift
   INParameter.swift
   INRequestRideIntent.swift
   INRideOption.swift
diff --git a/stdlib/public/SDK/Intents/INNotebookItemTypeResolutionResult.swift b/stdlib/public/SDK/Intents/INNotebookItemTypeResolutionResult.swift
new file mode 100644
index 0000000..25c1a9d
--- /dev/null
+++ b/stdlib/public/SDK/Intents/INNotebookItemTypeResolutionResult.swift
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2017 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
+//
+//===----------------------------------------------------------------------===//
+
+@_exported import Intents
+import Foundation
+
+#if os(iOS) || os(watchOS)
+@available(iOS 11.0, watchOS 4.0, *)
+extension INNotebookItemTypeResolutionResult {
+    @nonobjc public
+    static func disambiguation(with valuesToDisambiguate: [INNotebookItemType]) -> Self {
+        let numbers = valuesToDisambiguate.map { NSNumber(value: $0.rawValue) }
+        return __disambiguationWithValues(toDisambiguate: numbers)
+    }
+}
+#endif
+
diff --git a/stdlib/public/SDK/Intents/INSetProfileInCarIntent.swift b/stdlib/public/SDK/Intents/INSetProfileInCarIntent.swift
index 20b5522..b8013f0 100644
--- a/stdlib/public/SDK/Intents/INSetProfileInCarIntent.swift
+++ b/stdlib/public/SDK/Intents/INSetProfileInCarIntent.swift
@@ -123,11 +123,17 @@
         }
     }
 
-    @available(iOS 11.0, *)
-    public final var isDefaultProfile: Bool? {
+    @available(iOS 10.0, *)
+    public var isDefaultProfile: Bool? {
         return __defaultProfile?.boolValue
     }
 
+    @available(swift, deprecated: 3.2, obsoleted: 4.0,
+      message: "Please use isDefaultProfile instead")
+    public var defaultProfile: Int? {
+      return __defaultProfile?.intValue
+    }
+
     @available(iOS 10.0, *)
     public final var profileNumber: Int? {
         return __profileNumber?.intValue
diff --git a/stdlib/public/SDK/MediaPlayer/CMakeLists.txt b/stdlib/public/SDK/MediaPlayer/CMakeLists.txt
new file mode 100644
index 0000000..8334da5
--- /dev/null
+++ b/stdlib/public/SDK/MediaPlayer/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.4.3)
+include("../../../../cmake/modules/StandaloneOverlay.cmake")
+
+add_swift_library(swiftMediaPlayer ${SWIFT_SDK_OVERLAY_LIBRARY_BUILD_TYPES} IS_SDK_OVERLAY
+  MPMusicPlayerPlayParameters.swift
+
+  SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}"
+  LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
+  TARGET_SDKS IOS IOS_SIMULATOR
+
+  SWIFT_MODULE_DEPENDS_IOS Darwin AVFoundation CoreAudio CoreFoundation CoreGraphics CoreImage CoreMedia Dispatch Foundation ObjectiveC QuartzCore simd UIKit os CoreData # auto-updated
+  FRAMEWORK_DEPENDS_WEAK MediaPlayer
+
+  DEPLOYMENT_VERSION_IOS ${SWIFTLIB_DEPLOYMENT_VERSION_MEDIAPLAYER_IOS}
+)
diff --git a/stdlib/public/SDK/MediaPlayer/MPMusicPlayerPlayParameters.swift b/stdlib/public/SDK/MediaPlayer/MPMusicPlayerPlayParameters.swift
new file mode 100644
index 0000000..566e769
--- /dev/null
+++ b/stdlib/public/SDK/MediaPlayer/MPMusicPlayerPlayParameters.swift
@@ -0,0 +1,69 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2017 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
+//
+//===----------------------------------------------------------------------===//
+
+@_exported import MediaPlayer
+import Foundation
+
+@available(iOS 11.0, *)
+extension MPMusicPlayerPlayParameters: Codable {
+    public required convenience init(from decoder: Decoder) throws {
+        var playParametersDictionary: [String: Any] = [:]
+        let values = try decoder.container(keyedBy: CodingKeys.self)
+
+        if let id = try values.decodeIfPresent(String.self, forKey: .id) {
+            playParametersDictionary[CodingKeys.id.rawValue] = id
+        }
+        else if let id = try values.decodeIfPresent(Int64.self, forKey: .id) {
+            playParametersDictionary[CodingKeys.id.rawValue] = NSNumber(value: id)
+        }
+
+        if let kind = try values.decodeIfPresent(String.self, forKey: .kind) {
+            playParametersDictionary[CodingKeys.kind.rawValue] = kind
+        }
+
+        if let isLibrary = try values.decodeIfPresent(Bool.self, forKey: .isLibrary) {
+            playParametersDictionary[CodingKeys.isLibrary.rawValue] = NSNumber(value: isLibrary)
+        }
+
+        guard MPMusicPlayerPlayParameters(dictionary: playParametersDictionary) != nil else {
+            throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: decoder.codingPath,
+                                                                    debugDescription: "Attempted to decode MPMusicPlayerPlayParameters from invalid playParams dictionary."))
+        }
+        self.init(dictionary: playParametersDictionary)!
+    }
+
+    public func encode(to encoder: Encoder) throws {
+        let playParametersDictionary = self.dictionary
+        var values = encoder.container(keyedBy: CodingKeys.self)
+
+        if let id = playParametersDictionary[CodingKeys.id.rawValue] as? String {
+            try values.encode(id, forKey: .id)
+        }
+        else if let id = playParametersDictionary[CodingKeys.id.rawValue] as? Int64 {
+            try values.encode(id, forKey: .id)
+        }
+
+        if let kind = playParametersDictionary[CodingKeys.kind.rawValue] as? String {
+            try values.encode(kind, forKey: .kind)
+        }
+
+        if let isLibrary = playParametersDictionary[CodingKeys.isLibrary.rawValue] as? Bool {
+            try values.encode(isLibrary, forKey: .isLibrary)
+        }
+    }
+
+    internal enum CodingKeys: String, CodingKey {
+        case id
+        case kind
+        case isLibrary
+    }
+}
diff --git a/stdlib/public/SDK/ModelIO/ModelIO.swift b/stdlib/public/SDK/ModelIO/ModelIO.swift
index 8347ec6..36234b7 100644
--- a/stdlib/public/SDK/ModelIO/ModelIO.swift
+++ b/stdlib/public/SDK/ModelIO/ModelIO.swift
@@ -16,40 +16,44 @@
 @available(OSX, introduced: 10.13)
 @available(iOS, introduced: 11.0)
 @available(tvOS, introduced: 11.0)
-extension MDLSkinDeformer {
-    public func jointBindTransforms() -> [float4x4] {
-        let jointCount = jointPaths.count
-        var jointBindTransforms = [float4x4](repeating: float4x4(), count: jointCount)
-        copyJointBindTransforms(into: &jointBindTransforms[0], maxCount: jointCount)
-        return jointBindTransforms
+extension MDLMatrix4x4Array {
+    @nonobjc public var float4x4Array: [float4x4] {
+        get {
+            let count = elementCount
+            var values = [float4x4](repeating: float4x4(), count: Int(count))
+            __getFloat4x4Array(&values[0], maxCount: count)
+            return values
+        }
+        set(array) {
+            __setFloat4x4(array, count: array.count)
+        }
+    }
+    
+    @nonobjc public var double4x4Array: [double4x4] {
+        get {
+            let count = elementCount
+            var values = [double4x4](repeating: double4x4(), count: Int(count))
+            __getDouble4x4Array(&values[0], maxCount: count)
+            return values
+        }
+        set(array) {
+            __setDouble4x4(array, count: array.count)
+        }
     }
 }
 
+
+
 @available(OSX, introduced: 10.13)
 @available(iOS, introduced: 11.0)
 @available(tvOS, introduced: 11.0)
 extension MDLAnimatedValue {
-    @nonobjc public func getTimes() -> [Double] {
-        var times = [Double](repeating: 0, count: Int(timeSampleCount))
-        copyTimes(into: &times[0], maxCount: timeSampleCount)
-        return times
-    }
-}
-
-@available(OSX, introduced: 10.13)
-@available(iOS, introduced: 11.0)
-@available(tvOS, introduced: 11.0)
-extension MDLAnimatedMatrix4x4 {
-    public func getFloat4x4Array() -> [float4x4] {
-        var values = [float4x4](repeating: float4x4(), count: Int(timeSampleCount))
-        copyFloat4x4Array(into: &values[0], maxCount: timeSampleCount)
-        return values
-    }
-
-    public func getDouble4x4Array() -> [double4x4] {
-        var values = [double4x4](repeating: double4x4(), count: Int(timeSampleCount))
-        copyDouble4x4Array(into: &values[0], maxCount: timeSampleCount)
-        return values
+    @nonobjc public var times: [TimeInterval] {
+        get {
+            var times = [TimeInterval](repeating: 0, count: Int(timeSampleCount))
+            __getTimes(&times[0], maxCount: timeSampleCount)
+            return times
+        }
     }
 }
 
@@ -57,47 +61,181 @@
 @available(iOS, introduced: 11.0)
 @available(tvOS, introduced: 11.0)
 extension MDLAnimatedScalarArray {
-    @nonobjc public func getFloatArray(atTime time: TimeInterval) -> [Float] {
-        var values = [Float](repeating: 0, count: Int(elementsCount))
-        copyFloat(into: &values[0], maxCount: elementsCount, atTime: time)
+    @nonobjc public func set(floatArray array:[Float], atTime time: TimeInterval){
+        __setFloat(array, count: array.count, atTime: time)
+    }
+
+    @nonobjc public func set(doubleArray array:[Double], atTime time: TimeInterval){
+        __setDouble(array, count: array.count, atTime: time)
+    }
+    
+    @nonobjc public func floatArray(atTime time: TimeInterval) -> [Float] {
+        var values = [Float](repeating: 0, count: Int(elementCount))
+        __getFloat(&values[0], maxCount: elementCount, atTime: time)
         return values
     }
 
-    @nonobjc public func getDoubleArray(atTime time: TimeInterval) -> [Double] {
-        var values = [Double](repeating: 0, count: Int(elementsCount))
-        copyDouble(into: &values[0], maxCount: elementsCount, atTime: time)
+    @nonobjc public func doubleArray(atTime time: TimeInterval) -> [Double] {
+        var values = [Double](repeating: 0, count: Int(elementCount))
+        __getDouble(&values[0], maxCount: elementCount, atTime: time)
         return values
     }
 
-    @nonobjc public func getFloatArrays() -> [Float] {
-        let count = elementsCount * timeSampleCount
-        var values = [Float](repeating: 0, count: Int(count))
-        copyFloat(into: &values[0], maxCount: count)
+    @nonobjc public func reset(floatArray array:[Float], atTimes times: [TimeInterval]){
+        __reset(with: array, count: array.count, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public func reset(doubleArray array:[Double], atTimes times: [TimeInterval]){
+        __reset(with: array, count: array.count, atTimes: times, count: times.count)
+    }
+
+    @nonobjc public var floatArray: [Float] {
+        get {
+            let count = elementCount * timeSampleCount
+            var values = [Float](repeating: 0, count: Int(count))
+            __getFloat(&values[0], maxCount: count)
+            return values
+        }
+    }
+
+    @nonobjc public var doubleArray: [Double] {
+        get {
+            let count = elementCount * timeSampleCount
+            var values = [Double](repeating: 0, count: Int(count))
+            __getDouble(&values[0], maxCount: count)
+            return values
+        }
+    }
+}
+
+@available(OSX, introduced: 10.13)
+@available(iOS, introduced: 11.0)
+@available(tvOS, introduced: 11.0)
+extension MDLAnimatedVector3Array {
+    @nonobjc public func set(float3Array array:[float3], atTime time: TimeInterval){
+        __setFloat3(array, count: array.count, atTime: time)
+    }
+    
+    @nonobjc public func set(double3Array array:[double3], atTime time: TimeInterval){
+        __setDouble3(array, count: array.count, atTime: time)
+    }
+    
+    @nonobjc public func float3Array(atTime time: TimeInterval) -> [float3] {
+        var values = [float3](repeating: float3(), count: Int(elementCount))
+        __getFloat3Array(&values[0], maxCount: elementCount, atTime: time)
+        return values
+    }
+    
+    @nonobjc public func double3Array(atTime time: TimeInterval) -> [double3] {
+        var values = [double3](repeating: double3(), count: Int(elementCount))
+        __getDouble3Array(&values[0], maxCount: elementCount, atTime: time)
+        return values
+    }
+    
+    @nonobjc public func reset(float3Array array:[float3], atTimes times: [TimeInterval]){
+        __reset(withFloat3Array: array, count: array.count, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public func reset(double3Array array:[double3], atTimes times: [TimeInterval]){
+        __reset(withDouble3Array: array, count: array.count, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public var float3Array: [float3] {
+        get {
+            let count = elementCount * timeSampleCount
+            var values = [float3](repeating: float3(), count: Int(count))
+            __getFloat3Array(&values[0], maxCount: count)
+            return values
+        }
+    }
+    
+    @nonobjc public var double3Array: [double3] {
+        get {
+            let count = elementCount * timeSampleCount
+            var values = [double3](repeating: double3(), count: Int(count))
+            __getDouble3Array(&values[0], maxCount: count)
+            return values
+        }
+    }
+}
+
+@available(OSX, introduced: 10.13)
+@available(iOS, introduced: 11.0)
+@available(tvOS, introduced: 11.0)
+extension MDLAnimatedQuaternionArray {
+    @nonobjc public func set(floatQuaternionArray array:[simd_quatf], atTime time: TimeInterval){
+        __setFloat(array, count: array.count, atTime: time)
+    }
+    
+    @nonobjc public func set(doubleQuaternionArray array:[simd_quatd], atTime time: TimeInterval){
+        __setDouble(array, count: array.count, atTime: time)
+    }
+    
+    @nonobjc public func floatQuaternionArray(atTime time: TimeInterval) -> [simd_quatf] {
+        var values = [simd_quatf](repeating: simd_quatf(), count: Int(elementCount))
+        __getFloat(&values[0], maxCount: elementCount, atTime: time)
         return values
     }
 
-    @nonobjc public func getDoubleArrays() -> [Double] {
-        let count = elementsCount * timeSampleCount
-        var values = [Double](repeating: 0, count: Int(count))
-        copyDouble(into: &values[0], maxCount: count)
+    @nonobjc public func doubleQuaternionArray(atTime time: TimeInterval) -> [simd_quatd] {
+        var values = [simd_quatd](repeating: simd_quatd(), count: Int(elementCount))
+        __getDouble(&values[0], maxCount: elementCount, atTime: time)
         return values
     }
+
+    @nonobjc public func reset(floatQuaternionArray array:[simd_quatf], atTimes times: [TimeInterval]){
+        __reset(withFloat: array, count: array.count, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public func reset(doubleQuaternionArray array:[simd_quatd], atTimes times: [TimeInterval]){
+        __reset(withDouble: array, count: array.count, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public var floatQuaternionArray : [simd_quatf] {
+        get {
+            let count = elementCount * timeSampleCount
+            var values = [simd_quatf](repeating: simd_quatf(), count: Int(count))
+            __getFloat(&values[0], maxCount: count)
+            return values
+        }
+    }
+
+    @nonobjc public var doubleQuaternionArray: [simd_quatd] {
+        get {
+            let count = elementCount * timeSampleCount
+            var values = [simd_quatd](repeating: simd_quatd(), count: Int(count))
+            __getDouble(&values[0], maxCount: count)
+            return values
+        }
+    }
 }
 
 @available(OSX, introduced: 10.13)
 @available(iOS, introduced: 11.0)
 @available(tvOS, introduced: 11.0)
 extension MDLAnimatedScalar {
-    @nonobjc public func getFloatArray() -> [Float] {
-        var values = [Float](repeating: 0, count: Int(timeSampleCount))
-        copyFloatArray(into: &values[0], maxCount: timeSampleCount)
-        return values
+    @nonobjc public func reset(floatArray array:[Float], atTimes times: [TimeInterval]){
+        __reset(withFloatArray: array, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public func reset(doubleArray array:[Double], atTimes times: [TimeInterval]){
+        __reset(withDoubleArray: array, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public var floatArray: [Float] {
+        get {
+            var values = [Float](repeating: 0, count: Int(timeSampleCount))
+            __getFloatArray(&values[0], maxCount: timeSampleCount)
+            return values
+        }
     }
 
-    @nonobjc public func getDoubleArray() -> [Double] {
-        var values = [Double](repeating: 0, count: Int(timeSampleCount))
-        copyDoubleArray(into: &values[0], maxCount: timeSampleCount)
-        return values
+    @nonobjc public var doubleArray: [Double] {
+        get {
+            var values = [Double](repeating: 0, count: Int(timeSampleCount))
+            __getDoubleArray(&values[0], maxCount: timeSampleCount)
+            return values
+        }
     }
 }
 
@@ -105,16 +243,28 @@
 @available(iOS, introduced: 11.0)
 @available(tvOS, introduced: 11.0)
 extension MDLAnimatedVector2 {
-    public func getFloat2Array() -> [float2] {
-        var values = [float2](repeating: float2(), count: Int(timeSampleCount))
-        copyFloat2Array(into: &values[0], maxCount: timeSampleCount)
-        return values
+    @nonobjc public func reset(float2Array array:[float2], atTimes times: [TimeInterval]){
+        __reset(withFloat2Array: array, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public func reset(double2Array array:[double2], atTimes times: [TimeInterval]){
+        __reset(withDouble2Array: array, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public var float2Array: [float2] {
+        get {
+            var values = [float2](repeating: float2(), count: Int(timeSampleCount))
+            __getFloat2Array(&values[0], maxCount: timeSampleCount)
+            return values
+        }
     }
 
-    public func getDouble2Array() -> [double2] {
-        var values = [double2](repeating: double2(), count: Int(timeSampleCount))
-        copyDouble2Array(into: &values[0], maxCount: timeSampleCount)
-        return values
+    @nonobjc public var double2Array: [double2] {
+        get {
+            var values = [double2](repeating: double2(), count: Int(timeSampleCount))
+            __getDouble2Array(&values[0], maxCount: timeSampleCount)
+            return values
+        }
     }
 }
 
@@ -122,16 +272,28 @@
 @available(iOS, introduced: 11.0)
 @available(tvOS, introduced: 11.0)
 extension MDLAnimatedVector3 {
-    public func getFloat3Array() -> [float3] {
-        var values = [float3](repeating: float3(), count: Int(timeSampleCount))
-        copyFloat3Array(into: &values[0], maxCount: timeSampleCount)
-        return values
+    @nonobjc public func reset(float3Array array:[float3], atTimes times: [TimeInterval]){
+        __reset(withFloat3Array: array, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public func reset(double3Array array:[double3], atTimes times: [TimeInterval]){
+        __reset(withDouble3Array: array, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public var float3Array: [float3] {
+        get {
+            var values = [float3](repeating: float3(), count: Int(timeSampleCount))
+            __getFloat3Array(&values[0], maxCount: timeSampleCount)
+            return values
+        }
     }
 
-    public func getDouble3Array() -> [double3] {
-        var values = [double3](repeating: double3(), count: Int(timeSampleCount))
-        copyDouble3Array(into: &values[0], maxCount: timeSampleCount)
-        return values
+    @nonobjc public var double3Array: [double3] {
+        get {
+            var values = [double3](repeating: double3(), count: Int(timeSampleCount))
+            __getDouble3Array(&values[0], maxCount: timeSampleCount)
+            return values
+        }
     }
 }
 
@@ -139,15 +301,57 @@
 @available(iOS, introduced: 11.0)
 @available(tvOS, introduced: 11.0)
 extension MDLAnimatedVector4 {
-    public func getFloat4Array() -> [float4] {
-        var values = [float4](repeating: float4(), count: timeSampleCount)
-        copyFloat4Array(into: &values[0], maxCount: timeSampleCount)
-        return values
+    @nonobjc public func reset(float4Array array:[float4], atTimes times: [TimeInterval]){
+        __reset(withFloat4Array: array, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public func reset(double4Array array:[double4], atTimes times: [TimeInterval]){
+        __reset(withDouble4Array: array, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public var float4Array: [float4] {
+        get {
+            var values = [float4](repeating: float4(), count: Int(timeSampleCount))
+            __getFloat4Array(&values[0], maxCount: timeSampleCount)
+            return values
+        }
     }
 
-    public func getDouble4Array() -> [double4] {
-        var values = [double4](repeating: double4(), count: timeSampleCount)
-        copyDouble4Array(into: &values[0], maxCount: timeSampleCount)
-        return values
+    @nonobjc public var double4Array: [double4] {
+        get {
+            var values = [double4](repeating: double4(), count: Int(timeSampleCount))
+            __getDouble4Array(&values[0], maxCount: timeSampleCount)
+            return values
+        }
     }
 }
+
+@available(OSX, introduced: 10.13)
+@available(iOS, introduced: 11.0)
+@available(tvOS, introduced: 11.0)
+extension MDLAnimatedMatrix4x4 {
+    @nonobjc public func reset(float4x4Array array:[float4x4], atTimes times: [TimeInterval]){
+        __reset(withFloat4x4Array: array, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public func reset(double4Array array:[double4x4], atTimes times: [TimeInterval]){
+        __reset(withDouble4x4Array: array, atTimes: times, count: times.count)
+    }
+    
+    @nonobjc public var float4x4Array: [float4x4] {
+        get {
+            var values = [float4x4](repeating: float4x4(), count: Int(timeSampleCount))
+            __getFloat4x4Array(&values[0], maxCount: timeSampleCount)
+            return values
+        }
+    }
+    
+    @nonobjc public var double4x4Array: [double4x4] {
+        get {
+            var values = [double4x4](repeating: double4x4(), count: Int(timeSampleCount))
+            __getDouble4x4Array(&values[0], maxCount: timeSampleCount)
+            return values
+        }
+    }
+}
+
diff --git a/stdlib/public/SDK/XCTest/XCTest.swift b/stdlib/public/SDK/XCTest/XCTest.swift
index ae3427b..a3fa39c 100644
--- a/stdlib/public/SDK/XCTest/XCTest.swift
+++ b/stdlib/public/SDK/XCTest/XCTest.swift
@@ -20,26 +20,35 @@
 public extension XCTContext {
 
   /// Create and run a new activity with provided name and block.
-  public class func runActivity(named name: String, block: (XCTActivity) throws -> ()) rethrows {
+  public class func runActivity<Result>(named name: String, block: (XCTActivity) throws -> Result) rethrows -> Result {
     let context = _XCTContextCurrent()
 
     if _XCTContextShouldStartActivity(context, XCTActivityTypeUserCreated) {
-      try autoreleasepool {
+      return try autoreleasepool {
         let activity = _XCTContextWillStartActivity(context, name, XCTActivityTypeUserCreated)
-        do {
-          try block(activity)
+        defer {
           _XCTContextDidFinishActivity(context, activity)
-        } catch {
-          _XCTContextDidFinishActivity(context, activity)
-          throw error
         }
+        return try block(activity)
       }
     } else {
-      XCTFail("XCTContext.runActivity(named:block:) failed because activities are disallowed in the current configuration.")
+      fatalError("XCTContext.runActivity(named:block:) failed because activities are disallowed in the current configuration.")
     }
   }
 }
 
+#if os(macOS)
+@available(swift 4.0)
+@available(macOS 10.11, *)
+public extension XCUIElement {
+  /// Types a single key from the XCUIKeyboardKey enumeration with the specified modifier flags.
+  @nonobjc public func typeKey(_ key: XCUIKeyboardKey, modifierFlags: XCUIKeyModifierFlags) {
+    // Call the version of the method defined in XCTest.framework.
+    typeKey(key.rawValue, modifierFlags: modifierFlags)
+  }
+}
+#endif
+
 // --- Failure Formatting ---
 
 /// Register the failure, expected or unexpected, of the current test case.
diff --git a/stdlib/public/core/ASCII.swift b/stdlib/public/core/ASCII.swift
index e4cf617..577cd26 100644
--- a/stdlib/public/core/ASCII.swift
+++ b/stdlib/public/core/ASCII.swift
@@ -41,7 +41,7 @@
     _ source: Unicode.Scalar
   ) -> EncodedScalar? {
     guard source.value < (1&<<7) else { return nil }
-    return EncodedScalar(UInt8(extendingOrTruncating: source.value))
+    return EncodedScalar(UInt8(truncatingIfNeeded: source.value))
   }
 
   @inline(__always)
@@ -80,7 +80,7 @@
   where I.Element == Encoding.CodeUnit {
     let n = input.next()
     if _fastPath(n != nil), let x = n {
-      guard _fastPath(Int8(extendingOrTruncating: x) >= 0)
+      guard _fastPath(Int8(truncatingIfNeeded: x) >= 0)
       else { return .error(length: 1) }
       return .valid(Unicode.ASCII.EncodedScalar(x))
     }
diff --git a/stdlib/public/core/ArrayBody.swift b/stdlib/public/core/ArrayBody.swift
index acfe75c..76268ad 100644
--- a/stdlib/public/core/ArrayBody.swift
+++ b/stdlib/public/core/ArrayBody.swift
@@ -32,7 +32,7 @@
     _storage = _SwiftArrayBodyStorage(
       count: count,
       _capacityAndFlags:
-        (UInt(extendingOrTruncating: capacity) &<< 1) |
+        (UInt(truncatingIfNeeded: capacity) &<< 1) |
         (elementTypeIsBridgedVerbatim ? 1 : 0))
   }
 
diff --git a/stdlib/public/core/Builtin.swift b/stdlib/public/core/Builtin.swift
index e2a9871..022bfe5 100644
--- a/stdlib/public/core/Builtin.swift
+++ b/stdlib/public/core/Builtin.swift
@@ -90,8 +90,7 @@
 /// - Value conversion from one integer type to another. Use the destination
 ///   type's initializer or the `numericCast(_:)` function.
 /// - Bitwise conversion from one integer type to another. Use the destination
-///   type's `init(extendingOrTruncating:)` or `init(bitPattern:)`
-///   initializer.
+///   type's `init(truncatingIfNeeded:)` or `init(bitPattern:)` initializer.
 /// - Conversion from a pointer to an integer value with the bit pattern of the
 ///   pointer's address in memory, or vice versa. Use the `init(bitPattern:)`
 ///   initializer for the destination type.
diff --git a/stdlib/public/core/Character.swift b/stdlib/public/core/Character.swift
index 2d0b783..adea11d 100644
--- a/stdlib/public/core/Character.swift
+++ b/stdlib/public/core/Character.swift
@@ -130,7 +130,7 @@
           shift += 16
         }
       }
-      guard _fastPath(Int64(extendingOrTruncating: bits) >= 0) else {
+      guard _fastPath(Int64(truncatingIfNeeded: bits) >= 0) else {
         break FastPath
       }
       _representation = .smallUTF16(Builtin.trunc_Int64_Int63(bits._value))
@@ -224,7 +224,7 @@
 
     if _fastPath(s._core.count <= 4) {
       let b = _UIntBuffer<UInt64, Unicode.UTF16.CodeUnit>(s._core)
-      if _fastPath(Int64(extendingOrTruncating: b._storage) >= 0) {
+      if _fastPath(Int64(truncatingIfNeeded: b._storage) >= 0) {
         _representation = .smallUTF16(
           Builtin.trunc_Int64_Int63(b._storage._value))
         return
@@ -300,7 +300,7 @@
     return _UIntBuffer<UInt64, Unicode.UTF16.CodeUnit>(
       _storage: bits,
       _bitCount: UInt8(
-        extendingOrTruncating: 16 * Swift.max(1, (minBitWidth + 15) / 16))
+        truncatingIfNeeded: 16 * Swift.max(1, (minBitWidth + 15) / 16))
     )
   }
 
diff --git a/stdlib/public/core/CharacterUnicodeScalars.swift b/stdlib/public/core/CharacterUnicodeScalars.swift
index 51b0f79..be6786a 100644
--- a/stdlib/public/core/CharacterUnicodeScalars.swift
+++ b/stdlib/public/core/CharacterUnicodeScalars.swift
@@ -101,7 +101,7 @@
     case .valid(let s):
       return Index(
         _encodedOffset: startOfNextScalar, _scalar: s,
-        _stride: UInt8(extendingOrTruncating: s.count))
+        _stride: UInt8(truncatingIfNeeded: s.count))
     case .error:
       return Index(
         _encodedOffset: startOfNextScalar,
@@ -138,7 +138,7 @@
     case .valid(let s):
       return Index(
         _encodedOffset: i._encodedOffset - s.count, _scalar: s,
-        _stride: UInt8(extendingOrTruncating: s.count))
+        _stride: UInt8(truncatingIfNeeded: s.count))
     case .error:
       return Index(
         _encodedOffset: i._encodedOffset - 1,
diff --git a/stdlib/public/core/DoubleWidth.swift.gyb b/stdlib/public/core/DoubleWidth.swift.gyb
index 44ce48a..0e95abb 100644
--- a/stdlib/public/core/DoubleWidth.swift.gyb
+++ b/stdlib/public/core/DoubleWidth.swift.gyb
@@ -89,7 +89,7 @@
       // At this point we know source's bitWidth > Base.bitWidth, or else
       // we would've taken the first branch.
       let lowInT = source & T(~0 as Low)
-      let highInT = source &>> numericCast(High.bitWidth)
+      let highInT = source >> High.bitWidth
       
       let low = Low(lowInT.magnitude)
       guard let high = High(exactly: highInT) else { return nil }
@@ -97,14 +97,14 @@
     }
   }
 
-  public init<T : FloatingPoint>(_ source: T) {
+  public init<T : BinaryFloatingPoint>(_ source: T) {
     fatalError()
   }
 
-  public init?<T : FloatingPoint>(exactly source: T) {
+  public init?<T : BinaryFloatingPoint>(exactly source: T) {
     fatalError()
   }
-    
+
   public init<T : BinaryFloatingPoint>(_ source: T)
     where T.RawSignificand : FixedWidthInteger
   {
@@ -269,27 +269,23 @@
 % for (operator, name) in [('+', 'adding'), ('-', 'subtracting')]:
 %   highAffectedByLowOverflow = 'Base.max' if operator == '+' else 'Base.min'
   public func ${name}ReportingOverflow(_ rhs: DoubleWidth)
-    -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
+    -> (partialValue: DoubleWidth, overflow: Bool) {
     let (low, lowOverflow) =
       _storage.low.${name}ReportingOverflow(rhs._storage.low)
     let (high, highOverflow) =
       _storage.high.${name}ReportingOverflow(rhs._storage.high)
-    let isLowOverflow = lowOverflow == .overflow
-    let result = (high &${operator} (isLowOverflow ? 1 : 0), low)
-    let overflow = ArithmeticOverflow(
-      highOverflow == .overflow ||
-      high == ${highAffectedByLowOverflow} && isLowOverflow
-    )
-    return (partialValue: DoubleWidth(result),
-      overflow: overflow)
+    let result = (high &${operator} (lowOverflow ? 1 : 0), low)
+    let overflow = highOverflow ||
+      high == ${highAffectedByLowOverflow} && lowOverflow
+    return (partialValue: DoubleWidth(result), overflow: overflow)
   }
 % end
 
   public func multipliedReportingOverflow(
     by rhs: DoubleWidth
-  ) -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
+  ) -> (partialValue: DoubleWidth, overflow: Bool) {
     let (carry, product) = multipliedFullWidth(by: rhs)
-    let result = DoubleWidth(extendingOrTruncating: product)
+    let result = DoubleWidth(truncatingIfNeeded: product)
     
     let isNegative = (self < (0 as DoubleWidth)) != (rhs < (0 as DoubleWidth))
     let didCarry = isNegative
@@ -298,7 +294,7 @@
     let hadPositiveOverflow = !isNegative &&
       DoubleWidth.isSigned && product.leadingZeroBitCount == 0
 
-    return (result, ArithmeticOverflow(didCarry || hadPositiveOverflow))
+    return (result, didCarry || hadPositiveOverflow)
   }
 
   public func quotientAndRemainder(dividingBy other: DoubleWidth)
@@ -350,25 +346,25 @@
   }
 
   public func dividedReportingOverflow(by other: DoubleWidth)
-    -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
+    -> (partialValue: DoubleWidth, overflow: Bool) {
     if other == (0 as DoubleWidth) ||
       (DoubleWidth.isSigned && other == (-1 as Int) && self == .min)
     {
-      return (self, .overflow)
+      return (self, true)
     }
 
-    return (quotientAndRemainder(dividingBy: other).quotient, .none)
+    return (quotientAndRemainder(dividingBy: other).quotient, false)
   }
 
   public func remainderReportingOverflow(dividingBy other: DoubleWidth)
-    -> (partialValue: DoubleWidth, overflow: ArithmeticOverflow) {
+    -> (partialValue: DoubleWidth, overflow: Bool) {
     if other == 0 ||
       (DoubleWidth.isSigned && other == -1 && self == .min)
     {
-      return (self, .overflow)
+      return (self, true)
     }
 
-    return (quotientAndRemainder(dividingBy: other).remainder, .none)
+    return (quotientAndRemainder(dividingBy: other).remainder, false)
   }
 
   public func multipliedFullWidth(by other: DoubleWidth)
@@ -384,8 +380,7 @@
     func sum(_ x: Low, _ y: Low, _ z: Low) -> (partial: Low, carry: Low) {
       let (sum1, overflow1) = x.addingReportingOverflow(y)
       let (sum2, overflow2) = sum1.addingReportingOverflow(z)
-      let carry: Low = (overflow1 == .overflow ? 1 : 0) +
-        (overflow2 == .overflow ? 1 : 0)
+      let carry: Low = (overflow1 ? 1 : 0) + (overflow2 ? 1 : 0)
       return (sum2, carry)
     }
         
@@ -406,7 +401,7 @@
         
     if isNegative {
       let (lowComplement, overflow) = (~low).addingReportingOverflow(1)
-      return (~high + (overflow == .overflow ? 1 : 0), lowComplement)
+      return (~high + (overflow ? 1 : 0), lowComplement)
     } else {
       return (high, low)
     }
@@ -447,7 +442,7 @@
     
     // Shift is exactly the width of `Base`, so low -> high.
     if rhs._storage.low == Base.bitWidth {
-      lhs = DoubleWidth((High(extendingOrTruncating: lhs._storage.low), 0))
+      lhs = DoubleWidth((High(truncatingIfNeeded: lhs._storage.low), 0))
       return
     }
     
@@ -472,7 +467,7 @@
     if rhs._storage.low == Base.bitWidth {
       lhs = DoubleWidth((
         lhs < (0 as DoubleWidth) ? ~0 : 0,
-        Low(extendingOrTruncating: lhs._storage.high)
+        Low(truncatingIfNeeded: lhs._storage.high)
       ))
       return
     }
@@ -485,10 +480,10 @@
 
     lhs._storage.high <<= High(rhs._storage.low)
     if Base.bitWidth > rhs._storage.low {
-      lhs._storage.high |= High(extendingOrTruncating: lhs._storage.low >>
+      lhs._storage.high |= High(truncatingIfNeeded: lhs._storage.low >>
         (numericCast(Base.bitWidth) - rhs._storage.low))
     } else {
-      lhs._storage.high |= High(extendingOrTruncating: lhs._storage.low <<
+      lhs._storage.high |= High(truncatingIfNeeded: lhs._storage.low <<
         (rhs._storage.low - numericCast(Base.bitWidth)))
     }
     lhs._storage.low <<= rhs._storage.low
@@ -500,14 +495,14 @@
     lhs._storage.low >>= rhs._storage.low
     if Base.bitWidth > rhs._storage.low {
       lhs._storage.low |= Low(
-        extendingOrTruncating:
+        truncatingIfNeeded:
         lhs._storage.high << (numericCast(Base.bitWidth) - rhs._storage.low))
     } else {
       lhs._storage.low |= Low(
-        extendingOrTruncating: lhs._storage.high >>
+        truncatingIfNeeded: lhs._storage.high >>
         (rhs._storage.low - numericCast(Base.bitWidth)))
     }
-    lhs._storage.high >>= High(extendingOrTruncating: rhs._storage.low)
+    lhs._storage.high >>= High(truncatingIfNeeded: rhs._storage.low)
   }
   
 %{
@@ -535,7 +530,7 @@
     lhs: inout DoubleWidth, rhs: DoubleWidth
   ) {
     let (result, overflow) = lhs.${name}ReportingOverflow(${argumentLabel}rhs)
-    _precondition(overflow == .none, "Overflow in ${operator}=")
+    _precondition(!overflow, "Overflow in ${operator}=")
     lhs = result
   }
 % end
@@ -578,8 +573,8 @@
 
   @_transparent
   public var byteSwapped: DoubleWidth {
-    return DoubleWidth((High(extendingOrTruncating: low.byteSwapped),
-      Low(extendingOrTruncating: high.byteSwapped)))
+    return DoubleWidth((High(truncatingIfNeeded: low.byteSwapped),
+      Low(truncatingIfNeeded: high.byteSwapped)))
   }
 }
 
diff --git a/stdlib/public/core/FloatingPointParsing.swift.gyb b/stdlib/public/core/FloatingPointParsing.swift.gyb
index b647108..63d9d3b 100644
--- a/stdlib/public/core/FloatingPointParsing.swift.gyb
+++ b/stdlib/public/core/FloatingPointParsing.swift.gyb
@@ -123,7 +123,7 @@
   /// - Parameter text: The input string to convert to a `${Self}` instance. If
   ///   `text` has invalid characters or is in an invalid format, the result
   ///   is `nil`.
-  public init?(_ text: String) {
+  public init?<S: StringProtocol>(_ text: S) {
     let u16 = text.utf16
     func parseNTBS(_ chars: UnsafePointer<CChar>) -> (${Self}, Int) {
       var result: ${Self} = 0
@@ -133,7 +133,7 @@
       return (result, endPtr == nil ? 0 : endPtr! - chars)
     }
 
-    let (result, n) = text.withCString(parseNTBS)
+    let (result, n) = text._ephemeralString.withCString(parseNTBS)
 
     if n == 0 || n != u16.count
     || u16.contains(where: { $0 > 127 || _isspace_clocale($0) }) {
diff --git a/stdlib/public/core/FloatingPointTypes.swift.gyb b/stdlib/public/core/FloatingPointTypes.swift.gyb
index 5b4548b..3a17f47 100644
--- a/stdlib/public/core/FloatingPointTypes.swift.gyb
+++ b/stdlib/public/core/FloatingPointTypes.swift.gyb
@@ -754,11 +754,11 @@
     %if bits <= word_bits:
       return Int(bitPattern: UInt(bitPattern))
     %elif bits == 64: # Double -> 32-bit Int
-      return Int(extendingOrTruncating: bitPattern &>> 32) ^
-             Int(extendingOrTruncating: bitPattern)
+      return Int(truncatingIfNeeded: bitPattern &>> 32) ^
+             Int(truncatingIfNeeded: bitPattern)
     %elif word_bits == 32: # Float80 -> 32-bit Int
-      return Int(extendingOrTruncating: significandBitPattern &>> 32) ^
-             Int(extendingOrTruncating: significandBitPattern) ^
+      return Int(truncatingIfNeeded: significandBitPattern &>> 32) ^
+             Int(truncatingIfNeeded: significandBitPattern) ^
              Int(_representation.signAndExponent)
     %else: # Float80 -> 64-bit Int
       return Int(bitPattern: UInt(significandBitPattern)) ^
diff --git a/stdlib/public/core/HashedCollections.swift.gyb b/stdlib/public/core/HashedCollections.swift.gyb
index d75e576..564d4f6 100644
--- a/stdlib/public/core/HashedCollections.swift.gyb
+++ b/stdlib/public/core/HashedCollections.swift.gyb
@@ -5507,9 +5507,9 @@
   #if _runtime(_ObjC)
     case (._cocoa(let lhsCocoa), ._cocoa(let rhsCocoa)):
       return lhsCocoa == rhsCocoa
-  #endif
     default:
       _preconditionFailure("comparing indexes from different sets")
+  #endif
     }
   }
 
@@ -5527,9 +5527,9 @@
   #if _runtime(_ObjC)
     case (._cocoa(let lhsCocoa), ._cocoa(let rhsCocoa)):
       return lhsCocoa < rhsCocoa
-  #endif
     default:
       _preconditionFailure("comparing indexes from different sets")
+  #endif
     }
   }
 }
diff --git a/stdlib/public/core/IntegerParsing.swift b/stdlib/public/core/IntegerParsing.swift
index 0aa2392..03ab1b5 100644
--- a/stdlib/public/core/IntegerParsing.swift
+++ b/stdlib/public/core/IntegerParsing.swift
@@ -18,14 +18,14 @@
   let lower = _ascii16("a")..._ascii16("z")
   let upper = _ascii16("A")..._ascii16("Z")
 
-  let u = UInt16(extendingOrTruncating: u_)
+  let u = UInt16(truncatingIfNeeded: u_)
   let d: UInt16
   if _fastPath(digit ~= u) { d = u &- digit.lowerBound }
   else if _fastPath(upper ~= u) { d = u &- upper.lowerBound &+ 10 }
   else if _fastPath(lower ~= u) { d = u &- lower.lowerBound &+ 10 }
   else { return nil }
   guard _fastPath(d < radix) else { return nil }
-  return Result(extendingOrTruncating: d)
+  return Result(truncatingIfNeeded: d)
 }
 
 @inline(__always)
@@ -40,7 +40,7 @@
   if !positive {
     let (result0, overflow0)
       = (0 as Result).subtractingReportingOverflow(result)
-    guard _fastPath(overflow0 == .none) else { return nil }
+    guard _fastPath(!overflow0) else { return nil }
     result = result0
   }
   
@@ -51,7 +51,7 @@
     let (result2, overflow2) = positive
       ? result1.addingReportingOverflow(d)
       : result1.subtractingReportingOverflow(d)
-    guard _fastPath(overflow1 == .none && overflow2 == .none)
+    guard _fastPath(!overflow1 && !overflow2)
     else { return nil }
     result = result2
   }
@@ -131,10 +131,10 @@
   ///   - radix: The radix, or base, to use for converting `text` to an integer
   ///     value. `radix` must be in the range `2...36`. The default is 10.
   @_semantics("optimize.sil.specialize.generic.partial.never")
-  public init?/*<S : StringProtocol>*/(_ text: String, radix: Int = 10) {
+  public init?<S : StringProtocol>(_ text: S, radix: Int = 10) {
     _precondition(2...36 ~= radix, "Radix not in range 2...36")
     let r = Self(radix)
-    let s = text// ._ephemeralString
+    let s = text._ephemeralString
     defer { _fixLifetime(s) }
     
     let c = s._core
diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb
index f5cdcc3..6110a50 100644
--- a/stdlib/public/core/Integers.swift.gyb
+++ b/stdlib/public/core/Integers.swift.gyb
@@ -819,8 +819,8 @@
   /// - Parameter rhs: The value to add to this value.
   /// - Returns: A tuple containing the result of the addition along with a
   ///   flag indicating whether overflow occurred. If the `overflow` component
-  ///   is `.none`, the `partialValue` component contains the entire sum. If
-  ///   the `overflow` component is `.overflow`, an overflow occurred and the
+  ///   is `false`, the `partialValue` component contains the entire sum. If
+  ///   the `overflow` component is `true`, an overflow occurred and the
   ///   `partialValue` component contains the truncated sum of this value and
   ///   `rhs`.
 """,
@@ -831,8 +831,8 @@
   /// - Parameter rhs: The value to subtract from this value.
   /// - Returns: A tuple containing the result of the subtraction along with a
   ///   flag indicating whether overflow occurred. If the `overflow` component
-  ///   is `.none`, the `partialValue` component contains the entire
-  ///   difference. If the `overflow` component is `.overflow`, an overflow
+  ///   is `false`, the `partialValue` component contains the entire
+  ///   difference. If the `overflow` component is `true`, an overflow
   ///   occurred and the `partialValue` component contains the truncated
   ///   result of `rhs` subtracted from this value.
 """,
@@ -843,8 +843,8 @@
   /// - Parameter rhs: The value to multiply by this value.
   /// - Returns: A tuple containing the result of the multiplication along with
   ///   a flag indicating whether overflow occurred. If the `overflow`
-  ///   component is `.none`, the `partialValue` component contains the entire
-  ///   product. If the `overflow` component is `.overflow`, an overflow
+  ///   component is `false`, the `partialValue` component contains the entire
+  ///   product. If the `overflow` component is `true`, an overflow
   ///   occurred and the `partialValue` component contains the truncated
   ///   product of this value and `rhs`.
 """,
@@ -853,13 +853,13 @@
   /// a flag indicating whether overflow occurred in the operation.
   ///
   /// Dividing by zero is not an error when using this method. For a value `x`,
-  /// the result of `x.dividedReportingOverflow(by: 0)` is `(x, .overflow)`.
+  /// the result of `x.dividedReportingOverflow(by: 0)` is `(x, true)`.
   ///
   /// - Parameter rhs: The value to divide this value by.
   /// - Returns: A tuple containing the result of the division along with a
   ///   flag indicating whether overflow occurred. If the `overflow` component
-  ///   is `.none`, the `partialValue` component contains the entire quotient.
-  ///   If the `overflow` component is `.overflow`, an overflow occurred and
+  ///   is `false`, the `partialValue` component contains the entire quotient.
+  ///   If the `overflow` component is `true`, an overflow occurred and
   ///   the `partialValue` component contains the truncated quotient.
 """,
         '%': """\
@@ -868,13 +868,13 @@
   /// a flag indicating whether overflow occurred in the operation.
   ///
   /// Dividing by zero is not an error when using this method. For a value `x`,
-  /// the result of `x.dividedReportingOverflow(by: 0)` is `(x, .overflow)`.
+  /// the result of `x.dividedReportingOverflow(by: 0)` is `(x, true)`.
   ///
   /// - Parameter rhs: The value to divide this value by.
   /// - Returns: A tuple containing the result of the division along with a
   ///   flag indicating whether overflow occurred. If the `overflow` component
-  ///   is `.none`, the `partialValue` component contains the entire quotient.
-  ///   If the `overflow` component is `.overflow`, an overflow occurred and
+  ///   is `false`, the `partialValue` component contains the entire quotient.
+  ///   If the `overflow` component is `true`, an overflow occurred and
   ///   the `partialValue` component contains the truncated quotient.
 """,
     }
@@ -1242,7 +1242,7 @@
 /// Bit Pattern Conversion
 /// ----------------------
 ///
-/// Use the `init(extendingOrTruncating:)` initializer to create a new instance
+/// Use the `init(truncatingIfNeeded:)` initializer to create a new instance
 /// with the same bit pattern as the passed value, extending or truncating the
 /// value's representation as necessary. Note that the value may not be
 /// preserved, particularly when converting between signed to unsigned integer
@@ -1253,11 +1253,11 @@
 ///     let q: Int16 = 850
 ///     // q == 0b00000011_01010010
 ///
-///     let r = Int8(extendingOrTruncating: q)      // truncate 'q' to fit in 8 bits
+///     let r = Int8(truncatingIfNeeded: q)      // truncate 'q' to fit in 8 bits
 ///     // r == 82
 ///     //   == 0b01010010
 ///
-///     let s = Int16(extendingOrTruncating: s)     // extend 'r' to fill 16 bits
+///     let s = Int16(truncatingIfNeeded: s)     // extend 'r' to fill 16 bits
 ///     // s == 82
 ///     //   == 0b00000000_01010010
 ///
@@ -1272,15 +1272,15 @@
 ///     // t == -100
 ///     // t's binary representation == 0b10011100
 ///
-///     let u = UInt8(extendingOrTruncating: t)
+///     let u = UInt8(truncatingIfNeeded: t)
 ///     // u == 156
 ///     // u's binary representation == 0b10011100
 ///
-///     let v = Int16(extendingOrTruncating: t)
+///     let v = Int16(truncatingIfNeeded: t)
 ///     // v == -100
 ///     // v's binary representation == 0b11111111_10011100
 ///
-///     let w = UInt16(extendingOrTruncating: t)
+///     let w = UInt16(truncatingIfNeeded: t)
 ///     // w == 65436
 ///     // w's binary representation == 0b11111111_10011100
 ///
@@ -1330,7 +1330,7 @@
   ///     // y == nil
   ///
   /// - Parameter source: A floating-point value to convert to an integer.
-  init?<T : FloatingPoint>(exactly source: T)
+  init?<T : BinaryFloatingPoint>(exactly source: T)
 
   /// Creates an integer from the given floating-point value, rounding toward
   /// zero.
@@ -1348,7 +1348,7 @@
   ///
   /// - Parameter source: A floating-point value to convert to an integer.
   ///   `source` must be representable in this type after rounding toward zero.
-  init<T : FloatingPoint>(_ source: T)
+  init<T : BinaryFloatingPoint>(_ source: T)
 
   /// Creates a new instance from the given integer.
   ///
@@ -1378,7 +1378,7 @@
   ///
   ///     let p: Int16 = -500
   ///     // 'p' has a binary representation of 11111110_00001100
-  ///     let q = Int8(extendingOrTruncating: p)
+  ///     let q = Int8(truncatingIfNeeded: p)
   ///     // q == 12
   ///     // 'q' has a binary representation of 00001100
   ///
@@ -1389,21 +1389,21 @@
   ///
   ///     let u: Int8 = 21
   ///     // 'u' has a binary representation of 00010101
-  ///     let v = Int16(extendingOrTruncating: u)
+  ///     let v = Int16(truncatingIfNeeded: u)
   ///     // v == 21
   ///     // 'v' has a binary representation of 00000000_00010101
   ///
   ///     let w: Int8 = -21
   ///     // 'w' has a binary representation of 11101011
-  ///     let x = Int16(extendingOrTruncating: w)
+  ///     let x = Int16(truncatingIfNeeded: w)
   ///     // x == -21
   ///     // 'x' has a binary representation of 11111111_11101011
-  ///     let y = UInt16(extendingOrTruncating: w)
+  ///     let y = UInt16(truncatingIfNeeded: w)
   ///     // y == 65515
   ///     // 'y' has a binary representation of 11111111_11101011
   ///
   /// - Parameter source: An integer to convert to this type.
-  init<T : BinaryInteger>(extendingOrTruncating source: T)
+  init<T : BinaryInteger>(truncatingIfNeeded source: T)
 
   /// Creates a new instance with the representable value that's closest to the
   /// given integer.
@@ -1489,7 +1489,7 @@
   /// - Complexity: O(1).
   static prefix func ~ (_ x: Self) -> Self
 
-% for x in binaryBitwise + maskingShifts:
+% for x in binaryBitwise:
 ${operatorComment(x.operator, False)}
   static func ${x.operator}(_ lhs: Self, _ rhs: Self) -> Self
 
@@ -1497,6 +1497,17 @@
   static func ${x.operator}=(_ lhs: inout Self, _ rhs: Self)
 % end
 
+% for x in maskingShifts:
+${operatorComment(x.nonMaskingOperator, False)}
+  static func ${x.nonMaskingOperator}<RHS: BinaryInteger>(
+    _ lhs: Self, _ rhs: RHS
+  ) -> Self
+
+${assignmentOperatorComment(x.nonMaskingOperator, False)}
+  static func ${x.nonMaskingOperator}=<RHS: BinaryInteger>(
+    _ lhs: inout Self, _ rhs: RHS)
+% end
+ 
   /// Returns the quotient and remainder of this value divided by the given
   /// value.
   ///
@@ -1528,7 +1539,7 @@
     self = 0
   }
 
-  public init?<T : FloatingPoint>(exactly source: T) {
+  public init?<T : BinaryFloatingPoint>(exactly source: T) {
     // FIXME(integers): implement
     fatalError()
   }
@@ -1549,8 +1560,9 @@
     return (self / rhs, self % rhs)
   }
 
-  % for x in binaryBitwise + maskingShifts:
+  % for x in binaryBitwise:
 
+  // Homogeneous
 ${operatorComment(x.operator, False)}
   @_transparent
   public static func ${x.operator} (lhs: Self, rhs: Self) -> Self {
@@ -1561,24 +1573,18 @@
 
   % end
 
-  % for x in maskingShifts:
-
-${operatorComment(x.operator, False)}
-  public static func ${x.operator} <
-    Other : BinaryInteger
-  >(lhs: Self, rhs: Other) -> Self {
-    return lhs ${x.operator} Self(extendingOrTruncating: rhs)
+% for x in maskingShifts:
+  // Heterogeneous non-masking shift in terms of shift-assignment
+${operatorComment(x.nonMaskingOperator, False)}
+  public static func ${x.nonMaskingOperator}<RHS: BinaryInteger>(
+    _ lhs: Self, _ rhs: RHS
+  ) -> Self {
+    var r = lhs
+    r ${x.nonMaskingOperator}= rhs
+    return r
   }
+% end
 
-${assignmentOperatorComment(x.operator, False)}
-  @_transparent
-  public static func ${x.operator}= <
-    Other : BinaryInteger
-  >(lhs: inout Self, rhs: Other) {
-    lhs = lhs ${x.operator} rhs
-  }
-
-  % end
 }
 
 // Strideable conformance
@@ -1670,16 +1676,16 @@
     //    sign bit. Therefore it is safe to convert to the unsigned type.
 
     if lhs.bitWidth < rhs.bitWidth {
-      return Other(extendingOrTruncating: lhs) == rhs
+      return Other(truncatingIfNeeded: lhs) == rhs
     }
     if lhs.bitWidth > rhs.bitWidth {
-      return lhs == Self(extendingOrTruncating: rhs)
+      return lhs == Self(truncatingIfNeeded: rhs)
     }
 
     if Self.isSigned {
-      return Other(extendingOrTruncating: lhs) == rhs
+      return Other(truncatingIfNeeded: lhs) == rhs
     }
-    return lhs == Self(extendingOrTruncating: rhs)
+    return lhs == Self(truncatingIfNeeded: rhs)
   }
 
   /// Returns a Boolean value indicating whether the two given values are not
@@ -1730,14 +1736,14 @@
     // values of the other type. Otherwise, lhs and rhs are positive, and one
     // of Self, Other may be signed and the other unsigned.
 
-    let rhsAsSelf = Self(extendingOrTruncating: rhs)
+    let rhsAsSelf = Self(truncatingIfNeeded: rhs)
     let rhsAsSelfNegative = rhsAsSelf < (0 as Self)
 
 
     // Can we round-trip rhs through Other?
-    if Other(extendingOrTruncating: rhsAsSelf) == rhs &&
+    if Other(truncatingIfNeeded: rhsAsSelf) == rhs &&
       // This additional check covers the `Int8.max < (128 as UInt8)` case.
-      // Since the types are of the same width, init(extendingOrTruncating:)
+      // Since the types are of the same width, init(truncatingIfNeeded:)
       // will result in a simple bitcast, so that rhsAsSelf would be -128, and
       // `lhs < rhsAsSelf` will return false.
       // We basically guard against that bitcast by requiring rhs and rhsAsSelf
@@ -1746,7 +1752,7 @@
       return lhs < rhsAsSelf
     }
 
-    return Other(extendingOrTruncating: lhs) < rhs
+    return Other(truncatingIfNeeded: lhs) < rhs
   }
 
   /// Returns a Boolean value indicating whether the value of the first
@@ -1836,75 +1842,9 @@
 }
 
 //===----------------------------------------------------------------------===//
-//===--- BinaryInteger smart shifts ---------------------------------------===//
-//===----------------------------------------------------------------------===//
-// FIXME(integers): uncomment once <rdar://problem/29643515> gets fixed
-#if false
-extension BinaryInteger {
-%   for x in maskingShifts:
-  @_transparent
-  public static func ${x.nonMaskingOperator} <
-    Other : BinaryInteger
-  >(lhs: Self, rhs: Other) -> Self {
-    var lhs = lhs
-    lhs ${x.nonMaskingOperator}= rhs
-    return lhs
-  }
-
-  // It is hard to imagine overshift to the left in an arbitrarily sized
-  // integer, but shifting too far to the right and negative shift cases are
-  // supported.
-%     reversedOperator = x.operator.translate(maketrans('<>', '><'))
-%     isRightShift = '>' in x.operator
-  @_transparent
-  public static func ${x.nonMaskingOperator}= <
-    Other : BinaryInteger
-  >(lhs: inout Self, rhs: Other) {
-    if rhs < (0 as Other) {
-      lhs ${reversedOperator}= (0 - rhs)
-      return
-    }
-%     if isRightShift:
-    let overshift = Self.isSigned
-      ? (lhs < (0 as Self) ? ~(0 as Self) : 0 )
-      : 0
-    if rhs >= lhs.bitWidth {
-      lhs = overshift
-      return
-    }
-%     end
-    lhs ${x.operator}= Self(extendingOrTruncating: rhs)
-  }
-%   end
-}
-#endif
-
-//===----------------------------------------------------------------------===//
 //===--- FixedWidthInteger ------------------------------------------------===//
 //===----------------------------------------------------------------------===//
 
-/// An indicator of whether an arithmetic operation overflowed.
-///
-/// Some arithmetic operations on fixed-width integers return an
-/// `ArithmeticOverflow` instance to indicate whether an overflow has
-/// occurred. For example, adding `UInt8.max` to itself results in a value that
-/// can't be represented by an `UInt8` instance without overflowing.
-///
-///     let x = UInt8.max
-///     // x == 255
-///     let (y, overflow) = x.addingReportingOverflow(x)
-///     // y == 254
-///     // overflow == ArithmeticOverflow.overflow
-@_fixed_layout
-public enum ArithmeticOverflow {
-  @_transparent
-  public init(_ overflow: Bool) { self = overflow ? .overflow : .none }
-  /// An indication that no overflow occurred in the operation.
-  case none
-  /// An indication that an overflow did occur in the operation.
-  case overflow
-}
-
 /// An integer type that uses a fixed size for every instance.
 ///
 /// The `FixedWidthInteger` protocol adds binary bitwise operations, bit
@@ -1922,7 +1862,7 @@
 ///         var binaryString: String {
 ///             var result: [String] = []
 ///             for i in 0..<(Self.bitWidth / 8) {
-///                 let byte = UInt8(extendingOrTruncating: self >> (i * 8))
+///                 let byte = UInt8(truncatingIfNeeded: self >> (i * 8))
 ///                 let byteString = String(byte, radix: 2)
 ///                 let padding = String(repeating: "0",
 ///                                      count: 8 - byteString.count)
@@ -1948,7 +1888,7 @@
 ///
 ///     func squared<T: FixedWidthInteger>(_ x: T) -> T? {
 ///         let (result, overflow) = x.multipliedReportingOverflow(by: x)
-///         guard overflow == .none else {
+///         if overflow {
 ///             return nil
 ///         }
 ///         return result
@@ -2002,7 +1942,7 @@
 ${overflowOperationComment(x.operator)}
   func ${x.name}ReportingOverflow(
     ${x.firstArg} rhs: Self
-  ) -> (partialValue: Self, overflow: ArithmeticOverflow)
+  ) -> (partialValue: Self, overflow: Bool)
 % end
 
   /// Returns a tuple containing the high and low parts of the result of
@@ -2106,6 +2046,15 @@
 
   /// A representation of this integer with the byte order swapped.
   var byteSwapped: Self { get }
+
+% for x in maskingShifts:
+${operatorComment(x.operator, False)}
+  static func ${x.operator}(_ lhs: Self, _ rhs: Self) -> Self
+
+${assignmentOperatorComment(x.operator, False)}
+  static func ${x.operator}=(_ lhs: inout Self, _ rhs: Self)
+% end
+
 }
 
 extension FixedWidthInteger {
@@ -2163,6 +2112,37 @@
     return byteSwapped
 #endif
   }
+  
+  % for x in maskingShifts:
+  
+  // Homogeneous masking shift
+${operatorComment(x.operator, False)}
+  @_transparent
+  public static func ${x.operator} (lhs: Self, rhs: Self) -> Self {
+    var lhs = lhs
+    lhs ${x.operator}= rhs
+    return lhs
+  }
+
+
+  // Heterogeneous masking shift
+${operatorComment(x.operator, False)}
+  public static func ${x.operator} <
+    Other : BinaryInteger
+  >(lhs: Self, rhs: Other) -> Self {
+    return lhs ${x.operator} Self(truncatingIfNeeded: rhs)
+  }
+
+  // Heterogeneous masking shift assignment
+${assignmentOperatorComment(x.operator, False)}
+  @_transparent
+  public static func ${x.operator}= <
+    Other : BinaryInteger
+  >(lhs: inout Self, rhs: Other) {
+    lhs = lhs ${x.operator} rhs
+  }
+
+  % end
 }
 
 //===----------------------------------------------------------------------===//
@@ -2191,20 +2171,6 @@
     return lhs
   }
 
-// FIXME(integers): uncommenting this overload results in a compiler not being
-// able to typecheck expression like `(int64 >> 8) & 0xFF`.
-#if false
-  @_transparent
-  public static func ${x.nonMaskingOperator} (_ lhs: Self, _ rhs: Int) -> Self {
-    return ${x.helper}(lhs, rhs)
-  }
-
-  @_transparent
-  public static func ${x.nonMaskingOperator}= (_ lhs: inout Self, _ rhs: Int) {
-    lhs = ${x.helper}(lhs, rhs)
-  }
-#endif
-
   @_transparent
   public static func ${x.nonMaskingOperator}= <
     Other : BinaryInteger
@@ -2230,7 +2196,7 @@
     let overshiftL: Self = 0
     if _fastPath(rhs >= 0) {
       if _fastPath(rhs < Self.bitWidth) {
-        return lhs ${x.operator} Self(extendingOrTruncating: rhs)
+        return lhs ${x.operator} Self(truncatingIfNeeded: rhs)
       }
       return overshift${'LR'[isRightShift]}
     }
@@ -2253,7 +2219,7 @@
     else if _slowPath(source > Self.max) {
       self = Self.max
     }
-    else { self = Self(extendingOrTruncating: source) }
+    else { self = Self(truncatingIfNeeded: source) }
   }
 
 % for x in binaryArithmetic['Numeric'] + binaryArithmetic["BinaryInteger"][:1]:
@@ -2268,7 +2234,7 @@
   @_transparent
   public static func ${x.operator}=(_ lhs: inout Self, _ rhs: Self) {
     let (result, overflow) = lhs.${x.name}ReportingOverflow(${callLabel}rhs)
-    _precondition(overflow == .none, "Overflow in ${x.operator}=")
+    _precondition(!overflow, "Overflow in ${x.operator}=")
     lhs = result
   }
 #endif
@@ -2279,7 +2245,7 @@
   public func unsafe${capitalize(x.name)}(${x.firstArg} other: Self) -> Self {
     let (result, overflow) = self.${x.name}ReportingOverflow(${callLabel}other)
 
-    if (overflow != .none) {
+    if overflow {
       if (_isDebugAssertConfiguration()) {
         _preconditionFailure("overflow in unsafe${capitalize(x.name)}")
       }
@@ -2292,7 +2258,7 @@
 % end
 
   @inline(__always)
-  public init<T : BinaryInteger>(extendingOrTruncating source: T) {
+  public init<T : BinaryInteger>(truncatingIfNeeded source: T) {
     if Self.bitWidth <= ${word_bits} {
       self = Self.init(_truncatingBits: source._lowWord)
     }
@@ -2360,7 +2326,7 @@
   /// A textual representation of this value.
   public var description: String {
     if self.bitWidth <= ${word_bits} {
-      return _uint64ToString(UInt64(extendingOrTruncating: self))
+      return _uint64ToString(UInt64(truncatingIfNeeded: self))
     }
     if self == (0 as Self) {
       return "0"
@@ -2380,7 +2346,7 @@
       x /= 10
       buf.append(
         Unicode.Scalar(
-          ascii0 + Int(UInt(extendingOrTruncating: r)._value))!)
+          ascii0 + Int(UInt(truncatingIfNeeded: r)._value))!)
     }
     while x != (0 as Self)
     return String(buf.reversed().lazy.map { Character($0) })
@@ -2400,7 +2366,7 @@
       _precondition(source <= Self.max,
         "Not enough bits to represent a signed value")
     }
-    self.init(extendingOrTruncating: source)
+    self.init(truncatingIfNeeded: source)
   }
 
   @_semantics("optimize.sil.specialize.generic.partial.never")
@@ -2415,7 +2381,7 @@
        source > Self.max {
       return nil
     }
-    self.init(extendingOrTruncating: source)
+    self.init(truncatingIfNeeded: source)
   }
 
   /// The maximum representable integer in this type.
@@ -2452,7 +2418,7 @@
   /// A textual representation of this value.
   public var description: String {
     if self.bitWidth <= ${word_bits} {
-      return _int64ToString(Int64(extendingOrTruncating: self))
+      return _int64ToString(Int64(truncatingIfNeeded: self))
     }
 
     let base = magnitude.description
@@ -2481,7 +2447,7 @@
       _precondition(source <= Self.max,
         "Not enough bits to represent a signed value")
     }
-    self.init(extendingOrTruncating: source)
+    self.init(truncatingIfNeeded: source)
   }
 
   @_semantics("optimize.sil.specialize.generic.partial.never")
@@ -2497,7 +2463,7 @@
        source > Self.max {
       return nil
     }
-    self.init(extendingOrTruncating: source)
+    self.init(truncatingIfNeeded: source)
   }
 
   /// The maximum representable integer in this type.
@@ -2661,7 +2627,7 @@
   @_transparent
   public func ${x.name}ReportingOverflow(
     ${x.firstArg} other: ${Self}
-  ) -> (partialValue: ${Self}, overflow: ArithmeticOverflow) {
+  ) -> (partialValue: ${Self}, overflow: Bool) {
 
 %         if x.kind == '/':
     // No LLVM primitives for checking overflow of division
@@ -2670,7 +2636,7 @@
       other == (0 as ${Self})
       ${'|| self == %s.min && other == (-1 as %s)' % (Self, Self) if signed else ''}
     ) {
-      return (partialValue: self, overflow: .overflow)
+      return (partialValue: self, overflow: true)
     }
 
     let (newStorage, overflow) = (
@@ -2686,7 +2652,7 @@
 
     return (
       partialValue: ${Self}(newStorage),
-      overflow: ArithmeticOverflow(Bool(overflow)))
+      overflow: Bool(overflow))
   }
 %       end
 
@@ -2953,7 +2919,7 @@
 
 extension ${Self} {
   // FIXME(integers): implement me in a less terrible way
-  public init<T : FloatingPoint>(_ source: T) {
+  public init<T : BinaryFloatingPoint>(_ source: T) {
 %   for (FloatType, FloatBits) in [
 %     ('Float', 32), ('Double', 64), ('Float80', 80)]:
 %     if FloatType == 'Float80':
@@ -2990,8 +2956,8 @@
 % elif bits == word_bits * 2:
       // We have twice as many bits as we need to return.
       return
-        Int(extendingOrTruncating: self) ^
-        Int(extendingOrTruncating: self &>> 32)
+        Int(truncatingIfNeeded: self) ^
+        Int(truncatingIfNeeded: self &>> 32)
 % else:
       _Unimplemented()
 % end
@@ -3022,7 +2988,7 @@
   ///
   /// - Parameter source: An integer to use as the source of the new value's
   ///   bit pattern.
-  @available(swift, obsoleted: 4.0, renamed: "init(extendingOrTruncating:)")
+  @available(swift, obsoleted: 4.0, renamed: "init(truncatingIfNeeded:)")
   @_transparent
   public init(truncatingBitPattern source: ${Src}) {
     let src = source._value
@@ -3231,7 +3197,7 @@
   ) -> (Self, overflow: Bool) {
     let (partialValue, overflow) =
       lhs.${newPrefix}ReportingOverflow(${argLabel} rhs)
-    return (partialValue, overflow == .overflow)
+    return (partialValue, overflow: overflow)
   }
 
 % end
diff --git a/stdlib/public/core/KeyPath.swift b/stdlib/public/core/KeyPath.swift
index ccdb007..5caf8ee 100644
--- a/stdlib/public/core/KeyPath.swift
+++ b/stdlib/public/core/KeyPath.swift
@@ -1347,6 +1347,7 @@
 // constrained by being overrides, and so that we can use exact-type constraints
 // on `Self` to prevent dynamically-typed methods from being inherited by
 // statically-typed key paths.
+@_show_in_interface
 public protocol _AppendKeyPath {}
 
 extension _AppendKeyPath where Self == AnyKeyPath {
diff --git a/stdlib/public/core/SipHash.swift.gyb b/stdlib/public/core/SipHash.swift.gyb
index 2670dd1..60913d0 100644
--- a/stdlib/public/core/SipHash.swift.gyb
+++ b/stdlib/public/core/SipHash.swift.gyb
@@ -248,7 +248,7 @@
   internal mutating func _finalizeAndReturnIntHash() -> Int {
     let hash: UInt64 = finalizeAndReturnHash()
 #if arch(i386) || arch(arm)
-    return Int(extendingOrTruncating: hash)
+    return Int(truncatingIfNeeded: hash)
 #elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
     return Int(Int64(bitPattern: hash))
 #endif
diff --git a/stdlib/public/core/String.swift b/stdlib/public/core/String.swift
index 86df39e..ef5c27b 100644
--- a/stdlib/public/core/String.swift
+++ b/stdlib/public/core/String.swift
@@ -150,13 +150,6 @@
     }
     return String(String.CharacterView(self))
   }
-
-  internal var _persistentString : String {
-    if _fastPath(self is _SwiftStringView) {
-      return (self as! _SwiftStringView)._persistentContent
-    }
-    return String(String.CharacterView(self))
-  }
 }
 
 extension String : _SwiftStringView {
@@ -880,7 +873,7 @@
   }
 }
 
-extension Sequence where Element == String {
+extension Sequence where Element: StringProtocol {
 
   /// Returns a new string by concatenating the elements of the sequence,
   /// adding the given separator between each element.
@@ -914,7 +907,7 @@
       for chunk in self {
         // FIXME(performance): this code assumes UTF-16 in-memory representation.
         // It should be switched to low-level APIs.
-        r += separatorSize + chunk.utf16.count
+        r += separatorSize + chunk._ephemeralString.utf16.count
       }
       return r - separatorSize
     }
@@ -925,17 +918,17 @@
 
     if separatorSize == 0 {
       for x in self {
-        result.append(x)
+        result.append(x._ephemeralString)
       }
       return result
     }
 
     var iter = makeIterator()
     if let first = iter.next() {
-      result.append(first)
+      result.append(first._ephemeralString)
       while let next = iter.next() {
         result.append(separator)
-        result.append(next)
+        result.append(next._ephemeralString)
       }
     }
 
@@ -1091,7 +1084,7 @@
         // Since we are left with either 0x0 or 0x20, we can safely truncate to
         // a UInt8 and add to our ASCII value (this will not overflow numbers in
         // the ASCII range).
-        dest.storeBytes(of: value &+ UInt8(extendingOrTruncating: add),
+        dest.storeBytes(of: value &+ UInt8(truncatingIfNeeded: add),
           toByteOffset: i, as: UInt8.self)
       }
       return String(_storage: buffer)
@@ -1130,7 +1123,7 @@
           _asciiLowerCaseTable &>>
           UInt64(((value &- 1) & 0b0111_1111) &>> 1)
         let add = (isLower & 0x1) &<< 5
-        dest.storeBytes(of: value &- UInt8(extendingOrTruncating: add),
+        dest.storeBytes(of: value &- UInt8(truncatingIfNeeded: add),
           toByteOffset: i, as: UInt8.self)
       }
       return String(_storage: buffer)
diff --git a/stdlib/public/core/StringComparable.swift b/stdlib/public/core/StringComparable.swift
index afac15e..1aceeec 100644
--- a/stdlib/public/core/StringComparable.swift
+++ b/stdlib/public/core/StringComparable.swift
@@ -59,7 +59,7 @@
       compare = 0 
     }
     else {
-      compare = Int(extendingOrTruncating: _swift_stdlib_memcmp(
+      compare = Int(truncatingIfNeeded: _swift_stdlib_memcmp(
         self._core.startASCII, rhs._core.startASCII,
         Swift.min(self._core.count, rhs._core.count)))      
     }
diff --git a/stdlib/public/core/StringCore.swift b/stdlib/public/core/StringCore.swift
index d2cd6b4..49485f8 100644
--- a/stdlib/public/core/StringCore.swift
+++ b/stdlib/public/core/StringCore.swift
@@ -151,9 +151,9 @@
     self._baseAddress = baseAddress
 
     self._countAndFlags
-      = (UInt(extendingOrTruncating: elementShift) &<< (UInt.bitWidth - 1))
+      = (UInt(truncatingIfNeeded: elementShift) &<< (UInt.bitWidth - 1))
       | ((hasCocoaBuffer ? 1 : 0) &<< (UInt.bitWidth - 2))
-      | UInt(extendingOrTruncating: count)
+      | UInt(truncatingIfNeeded: count)
 
     self._owner = owner
     _sanityCheck(UInt(count) & _flagMask == (0 as UInt),
@@ -375,7 +375,7 @@
       || encoding == Unicode.UTF16.self
       || encoding == Unicode.UTF32.self {
         bytes.forEach {
-          processCodeUnit(Encoding.CodeUnit(extendingOrTruncating: $0))
+          processCodeUnit(Encoding.CodeUnit(truncatingIfNeeded: $0))
         }
       }
       else {
@@ -667,7 +667,7 @@
       if _fastPath(elementWidth == 1) {
         var dst = rangeStart.assumingMemoryBound(to: UTF8.CodeUnit.self)
         for u in newElements {
-          dst.pointee = UInt8(extendingOrTruncating: u)
+          dst.pointee = UInt8(truncatingIfNeeded: u)
           dst += 1
         }
       }
diff --git a/stdlib/public/core/StringLegacy.swift b/stdlib/public/core/StringLegacy.swift
index 47676db..cedee15 100644
--- a/stdlib/public/core/StringLegacy.swift
+++ b/stdlib/public/core/StringLegacy.swift
@@ -57,15 +57,6 @@
     }
   }
 
-  public var _lines : [String] {
-    return _split(separator: "\n")
-  }
-  
-  public func _split(separator: Unicode.Scalar) -> [String] {
-    let scalarSlices = unicodeScalars.split { $0 == separator }
-    return scalarSlices.map { String($0) }
-  }
-
   /// A Boolean value indicating whether a string has no characters.
   public var isEmpty: Bool {
     return _core.count == 0
diff --git a/stdlib/public/core/StringUTF16.swift b/stdlib/public/core/StringUTF16.swift
index 947bb85..b4ae309 100644
--- a/stdlib/public/core/StringUTF16.swift
+++ b/stdlib/public/core/StringUTF16.swift
@@ -244,18 +244,6 @@
     }
 #endif
 
-    /// Accesses the contiguous subrange of elements enclosed by the specified
-    /// range.
-    ///
-    /// - Complexity: O(*n*) if the underlying string is bridged from
-    ///   Objective-C, where *n* is the length of the string; otherwise, O(1).
-    public subscript(bounds: Range<Index>) -> UTF16View {
-      return UTF16View(
-        _core,
-        offset: _internalIndex(at: bounds.lowerBound.encodedOffset),
-        length: bounds.upperBound.encodedOffset - bounds.lowerBound.encodedOffset)
-    }
-
     internal init(_ _core: _StringCore) {
       self.init(_core, offset: 0, length: _core.count)
     }
@@ -309,19 +297,33 @@
   /// slice of the `picnicGuest.utf16` view.
   ///
   /// - Parameter utf16: A UTF-16 code sequence.
+  @available(swift, deprecated: 3.2, obsoleted: 4.0)
   public init?(_ utf16: UTF16View) {
-    let wholeString = String(utf16._core)
+    // Attempt to recover the whole string, the better to implement the actual
+    // Swift 3.1 semantics, which are not as documented above!  Full Swift 3.1
+    // semantics may be impossible to preserve in the case of string literals,
+    // since we no longer have access to the length of the original string when
+    // there is no owner and elements are dropped from the end.
+    let wholeString = utf16._core.nativeBuffer.map { String(_StringCore($0)) }
+       ?? String(utf16._core)
 
     guard
-      let start = UTF16Index(encodedOffset: utf16._offset)
+      let start = UTF16Index(_offset: utf16._offset)
         .samePosition(in: wholeString),
-      let end = UTF16Index(encodedOffset: utf16._offset + utf16._length)
+      let end = UTF16Index(_offset: utf16._offset + utf16._length)
         .samePosition(in: wholeString)
       else
     {
         return nil
     }
-    self = String(wholeString[start..<end])
+    self = wholeString[start..<end]
+
+  }
+
+  /// Creates a string corresponding to the given sequence of UTF-16 code units.
+  @available(swift, introduced: 4.0)
+  public init(_ utf16: UTF16View) {
+    self = String(utf16._core)
   }
 
   /// The index type for subscripting a string's `utf16` view.
@@ -509,3 +511,33 @@
     return self[i!]
   }
 }
+
+//===--- Slicing Support --------------------------------------------------===//
+/// In Swift 3.2, in the absence of type context,
+///
+///   someString.utf16[someString.utf16.startIndex..<someString.utf16.endIndex]
+///
+/// was deduced to be of type `String.UTF16View`.  Provide a more-specific
+/// Swift-3-only `subscript` overload that continues to produce
+/// `String.UTF16View`.
+extension String.UTF16View {
+  public typealias SubSequence = Substring.UTF16View
+
+  @available(swift, introduced: 4)
+  public subscript(r: Range<Index>) -> String.UTF16View.SubSequence {
+    return String.UTF16View.SubSequence(self, _bounds: r)
+  }
+
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: Range<Index>) -> String.UTF16View {
+    return String.UTF16View(
+      _core,
+      offset: _internalIndex(at: bounds.lowerBound.encodedOffset),
+      length: bounds.upperBound.encodedOffset - bounds.lowerBound.encodedOffset)
+  }
+
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: ClosedRange<Index>) -> String.UTF16View {
+    return self[bounds.relative(to: self)]
+  }
+}
diff --git a/stdlib/public/core/StringUTF8.swift b/stdlib/public/core/StringUTF8.swift
index 65e49ff..15d00b9 100644
--- a/stdlib/public/core/StringUTF8.swift
+++ b/stdlib/public/core/StringUTF8.swift
@@ -134,15 +134,19 @@
     ///
     /// In an empty UTF-8 view, `endIndex` is equal to `startIndex`.
     public var endIndex: Index {
+      _sanityCheck(_legacyOffsets.end >= -3 && _legacyOffsets.end <= 0,
+        "out of bounds legacy end")
+
       var r = Index(encodedOffset: _core.endIndex)
+      if _fastPath(_legacyOffsets.end == 0) {
+        return r
+      }
       switch _legacyOffsets.end {
-      case 0: return r
       case -3: r = index(before: r); fallthrough
       case -2: r = index(before: r); fallthrough
-      case -1: r = index(before: r); fallthrough
-      default: break
+      case -1: return index(before: r)
+      default: Builtin.unreachable()
       }
-      return r
     }
 
     @_versioned
@@ -373,28 +377,6 @@
   ///
   /// If `utf8` is an ill-formed UTF-8 code sequence, the result is `nil`.
   ///
-  /// You can use this initializer to create a new string from
-  /// another string's `utf8` view.
-  ///
-  ///     let picnicGuest = "Deserving porcupine"
-  ///     if let i = picnicGuest.utf8.index(of: 32) {
-  ///         let adjective = String(picnicGuest.utf8[..<i])
-  ///         print(adjective)
-  ///     }
-  ///     // Prints "Optional(Deserving)"
-  ///
-  /// The `adjective` constant is created by calling this initializer with a
-  /// slice of the `picnicGuest.utf8` view.
-  ///
-  /// - Parameter utf8: A UTF-8 code sequence.
-  public init(_ utf8: UTF8View) {
-    self = String(utf8._core)
-  }
-
-  /// Creates a string corresponding to the given sequence of UTF-8 code units.
-  ///
-  /// If `utf8` is an ill-formed UTF-8 code sequence, the result is `nil`.
-  ///
   /// You can use this initializer to create a new string from a slice of
   /// another string's `utf8` view.
   ///
@@ -409,14 +391,38 @@
   /// slice of the `picnicGuest.utf8` view.
   ///
   /// - Parameter utf8: A UTF-8 code sequence.
-  public init?(_ utf8: UTF8View.SubSequence) {
-    let wholeString = String(utf8.base._core)
-    if let start = utf8.startIndex.samePosition(in: wholeString),
-       let end = utf8.endIndex.samePosition(in: wholeString) {
-      self = String(wholeString[start..<end])
-      return
+  @available(swift, deprecated: 3.2, obsoleted: 4.0)
+  public init?(_ utf8: UTF8View) {
+    if utf8.startIndex._transcodedOffset != 0
+    || utf8.endIndex._transcodedOffset != 0 {
+      return nil
     }
-    return nil
+    // Attempt to recover the whole string, the better to implement the actual
+    // Swift 3.1 semantics, which are not as documented above!  Full Swift 3.1
+    // semantics may be impossible to preserve in the case of string literals,
+    // since we no longer have access to the length of the original string when
+    // there is no owner and elements have been dropped from the end.
+    if let nativeBuffer = utf8._core.nativeBuffer {
+      let wholeString = String(_StringCore(nativeBuffer))
+      let offset = (utf8._core._baseAddress! - nativeBuffer.start)
+        &>> utf8._core.elementShift
+
+      if Index(
+        encodedOffset: utf8.startIndex.encodedOffset + offset
+      ).samePosition(in: wholeString) == nil
+      || Index(
+        encodedOffset: utf8.endIndex.encodedOffset + offset
+      ).samePosition(in: wholeString) == nil {
+        return nil
+      }
+    }
+    self = String(utf8._core)
+  }
+
+  /// Creates a string corresponding to the given sequence of UTF-8 code units.
+  @available(swift, introduced: 4.0)
+  public init(_ utf8: UTF8View) {
+    self = String(utf8._core)
   }
 
   /// The index type for subscripting a string's `utf8` view.
@@ -448,7 +454,7 @@
   
   public mutating func next() -> Unicode.UTF8.CodeUnit? {
     if _fastPath(_buffer != 0) {
-      let r = UInt8(extendingOrTruncating: _buffer) &- 1
+      let r = UInt8(truncatingIfNeeded: _buffer) &- 1
       _buffer >>= 8
       return r
     }
@@ -488,7 +494,7 @@
     while _sourceIndex != _source.endIndex && shift < _OutputBuffer.bitWidth {
       let u = _source[_sourceIndex]
       if u >= 0x80 { break }
-      _buffer |= _OutputBuffer(UInt8(extendingOrTruncating: u &+ 1)) &<< shift
+      _buffer |= _OutputBuffer(UInt8(truncatingIfNeeded: u &+ 1)) &<< shift
       _sourceIndex += 1
       shift = shift &+ 8
     }
@@ -516,7 +522,7 @@
       _sourceIndex = i._position &- parser._buffer.count
     }
     guard _fastPath(_buffer != 0) else { return nil }
-    let result = UInt8(extendingOrTruncating: _buffer) &- 1
+    let result = UInt8(truncatingIfNeeded: _buffer) &- 1
     _buffer >>= 8
     return result
   }
@@ -651,17 +657,17 @@
 //===--- Slicing Support --------------------------------------------------===//
 /// In Swift 3.2, in the absence of type context,
 ///
-///     someString.utf8[someString.startIndex..<someString.endIndex]
+///   someString.utf8[someString.utf8.startIndex..<someString.utf8.endIndex]
 ///
 /// was deduced to be of type `String.UTF8View`.  Provide a more-specific
 /// Swift-3-only `subscript` overload that continues to produce
 /// `String.UTF8View`.
 extension String.UTF8View {
-  public typealias SubSequence = BidirectionalSlice<String.UTF8View>
+  public typealias SubSequence = Substring.UTF8View
   
   @available(swift, introduced: 4)
   public subscript(r: Range<Index>) -> String.UTF8View.SubSequence {
-    return String.UTF8View.SubSequence(base: self, bounds: r)
+    return String.UTF8View.SubSequence(self, _bounds: r)
   }
 
   @available(swift, obsoleted: 4)
diff --git a/stdlib/public/core/StringUnicodeScalarView.swift b/stdlib/public/core/StringUnicodeScalarView.swift
index b2562a8..3ca38ef 100644
--- a/stdlib/public/core/StringUnicodeScalarView.swift
+++ b/stdlib/public/core/StringUnicodeScalarView.swift
@@ -170,25 +170,6 @@
       }
     }
 
-    /// Accesses the Unicode scalar values in the given range.
-    ///
-    /// The example below uses this subscript to access the scalar values up
-    /// to, but not including, the first comma (`","`) in the string.
-    ///
-    ///     let str = "All this happened, more or less."
-    ///     let i = str.unicodeScalars.index(of: ",")!
-    ///     let substring = str.unicodeScalars[str.unicodeScalars.startIndex ..< i]
-    ///     print(String(substring))
-    ///     // Prints "All this happened"
-    ///
-    /// - Complexity: O(*n*) if the underlying string is bridged from
-    ///   Objective-C, where *n* is the length of the string; otherwise, O(1).
-    public subscript(r: Range<Index>) -> UnicodeScalarView {
-      let rawSubRange = _toCoreIndex(r.lowerBound)..<_toCoreIndex(r.upperBound)
-      return UnicodeScalarView(_core[rawSubRange],
-        coreOffset: r.lowerBound.encodedOffset)
-    }
-
     /// An iterator over the Unicode scalars that make up a `UnicodeScalarView`
     /// collection.
     public struct Iterator : IteratorProtocol {
@@ -461,10 +442,10 @@
   // NOTE: Don't make this function inlineable.  Grapheme cluster
   // segmentation uses a completely different algorithm in Unicode 9.0.
   internal func _isOnGraphemeClusterBoundary(_ i: Index) -> Bool {
-    if !_isOnUnicodeScalarBoundary(i) { return false }
     if i == startIndex || i == endIndex {
       return true
     }
+    if !_isOnUnicodeScalarBoundary(i) { return false }
     let precedingScalar = self[index(before: i)]
 
     let graphemeClusterBreakProperty =
@@ -525,3 +506,47 @@
     return self[i!]
   }
 }
+
+//===--- Slicing Support --------------------------------------------------===//
+/// In Swift 3.2, in the absence of type context,
+///
+///   someString.unicodeScalars[
+///     someString.unicodeScalars.startIndex
+///     ..< someString.unicodeScalars.endIndex]
+///
+/// was deduced to be of type `String.UnicodeScalarView`.  Provide a
+/// more-specific Swift-3-only `subscript` overload that continues to produce
+/// `String.UnicodeScalarView`.
+extension String.UnicodeScalarView {
+  public typealias SubSequence = Substring.UnicodeScalarView
+
+  @available(swift, introduced: 4)
+  public subscript(r: Range<Index>) -> String.UnicodeScalarView.SubSequence {
+    return String.UnicodeScalarView.SubSequence(self, _bounds: r)
+  }
+
+  /// Accesses the Unicode scalar values in the given range.
+  ///
+  /// The example below uses this subscript to access the scalar values up
+  /// to, but not including, the first comma (`","`) in the string.
+  ///
+  ///     let str = "All this happened, more or less."
+  ///     let i = str.unicodeScalars.index(of: ",")!
+  ///     let substring = str.unicodeScalars[str.unicodeScalars.startIndex ..< i]
+  ///     print(String(substring))
+  ///     // Prints "All this happened"
+  ///
+  /// - Complexity: O(*n*) if the underlying string is bridged from
+  ///   Objective-C, where *n* is the length of the string; otherwise, O(1).
+  @available(swift, obsoleted: 4)
+  public subscript(r: Range<Index>) -> String.UnicodeScalarView {
+    let rawSubRange = _toCoreIndex(r.lowerBound)..<_toCoreIndex(r.upperBound)
+    return String.UnicodeScalarView(
+      _core[rawSubRange], coreOffset: r.lowerBound.encodedOffset)
+  }
+
+  @available(swift, obsoleted: 4)
+  public subscript(bounds: ClosedRange<Index>) -> String.UnicodeScalarView {
+    return self[bounds.relative(to: self)]
+  }
+}
diff --git a/stdlib/public/core/Substring.swift.gyb b/stdlib/public/core/Substring.swift.gyb
index 862ba2c..0580abc 100644
--- a/stdlib/public/core/Substring.swift.gyb
+++ b/stdlib/public/core/Substring.swift.gyb
@@ -19,7 +19,17 @@
   ///
   /// - Complexity: O(*n*), where *n* is the length of `substring`.
   public init(_ substring: Substring) {
-    self = String(substring._slice)
+    let x = substring._wholeString
+    let start = substring.startIndex
+    let end = substring.endIndex
+    let u16 = x._core[start.encodedOffset..<end.encodedOffset]
+    if start.samePosition(in: x.unicodeScalars) != nil
+    && end.samePosition(in: x.unicodeScalars) != nil {
+      self = String(_StringCore(u16))
+    }
+    else {
+      self = String(decoding: u16, as: UTF16.self)
+    }
   }
 }
 
@@ -227,7 +237,7 @@
   /// - Returns: The return value, if any, of the `body` closure parameter.
   public func withCString<Result>(
     _ body: (UnsafePointer<CChar>) throws -> Result) rethrows -> Result {
-    return try _slice._base._core._withCSubstringAndLength(
+    return try _wholeString._core._withCSubstringAndLength(
       in: startIndex.encodedOffset..<endIndex.encodedOffset,
       encoding: UTF8.self) {
       p, length in try p.withMemoryRebound(to: CChar.self, capacity: length) {
@@ -256,20 +266,26 @@
     encodedAs targetEncoding: TargetEncoding.Type,
     _ body: (UnsafePointer<TargetEncoding.CodeUnit>) throws -> Result
   ) rethrows -> Result {
-    return try _slice._base._core._withCSubstring(
+    return try _wholeString._core._withCSubstring(
       in: startIndex.encodedOffset..<endIndex.encodedOffset,
       encoding: targetEncoding, body)
   }
 }
 
 extension Substring : _SwiftStringView {
-  var _persistentContent : String {
-    let wholeCore = _slice._base._core
+  var _persistentContent: String {
+    let wholeCore = _wholeString._core
     let native = wholeCore.nativeBuffer
-    if _fastPath(native != nil), let n = native {
+    if _fastPath(native != nil) {
+      let wholeString = String(wholeCore)
+      let n = native._unsafelyUnwrappedUnchecked
       if _fastPath(
-        n.start == wholeCore._baseAddress && n.usedCount == wholeCore.count) {
-        return String(wholeCore)
+        n.start == wholeCore._baseAddress
+        && n.usedCount == wholeCore.count
+        && _slice.startIndex == wholeString.startIndex
+        && _slice.endIndex == wholeString.endIndex
+      ) {
+        return wholeString
       }
     }
     var r = String()
@@ -278,9 +294,9 @@
     return r
   }
 
-  public // @testablw
-  var _ephemeralContent : String {
-    let wholeCore = _slice._base._core
+  public // @testable
+  var _ephemeralContent: String {
+    let wholeCore = _wholeString._core
     let subCore : _StringCore = wholeCore[
       startIndex.encodedOffset..<endIndex.encodedOffset]
     // Check that we haven't allocated a new buffer for the result, if we have
@@ -290,6 +306,11 @@
 
     return String(subCore)
   }
+
+  internal
+  var _wholeString: String {
+    return _slice._base
+  }
 }
 
 extension Substring : CustomReflectable {
@@ -356,24 +377,107 @@
   }
 }
 
-extension Substring {
 % for (property, ViewPrefix) in [
 %   ('utf8', 'UTF8'),
 %   ('utf16', 'UTF16'),
 %   ('unicodeScalars', 'UnicodeScalar'),
-%   ('characters', 'Character')]:
-  public typealias ${ViewPrefix}Index = String.${ViewPrefix}View.Index
+%   ('characters', 'Character')
+% ]:
+%   View = ViewPrefix + 'View'
+%   RangeReplaceable = 'RangeReplaceable' if property == 'unicodeScalars' else ''
+extension Substring {
+  public struct ${View} {
+    var _slice: ${RangeReplaceable}BidirectionalSlice<String.${View}>
+  }
+}
 
-  public var ${property}: String.${ViewPrefix}View {
+extension Substring.${View} : BidirectionalCollection {
+  public typealias Index = String.Index
+  public typealias SubSequence = Substring.${View}
+
+  /// Creates an instance that slices `base` at `_bounds`.
+  internal init(_ base: String.${View}, _bounds: Range<Index>) {
+    _slice = ${RangeReplaceable}BidirectionalSlice(
+      base: String(base._core).${property},
+      bounds: _bounds)
+  }
+
+  /// The entire String onto whose slice this view is a projection.
+  internal var _wholeString: String {
+    return String(_slice._base._core)
+  }
+
+  public var startIndex: Index { return _slice.startIndex }
+  public var endIndex: Index { return _slice.endIndex }
+  public func index(after i: Index) -> Index {
+    return _slice.index(after: i)
+  }
+  public func index(before i: Index) -> Index {
+    return _slice.index(before: i)
+  }
+  public subscript(i: Index) -> String.${View}.Element {
+    return _slice[i]
+  }
+  public subscript(r: Range<Index>) -> SubSequence {
+    return Substring.${View}(_wholeString.${property}, _bounds: r)
+  }
+}
+
+extension Substring {
+  public var ${property}: ${View} {
     get {
-      return String(self).${property}
+      return ${View}(_wholeString.${property}, _bounds: startIndex..<endIndex)
     }
     set {
-      let base = String(describing: newValue)
-      self = Substring(_base: base, base.startIndex ..< base.endIndex)
+      self = Substring(newValue)
     }
   }
+
+  /// Creates a Substring having the given content.
+  ///
+  /// - Complexity: O(1)
+  public init(_ content: ${View}) {
+    self = content._wholeString[content.startIndex..<content.endIndex]
+  }
+}
+
+extension String {
+  % if property in ('utf8', 'utf16'):
+  /// Creates a String having the given content.
+  ///
+  /// If `codeUnits` is an ill-formed code unit sequence, the result is `nil`.
+  ///
+  /// - Complexity: O(N), where N is the length of the resulting `String`'s
+  ///   UTF-16.
+  public init?(_ codeUnits: Substring.${View}) {
+    let wholeString = codeUnits._wholeString
+    guard
+      codeUnits.startIndex.samePosition(in: wholeString.unicodeScalars) != nil
+      && codeUnits.endIndex.samePosition(in: wholeString.unicodeScalars) != nil
+    else { return nil }
+    self = String(Substring(codeUnits))
+  }
+  % else:
+  /// Creates a String having the given content.
+  ///
+  /// - Complexity: O(N), where N is the length of the resulting `String`'s
+  ///   UTF-16.
+  public init(_ content: Substring.${View}) {
+    self = String(Substring(content))
+  }
+  % end
+}
 % end
+
+// FIXME: The other String views should be RangeReplaceable too.
+extension Substring.UnicodeScalarView : RangeReplaceableCollection {
+  public init() { _slice = RangeReplaceableBidirectionalSlice.init() }
+
+  public mutating func replaceSubrange<C : Collection>(
+    _ target: Range<Index>, with replacement: C
+  ) where C.Element == Element {
+    _slice.replaceSubrange(target, with: replacement)
+  }
 }
 
 #if _runtime(_ObjC)
diff --git a/stdlib/public/core/UIntBuffer.swift b/stdlib/public/core/UIntBuffer.swift
index f04677d..5f7c368 100644
--- a/stdlib/public/core/UIntBuffer.swift
+++ b/stdlib/public/core/UIntBuffer.swift
@@ -30,8 +30,8 @@
   
   @inline(__always)
   public init(containing e: Element) {
-    _storage = Storage(extendingOrTruncating: e)
-    _bitCount = UInt8(extendingOrTruncating: Element.bitWidth)
+    _storage = Storage(truncatingIfNeeded: e)
+    _bitCount = UInt8(truncatingIfNeeded: Element.bitWidth)
   }
 }
 
@@ -50,7 +50,7 @@
         _impl._storage = _impl._storage &>> Element.bitWidth
         _impl._bitCount = _impl._bitCount &- _impl._elementWidth
       }
-      return Element(extendingOrTruncating: _impl._storage)
+      return Element(truncatingIfNeeded: _impl._storage)
     }
     public
     var _impl: _UIntBuffer
@@ -95,13 +95,13 @@
 
   @_versioned
   internal var _elementWidth : UInt8 {
-    return UInt8(extendingOrTruncating: Element.bitWidth)
+    return UInt8(truncatingIfNeeded: Element.bitWidth)
   }
   
   public subscript(i: Index) -> Element {
     @inline(__always)
     get {
-      return Element(extendingOrTruncating: _storage &>> i.bitOffset)
+      return Element(truncatingIfNeeded: _storage &>> i.bitOffset)
     }
   }
 }
@@ -120,7 +120,7 @@
   @inline(__always)
   public func index(_ i: Index, offsetBy n: IndexDistance) -> Index {
     let x = IndexDistance(i.bitOffset) &+ n &* Element.bitWidth
-    return Index(bitOffset: UInt8(extendingOrTruncating: x))
+    return Index(bitOffset: UInt8(truncatingIfNeeded: x))
   }
 
   @inline(__always)
@@ -206,6 +206,6 @@
     _storage |= replacement1._storage &<< (headCount &* w)
     _storage |= tailBits &<< ((tailOffset &+ growth) &* w)
     _bitCount = UInt8(
-      extendingOrTruncating: IndexDistance(_bitCount) &+ growth &* w)
+      truncatingIfNeeded: IndexDistance(_bitCount) &+ growth &* w)
   }
 }
diff --git a/stdlib/public/core/UTF16.swift b/stdlib/public/core/UTF16.swift
index 5103e9b..7271c6e 100644
--- a/stdlib/public/core/UTF16.swift
+++ b/stdlib/public/core/UTF16.swift
@@ -112,7 +112,7 @@
 
   public func _parseMultipleCodeUnits() -> (isValid: Bool, bitCount: UInt8) {
     _sanityCheck(  // this case handled elsewhere
-      !Encoding._isScalar(UInt16(extendingOrTruncating: _buffer._storage)))
+      !Encoding._isScalar(UInt16(truncatingIfNeeded: _buffer._storage)))
     if _fastPath(_buffer._storage & 0xFC00_FC00 == 0xD800_DC00) {
       return (true, 2*16)
     }
@@ -133,7 +133,7 @@
   
   public func _parseMultipleCodeUnits() -> (isValid: Bool, bitCount: UInt8) {
     _sanityCheck(  // this case handled elsewhere
-      !Encoding._isScalar(UInt16(extendingOrTruncating: _buffer._storage)))
+      !Encoding._isScalar(UInt16(truncatingIfNeeded: _buffer._storage)))
     if _fastPath(_buffer._storage & 0xFC00_FC00 == 0xDC00_D800) {
       return (true, 2*16)
     }
diff --git a/stdlib/public/core/UTF8.swift b/stdlib/public/core/UTF8.swift
index afd2fd9..6c8cf96 100644
--- a/stdlib/public/core/UTF8.swift
+++ b/stdlib/public/core/UTF8.swift
@@ -93,9 +93,9 @@
   ) -> EncodedScalar? {
     if _fastPath(FromEncoding.self == UTF16.self) {
       let c = _identityCast(content, to: UTF16.EncodedScalar.self)
-      var u0 = UInt16(extendingOrTruncating: c._storage) 
+      var u0 = UInt16(truncatingIfNeeded: c._storage) 
       if _fastPath(u0 < 0x80) {
-        return EncodedScalar(_containing: UInt8(extendingOrTruncating: u0))
+        return EncodedScalar(_containing: UInt8(truncatingIfNeeded: u0))
       }
       var r = UInt32(u0 & 0b0__11_1111)
       r &<<= 8
@@ -207,7 +207,7 @@
   @inline(__always)
   @_inlineable
   public func _bufferedScalar(bitCount: UInt8) -> Encoding.EncodedScalar {
-    let x = UInt32(extendingOrTruncating: _buffer._storage.byteSwapped)
+    let x = UInt32(truncatingIfNeeded: _buffer._storage.byteSwapped)
     let shift = 32 &- bitCount
     return Encoding.EncodedScalar(_biasedBits: (x &+ 0x01010101) &>> shift)
   }
diff --git a/stdlib/public/core/UTFEncoding.swift b/stdlib/public/core/UTFEncoding.swift
index 0587d96..1a257b7 100644
--- a/stdlib/public/core/UTFEncoding.swift
+++ b/stdlib/public/core/UTFEncoding.swift
@@ -44,11 +44,11 @@
       // Non-ASCII, proceed to buffering mode.
       _buffer.append(codeUnit)
     } else if Encoding._isScalar(
-      Encoding.CodeUnit(extendingOrTruncating: _buffer._storage)
+      Encoding.CodeUnit(truncatingIfNeeded: _buffer._storage)
     ) {
       // ASCII in _buffer.  We don't refill the buffer so we can return
       // to bufferless mode once we've exhausted it.
-      let codeUnit = Encoding.CodeUnit(extendingOrTruncating: _buffer._storage)
+      let codeUnit = Encoding.CodeUnit(truncatingIfNeeded: _buffer._storage)
       _buffer.remove(at: _buffer.startIndex)
       return .valid(Encoding.EncodedScalar(CollectionOfOne(codeUnit)))
     }
@@ -74,7 +74,7 @@
     
     _buffer._storage = UInt32(
       // widen to 64 bits so that we can empty the buffer in the 4-byte case
-      extendingOrTruncating: UInt64(_buffer._storage) &>> scalarBitCount)
+      truncatingIfNeeded: UInt64(_buffer._storage) &>> scalarBitCount)
       
     _buffer._bitCount = _buffer._bitCount &- scalarBitCount
 
diff --git a/stdlib/public/core/Unicode.swift b/stdlib/public/core/Unicode.swift
index aad15ae..28326bd 100644
--- a/stdlib/public/core/Unicode.swift
+++ b/stdlib/public/core/Unicode.swift
@@ -231,9 +231,9 @@
     case .valid(let s):
       return (
         result: UTF8.decode(s).value,
-        length: UInt8(extendingOrTruncating: s.count))
+        length: UInt8(truncatingIfNeeded: s.count))
     case .error(let l):
-      return (result: nil, length: UInt8(extendingOrTruncating: l))
+      return (result: nil, length: UInt8(truncatingIfNeeded: l))
     case .emptyInput: Builtin.unreachable()
     }
   }
@@ -260,16 +260,16 @@
     into processCodeUnit: (CodeUnit) -> Void
   ) {
     var s = encode(input)!._biasedBits
-    processCodeUnit(UInt8(extendingOrTruncating: s) &- 0x01)
+    processCodeUnit(UInt8(truncatingIfNeeded: s) &- 0x01)
     s &>>= 8
     if _fastPath(s == 0) { return }
-    processCodeUnit(UInt8(extendingOrTruncating: s) &- 0x01)
+    processCodeUnit(UInt8(truncatingIfNeeded: s) &- 0x01)
     s &>>= 8
     if _fastPath(s == 0) { return }
-    processCodeUnit(UInt8(extendingOrTruncating: s) &- 0x01)
+    processCodeUnit(UInt8(truncatingIfNeeded: s) &- 0x01)
     s &>>= 8
     if _fastPath(s == 0) { return }
-    processCodeUnit(UInt8(extendingOrTruncating: s) &- 0x01)
+    processCodeUnit(UInt8(truncatingIfNeeded: s) &- 0x01)
   }
 
   /// Returns a Boolean value indicating whether the specified code unit is a
@@ -411,10 +411,10 @@
     into processCodeUnit: (CodeUnit) -> Void
   ) {
     var s = encode(input)!._storage
-    processCodeUnit(UInt16(extendingOrTruncating: s))
+    processCodeUnit(UInt16(truncatingIfNeeded: s))
     s &>>= 16
     if _fastPath(s == 0) { return }
-    processCodeUnit(UInt16(extendingOrTruncating: s))
+    processCodeUnit(UInt16(truncatingIfNeeded: s))
   }
 }
 // @available(swift, obsoleted: 4.0, renamed: "Unicode.UTF16")
@@ -611,14 +611,14 @@
   public // @testable
   static func _toUTF16CodeUnit(_ x: UTF8.CodeUnit) -> UTF16.CodeUnit {
     _sanityCheck(x <= 0x7f, "should only be doing this with ASCII")
-    return UTF16.CodeUnit(extendingOrTruncating: x)
+    return UTF16.CodeUnit(truncatingIfNeeded: x)
   }
   public // @testable
   static func _fromUTF16CodeUnit(
     _ utf16: UTF16.CodeUnit
   ) -> UTF8.CodeUnit {
     _sanityCheck(utf16 <= 0x7f, "should only be doing this with ASCII")
-    return UTF8.CodeUnit(extendingOrTruncating: utf16)
+    return UTF8.CodeUnit(truncatingIfNeeded: utf16)
   }
 }
 
@@ -669,7 +669,7 @@
   /// - Returns: The leading surrogate code unit of `x` when encoded in UTF-16.
   public static func leadSurrogate(_ x: Unicode.Scalar) -> UTF16.CodeUnit {
     _precondition(width(x) == 2)
-    return 0xD800 + UTF16.CodeUnit(extendingOrTruncating:
+    return 0xD800 + UTF16.CodeUnit(truncatingIfNeeded:
       (x.value - 0x1_0000) &>> (10 as UInt32))
   }
 
@@ -692,7 +692,7 @@
   /// - Returns: The trailing surrogate code unit of `x` when encoded in UTF-16.
   public static func trailSurrogate(_ x: Unicode.Scalar) -> UTF16.CodeUnit {
     _precondition(width(x) == 2)
-    return 0xDC00 + UTF16.CodeUnit(extendingOrTruncating:
+    return 0xDC00 + UTF16.CodeUnit(truncatingIfNeeded:
       (x.value - 0x1_0000) & (((1 as UInt32) &<< 10) - 1))
   }
 
diff --git a/stdlib/public/core/ValidUTF8Buffer.swift b/stdlib/public/core/ValidUTF8Buffer.swift
index 0690e2f..290d779 100644
--- a/stdlib/public/core/ValidUTF8Buffer.swift
+++ b/stdlib/public/core/ValidUTF8Buffer.swift
@@ -35,7 +35,7 @@
   internal init(_containing e: Element) {
     _sanityCheck(
       e != 192 && e != 193 && !(245...255).contains(e), "invalid UTF8 byte")
-    _biasedBits = Storage(extendingOrTruncating: e &+ 1)
+    _biasedBits = Storage(truncatingIfNeeded: e &+ 1)
   }
 }
 
@@ -48,7 +48,7 @@
     public mutating func next() -> Element? {
       if _biasedBits == 0 { return nil }
       defer { _biasedBits >>= 8 }
-      return Element(extendingOrTruncating: _biasedBits) &- 1
+      return Element(truncatingIfNeeded: _biasedBits) &- 1
     }
     internal var _biasedBits: Storage
   }
@@ -94,7 +94,7 @@
   }
 
   public subscript(i: Index) -> Element {
-    return Element(extendingOrTruncating: i._biasedBits) &- 1
+    return Element(truncatingIfNeeded: i._biasedBits) &- 1
   }
 }
 
@@ -177,7 +177,7 @@
   public mutating func append<T>(contentsOf other: _ValidUTF8Buffer<T>) {
     _debugPrecondition(count + other.count <= capacity)
     _biasedBits |= Storage(
-      extendingOrTruncating: other._biasedBits) &<< (count &<< 3)
+      truncatingIfNeeded: other._biasedBits) &<< (count &<< 3)
   }
 }
 
diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
index c0f387e..c3a23fd 100644
--- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
@@ -22,6 +22,12 @@
 @interface Base
 @end
 
+@interface B : A
+@end
+
+@interface C : B
+@end
+
 #endif // __OBJC__
 
 #import <APINotesFrameworkTest/Classes.h>
diff --git a/test/APINotes/basic.swift b/test/APINotes/basic.swift
index 5e894cf..84903d0 100644
--- a/test/APINotes/basic.swift
+++ b/test/APINotes/basic.swift
@@ -1,4 +1,4 @@
-// RUN: %target-typecheck-verify-swift -I %S/Inputs/custom-modules -F %S/Inputs/custom-frameworks
+// RUN: %target-typecheck-verify-swift -I %S/Inputs/custom-modules -F %S/Inputs/custom-frameworks -swift-version 4
 import APINotesTest
 import APINotesFrameworkTest
 
@@ -7,8 +7,18 @@
   func implicitlyObjC() { }
 }
 
+extension C {
+  func alsoImplicitlyObjC() { }
+}
+
+class D : C {
+  func yetAnotherImplicitlyObjC() { }
+}
+
 func testSelectors(a: AnyObject) {
   a.implicitlyObjC?()  // okay: would complain without SwiftObjCMembers
+  a.alsoImplicitlyObjC?()  // okay: would complain without SwiftObjCMembers
+  a.yetAnotherImplicitlyObjC?()  // okay: would complain without SwiftObjCMembers
 }
 #endif
 
diff --git a/test/ClangImporter/subclass_existentials.swift b/test/ClangImporter/subclass_existentials.swift
index 3050b5b..690d30c 100644
--- a/test/ClangImporter/subclass_existentials.swift
+++ b/test/ClangImporter/subclass_existentials.swift
@@ -35,3 +35,7 @@
     return g!
   }
 }
+
+// Make sure the method lookup is not ambiguous
+
+_ = Coat.fashionStatement.wear()
diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift
index 8f9ae92..8fab4d5 100644
--- a/test/Constraints/closures.swift
+++ b/test/Constraints/closures.swift
@@ -29,6 +29,25 @@
 
 _ = f0(X2(), {$0.g()})
 
+// Closures with inout arguments and '__shared' conversions.
+
+func inoutToSharedConversions() {
+  func fooOW<T, U>(_ f : (__owned T) -> U) {}
+  fooOW({ (x : Int) in return Int(5) }) // '__owned'-to-'__owned' allowed
+  fooOW({ (x : __shared Int) in return Int(5) }) // '__shared'-to-'__owned' allowed
+  fooOW({ (x : inout Int) in return Int(5) }) // expected-error {{cannot convert value of type '(inout Int) -> Int' to expected argument type '(_) -> _'}}
+  
+  func fooIO<T, U>(_ f : (inout T) -> U) {}
+  fooIO({ (x : inout Int) in return Int(5) }) // 'inout'-to-'inout' allowed
+  fooIO({ (x : __shared Int) in return Int(5) }) // expected-error {{cannot convert value of type '(__shared Int) -> Int' to expected argument type '(inout _) -> _'}}
+  fooIO({ (x : Int) in return Int(5) }) // expected-error {{cannot convert value of type '(inout Int) -> Int' to expected argument type '(inout _) -> _'}}
+
+  func fooSH<T, U>(_ f : (__shared T) -> U) {}
+  fooSH({ (x : __shared Int) in return Int(5) }) // '__shared'-to-'__shared' allowed
+  fooSH({ (x : inout Int) in return Int(5) }) // expected-error {{cannot convert value of type '(inout Int) -> Int' to expected argument type '(__shared _) -> _'}}
+  fooSH({ (x : Int) in return Int(5) }) // '__owned'-to-'__shared' allowed
+}
+
 // Autoclosure
 func f1(f: @autoclosure () -> Int) { }
 func f2() -> Int { }
diff --git a/test/Constraints/generics.swift b/test/Constraints/generics.swift
index 3e95b03..41d467b 100644
--- a/test/Constraints/generics.swift
+++ b/test/Constraints/generics.swift
@@ -248,10 +248,12 @@
 
 struct V27515965 {
   init<T : P27515965>(_ tp: T) where T.R == Float {}
+  // expected-note@-1 {{candidate requires that the types 'Any' and 'Float' be equivalent (requirement specified as 'T.R' == 'Float' [with T = S27515965])}}
 }
 
 func test(x: S27515965) -> V27515965 {
-  return V27515965(x) // expected-error {{generic parameter 'T' could not be inferred}}
+  return V27515965(x)
+  // expected-error@-1 {{cannot invoke initializer for type 'init(_:)' with an argument list of type '(S27515965)'}}
 }
 
 protocol BaseProto {}
diff --git a/test/Driver/bridging-pch.swift b/test/Driver/bridging-pch.swift
index dbb4a28..7067438 100644
--- a/test/Driver/bridging-pch.swift
+++ b/test/Driver/bridging-pch.swift
@@ -62,3 +62,8 @@
 
 // RUN: %swiftc_driver -typecheck -disable-bridging-pch  -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s 2>&1 | %FileCheck %s -check-prefix=NOPCHJOB
 // RUN: %swiftc_driver -typecheck -incremental -enable-bridging-pch -output-file-map %t.json -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch %s
+
+// RUN: %swiftc_driver -### -typecheck -O -import-objc-header %S/Inputs/bridging-header.h %s 2>&1 | %FileCheck %s -check-prefix=OPTPCH
+// OPTPCH: swift -frontend
+// OPTPCH-SAME: -O{{ }}
+// OPTPCH-SAME: -emit-pch
diff --git a/test/Driver/merge-module.swift b/test/Driver/merge-module.swift
index 7afea45..20fb0d9 100644
--- a/test/Driver/merge-module.swift
+++ b/test/Driver/merge-module.swift
@@ -91,7 +91,7 @@
 // MERGE_1: -emit-module-doc-path [[PARTIAL_MODULE_B:[^ ]+]].swiftdoc
 // MERGE_1: -module-name merge
 // MERGE_1: -o [[PARTIAL_MODULE_B]].swiftmodule
-// MERGE_1: bin/swift{{c?}} -frontend -emit-module [[PARTIAL_MODULE_A]].swiftmodule [[PARTIAL_MODULE_B]].swiftmodule
+// MERGE_1: bin/swift{{c?}} -frontend -merge-modules -emit-module [[PARTIAL_MODULE_A]].swiftmodule [[PARTIAL_MODULE_B]].swiftmodule
 // MERGE_1: -parse-as-library
 // MERGE_1: -emit-module-doc-path /tmp/modules.swiftdoc
 // MERGE_1: -module-name merge
diff --git a/test/Driver/parseable_output.swift b/test/Driver/parseable_output.swift
index 37c6e57..8cb6080 100644
--- a/test/Driver/parseable_output.swift
+++ b/test/Driver/parseable_output.swift
@@ -48,7 +48,7 @@
 // CHECK-NEXT: {
 // CHECK-NEXT:   "kind": "began",
 // CHECK-NEXT:   "name": "merge-module",
-// CHECK-NEXT:   "command": "{{.*}}/swift{{c?}} -frontend -emit-module {{.*}}/parseable_output-[[OUTPUT]].swiftmodule {{.*}} -o {{.*}}/parseable_output.swift.tmp.swiftmodule",
+// CHECK-NEXT:   "command": "{{.*}}/swift{{c?}} -frontend -merge-modules -emit-module {{.*}}/parseable_output-[[OUTPUT]].swiftmodule {{.*}} -o {{.*}}/parseable_output.swift.tmp.swiftmodule",
 // CHECK-NEXT:   "inputs": [
 // CHECK-NEXT:     "{{.*}}/parseable_output-[[OUTPUT]].o"
 // CHECK-NEXT:   ],
diff --git a/test/Driver/parseable_output_unicode.swift b/test/Driver/parseable_output_unicode.swift
index 8445518..46bebd6 100644
--- a/test/Driver/parseable_output_unicode.swift
+++ b/test/Driver/parseable_output_unicode.swift
@@ -48,7 +48,7 @@
 // CHECK-NEXT: {
 // CHECK-NEXT:   "kind": "began",
 // CHECK-NEXT:   "name": "merge-module",
-// CHECK-NEXT:   "command": "{{.*}}/swift{{c?}} -frontend -emit-module {{.*}}/你好-[[OUTPUT]].swiftmodule {{.*}} -o {{.*}}/parseable_output_unicode.swift.tmp.swiftmodule",
+// CHECK-NEXT:   "command": "{{.*}}/swift{{c?}} -frontend -merge-modules -emit-module {{.*}}/你好-[[OUTPUT]].swiftmodule {{.*}} -o {{.*}}/parseable_output_unicode.swift.tmp.swiftmodule",
 // CHECK-NEXT:   "inputs": [
 // CHECK-NEXT:     "{{.*}}/你好-[[OUTPUT]].o"
 // CHECK-NEXT:   ],
diff --git a/test/Generics/deduction.swift b/test/Generics/deduction.swift
index 02408ed..4dc2647 100644
--- a/test/Generics/deduction.swift
+++ b/test/Generics/deduction.swift
@@ -216,11 +216,12 @@
 }
 
 func testEqualIterElementTypes<A: IteratorProtocol, B: IteratorProtocol>(_ a: A, _ b: B) where A.Element == B.Element {}
-// expected-note@-1 {{requirement specified as 'A.Element' == 'B.Element' [with A = IndexingIterator<[Int]>, B = IndexingIterator<[Double]>]}}
+// expected-note@-1 {{candidate requires that the types 'Int' and 'Double' be equivalent (requirement specified as 'A.Element' == 'B.Element' [with A = IndexingIterator<[Int]>, B = IndexingIterator<[Double]>])}}
 func compareIterators() {
   var a: [Int] = []
   var b: [Double] = []
-  testEqualIterElementTypes(a.makeIterator(), b.makeIterator()) // expected-error {{'<A, B where A : IteratorProtocol, B : IteratorProtocol, A.Element == B.Element> (A, B) -> ()' requires the types 'Int' and 'Double' be equivalent}}
+  testEqualIterElementTypes(a.makeIterator(), b.makeIterator())
+  // expected-error@-1 {{cannot invoke 'testEqualIterElementTypes(_:_:)' with an argument list of type '(IndexingIterator<[Int]>, IndexingIterator<[Double]>)'}}
 }
 
 protocol P_GI {
@@ -233,9 +234,9 @@
 
 class GI_Diff {}
 func genericInheritsA<T>(_ x: T) where T : P_GI, T.Y : GI_Diff {}
-// expected-note@-1 {{requirement specified as 'T.Y' : 'GI_Diff' [with T = C_GI]}}
-genericInheritsA(C_GI()) // expected-error {{<T where T : P_GI, T.Y : GI_Diff> (T) -> ()' requires that 'C_GI.Y' (aka 'Double') inherit from 'GI_Diff'}}
-
+// expected-note@-1 {{candidate requires that 'GI_Diff' inherit from 'T.Y' (requirement specified as 'T.Y' : 'GI_Diff' [with T = C_GI])}}
+genericInheritsA(C_GI())
+// expected-error@-1 {{cannot invoke 'genericInheritsA(_:)' with an argument list of type '(C_GI)'}}
 
 //===----------------------------------------------------------------------===//
 // Deduction for member operators
@@ -318,3 +319,24 @@
     let l = min(3, oi) // expected-error{{value of optional type 'Int?' not unwrapped; did you mean to use '!' or '?'?}}
 }
 
+infix operator +&
+func +&<R, S>(lhs: inout R, rhs: S) where R : RangeReplaceableCollection, S : Sequence, R.Element == S.Element {}
+// expected-note@-1 {{candidate requires that the types 'String' and 'String.Element' (aka 'Character') be equivalent (requirement specified as 'R.Element' == 'S.Element' [with R = [String], S = String])}}
+
+func rdar33477726_1() {
+  var arr: [String] = []
+  arr +& "hello"
+  // expected-error@-1 {{binary operator '+&(_:_:)' cannot be applied to operands of type '[String]' and 'String'}}
+}
+
+func rdar33477726_2<R, S>(_: R, _: S) where R: Sequence, S == R.Element {}
+// expected-note@-1 {{candidate requires that the types 'Int' and 'String.Element' (aka 'Character') be equivalent (requirement specified as 'S' == 'R.Element' [with R = String, S = Int])}}
+rdar33477726_2("answer", 42)
+// expected-error@-1 {{cannot invoke 'rdar33477726_2(_:_:)' with an argument list of type '(String, Int)'}}
+
+prefix operator +-
+prefix func +-<T>(_: T) where T: Sequence, T.Element == Int {}
+// expected-note@-1 {{candidate requires that the types 'String.Element' (aka 'Character') and 'Int' be equivalent (requirement specified as 'T.Element' == 'Int' [with T = String])}}
+
++-"hello"
+// expected-error@-1 {{unary operator '+-(_:)' cannot be applied to an operand of type 'String'}}
diff --git a/test/Generics/same_type_constraints.swift b/test/Generics/same_type_constraints.swift
index 01b3294..c30e592 100644
--- a/test/Generics/same_type_constraints.swift
+++ b/test/Generics/same_type_constraints.swift
@@ -154,7 +154,7 @@
 
 // rdar://problem/19245317
 protocol P {
-	associatedtype T: P // expected-error{{type may not reference itself as a requirement}}
+	associatedtype T: P
 }
 
 struct S<A: P> {
diff --git a/test/IDE/complete_stmt_controlling_expr.swift b/test/IDE/complete_stmt_controlling_expr.swift
index 2308d39..2758b6f 100644
--- a/test/IDE/complete_stmt_controlling_expr.swift
+++ b/test/IDE/complete_stmt_controlling_expr.swift
@@ -132,6 +132,15 @@
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNRESOLVED_GUARD_6 | %FileCheck %s -check-prefix=UNRESOLVED_B
 // RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=UNRESOLVED_GUARD_7 | %FileCheck %s -check-prefix=UNRESOLVED_B
 
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IF_LET_BIND_1 | %FileCheck %s -check-prefix=FOOSTRUCT_DOT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IF_LET_BIND_2 | %FileCheck %s -check-prefix=FOOSTRUCT_DOT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=IF_LET_BIND_3 | %FileCheck %s -check-prefix=FOOSTRUCT_DOT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GUARD_LET_BIND_1 | %FileCheck %s -check-prefix=FOOSTRUCT_DOT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GUARD_LET_BIND_2 | %FileCheck %s -check-prefix=FOOSTRUCT_DOT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GUARD_LET_BIND_3 | %FileCheck %s -check-prefix=FOOSTRUCT_DOT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GUARD_LET_BIND_4 | %FileCheck %s -check-prefix=FOOSTRUCT_DOT
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GUARD_LET_BIND_5 | %FileCheck %s -check-prefix=FOOSTRUCT_DOT
+
 
 struct FooStruct {
   var instanceVar : Int
@@ -572,3 +581,34 @@
 func testUnresolvedGuard7(x: BB) {
   guard let x.takeEnum(.#^UNRESOLVED_GUARD_7^#) else {}
 }
+
+func testIfLetBinding1(x: FooStruct?) {
+  if let y = x, y.#^IF_LET_BIND_1^# {}
+}
+func testIfLetBinding2(x: FooStruct?) {
+  if let y = x, y.#^IF_LET_BIND_2^#
+}
+func testIfLetBinding3(x: FooStruct?) {
+  if let y = x, let z = y.#^IF_LET_BIND_3^# {}
+}
+func testGuardLetBinding1(x: FooStruct?) {
+  guard let y = x, y.#^GUARD_LET_BIND_1^# else {}
+}
+func testGuardLetBinding2(x: FooStruct?) {
+  guard let y = x, y.#^GUARD_LET_BIND_2^#
+}
+func testGuardLetBinding3(x: FooStruct?) {
+  guard let y = x, y.#^GUARD_LET_BIND_3^# else
+}
+func testGuardLetBinding4(x: FooStruct?) {
+  guard let y = x, y.#^GUARD_LET_BIND_4^# {}
+}
+func testGuardLetBinding5(x: FooStruct?) {
+  guard let y = x, let z = y.#^GUARD_LET_BIND_5^# else {}
+}
+
+// FOOSTRUCT_DOT: Begin completions
+// FOOSTRUCT_DOT-DAG: Decl[InstanceVar]/CurrNominal:      instanceVar[#Int#];
+// FOOSTRUCT_DOT-DAG: Decl[InstanceMethod]/CurrNominal:   boolGen()[#Bool#];
+// FOOSTRUCT_DOT-DAG: Decl[InstanceMethod]/CurrNominal:   intGen()[#Int#];
+// FOOSTRUCT_DOT: End completions
diff --git a/test/IDE/structure.swift b/test/IDE/structure.swift
index 36e9b86..5938294 100644
--- a/test/IDE/structure.swift
+++ b/test/IDE/structure.swift
@@ -184,3 +184,6 @@
   func perform() {foo(5, animations: {})}
 // CHECK:  <ifunc>func <name>perform()</name> {<call><name>foo</name>(<arg>5</arg>, <arg><name>animations</name>: <brace>{}</brace></arg>)</call>}</ifunc>
 }
+
+// CHECK: <typealias>typealias <name>OtherA</name> = A</typealias>
+typealias OtherA = A
diff --git a/test/IRGen/Inputs/c_functions.h b/test/IRGen/Inputs/c_functions.h
index e0b4239..b613f89 100644
--- a/test/IRGen/Inputs/c_functions.h
+++ b/test/IRGen/Inputs/c_functions.h
@@ -20,3 +20,7 @@
  useInt(thing.val[0]);
  useInt(thing.val[7]);
 }
+
+static inline unsigned int return7(void) {
+  return 7;
+}
diff --git a/test/IRGen/big_types_corner_cases.sil b/test/IRGen/big_types_corner_cases.sil
new file mode 100644
index 0000000..7d17384
--- /dev/null
+++ b/test/IRGen/big_types_corner_cases.sil
@@ -0,0 +1,113 @@
+// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -I %S/Inputs/abi %s -emit-ir -enable-large-loadable-types | %FileCheck %s
+
+// UNSUPPORTED: resilient_stdlib
+
+// REQUIRES: CPU=x86_64
+
+// REQUIRES: OS=macosx
+
+sil_stage canonical
+import c_layout
+import Builtin
+import Swift
+
+struct BigTempStruct<T> {
+  var i0 : Int32
+  var i1 : Int32
+  var i2 : Int32
+  var i3 : Int32
+  var i4 : Int32
+  var i5 : Int32
+  var i6 : Int32
+  var i7 : Int32
+  var i8 : Int32
+}
+
+public struct BigStruct {
+  var i0 : Int32 = 0
+  var i1 : Int32 = 1
+  var i2 : Int32 = 2
+  var i3 : Int32 = 3
+  var i4 : Int32 = 4
+  var i5 : Int32 = 5
+  var i6 : Int32 = 6
+  var i7 : Int32 = 7
+  var i8 : Int32 = 8
+}
+
+public struct BigBigStruct {
+  var s : BigStruct
+}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @testBitfieldInBlock
+// CHECK:         call void {{%.*}}(%TSC11BitfieldOneV* noalias nocapture sret {{%.*}}, %objc_block* {{%.*}}, %TSC11BitfieldOneV* byval align 8 {{%.*}})
+sil @testBitfieldInBlock : $@convention(thin) (@owned @convention(block) (BitfieldOne) -> BitfieldOne, BitfieldOne) -> BitfieldOne  {
+entry(%b : $@convention(block) (BitfieldOne) -> BitfieldOne, %x : $BitfieldOne):
+  %r = apply %b(%x) : $@convention(block) (BitfieldOne) -> BitfieldOne
+  return %r : $BitfieldOne
+}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @testTupleExtract
+// CHECK:         call void {{%.*}}(%TSC11BitfieldOneV* noalias nocapture sret {{%.*}}, %objc_block* {{%.*}}, %TSC11BitfieldOneV* byval align 8 {{%.*}})
+sil @testTupleExtract : $@convention(thin) (@owned (BitfieldOne, @convention(block) (BitfieldOne) -> BitfieldOne), BitfieldOne) -> BitfieldOne  {
+entry(%b : $(BitfieldOne, @convention(block) (BitfieldOne) -> (BitfieldOne)), %x : $BitfieldOne):
+  %a = tuple_extract %b : $(BitfieldOne, @convention(block) (BitfieldOne) -> (BitfieldOne)), 1
+  %r = apply %a(%x) : $@convention(block) (BitfieldOne) -> BitfieldOne
+  return %r : $BitfieldOne
+}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @testBigTempStruct(%T22big_types_corner_cases13BigTempStructV* noalias nocapture sret, %swift.bridge*, %swift.type* %Element) #0 {
+// CHECK: [[ALLOC:%.*]] = alloca %T22big_types_corner_cases13BigTempStructV
+// CHECK: call swiftcc void @testBigTempStruct(%T22big_types_corner_cases13BigTempStructV* noalias nocapture sret [[ALLOC]], %swift.bridge* %1, %swift.type* %Element)
+// CHECK: ret void
+sil @testBigTempStruct : $@convention(method) <Element> (@guaranteed _ArrayBuffer<Element>) -> @owned BigTempStruct<Element> {
+bb0(%0 : $_ArrayBuffer<Element>):
+  // function_ref specialized _ArrayBuffer.subscript.getter
+  %4 = function_ref @testBigTempStruct : $@convention(method) <τ_0_0> (@guaranteed _ArrayBuffer<τ_0_0>) -> @owned BigTempStruct<τ_0_0>
+  %9 = apply %4<Element>(%0) : $@convention(method) <τ_0_0> (@guaranteed _ArrayBuffer<τ_0_0>) -> @owned BigTempStruct<τ_0_0>
+  return %9 : $BigTempStruct<Element>
+}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @testTryApply(%T22big_types_corner_cases9BigStructV* noalias nocapture sret, i8*, %swift.refcounted*, %swift.refcounted* swiftself, %swift.error** swifterror) #0 {
+// CHECK: [[ALLOC:%.*]] = alloca %T22big_types_corner_cases9BigStructV
+// CHECK: call swiftcc void {{.*}}(%T22big_types_corner_cases9BigStructV* noalias nocapture sret [[ALLOC]]
+// CHECK: ret void
+sil @testTryApply : $@convention(thin)(() -> (@owned BigStruct, @error Error)) -> (@owned BigStruct, @error Error) {
+bb0(%0 : $() -> (@owned BigStruct, @error Error)):
+  try_apply %0() : $() -> (@owned BigStruct, @error Error), normal bb1, error bb2
+
+bb1(%ret : $BigStruct):
+  %s = struct $BigBigStruct (%ret : $BigStruct)
+  return %ret : $BigStruct
+  
+bb2(%err : $Error):
+  throw %err : $Error
+}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc i8* @testThinFuncPointer(%swift.type* %"BigTempStruct<Element>", %T22big_types_corner_cases13BigTempStructV* noalias nocapture swiftself dereferenceable({{.*}}) #0 {
+// CHECK-NEXT: entry
+// CHECK-NEXT: ret i8* bitcast (i8* (%swift.type*, %T22big_types_corner_cases13BigTempStructV*)* @testThinFuncPointer to i8*)
+sil @testThinFuncPointer : $@convention(method) <Element> (@guaranteed BigTempStruct<Element>) -> @owned Builtin.RawPointer {
+bb0(%0 : $BigTempStruct<Element>):
+  // function_ref specialized BigTempStruct.subscript.getter
+  %fref = function_ref @testThinFuncPointer : $@convention(method) <τ_0_0> (@guaranteed BigTempStruct<τ_0_0>) -> @owned Builtin.RawPointer
+  %ret = thin_function_to_pointer %fref : $@convention(method) <τ_0_0> (@guaranteed BigTempStruct<τ_0_0>) -> @owned Builtin.RawPointer to $Builtin.RawPointer
+  return %ret : $Builtin.RawPointer
+}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @testFuncWithModBlockStorageApply({ %objc_block, %swift.function }* nocapture dereferenceable({{.*}}), %T22big_types_corner_cases9BigStructV* noalias nocapture dereferenceable({{.*}}) #0 {
+// CHECK: call swiftcc void {{.*}}(%T22big_types_corner_cases9BigStructV* noalias nocapture dereferenceable({{.*}}) %1
+// CHECK: ret void
+sil @testFuncWithModBlockStorageApply : $@convention(thin) (@inout_aliasable @block_storage @callee_owned (@owned BigStruct) -> (), BigStruct) -> () {
+// %0                                             // user: %5
+// %1                                             // users: %12, %13, %7
+// %2                                             // user: %20
+// %3                                             // user: %20
+// %4                                             // user: %20
+bb0(%0 : $*@block_storage @callee_owned (@owned BigStruct) -> (), %1 : $BigStruct):
+  %proji = project_block_storage %0 : $*@block_storage @callee_owned (@owned BigStruct) -> () // user: %6
+  %ldi = load %proji : $*@callee_owned (@owned BigStruct) -> () // users: %11, %17, %20
+  %appi = apply %ldi(%1) : $@callee_owned (@owned BigStruct) -> ()
+  %ret = tuple ()                                  // user: %22
+  return %ret : $()                                // id: %22
+}
diff --git a/test/IRGen/big_types_corner_cases.swift b/test/IRGen/big_types_corner_cases.swift
index cdecd7d..6f45e7b 100644
--- a/test/IRGen/big_types_corner_cases.swift
+++ b/test/IRGen/big_types_corner_cases.swift
@@ -1,4 +1,5 @@
 // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -enable-large-loadable-types %s -emit-ir | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
+// UNSUPPORTED: resilient_stdlib
 
 public struct BigStruct {
   var i0 : Int32 = 0
@@ -194,3 +195,13 @@
   let a = Substring(s).dropFirst()
   return (s, a)
 }
+
+func bigStructGet() -> BigStruct {
+  return BigStruct()
+}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc void @_T022big_types_corner_cases11testGetFuncyyF() #0 {
+// CHECK: ret void
+public func testGetFunc() {
+  let testGetPtr: @convention(thin) () -> BigStruct = bigStructGet
+}
diff --git a/test/IRGen/big_types_corner_cases_as_library.swift b/test/IRGen/big_types_corner_cases_as_library.swift
index 6e43fd8..fc1ded6 100644
--- a/test/IRGen/big_types_corner_cases_as_library.swift
+++ b/test/IRGen/big_types_corner_cases_as_library.swift
@@ -1,4 +1,5 @@
 // RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -enable-large-loadable-types %s -emit-ir  -parse-as-library | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize
+// UNSUPPORTED: resilient_stdlib
 
 public struct BigStruct {
   var i0 : Int32 = 0
diff --git a/test/IRGen/clang_inline_opt.swift b/test/IRGen/clang_inline_opt.swift
new file mode 100644
index 0000000..11a91a9
--- /dev/null
+++ b/test/IRGen/clang_inline_opt.swift
@@ -0,0 +1,14 @@
+// RUN: %target-swift-frontend -import-objc-header %S/Inputs/c_functions.h -primary-file %s -O -emit-ir -disable-llvm-optzns | %FileCheck %s
+
+func return10() -> UInt32 {
+	return return7() + 3
+}
+
+// Sanity check that we tell Clang to generate optimizable code when
+// we're optimizing.
+
+// CHECK: define internal i32 @return7() [[CLANG_ATTRS:#[0-9]+]] {
+
+// CHECK: attributes [[CLANG_ATTRS]] = {
+// CHECK-NOT: noinline
+// CHECK-SAME: }
diff --git a/test/IRGen/partial_apply_forwarder.sil b/test/IRGen/partial_apply_forwarder.sil
index 9c6a173..4734dcc 100644
--- a/test/IRGen/partial_apply_forwarder.sil
+++ b/test/IRGen/partial_apply_forwarder.sil
@@ -70,7 +70,11 @@
 
 public class WeakBox<T> {}
 
+public struct EmptyType {}
+
 sil hidden_external @takingQ : $@convention(thin) <τ_0_0 where  τ_0_0 : Q> (@owned WeakBox<τ_0_0>) -> ()
+sil hidden_external @takingQAndEmpty : $@convention(thin) <τ_0_0 where  τ_0_0 : Q> (@owned WeakBox<τ_0_0>, EmptyType) -> ()
+sil hidden_external @takingEmptyAndQ : $@convention(thin) <τ_0_0 where  τ_0_0 : Q> (EmptyType, @owned WeakBox<τ_0_0>) -> ()
 
 // CHECK-LABEL: define{{( protected)?}} swiftcc { i8*, %swift.refcounted* } @bind_polymorphic_param_from_context(%swift.opaque* noalias nocapture, %swift.type* %"\CF\84_0_1")
 // CHECK: entry:
@@ -103,6 +107,35 @@
   return %9 : $@callee_owned () -> ()
 }
 
+// CHECK-LABEL: define{{( protected)?}} swiftcc { i8*, %swift.refcounted* } @bind_polymorphic_param_from_context_2(%swift.opaque* noalias nocapture, %swift.type* %"\CF\84_0_1")
+// CHECK:   [[OBJ:%.*]] = call {{.*}} @swift_rt_swift_allocObject
+// CHECK:   [[WB:%.*]] = bitcast %swift.refcounted* [[OBJ]]
+// CHECK:   [[REF:%.*]] = bitcast {{.*}}* [[WB]] to %swift.refcounted*
+// CHECK:   [[CLOSURE:%.*]] = insertvalue { i8*, %swift.refcounted* } { i8* bitcast (void (%swift.refcounted*)* @_T015takingQAndEmptyTA to i8*), %swift.refcounted* undef }, %swift.refcounted* [[REF]], 1
+// CHECK: }
+sil public @bind_polymorphic_param_from_context_2 : $@convention(thin) <τ_0_1>(@in τ_0_1, EmptyType) -> @owned @callee_owned () -> () {
+bb0(%0 : $*τ_0_1, %2: $EmptyType):
+  %1 = alloc_ref $WeakBox<BaseProducer<τ_0_1>>
+  %8 = function_ref @takingQAndEmpty : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>, EmptyType) -> ()
+  %9 = partial_apply %8<BaseProducer<τ_0_1>>(%1, %2) : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@owned WeakBox<τ_0_0>, EmptyType) -> ()
+  return %9 : $@callee_owned () -> ()
+}
+
+// CHECK-LABEL: define{{( protected)?}} swiftcc { i8*, %swift.refcounted* } @bind_polymorphic_param_from_context_3(%swift.opaque* noalias nocapture, %swift.type* %"\CF\84_0_1")
+// CHECK:   [[OBJ:%.*]] = call {{.*}} @swift_rt_swift_allocObject
+// CHECK:   [[WB:%.*]] = bitcast %swift.refcounted* [[OBJ]]
+// CHECK:   [[REF:%.*]] = bitcast {{.*}}* [[WB]] to %swift.refcounted*
+// CHECK:   [[CLOSURE:%.*]] = insertvalue { i8*, %swift.refcounted* } { i8* bitcast (void (%swift.refcounted*)* @_T015takingEmptyAndQTA to i8*), %swift.refcounted* undef }, %swift.refcounted* [[REF]], 1
+// CHECK: }
+
+sil public @bind_polymorphic_param_from_context_3 : $@convention(thin) <τ_0_1>(@in τ_0_1, EmptyType) -> @owned @callee_owned () -> () {
+bb0(%0 : $*τ_0_1, %2: $EmptyType):
+  %1 = alloc_ref $WeakBox<BaseProducer<τ_0_1>>
+  %8 = function_ref @takingEmptyAndQ : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (EmptyType, @owned WeakBox<τ_0_0>) -> ()
+  %9 = partial_apply %8<BaseProducer<τ_0_1>>(%2, %1) : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (EmptyType, @owned WeakBox<τ_0_0>) -> ()
+  return %9 : $@callee_owned () -> ()
+}
+
 // CHECK-LABEL: define{{( protected)?}} swiftcc void @bind_polymorphic_param_from_forwarder_parameter(%swift.opaque* noalias nocapture, %swift.type* %"\CF\84_0_1")
 // CHECK: entry:
 // CHECK:   [[BPTY:%.*]] = call %swift.type* @_T023partial_apply_forwarder12BaseProducerVMa(%swift.type* %"\CF\84_0_1")
diff --git a/test/IRGen/tail_alloc.sil b/test/IRGen/tail_alloc.sil
index 4c5ad1c..5bf1139 100644
--- a/test/IRGen/tail_alloc.sil
+++ b/test/IRGen/tail_alloc.sil
@@ -35,7 +35,7 @@
 
 // CHECK-LABEL: define{{( protected)?}} {{.*}}* @alloc_on_heap
 // CHECK:      [[M:%[0-9]+]] = call %swift.type* @_T0{{[a-zA-Z0-9_]+}}Ma()
-// CHECK-NEXT: [[O:%[0-9]+]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* [[M]], i64 28, i64 7) #5
+// CHECK-NEXT: [[O:%[0-9]+]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* [[M]], i64 28, i64 7)
 // CHECK-NEXT: [[O2:%[0-9]+]] = bitcast %swift.refcounted* [[O]] to %[[C:.*TestClass.*]]*
 // CHECK-NEXT:  ret %[[C]]* [[O2]]
 sil @alloc_on_heap : $@convention(thin) () -> @owned TestClass {
@@ -47,7 +47,7 @@
 
 // CHECK-LABEL: define{{( protected)?}} {{.*}}* @alloc_3_on_heap
 // CHECK:      [[M:%[0-9]+]] = call %swift.type* @_T0{{[a-zA-Z0-9_]+}}CMa()
-// CHECK-NEXT: [[O:%[0-9]+]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* [[M]], i64 40, i64 7) #5
+// CHECK-NEXT: [[O:%[0-9]+]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* [[M]], i64 40, i64 7)
 // CHECK-NEXT: [[O2:%[0-9]+]] = bitcast %swift.refcounted* [[O]] to %[[C:.*TestClass.*]]*
 // CHECK-NEXT:  ret %[[C]]* [[O2]]
 sil @alloc_3_on_heap : $@convention(thin) () -> @owned TestClass {
@@ -63,7 +63,7 @@
 // CHECK:      [[M:%[0-9]+]] = call %swift.type* @_T0{{[a-zA-Z0-9_]+}}Ma()
 // CHECK-NEXT: [[S:%[0-9]+]] = mul i64 4, %0
 // CHECK-NEXT: [[A:%[0-9]+]] = add i64 20, [[S]]
-// CHECK-NEXT: [[O:%[0-9]+]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* [[M]], i64 [[A]], i64 7) #5
+// CHECK-NEXT: [[O:%[0-9]+]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* [[M]], i64 [[A]], i64 7)
 // CHECK-NEXT: [[O2:%[0-9]+]] = bitcast %swift.refcounted* [[O]] to %[[C:.*TestClass.*]]*
 // CHECK-NEXT:  ret %[[C]]* [[O2]]
 sil @alloc_non_const_count : $@convention(thin) (Builtin.Word) -> @owned TestClass {
@@ -80,7 +80,7 @@
 // CHECK-NEXT: [[S4:%[0-9]+]] = and i64 [[S3]], -4
 // CHECK-NEXT: [[S5:%[0-9]+]] = mul i64 4, %1
 // CHECK-NEXT: [[S6:%[0-9]+]] = add i64 [[S4]], [[S5]]
-// CHECK-NEXT: [[O:%[0-9]+]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* [[M]], i64 [[S6]], i64 7) #5
+// CHECK-NEXT: [[O:%[0-9]+]] = call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* [[M]], i64 [[S6]], i64 7)
 // CHECK-NEXT: [[O2:%[0-9]+]] = bitcast %swift.refcounted* [[O]] to %[[C:.*TestClass.*]]*
 // CHECK-NEXT:  ret %[[C]]* [[O2]]
 sil @alloc_2_non_const_count : $@convention(thin) (Builtin.Word, Builtin.Word) -> @owned TestClass {
@@ -95,7 +95,7 @@
 // CHECK-NEXT: [[S3:%[0-9]+]] = and i64 [[S1]], [[S2]]
 // CHECK-NEXT: [[S4:%[0-9]+]] = mul i64 %stride, %0
 // CHECK-NEXT: [[S5:%[0-9]+]] = add i64 [[S3]], [[S4]]
-// CHECK:      call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* %{{[0-9]+}}, i64 [[S5]], i64 7) #5
+// CHECK:      call noalias %swift.refcounted* @swift_rt_swift_allocObject(%swift.type* %{{[0-9]+}}, i64 [[S5]], i64 7)
 // CHECK:      ret
 sil @alloc_generic : $@convention(thin) <T> (Builtin.Word, @thick T.Type) -> @owned TestClass {
 bb0(%0 : $Builtin.Word, %1 : $@thick T.Type):
diff --git a/test/Inputs/clang-importer-sdk/usr/include/Foundation.h b/test/Inputs/clang-importer-sdk/usr/include/Foundation.h
index d5d434c..a5faad7 100644
--- a/test/Inputs/clang-importer-sdk/usr/include/Foundation.h
+++ b/test/Inputs/clang-importer-sdk/usr/include/Foundation.h
@@ -1098,13 +1098,21 @@
   FictionalServerErrorMeltedDown = 1
 } FictionalServerErrorCode;
 
+@protocol Wearable
+- (void)wear;
+@end
+
 @protocol Garment
 @end
 
 @protocol Cotton
 @end
 
-@interface Coat
+@interface Coat : NSObject<Wearable>
+
+- (void)wear;
+@property (class) Coat <Wearable> *fashionStatement;
+
 @end
 
 @protocol NSLaundry
diff --git a/test/Parse/multiline_errors.swift b/test/Parse/multiline_errors.swift
index ff1f68c..4fa56d0 100644
--- a/test/Parse/multiline_errors.swift
+++ b/test/Parse/multiline_errors.swift
Binary files differ
diff --git a/test/Parse/multiline_normalize_newline.swift b/test/Parse/multiline_normalize_newline.swift
new file mode 100644
index 0000000..acbaa5a
--- /dev/null
+++ b/test/Parse/multiline_normalize_newline.swift
Binary files differ
diff --git a/test/Parse/multiline_string.swift b/test/Parse/multiline_string.swift
index d9965f9..c2a3d3d 100644
--- a/test/Parse/multiline_string.swift
+++ b/test/Parse/multiline_string.swift
@@ -83,6 +83,11 @@
 // CHECK: "\\"
 
 _ = """
+  \\
+  """
+// CHECK: "\\"
+
+_ = """
 
   ABC
   """
@@ -122,7 +127,7 @@
     \("""
       substring2 \          
       substring3
-      """)\
+      """)
     """) \
   whitepsace
   """
diff --git a/test/Prototypes/BigInt.swift b/test/Prototypes/BigInt.swift
index ee81655..56374da 100644
--- a/test/Prototypes/BigInt.swift
+++ b/test/Prototypes/BigInt.swift
@@ -24,7 +24,7 @@
   func addingFullWidth(_ other: Self) ->
     (high: Self, low: Self) {
     let sum = self.addingReportingOverflow(other)
-    return (sum.overflow == .overflow ? 1 : 0, sum.partialValue)
+    return (sum.overflow ? 1 : 0, sum.partialValue)
   }
 
   /// Returns the high and low parts of two seqeuential potentially overflowing
@@ -33,8 +33,8 @@
     (high: Self, low: Self) {
     let xy = x.addingReportingOverflow(y)
     let xyz = xy.partialValue.addingReportingOverflow(z)
-    let high: Self = (xy.overflow == .overflow ? 1 : 0) +
-      (xyz.overflow == .overflow ? 1 : 0)
+    let high: Self = (xy.overflow ? 1 : 0) +
+      (xyz.overflow ? 1 : 0)
     return (high, xyz.partialValue)
   }
 
@@ -43,7 +43,7 @@
   func subtractingWithBorrow(_ rhs: Self) ->
     (borrow: Self, partialValue: Self) {
     let difference = subtractingReportingOverflow(rhs)
-    return (difference.overflow == .overflow ? 1 : 0, difference.partialValue)
+    return (difference.overflow ? 1 : 0, difference.partialValue)
   }
 
   /// Returns a tuple containing the value that would be borrowed from a higher
@@ -53,8 +53,8 @@
     let firstDifference = subtractingReportingOverflow(x)
     let secondDifference =
       firstDifference.partialValue.subtractingReportingOverflow(y)
-    let borrow: Self = (firstDifference.overflow == .overflow ? 1 : 0) +
-      (secondDifference.overflow == .overflow ? 1 : 0)
+    let borrow: Self = (firstDifference.overflow ? 1 : 0) +
+      (secondDifference.overflow ? 1 : 0)
     return (borrow, secondDifference.partialValue)
   }
 }
@@ -107,7 +107,7 @@
     var source = source
     if source < 0 as T {
       if source.bitWidth <= UInt64.bitWidth {
-        let sourceMag = Int(extendingOrTruncating: source).magnitude
+        let sourceMag = Int(truncatingIfNeeded: source).magnitude
         self = _BigInt(sourceMag)
         self.isNegative = true
         return
@@ -123,7 +123,7 @@
     _sanityCheck(wordRatio != 0)
     for var sourceWord in source.words {
       for _ in 0..<wordRatio {
-        _data.append(Word(extendingOrTruncating: sourceWord))
+        _data.append(Word(truncatingIfNeeded: sourceWord))
         sourceWord >>= Word.bitWidth
       }
     }
@@ -134,7 +134,7 @@
     self.init(source)
   }
 
-  public init<T : BinaryInteger>(extendingOrTruncating source: T) {
+  public init<T : BinaryInteger>(truncatingIfNeeded source: T) {
     self.init(source)
   }
 
@@ -142,11 +142,11 @@
     self.init(source)
   }
 
-  public init<T : FloatingPoint>(_ source: T) {
+  public init<T : BinaryFloatingPoint>(_ source: T) {
     fatalError("Not implemented")
   }
 
-  public init?<T : FloatingPoint>(exactly source: T) {
+  public init?<T : BinaryFloatingPoint>(exactly source: T) {
     fatalError("Not implemented")
   }
 
@@ -156,7 +156,7 @@
     if Word.bitWidth > UInt32.bitWidth {
       return Word(arc4random()) << 32 | Word(arc4random())
     } else {
-      return Word(extendingOrTruncating: arc4random())
+      return Word(truncatingIfNeeded: arc4random())
     }
   }
 
@@ -513,8 +513,7 @@
         //      0b11111111 + (0b11111101_____00000010) + 0b11111111
         //                   (0b11111110_____00000001) + 0b11111111
         //                   (0b11111111_____00000000)
-        _sanityCheck(
-          product.high.addingReportingOverflow(carry).overflow == .none)
+        _sanityCheck(!product.high.addingReportingOverflow(carry).overflow)
         carry = product.high &+ carry
       }
 
@@ -668,7 +667,7 @@
     var word: UInt = 0
     var shift = 0
     for w in twosComplementData {
-      word |= UInt(extendingOrTruncating: w) << shift
+      word |= UInt(truncatingIfNeeded: w) << shift
       shift += Word.bitWidth
       if shift == UInt.bitWidth {
         words.append(word)
@@ -1090,16 +1089,18 @@
     data.removeFirst(Swift.min(data.count, words))
   }
 
-  public static func <<=(lhs: inout _BigInt, rhs: Int) {
+  public static func <<= <RHS : BinaryInteger>(lhs: inout _BigInt, rhs: RHS) {
     defer { lhs._checkInvariants() }
     guard rhs != 0 else { return }
     guard rhs > 0 else {
-      lhs >>= -rhs
+      lhs >>= 0 - rhs
       return
     }
 
+    let wordWidth = RHS(Word.bitWidth)
+    
     // We can add `rhs / bits` extra words full of zero at the low end.
-    let extraWords = rhs / Word.bitWidth
+    let extraWords = Int(rhs / wordWidth)
     lhs._data.reserveCapacity(lhs._data.count + extraWords + 1)
     _BigInt._shiftLeft(&lhs._data, byWords: extraWords)
 
@@ -1107,7 +1108,7 @@
     // For each pair of words, we'll use the high `offset` bits of the
     // lower word and the low `Word.bitWidth - offset` bits of the higher
     // word.
-    let highOffset = rhs % Word.bitWidth
+    let highOffset = Int(rhs % wordWidth)
     let lowOffset = Word.bitWidth - highOffset
 
     // If there's no offset, we're finished, as `rhs` was a multiple of
@@ -1126,19 +1127,20 @@
     lhs._standardize()
   }
 
-  public static func >>=(lhs: inout _BigInt, rhs: Int) {
+  public static func >>= <RHS : BinaryInteger>(lhs: inout _BigInt, rhs: RHS) {
     defer { lhs._checkInvariants() }
     guard rhs != 0 else { return }
     guard rhs > 0 else {
-      lhs <<= -rhs
+      lhs <<= 0 - rhs
       return
     }
 
     var tempData = lhs._dataAsTwosComplement()
 
+    let wordWidth = RHS(Word.bitWidth)
     // We can remove `rhs / bits` full words at the low end.
     // If that removes the entirety of `_data`, we're done.
-    let wordsToRemove = rhs / Word.bitWidth
+    let wordsToRemove = Int(rhs / wordWidth)
     _BigInt._shiftRight(&tempData, byWords: wordsToRemove)
     guard tempData.count != 0 else {
       lhs = lhs.isNegative ? -1 : 0
@@ -1149,7 +1151,7 @@
     // For each pair of words, we'll use the low `offset` bits of the
     // higher word and the high `_BigInt.Word.bitWidth - offset` bits of
     // the lower word.
-    let lowOffset = rhs % Word.bitWidth
+    let lowOffset = Int(rhs % wordWidth)
     let highOffset = Word.bitWidth - lowOffset
 
     // If there's no offset, we're finished, as `rhs` was a multiple of
@@ -1169,18 +1171,6 @@
     tempData[tempData.count - 1] >>= lowOffset
     lhs = _BigInt(_twosComplementData: tempData)
   }
-
-  public static func <<(lhs: _BigInt, rhs: Int) -> _BigInt {
-    var lhs = lhs
-    lhs <<= rhs
-    return lhs
-  }
-
-  public static func >>(lhs: _BigInt, rhs: Int) -> _BigInt {
-    var lhs = lhs
-    lhs >>= rhs
-    return lhs
-  }
 }
 
 //===--- Bit --------------------------------------------------------------===//
@@ -1206,7 +1196,7 @@
     self = value
   }
 
-  init?<T: FloatingPoint>(exactly source: T) {
+  init?<T: BinaryFloatingPoint>(exactly source: T) {
     switch source {
     case T(0): value = 0
     case T(1): value = 1
@@ -1215,7 +1205,7 @@
     }
   }
 
-  init<T: FloatingPoint>(_ source: T) {
+  init<T: BinaryFloatingPoint>(_ source: T) {
     self = Bit(exactly: source.rounded(.down))!
   }
 
@@ -1228,7 +1218,7 @@
     }
   }
 
-  init<T: BinaryInteger>(extendingOrTruncating source: T) {
+  init<T: BinaryInteger>(truncatingIfNeeded source: T) {
     value = UInt8(source & 1)
   }
 
@@ -1302,60 +1292,60 @@
 
   // Arithmetic Operations / Operators
 
-  func _checkOverflow(_ v: UInt8) -> ArithmeticOverflow {
+  func _checkOverflow(_ v: UInt8) -> Bool {
     let mask: UInt8 = ~0 << 1
-    return v & mask == 0 ? .none : .overflow
+    return v & mask != 0
   }
   
   func addingReportingOverflow(_ rhs: Bit) ->
-    (partialValue: Bit, overflow: ArithmeticOverflow) {
+    (partialValue: Bit, overflow: Bool) {
       let result = value &+ rhs.value
       return (Bit(result & 1), _checkOverflow(result))
   }
 
   func subtractingReportingOverflow(_ rhs: Bit) ->
-    (partialValue: Bit, overflow: ArithmeticOverflow) {
+    (partialValue: Bit, overflow: Bool) {
       let result = value &- rhs.value
       return (Bit(result & 1), _checkOverflow(result))
   }
 
   func multipliedReportingOverflow(by rhs: Bit) ->
-    (partialValue: Bit, overflow: ArithmeticOverflow) {
+    (partialValue: Bit, overflow: Bool) {
       let result = value &* rhs.value
-      return (Bit(result), .none)
+      return (Bit(result), false)
   }
 
   func dividedReportingOverflow(by rhs: Bit) ->
-    (partialValue: Bit, overflow: ArithmeticOverflow) {
-      return rhs == 0 ? (self, .none) : (self, .overflow)
+    (partialValue: Bit, overflow: Bool) {
+      return (self, rhs != 0)
   }
 
   func remainderReportingOverflow(dividingBy rhs: Bit) ->
-    (partialValue: Bit, overflow: ArithmeticOverflow) {
+    (partialValue: Bit, overflow: Bool) {
       fatalError()
   }
 
   static func +=(lhs: inout Bit, rhs: Bit) {
     let result = lhs.addingReportingOverflow(rhs)
-    assert(result.overflow == .none, "Addition overflow")
+    assert(!result.overflow, "Addition overflow")
     lhs = result.partialValue
   }
 
   static func -=(lhs: inout Bit, rhs: Bit) {
     let result = lhs.subtractingReportingOverflow(rhs)
-    assert(result.overflow == .none, "Subtraction overflow")
+    assert(!result.overflow, "Subtraction overflow")
     lhs = result.partialValue
   }
 
   static func *=(lhs: inout Bit, rhs: Bit) {
     let result = lhs.multipliedReportingOverflow(by: rhs)
-    assert(result.overflow == .none, "Multiplication overflow")
+    assert(!result.overflow, "Multiplication overflow")
     lhs = result.partialValue
   }
 
   static func /=(lhs: inout Bit, rhs: Bit) {
     let result = lhs.dividedReportingOverflow(by: rhs)
-    assert(result.overflow == .none, "Division overflow")
+    assert(!result.overflow, "Division overflow")
     lhs = result.partialValue
   }
 
@@ -1629,7 +1619,7 @@
   expectTrue(z < zComp + 1)
 
   let w = BigInt(UInt.max)
-  let wComp = UInt(extendingOrTruncating: w)
+  let wComp = UInt(truncatingIfNeeded: w)
   expectTrue(w == wComp)
   expectTrue(wComp == w)
   expectTrue(wComp - (1 as UInt) < w)
@@ -1749,7 +1739,7 @@
   expectTrue(z < zComp + 1)
 
   let w = BigInt8(UInt.max)
-  let wComp = UInt(extendingOrTruncating: w)
+  let wComp = UInt(truncatingIfNeeded: w)
   expectTrue(w == wComp)
   expectTrue(wComp == w)
   expectTrue(wComp - (1 as UInt) < w)
@@ -1788,7 +1778,8 @@
 
   (x, y) = (BigInt(UInt.max), UInt.max)
   for i in 0...64 {   // test 64-bit shift, should both be zero
-    expectTrue(x >> i == y >> i)
+    expectTrue(x >> i == y >> i,
+    "\(x) as \(type(of:x)) >> \(i) => \(x >> i)  !=  \(y) as \(type(of:y)) >> \(i) => \(y >> i)")
   }
 
   x = BigInt(-1)
@@ -1811,8 +1802,8 @@
     expectTrue(x & ~0 == x)
     expectTrue(x ^ 0 == x)
     expectTrue(x ^ ~0 == ~x)
-    expectTrue(x == BigInt8(Int(extendingOrTruncating: x)))
-    expectTrue(~x == BigInt8(~Int(extendingOrTruncating: x)))
+    expectTrue(x == BigInt8(Int(truncatingIfNeeded: x)))
+    expectTrue(~x == BigInt8(~Int(truncatingIfNeeded: x)))
   }
 }
 
diff --git a/test/Prototypes/UnicodeDecoders.swift b/test/Prototypes/UnicodeDecoders.swift
index 96491e3..ef9e6cb 100644
--- a/test/Prototypes/UnicodeDecoders.swift
+++ b/test/Prototypes/UnicodeDecoders.swift
@@ -195,7 +195,7 @@
 
   if !utfStr.contains(0) {
     if Encoding.self == Unicode.UTF8.self {
-      var ntbs = utfStr.map { CChar(extendingOrTruncating: $0) }
+      var ntbs = utfStr.map { CChar(truncatingIfNeeded: $0) }
       ntbs.append(0)
       expectEqualSequence(
         expected, utf32(S(cString: ntbs)), "\(S.self) init(cString:)")
diff --git a/test/SIL/ownership-verifier/opaque_use_verifier.sil b/test/SIL/ownership-verifier/opaque_use_verifier.sil
index 23f767a..d57b0b1 100644
--- a/test/SIL/ownership-verifier/opaque_use_verifier.sil
+++ b/test/SIL/ownership-verifier/opaque_use_verifier.sil
@@ -14,3 +14,46 @@
   %1 = unconditional_checked_cast_value take_always %0 : $Builtin.Int32 to $T
   return %1 : $T
 }
+
+sil @opaque_identity : $@convention(thin) <T> (@in T) -> @out T {
+bb0(%0 : @owned $T):
+  return %0 : $T
+}
+
+sil @opaque_copy : $@convention(thin) <T> (@in_guaranteed T) -> @out T {
+bb0(%0 : @guaranteed $T):
+  %1 = copy_value %0 : $T
+  return %1 : $T
+}
+
+sil @opaque_arg_copy : $@convention(thin) <T> (@in T) -> @out T {
+bb0(%0 : @owned $T):
+  %1 = begin_borrow %0 : $T
+  %2 = copy_value %1 : $T
+  %9 = function_ref @opaque_identity : $@convention(thin) <T> (@in T) -> @out T
+  %11 = apply %9<T>(%2) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @out τ_0_0
+  end_borrow %1 from %0 : $T, $T
+  destroy_value %0 : $T
+  return %11 : $T
+}
+
+sil @opaque_arg_borrow : $@convention(thin) <T> (@in T) -> @out T {
+bb0(%0 : @owned $T):
+  %1 = begin_borrow %0 : $T
+  %9 = function_ref @opaque_copy : $@convention(thin) <T> (@in_guaranteed T) -> @out T
+  %11 = apply %9<T>(%1) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> @out τ_0_0
+  end_borrow %1 from %0 : $T, $T
+  destroy_value %0 : $T
+  return %11 : $T
+}
+
+sil @opaque_arg_guaranteed : $@convention(thin) <T> (@in_guaranteed T) -> @out T {
+bb0(%0 : @guaranteed $T):
+  %1 = copy_value %0 : $T
+  %2 = begin_borrow %1 : $T
+  %3 = function_ref @opaque_copy : $@convention(thin) <T> (@in_guaranteed T) -> @out T
+  %4 = apply %3<T>(%2) : $@convention(thin) <T> (@in_guaranteed T) -> @out T
+  end_borrow %2 from %1 : $T, $T
+  destroy_value %1 : $T
+  return %4 : $T
+}
diff --git a/test/SILGen/opaque_ownership.swift b/test/SILGen/opaque_ownership.swift
new file mode 100644
index 0000000..0b666957
--- /dev/null
+++ b/test/SILGen/opaque_ownership.swift
@@ -0,0 +1,34 @@
+// RUN: %target-swift-frontend -enable-sil-opaque-values -enable-sil-ownership -emit-sorted-sil -Xllvm -sil-full-demangle -emit-silgen -parse-stdlib -parse-as-library %s | %FileCheck %s
+
+public protocol UnkeyedDecodingContainer {
+  var isAtEnd: Builtin.Int1 { get }
+}
+
+public protocol Decoder {
+  func unkeyedContainer() throws -> UnkeyedDecodingContainer
+}
+
+// Test open_existential_value ownership
+// ---
+// CHECK-LABEL: sil @_T016opaque_ownership11takeDecoderBi1_AA0D0_p4from_tKF : $@convention(thin) (@in Decoder) -> (Builtin.Int1, @error Builtin.NativeObject) {
+// CHECK: bb0(%0 : @owned $Decoder):
+// CHECK:  [[BORROW1:%.*]] = begin_borrow %0 : $Decoder
+// CHECK:  [[OPENED:%.*]] = open_existential_value [[BORROW1]] : $Decoder to $@opened("{{.*}}") Decoder
+// CHECK:  [[WT:%.*]] = witness_method $@opened("{{.*}}") Decoder, #Decoder.unkeyedContainer!1 : <Self where Self : Decoder> (Self) -> () throws -> UnkeyedDecodingContainer, %4 : $@opened("{{.*}}") Decoder : $@convention(witness_method) <τ_0_0 where τ_0_0 : Decoder> (@in_guaranteed τ_0_0) -> (@out UnkeyedDecodingContainer, @error Builtin.NativeObject)
+// CHECK:  try_apply [[WT]]<@opened("{{.*}}") Decoder>([[OPENED]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Decoder> (@in_guaranteed τ_0_0) -> (@out UnkeyedDecodingContainer, @error Builtin.NativeObject), normal bb2, error bb1
+//
+// CHECK:bb{{.*}}([[RET1:%.*]] : @owned $UnkeyedDecodingContainer):
+// CHECK:  end_borrow [[BORROW1]] from %0 : $Decoder, $Decoder
+// CHECK:  [[BORROW2:%.*]] = begin_borrow [[RET1]] : $UnkeyedDecodingContainer
+// CHECK:  [[OPENED2:%.*]] = open_existential_value [[BORROW2]] : $UnkeyedDecodingContainer to $@opened("{{.*}}") UnkeyedDecodingContainer
+// CHECK:  [[WT2:%.*]] = witness_method $@opened("{{.*}}") UnkeyedDecodingContainer, #UnkeyedDecodingContainer.isAtEnd!getter.1 : <Self where Self : UnkeyedDecodingContainer> (Self) -> () -> Builtin.Int1, [[OPENED2]] : $@opened("{{.*}}") UnkeyedDecodingContainer : $@convention(witness_method) <τ_0_0 where τ_0_0 : UnkeyedDecodingContainer> (@in_guaranteed τ_0_0) -> Builtin.Int1
+// CHECK:  [[RET2:%.*]] = apply [[WT2]]<@opened("{{.*}}") UnkeyedDecodingContainer>([[OPENED2]]) : $@convention(witness_method) <τ_0_0 where τ_0_0 : UnkeyedDecodingContainer> (@in_guaranteed τ_0_0) -> Builtin.Int1
+// CHECK:  end_borrow [[BORROW2]] from [[RET1]] : $UnkeyedDecodingContainer, $UnkeyedDecodingContainer
+// CHECK:  destroy_value [[RET1]] : $UnkeyedDecodingContainer
+// CHECK:  destroy_value %0 : $Decoder
+// CHECK:  return [[RET2]] : $Builtin.Int1
+// CHECK-LABEL: } // end sil function '_T016opaque_ownership11takeDecoderBi1_AA0D0_p4from_tKF'
+public func takeDecoder(from decoder: Decoder) throws -> Builtin.Int1 {
+  let container = try decoder.unkeyedContainer()
+  return container.isAtEnd
+}
diff --git a/test/SILGen/opaque_values_silgen.swift b/test/SILGen/opaque_values_silgen.swift
index 762ce3d..4248bf8 100644
--- a/test/SILGen/opaque_values_silgen.swift
+++ b/test/SILGen/opaque_values_silgen.swift
@@ -1074,6 +1074,30 @@
   return value?.asP()
 }
 
+public protocol FooP {
+  func foo() -> Self
+}
+
+// Test emitting a protocol witness for a method (with @in_guaranteed self) on a dependent generic type.
+// ---
+// CHECK-LABEL: sil private [transparent] [thunk] @_T020opaque_values_silgen21s510_______OpaqueSelfVyxGAA4FooPAAlAaEP3fooxyFTW : $@convention(witness_method) <τ_0_0> (@in_guaranteed s510_______OpaqueSelf<τ_0_0>) -> @out s510_______OpaqueSelf<τ_0_0> {
+// CHECK: bb0(%0 : $s510_______OpaqueSelf<τ_0_0>):
+// CHECK:   [[COPY:%.*]] = copy_value %0 : $s510_______OpaqueSelf<τ_0_0>
+// CHECK:   [[FN:%.*]] = function_ref @_T020opaque_values_silgen21s510_______OpaqueSelfV3fooACyxGyF : $@convention(method) <τ_0_0> (@in_guaranteed s510_______OpaqueSelf<τ_0_0>) -> @out s510_______OpaqueSelf<τ_0_0>
+// CHECK:   [[BORROW:%.*]] = begin_borrow [[COPY]] : $s510_______OpaqueSelf<τ_0_0>
+// CHECK:   [[RESULT:%.*]] = apply [[FN]]<τ_0_0>([[BORROW]]) : $@convention(method) <τ_0_0> (@in_guaranteed s510_______OpaqueSelf<τ_0_0>) -> @out s510_______OpaqueSelf<τ_0_0>
+// CHECK:   end_borrow [[BORROW]] from [[COPY]] : $s510_______OpaqueSelf<τ_0_0>
+// CHECK:   destroy_value [[COPY]] : $s510_______OpaqueSelf<τ_0_0>
+// CHECK:   return [[RESULT]] : $s510_______OpaqueSelf<τ_0_0>
+// CHECK-LABEL: } // end sil function '_T020opaque_values_silgen21s510_______OpaqueSelfVyxGAA4FooPAAlAaEP3fooxyFTW'
+struct s510_______OpaqueSelf<Base> : FooP {
+  var x: Base
+
+  func foo() -> s510_______OpaqueSelf<Base> {
+    return self
+  }
+}
+
 // Tests conditional value casts and correspondingly generated reabstraction thunk, with <T> types
 // ---
 // CHECK-LABEL: sil hidden @_T020opaque_values_silgen21s999_____condTFromAnyyyp_xtlF : $@convention(thin) <T> (@in Any, @in T) -> () {
diff --git a/test/SILGen/shared.swift b/test/SILGen/shared.swift
index 9d84c61..f8a859f 100644
--- a/test/SILGen/shared.swift
+++ b/test/SILGen/shared.swift
@@ -1,4 +1,140 @@
-// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -emit-silgen -sil-serialize-witness-tables %s -disable-objc-attr-requires-foundation-module | %FileCheck %s
+// RUN: %target-swift-frontend -Xllvm -sil-full-demangle -emit-silgen -sil-serialize-witness-tables %s -disable-objc-attr-requires-foundation-module -enable-sil-ownership | %FileCheck %s
 
-// CHECK-LABEL: sil hidden @_T06shared0A9_argumentySih1x_SSh1ytF 
-func shared_argument(x : __shared Int, y : __shared String) {}
+class RefAggregate {}
+struct ValueAggregate { let x = RefAggregate() }
+
+
+// CHECK-LABEL: sil hidden @_T06shared0A10_argumentsySih7trivial_AA14ValueAggregateVh5valueAA03RefE0Ch3reftF : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()
+func shared_arguments(trivial : __shared Int, value : __shared ValueAggregate, ref : __shared RefAggregate) {
+  // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @guaranteed $ValueAggregate, [[REF_VAL:%[0-9]+]] : @guaranteed $RefAggregate):
+  // CHECK: [[OWNED_FUNC:%[0-9]+]] = function_ref @_T06shared15owned_argumentsySi7trivial_AA14ValueAggregateV5valueAA03RefF0C3reftF
+  // CHECK: [[COPY_VALUE_VAL:%[0-9]+]] = copy_value [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: [[COPY_REF_VAL:%[0-9]+]] = copy_value [[REF_VAL]] : $RefAggregate
+  // CHECK: {{%.*}} = apply [[OWNED_FUNC]]([[TRIVIAL_VAL]], [[COPY_VALUE_VAL]], [[COPY_REF_VAL]]) : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  // CHECK: } // end sil function '_T06shared0A10_argumentsySih7trivial_AA14ValueAggregateVh5valueAA03RefE0Ch3reftF'
+  return owned_arguments(trivial: trivial, value: value, ref: ref)
+}
+
+// CHECK-LABEL: sil hidden @_T06shared15owned_argumentsySi7trivial_AA14ValueAggregateV5valueAA03RefF0C3reftF : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+func owned_arguments(trivial : Int, value : ValueAggregate, ref : RefAggregate) {
+  // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @owned $ValueAggregate, [[REF_VAL:%[0-9]+]] : @owned $RefAggregate):
+  // CHECK: [[SHARED_FUNC:%[0-9]+]] = function_ref @_T06shared0A10_argumentsySih7trivial_AA14ValueAggregateVh5valueAA03RefE0Ch3reftF
+  // CHECK: [[BORROW_VALUE_VAL:%[0-9]+]] = begin_borrow [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: [[BORROW_REF_VAL:%[0-9]+]] = begin_borrow [[REF_VAL]] : $RefAggregate
+  // CHECK: {{%.*}} = apply [[SHARED_FUNC]]([[TRIVIAL_VAL]], [[BORROW_VALUE_VAL]], [[BORROW_REF_VAL]])
+  // CHECK: end_borrow [[BORROW_REF_VAL]] from [[REF_VAL]] : $RefAggregate, $RefAggregate
+  // CHECK: end_borrow [[BORROW_VALUE_VAL]] from [[VALUE_VAL]] : $ValueAggregate, $ValueAggregate
+  // CHECK: destroy_value [[REF_VAL]] : $RefAggregate
+  // CHECK: destroy_value [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: } // end sil function '_T06shared15owned_argumentsySi7trivial_AA14ValueAggregateV5valueAA03RefF0C3reftF'
+  return shared_arguments(trivial: trivial, value: value, ref: ref)
+}
+
+// CHECK-LABEL: sil hidden @_T06shared0A17_argument_captureySih7trivial_AA14ValueAggregateVh5valueAA03RefF0Ch3reftF : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()
+func shared_argument_capture(trivial : __shared Int, value : __shared ValueAggregate, ref : __shared RefAggregate) {
+  // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @guaranteed $ValueAggregate, [[REF_VAL:%[0-9]+]] : @guaranteed $RefAggregate):
+  // CHECK: [[COPY_VALUE_VAL:%[0-9]+]] = copy_value [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: [[COPY_REF_VAL:%[0-9]+]] = copy_value [[REF_VAL]] : $RefAggregate
+  // CHECK: [[CLO_1:%[0-9]+]] = function_ref @_T06shared0A17_argument_captureySih7trivial_AA14ValueAggregateVh5valueAA03RefF0Ch3reftFyycfU_
+  // CHECK: {{%.*}} = apply [[CLO_1]]([[TRIVIAL_VAL]], [[COPY_VALUE_VAL]], [[COPY_REF_VAL]]) : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  _ = {
+    return shared_arguments(trivial: trivial, value: value, ref: ref)
+  }()
+  
+  // CHECK: [[COPY_VALUE_VAL_AGAIN:%[0-9]+]] = copy_value [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: [[COPY_REF_VAL_AGAIN:%[0-9]+]] = copy_value [[REF_VAL]] : $RefAggregate
+  // CHECK: [[CLO_2:%[0-9]+]] = function_ref @_T06shared0A17_argument_captureySih7trivial_AA14ValueAggregateVh5valueAA03RefF0Ch3reftFyycfU0_ : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  // CHECK: {{%.*}} = apply [[CLO_2]]([[TRIVIAL_VAL]], [[COPY_VALUE_VAL_AGAIN]], [[COPY_REF_VAL_AGAIN]]) : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  _ = {
+    return owned_arguments(trivial: trivial, value: value, ref: ref)
+  }()
+  
+  // CHECK: } // end sil function '_T06shared0A17_argument_captureySih7trivial_AA14ValueAggregateVh5valueAA03RefF0Ch3reftF'
+  
+  // ======== FIRST CLOSURE ==========
+
+  // CHECK-LABEL: sil private @_T06shared0A17_argument_captureySih7trivial_AA14ValueAggregateVh5valueAA03RefF0Ch3reftFyycfU_ : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @owned $ValueAggregate, [[REF_VAL:%[0-9]+]] : @owned $RefAggregate):
+  // CHECK: [[SHARED_CALL:%[0-9]+]] = function_ref @_T06shared0A10_argumentsySih7trivial_AA14ValueAggregateVh5valueAA03RefE0Ch3reftF : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()
+  // CHECK: [[BORROW_VALUE_VAL:%[0-9]+]] = begin_borrow [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: [[BORROW_REF_VAL:%[0-9]+]] = begin_borrow [[REF_VAL]] : $RefAggregate
+  // CHECK: {{%.*}} = apply [[SHARED_CALL]]([[TRIVIAL_VAL]], [[BORROW_VALUE_VAL]], [[BORROW_REF_VAL]]) : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()
+  // CHECK: end_borrow [[BORROW_REF_VAL]] from [[REF_VAL]] : $RefAggregate, $RefAggregate
+  // CHECK: end_borrow [[BORROW_VALUE_VAL]] from [[VALUE_VAL]] : $ValueAggregate, $ValueAggregate
+  // CHECK: destroy_value [[REF_VAL]] : $RefAggregate
+  // CHECK: destroy_value [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: } // end sil function '_T06shared0A17_argument_captureySih7trivial_AA14ValueAggregateVh5valueAA03RefF0Ch3reftFyycfU_'
+  
+  // ======== SECOND CLOSURE ==========
+  
+  // CHECK-LABEL:  sil private @_T06shared0A17_argument_captureySih7trivial_AA14ValueAggregateVh5valueAA03RefF0Ch3reftFyycfU0_ : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> () {
+  // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @owned $ValueAggregate, [[REF_VAL:%[0-9]+]] : @owned $RefAggregate):
+  // CHECK: [[OWNED_CALL:%[0-9]+]] = function_ref @_T06shared15owned_argumentsySi7trivial_AA14ValueAggregateV5valueAA03RefF0C3reftF : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  // CHECK: [[BORROW_VALUE_VAL:%[0-9]+]] = begin_borrow [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: [[COPY_BORROW_VALUE_VAL:%[0-9]+]] = copy_value [[BORROW_VALUE_VAL]] : $ValueAggregate
+  // CHECK: [[BORROW_REF_VAL:%[0-9]+]] = begin_borrow [[REF_VAL]] : $RefAggregate
+  // CHECK: [[COPY_BORROW_REF_VAL:%[0-9]+]] = copy_value [[BORROW_REF_VAL]] : $RefAggregate
+  // CHECK: {{%.*}} = apply [[OWNED_CALL]]([[TRIVIAL_VAL]], [[COPY_BORROW_VALUE_VAL]], [[COPY_BORROW_REF_VAL]]) : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  // CHECK: end_borrow [[BORROW_REF_VAL]] from [[REF_VAL]] : $RefAggregate, $RefAggregate
+  // CHECK: end_borrow [[BORROW_VALUE_VAL]] from [[VALUE_VAL]] : $ValueAggregate, $ValueAggregate
+  // CHECK: destroy_value [[REF_VAL]] : $RefAggregate
+  // CHECK: destroy_value [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: } // end sil function '_T06shared0A17_argument_captureySih7trivial_AA14ValueAggregateVh5valueAA03RefF0Ch3reftFyycfU0_'
+}
+
+// CHECK-LABEL: sil hidden @_T06shared0A20_to_owned_conversionyySih_AA14ValueAggregateVhAA03RefF0ChtcF : $@convention(thin) (@owned @callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()) -> ()
+func shared_to_owned_conversion(_ f : (__shared Int, __shared ValueAggregate, __shared RefAggregate) -> Void) {
+  // CHECK: bb0([[UNUSED_FUNC:%[0-9]+]] : @owned $@callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()):
+  // CHECK: [[RECUR_FN:%[0-9]+]] = function_ref @_T06shared0A20_to_owned_conversionyySih_AA14ValueAggregateVhAA03RefF0ChtcF : $@convention(thin) (@owned @callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()) -> ()
+  // CHECK: [[OWNED_THUNK:%[0-9]+]] = function_ref @_T06shared0A20_to_owned_conversionyySih_AA14ValueAggregateVhAA03RefF0ChtcFySi_AdFtcfU_ : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  // CHECK: [[THICK_OWNED_THUNK:%[0-9]+]] = thin_to_thick_function [[OWNED_THUNK]] : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate) -> () to $@callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  // CHECK: [[GUARANTEED_TO_OWNED_THUNK:%[0-9]+]] =  function_ref @_T0Si6shared14ValueAggregateVAA03RefC0CIxyxx_SiAcEIxygg_TR : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate, @owned @callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()) -> ()
+  // CHECK: [[APPLIED_THUNK:%[0-9]+]] = partial_apply [[GUARANTEED_TO_OWNED_THUNK]]([[THICK_OWNED_THUNK]]) : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate, @owned @callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()) -> ()
+  // CHECK: {{%.*}} = apply [[RECUR_FN]]([[APPLIED_THUNK]]) : $@convention(thin) (@owned @callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()) -> ()
+  // CHECK: destroy_value [[UNUSED_FUNC]] : $@callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> () // id: %8
+  // CHECK: } // end sil function '_T06shared0A20_to_owned_conversionyySih_AA14ValueAggregateVhAA03RefF0ChtcF'
+  
+  // ======== REABSTRACTION THUNK =========
+  
+  // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @_T0Si6shared14ValueAggregateVAA03RefC0CIxyxx_SiAcEIxygg_TR : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate, @owned @callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()) -> ()
+  // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @guaranteed $ValueAggregate, [[REF_VAL:%[0-9]+]] : @guaranteed $RefAggregate, [[OWNED_FUNC:%[0-9]+]] : @owned $@callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()):
+  // CHECK: [[COPY_VALUE_VAL:%[0-9]+]] = copy_value [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: [[COPY_REF_VAL:%[0-9]+]] = copy_value [[REF_VAL]] : $RefAggregate
+  // CHECK: {{%.*}} = apply %3([[TRIVIAL_VAL]], [[COPY_VALUE_VAL]], [[COPY_REF_VAL]]) : $@callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  // CHECK: } // end sil function '_T0Si6shared14ValueAggregateVAA03RefC0CIxyxx_SiAcEIxygg_TR'
+  
+  return shared_to_owned_conversion { (trivial : Int, val : ValueAggregate, ref : RefAggregate) in }
+}
+
+// CHECK-LABEL: sil hidden @_T06shared09owned_to_A11_conversionyySi_AA14ValueAggregateVAA03RefF0CtcF : $@convention(thin) (@owned @callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()) -> ()
+func owned_to_shared_conversion(_ f : (Int, ValueAggregate, RefAggregate) -> Void) {
+  // CHECK: bb0([[UNUSED_FUNC:%[0-9]+]] : @owned $@callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()):
+  // CHECK: [[RECUR_FN:%[0-9]+]] = function_ref @_T06shared09owned_to_A11_conversionyySi_AA14ValueAggregateVAA03RefF0CtcF : $@convention(thin) (@owned @callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()) -> ()
+  // CHECK: [[SHARED_THUNK:%[0-9]+]] = function_ref @_T06shared09owned_to_A11_conversionyySi_AA14ValueAggregateVAA03RefF0CtcFySih_ADhAFhtcfU_ : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()
+  // CHECK: [[THICK_SHARED_THUNK:%[0-9]+]] = thin_to_thick_function %3 : $@convention(thin) (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> () to $@callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()
+  // CHECK: [[OWNED_TO_GUARANTEED_THUNK:%[0-9]+]] = function_ref @_T0Si6shared14ValueAggregateVAA03RefC0CIxygg_SiAcEIxyxx_TR : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate, @owned @callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()) -> ()
+  // CHECK: [[APPLIED_THUNK:%[0-9]+]] = partial_apply [[OWNED_TO_GUARANTEED_THUNK]]([[THICK_SHARED_THUNK]]) : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate, @owned @callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()) -> ()
+  // CHECK: {{%.*}} = apply [[RECUR_FN]]([[APPLIED_THUNK]]) : $@convention(thin) (@owned @callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()) -> ()
+  // CHECK: destroy_value [[UNUSED_FUNC]] : $@callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()
+  // CHECK: } // end sil function '_T06shared09owned_to_A11_conversionyySi_AA14ValueAggregateVAA03RefF0CtcF'
+
+  // ======== REABSTRACTION THUNK =========
+
+  // CHECK-LABEL: sil shared [transparent] [serializable] [reabstraction_thunk] @_T0Si6shared14ValueAggregateVAA03RefC0CIxygg_SiAcEIxyxx_TR : $@convention(thin) (Int, @owned ValueAggregate, @owned RefAggregate, @owned @callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()) -> ()
+  // CHECK: bb0([[TRIVIAL_VAL:%[0-9]+]] : @trivial $Int, [[VALUE_VAL:%[0-9]+]] : @owned $ValueAggregate, [[REF_VAL:%[0-9]+]] : @owned $RefAggregate, [[OWNED_FUNC:%[0-9]+]] : @owned $@callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()):
+  // CHECK: [[BORROW_VALUE_VAL:%[0-9]+]] = begin_borrow [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: [[BORROW_REF_VAL:%[0-9]+]] = begin_borrow [[REF_VAL]] : $RefAggregate
+  // CHECK: {{%.*}} = apply %3([[TRIVIAL_VAL]], [[BORROW_VALUE_VAL]], [[BORROW_REF_VAL]]) : $@callee_owned (Int, @guaranteed ValueAggregate, @guaranteed RefAggregate) -> ()
+  // CHECK: end_borrow [[BORROW_REF_VAL]] from [[REF_VAL]] : $RefAggregate, $RefAggregate
+  // CHECK: end_borrow [[BORROW_VALUE_VAL]] from [[VALUE_VAL]] : $ValueAggregate, $ValueAggregate
+  // CHECK: destroy_value [[REF_VAL]] : $RefAggregate
+  // CHECK: destroy_value [[VALUE_VAL]] : $ValueAggregate
+  // CHECK: } // end sil function '_T0Si6shared14ValueAggregateVAA03RefC0CIxygg_SiAcEIxyxx_TR'
+  
+  return owned_to_shared_conversion { (trivial : __shared Int, val : __shared ValueAggregate, ref : __shared RefAggregate) in }
+}
+
+// TODO: Investigate a different lowering scheme than @owned.  Perhaps '@guaranteed $@callee_guaranteed'?
+
+// CHECK-LABEL: sil hidden @_T06shared0A17_closure_loweringyySi_AA14ValueAggregateVAA03RefE0CtcF : $@convention(thin) (@owned @callee_owned (Int, @owned ValueAggregate, @owned RefAggregate) -> ()) -> ()
+func shared_closure_lowering(_ f : __shared (Int, ValueAggregate, RefAggregate) -> Void) {}
diff --git a/test/SILOptimizer/opened_archetype_operands_tracking.sil b/test/SILOptimizer/opened_archetype_operands_tracking.sil
index 1f0745e..8719fc0 100644
--- a/test/SILOptimizer/opened_archetype_operands_tracking.sil
+++ b/test/SILOptimizer/opened_archetype_operands_tracking.sil
@@ -229,3 +229,36 @@
   return %6 : $()
 } // end sil function 'bar'
 
+// A helper function that does not use its arguments at all
+sil @dont_use_arguments: $@convention(thin) (Int32) -> () {
+bb0(%0 : $Int32):
+  %1 = tuple ()
+  return %1 : $()
+}
+
+// Check that dont_use_arguments is inlined into check_removal_of_unregistered_archetype_def
+// and this does not lead to an "Opened archetype definition is not registered in
+// SILFunction" assertion failure, that used to happen because the apply instruction
+// was not aware of the opened archetype definition that becomes unused and gets removed
+// after the inlining.
+//
+// CHECK-LABEL: sil @check_removal_of_unregistered_archetype_def
+// CHECK-NOT: init_existential
+// CHECK-NOT: open_existential
+// CHECK-NOT: function_ref
+// CHECK-NOT: apply
+// CHECK: strong_release
+// CHECK: end sil function 'check_removal_of_unregistered_archetype_def'
+sil @check_removal_of_unregistered_archetype_def : $@convention(thin) (AnyObject) -> () {
+bb0(%0 : $AnyObject):
+  %1 = open_existential_ref %0 : $AnyObject to $@opened("2CAE06CE-5F10-11E4-AF13-C82A1428F987") AnyObject
+  %2 = integer_literal $Builtin.Int32, 1
+  %3 = struct $Int32(%2 : $Builtin.Int32)
+  %4 = mark_dependence %3 : $Int32 on %1 : $@opened("2CAE06CE-5F10-11E4-AF13-C82A1428F987") AnyObject
+  %5 = function_ref @dont_use_arguments : $@convention(thin) (Int32) -> ()
+  %6 = apply %5(%4) : $@convention(thin) (Int32) -> ()
+  strong_release %0 : $AnyObject
+  %8 = tuple ()
+  return %8 : $()
+} // end sil function 'check_removal_of_unregistered_archetype_def'
+
diff --git a/test/SILOptimizer/pointer_conversion.swift b/test/SILOptimizer/pointer_conversion.swift
index aea4833..c408fb4 100644
--- a/test/SILOptimizer/pointer_conversion.swift
+++ b/test/SILOptimizer/pointer_conversion.swift
@@ -1,4 +1,5 @@
 // RUN: %target-swift-frontend -emit-sil -O %s | %FileCheck %s
+// REQUIRES: optimized_stdlib
 
 // Opaque, unoptimizable functions to call.
 @_silgen_name("takesConstRawPointer")
diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil
index 47f424d..38343bc 100644
--- a/test/SILOptimizer/sil_combine.sil
+++ b/test/SILOptimizer/sil_combine.sil
@@ -2878,8 +2878,8 @@
 // CHECK-NEXT: [[TMP:%.*]] = alloc_stack $T
 // CHECK: [[FN:%.*]] = function_ref @generic_callee
 // CHECK-NEXT: copy_addr [[ARG1]] to [initialization] [[TMP]] : $*T
-// CHECK-NEXT: apply [[FN]]<T, T>([[ARG0]], [[TMP]])
 // CHECK-NEXT: destroy_addr [[ARG1]]
+// CHECK-NEXT: apply [[FN]]<T, T>([[ARG0]], [[TMP]])
 // CHECK-NEXT: destroy_addr [[TMP]]
 // CHECK-NEXT: tuple
 // CHECK-NEXT: dealloc_stack [[TMP]]
diff --git a/test/SILOptimizer/sil_combine_apply.sil b/test/SILOptimizer/sil_combine_apply.sil
index c8d3551..2bf1e6f 100644
--- a/test/SILOptimizer/sil_combine_apply.sil
+++ b/test/SILOptimizer/sil_combine_apply.sil
@@ -7,6 +7,13 @@
 //////////////////
 
 sil @unknown : $@convention(thin) () -> ()
+sil @generic_callee : $@convention(thin) <T, U> (@in T, @in U) -> ()
+
+protocol Error {}
+
+protocol SwiftP {
+  func foo()
+}
 
 /////////////////////////////////
 // Tests for SILCombinerApply. //
@@ -36,21 +43,30 @@
 // CHECK-LABEL: sil @sil_combine_dead_partial_apply : $@convention(thin) (@in S2, @in S4, @inout S5, S6, @owned S7, @guaranteed S8) -> () {
 // CHECK: bb0([[IN_ARG:%.*]] : $*S2, [[INGUARANTEED_ARG:%.*]] : $*S4, [[INOUT_ARG:%.*]] : $*S5, [[UNOWNED_ARG:%.*]] : $S6, [[OWNED_ARG:%.*]] : $S7, [[GUARANTEED_ARG:%.*]] : $S8):
 //
+// CHECK: [[IN_ADDRESS_1:%.*]] = alloc_stack $S1
+// CHECK: [[IN_ARG_1:%.*]] = alloc_stack $S2
+// CHECK: [[INGUARANTEED_ADDRESS_1:%.*]] = alloc_stack $S3
+// CHECK: [[INGUARANTEED_ARG_1:%.*]] = alloc_stack $S4
+//
 // CHECK: function_ref unknown
 // CHECK: [[UNKNOWN_FUNC:%.*]] = function_ref @unknown
 // CHECK-NEXT: [[IN_ADDRESS:%.*]] = alloc_stack $S1
 // CHECK-NEXT: [[INGUARANTEED_ADDRESS:%.*]] = alloc_stack $S3
 //
 // CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK: copy_addr [take] [[INGUARANTEED_ARG]] to [initialization] [[INGUARANTEED_ARG_1]]
+// CHECK: copy_addr [take] [[INGUARANTEED_ADDRESS]] to [initialization] [[INGUARANTEED_ADDRESS_1]]
+// CHECK: copy_addr [take] [[IN_ARG]] to [initialization] [[IN_ARG_1]]
+// CHECK: copy_addr [take] [[IN_ADDRESS]] to [initialization] [[IN_ADDRESS_1]]
 //
 // Then make sure that the destroys are placed after the destroy_value of the
 // partial_apply (which is after this apply)...
 // CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
 //
-// CHECK-NEXT: destroy_addr [[IN_ADDRESS]]
-// CHECK-NEXT: destroy_addr [[IN_ARG]]
-// CHECK-NEXT: destroy_addr [[INGUARANTEED_ADDRESS]]
-// CHECK-NEXT: destroy_addr [[INGUARANTEED_ARG]]
+// CHECK-NEXT: destroy_addr [[IN_ADDRESS_1]]
+// CHECK-NEXT: destroy_addr [[IN_ARG_1]]
+// CHECK-NEXT: destroy_addr [[INGUARANTEED_ADDRESS_1]]
+// CHECK-NEXT: destroy_addr [[INGUARANTEED_ARG_1]]
 // CHECK-NEXT: release_value [[UNOWNED_ARG]]
 // CHECK-NEXT: release_value [[OWNED_ARG]]
 // CHECK-NEXT: release_value [[GUARANTEED_ARG]]
@@ -60,6 +76,10 @@
 // CHECK-NEXT: dealloc_stack [[INGUARANTEED_ADDRESS]]
 // CHECK-NEXT: dealloc_stack [[IN_ADDRESS]]
 // CHECK-NEXT: tuple
+// CHECK-NEXT: dealloc_stack [[INGUARANTEED_ARG_1]]
+// CHECK-NEXT: dealloc_stack [[INGUARANTEED_ADDRESS_1]]
+// CHECK-NEXT: dealloc_stack [[IN_ARG_1]]
+// CHECK-NEXT: dealloc_stack [[IN_ADDRESS_1]]
 // CHECK-NEXT: return
 // CHECK-NEXT: } // end sil function 'sil_combine_dead_partial_apply'
 sil @sil_combine_dead_partial_apply : $@convention(thin) (@in S2, @in S4, @inout S5, S6, @owned S7, @guaranteed S8) -> () {
@@ -96,3 +116,196 @@
   %9999 = tuple()
   return %9999 : $()
 }
+
+sil @sil_combine_partial_apply_callee_2 : $@convention(thin) (@in S1) -> ()
+
+// CHECK-LABEL: sil @sil_combine_dead_partial_apply_non_overlapping_lifetime : $@convention(thin) () -> () {
+// CHECK: bb0:
+// CHECK:   [[NEW_ALLOC_STACK:%.*]] = alloc_stack $S1
+// CHECK-NEXT: function_ref unknown
+// CHECK-NEXT: [[UNKNOWN_FUNC:%.*]] = function_ref @unknown : $@convention(thin) () -> ()
+// CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK-NEXT: br bb1
+//
+// CHECK: bb1:
+// CHECK:   [[ORIGINAL_ALLOC_STACK:%.*]] = alloc_stack $S1
+// CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK-NEXT: copy_addr [take] [[ORIGINAL_ALLOC_STACK]] to [initialization] [[NEW_ALLOC_STACK]]
+// CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK-NEXT: dealloc_stack [[ORIGINAL_ALLOC_STACK]]
+// CHECK-NEXT: apply
+// CHECK-NEXT: cond_br undef, bb2, bb3
+//
+// CHECK: bb2:
+// CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK-NEXT: destroy_addr [[NEW_ALLOC_STACK]]
+// CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK-NEXT:   br bb4
+//
+// CHECK: bb3:
+// CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK-NEXT:   destroy_addr [[NEW_ALLOC_STACK]]
+// CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK-NEXT:   br bb4
+//
+// CHECK: bb4:
+// CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK-NEXT: tuple
+// CHECK-NEXT: apply [[UNKNOWN_FUNC]]()
+// CHECK-NEXT: dealloc_stack [[NEW_ALLOC_STACK]]
+// CHECK: } // end sil function 'sil_combine_dead_partial_apply_non_overlapping_lifetime'
+sil @sil_combine_dead_partial_apply_non_overlapping_lifetime : $@convention(thin) () -> () {
+bb0:
+  %3 = function_ref @unknown : $@convention(thin) () -> ()
+  apply %3() : $@convention(thin) () -> ()
+  br bb1
+
+bb1:
+  %0 = alloc_stack $S1
+  apply %3() : $@convention(thin) () -> ()
+  %1 = function_ref @sil_combine_partial_apply_callee_2 : $@convention(thin) (@in S1) -> ()
+  apply %3() : $@convention(thin) () -> ()
+  %2 = partial_apply %1(%0) : $@convention(thin) (@in S1) -> ()
+  apply %3() : $@convention(thin) () -> ()
+  dealloc_stack %0 : $*S1
+  apply %3() : $@convention(thin) () -> ()
+  cond_br undef, bb2, bb3
+
+bb2:
+  apply %3() : $@convention(thin) () -> ()
+  strong_release %2 : $@callee_owned () -> ()
+  apply %3() : $@convention(thin) () -> ()
+  br bb4
+
+bb3:
+  apply %3() : $@convention(thin) () -> ()
+  strong_release %2 : $@callee_owned () -> ()
+  apply %3() : $@convention(thin) () -> ()
+  br bb4
+
+bb4:
+  apply %3() : $@convention(thin) () -> ()
+  %9999 = tuple()
+  apply %3() : $@convention(thin) () -> ()
+  return %9999 : $()
+}
+
+sil @try_apply_func : $@convention(thin) () -> (Builtin.Int32, @error Error)
+
+// CHECK-LABEL: sil @sil_combine_dead_partial_apply_try_apply : $@convention(thin) () -> ((), @error Error) {
+// CHECK: bb0:
+// CHECK:   [[NEW_ALLOC_STACK:%.*]] = alloc_stack $S1
+// CHECK-NEXT: br bb1
+// CHECK: bb5(
+// CHECK-NEXT: tuple
+// CHECK-NEXT: dealloc_stack [[NEW_ALLOC_STACK]]
+// CHECK-NEXT: return
+// CHECK: bb6(
+// CHECK-NEXT: dealloc_stack [[NEW_ALLOC_STACK]]
+// CHECK-NEXT: throw
+// CHECK: } // end sil function 'sil_combine_dead_partial_apply_try_apply'
+sil @sil_combine_dead_partial_apply_try_apply : $@convention(thin) () -> ((), @error Error) {
+bb0:
+  br bb1
+
+bb1:
+  %0 = alloc_stack $S1
+  %1 = function_ref @sil_combine_partial_apply_callee_2 : $@convention(thin) (@in S1) -> ()
+  %2 = partial_apply %1(%0) : $@convention(thin) (@in S1) -> ()
+  dealloc_stack %0 : $*S1
+  cond_br undef, bb2, bb3
+
+bb2:
+  strong_release %2 : $@callee_owned () -> ()
+  %99991 = tuple()
+  br bb4
+
+bb3:
+  strong_release %2 : $@callee_owned () -> ()
+  %99992 = tuple()
+  br bb4
+
+bb4:
+  %3 = function_ref @try_apply_func : $@convention(thin) () -> (Builtin.Int32, @error Error)
+  try_apply %3() : $@convention(thin) () -> (Builtin.Int32, @error Error), normal bb5, error bb6
+
+bb5(%4 : $Builtin.Int32):
+  %9999 = tuple()
+  return %9999 : $()
+
+bb6(%5 : $Error):
+  %6 = builtin "willThrow"(%5 : $Error) : $()
+  throw %5 : $Error
+}
+
+// Make sure that we do not optimize this case. If we do optimize this case,
+// given the current algorithm which puts alloc_stack at the beginning/end of
+// the function, we will have a fatal error.
+sil @sil_combine_dead_partial_apply_with_opened_existential : $@convention(thin) () -> ((), @error Error) {
+bb0:
+  %0b = alloc_stack $SwiftP
+  %1 = open_existential_addr mutable_access %0b : $*SwiftP to $*@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP
+  %2 = witness_method $@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP, #SwiftP.foo!1, %1 : $*@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP : $@convention(witness_method) <τ_0_0 where τ_0_0 : SwiftP> (@in_guaranteed τ_0_0) -> ()
+  %0c = alloc_stack $@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP
+  %3 = partial_apply %2<@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP>(%0c) : $@convention(witness_method) <τ_0_0 where τ_0_0 : SwiftP> (@in_guaranteed τ_0_0) -> ()
+  dealloc_stack %0c : $*@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP
+  strong_release %3 : $@callee_owned () -> ()
+  dealloc_stack %0b : $*SwiftP
+  %9999 = tuple()
+  return %9999 : $()
+}
+
+// This is a version of a test in sil_combine.sil that tests ignoring the
+// trivial alloc stack elimination optimization. Said optimization can make
+// testing ownership more difficult since the optimization does not care about
+// ownership correctness (i.e. it can hide leaks).
+//
+// This test first transforms (apply (partial_apply)) -> apply and then lets the
+// dead partial apply code eliminate the partial apply.
+//
+// CHECK-LABEL: sil @test_generic_partial_apply_apply
+// CHECK: bb0([[ARG0:%.*]] : $*T, [[ARG1:%.*]] : $*T):
+// CHECK-NEXT: [[PA_TMP:%.*]] = alloc_stack $T
+// CHECK-NEXT: [[APPLY_TMP:%.*]] = alloc_stack $T
+// CHECK: [[FN:%.*]] = function_ref @generic_callee
+// CHECK-NEXT: copy_addr [[ARG1]] to [initialization] [[APPLY_TMP]]
+// CHECK-NEXT: copy_addr [take] [[ARG1]] to [initialization] [[PA_TMP]]
+// CHECK-NEXT: apply [[FN]]<T, T>([[ARG0]], [[APPLY_TMP]])
+// CHECK-NEXT: destroy_addr [[PA_TMP]]
+// CHECK-NEXT: destroy_addr [[APPLY_TMP]]
+// CHECK-NEXT: tuple
+// CHECK-NEXT: dealloc_stack [[APPLY_TMP]]
+// CHECK-NEXT: dealloc_stack [[PA_TMP]]
+// CHECK-NEXT: return
+sil @test_generic_partial_apply_apply : $@convention(thin) <T> (@in T, @in T) -> () {
+bb0(%0 : $*T, %1 : $*T):
+  %f1 = function_ref @generic_callee : $@convention(thin) <T, U> (@in T, @in U) -> ()
+  %pa = partial_apply %f1<T, T>(%1) : $@convention(thin) <T, U> (@in T, @in U) -> ()
+  %a1 = apply %pa(%0) : $@callee_owned (@in T) -> ()
+  %r = tuple ()
+  return %r : $()
+}
+
+// Today when we optimize (apply (partial_apply)) -> apply, we can not handle
+// dependent types since the algorithm attempts to create an alloc_stack at the
+// beginning/end of the function. In such a case, the dependent type may not be
+// alive at that point, so the compiler will crash. This test ensures that we do
+// not optimize this case.
+//
+// CHECK-LABEL: sil @sil_combine_applied_partialapply_to_apply_with_dependent_type : $@convention(thin) (@in SwiftP) -> () {
+// CHECK: [[PAI:%.*]] = partial_apply
+// CHECK: apply [[PAI]]
+sil @sil_combine_applied_partialapply_to_apply_with_dependent_type : $@convention(thin) (@in SwiftP) -> () {
+bb0(%0 : $*SwiftP):
+  %0b = alloc_stack $SwiftP
+  %1 = open_existential_addr mutable_access %0b : $*SwiftP to $*@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP
+  %2 = witness_method $@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP, #SwiftP.foo!1, %1 : $*@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP : $@convention(witness_method) <τ_0_0 where τ_0_0 : SwiftP> (@in_guaranteed τ_0_0) -> ()
+  %0c = alloc_stack $@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP
+  %3 = partial_apply %2<@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP>(%0c) : $@convention(witness_method) <τ_0_0 where τ_0_0 : SwiftP> (@in_guaranteed τ_0_0) -> ()
+  dealloc_stack %0c : $*@opened("3305E696-5685-11E5-9393-B8E856428C60") SwiftP
+  dealloc_stack %0b : $*SwiftP
+  %4 = apply %3() : $@callee_owned () -> ()
+  %9999 = tuple()
+  return %9999 : $()
+}
\ No newline at end of file
diff --git a/test/Sema/diag_invalid_synthesized_init_proto_conformance.swift b/test/Sema/diag_invalid_synthesized_init_proto_conformance.swift
index d453edd..1a5dfd0 100644
--- a/test/Sema/diag_invalid_synthesized_init_proto_conformance.swift
+++ b/test/Sema/diag_invalid_synthesized_init_proto_conformance.swift
@@ -8,14 +8,14 @@
 // No further errors
 
 class B : A {
-    init(x : Int) {} // expected-note {{'init(x:)' declared here}}
+    init(x : Int) {}
 }
 
 class C : B { }
 
 class D : B {
   init() {
-    super.init() // expected-error{{missing argument for parameter 'x' in call}}
+    super.init()
   }
 }
 
diff --git a/test/Sema/substring_to_string_conversion_swift4.swift b/test/Sema/substring_to_string_conversion_swift4.swift
index 5254251..0642bde 100644
--- a/test/Sema/substring_to_string_conversion_swift4.swift
+++ b/test/Sema/substring_to_string_conversion_swift4.swift
@@ -86,3 +86,11 @@
   let _: String = s[s.startIndex..<s.endIndex] // expected-error{{subscripts returning String were obsoleted in Swift 4; explicitly construct a String from subscripted result}} {{19-19=String(}} {{47-47=)}}
   _ = s[s.startIndex..<s.endIndex] as String // expected-error{{subscripts returning String were obsoleted in Swift 4; explicitly construct a String from subscripted result}} {{7-7=String(}} {{35-35=)}}
 }
+
+// rdar://33474838
+protocol Derivable {
+  func derive() -> Substring
+}
+func foo<T: Derivable>(t: T) -> String {
+  return t.derive()  // expected-error {{cannot convert return expression of type 'Substring' to return type 'String'}} {{10-10=String(}} {{20-20=)}}
+}
diff --git a/test/SourceKit/DocumentStructure/access_parse.swift.response b/test/SourceKit/DocumentStructure/access_parse.swift.response
index c6dd6e4..f147a1c 100644
--- a/test/SourceKit/DocumentStructure/access_parse.swift.response
+++ b/test/SourceKit/DocumentStructure/access_parse.swift.response
@@ -650,6 +650,42 @@
           key.bodylength: 0
         }
       ]
+    },
+    {
+      key.kind: source.lang.swift.decl.typealias,
+      key.accessibility: source.lang.swift.accessibility.internal,
+      key.name: "defAlias",
+      key.offset: 1633,
+      key.length: 24,
+      key.nameoffset: 1643,
+      key.namelength: 8
+    },
+    {
+      key.kind: source.lang.swift.decl.typealias,
+      key.accessibility: source.lang.swift.accessibility.public,
+      key.name: "pubAlias",
+      key.offset: 1665,
+      key.length: 24,
+      key.nameoffset: 1675,
+      key.namelength: 8
+    },
+    {
+      key.kind: source.lang.swift.decl.typealias,
+      key.accessibility: source.lang.swift.accessibility.private,
+      key.name: "privAlias",
+      key.offset: 1698,
+      key.length: 25,
+      key.nameoffset: 1708,
+      key.namelength: 9
+    },
+    {
+      key.kind: source.lang.swift.decl.typealias,
+      key.accessibility: source.lang.swift.accessibility.internal,
+      key.name: "intAlias",
+      key.offset: 1733,
+      key.length: 24,
+      key.nameoffset: 1743,
+      key.namelength: 8
     }
   ]
 }
diff --git a/test/SourceKit/InterfaceGen/gen_clang_module.swift.response b/test/SourceKit/InterfaceGen/gen_clang_module.swift.response
index a9b465f..bddccba 100644
--- a/test/SourceKit/InterfaceGen/gen_clang_module.swift.response
+++ b/test/SourceKit/InterfaceGen/gen_clang_module.swift.response
@@ -4633,6 +4633,15 @@
     ]
   },
   {
+    key.kind: source.lang.swift.decl.typealias,
+    key.accessibility: source.lang.swift.accessibility.public,
+    key.name: "FooStruct1Pointer",
+    key.offset: 1543,
+    key.length: 62,
+    key.nameoffset: 1553,
+    key.namelength: 17
+  },
+  {
     key.kind: source.lang.swift.decl.struct,
     key.accessibility: source.lang.swift.accessibility.public,
     key.name: "FooStruct2",
@@ -4706,6 +4715,15 @@
     ]
   },
   {
+    key.kind: source.lang.swift.decl.typealias,
+    key.accessibility: source.lang.swift.accessibility.public,
+    key.name: "FooStructTypedef1",
+    key.offset: 1751,
+    key.length: 40,
+    key.nameoffset: 1761,
+    key.namelength: 17
+  },
+  {
     key.kind: source.lang.swift.decl.struct,
     key.accessibility: source.lang.swift.accessibility.public,
     key.name: "FooStructTypedef2",
@@ -4779,6 +4797,15 @@
     ]
   },
   {
+    key.kind: source.lang.swift.decl.typealias,
+    key.accessibility: source.lang.swift.accessibility.public,
+    key.name: "FooTypedef1",
+    key.offset: 1974,
+    key.length: 29,
+    key.nameoffset: 1984,
+    key.namelength: 11
+  },
+  {
     key.kind: source.lang.swift.decl.var.global,
     key.accessibility: source.lang.swift.accessibility.public,
     key.setter_accessibility: source.lang.swift.accessibility.public,
@@ -5349,6 +5376,15 @@
     ]
   },
   {
+    key.kind: source.lang.swift.decl.typealias,
+    key.accessibility: source.lang.swift.accessibility.public,
+    key.name: "typedef_int_t",
+    key.offset: 4624,
+    key.length: 31,
+    key.nameoffset: 4634,
+    key.namelength: 13
+  },
+  {
     key.kind: source.lang.swift.decl.var.global,
     key.accessibility: source.lang.swift.accessibility.public,
     key.setter_accessibility: source.lang.swift.accessibility.public,
diff --git a/test/decl/protocol/recursive_requirement.swift b/test/decl/protocol/recursive_requirement.swift
index 53f0da5..736d2af 100644
--- a/test/decl/protocol/recursive_requirement.swift
+++ b/test/decl/protocol/recursive_requirement.swift
@@ -3,7 +3,7 @@
 // -----
 
 protocol Foo {
-  associatedtype Bar : Foo // expected-error{{type may not reference itself as a requirement}}
+  associatedtype Bar : Foo
 }
 
 struct Oroborous : Foo {
@@ -13,7 +13,7 @@
 // -----
 
 protocol P {
- associatedtype A : P // expected-error{{type may not reference itself as a requirement}}
+ associatedtype A : P
 }
 
 struct X<T: P> {
@@ -26,7 +26,7 @@
 // -----
 
 protocol PP2 {
-  associatedtype A : P2 = Self // expected-error{{type may not reference itself as a requirement}}
+  associatedtype A : P2 = Self
 }
 
 protocol P2 : PP2 {
@@ -41,13 +41,13 @@
 }
 
 func f<T : P2>(_ z: T) {
- _ = X2<T.A>() // expected-error{{type 'T.A' does not conform to protocol 'P2'}}
+ _ = X2<T.A>()
 }
 
 // -----
 
 protocol P3 {
- associatedtype A: P4 = Self // expected-error{{type may not reference itself as a requirement}}
+ associatedtype A: P4 = Self
 }
 
 protocol P4 : P3 {}
diff --git a/test/decl/protocol/recursive_requirement_ok.swift b/test/decl/protocol/recursive_requirement_ok.swift
index 03bd7dd..cb07937 100644
--- a/test/decl/protocol/recursive_requirement_ok.swift
+++ b/test/decl/protocol/recursive_requirement_ok.swift
@@ -1,4 +1,6 @@
-// RUN: %target-typecheck-verify-swift -enable-recursive-constraints
+// RUN: %target-typecheck-verify-swift
+// RUN: %target-typecheck-verify-swift -typecheck -debug-generic-signatures %s > %t.dump 2>&1
+// RUN: %FileCheck %s < %t.dump
 
 protocol P {
   associatedtype Assoc : P
@@ -17,7 +19,22 @@
 protocol P1 {
   associatedtype X : P2
 }
+
+// CHECK: P2
+// CHECK: Requirement signature: <Self where Self == Self.Y.X, Self.Y : P1, Self.Z : P1>
 protocol P2 {
-  associatedtype Y : P1 where Y.X == Self // expected-note{{conformance constraint 'Self.Z': 'P1' implied here}}
-  associatedtype Z : P1 // expected-warning{{redundant conformance constraint 'Self.Z': 'P1'}}
+  associatedtype Y : P1 where Y.X == Self
+  associatedtype Z : P1
+}
+
+// SR-5473
+protocol P3 {
+	associatedtype X : P4
+}
+
+// CHECK: .P4@
+// CHECK: Requirement signature: <Self where Self == Self.Y.X, Self.Y : P3, Self.Z : P3, Self.Y.X == Self.Z.X>
+protocol P4 {
+	associatedtype Y: P3 where Y.X == Self
+	associatedtype Z: P3 where Z.X == Self
 }
diff --git a/test/decl/protocol/req/recursion.swift b/test/decl/protocol/req/recursion.swift
index cc4bc07..4c8bd90 100644
--- a/test/decl/protocol/req/recursion.swift
+++ b/test/decl/protocol/req/recursion.swift
@@ -48,7 +48,7 @@
 // expected-error@-2 {{generic struct 'S' references itself}}
   func f(a: A.T) {
     g(a: id(t: a))
-    // expected-error@-1 {{cannot convert value of type 'A.T' to expected argument type 'S<_>'}}
+    // expected-error@-1 {{generic parameter 'T' could not be inferred}}
     _ = A.T.self
   }
 
diff --git a/test/stdlib/AVFoundation.swift b/test/stdlib/AVFoundation.swift
deleted file mode 100644
index ff429e3..0000000
--- a/test/stdlib/AVFoundation.swift
+++ /dev/null
@@ -1,60 +0,0 @@
-// RUN: %target-run-simple-swift
-// REQUIRES: executable_test
-// REQUIRES: objc_interop
-// CoreMedia is not present on watchOS.
-// UNSUPPORTED: OS=watchos
-
-import CoreMedia
-import AVFoundation
-import StdlibUnittest
-import StdlibUnittestFoundationExtras
-
-var coreMedia = TestSuite("CoreMedia")
-
-func equalCMTimeMappings(_ x: CMTimeMapping, _ y: CMTimeMapping) -> Bool {
-  var xx = x, yy = y
-  return memcmp(&xx, &yy, MemoryLayout<CMTimeMapping>.size) == 0
-}
-
-coreMedia.test("NSValue bridging") {
-  let time1 = CMTimeMake(181, 60)
-  expectBridgeToNSValue(time1,
-                        nsValueInitializer: { NSValue(time: $0) },
-                        nsValueGetter: { $0.timeValue },
-                        equal: (==))
-  let time2 = CMTimeMake(242, 60)
-  let timeRange1 = CMTimeRangeFromTimeToTime(time1, time2)
-
-  expectBridgeToNSValue(timeRange1,
-                        nsValueInitializer: { NSValue(timeRange: $0) },
-                        nsValueGetter: { $0.timeRangeValue },
-                        equal: (==))
-
-  let time3 = CMTimeMake(303, 60)
-  let timeRange2 = CMTimeRangeFromTimeToTime(time2, time3)
-  let timeMapping = CMTimeMapping(source: timeRange1, target: timeRange2)
-  expectBridgeToNSValue(timeMapping,
-                        nsValueInitializer: { NSValue(timeMapping: $0) },
-                        nsValueGetter: { $0.timeMappingValue },
-                        equal: equalCMTimeMappings)
-}
-
-
-var AVFoundationTests = TestSuite("AVFoundation")
-
-#if os(iOS)
-
-if #available(iOS 11, *) {
-  AVFoundationTests.test("AVCaptureSynchronizedDataCollection/iteration") {
-    func f(c: AVCaptureSynchronizedDataCollection) {
-      for element in c {
-        var element = element
-        expectType(AVCaptureSynchronizedData.self, &element)
-      }
-    }
-  }
-}
-
-#endif
-
-runAllTests()
diff --git a/test/stdlib/AVFoundation_Swift3.swift b/test/stdlib/AVFoundation_Swift3.swift
new file mode 100644
index 0000000..ed9e896
--- /dev/null
+++ b/test/stdlib/AVFoundation_Swift3.swift
@@ -0,0 +1,116 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-build-swift -swift-version 3 %s -o %t/a.out
+// RUN: %target-run %t/a.out
+// REQUIRES: objc_interop
+// REQUIRES: executable_test
+// CoreMedia is not present on watchOS.
+// UNSUPPORTED: OS=watchos
+
+import CoreMedia
+import AVFoundation
+import StdlibUnittest
+import StdlibUnittestFoundationExtras
+
+var coreMedia = TestSuite("CoreMedia")
+
+func equalCMTimeMappings(_ x: CMTimeMapping, _ y: CMTimeMapping) -> Bool {
+  var xx = x, yy = y
+  return memcmp(&xx, &yy, MemoryLayout<CMTimeMapping>.size) == 0
+}
+
+coreMedia.test("NSValue bridging") {
+  let time1 = CMTimeMake(181, 60)
+  expectBridgeToNSValue(time1,
+                        nsValueInitializer: { NSValue(time: $0) },
+                        nsValueGetter: { $0.timeValue },
+                        equal: (==))
+  let time2 = CMTimeMake(242, 60)
+  let timeRange1 = CMTimeRangeFromTimeToTime(time1, time2)
+
+  expectBridgeToNSValue(timeRange1,
+                        nsValueInitializer: { NSValue(timeRange: $0) },
+                        nsValueGetter: { $0.timeRangeValue },
+                        equal: (==))
+
+  let time3 = CMTimeMake(303, 60)
+  let timeRange2 = CMTimeRangeFromTimeToTime(time2, time3)
+  let timeMapping = CMTimeMapping(source: timeRange1, target: timeRange2)
+  expectBridgeToNSValue(timeMapping,
+                        nsValueInitializer: { NSValue(timeMapping: $0) },
+                        nsValueGetter: { $0.timeMappingValue },
+                        equal: equalCMTimeMappings)
+}
+
+
+var AVFoundationTests = TestSuite("AVFoundation_Swift3")
+
+let boxedPixelFormat = NSNumber(value: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)
+
+#if os(macOS) || os(iOS)
+
+if #available(iOS 5, *) {
+  AVFoundationTests.test("AVCaptureVideoDataOutput.availableVideoCVPixelFormatTypes") {
+    func f(v: AVCaptureVideoDataOutput) -> Bool {
+      return v.availableVideoCVPixelFormatTypes.contains(boxedPixelFormat)
+    }
+  }
+}
+
+#endif
+
+#if os(iOS)
+
+if #available(iOS 7, *) {
+  AVFoundationTests.test("AVMetadataMachineReadableCodeObject.corners") {
+    func f(m: AVMetadataMachineReadableCodeObject) -> [Any]! {
+      return m.corners
+    }
+  }
+}
+
+if #available(iOS 10, *) {
+  AVFoundationTests.test("AVCaptureDeviceFormat.supportedColorSpaces") {
+    func f(df: AVCaptureDeviceFormat) -> Bool {
+      return df.supportedColorSpaces.contains(NSNumber(value: AVCaptureColorSpace.sRGB.rawValue))
+    }
+  }
+
+  AVFoundationTests.test("AVCapturePhotoOutput.supportedFlashModes") {
+    func f(p: AVCapturePhotoOutput) -> Bool {
+      return p.supportedFlashModes.contains(NSNumber(value: AVCaptureFlashMode.off.rawValue))
+    }
+  }
+
+  AVFoundationTests.test("AVCapturePhotoOutput.availablePhotoPixelFormatTypes") {
+    func f(p: AVCapturePhotoOutput) -> Bool {
+      return p.availablePhotoPixelFormatTypes.contains(boxedPixelFormat)
+    }
+  }
+
+  AVFoundationTests.test("AVCapturePhotoOutput.availableRawPhotoPixelFormatTypes") {
+    func f(p: AVCapturePhotoOutput) -> Bool {
+      return p.availableRawPhotoPixelFormatTypes.contains(boxedPixelFormat)
+    }
+  }
+
+  AVFoundationTests.test("AVCapturePhotoSettings.availablePreviewPhotoPixelFormatTypes") {
+    func f(p: AVCapturePhotoSettings) -> Bool {
+      return p.availablePreviewPhotoPixelFormatTypes.contains(boxedPixelFormat)
+    }
+  }
+}
+
+if #available(iOS 11, *) {
+  AVFoundationTests.test("AVCaptureSynchronizedDataCollection/iteration") {
+    func f(c: AVCaptureSynchronizedDataCollection) {
+      for element in c {
+        var element = element
+        expectType(AVCaptureSynchronizedData.self, &element)
+      }
+    }
+  }
+}
+
+#endif
+
+runAllTests()
diff --git a/test/stdlib/AVFoundation_Swift4.swift b/test/stdlib/AVFoundation_Swift4.swift
new file mode 100644
index 0000000..dd24e27
--- /dev/null
+++ b/test/stdlib/AVFoundation_Swift4.swift
@@ -0,0 +1,83 @@
+// RUN: rm -rf %t && mkdir %t
+// RUN: %target-build-swift -swift-version 4 %s -o %t/a.out
+// RUN: %target-run %t/a.out
+// REQUIRES: objc_interop
+// REQUIRES: executable_test
+// CoreMedia is not present on watchOS.
+// UNSUPPORTED: OS=watchos
+
+import AVFoundation
+import StdlibUnittest
+
+var AVFoundationTests = TestSuite("AVFoundation_Swift4")
+
+let pixelFormat = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
+
+#if os(macOS) || os(iOS)
+
+if #available(iOS 5, *) {
+  AVFoundationTests.test("AVCaptureVideoDataOutput.availableVideoPixelFormatTypes") {
+    func f(v: AVCaptureVideoDataOutput) -> Bool {
+      return v.availableVideoPixelFormatTypes.contains(pixelFormat)
+    }
+  }
+}
+
+#endif
+
+#if os(iOS)
+
+if #available(iOS 7, *) {
+  AVFoundationTests.test("AVMetadataMachineReadableCodeObject.corners") {
+    func f(m: AVMetadataMachineReadableCodeObject) -> Bool {
+      if let c = m.corners.first {
+        return c.x == 0
+      }
+      return false
+    }
+  }
+}
+
+if #available(iOS 10, *) {
+  AVFoundationTests.test("AVCaptureDevice.Format.supportedColorSpaces") {
+    func f(df: AVCaptureDevice.Format) -> Bool {
+      return df.supportedColorSpaces.contains(.sRGB)
+    }
+  }
+
+  AVFoundationTests.test("AVCapturePhotoOutput.supportedFlashModes") {
+    func f(p: AVCapturePhotoOutput) -> Bool {
+      return p.supportedFlashModes.contains(.off)
+    }
+  }
+
+  AVFoundationTests.test("AVCapturePhotoOutput.availablePhotoPixelFormatTypes") {
+    func f(p: AVCapturePhotoOutput) -> Bool {
+      return p.availablePhotoPixelFormatTypes.contains(pixelFormat)
+    }
+  }
+
+  AVFoundationTests.test("AVCapturePhotoOutput.availableRawPhotoPixelFormatTypes") {
+    func f(p: AVCapturePhotoOutput) -> Bool {
+      return p.availableRawPhotoPixelFormatTypes.contains(pixelFormat)
+    }
+  }
+
+  AVFoundationTests.test("AVCapturePhotoSettings.availablePreviewPhotoPixelFormatTypes") {
+    func f(p: AVCapturePhotoSettings) -> Bool {
+      return p.availablePreviewPhotoPixelFormatTypes.contains(pixelFormat)
+    }
+  }
+}
+
+if #available(iOS 11, *) {
+  AVFoundationTests.test("AVCaptureSynchronizedDataCollection.makeIterator()") {
+    func f(c: AVCaptureSynchronizedDataCollection) {
+      for _ in c {}
+    }
+  }
+}
+
+#endif
+
+runAllTests()
diff --git a/test/stdlib/CodableTests.swift b/test/stdlib/CodableTests.swift
index 30d1fd5..13f3969 100644
--- a/test/stdlib/CodableTests.swift
+++ b/test/stdlib/CodableTests.swift
@@ -108,6 +108,7 @@
 class TestCodable : TestCodableSuper {
     // MARK: - AffineTransform
 #if os(OSX)
+    // FIXME: Comment the tests back in once rdar://problem/33363218 is in the SDK.
     lazy var affineTransformValues: [AffineTransform] = [
         AffineTransform.identity,
         AffineTransform(),
@@ -116,10 +117,10 @@
         AffineTransform(rotationByDegrees: .pi / 2),
 
         AffineTransform(m11: 1.0, m12: 2.5, m21: 66.2, m22: 40.2, tX: -5.5, tY: 3.7),
-        AffineTransform(m11: -55.66, m12: 22.7, m21: 1.5, m22: 0.0, tX: -22, tY: -33),
+        // AffineTransform(m11: -55.66, m12: 22.7, m21: 1.5, m22: 0.0, tX: -22, tY: -33),
         AffineTransform(m11: 4.5, m12: 1.1, m21: 0.025, m22: 0.077, tX: -0.55, tY: 33.2),
-        AffineTransform(m11: 7.0, m12: -2.3, m21: 6.7, m22: 0.25, tX: 0.556, tY: 0.99),
-        AffineTransform(m11: 0.498, m12: -0.284, m21: -0.742, m22: 0.3248, tX: 12, tY: 44)
+        // AffineTransform(m11: 7.0, m12: -2.3, m21: 6.7, m22: 0.25, tX: 0.556, tY: 0.99),
+        // AffineTransform(m11: 0.498, m12: -0.284, m21: -0.742, m22: 0.3248, tX: 12, tY: 44)
     ]
 
     func test_AffineTransform_JSON() {
@@ -198,16 +199,17 @@
 
     // MARK: - CGAffineTransform
     lazy var cg_affineTransformValues: [CGAffineTransform] = {
+        // FIXME: Comment the tests back in once rdar://problem/33363218 is in the SDK.
         var values = [
             CGAffineTransform.identity,
             CGAffineTransform(),
             CGAffineTransform(translationX: 2.0, y: 2.0),
             CGAffineTransform(scaleX: 2.0, y: 2.0),
             CGAffineTransform(a: 1.0, b: 2.5, c: 66.2, d: 40.2, tx: -5.5, ty: 3.7),
-            CGAffineTransform(a: -55.66, b: 22.7, c: 1.5, d: 0.0, tx: -22, ty: -33),
+            // CGAffineTransform(a: -55.66, b: 22.7, c: 1.5, d: 0.0, tx: -22, ty: -33),
             CGAffineTransform(a: 4.5, b: 1.1, c: 0.025, d: 0.077, tx: -0.55, ty: 33.2),
-            CGAffineTransform(a: 7.0, b: -2.3, c: 6.7, d: 0.25, tx: 0.556, ty: 0.99),
-            CGAffineTransform(a: 0.498, b: -0.284, c: -0.742, d: 0.3248, tx: 12, ty: 44)
+            // CGAffineTransform(a: 7.0, b: -2.3, c: 6.7, d: 0.25, tx: 0.556, ty: 0.99),
+            // CGAffineTransform(a: 0.498, b: -0.284, c: -0.742, d: 0.3248, tx: 12, ty: 44)
         ]
 
         if #available(OSX 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
@@ -287,15 +289,16 @@
 
     // MARK: - CGRect
     lazy var cg_rectValues: [CGRect] = {
+        // FIXME: Comment the tests back in once rdar://problem/33363218 is in the SDK.
         var values = [
             CGRect.zero,
-            CGRect.null,
+            // CGRect.null,
             CGRect(x: 10, y: 20, width: 30, height: 40)
         ]
 
         if #available(OSX 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
             // Limit on magnitude in JSON. See rdar://problem/12717407
-            values.append(CGRect.infinite)
+            // values.append(CGRect.infinite)
         }
 
         return values
@@ -315,9 +318,10 @@
 
     // MARK: - CGVector
     lazy var cg_vectorValues: [CGVector] = {
+        // FIXME: Comment the tests back in once rdar://problem/33363218 is in the SDK.
         var values = [
             CGVector.zero,
-            CGVector(dx: 0.0, dy: -9.81)
+            // CGVector(dx: 0.0, dy: -9.81)
         ]
 
         if #available(OSX 10.13, iOS 11.0, watchOS 4.0, tvOS 11.0, *) {
diff --git a/test/stdlib/Inputs/CommonArrayTests.gyb b/test/stdlib/Inputs/CommonArrayTests.gyb
index 39e2dc4..e4c2fce 100644
--- a/test/stdlib/Inputs/CommonArrayTests.gyb
+++ b/test/stdlib/Inputs/CommonArrayTests.gyb
@@ -156,19 +156,17 @@
     let arr: ${ArrayType}<Int> = [ 0, 30, 10, 90 ]
     let result = arr.filter() { (x: Int) -> Bool in true }
     expectEqual([ 0, 30, 10, 90 ], result)
-    expectGE(2 * result.count, result.capacity)
   }
   do {
     let arr: ${ArrayType}<Int> = [ 0, 30, 10, 90 ]
     let result = arr.filter() { (x: Int) -> Bool in false }
     expectEqual([], result)
-    expectGE(2 * result.count, result.capacity)
+    expectEqual(0, result.capacity)
   }
   do {
     let arr: ${ArrayType}<Int> = [ 0, 30, 10, 90 ]
     let result = arr.filter() { $0 % 3 == 0 }
     expectEqual([ 0, 30, 90 ], result)
-    expectGE(2 * result.count, result.capacity)
   }
 }
 
diff --git a/test/stdlib/Integers.swift.gyb b/test/stdlib/Integers.swift.gyb
index b4ed430..c2e6000 100644
--- a/test/stdlib/Integers.swift.gyb
+++ b/test/stdlib/Integers.swift.gyb
@@ -87,7 +87,7 @@
 }
 
 func expectEqual<T : FixedWidthInteger>(
-  _ expected: (T, ArithmeticOverflow), _ actual: (T, ArithmeticOverflow),
+  _ expected: (T, Bool), _ actual: (T, Bool),
   _ message: @autoclosure () -> String = "",
   stackTrace: SourceLocStack = SourceLocStack(),
   showFrame: Bool = true,
@@ -322,46 +322,46 @@
   _ = UWord(tooLarge)
 }
 
-tests.test("extendingOrTruncating") {
+tests.test("truncatingIfNeeded") {
 
-  expectEqual(-2, Int8(extendingOrTruncating: UInt8.max - 1))
-  expectEqual(3, Int8(extendingOrTruncating: 3 as UInt8))
-  expectEqual(UInt8.max - 1, UInt8(extendingOrTruncating: -2 as Int8))
-  expectEqual(3, UInt8(extendingOrTruncating: 3 as Int8))
+  expectEqual(-2, Int8(truncatingIfNeeded: UInt8.max - 1))
+  expectEqual(3, Int8(truncatingIfNeeded: 3 as UInt8))
+  expectEqual(UInt8.max - 1, UInt8(truncatingIfNeeded: -2 as Int8))
+  expectEqual(3, UInt8(truncatingIfNeeded: 3 as Int8))
 
-  expectEqual(-2, DWord(extendingOrTruncating: UDWord.max - 1))
-  expectEqual(3, DWord(extendingOrTruncating: 3 as UDWord))
-  expectEqual(UDWord.max - 1, UDWord(extendingOrTruncating: -2 as DWord))
-  expectEqual(3, UDWord(extendingOrTruncating: 3 as DWord))
+  expectEqual(-2, DWord(truncatingIfNeeded: UDWord.max - 1))
+  expectEqual(3, DWord(truncatingIfNeeded: 3 as UDWord))
+  expectEqual(UDWord.max - 1, UDWord(truncatingIfNeeded: -2 as DWord))
+  expectEqual(3, UDWord(truncatingIfNeeded: 3 as DWord))
 
-  expectEqual(-2, Int32(extendingOrTruncating: -2 as Int8))
-  expectEqual(3, Int32(extendingOrTruncating: 3 as Int8))
-  expectEqual(127, Int32(extendingOrTruncating: 127 as UInt8))
-  expectEqual(129, Int32(extendingOrTruncating: 129 as UInt8))
-  expectEqual((1 << 31 - 1) << 1, UInt32(extendingOrTruncating: -2 as Int8))
-  expectEqual(3, UInt32(extendingOrTruncating: 3 as Int8))
-  expectEqual(128, UInt32(extendingOrTruncating: 128 as UInt8))
-  expectEqual(129, UInt32(extendingOrTruncating: 129 as UInt8))
+  expectEqual(-2, Int32(truncatingIfNeeded: -2 as Int8))
+  expectEqual(3, Int32(truncatingIfNeeded: 3 as Int8))
+  expectEqual(127, Int32(truncatingIfNeeded: 127 as UInt8))
+  expectEqual(129, Int32(truncatingIfNeeded: 129 as UInt8))
+  expectEqual((1 << 31 - 1) << 1, UInt32(truncatingIfNeeded: -2 as Int8))
+  expectEqual(3, UInt32(truncatingIfNeeded: 3 as Int8))
+  expectEqual(128, UInt32(truncatingIfNeeded: 128 as UInt8))
+  expectEqual(129, UInt32(truncatingIfNeeded: 129 as UInt8))
 
-  expectEqual(-2, DWord(extendingOrTruncating: -2 as Int8))
-  expectEqual(3, DWord(extendingOrTruncating: 3 as Int8))
-  expectEqual(127, DWord(extendingOrTruncating: 127 as UInt8))
-  expectEqual(129, DWord(extendingOrTruncating: 129 as UInt8))
+  expectEqual(-2, DWord(truncatingIfNeeded: -2 as Int8))
+  expectEqual(3, DWord(truncatingIfNeeded: 3 as Int8))
+  expectEqual(127, DWord(truncatingIfNeeded: 127 as UInt8))
+  expectEqual(129, DWord(truncatingIfNeeded: 129 as UInt8))
   expectEqual(
     (1 << ${word_bits*2-1} - 1) << 1,
-    UDWord(extendingOrTruncating: -2 as Int8))
-  expectEqual(3, UDWord(extendingOrTruncating: 3 as Int8))
-  expectEqual(128, UDWord(extendingOrTruncating: 128 as UInt8))
-  expectEqual(129, UDWord(extendingOrTruncating: 129 as UInt8))
+    UDWord(truncatingIfNeeded: -2 as Int8))
+  expectEqual(3, UDWord(truncatingIfNeeded: 3 as Int8))
+  expectEqual(128, UDWord(truncatingIfNeeded: 128 as UInt8))
+  expectEqual(129, UDWord(truncatingIfNeeded: 129 as UInt8))
 
-  expectEqual(-2, Int8(extendingOrTruncating: -2 as DWord))
-  expectEqual(-2, Int8(extendingOrTruncating: -1 << 67 - 2 as DWord))
-  expectEqual(127, Int8(extendingOrTruncating: 127 as UDWord))
-  expectEqual(-127, Int8(extendingOrTruncating: 129 as UDWord))
-  expectEqual(0b1111_1100, UInt8(extendingOrTruncating: -4 as DWord))
-  expectEqual(0b1111_1100, UInt8(extendingOrTruncating: -1 << 67 - 4 as DWord))
-  expectEqual(128, UInt8(extendingOrTruncating: 128 + 1024 as UDWord))
-  expectEqual(129, UInt8(extendingOrTruncating: 129 + 1024 as UDWord))
+  expectEqual(-2, Int8(truncatingIfNeeded: -2 as DWord))
+  expectEqual(-2, Int8(truncatingIfNeeded: -1 << 67 - 2 as DWord))
+  expectEqual(127, Int8(truncatingIfNeeded: 127 as UDWord))
+  expectEqual(-127, Int8(truncatingIfNeeded: 129 as UDWord))
+  expectEqual(0b1111_1100, UInt8(truncatingIfNeeded: -4 as DWord))
+  expectEqual(0b1111_1100, UInt8(truncatingIfNeeded: -1 << 67 - 4 as DWord))
+  expectEqual(128, UInt8(truncatingIfNeeded: 128 + 1024 as UDWord))
+  expectEqual(129, UInt8(truncatingIfNeeded: 129 + 1024 as UDWord))
 }
 
 tests.test("Parsing/LosslessStringConvertible") {
@@ -716,7 +716,7 @@
     let (y, o) = x.addingReportingOverflow(1)
     expectEqual(y, 0)
     expectTrue(y == (0 as Int))
-    expectTrue(o == .overflow)
+    expectTrue(o)
   }
 
   do {
@@ -726,7 +726,7 @@
     expectLT(y, 0)
     expectTrue(y < (0 as Int))
     expectTrue(y < (0 as UInt))
-    expectTrue(o == .overflow)
+    expectTrue(o)
   }
 
   expectFalse(UInt1024.isSigned)
@@ -742,7 +742,7 @@
 
   expectTrue(DWU16(UInt16.max) == UInt16.max)
   expectNil(DWU16(exactly: UInt32.max))
-  expectEqual(DWU16(extendingOrTruncating: UInt64.max), DWU16.max)
+  expectEqual(DWU16(truncatingIfNeeded: UInt64.max), DWU16.max)
 
   expectCrashLater()
   _ = DWU16(UInt32.max)
@@ -751,7 +751,7 @@
 dwTests.test("TwoWords") {
   typealias DW = DoubleWidth<Int>
 
-  expectEqual(-1 as DW, DW(extendingOrTruncating: -1 as Int8))
+  expectEqual(-1 as DW, DW(truncatingIfNeeded: -1 as Int8))
 
   expectNil(Int(exactly: DW(Int.min) - 1))
   expectNil(Int(exactly: DW(Int.max) + 1))
diff --git a/test/stdlib/Intents.swift b/test/stdlib/Intents.swift
index a34ece1..e73b85e 100644
--- a/test/stdlib/Intents.swift
+++ b/test/stdlib/Intents.swift
@@ -41,6 +41,17 @@
       expectUnreachable()
     }
   }
+
+  IntentsTestSuite.test("INSetProfileInCarIntent/defaultProfile availability/\(swiftVersion)") {
+    func f(profile: INSetProfileInCarIntent) {
+      var isDefaultProfile = profile.isDefaultProfile
+      expectType(Bool?.self, &isDefaultProfile)
+#if !swift(>=4)
+      var defaultProfile = profile.defaultProfile
+      expectType(Int?.self, &defaultProfile)
+#endif
+    }
+  }
 }
 #endif
 
diff --git a/test/stdlib/MediaPlayer.swift b/test/stdlib/MediaPlayer.swift
new file mode 100644
index 0000000..597cd03
--- /dev/null
+++ b/test/stdlib/MediaPlayer.swift
@@ -0,0 +1,91 @@
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+// REQUIRES: objc_interop
+// REQUIRES: OS=ios
+
+import MediaPlayer
+import StdlibUnittest
+import StdlibUnittestFoundationExtras
+
+let MediaPlayerTests = TestSuite("MediaPlayer")
+
+MediaPlayerTests.test("decodablePlayParameters") {
+    if #available(iOS 11.0, *) {
+        let identifier = "1234567890"
+        let kind = "song"
+        let isLibrary = true
+        let playParamsData = """
+{
+    "id": "\(identifier)",
+    "kind": "\(kind)",
+    "isLibrary": \(isLibrary)
+}
+""".data(using: .utf8)!
+
+        do {
+            let decoder = JSONDecoder()
+            let playParameters = try decoder.decode(MPMusicPlayerPlayParameters.self, from: playParamsData)
+            let playParametersDictionary = playParameters.dictionary
+            expectEqual(identifier, playParametersDictionary["id"] as! String)
+            expectEqual(kind, playParametersDictionary["kind"] as! String)
+            expectEqual(isLibrary, playParametersDictionary["isLibrary"] as! Bool)
+        }
+        catch {
+            expectUnreachableCatch(error)
+        }
+    }
+}
+
+MediaPlayerTests.test("decodingInvalidPlayParameters") {
+    if #available(iOS 11.0, *) {
+        let invalidPlayParamsData = """
+{
+    "kind": "song"
+}
+""".data(using: .utf8)!
+
+        do {
+            let decoder = JSONDecoder()
+            let _ = try decoder.decode(MPMusicPlayerPlayParameters.self, from: invalidPlayParamsData)
+            expectUnreachable()
+        }
+        catch DecodingError.dataCorrupted(_) {}
+        catch {
+            expectUnreachableCatch(error)
+        }
+    }
+}
+
+
+MediaPlayerTests.test("encodablePlayParameters") {
+    if #available(iOS 11.0, *) {
+        let identifier = "1234567890"
+        let kind = "song"
+        let isLibrary = true
+        let correspondingPlayParamsString = """
+{"id":"\(identifier)","kind":"\(kind)","isLibrary":\(isLibrary)}
+"""
+
+        let playParametersDictionary: [String: Any] = [
+            "id": identifier,
+            "kind": kind,
+            "isLibrary": isLibrary
+        ]
+        guard let playParameters = MPMusicPlayerPlayParameters(dictionary: playParametersDictionary) else {
+            expectUnreachable()
+            return
+        }
+
+        do {
+            let encoder = JSONEncoder()
+            let encodedPlayParamsData = try encoder.encode(playParameters)
+            let encodedPlayParamsString = String(data: encodedPlayParamsData, encoding: .utf8)!
+            expectEqual(correspondingPlayParamsString, encodedPlayParamsString)
+        }
+        catch {
+            expectUnreachableCatch(error)
+        }
+    }
+}
+
+runAllTests()
diff --git a/test/stdlib/StringAPI.swift b/test/stdlib/StringAPI.swift
index 4b24f7a..99c629e 100644
--- a/test/stdlib/StringAPI.swift
+++ b/test/stdlib/StringAPI.swift
@@ -397,6 +397,105 @@
   }
 }
 
+StringTests.test("Regression/corelibs-foundation") {
+  struct NSRange { var location, length: Int }
+
+  func NSFakeRange(_ location: Int, _ length: Int) -> NSRange {
+    return NSRange(location: location, length: length)
+  }
+
+  func substring(of _storage: String, with range: NSRange) -> String {
+    let start = _storage.utf16.startIndex
+    let min = _storage.utf16.index(start, offsetBy: range.location)
+    let max = _storage.utf16.index(
+      start, offsetBy: range.location + range.length)
+
+    if let substr = String(_storage.utf16[min..<max]) {
+      return substr
+    }
+    //If we come here, then the range has created unpaired surrogates on either end.
+    //An unpaired surrogate is replaced by OXFFFD - the Unicode Replacement Character.
+    //The CRLF ("\r\n") sequence is also treated like a surrogate pair, but its constinuent
+    //characters "\r" and "\n" can exist outside the pair!
+
+    let replacementCharacter = String(describing: UnicodeScalar(0xFFFD)!)
+    let CR: UInt16 = 13  //carriage return
+    let LF: UInt16 = 10  //new line
+
+    //make sure the range is of non-zero length
+    guard range.length > 0 else { return "" }
+
+    //if the range is pointing to a single unpaired surrogate
+    if range.length == 1 {
+      switch _storage.utf16[min] {
+      case CR: return "\r"
+      case LF: return "\n"
+      default: return replacementCharacter
+      }
+    }
+
+    //set the prefix and suffix characters
+    let prefix = _storage.utf16[min] == LF ? "\n" : replacementCharacter
+    let suffix = _storage.utf16[_storage.utf16.index(before: max)] == CR
+      ? "\r" : replacementCharacter
+
+    let postMin = _storage.utf16.index(after: min)
+
+    //if the range breaks a surrogate pair at the beginning of the string
+    if let substrSuffix = String(
+      _storage.utf16[postMin..<max]) {
+      return prefix + substrSuffix
+    }
+
+    let preMax = _storage.utf16.index(before: max)
+    //if the range breaks a surrogate pair at the end of the string
+    if let substrPrefix = String(_storage.utf16[min..<preMax]) {
+      return substrPrefix + suffix
+    }
+
+    //the range probably breaks surrogate pairs at both the ends
+    guard postMin <= preMax else { return prefix + suffix }
+
+    let substr =  String(_storage.utf16[postMin..<preMax])!
+    return prefix + substr + suffix
+  }
+
+  let trivial = "swift.org"
+  expectEqual(substring(of: trivial, with: NSFakeRange(0, 5)), "swift")
+
+  let surrogatePairSuffix = "Hurray🎉"
+  expectEqual(substring(of: surrogatePairSuffix, with: NSFakeRange(0, 7)), "Hurray�")
+
+  let surrogatePairPrefix = "🐱Cat"
+  expectEqual(substring(of: surrogatePairPrefix, with: NSFakeRange(1, 4)), "�Cat")
+
+  let singleChar = "😹"
+  expectEqual(substring(of: singleChar, with: NSFakeRange(0,1)), "�")
+
+  let crlf = "\r\n"
+  expectEqual(substring(of: crlf, with: NSFakeRange(0,1)), "\r")
+  expectEqual(substring(of: crlf, with: NSFakeRange(1,1)), "\n")
+  expectEqual(substring(of: crlf, with: NSFakeRange(1,0)), "")
+
+  let bothEnds1 = "😺😺"
+  expectEqual(substring(of: bothEnds1, with: NSFakeRange(1,2)), "��")
+
+  let s1 = "😺\r\n"
+  expectEqual(substring(of: s1, with: NSFakeRange(1,2)), "�\r")
+
+  let s2 = "\r\n😺"
+  expectEqual(substring(of: s2, with: NSFakeRange(1,2)), "\n�")
+
+  let s3 = "😺cats😺"
+  expectEqual(substring(of: s3, with: NSFakeRange(1,6)), "�cats�")
+
+  let s4 = "😺cats\r\n"
+  expectEqual(substring(of: s4, with: NSFakeRange(1,6)), "�cats\r")
+
+  let s5 = "\r\ncats😺"
+  expectEqual(substring(of: s5, with: NSFakeRange(1,6)), "\ncats�")
+}
+
 var CStringTests = TestSuite("CStringTests")
 
 func getNullUTF8() -> UnsafeMutablePointer<UInt8>? {
diff --git a/test/stdlib/StringReallocation.swift b/test/stdlib/StringReallocation.swift
index e774fbb..c3b9d1e 100644
--- a/test/stdlib/StringReallocation.swift
+++ b/test/stdlib/StringReallocation.swift
@@ -1,6 +1,8 @@
 // RUN: %target-run-simple-swift | %FileCheck %s
 // REQUIRES: executable_test
 
+import StdlibUnittest
+
 // CHECK-NOT: Reallocations exceeded 30
 func testReallocation() {
   var x = "The quick brown fox jumped over the lazy dog\n"._split(separator: " ")
diff --git a/test/stdlib/subString.swift b/test/stdlib/subString.swift
index 43806a9..3ed4d7c 100644
--- a/test/stdlib/subString.swift
+++ b/test/stdlib/subString.swift
@@ -190,4 +190,11 @@
   expectEqual("", String(u.dropLast(10))!)
 }
 
+SubstringTests.test("Persistent Content") {
+  var str = "abc"
+  str += "def"
+  expectEqual("bcdefg", str.dropFirst(1) + "g")
+  expectEqual("bcdefg", (str.dropFirst(1) + "g") as String)
+}
+
 runAllTests()
diff --git a/tools/SourceKit/CMakeLists.txt b/tools/SourceKit/CMakeLists.txt
index bd9e7a8..cdcb467 100644
--- a/tools/SourceKit/CMakeLists.txt
+++ b/tools/SourceKit/CMakeLists.txt
@@ -22,7 +22,7 @@
 
 swift_is_installing_component(sourcekit-inproc SOURCEKIT_INSTALLING_INPROC)
 
-if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin" AND NOT CMAKE_CROSSCOMPILING)
   set(CMAKE_OSX_SYSROOT "${SWIFT_SDK_${SWIFT_HOST_VARIANT_SDK}_PATH}")
   set(CMAKE_OSX_ARCHITECTURES "${SWIFT_HOST_VARIANT_ARCH}")
   set(CMAKE_OSX_DEPLOYMENT_TARGET "")
@@ -115,7 +115,8 @@
 #
 # Usage:
 #   add_sourcekit_library(name       # Name of the library
-#     [DEPENDS dep1 ...]             # Libraries this library depends on
+#     [DEPENDS dep1 ...]             # Libraries this library will be linked with
+#     [TARGET_DEPENDS dep1 ...]      # Targets this library depends on
 #     [LLVM_COMPONENT_DEPENDS comp1 ...]  # LLVM components this library depends on
 #     [INSTALL_IN_COMPONENT comp]    # The Swift installation component that this library belongs to.
 #     [SHARED]
@@ -124,7 +125,7 @@
   cmake_parse_arguments(SOURCEKITLIB
       "SHARED"
       "INSTALL_IN_COMPONENT"
-      "DEPENDS;LLVM_COMPONENT_DEPENDS"
+      "DEPENDS;TARGET_DEPENDS;LLVM_COMPONENT_DEPENDS"
       ${ARGN})
   set(srcs ${SOURCEKITLIB_UNPARSED_ARGUMENTS})
 
@@ -169,6 +170,10 @@
     add_dependencies(${name} ${LLVM_COMMON_DEPENDS})
   endif(LLVM_COMMON_DEPENDS)
 
+  if(SOURCEKITLIB_TARGET_DEPENDS)
+    add_dependencies(${name} ${SOURCEKITLIB_TARGET_DEPENDS})
+  endif(SOURCEKITLIB_TARGET_DEPENDS)
+
   set(prefixed_link_libraries)
   foreach(dep ${SOURCEKITLIB_DEPENDS})
     if("${dep}" MATCHES "^clang")
diff --git a/tools/SourceKit/lib/SwiftLang/CMakeLists.txt b/tools/SourceKit/lib/SwiftLang/CMakeLists.txt
index 128be2d..3ed6f61 100644
--- a/tools/SourceKit/lib/SwiftLang/CMakeLists.txt
+++ b/tools/SourceKit/lib/SwiftLang/CMakeLists.txt
@@ -8,6 +8,7 @@
   SwiftIndexing.cpp
   SwiftLangSupport.cpp
   SwiftSourceDocInfo.cpp
+  TARGET_DEPENDS swift-syntax-generated-headers
   DEPENDS SourceKitCore swiftDriver swiftFrontend swiftClangImporter swiftIDE
           swiftAST swiftMarkup swiftParse swiftParseSIL swiftSIL swiftSILGen
           swiftSILOptimizer swiftIRGen swiftSema swiftBasic swiftSerialization
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
index 91624ca..298d4f2 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp
@@ -375,6 +375,8 @@
       return KindDeclEnumCase;
     case SyntaxStructureKind::EnumElement:
       return KindDeclEnumElement;
+    case SyntaxStructureKind::TypeAlias:
+      return KindDeclTypeAlias;
     case SyntaxStructureKind::Parameter:
       return KindDeclVarParam;
     case SyntaxStructureKind::ForEachStatement:
diff --git a/tools/swift-ide-test/swift-ide-test.cpp b/tools/swift-ide-test/swift-ide-test.cpp
index 9b9362c..6b14f28 100644
--- a/tools/swift-ide-test/swift-ide-test.cpp
+++ b/tools/swift-ide-test/swift-ide-test.cpp
@@ -1069,6 +1069,7 @@
       case SyntaxStructureKind::ClassVariable: return "cvar";
       case SyntaxStructureKind::EnumCase: return "enum-case";
       case SyntaxStructureKind::EnumElement: return "enum-elem";
+      case SyntaxStructureKind::TypeAlias: return "typealias";
       case SyntaxStructureKind::Parameter: return "param";
       case SyntaxStructureKind::ForEachStatement: return "foreach";
       case SyntaxStructureKind::ForStatement: return "for";
diff --git a/validation-test/compiler_crashers/28827-type-ismaterializable-argument-to-setmustbematerializablerecursive-may-not-be-in.swift b/validation-test/compiler_crashers/28828-unreachable-executed-at-swift-lib-ast-type-cpp-3237.swift
similarity index 86%
copy from validation-test/compiler_crashers/28827-type-ismaterializable-argument-to-setmustbematerializablerecursive-may-not-be-in.swift
copy to validation-test/compiler_crashers/28828-unreachable-executed-at-swift-lib-ast-type-cpp-3237.swift
index 9dc86c5..6e3d98b 100644
--- a/validation-test/compiler_crashers/28827-type-ismaterializable-argument-to-setmustbematerializablerecursive-may-not-be-in.swift
+++ b/validation-test/compiler_crashers/28828-unreachable-executed-at-swift-lib-ast-type-cpp-3237.swift
@@ -5,7 +5,5 @@
 // See https://swift.org/LICENSE.txt for license information
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
-// REQUIRES: asserts
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-[(Int
-(t:&_
+class a<a{class a{extension{protocol P{class a:a{func a:Self.a
diff --git a/validation-test/compiler_crashers/28820-fl-isinout-caller-did-not-set-flags-correctly.swift b/validation-test/compiler_crashers/28829-replacement-ismaterializable-cannot-substitute-with-a-non-materializable-type.swift
similarity index 97%
rename from validation-test/compiler_crashers/28820-fl-isinout-caller-did-not-set-flags-correctly.swift
rename to validation-test/compiler_crashers/28829-replacement-ismaterializable-cannot-substitute-with-a-non-materializable-type.swift
index 8f0a90d..7c481e9 100644
--- a/validation-test/compiler_crashers/28820-fl-isinout-caller-did-not-set-flags-correctly.swift
+++ b/validation-test/compiler_crashers/28829-replacement-ismaterializable-cannot-substitute-with-a-non-materializable-type.swift
@@ -7,4 +7,4 @@
 
 // REQUIRES: asserts
 // RUN: not --crash %target-swift-frontend %s -emit-ir
-.a.i(t:&_
+&_==nil
diff --git a/validation-test/compiler_crashers_2/0109-sr4737.swift b/validation-test/compiler_crashers_2/0109-sr4737.swift
index d97a135..1d84f4c 100644
--- a/validation-test/compiler_crashers_2/0109-sr4737.swift
+++ b/validation-test/compiler_crashers_2/0109-sr4737.swift
@@ -33,8 +33,8 @@
   
   @inline(__always)
   public init(containing e: Element) {
-    _storage = Storage(extendingOrTruncating: e)
-    _bitCount = UInt8(extendingOrTruncating: Element.bitWidth)
+    _storage = Storage(truncatingIfNeeded: e)
+    _bitCount = UInt8(truncatingIfNeeded: Element.bitWidth)
   }
 }
 
@@ -51,7 +51,7 @@
         _impl._storage = _impl._storage &>> Element.bitWidth
         _impl._bitCount = _impl._bitCount &- _impl._elementWidth
       }
-      return Element(extendingOrTruncating: _impl._storage)
+      return Element(truncatingIfNeeded: _impl._storage)
     }
     @_versioned
     var _impl: _UIntBuffer
@@ -74,7 +74,7 @@
       var s: Storage = 0
       for x in self {
         s <<= Element.bitWidth
-        s |= Storage(extendingOrTruncating: x)
+        s |= Storage(truncatingIfNeeded: x)
       }
       return Self(_storage: s, _bitCount: _bitCount)
     }
@@ -116,13 +116,13 @@
 
   @_versioned
   internal var _elementWidth : UInt8 {
-    return UInt8(extendingOrTruncating: Element.bitWidth)
+    return UInt8(truncatingIfNeeded: Element.bitWidth)
   }
   
   public subscript(i: Index) -> Element {
     @inline(__always)
     get {
-      return Element(extendingOrTruncating: _storage &>> i.bitOffset)
+      return Element(truncatingIfNeeded: _storage &>> i.bitOffset)
     }
   }
 }
@@ -141,7 +141,7 @@
   @inline(__always)
   public func index(_ i: Index, offsetBy n: IndexDistance) -> Index {
     let x = IndexDistance(i.bitOffset) &+ n &* Element.bitWidth
-    return Index(bitOffset: UInt8(extendingOrTruncating: x))
+    return Index(bitOffset: UInt8(truncatingIfNeeded: x))
   }
 
   @inline(__always)
@@ -220,7 +220,7 @@
     _storage |= replacement1._storage &<< (headCount &* w)
     _storage |= tailBits &<< ((tailOffset &+ growth) &* w)
     _bitCount = UInt8(
-      extendingOrTruncating: IndexDistance(_bitCount) &+ growth &* w)
+      truncatingIfNeeded: IndexDistance(_bitCount) &+ growth &* w)
   }
 }
 //===----------------------------------------------------------------------===//
@@ -520,10 +520,10 @@
       }
       // Non-ASCII, proceed to buffering mode.
       buffer.append(codeUnit)
-    } else if Self._isScalar(CodeUnit(extendingOrTruncating: buffer._storage)) {
+    } else if Self._isScalar(CodeUnit(truncatingIfNeeded: buffer._storage)) {
       // ASCII in buffer.  We don't refill the buffer so we can return
       // to bufferless mode once we've exhausted it.
-      let codeUnit = CodeUnit(extendingOrTruncating: buffer._storage)
+      let codeUnit = CodeUnit(truncatingIfNeeded: buffer._storage)
       buffer.remove(at: buffer.startIndex)
       return (
           EncodedScalar(containing: codeUnit),
@@ -826,7 +826,7 @@
   public // @testable
   func _parseMultipleCodeUnits() -> (isValid: Bool, bitCount: UInt8) {
     _sanityCheck(  // this case handled elsewhere
-      !Self._isScalar(UInt16(extendingOrTruncating: buffer._storage)))
+      !Self._isScalar(UInt16(truncatingIfNeeded: buffer._storage)))
     
     if _fastPath(buffer._storage & 0xFC00_FC00 == Self._surrogatePattern) {
       return (true, 2*16)
diff --git a/validation-test/compiler_crashers/28820-fl-isinout-caller-did-not-set-flags-correctly.swift b/validation-test/compiler_crashers_fixed/28820-fl-isinout-caller-did-not-set-flags-correctly.swift
similarity index 87%
copy from validation-test/compiler_crashers/28820-fl-isinout-caller-did-not-set-flags-correctly.swift
copy to validation-test/compiler_crashers_fixed/28820-fl-isinout-caller-did-not-set-flags-correctly.swift
index 8f0a90d..cebc195 100644
--- a/validation-test/compiler_crashers/28820-fl-isinout-caller-did-not-set-flags-correctly.swift
+++ b/validation-test/compiler_crashers_fixed/28820-fl-isinout-caller-did-not-set-flags-correctly.swift
@@ -6,5 +6,5 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 .a.i(t:&_
diff --git a/validation-test/compiler_crashers/28827-type-ismaterializable-argument-to-setmustbematerializablerecursive-may-not-be-in.swift b/validation-test/compiler_crashers_fixed/28827-type-ismaterializable-argument-to-setmustbematerializablerecursive-may-not-be-in.swift
similarity index 87%
rename from validation-test/compiler_crashers/28827-type-ismaterializable-argument-to-setmustbematerializablerecursive-may-not-be-in.swift
rename to validation-test/compiler_crashers_fixed/28827-type-ismaterializable-argument-to-setmustbematerializablerecursive-may-not-be-in.swift
index 9dc86c5..cd7ff73 100644
--- a/validation-test/compiler_crashers/28827-type-ismaterializable-argument-to-setmustbematerializablerecursive-may-not-be-in.swift
+++ b/validation-test/compiler_crashers_fixed/28827-type-ismaterializable-argument-to-setmustbematerializablerecursive-may-not-be-in.swift
@@ -6,6 +6,6 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // REQUIRES: asserts
-// RUN: not --crash %target-swift-frontend %s -emit-ir
+// RUN: not %target-swift-frontend %s -emit-ir
 [(Int
 (t:&_
diff --git a/validation-test/stdlib/Collection/DefaultedBidirectionalCollection.swift b/validation-test/stdlib/Collection/DefaultedBidirectionalCollection.swift
index 7e67940..01546cd 100644
--- a/validation-test/stdlib/Collection/DefaultedBidirectionalCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedBidirectionalCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addBidirectionalCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedBidirectionalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedBidirectionalCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedBidirectionalCollectionOfRef.swift
new file mode 100644
index 0000000..fd7e584
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedBidirectionalCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addBidirectionalCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedBidirectionalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedCollection.swift b/validation-test/stdlib/Collection/DefaultedCollection.swift
index ac86a40..f90be56 100644
--- a/validation-test/stdlib/Collection/DefaultedCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedCollectionOfRef.swift
new file mode 100644
index 0000000..2ed3e4f
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedMutableBidirectionalCollection.swift b/validation-test/stdlib/Collection/DefaultedMutableBidirectionalCollection.swift
index 7a40abd..7ba2ebf 100644
--- a/validation-test/stdlib/Collection/DefaultedMutableBidirectionalCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedMutableBidirectionalCollection.swift
@@ -40,37 +40,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addMutableBidirectionalCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedMutableBidirectionalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedMutableBidirectionalCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedMutableBidirectionalCollectionOfRef.swift
new file mode 100644
index 0000000..e547f05
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedMutableBidirectionalCollectionOfRef.swift
@@ -0,0 +1,49 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addMutableBidirectionalCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedMutableBidirectionalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedMutableCollection.swift b/validation-test/stdlib/Collection/DefaultedMutableCollection.swift
index 93b067e..6adf37b 100644
--- a/validation-test/stdlib/Collection/DefaultedMutableCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedMutableCollection.swift
@@ -40,37 +40,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addMutableCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedMutableCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedMutableCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedMutableCollectionOfRef.swift
new file mode 100644
index 0000000..11fc885
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedMutableCollectionOfRef.swift
@@ -0,0 +1,49 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addMutableCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedMutableCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedMutableRandomAccessCollection.swift b/validation-test/stdlib/Collection/DefaultedMutableRandomAccessCollection.swift
index 92d629f..7082438 100644
--- a/validation-test/stdlib/Collection/DefaultedMutableRandomAccessCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedMutableRandomAccessCollection.swift
@@ -40,37 +40,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addMutableRandomAccessCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedMutableRandomAccessCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedMutableRandomAccessCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedMutableRandomAccessCollectionOfRef.swift
new file mode 100644
index 0000000..7ab6fa5
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedMutableRandomAccessCollectionOfRef.swift
@@ -0,0 +1,49 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addMutableRandomAccessCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedMutableRandomAccessCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableBidirectionalCollection.swift b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableBidirectionalCollection.swift
index 531a406..56b8ddf 100644
--- a/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableBidirectionalCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableBidirectionalCollection.swift
@@ -53,55 +53,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableBidirectionalCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedMutableRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-  CollectionTests.addMutableBidirectionalCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedMutableRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableBidirectionalCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableBidirectionalCollectionOfRef.swift
new file mode 100644
index 0000000..1d4c801
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableBidirectionalCollectionOfRef.swift
@@ -0,0 +1,67 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableBidirectionalCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedMutableRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+  CollectionTests.addMutableBidirectionalCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedMutableRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableCollection.swift b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableCollection.swift
index 5f50cad..84c06c5 100644
--- a/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableCollection.swift
@@ -53,55 +53,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedMutableRangeReplaceableCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRangeReplaceableCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-  CollectionTests.addMutableCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedMutableRangeReplaceableCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRangeReplaceableCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRangeReplaceableCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableCollectionOfRef.swift
new file mode 100644
index 0000000..b1fdee3
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableCollectionOfRef.swift
@@ -0,0 +1,67 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedMutableRangeReplaceableCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRangeReplaceableCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+  CollectionTests.addMutableCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedMutableRangeReplaceableCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRangeReplaceableCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRangeReplaceableCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableRandomAccessCollection.swift b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableRandomAccessCollection.swift
index 09678fe..df73b15 100644
--- a/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableRandomAccessCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableRandomAccessCollection.swift
@@ -53,55 +53,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableRandomAccessCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedMutableRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-  CollectionTests.addMutableRandomAccessCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedMutableRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedMutableRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableRandomAccessCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableRandomAccessCollectionOfRef.swift
new file mode 100644
index 0000000..7890841
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedMutableRangeReplaceableRandomAccessCollectionOfRef.swift
@@ -0,0 +1,67 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableRandomAccessCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedMutableRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+  CollectionTests.addMutableRandomAccessCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedMutableRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedMutableRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedRandomAccessCollection.swift b/validation-test/stdlib/Collection/DefaultedRandomAccessCollection.swift
index f8baffe..b36878e 100644
--- a/validation-test/stdlib/Collection/DefaultedRandomAccessCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedRandomAccessCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRandomAccessCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedRandomAccessCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedRandomAccessCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedRandomAccessCollectionOfRef.swift
new file mode 100644
index 0000000..6fa6406
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedRandomAccessCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRandomAccessCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedRandomAccessCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedRangeReplaceableBidirectionalCollection.swift b/validation-test/stdlib/Collection/DefaultedRangeReplaceableBidirectionalCollection.swift
index 48d5adc..0e09f4d 100644
--- a/validation-test/stdlib/Collection/DefaultedRangeReplaceableBidirectionalCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedRangeReplaceableBidirectionalCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableBidirectionalCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedRangeReplaceableBidirectionalCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedRangeReplaceableBidirectionalCollectionOfRef.swift
new file mode 100644
index 0000000..e2d5c90
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedRangeReplaceableBidirectionalCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableBidirectionalCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedRangeReplaceableCollection.swift b/validation-test/stdlib/Collection/DefaultedRangeReplaceableCollection.swift
index 95f89dc..1bfbd58 100644
--- a/validation-test/stdlib/Collection/DefaultedRangeReplaceableCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedRangeReplaceableCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedRangeReplaceableCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedRangeReplaceableCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedRangeReplaceableCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedRangeReplaceableCollectionOfRef.swift
new file mode 100644
index 0000000..2ec0372
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedRangeReplaceableCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedRangeReplaceableCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedRangeReplaceableCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/DefaultedRangeReplaceableRandomAccessCollection.swift b/validation-test/stdlib/Collection/DefaultedRangeReplaceableRandomAccessCollection.swift
index ed9c65c..9b5e75a 100644
--- a/validation-test/stdlib/Collection/DefaultedRangeReplaceableRandomAccessCollection.swift
+++ b/validation-test/stdlib/Collection/DefaultedRangeReplaceableRandomAccessCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableRandomAccessCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return DefaultedRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return DefaultedRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/DefaultedRangeReplaceableRandomAccessCollectionOfRef.swift b/validation-test/stdlib/Collection/DefaultedRangeReplaceableRandomAccessCollectionOfRef.swift
new file mode 100644
index 0000000..fde707e
--- /dev/null
+++ b/validation-test/stdlib/Collection/DefaultedRangeReplaceableRandomAccessCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableRandomAccessCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return DefaultedRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return DefaultedRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/LazyMapCollection.swift.gyb b/validation-test/stdlib/Collection/Inputs/LazyMapTemplate.swift.gyb
similarity index 80%
rename from validation-test/stdlib/Collection/LazyMapCollection.swift.gyb
rename to validation-test/stdlib/Collection/Inputs/LazyMapTemplate.swift.gyb
index 8ec67ac..9bdf5f9 100644
--- a/validation-test/stdlib/Collection/LazyMapCollection.swift.gyb
+++ b/validation-test/stdlib/Collection/Inputs/LazyMapTemplate.swift.gyb
@@ -1,5 +1,28 @@
+%{
+# This is a template of validation-test/stdlib/Collection/LazyMap*.swift
+#
+# cd validation-test/stdlib/Collection
+# ../../../utils/gyb --line-directive="" Inputs/LazyMapTemplate.swift.gyb | ../../../utils/split_file.py
+
+variations = [
+  ('', 'Sequence'),
+  ('', 'Collection'),
+  ('Bidirectional', 'Collection'),
+  ('RandomAccess', 'Collection')
+  ]
+}%
+
+
+% for (traversal, kind) in variations:
+// BEGIN LazyMap${traversal}${kind}.swift
 // -*- swift -*-
-// RUN: %target-run-simple-swiftgyb
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/LazyMapTemplate.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
 // REQUIRES: executable_test
 
 import StdlibUnittest
@@ -7,12 +30,7 @@
 
 var CollectionTests = TestSuite("Collection")
 
-%{
-variations = [('', 'Sequence'), ('', 'Collection'), ('Bidirectional', 'Collection'), ('RandomAccess', 'Collection')]
-}%
-
 // Test collections using value types as elements.
-% for (traversal, kind) in variations:
 CollectionTests.add${traversal}${kind}Tests(
   make${kind}: { (elements: [OpaqueValue<Int>]) -> LazyMap${traversal}${kind}<Minimal${traversal}${kind}<OpaqueValue<Int>>, OpaqueValue<Int>> in
     Minimal${traversal}${kind}(elements: elements).lazy.map(identity)
@@ -25,10 +43,8 @@
   wrapValueIntoEquatable: identityEq,
   extractValueFromEquatable: identityEq
 )
-% end
 
 // Test collections using reference types as elements.
-% for (traversal, kind) in variations:
 CollectionTests.add${traversal}${kind}Tests(
   make${kind}: { (elements: [LifetimeTracked]) -> LazyMap${traversal}${kind}<Minimal${traversal}${kind}<LifetimeTracked>, LifetimeTracked> in
     Minimal${traversal}${kind}(elements: elements).lazy.map { $0 }
@@ -49,10 +65,8 @@
     MinimalEquatableValue(element.value, identity: element.identity)
   }
 )
-% end
 
 // Test sequence instances and iterators.
-% for (traversal, kind) in variations:
 CollectionTests.test("LazyMapCollection instances (${traversal}${kind})") {
   do {
     let expected = ["convent", "conform", "constrict", "condone"]
@@ -90,6 +104,7 @@
 % end
   }
 }
-% end
 
 runAllTests()
+
+% end # for (traversal, kind) in variations
diff --git a/validation-test/stdlib/Collection/Inputs/Template.swift.gyb b/validation-test/stdlib/Collection/Inputs/Template.swift.gyb
index 0f7c1da..b21184c 100644
--- a/validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+++ b/validation-test/stdlib/Collection/Inputs/Template.swift.gyb
@@ -14,6 +14,7 @@
 
 class TestParameters(object):
   name = ''
+  ref_name = ''
   base = ''
   traversal = ''
   mutable = False
@@ -36,6 +37,7 @@
       mutable=mutable,
       rangeReplaceable=range_replaceable).replace('Slice', 'Collection')
     test.name = test.base + '.swift'
+    test.ref_name = test.base + 'OfRef.swift'
     yield test
 
 def test_methods(test):
@@ -107,6 +109,25 @@
 % end
 }
 
+runAllTests()
+
+
+// BEGIN ${test.ref_name}
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
 // Test collections using a reference type as element.
 do {
   var resiliencyChecks = CollectionMisuseResiliencyChecks.all
diff --git a/validation-test/stdlib/Collection/LazyMapBidirectionalCollection.swift b/validation-test/stdlib/Collection/LazyMapBidirectionalCollection.swift
new file mode 100644
index 0000000..de4162b
--- /dev/null
+++ b/validation-test/stdlib/Collection/LazyMapBidirectionalCollection.swift
@@ -0,0 +1,72 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/LazyMapTemplate.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using value types as elements.
+CollectionTests.addBidirectionalCollectionTests(
+  makeCollection: { (elements: [OpaqueValue<Int>]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<OpaqueValue<Int>>, OpaqueValue<Int>> in
+    MinimalBidirectionalCollection(elements: elements).lazy.map(identity)
+  },
+  wrapValue: identity,
+  extractValue: identity,
+  makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<MinimalEquatableValue>, MinimalEquatableValue> in
+    MinimalBidirectionalCollection(elements: elements).lazy.map(identityEq)
+  },
+  wrapValueIntoEquatable: identityEq,
+  extractValueFromEquatable: identityEq
+)
+
+// Test collections using reference types as elements.
+CollectionTests.addBidirectionalCollectionTests(
+  makeCollection: { (elements: [LifetimeTracked]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<LifetimeTracked>, LifetimeTracked> in
+    MinimalBidirectionalCollection(elements: elements).lazy.map { $0 }
+  },
+  wrapValue: { (element: OpaqueValue<Int>) in
+    LifetimeTracked(element.value, identity: element.identity)
+  },
+  extractValue: { (element: LifetimeTracked) in
+    OpaqueValue(element.value, identity: element.identity)
+  },
+  makeCollectionOfEquatable: { (elements: [LifetimeTracked]) -> LazyMapBidirectionalCollection<MinimalBidirectionalCollection<LifetimeTracked>, LifetimeTracked> in
+    MinimalBidirectionalCollection(elements: elements).lazy.map { $0 }
+  },
+  wrapValueIntoEquatable: { (element: MinimalEquatableValue) in
+    LifetimeTracked(element.value, identity: element.identity)
+  },
+  extractValueFromEquatable: { (element: LifetimeTracked) in
+    MinimalEquatableValue(element.value, identity: element.identity)
+  }
+)
+
+// Test sequence instances and iterators.
+CollectionTests.test("LazyMapCollection instances (BidirectionalCollection)") {
+  do {
+    let expected = ["convent", "conform", "constrict", "condone"]
+    let base = ["vent", "form", "strict", "done"]
+    checkBidirectionalCollection(expected,
+      MinimalBidirectionalCollection(elements: base).lazy.map { "con" + $0 },
+      sameValue: { $0 == $1 })
+  }
+  do {
+    let expected = [1, 4, 9, 16, 25, 36, 49, 64]
+    let base = [1, 2, 3, 4, 5, 6, 7, 8]
+    checkBidirectionalCollection(
+      expected,
+      MinimalBidirectionalCollection(elements: base).lazy.map { $0 * $0 },
+      sameValue: { $0 == $1 })
+  }
+}
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Collection/LazyMapCollection.swift b/validation-test/stdlib/Collection/LazyMapCollection.swift
new file mode 100644
index 0000000..f3c3e65
--- /dev/null
+++ b/validation-test/stdlib/Collection/LazyMapCollection.swift
@@ -0,0 +1,71 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/LazyMapTemplate.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using value types as elements.
+CollectionTests.addCollectionTests(
+  makeCollection: { (elements: [OpaqueValue<Int>]) -> LazyMapCollection<MinimalCollection<OpaqueValue<Int>>, OpaqueValue<Int>> in
+    MinimalCollection(elements: elements).lazy.map(identity)
+  },
+  wrapValue: identity,
+  extractValue: identity,
+  makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) -> LazyMapCollection<MinimalCollection<MinimalEquatableValue>, MinimalEquatableValue> in
+    MinimalCollection(elements: elements).lazy.map(identityEq)
+  },
+  wrapValueIntoEquatable: identityEq,
+  extractValueFromEquatable: identityEq
+)
+
+// Test collections using reference types as elements.
+CollectionTests.addCollectionTests(
+  makeCollection: { (elements: [LifetimeTracked]) -> LazyMapCollection<MinimalCollection<LifetimeTracked>, LifetimeTracked> in
+    MinimalCollection(elements: elements).lazy.map { $0 }
+  },
+  wrapValue: { (element: OpaqueValue<Int>) in
+    LifetimeTracked(element.value, identity: element.identity)
+  },
+  extractValue: { (element: LifetimeTracked) in
+    OpaqueValue(element.value, identity: element.identity)
+  },
+  makeCollectionOfEquatable: { (elements: [LifetimeTracked]) -> LazyMapCollection<MinimalCollection<LifetimeTracked>, LifetimeTracked> in
+    MinimalCollection(elements: elements).lazy.map { $0 }
+  },
+  wrapValueIntoEquatable: { (element: MinimalEquatableValue) in
+    LifetimeTracked(element.value, identity: element.identity)
+  },
+  extractValueFromEquatable: { (element: LifetimeTracked) in
+    MinimalEquatableValue(element.value, identity: element.identity)
+  }
+)
+
+// Test sequence instances and iterators.
+CollectionTests.test("LazyMapCollection instances (Collection)") {
+  do {
+    let expected = ["convent", "conform", "constrict", "condone"]
+    let base = ["vent", "form", "strict", "done"]
+    checkForwardCollection(expected,
+      MinimalCollection(elements: base).lazy.map { "con" + $0 },
+      sameValue: { $0 == $1 })
+  }
+  do {
+    let expected = [1, 4, 9, 16, 25, 36, 49, 64]
+    let base = [1, 2, 3, 4, 5, 6, 7, 8]
+    checkForwardCollection(expected,
+      MinimalCollection(elements: base).lazy.map { $0 * $0 },
+      sameValue: { $0 == $1 })
+  }
+}
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Collection/LazyMapRandomAccessCollection.swift b/validation-test/stdlib/Collection/LazyMapRandomAccessCollection.swift
new file mode 100644
index 0000000..8adec60
--- /dev/null
+++ b/validation-test/stdlib/Collection/LazyMapRandomAccessCollection.swift
@@ -0,0 +1,72 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/LazyMapTemplate.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using value types as elements.
+CollectionTests.addRandomAccessCollectionTests(
+  makeCollection: { (elements: [OpaqueValue<Int>]) -> LazyMapRandomAccessCollection<MinimalRandomAccessCollection<OpaqueValue<Int>>, OpaqueValue<Int>> in
+    MinimalRandomAccessCollection(elements: elements).lazy.map(identity)
+  },
+  wrapValue: identity,
+  extractValue: identity,
+  makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) -> LazyMapRandomAccessCollection<MinimalRandomAccessCollection<MinimalEquatableValue>, MinimalEquatableValue> in
+    MinimalRandomAccessCollection(elements: elements).lazy.map(identityEq)
+  },
+  wrapValueIntoEquatable: identityEq,
+  extractValueFromEquatable: identityEq
+)
+
+// Test collections using reference types as elements.
+CollectionTests.addRandomAccessCollectionTests(
+  makeCollection: { (elements: [LifetimeTracked]) -> LazyMapRandomAccessCollection<MinimalRandomAccessCollection<LifetimeTracked>, LifetimeTracked> in
+    MinimalRandomAccessCollection(elements: elements).lazy.map { $0 }
+  },
+  wrapValue: { (element: OpaqueValue<Int>) in
+    LifetimeTracked(element.value, identity: element.identity)
+  },
+  extractValue: { (element: LifetimeTracked) in
+    OpaqueValue(element.value, identity: element.identity)
+  },
+  makeCollectionOfEquatable: { (elements: [LifetimeTracked]) -> LazyMapRandomAccessCollection<MinimalRandomAccessCollection<LifetimeTracked>, LifetimeTracked> in
+    MinimalRandomAccessCollection(elements: elements).lazy.map { $0 }
+  },
+  wrapValueIntoEquatable: { (element: MinimalEquatableValue) in
+    LifetimeTracked(element.value, identity: element.identity)
+  },
+  extractValueFromEquatable: { (element: LifetimeTracked) in
+    MinimalEquatableValue(element.value, identity: element.identity)
+  }
+)
+
+// Test sequence instances and iterators.
+CollectionTests.test("LazyMapCollection instances (RandomAccessCollection)") {
+  do {
+    let expected = ["convent", "conform", "constrict", "condone"]
+    let base = ["vent", "form", "strict", "done"]
+    checkRandomAccessCollection(expected,
+      MinimalRandomAccessCollection(elements: base).lazy.map { "con" + $0 },
+      sameValue: { $0 == $1 })
+  }
+  do {
+    let expected = [1, 4, 9, 16, 25, 36, 49, 64]
+    let base = [1, 2, 3, 4, 5, 6, 7, 8]
+    checkRandomAccessCollection(
+      expected,
+      MinimalRandomAccessCollection(elements: base).lazy.map { $0 * $0 },
+      sameValue: { $0 == $1 })
+  }
+}
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Collection/LazyMapSequence.swift b/validation-test/stdlib/Collection/LazyMapSequence.swift
new file mode 100644
index 0000000..c37feae
--- /dev/null
+++ b/validation-test/stdlib/Collection/LazyMapSequence.swift
@@ -0,0 +1,71 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/LazyMapTemplate.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using value types as elements.
+CollectionTests.addSequenceTests(
+  makeSequence: { (elements: [OpaqueValue<Int>]) -> LazyMapSequence<MinimalSequence<OpaqueValue<Int>>, OpaqueValue<Int>> in
+    MinimalSequence(elements: elements).lazy.map(identity)
+  },
+  wrapValue: identity,
+  extractValue: identity,
+  makeSequenceOfEquatable: { (elements: [MinimalEquatableValue]) -> LazyMapSequence<MinimalSequence<MinimalEquatableValue>, MinimalEquatableValue> in
+    MinimalSequence(elements: elements).lazy.map(identityEq)
+  },
+  wrapValueIntoEquatable: identityEq,
+  extractValueFromEquatable: identityEq
+)
+
+// Test collections using reference types as elements.
+CollectionTests.addSequenceTests(
+  makeSequence: { (elements: [LifetimeTracked]) -> LazyMapSequence<MinimalSequence<LifetimeTracked>, LifetimeTracked> in
+    MinimalSequence(elements: elements).lazy.map { $0 }
+  },
+  wrapValue: { (element: OpaqueValue<Int>) in
+    LifetimeTracked(element.value, identity: element.identity)
+  },
+  extractValue: { (element: LifetimeTracked) in
+    OpaqueValue(element.value, identity: element.identity)
+  },
+  makeSequenceOfEquatable: { (elements: [LifetimeTracked]) -> LazyMapSequence<MinimalSequence<LifetimeTracked>, LifetimeTracked> in
+    MinimalSequence(elements: elements).lazy.map { $0 }
+  },
+  wrapValueIntoEquatable: { (element: MinimalEquatableValue) in
+    LifetimeTracked(element.value, identity: element.identity)
+  },
+  extractValueFromEquatable: { (element: LifetimeTracked) in
+    MinimalEquatableValue(element.value, identity: element.identity)
+  }
+)
+
+// Test sequence instances and iterators.
+CollectionTests.test("LazyMapCollection instances (Sequence)") {
+  do {
+    let expected = ["convent", "conform", "constrict", "condone"]
+    let base = ["vent", "form", "strict", "done"]
+    checkSequence(
+      expected,
+      MinimalSequence(elements: base).lazy.map { "con" + $0 })
+  }
+  do {
+    let expected = [1, 4, 9, 16, 25, 36, 49, 64]
+    let base = [1, 2, 3, 4, 5, 6, 7, 8]
+    checkSequence(
+      expected,
+      MinimalSequence(elements: base).lazy.map { $0 * $0 })
+  }
+}
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Collection/MinimalBidirectionalCollection.swift b/validation-test/stdlib/Collection/MinimalBidirectionalCollection.swift
index d4f96ab..64c4661 100644
--- a/validation-test/stdlib/Collection/MinimalBidirectionalCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalBidirectionalCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addBidirectionalCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalBidirectionalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalBidirectionalCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalBidirectionalCollectionOfRef.swift
new file mode 100644
index 0000000..dd0283c
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalBidirectionalCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addBidirectionalCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalBidirectionalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalCollection.swift b/validation-test/stdlib/Collection/MinimalCollection.swift
index 2c60dd3..db40482 100644
--- a/validation-test/stdlib/Collection/MinimalCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalCollectionOfRef.swift
new file mode 100644
index 0000000..bf2d796
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalMutableBidirectionalCollection.swift b/validation-test/stdlib/Collection/MinimalMutableBidirectionalCollection.swift
index 0a574cf..974d6ae 100644
--- a/validation-test/stdlib/Collection/MinimalMutableBidirectionalCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalMutableBidirectionalCollection.swift
@@ -40,37 +40,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addMutableBidirectionalCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalMutableBidirectionalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalMutableBidirectionalCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalMutableBidirectionalCollectionOfRef.swift
new file mode 100644
index 0000000..d1b15a8
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalMutableBidirectionalCollectionOfRef.swift
@@ -0,0 +1,49 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addMutableBidirectionalCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalMutableBidirectionalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalMutableCollection.swift b/validation-test/stdlib/Collection/MinimalMutableCollection.swift
index 210fbd0..a5bc7ed 100644
--- a/validation-test/stdlib/Collection/MinimalMutableCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalMutableCollection.swift
@@ -40,37 +40,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addMutableCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalMutableCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalMutableCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalMutableCollectionOfRef.swift
new file mode 100644
index 0000000..7aad615
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalMutableCollectionOfRef.swift
@@ -0,0 +1,49 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addMutableCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalMutableCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalMutableRandomAccessCollection.swift b/validation-test/stdlib/Collection/MinimalMutableRandomAccessCollection.swift
index c8bf255..e09a58f 100644
--- a/validation-test/stdlib/Collection/MinimalMutableRandomAccessCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalMutableRandomAccessCollection.swift
@@ -40,37 +40,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addMutableRandomAccessCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalMutableRandomAccessCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalMutableRandomAccessCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalMutableRandomAccessCollectionOfRef.swift
new file mode 100644
index 0000000..0e5446c
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalMutableRandomAccessCollectionOfRef.swift
@@ -0,0 +1,49 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addMutableRandomAccessCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalMutableRandomAccessCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableBidirectionalCollection.swift b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableBidirectionalCollection.swift
index f3111d4..c2f3d07 100644
--- a/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableBidirectionalCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableBidirectionalCollection.swift
@@ -53,55 +53,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableBidirectionalCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-  CollectionTests.addMutableBidirectionalCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableBidirectionalCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableBidirectionalCollectionOfRef.swift
new file mode 100644
index 0000000..de60215
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableBidirectionalCollectionOfRef.swift
@@ -0,0 +1,67 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableBidirectionalCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+  CollectionTests.addMutableBidirectionalCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableCollection.swift b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableCollection.swift
index ce91b58..b428246 100644
--- a/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableCollection.swift
@@ -53,55 +53,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalMutableRangeReplaceableCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRangeReplaceableCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-  CollectionTests.addMutableCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalMutableRangeReplaceableCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRangeReplaceableCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRangeReplaceableCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableCollectionOfRef.swift
new file mode 100644
index 0000000..72f3387
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableCollectionOfRef.swift
@@ -0,0 +1,67 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalMutableRangeReplaceableCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRangeReplaceableCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+  CollectionTests.addMutableCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalMutableRangeReplaceableCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRangeReplaceableCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRangeReplaceableCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableRandomAccessCollection.swift b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableRandomAccessCollection.swift
index 99c66b3..fea9f13 100644
--- a/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableRandomAccessCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableRandomAccessCollection.swift
@@ -53,55 +53,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableRandomAccessCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-  CollectionTests.addMutableRandomAccessCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks
-    , withUnsafeMutableBufferPointerIsSupported: false,
-    isFixedLengthCollection: true
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableRandomAccessCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableRandomAccessCollectionOfRef.swift
new file mode 100644
index 0000000..5e07b6b
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalMutableRangeReplaceableRandomAccessCollectionOfRef.swift
@@ -0,0 +1,67 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableRandomAccessCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+  CollectionTests.addMutableRandomAccessCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalMutableRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks
+    , withUnsafeMutableBufferPointerIsSupported: false,
+    isFixedLengthCollection: true
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalRandomAccessCollection.swift b/validation-test/stdlib/Collection/MinimalRandomAccessCollection.swift
index dac81da..35c402c 100644
--- a/validation-test/stdlib/Collection/MinimalRandomAccessCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalRandomAccessCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRandomAccessCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalRandomAccessCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalRandomAccessCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalRandomAccessCollectionOfRef.swift
new file mode 100644
index 0000000..5de44c7
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalRandomAccessCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRandomAccessCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalRandomAccessCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalRangeReplaceableBidirectionalCollection.swift b/validation-test/stdlib/Collection/MinimalRangeReplaceableBidirectionalCollection.swift
index 18c8d2e..6b2e34a 100644
--- a/validation-test/stdlib/Collection/MinimalRangeReplaceableBidirectionalCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalRangeReplaceableBidirectionalCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableBidirectionalCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalRangeReplaceableBidirectionalCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalRangeReplaceableBidirectionalCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalRangeReplaceableBidirectionalCollectionOfRef.swift
new file mode 100644
index 0000000..6523ecc
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalRangeReplaceableBidirectionalCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableBidirectionalCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalRangeReplaceableBidirectionalCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalRangeReplaceableCollection.swift b/validation-test/stdlib/Collection/MinimalRangeReplaceableCollection.swift
index a009e4c..d6b16da 100644
--- a/validation-test/stdlib/Collection/MinimalRangeReplaceableCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalRangeReplaceableCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalRangeReplaceableCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalRangeReplaceableCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalRangeReplaceableCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalRangeReplaceableCollectionOfRef.swift
new file mode 100644
index 0000000..16be8c0
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalRangeReplaceableCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalRangeReplaceableCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalRangeReplaceableCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/Collection/MinimalRangeReplaceableRandomAccessCollection.swift b/validation-test/stdlib/Collection/MinimalRangeReplaceableRandomAccessCollection.swift
index 72e4f6d..37c9f05 100644
--- a/validation-test/stdlib/Collection/MinimalRangeReplaceableRandomAccessCollection.swift
+++ b/validation-test/stdlib/Collection/MinimalRangeReplaceableRandomAccessCollection.swift
@@ -33,29 +33,6 @@
   )
 }
 
-// Test collections using a reference type as element.
-do {
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
-
-  CollectionTests.addRangeReplaceableRandomAccessCollectionTests(
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return MinimalRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return MinimalRangeReplaceableRandomAccessCollection(elements: elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks
-  )
-}
-
 runAllTests()
+
+
diff --git a/validation-test/stdlib/Collection/MinimalRangeReplaceableRandomAccessCollectionOfRef.swift b/validation-test/stdlib/Collection/MinimalRangeReplaceableRandomAccessCollectionOfRef.swift
new file mode 100644
index 0000000..c56ba1e
--- /dev/null
+++ b/validation-test/stdlib/Collection/MinimalRangeReplaceableRandomAccessCollectionOfRef.swift
@@ -0,0 +1,41 @@
+// -*- swift -*-
+
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Collection/Inputs/Template.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+var CollectionTests = TestSuite("Collection")
+
+// Test collections using a reference type as element.
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .trap
+
+  CollectionTests.addRangeReplaceableRandomAccessCollectionTests(
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return MinimalRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return MinimalRangeReplaceableRandomAccessCollection(elements: elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks
+  )
+}
+
+runAllTests()
diff --git a/validation-test/stdlib/FixedPoint.swift.gyb b/validation-test/stdlib/FixedPoint.swift.gyb
index eca0aa3..6cecc0c 100644
--- a/validation-test/stdlib/FixedPoint.swift.gyb
+++ b/validation-test/stdlib/FixedPoint.swift.gyb
@@ -327,11 +327,11 @@
 }
 
 FixedPoint.test("OverflowCheck") {
-  expectEqual((partialValue: 9, overflow: .none),
+  expectEqual((partialValue: 9, overflow: false),
     (4 as Int8).addingReportingOverflow(5))
-  expectEqual((partialValue: -128, overflow: .overflow),
+  expectEqual((partialValue: -128, overflow: true),
     (1 as Int8).addingReportingOverflow(127))
-  expectEqual((partialValue: 0, overflow: .overflow),
+  expectEqual((partialValue: 0, overflow: true),
     (2 as UInt8).multipliedReportingOverflow(by: 128))
 }
 
diff --git a/validation-test/stdlib/FixedPointArithmeticTraps.swift.gyb b/validation-test/stdlib/FixedPointArithmeticTraps.swift.gyb
index 4ed2f92..a497b80 100644
--- a/validation-test/stdlib/FixedPointArithmeticTraps.swift.gyb
+++ b/validation-test/stdlib/FixedPointArithmeticTraps.swift.gyb
@@ -15,7 +15,7 @@
 // not folded.
 
 func expectOverflow<T>(
-  _ res: (T, overflow: Bool),
+  _ res: (partialValue: T, overflow: Bool),
   //===--- TRACE boilerplate ----------------------------------------------===//
   _ message: @autoclosure () -> String = "",
     showFrame: Bool = true,
@@ -28,7 +28,7 @@
 }
 
 func expectNoOverflow<T>(
-  _ res: (T, overflow: Bool),
+  _ res: (partialValue: T, overflow: Bool),
   //===--- TRACE boilerplate ----------------------------------------------===//
   _ message: @autoclosure () -> String = "",
     showFrame: Bool = true,
@@ -40,32 +40,6 @@
     stackTrace: stackTrace.pushIf(showFrame, file: file, line: line))
 }
 
-func expectOverflow<T>(
-  _ res: (partialValue: T, overflow: ArithmeticOverflow),
-  //===--- TRACE boilerplate ----------------------------------------------===//
-  _ message: @autoclosure () -> String = "",
-    showFrame: Bool = true,
-    stackTrace: SourceLocStack = SourceLocStack(),
-    file: String = #file, line: UInt = #line
-) {
-  expectTrue(
-    res.overflow == .overflow, "expected overflow",
-    stackTrace: stackTrace.pushIf(showFrame, file: file, line: line))
-}
-
-func expectNoOverflow<T>(
-  _ res: (partialValue: T, overflow: ArithmeticOverflow),
-  //===--- TRACE boilerplate ----------------------------------------------===//
-  _ message: @autoclosure () -> String = "",
-    showFrame: Bool = true,
-    stackTrace: SourceLocStack = SourceLocStack(),
-    file: String = #file, line: UInt = #line
-) {
-  expectTrue(
-    res.overflow == .none, "expected no overflow",
-    stackTrace: stackTrace.pushIf(showFrame, file: file, line: line))
-}
-
 %{
 
 from SwiftIntTypes import all_integer_types
diff --git a/validation-test/stdlib/ModelIO.swift b/validation-test/stdlib/ModelIO.swift
index 815bab1..6272a35 100644
--- a/validation-test/stdlib/ModelIO.swift
+++ b/validation-test/stdlib/ModelIO.swift
@@ -11,28 +11,6 @@
 var ModelIOTests = TestSuite("ModelIO")
 
 if #available(OSX 10.13, iOS 11.0, tvOS 11.0, *) {
-    ModelIOTests.test("MDLSkinDeformer.jointBindTransforms()") {
-        let jointPaths = ["Aa", "Bb", "Cc"]
-        let count = 3
-        let jointTransforms = [matrix_float4x4](repeating: matrix_identity_float4x4, count: count)
-        let meshBindTransform = matrix_identity_float4x4
-        let skinDeformer = MDLSkinDeformer(jointPaths: jointPaths,
-                                           jointBindTransforms: jointTransforms,
-                                           count: count,
-                                           meshBindTransform: meshBindTransform)
-        let jointBindTransforms = skinDeformer.jointBindTransforms()
-
-        expectEqual(jointBindTransforms.count, count)
-        for (bindIdx, jointBindTransform) in jointBindTransforms.enumerated() {
-            for idx in 0..<4 {
-                expectEqual(jointBindTransform[idx].x, jointTransforms[bindIdx][idx].x)
-                expectEqual(jointBindTransform[idx].y, jointTransforms[bindIdx][idx].y)
-                expectEqual(jointBindTransform[idx].z, jointTransforms[bindIdx][idx].z)
-                expectEqual(jointBindTransform[idx].w, jointTransforms[bindIdx][idx].w)
-            }
-        }
-    }
-
     ModelIOTests.test("MDLAnimatedScalar/accessors") {
         let animatedVal = MDLAnimatedScalar()
         let testCount = 10
@@ -40,37 +18,13 @@
         let testFloatVal:Float = 1.0
         let testDoubleVal = Double(testFloatVal)
         let fArray = [Float](repeating: testFloatVal, count: testCount)
+        let dArray = [Double](repeating: testDoubleVal, count: testCount)
         var times = [TimeInterval](repeating: testTimeVal, count: testCount)
-        animatedVal.reset(withFloatArray: fArray, atTimes: times, count: testCount)
-
-        let floats = animatedVal.getFloatArray()
-        let doubles = animatedVal.getDoubleArray()
-        times = animatedVal.getTimes()
-
-        expectEqual(floats.count, testCount)
-        expectEqual(doubles.count, testCount)
-        expectEqual(times.count, testCount)
-
-        for idx in 0..<testCount {
-            expectEqual(floats[idx], testFloatVal)
-            expectEqual(doubles[idx], testDoubleVal)
-            expectEqual(times[idx], testTimeVal)
-        }
-    }
-
-    ModelIOTests.test("MDLAnimatedScalar/accessors") {
-        let animatedVal = MDLAnimatedScalar()
-        let testCount = 10
-        let testTimeVal = 5.0
-        let testFloatVal:Float = 1.0
-        let testDoubleVal = Double(testFloatVal)
-        let fArray = [Float](repeating: testFloatVal, count: testCount)
-        var times = [TimeInterval](repeating: testTimeVal, count: testCount)
-        animatedVal.reset(withFloatArray: fArray, atTimes: times, count: testCount)
-
-        let floats = animatedVal.getFloatArray()
-        let doubles = animatedVal.getDoubleArray()
-        times = animatedVal.getTimes()
+        animatedVal.reset(floatArray: fArray, atTimes: times)
+        let floats = animatedVal.floatArray
+        animatedVal.reset(doubleArray: dArray, atTimes: times)
+        let doubles = animatedVal.doubleArray
+        times = animatedVal.times
 
         expectEqual(floats.count, testCount)
         expectEqual(doubles.count, testCount)
@@ -90,12 +44,14 @@
         let testFloatVal = float2(1.0, 2.0)
         let testDoubleVal = double2(Double(testFloatVal.x), Double(testFloatVal.y))
         let fArray = [float2](repeating: testFloatVal, count: testCount)
+        let dArray = [double2](repeating: testDoubleVal, count: testCount)
         var times = [TimeInterval](repeating: testTimeVal, count: testCount)
-        animatedVal.reset(withFloat2Array: fArray, atTimes: times, count: testCount)
+        animatedVal.reset(float2Array: fArray, atTimes: times)
 
-        let floats = animatedVal.getFloat2Array()
-        let doubles = animatedVal.getDouble2Array()
-        times = animatedVal.getTimes()
+        let floats = animatedVal.float2Array
+        animatedVal.reset(double2Array: dArray, atTimes: times)
+        let doubles = animatedVal.double2Array
+        times = animatedVal.times
 
         expectEqual(floats.count, testCount)
         expectEqual(doubles.count, testCount)
@@ -117,12 +73,14 @@
         let testFloatVal = float3(1.0, 2.0, 3.0)
         let testDoubleVal = double3(Double(testFloatVal.x), Double(testFloatVal.y), Double(testFloatVal.z))
         let fArray = [float3](repeating: testFloatVal, count: testCount)
+        let dArray = [double3](repeating: testDoubleVal, count: testCount)
         var times = [TimeInterval](repeating: testTimeVal, count: testCount)
-        animatedVal.reset(withFloat3Array: fArray, atTimes: times, count: testCount)
+        animatedVal.reset(float3Array: fArray, atTimes: times)
 
-        let floats = animatedVal.getFloat3Array()
-        let doubles = animatedVal.getDouble3Array()
-        times = animatedVal.getTimes()
+        let floats = animatedVal.float3Array
+        animatedVal.reset(double3Array: dArray, atTimes: times)
+        let doubles = animatedVal.double3Array
+        times = animatedVal.times
 
         expectEqual(floats.count, testCount)
         expectEqual(doubles.count, testCount)
@@ -146,12 +104,14 @@
         let testFloatVal = float4(1.0, 2.0, 3.0, 4.0)
         let testDoubleVal = double4(Double(testFloatVal.x), Double(testFloatVal.y), Double(testFloatVal.z), Double(testFloatVal.w))
         let fArray = [float4](repeating: testFloatVal, count: testCount)
+        let dArray = [double4](repeating: testDoubleVal, count: testCount)
         var times = [TimeInterval](repeating: testTimeVal, count: testCount)
-        animatedVal.reset(withFloat4Array: fArray, atTimes: times, count: testCount)
+        animatedVal.reset(float4Array: fArray, atTimes: times)
 
-        let floats = animatedVal.getFloat4Array()
-        let doubles = animatedVal.getDouble4Array()
-        times = animatedVal.getTimes()
+        let floats = animatedVal.float4Array
+        animatedVal.reset(double4Array: dArray, atTimes: times)
+        let doubles = animatedVal.double4Array
+        times = animatedVal.times
 
         expectEqual(floats.count, testCount)
         expectEqual(doubles.count, testCount)
@@ -177,12 +137,14 @@
         let testFloatVal = matrix_identity_float4x4
         let testDoubleVal = matrix_identity_double4x4
         let fArray = [float4x4](repeating: testFloatVal, count: testCount)
+        let dArray = [double4x4](repeating: testDoubleVal, count: testCount)
         var times = [TimeInterval](repeating: testTimeVal, count: testCount)
-        animatedVal.reset(withFloat4x4Array: fArray, atTimes: times, count: testCount)
+        animatedVal.reset(float4x4Array: fArray, atTimes: times)
 
-        let floats = animatedVal.getFloat4x4Array()
-        let doubles = animatedVal.getDouble4x4Array()
-        times = animatedVal.getTimes()
+        let floats = animatedVal.float4x4Array
+        animatedVal.reset(double4Array: dArray, atTimes: times)
+        let doubles = animatedVal.double4x4Array
+        times = animatedVal.times
 
         expectEqual(floats.count, testCount)
         expectEqual(doubles.count, testCount)
@@ -203,30 +165,157 @@
         }
     }
 
-    ModelIOTests.test("MDLAnimatedScalarArray/accessors") {
-        let elementsCount = 10
-        let animatedVal = MDLAnimatedScalarArray(name: "test", elementsCount: elementsCount)
+    ModelIOTests.test("MDLMatrix4x4Array/accessors") {
         let testCount = 10
-        let totalCount = elementsCount * testCount
+        let matrixArray = MDLMatrix4x4Array(elementCount: testCount)
+        let testFloatVal = float4x4()
+        let testDoubleVal = double4x4()
+        let fArray = [float4x4](repeating: testFloatVal, count: testCount)
+        let dArray = [double4x4](repeating: testDoubleVal, count: testCount)
+        matrixArray.float4x4Array = fArray
+
+        let floats = matrixArray.float4x4Array
+        matrixArray.double4x4Array = dArray
+        let doubles = matrixArray.double4x4Array
+
+        expectEqual(floats.count, testCount)
+        expectEqual(doubles.count, testCount)
+
+        for idx in 0..<testCount {
+            for matIdx in 0..<4 {
+                expectEqual(floats[idx][matIdx].x, testFloatVal[matIdx].x)
+                expectEqual(floats[idx][matIdx].y, testFloatVal[matIdx].y)
+                expectEqual(floats[idx][matIdx].z, testFloatVal[matIdx].z)
+                expectEqual(floats[idx][matIdx].w, testFloatVal[matIdx].w)
+                expectEqual(doubles[idx][matIdx].x, testDoubleVal[matIdx].x)
+                expectEqual(doubles[idx][matIdx].y, testDoubleVal[matIdx].y)
+                expectEqual(doubles[idx][matIdx].z, testDoubleVal[matIdx].z)
+                expectEqual(doubles[idx][matIdx].w, testDoubleVal[matIdx].w)
+            }
+        }
+    }
+
+    ModelIOTests.test("MDLAnimatedScalarArray/accessors") {
+        let elementCount = 10
+        let animatedVal = MDLAnimatedScalarArray(elementCount: elementCount)
+        let subCount = 2
+        let testCount = 10
+        let totalCount = elementCount * testCount
         let testTimeVal = 5.0
         let testFloatVal:Float = 10.0
+        let testSubFloatVal:Float = 5.0
         let testDoubleVal = Double(testFloatVal)
+        let testSubDoubleVal = Double(testSubFloatVal)
         let fArray = [Float](repeating: testFloatVal, count: totalCount)
+        let _ = [Float](repeating: testSubFloatVal, count: subCount)
+        let dArray = [Double](repeating: testDoubleVal, count: totalCount)
+        let _ = [Double](repeating: testSubDoubleVal, count: subCount)
         var times = [TimeInterval](repeating: testTimeVal, count: testCount)
-        animatedVal.reset(with: fArray, count: totalCount, atTimes: times, count: testCount)
+        animatedVal.reset(floatArray: fArray, atTimes: times)
 
-        let floats = animatedVal.getFloatArrays()
-        let doubles = animatedVal.getDoubleArrays()
-        times = animatedVal.getTimes()
+        let floats = animatedVal.floatArray
+        // reset is currently appending instead of resetting the time sampled data
+        //animatedVal.reset(doubleArray: dArray, atTimes: times)
+        let doubles = animatedVal.doubleArray
+        let sampledFloatArray = animatedVal.floatArray(atTime: 5.0)
+        let sampledDoubleArray = animatedVal.doubleArray(atTime: 5.0)
+        times = animatedVal.times
 
         expectEqual(floats.count, totalCount)
         expectEqual(doubles.count, totalCount)
         expectEqual(times.count, testCount)
 
         for idx in 0..<testCount {
-            for arrIdx in 0..<elementsCount {
-                expectEqual(floats[idx * elementsCount + arrIdx], testFloatVal)
-                expectEqual(doubles[idx * elementsCount + arrIdx], testDoubleVal)
+            // -- test a sampled time
+            expectEqual(sampledFloatArray[idx], testFloatVal)
+            expectEqual(sampledDoubleArray[idx], testDoubleVal)
+
+            // -- for each time test the arrays
+            for arrIdx in 0..<elementCount {
+                expectEqual(floats[idx * elementCount + arrIdx], testFloatVal)
+                expectEqual(doubles[idx * elementCount + arrIdx], testDoubleVal)
+            }
+            expectEqual(times[idx], testTimeVal)
+        }
+    }
+
+    ModelIOTests.test("MDLAnimatedQuaternionArray/accessors") {
+        let elementCount = 10
+        let testCount = 10
+        let totalCount = elementCount * testCount
+        let animatedVal = MDLAnimatedQuaternionArray(elementCount: elementCount)
+        let testTimeVal = 5.0;
+        let testFloatVal = simd_quatf(ix: 1.0, iy: 2.0, iz: 3.0, r: 4.0)
+        let testDoubleVal = simd_quatd(ix: 1.0, iy: 2.0, iz: 3.0, r: 4.0)
+        let fArray = [simd_quatf](repeating: testFloatVal, count: totalCount)
+        let dArray = [simd_quatd](repeating: testDoubleVal, count: totalCount)
+        var times = [TimeInterval](repeating: testTimeVal, count: testCount)
+        animatedVal.reset(floatQuaternionArray: fArray, atTimes: times)
+
+        let quatFloats = animatedVal.floatQuaternionArray
+        // reset is appending instead of reseting the time sampled data
+        //animatedVal.reset(doubleQuaternionArray: dArray, atTimes: times)
+        let quatDoubles = animatedVal.doubleQuaternionArray
+        let sampledFloatQuaternionArray = animatedVal.floatQuaternionArray(atTime: 5.0)
+        let sampledDoubleQuaternionArray = animatedVal.doubleQuaternionArray(atTime: 5.0)
+        times = animatedVal.times
+
+        expectEqual(quatFloats.count, totalCount)
+        expectEqual(quatDoubles.count, totalCount)
+        expectEqual(times.count, testCount)
+
+        for idx in 0..<testCount {
+            // -- test a sampled time
+            // -- data gets swizzled somewhere between getting and setting so we just
+            // -- check to make sure we can at least access the data
+            sampledFloatQuaternionArray[idx]
+            sampledDoubleQuaternionArray[idx]
+            /*expectEqual(sampledFloatQuaternionArray[idx], testFloatVal)
+            expectEqual(sampledDoubleQuaternionArray[idx], testDoubleVal)
+
+            // -- for each time test the arrays
+            for arrIdx in 0..<elementCount {
+                expectEqual(quatFloats[idx * elementCount + arrIdx], testFloatVal)
+                expectEqual(quatDoubles[idx * elementCount + arrIdx], testDoubleVal)
+            }*/
+            expectEqual(times[idx], testTimeVal)
+        }
+    }
+
+    ModelIOTests.test("MDLAnimatedVector3Array/accessors") {
+        let elementCount = 10
+        let animatedVal = MDLAnimatedVector3Array(elementCount: elementCount)
+        let testCount = 10
+        let totalCount = elementCount * testCount
+        let testTimeVal = 5.0
+        let testFloatVal = float3(1.0, 2.0, 3.0)
+        let testDoubleVal = double3(1.0, 2.0, 3.0)
+        let fArray = [float3](repeating: testFloatVal, count: totalCount)
+        let dArray = [double3](repeating: testDoubleVal, count: totalCount)
+        var times = [TimeInterval](repeating: testTimeVal, count: testCount)
+        animatedVal.reset(float3Array: fArray, atTimes: times)
+
+        let vector3Floats = animatedVal.float3Array
+        // reset is appending  instead reseting the time sampled data
+        //animatedVal.reset(double3Array: dArray, atTimes: times)
+        let vector3Doubles = animatedVal.double3Array
+        let sampledFloatVector3Array = animatedVal.float3Array(atTime: 5.0)
+        let sampledDoubleVector3Array = animatedVal.double3Array(atTime: 5.0)
+        times = animatedVal.times
+
+        expectEqual(vector3Floats.count, totalCount)
+        expectEqual(vector3Doubles.count, totalCount)
+        expectEqual(times.count, testCount)
+
+        for idx in 0..<testCount {
+            // -- test a sampled time
+            expectEqual(sampledFloatVector3Array[idx], testFloatVal)
+            expectEqual(sampledDoubleVector3Array[idx], testDoubleVal)
+
+            // -- for each time test the arrays
+            for arrIdx in 0..<elementCount {
+                expectEqual(vector3Floats[idx * elementCount + arrIdx], testFloatVal)
+                expectEqual(vector3Doubles[idx * elementCount + arrIdx], testDoubleVal)
             }
             expectEqual(times[idx], testTimeVal)
         }
diff --git a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
index 0e0910d..cedd736 100644
--- a/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
+++ b/validation-test/stdlib/Prototypes/PersistentVector.swift.gyb
@@ -217,7 +217,7 @@
 %   if underlyingType == 'UInt':
       let iAsUnderlyingType = UInt(bitPattern: i)
 %   elif underlyingType == 'UInt32':
-      let iAsUnderlyingType = UInt32(extendingOrTruncating: i)
+      let iAsUnderlyingType = UInt32(truncatingIfNeeded: i)
 %   end
       _bits =
         (_bits & ~(1 << iAsUnderlyingType))
@@ -230,7 +230,7 @@
 %   if underlyingType == 'UInt':
       let iAsUnderlyingType = UInt(bitPattern: i)
 %   elif underlyingType == 'UInt32':
-      let iAsUnderlyingType = UInt32(extendingOrTruncating: i)
+      let iAsUnderlyingType = UInt32(truncatingIfNeeded: i)
 %   end
     let lowBits = _bits & ((1 << iAsUnderlyingType) - 1)
     return _${name}Bitmap(_bits: lowBits).setBitCount
diff --git a/validation-test/stdlib/String.swift b/validation-test/stdlib/String.swift
index 3c67908..0e0b4aa 100644
--- a/validation-test/stdlib/String.swift
+++ b/validation-test/stdlib/String.swift
@@ -59,7 +59,7 @@
   expectCollectionAssociatedTypes(
     collectionType: View.self,
     iteratorType: View.Iterator.self,
-    subSequenceType: BidirectionalSlice<View>.self,
+    subSequenceType: Substring.UTF8View.self,
     indexType: View.Index.self,
     indexDistanceType: Int.self,
     indicesType: DefaultBidirectionalIndices<View>.self)
@@ -70,7 +70,7 @@
   expectCollectionAssociatedTypes(
     collectionType: View.self,
     iteratorType: IndexingIterator<View>.self,
-    subSequenceType: View.self,
+    subSequenceType: Substring.UTF16View.self,
     indexType: View.Index.self,
     indexDistanceType: Int.self,
     indicesType: View.Indices.self)
@@ -81,7 +81,7 @@
   expectCollectionAssociatedTypes(
     collectionType: View.self,
     iteratorType: View.Iterator.self,
-    subSequenceType: View.self,
+    subSequenceType: Substring.UnicodeScalarView.self,
     indexType: View.Index.self,
     indexDistanceType: Int.self,
     indicesType: DefaultBidirectionalIndices<View>.self)
@@ -466,7 +466,7 @@
   }
 
   do {
-    var (s, unused) = { ()->(String, Int) in
+    var (s, _) = { ()->(String, Int) in
       let (s0, unused) = stringWithUnusedCapacity()
       return (s0[s0.index(_nth: 5)..<s0.endIndex], unused)
     }()
@@ -478,7 +478,7 @@
   }
 
   do {
-    var (s, unused) = { ()->(Substring, Int) in
+    var (s, _) = { ()->(Substring, Int) in
       let (s0, unused) = stringWithUnusedCapacity()
       return (s0[s0.index(_nth: 5)..<s0.endIndex], unused)
     }()
@@ -503,6 +503,7 @@
     expectEqual(originalID, s.bufferID)
     s += "."
     expectNotEqual(originalID, s.bufferID)
+    unused += 0 // warning suppression
   }
 }
 
@@ -640,7 +641,7 @@
 StringTests.test("COW/replaceSubrange/end") {
   // Check literal-to-heap reallocation.
   do {
-    var str = "12345678"
+    let str = "12345678"
     let literalIdentity = str.bufferID
 
     var slice = str[str.startIndex..<str.index(_nth: 7)]
@@ -772,7 +773,7 @@
     }
     expectEqual(!base._core.hasCocoaBuffer, startedNative)
     
-    var originalBuffer = base.bufferID
+    let originalBuffer = base.bufferID
     let startedUnique = startedNative && base._core._owner != nil
       && isKnownUniquelyReferenced(&base._core._owner!)
     
@@ -975,10 +976,11 @@
   var s = ""
   var s2 = s
 
-  for i in 0..<20 {
+  for _ in 0..<20 {
     s += "x"
     s2 = s
   }
+  expectEqual(s2, s)
   expectLE(s.nativeCapacity, 34)
 }
 
@@ -988,20 +990,20 @@
 
 StringTests.test("Conversions") {
   do {
-    var c: Character = "a"
+    let c: Character = "a"
     let x = String(c)
     expectTrue(x._core.isASCII)
 
-    var s: String = "a"
+    let s: String = "a"
     expectEqual(s, x)
   }
 
   do {
-    var c: Character = "\u{B977}"
+    let c: Character = "\u{B977}"
     let x = String(c)
     expectFalse(x._core.isASCII)
 
-    var s: String = "\u{B977}"
+    let s: String = "\u{B977}"
     expectEqual(s, x)
   }
 }
diff --git a/validation-test/stdlib/StringViews.swift b/validation-test/stdlib/StringViews.swift
index 9cd1576..2e5b049 100644
--- a/validation-test/stdlib/StringViews.swift
+++ b/validation-test/stdlib/StringViews.swift
@@ -687,6 +687,8 @@
           continue
         }
       }
+      // This tests for the Swift 3 semantics, which don't match the documented
+      // semantics!
       expectNil(String(v[i..<j]))
     }
   }
@@ -695,14 +697,20 @@
 tests.test("UTF8->String") {
   let s = summer + winter + winter + summer
   let v = s.utf8
+
   for i in v.indices {
     for j in v.indices[i..<v.endIndex] {
       if let si = i.samePosition(in: s) {
         if let sj = j.samePosition(in: s) {
-          expectEqual(s[si..<sj], String(v[i..<j])!)
+          expectEqual(
+            s[si..<sj], String(v[i..<j])!,
+            "\(String(reflecting: s))[\n  \(si..<sj)\n] != String(\n  \(String(reflecting: v))[\n    \(i..<j)\n  ])!"
+          )
           continue
         }
       }
+      // This tests for the Swift 3 semantics, which don't match the documented
+      // semantics!
       expectNil(String(v[i..<j]))
     }
   }
diff --git a/validation-test/stdlib/XCTest.swift b/validation-test/stdlib/XCTest.swift
index da6dda6..59d683e 100644
--- a/validation-test/stdlib/XCTest.swift
+++ b/validation-test/stdlib/XCTest.swift
@@ -1,4 +1,7 @@
-// RUN: %target-run-stdlib-swift
+// RUN: rm -rf %t ; mkdir -p %t
+// RUN: %target-build-swift %s -o %t/a.out3 -swift-version 3 && %target-run %t/a.out3
+// RUN: %target-build-swift %s -o %t/a.out4 -swift-version 4 && %target-run %t/a.out4
+
 // REQUIRES: executable_test
 // REQUIRES: objc_interop
 
@@ -20,20 +23,35 @@
 
 func execute(observers: [XCTestObservation] = [], _ run: () -> Void) {
   for observer in observers {
+#if swift(>=4.0)
+    XCTestObservationCenter.shared.addTestObserver(observer)
+#else
     XCTestObservationCenter.shared().addTestObserver(observer)
+#endif
+
   }
 
   run()
 
   for observer in observers {
+#if swift(>=4.0)
+    XCTestObservationCenter.shared.removeTestObserver(observer)
+#else
     XCTestObservationCenter.shared().removeTestObserver(observer)
+#endif
   }
 }
 
 class FailureDescriptionObserver: NSObject, XCTestObservation {
   var failureDescription: String?
 
-  func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: UInt) {
+#if swift(>=4.0)
+  typealias LineNumber=Int
+#else
+  typealias LineNumber=UInt
+#endif
+
+  func testCase(_ testCase: XCTestCase, didFailWithDescription description: String, inFile filePath: String?, atLine lineNumber: LineNumber) {
     failureDescription = description
   }
 }
@@ -463,7 +481,7 @@
 XCTestTestSuite.test("XCTContext/runActivity(named:block:)") {
   class RunActivityTestCase: XCTestCase {
 
-    dynamic func test_noThrow() {
+    dynamic func test_noThrow_void() {
       var blockCalled = false
       XCTContext.runActivity(named: "noThrow") { activity in
         blockCalled = true
@@ -471,6 +489,16 @@
       expectTrue(blockCalled)
     }
 
+    dynamic func test_noThrow_returns_string() {
+      var blockCalled = false
+      let value = XCTContext.runActivity(named: "noThrow") { activity -> String in
+        blockCalled = true
+        return "Activities can return values now!"
+      }
+      expectEqual(value, "Activities can return values now!")
+      expectTrue(blockCalled)
+    }
+
     dynamic func test_throwing() {
       var blockCalled = false
       var catchCalled = false
@@ -488,6 +516,25 @@
   }
 }
 
+#if os(macOS)
+if #available(macOS 10.11, *) {
+    XCTestTestSuite.test("XCUIElement/typeKey(_:modifierFlags:)") {
+        class TypeKeyTestCase: XCTestCase {
+            func testTypeKey() {
+                #if swift(>=4.0)
+                    XCUIApplication().typeKey("a", modifierFlags: [])
+                    XCUIApplication().typeKey(.delete, modifierFlags: [])
+                #else
+                    XCUIApplication().typeKey("a", modifierFlags: [])
+                    XCUIApplication().typeKey(XCUIKeyboardKeyDelete, modifierFlags: [])
+                #endif
+            }
+        }
+    }
+}
+#endif
+
 
 runAllTests()
 
+