Merge pull request #21421 from harlanhaskins/oops-indeed-5.0

[5.0] [TBDGen] Allow #warning/#error in protocols
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7e4ce32..80380e6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,12 +23,49 @@
 
 Swift 5.0
 ---------
+
+* Swift 3 mode has been removed. Supported values for the `-swift-version`
+  flag are `4`, `4.2`, and `5`.
+
+* [SE-0228][]:
+
+  String interpolation has been overhauled to improve its performance,
+  clarity, and efficiency.
+
+  Note that the old `_ExpressibleByStringInterpolation` protocol has been
+  removed; any code making use of this protocol will need to be updated
+  for the new design. An `#if compiler` block can be used to conditionalize
+  code between 4.2 and 5.0, for example:
+  
+  ```swift
+  #if compiler(<5.0)
+  extension MyType : _ExpressibleByStringInterpolation { ... }
+  #else
+  extension MyType : ExpressibleByStringInterpolation { ... }
+  #endif
+  ```
+
+* [SE-0213][]:
+
+  If `T` conforms to one of the `ExpressibleBy*` protocols and `literal` is a
+  literal expression, then `T(literal)` will construct a literal of type `T`
+  using the corresponding protocol, rather than calling a constructor member
+  of `T` with a value of  the protocol's default literal type.
+
+  For example, expressions like `UInt64(0xffff_ffff_ffff_ffff)` are now valid,
+  where previously they would overflow the default integer literal type of `Int`.
+
+* [SE-0230][]:
+
+  In Swift 5 mode, `try?` with an expression of Optional type will flatten the
+  resulting Optional, instead of returning an Optional of an Optional.
+
 * [SR-5719][]:
 
-  Starting from `-swift-version 5`, implicit `@autoclosure` function type
-  forwarding has been disabled, and new a diagnostic has been added suggesting
-  to add `()` to call the function value in such case. The call itself would be
-  wrapped in an implicit closure and passed to the corresponding parameter.
+  In Swift 5 mode, `@autoclosure` parameters can no longer be forwarded to
+  `@autoclosure` arguments in another function call. Instead, you must explicitly
+  call the function value with `()`; the call itself is wrapped inside an
+  implicit closure, guaranteeing the same behavior as in Swift 4 mode.
 
   Example:
 
@@ -40,6 +77,56 @@
   }
   ```
 
+* [SR-8109][]:
+
+  Single-element labeled tuple expressions, for example `(label: 123)`, were
+  allowed in some contexts but often resulted in surprising, inconsistent
+  behavior that varied across compiler releases. They are now completely
+  disallowed.
+
+  Note that single-element labeled _types_, for example `var x: (label: Int)`,
+  have already been prohibited since Swift 3.
+
+* [SR-695][]:
+
+  In Swift 5 mode, a class method returning `Self` can no longer be overridden
+  with a method returning a non-final concrete class type. Such code is not
+  type safe and will need to be updated.
+
+  For example,
+
+  ```swift
+  class Base {
+    class func factory() -> Self { ... }
+  }
+
+  class Derived : Base {
+    class override func factory() -> Derived { ... }
+  }
+  ```
+
+* In Swift 5 mode, the type of `self` in a convenience initializer of a non-final
+  class is now the dynamic `Self` type, and not the concrete class type.
+
+* [SR-5581][]:
+
+  Protocols can now constrain their conforming types to those that subclasses a
+  given class. Two equivalent forms are supported:
+
+  ```swift
+  protocol MyView : UIView { ... }
+  protocol MyView where Self : UIView { ... }
+  ```
+
+  Note that Swift 4.2 accepted the second form, but it was not fully implemented
+  and could sometimes crash at compile time or run time.
+
+* [SR-631][]:
+
+  Extension binding now supports extensions of nested types which themselves are
+  defined inside extensions. Previously this could fail with some declaration orders,
+  producing spurious "undeclared type" errors.
+
 * [SR-7139][]:
 
   Exclusive memory access is now enforced at runtime by default in
@@ -129,7 +216,7 @@
 
 * [SE-0214][]:
 
-  Renamed the `DictionaryLiteral` type to `KeyValuePairs`.
+  The `DictionaryLiteral` type has been renamed to `KeyValuePairs`.
   A typealias preserves the old name for compatibility.
 
 * [SR-2608][]
@@ -137,8 +224,16 @@
   Default arguments are now printed in SourceKit-generated interfaces for Swift
   modules, instead of just using a placeholder `default`.
 
-* Notable bug fix: unowned and unowned(unsafe) variables now support optional
-  types.
+* `unowned` and `unowned(unsafe)` variables now support Optional types.
+
+* Designated initializers with variadic parameters are now correctly inherited
+  in subclasses.
+
+* Extensions of concrete subclasses of generic classes can now contain
+  `@objc` members.
+
+* Complex recursive type definitions involving classes and generics that would
+  previously cause deadlocks at run time are now fully supported.
 
 * [SR-419][]
 
@@ -7309,9 +7404,13 @@
 [SE-0225]: <https://github.com/apple/swift-evolution/blob/master/proposals/0225-binaryinteger-iseven-isodd-ismultiple.md>
 [SE-0226]: <https://github.com/apple/swift-evolution/blob/master/proposals/0226-package-manager-target-based-dep-resolution.md>
 [SE-0227]: <https://github.com/apple/swift-evolution/blob/master/proposals/0227-identity-keypath.md>
+[SE-0228]: <https://github.com/apple/swift-evolution/blob/master/proposals/0228-fix-expressiblebystringinterpolation.md>
+[SE-0230]: <https://github.com/apple/swift-evolution/blob/master/proposals/0230-flatten-optional-try.md>
 
 [SR-106]: <https://bugs.swift.org/browse/SR-106>
 [SR-419]: <https://bugs.swift.org/browse/SR-419>
+[SR-631]: <https://bugs.swift.org/browse/SR-631>
+[SR-695]: <https://bugs.swift.org/browse/SR-695>
 [SR-1009]: <https://bugs.swift.org/browse/SR-1009>
 [SR-1446]: <https://bugs.swift.org/browse/SR-1446>
 [SR-1529]: <https://bugs.swift.org/browse/SR-1529>
@@ -7320,6 +7419,8 @@
 [SR-2394]: <https://bugs.swift.org/browse/SR-2394>
 [SR-2608]: <https://bugs.swift.org/browse/SR-2608>
 [SR-4248]: <https://bugs.swift.org/browse/SR-4248>
+[SR-5581]: <https://bugs.swift.org/browse/SR-5581>
+[SR-5719]: <https://bugs.swift.org/browse/SR-5719>
 [SR-7139]: <https://bugs.swift.org/browse/SR-7139>
 [SR-7251]: <https://bugs.swift.org/browse/SR-7251>
-[SR-5719]: <https://bugs.swift.org/browse/SR-5719>
+[SR-8109]: <https://bugs.swift.org/browse/SR-8109>
diff --git a/cmake/modules/AddSwift.cmake b/cmake/modules/AddSwift.cmake
index 3d30e7d..e23ae1e 100644
--- a/cmake/modules/AddSwift.cmake
+++ b/cmake/modules/AddSwift.cmake
@@ -432,12 +432,14 @@
     # we need to add the math library, which is linked implicitly by libc++.
     list(APPEND result "-nostdlib++" "-lm")
     if("${LFLAGS_ARCH}" MATCHES armv7)
-      list(APPEND result "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a/libc++_shared.so")
+      set(android_libcxx_path "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a")
     elseif("${LFLAGS_ARCH}" MATCHES aarch64)
-      list(APPEND result "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_shared.so")
+      set(android_libcxx_path "${SWIFT_ANDROID_NDK_PATH}/sources/cxx-stl/llvm-libc++/libs/arm64-v8a")
     else()
       message(SEND_ERROR "unknown architecture (${LFLAGS_ARCH}) for android")
     endif()
+    list(APPEND link_libraries "${android_libcxx_path}/libc++abi.a")
+    list(APPEND link_libraries "${android_libcxx_path}/libc++_shared.so")
     swift_android_lib_for_arch(${LFLAGS_ARCH} ${LFLAGS_ARCH}_LIB)
     foreach(path IN LISTS ${LFLAGS_ARCH}_LIB)
       list(APPEND library_search_directories ${path})
diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst
index 1f44445..41829c7 100644
--- a/docs/ABI/Mangling.rst
+++ b/docs/ABI/Mangling.rst
@@ -633,7 +633,7 @@
 ::
 
   concrete-protocol-conformance ::= type protocol-conformance-ref any-protocol-conformance-list 'HC'
-  protocol-conformance-ref ::= protocol module?
+  protocol-conformance-ref ::= protocol module? 'HP'
 
   any-protocol-conformance ::= concrete-protocol-conformance
   any-protocol-conformance ::= dependent-protocol-conformance
diff --git a/include/swift/AST/Type.h b/include/swift/AST/Type.h
index c8253a2..7d610e4 100644
--- a/include/swift/AST/Type.h
+++ b/include/swift/AST/Type.h
@@ -647,7 +647,8 @@
   template<> struct DenseMapInfo<swift::CanType>
     : public DenseMapInfo<swift::Type> {
     static swift::CanType getEmptyKey() {
-      return swift::CanType(nullptr);
+      return swift::CanType(llvm::DenseMapInfo<swift::
+                              TypeBase*>::getEmptyKey());
     }
     static swift::CanType getTombstoneKey() {
       return swift::CanType(llvm::DenseMapInfo<swift::
diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h
index d3f0857..c752958 100644
--- a/include/swift/AST/Types.h
+++ b/include/swift/AST/Types.h
@@ -5281,6 +5281,7 @@
 
 inline bool CanType::isActuallyCanonicalOrNull() const {
   return getPointer() == nullptr ||
+         getPointer() == llvm::DenseMapInfo<TypeBase *>::getEmptyKey() ||
          getPointer() == llvm::DenseMapInfo<TypeBase *>::getTombstoneKey() ||
          getPointer()->isCanonical();
 }
diff --git a/include/swift/Demangling/Demangler.h b/include/swift/Demangling/Demangler.h
index ea52235..b416b7e 100644
--- a/include/swift/Demangling/Demangler.h
+++ b/include/swift/Demangling/Demangler.h
@@ -458,7 +458,7 @@
   NodePointer getDependentGenericParamType(int depth, int index);
   NodePointer demangleGenericParamIndex();
   NodePointer popProtocolConformance();
-  NodePointer popProtocolConformanceRef();
+  NodePointer demangleProtocolConformanceRef();
   NodePointer popAnyProtocolConformance();
   NodePointer demangleConcreteProtocolConformance();
   NodePointer popDependentProtocolConformance();
diff --git a/include/swift/Migrator/Migrator.h b/include/swift/Migrator/Migrator.h
index a43ef1a..8f88559 100644
--- a/include/swift/Migrator/Migrator.h
+++ b/include/swift/Migrator/Migrator.h
@@ -31,6 +31,11 @@
 bool updateCodeAndEmitRemapIfNeeded(CompilerInstance *Instance,
                                     const CompilerInvocation &Invocation);
 
+/// Specify options when running syntactic migration pass.
+struct SyntacticPassOptions {
+  bool RunOptionalTryMigration = false;
+};
+
 struct Migrator {
   CompilerInstance *StartInstance;
   const CompilerInvocation &StartInvocation;
@@ -69,7 +74,7 @@
   /// Returns true if failed:
   ///   - Setting up the Swift CompilerInstance failed.
   ///   - performSema emitted fatal errors along the way.
-  bool performSyntacticPasses();
+  bool performSyntacticPasses(SyntacticPassOptions Opts);
 
   /// Emit a replacement map from the very start state's output text to the
   /// final state's output text to the StartInvocation's output file.
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index fd2f0e2..d009098 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -2293,6 +2293,8 @@
   // are global anyway.
   if (isRetroactiveConformance(conformance))
     appendModule(conformance->getDeclContext()->getParentModule());
+
+  appendOperator("HP");
 }
 
 /// Retrieve the index of the conformance requirement indicated by the
diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp
index 69e6f8d..2cd878c 100644
--- a/lib/AST/ASTPrinter.cpp
+++ b/lib/AST/ASTPrinter.cpp
@@ -104,6 +104,7 @@
   result.OmitNameOfInaccessibleProperties = true;
   result.FunctionDefinitions = true;
   result.CollapseSingleGetterProperty = false;
+  result.VarInitializers = true;
 
   result.FunctionBody = [](const ValueDecl *decl, ASTPrinter &printer) {
     auto AFD = dyn_cast<AbstractFunctionDecl>(decl);
@@ -2099,20 +2100,19 @@
     }
 
     if (Options.VarInitializers) {
-      // FIXME: Implement once we can pretty-print expressions.
+      auto vd = entry.getAnchoringVarDecl();
+      if (entry.hasInitStringRepresentation() &&
+          vd->isInitExposedToClients()) {
+        SmallString<128> scratch;
+        Printer << " = " << entry.getInitStringRepresentation(scratch);
+      }
     }
 
-    auto vd = entry.getAnchoringVarDecl();
-    if (entry.hasInitStringRepresentation() &&
-        vd->isInitExposedToClients()) {
-      SmallString<128> scratch;
-      Printer << " = " << entry.getInitStringRepresentation(scratch);
-    }
-
-    // HACK: If we're just printing a single pattern and it has accessors,
-    //       print the accessors here.
-    if (decl->getNumPatternEntries() == 1) {
-      printAccessors(vd);
+    // If we're just printing a single pattern and it has accessors,
+    // print the accessors here. It is an error to add accessors to a
+    // pattern binding with multiple entries.
+    if (auto var = decl->getSingleVar()) {
+      printAccessors(var);
     }
   }
 }
@@ -3230,7 +3230,7 @@
     // Stored variables in Swift source will be picked up by the
     // PatternBindingDecl.
     if (auto *VD = dyn_cast<VarDecl>(this)) {
-      if (!VD->hasClangNode() && VD->getImplInfo().isSimpleStored())
+      if (!VD->hasClangNode() && VD->hasStorage())
         return false;
     }
 
@@ -3241,7 +3241,7 @@
         auto pattern =
           pbd->getPatternList()[0].getPattern()->getSemanticsProvidingPattern();
         if (auto named = dyn_cast<NamedPattern>(pattern)) {
-          if (!named->getDecl()->getImplInfo().isSimpleStored())
+          if (!named->getDecl()->hasStorage())
             return false;
         }
       }
diff --git a/lib/AST/GenericSignature.cpp b/lib/AST/GenericSignature.cpp
index c1e71d0..30831bd 100644
--- a/lib/AST/GenericSignature.cpp
+++ b/lib/AST/GenericSignature.cpp
@@ -24,6 +24,7 @@
 #include "swift/AST/Types.h"
 #include "swift/Basic/STLExtras.h"
 #include <functional>
+#include "GenericSignatureBuilderImpl.h"
 
 using namespace swift;
 
@@ -667,11 +668,17 @@
         !isa<DependentMemberType>(component))
       return None;
 
-    // Find the equivalence class for this dependent member type.
-    auto equivClass =
-      builder.resolveEquivalenceClass(
-                               Type(component),
-                               ArchetypeResolutionKind::CompleteWellFormed);
+    // Find the equivalence class for this dependent type.
+    auto resolved = builder.maybeResolveEquivalenceClass(
+                      Type(component),
+                      ArchetypeResolutionKind::CompleteWellFormed,
+                      /*wantExactPotentialArchetype=*/false);
+    if (!resolved) return None;
+
+    if (auto concrete = resolved.getAsConcreteType())
+      return getCanonicalTypeInContext(concrete, builder);
+
+    auto equivClass = resolved.getEquivalenceClass(builder);
     if (!equivClass) return None;
 
     if (equivClass->concreteType) {
diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp
index 89afeac..ff8e6cc 100644
--- a/lib/AST/GenericSignatureBuilder.cpp
+++ b/lib/AST/GenericSignatureBuilder.cpp
@@ -44,6 +44,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/SaveAndRestore.h"
 #include <algorithm>
+#include "GenericSignatureBuilderImpl.h"
 
 using namespace swift;
 using llvm::DenseMap;
@@ -1856,96 +1857,6 @@
   }
 }
 
-class GenericSignatureBuilder::ResolvedType {
-  llvm::PointerUnion<PotentialArchetype *, Type> type;
-  EquivalenceClass *equivClass;
-
-  /// For a type that could not be resolved further unless the given
-  /// equivalence class changes.
-  ResolvedType(EquivalenceClass *equivClass)
-    : type(), equivClass(equivClass) { }
-
-public:
-  /// A specific resolved potential archetype.
-  ResolvedType(PotentialArchetype *pa)
-    : type(pa), equivClass(pa->getEquivalenceClassIfPresent()) { }
-
-  /// A resolved type within the given equivalence class.
-  ResolvedType(Type type, EquivalenceClass *equivClass)
-      : type(type), equivClass(equivClass) {
-    assert(type->isTypeParameter() == static_cast<bool>(equivClass) &&
-           "type parameters must have equivalence classes");
-  }
-
-  /// Return an unresolved result, which could be resolved when we
-  /// learn more information about the given equivalence class.
-  static ResolvedType forUnresolved(EquivalenceClass *equivClass) {
-    return ResolvedType(equivClass);
-  }
-
-  /// Return a result for a concrete type.
-  static ResolvedType forConcrete(Type concreteType) {
-    return ResolvedType(concreteType, nullptr);
-  }
-
-  /// Determine whether this result was resolved.
-  explicit operator bool() const { return !type.isNull(); }
-
-  /// Retrieve the dependent type.
-  Type getDependentType(GenericSignatureBuilder &builder) const;
-
-  /// Retrieve the concrete type, or a null type if this result doesn't store
-  /// a concrete type.
-  Type getAsConcreteType() const {
-    assert(*this && "Doesn't contain any result");
-    if (equivClass) return Type();
-    return type.dyn_cast<Type>();
-  }
-
-  /// Realize a potential archetype for this type parameter.
-  PotentialArchetype *realizePotentialArchetype(
-                                            GenericSignatureBuilder &builder);
-
-  /// Retrieve the potential archetype, if already known.
-  PotentialArchetype *getPotentialArchetypeIfKnown() const {
-    return type.dyn_cast<PotentialArchetype *>();
-  }
-
-  /// Retrieve the equivalence class into which a resolved type refers.
-  EquivalenceClass *getEquivalenceClass(
-                     GenericSignatureBuilder &builder) const {
-    assert(*this && "Only for resolved types");
-    if (equivClass) return equivClass;
-
-    // Create the equivalence class now.
-    return type.get<PotentialArchetype *>()
-             ->getOrCreateEquivalenceClass(builder);
-  }
-
-  /// Retrieve the equivalence class into which a resolved type refers.
-  EquivalenceClass *getEquivalenceClassIfPresent() const {
-    assert(*this && "Only for resolved types");
-    if (equivClass) return equivClass;
-
-    // Create the equivalence class now.
-    return type.get<PotentialArchetype *>()->getEquivalenceClassIfPresent();
-  }
-
-  /// Retrieve the unresolved result.
-  EquivalenceClass *getUnresolvedEquivClass() const {
-    assert(!*this);
-    return equivClass;
-  }
-
-  /// Return an unresolved type.
-  ///
-  /// This loses equivalence-class information that could be useful, which
-  /// is unfortunate.
-  UnresolvedType getUnresolvedType() const {
-    return type;
-  }
-};
-
 bool EquivalenceClass::recordConformanceConstraint(
                                  GenericSignatureBuilder &builder,
                                  ResolvedType type,
diff --git a/lib/AST/GenericSignatureBuilderImpl.h b/lib/AST/GenericSignatureBuilderImpl.h
new file mode 100644
index 0000000..88467f5
--- /dev/null
+++ b/lib/AST/GenericSignatureBuilderImpl.h
@@ -0,0 +1,107 @@
+//
+//  GenericSignatureBuilderImpl.h
+//  Swift
+//
+//  Created by Doug Gregor on 12/17/18.
+//
+
+#ifndef SWIFT_AST_GENERIC_SIGNATURE_BUILDER_IMPL_H
+#define SWIFT_AST_GENERIC_SIGNATURE_BUILDER_IMPL_H
+
+#include "swift/AST/GenericSignatureBuilder.h"
+
+namespace swift {
+
+class GenericSignatureBuilder::ResolvedType {
+  llvm::PointerUnion<PotentialArchetype *, Type> type;
+  EquivalenceClass *equivClass;
+
+  /// For a type that could not be resolved further unless the given
+  /// equivalence class changes.
+  ResolvedType(EquivalenceClass *equivClass)
+    : type(), equivClass(equivClass) { }
+
+public:
+  /// A specific resolved potential archetype.
+  ResolvedType(PotentialArchetype *pa)
+    : type(pa), equivClass(pa->getEquivalenceClassIfPresent()) { }
+
+  /// A resolved type within the given equivalence class.
+  ResolvedType(Type type, EquivalenceClass *equivClass)
+      : type(type), equivClass(equivClass) {
+    assert(type->isTypeParameter() == static_cast<bool>(equivClass) &&
+           "type parameters must have equivalence classes");
+  }
+
+  /// Return an unresolved result, which could be resolved when we
+  /// learn more information about the given equivalence class.
+  static ResolvedType forUnresolved(EquivalenceClass *equivClass) {
+    return ResolvedType(equivClass);
+  }
+
+  /// Return a result for a concrete type.
+  static ResolvedType forConcrete(Type concreteType) {
+    return ResolvedType(concreteType, nullptr);
+  }
+
+  /// Determine whether this result was resolved.
+  explicit operator bool() const { return !type.isNull(); }
+
+  /// Retrieve the dependent type.
+  Type getDependentType(GenericSignatureBuilder &builder) const;
+
+  /// Retrieve the concrete type, or a null type if this result doesn't store
+  /// a concrete type.
+  Type getAsConcreteType() const {
+    assert(*this && "Doesn't contain any result");
+    if (equivClass) return Type();
+    return type.dyn_cast<Type>();
+  }
+
+  /// Realize a potential archetype for this type parameter.
+  PotentialArchetype *realizePotentialArchetype(
+                                            GenericSignatureBuilder &builder);
+
+  /// Retrieve the potential archetype, if already known.
+  PotentialArchetype *getPotentialArchetypeIfKnown() const {
+    return type.dyn_cast<PotentialArchetype *>();
+  }
+
+  /// Retrieve the equivalence class into which a resolved type refers.
+  EquivalenceClass *getEquivalenceClass(
+                     GenericSignatureBuilder &builder) const {
+    assert(*this && "Only for resolved types");
+    if (equivClass) return equivClass;
+
+    // Create the equivalence class now.
+    return type.get<PotentialArchetype *>()
+             ->getOrCreateEquivalenceClass(builder);
+  }
+
+  /// Retrieve the equivalence class into which a resolved type refers.
+  EquivalenceClass *getEquivalenceClassIfPresent() const {
+    assert(*this && "Only for resolved types");
+    if (equivClass) return equivClass;
+
+    // Create the equivalence class now.
+    return type.get<PotentialArchetype *>()->getEquivalenceClassIfPresent();
+  }
+
+  /// Retrieve the unresolved result.
+  EquivalenceClass *getUnresolvedEquivClass() const {
+    assert(!*this);
+    return equivClass;
+  }
+
+  /// Return an unresolved type.
+  ///
+  /// This loses equivalence-class information that could be useful, which
+  /// is unfortunate.
+  UnresolvedType getUnresolvedType() const {
+    return type;
+  }
+};
+
+} // end namepsace swift
+
+#endif // SWIFT_AST_GENERIC_SIGNATURE_BUILDER_IMPL_H
diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp
index 6f46836..61a8866 100644
--- a/lib/AST/NameLookup.cpp
+++ b/lib/AST/NameLookup.cpp
@@ -249,6 +249,24 @@
         break;
       }
 
+      // Prefer declarations in the any module over those in the standard
+      // library module.
+      if (auto swiftModule = ctx.getStdlibModule()) {
+        if ((firstModule == swiftModule) != (secondModule == swiftModule)) {
+          // If the second module is the standard library module, the second
+          // declaration is shadowed by the first.
+          if (secondModule == swiftModule) {
+            shadowed.insert(secondDecl);
+            continue;
+          }
+
+          // Otherwise, the first declaration is shadowed by the second. There is
+          // no point in continuing to compare the first declaration to others.
+          shadowed.insert(firstDecl);
+          break;
+        }
+      }
+
       // Prefer declarations in an overlay to similar declarations in
       // the Clang module it customizes.
       if (firstDecl->hasClangNode() != secondDecl->hasClangNode()) {
@@ -331,26 +349,33 @@
       }
     }
 
-    // We need an interface type here.
-    if (typeResolver)
-      typeResolver->resolveDeclSignature(decl);
+    CanType signature;
 
-    // If the decl is currently being validated, this is likely a recursive
-    // reference and we'll want to skip ahead so as to avoid having its type
-    // attempt to desugar itself.
-    if (!decl->hasValidSignature())
+    if (!isa<TypeDecl>(decl)) {
+      // We need an interface type here.
+      if (typeResolver)
+        typeResolver->resolveDeclSignature(decl);
+
+      // If the decl is currently being validated, this is likely a recursive
+      // reference and we'll want to skip ahead so as to avoid having its type
+      // attempt to desugar itself.
+      if (!decl->hasValidSignature())
+        continue;
+
+      // FIXME: the canonical type makes a poor signature, because we don't
+      // canonicalize away default arguments.
+      signature = decl->getInterfaceType()->getCanonicalType();
+
+      // FIXME: The type of a variable or subscript doesn't include
+      // enough context to distinguish entities from different
+      // constrained extensions, so use the overload signature's
+      // type. This is layering a partial fix upon a total hack.
+      if (auto asd = dyn_cast<AbstractStorageDecl>(decl))
+        signature = asd->getOverloadSignatureType();
+    } else if (decl->getDeclContext()->isTypeContext()) {
+      // Do not apply shadowing rules for member types.
       continue;
-
-    // FIXME: the canonical type makes a poor signature, because we don't
-    // canonicalize away default arguments.
-    auto signature = decl->getInterfaceType()->getCanonicalType();
-
-    // FIXME: The type of a variable or subscript doesn't include
-    // enough context to distinguish entities from different
-    // constrained extensions, so use the overload signature's
-    // type. This is layering a partial fix upon a total hack.
-    if (auto asd = dyn_cast<AbstractStorageDecl>(decl))
-      signature = asd->getOverloadSignatureType();
+    }
 
     // Record this declaration based on its signature.
     auto &known = collisions[signature];
@@ -1169,6 +1194,11 @@
   lookupInModule(&M, {}, Name, CurModuleResults, NLKind::UnqualifiedLookup,
                  resolutionKind, TypeResolver, DC, extraImports);
 
+  // Always perform name shadowing for type lookup.
+  if (options.contains(Flags::TypeLookup)) {
+    removeShadowedDecls(CurModuleResults, &M);
+  }
+
   for (auto VD : CurModuleResults)
     Results.push_back(LookupResultEntry(VD));
 
diff --git a/lib/ClangImporter/MappedTypes.def b/lib/ClangImporter/MappedTypes.def
index 0fd435a..9afc664 100644
--- a/lib/ClangImporter/MappedTypes.def
+++ b/lib/ClangImporter/MappedTypes.def
@@ -161,6 +161,9 @@
 
 // CoreFoundation types.
 // Note that we're preserving the typealias for CFIndex.
+MAP_STDLIB_TYPE("CFTypeID", UnsignedWord, 0, "UInt", false, DefineAndUse)
+MAP_STDLIB_TYPE("CFOptionFlags", UnsignedWord, 0, "UInt", false, DefineAndUse)
+MAP_STDLIB_TYPE("CFHashCode", UnsignedWord, 0, "UInt", false, DefineAndUse)
 MAP_STDLIB_TYPE("CFIndex", SignedWord, 0, "Int", false, DefineAndUse)
 
 // Foundation types.
diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp
index dd9b798..d9729b7 100644
--- a/lib/Demangling/Demangler.cpp
+++ b/lib/Demangling/Demangler.cpp
@@ -610,6 +610,7 @@
       case 'C': return demangleConcreteProtocolConformance();
       case 'D': return demangleDependentProtocolConformanceRoot();
       case 'I': return demangleDependentProtocolConformanceInherited();
+      case 'P': return demangleProtocolConformanceRef();
       default:
         pushBack();
         pushBack();
@@ -1294,7 +1295,7 @@
   });
 }
 
-NodePointer Demangler::popProtocolConformanceRef() {
+NodePointer Demangler::demangleProtocolConformanceRef() {
   NodePointer module = popModule();
   NodePointer proto = popProtocol();
   auto protocolConformanceRef =
@@ -1309,7 +1310,7 @@
 
 NodePointer Demangler::demangleConcreteProtocolConformance() {
   NodePointer conditionalConformanceList = popAnyProtocolConformanceList();
-  NodePointer conformanceRef = popProtocolConformanceRef();
+  NodePointer conformanceRef = popNode(Node::Kind::ProtocolConformanceRef);
   NodePointer type = popNode(Node::Kind::Type);
   return createWithChildren(Node::Kind::ConcreteProtocolConformance,
                             type, conformanceRef, conditionalConformanceList);
diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp
index 5f6afbb..0f61baf 100644
--- a/lib/Demangling/Remangler.cpp
+++ b/lib/Demangling/Remangler.cpp
@@ -1657,6 +1657,7 @@
   manglePureProtocol(node->getChild(0));
   if (node->getNumChildren() > 1)
     mangleChildNode(node, 1);
+  Buffer << "HP";
 }
 
 void Remangler::mangleConcreteProtocolConformance(Node *node) {
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 9d900ef..c00be92 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1079,8 +1079,11 @@
   return false;
 }
 
-static std::string getScriptFileName(StringRef name) {
-  return (Twine(name) + "4" + ".json").str();
+static std::string getScriptFileName(StringRef name, version::Version &ver) {
+  if (ver.isVersionAtLeast(4, 2))
+    return (Twine(name) + "42" + ".json").str();
+  else
+    return (Twine(name) + "4" + ".json").str();
 }
 
 static bool ParseMigratorArgs(MigratorOptions &Opts,
@@ -1124,20 +1127,20 @@
 
     bool Supported = true;
     llvm::SmallString<128> dataPath(basePath);
-
+    auto &langVer = LangOpts.EffectiveLanguageVersion;
     if (Triple.isMacOSX())
-      llvm::sys::path::append(dataPath, getScriptFileName("macos"));
+      llvm::sys::path::append(dataPath, getScriptFileName("macos", langVer));
     else if (Triple.isiOS())
-      llvm::sys::path::append(dataPath, getScriptFileName("ios"));
+      llvm::sys::path::append(dataPath, getScriptFileName("ios", langVer));
     else if (Triple.isTvOS())
-      llvm::sys::path::append(dataPath, getScriptFileName("tvos"));
+      llvm::sys::path::append(dataPath, getScriptFileName("tvos", langVer));
     else if (Triple.isWatchOS())
-      llvm::sys::path::append(dataPath, getScriptFileName("watchos"));
+      llvm::sys::path::append(dataPath, getScriptFileName("watchos", langVer));
     else
       Supported = false;
     if (Supported) {
       llvm::SmallString<128> authoredDataPath(basePath);
-      llvm::sys::path::append(authoredDataPath, getScriptFileName("overlay"));
+      llvm::sys::path::append(authoredDataPath, getScriptFileName("overlay", langVer));
       // Add authored list first to take higher priority.
       Opts.APIDigesterDataStorePaths.push_back(authoredDataPath.str());
       Opts.APIDigesterDataStorePaths.push_back(dataPath.str());
diff --git a/lib/IRGen/GenDecl.cpp b/lib/IRGen/GenDecl.cpp
index bbe3496..69023b0 100644
--- a/lib/IRGen/GenDecl.cpp
+++ b/lib/IRGen/GenDecl.cpp
@@ -1099,30 +1099,8 @@
   while (!LazyTypeMetadata.empty() ||
          !LazyTypeContextDescriptors.empty() ||
          !LazyFunctionDefinitions.empty() ||
-         !LazyFieldTypes.empty() ||
          !LazyWitnessTables.empty()) {
 
-    while (!LazyFieldTypes.empty()) {
-      auto info = LazyFieldTypes.pop_back_val();
-      auto &IGM = *info.IGM;
-
-      for (auto fieldType : info.fieldTypes) {
-        if (fieldType->hasArchetype())
-          continue;
-
-        // All of the required attributes are going to be preserved
-        // by field reflection metadata in the mangled name, so
-        // there is no need to worry about ownership semantics here.
-        if (auto refStorTy = dyn_cast<ReferenceStorageType>(fieldType))
-          fieldType = refStorTy.getReferentType();
-
-        // Make sure that all of the field type metadata is forced,
-        // otherwise there might be a problem when fields are accessed
-        // through reflection.
-        (void)irgen::getOrCreateTypeMetadataAccessFunction(IGM, fieldType);
-      }
-    }
-
     // Emit any lazy type metadata we require.
     while (!LazyTypeMetadata.empty()) {
       NominalTypeDecl *type = LazyTypeMetadata.pop_back_val();
diff --git a/lib/IRGen/GenMeta.cpp b/lib/IRGen/GenMeta.cpp
index 08d9344..2b43e02 100644
--- a/lib/IRGen/GenMeta.cpp
+++ b/lib/IRGen/GenMeta.cpp
@@ -1198,37 +1198,6 @@
     }
     return numFields;
   }
-  
-  /// Track the field types of a struct or class for reflection metadata
-  /// emission.
-  static void
-  addFieldTypes(IRGenModule &IGM, NominalTypeDecl *type,
-                NominalTypeDecl::StoredPropertyRange storedProperties) {
-    SmallVector<CanType, 4> types;
-    for (VarDecl *prop : storedProperties) {
-      auto propertyType = type->mapTypeIntoContext(prop->getInterfaceType())
-                              ->getCanonicalType();
-      types.push_back(propertyType);
-    }
-
-    IGM.addFieldTypes(types);
-  }
-  
-  /// Track the payload types of an enum for reflection metadata
-  /// emission.
-  static void addFieldTypes(IRGenModule &IGM,
-                            ArrayRef<EnumImplStrategy::Element> enumElements) {
-    SmallVector<CanType, 4> types;
-
-    for (auto &elt : enumElements) {
-      auto caseType = elt.decl->getParentEnum()->mapTypeIntoContext(
-        elt.decl->getArgumentInterfaceType())
-          ->getCanonicalType();
-      types.push_back(caseType);
-    }
-
-    IGM.addFieldTypes(types);
-  }
 
   class StructContextDescriptorBuilder
     : public TypeContextDescriptorBuilderBase<StructContextDescriptorBuilder,
@@ -1264,7 +1233,9 @@
       // uint32_t FieldOffsetVectorOffset;
       B.addInt32(FieldVectorOffset / IGM.getPointerSize());
 
-      addFieldTypes(IGM, getType(), properties);
+      // For any nominal type metadata required for reflection.
+      for (auto *prop : properties)
+        IGM.IRGen.noteUseOfTypeMetadata(prop->getValueInterfaceType());
     }
     
     uint16_t getKindSpecificFlags() {
@@ -1336,7 +1307,9 @@
       // uint32_t NumEmptyCases;
       B.addInt32(Strategy.getElementsWithNoPayload().size());
 
-      addFieldTypes(IGM, Strategy.getElementsWithPayload());
+      // For any nominal type metadata required for reflection.
+      for (auto elt : Strategy.getElementsWithPayload())
+        IGM.IRGen.noteUseOfTypeMetadata(elt.decl->getArgumentInterfaceType());
     }
     
     uint16_t getKindSpecificFlags() {
@@ -1646,7 +1619,9 @@
       // uint32_t FieldOffsetVectorOffset;
       B.addInt32(getFieldVectorOffset() / IGM.getPointerSize());
 
-      addFieldTypes(IGM, getType(), properties);
+      // For any nominal type metadata required for reflection.
+      for (auto *prop : properties)
+        IGM.IRGen.noteUseOfTypeMetadata(prop->getValueInterfaceType());
     }
   };
 } // end anonymous namespace
@@ -1772,10 +1747,6 @@
     [&]{ AnonymousContextDescriptorBuilder(*this, DC).emit(); });
 }
 
-void IRGenModule::addFieldTypes(ArrayRef<CanType> fieldTypes) {
-  IRGen.addFieldTypes(fieldTypes, this);
-}
-
 static void emitInitializeFieldOffsetVector(IRGenFunction &IGF,
                                             SILType T,
                                             llvm::Value *metadata,
diff --git a/lib/IRGen/IRGenModule.h b/lib/IRGen/IRGenModule.h
index 6d41125..47de693 100644
--- a/lib/IRGen/IRGenModule.h
+++ b/lib/IRGen/IRGenModule.h
@@ -241,14 +241,6 @@
 
   llvm::SetVector<SILFunction*> DynamicReplacements;
 
-  struct FieldTypeMetadata {
-    IRGenModule *IGM;
-    std::vector<CanType> fieldTypes;
-  };
-
-  /// Field types we need to verify are present.
-  llvm::SmallVector<FieldTypeMetadata, 4> LazyFieldTypes;
-
   /// SIL functions that we need to emit lazily.
   llvm::SmallVector<SILFunction*, 4> LazyFunctionDefinitions;
 
@@ -367,6 +359,13 @@
     noteUseOfTypeGlobals(type, true, RequireMetadata);
   }
 
+  void noteUseOfTypeMetadata(Type type) {
+    type.visit([&](Type t) {
+      if (auto *nominal = t->getAnyNominal())
+        noteUseOfTypeMetadata(nominal);
+    });
+  }
+
   void noteUseOfTypeContextDescriptor(NominalTypeDecl *type,
                                       RequireMetadata_t requireMetadata) {
     noteUseOfTypeGlobals(type, false, requireMetadata);
@@ -386,9 +385,6 @@
   /// Adds \p Conf to LazyWitnessTables if it has not been added yet.
   void addLazyWitnessTable(const ProtocolConformance *Conf);
 
-  void addFieldTypes(ArrayRef<CanType> fieldTypes, IRGenModule *IGM) {
-    LazyFieldTypes.push_back({IGM, {fieldTypes.begin(), fieldTypes.end()}});
-  }
 
   void addClassForEagerInitialization(ClassDecl *ClassDecl);
 
@@ -850,7 +846,6 @@
   void addUsedGlobal(llvm::GlobalValue *global);
   void addCompilerUsedGlobal(llvm::GlobalValue *global);
   void addObjCClass(llvm::Constant *addr, bool nonlazy);
-  void addFieldTypes(ArrayRef<CanType> fieldTypes);
   void addProtocolConformance(ConformanceDescription &&conformance);
 
   llvm::Constant *emitSwiftProtocols();
diff --git a/lib/Migrator/CMakeLists.txt b/lib/Migrator/CMakeLists.txt
index 1b28f1f..c7ad2c7 100644
--- a/lib/Migrator/CMakeLists.txt
+++ b/lib/Migrator/CMakeLists.txt
@@ -4,6 +4,11 @@
   tvos4.json
   watchos4.json
   overlay4.json
+  macos42.json
+  ios42.json
+  tvos42.json
+  watchos42.json
+  overlay42.json
 )
 set(SWIFTLIB_DIR
     "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib/swift")
diff --git a/lib/Migrator/Migrator.cpp b/lib/Migrator/Migrator.cpp
index afa0696..d324289 100644
--- a/lib/Migrator/Migrator.cpp
+++ b/lib/Migrator/Migrator.cpp
@@ -59,7 +59,11 @@
   // Phase 2: Syntactic Transformations
   // Don't run these passes if we're already in newest Swift version.
   if (EffectiveVersion != CurrentVersion) {
-    auto FailedSyntacticPasses = M.performSyntacticPasses();
+    SyntacticPassOptions Opts;
+
+    // Type of optional try changes since Swift 5.
+    Opts.RunOptionalTryMigration = !EffectiveVersion.isVersionAtLeast(5);
+    auto FailedSyntacticPasses = M.performSyntacticPasses(Opts);
     if (FailedSyntacticPasses) {
       return true;
     }
@@ -173,7 +177,7 @@
   return Instance;
 }
 
-bool Migrator::performSyntacticPasses() {
+bool Migrator::performSyntacticPasses(SyntacticPassOptions Opts) {
   clang::FileSystemOptions ClangFileSystemOptions;
   clang::FileManager ClangFileManager { ClangFileSystemOptions };
 
@@ -197,8 +201,10 @@
 
   runAPIDiffMigratorPass(Editor, StartInstance->getPrimarySourceFile(),
                          getMigratorOptions());
-  runOptionalTryMigratorPass(Editor, StartInstance->getPrimarySourceFile(),
-                        getMigratorOptions());
+  if (Opts.RunOptionalTryMigration) {
+    runOptionalTryMigratorPass(Editor, StartInstance->getPrimarySourceFile(),
+                               getMigratorOptions());
+  }
 
   Edits.commit(Editor.getEdits());
 
diff --git a/lib/Migrator/ios42.json b/lib/Migrator/ios42.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/lib/Migrator/ios42.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/lib/Migrator/macos42.json b/lib/Migrator/macos42.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/lib/Migrator/macos42.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/lib/Migrator/overlay4.json b/lib/Migrator/overlay4.json
index c5475de..d5fb336 100644
--- a/lib/Migrator/overlay4.json
+++ b/lib/Migrator/overlay4.json
@@ -1320,5 +1320,16 @@
     "DiffItemKind": "SpecialCaseDiffItem",
     "Usr": "s:5UIKit17UIApplicationMainys5Int32VAD_SpySpys4Int8VGGSgSSSgAJtF",
     "SpecialCaseId": "UIApplicationMain"
-  }
+  },
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "Rename",
+    "ChildIndex": "0",
+    "LeftUsr": "s:SlsSQ7ElementRpzrlE5index2of5IndexQzSgAB_tF",
+    "LeftComment": "index",
+    "RightUsr": "",
+    "RightComment": "firstIndex",
+    "ModuleName": "Swift"
+  },
 ]
diff --git a/lib/Migrator/overlay42.json b/lib/Migrator/overlay42.json
new file mode 100644
index 0000000..cc6d339
--- /dev/null
+++ b/lib/Migrator/overlay42.json
@@ -0,0 +1,13 @@
+[
+  {
+    "DiffItemKind": "CommonDiffItem",
+    "NodeKind": "Function",
+    "NodeAnnotation": "Rename",
+    "ChildIndex": "0",
+    "LeftUsr": "s:SlsSQ7ElementRpzrlE5index2of5IndexQzSgAB_tF",
+    "LeftComment": "index",
+    "RightUsr": "",
+    "RightComment": "firstIndex",
+    "ModuleName": "Swift"
+  },
+]
diff --git a/lib/Migrator/tvos42.json b/lib/Migrator/tvos42.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/lib/Migrator/tvos42.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/lib/Migrator/watchos42.json b/lib/Migrator/watchos42.json
new file mode 100644
index 0000000..0637a08
--- /dev/null
+++ b/lib/Migrator/watchos42.json
@@ -0,0 +1 @@
+[]
\ No newline at end of file
diff --git a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
index b63c6ed..33ac9b6 100644
--- a/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
+++ b/lib/SILOptimizer/Analysis/ARCAnalysis.cpp
@@ -1055,7 +1055,7 @@
 
     // Try to speed up the trivial case of single release/dealloc.
     if (isa<StrongReleaseInst>(User) || isa<DeallocBoxInst>(User) ||
-        isa<DestroyValueInst>(User)) {
+        isa<DestroyValueInst>(User) || isa<ReleaseValueInst>(User)) {
       if (!seenRelease)
         OneRelease = User;
       else
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 7bed4bc..d502b3a 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -403,14 +403,15 @@
   // Build and type check the string literal index value to the specific
   // string type expected by the subscript.
   Expr *nameExpr = new (ctx) StringLiteralExpr(name, loc, /*implicit*/true);
+  (void)cs.TC.typeCheckExpression(nameExpr, dc);
+  cs.cacheExprTypes(nameExpr);
 
   // Build a tuple so that the argument has a label.
   Expr *tuple = TupleExpr::create(ctx, loc, nameExpr, ctx.Id_dynamicMember,
                                   loc, loc, /*hasTrailingClosure*/false,
                                   /*implicit*/true);
-  (void)cs.TC.typeCheckExpression(tuple, dc, TypeLoc::withoutLoc(ty),
-                                  CTP_CallArgument);
-  cs.cacheExprTypes(tuple);
+  cs.setType(tuple, ty);
+  tuple->setType(ty);
   return tuple;
 }
 
@@ -2824,23 +2825,14 @@
         return simplifyExprType(expr);
       }
       
-      Type subExprType = cs.getType(expr->getSubExpr());
-      Type targetType = simplifyType(subExprType);
-      
-      // If the subexpression is not optional, wrap it in
-      // an InjectIntoOptionalExpr. Then use the type of the
-      // subexpression as the type of the 'try?' expr
-      bool subExprIsOptional = (bool) subExprType->getOptionalObjectType();
-      
-      if (!subExprIsOptional) {
-        targetType = OptionalType::get(targetType);
-        auto subExpr = coerceToType(expr->getSubExpr(), targetType,
-                                    cs.getConstraintLocator(expr));
-        if (!subExpr) return nullptr;
-        expr->setSubExpr(subExpr);
-      }
-      
-      cs.setType(expr, targetType);
+      Type exprType = simplifyType(cs.getType(expr));
+
+      auto subExpr = coerceToType(expr->getSubExpr(), exprType,
+                                  cs.getConstraintLocator(expr));
+      if (!subExpr) return nullptr;
+      expr->setSubExpr(subExpr);
+
+      cs.setType(expr, exprType);
       return expr;
     }
 
@@ -4430,13 +4422,17 @@
             auto loc = origComponent.getLoc();
             auto fieldName =
                 foundDecl->choice.getName().getBaseIdentifier().str();
-            auto index = buildDynamicMemberLookupIndexExpr(fieldName, indexType,
-                                                           loc, dc, cs);
-            
+
+            Expr *nameExpr = new (ctx) StringLiteralExpr(fieldName, loc,
+                                                         /*implicit*/true);
+            (void)cs.TC.typeCheckExpression(nameExpr, dc);
+            cs.cacheExprTypes(nameExpr);
+
             origComponent = KeyPathExpr::Component::
-              forUnresolvedSubscript(ctx, loc, index, {}, loc, loc,
-                                     /*trailingClosure*/nullptr);
-            cs.setType(origComponent.getIndexExpr(), index->getType());
+              forUnresolvedSubscript(ctx, loc,
+                                     {nameExpr}, {ctx.Id_dynamicMember}, {loc},
+                                     loc, /*trailingClosure*/nullptr);
+            cs.setType(origComponent.getIndexExpr(), indexType);
           }
 
           auto subscriptType =
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 656f1c8..5100bd6 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -423,6 +423,27 @@
                                         const CalleeCandidateInfo &candidates,
                                             TCCOptions options = TCCOptions());
 
+  void getPossibleTypesOfExpressionWithoutApplying(
+      Expr *&expr, DeclContext *dc, SmallPtrSetImpl<TypeBase *> &types,
+      FreeTypeVariableBinding allowFreeTypeVariables =
+          FreeTypeVariableBinding::Disallow,
+      ExprTypeCheckListener *listener = nullptr) {
+    CS.TC.getPossibleTypesOfExpressionWithoutApplying(
+        expr, dc, types, allowFreeTypeVariables, listener);
+    CS.cacheExprTypes(expr);
+  }
+
+  Type getTypeOfExpressionWithoutApplying(
+      Expr *&expr, DeclContext *dc, ConcreteDeclRef &referencedDecl,
+      FreeTypeVariableBinding allowFreeTypeVariables =
+          FreeTypeVariableBinding::Disallow,
+      ExprTypeCheckListener *listener = nullptr) {
+    auto type = CS.TC.getTypeOfExpressionWithoutApplying(expr, dc, referencedDecl,
+                                                         allowFreeTypeVariables, listener);
+    CS.cacheExprTypes(expr);
+    return type;
+  }
+
   /// Diagnose common failures due to applications of an argument list to an
   /// ApplyExpr or SubscriptExpr.
   bool diagnoseParameterErrors(CalleeCandidateInfo &CCI,
@@ -452,6 +473,10 @@
                                               Type contextualType,
                                               ContextualTypePurpose CTP);
 
+  bool diagnoseImplicitSelfErrors(Expr *fnExpr, Expr *argExpr,
+                                  CalleeCandidateInfo &CCI,
+                                  ArrayRef<Identifier> argLabels);
+
 private:
   /// Validate potential contextual type for type-checking one of the
   /// sub-expressions, usually correct/valid types are the ones which
@@ -3194,10 +3219,9 @@
   return result;
 }
 
-static bool diagnoseImplicitSelfErrors(Expr *fnExpr, Expr *argExpr,
-                                       CalleeCandidateInfo &CCI,
-                                       ArrayRef<Identifier> argLabels,
-                                       ConstraintSystem &CS) {
+bool FailureDiagnosis::diagnoseImplicitSelfErrors(
+    Expr *fnExpr, Expr *argExpr, CalleeCandidateInfo &CCI,
+    ArrayRef<Identifier> argLabels) {
   // If candidate list is empty it means that problem is somewhere else,
   // since we need to have candidates which might be shadowing other funcs.
   if (CCI.empty() || !CCI[0].getDecl())
@@ -3251,8 +3275,7 @@
     for (unsigned i = 0, e = argTuple->getNumElements(); i < e; ++i) {
       ConcreteDeclRef ref = nullptr;
       auto *el = argTuple->getElement(i);
-      auto typeResult =
-        TC.getTypeOfExpressionWithoutApplying(el, CS.DC, ref);
+      auto typeResult = getTypeOfExpressionWithoutApplying(el, CS.DC, ref);
       if (!typeResult)
         return false;
       auto flags = ParameterTypeFlags().withInOut(typeResult->is<InOutType>());
@@ -4226,7 +4249,7 @@
   }
 
   // Try to diagnose errors related to the use of implicit self reference.
-  if (diagnoseImplicitSelfErrors(fnExpr, argExpr, CCI, argLabels, CS))
+  if (diagnoseImplicitSelfErrors(fnExpr, argExpr, CCI, argLabels))
     return true;
 
   if (diagnoseInstanceMethodAsCurriedMemberOnType(CCI, fnExpr, argExpr))
@@ -4368,7 +4391,7 @@
         ConcreteDeclRef decl = nullptr;
         message = diag::cannot_subscript_with_index;
 
-        if (CS.TC.getTypeOfExpressionWithoutApplying(expr, CS.DC, decl))
+        if (getTypeOfExpressionWithoutApplying(expr, CS.DC, decl))
           return false;
 
         // If we are down to a single candidate but with an unresolved
@@ -4932,7 +4955,7 @@
   if (currentType->hasTypeVariable() || currentType->hasUnresolvedType()) {
     auto contextualType = CS.getContextualType();
     CallResultListener listener(contextualType);
-    CS.TC.getPossibleTypesOfExpressionWithoutApplying(
+    getPossibleTypesOfExpressionWithoutApplying(
         fnExpr, CS.DC, possibleTypes, FreeTypeVariableBinding::UnresolvedType,
         &listener);
 
@@ -5037,9 +5060,9 @@
   auto &TC = CS.TC;
   auto *DC = CS.DC;
 
-  auto typeCheckExpr = [](TypeChecker &TC, Expr *expr, DeclContext *DC,
-                          SmallPtrSetImpl<TypeBase *> &types) {
-    TC.getPossibleTypesOfExpressionWithoutApplying(
+  auto typeCheckExpr = [&](TypeChecker &TC, Expr *expr, DeclContext *DC,
+                           SmallPtrSetImpl<TypeBase *> &types) {
+    getPossibleTypesOfExpressionWithoutApplying(
         expr, DC, types, FreeTypeVariableBinding::Disallow);
   };
 
@@ -5165,14 +5188,14 @@
 // unresolved result let's not re-typecheck the function expression,
 // because it might produce unrelated diagnostics due to lack of
 // contextual information.
-static bool shouldTypeCheckFunctionExpr(TypeChecker &TC, DeclContext *DC,
+static bool shouldTypeCheckFunctionExpr(FailureDiagnosis &FD, DeclContext *DC,
                                         Expr *fnExpr) {
   if (!isa<UnresolvedDotExpr>(fnExpr))
     return true;
 
   SmallPtrSet<TypeBase *, 4> fnTypes;
-  TC.getPossibleTypesOfExpressionWithoutApplying(fnExpr, DC, fnTypes,
-                                       FreeTypeVariableBinding::UnresolvedType);
+  FD.getPossibleTypesOfExpressionWithoutApplying(
+      fnExpr, DC, fnTypes, FreeTypeVariableBinding::UnresolvedType);
 
   if (fnTypes.size() == 1) {
     // Some member types depend on the arguments to produce a result type,
@@ -5232,7 +5255,7 @@
   auto *fnExpr = callExpr->getFn();
   auto originalFnType = CS.getType(callExpr->getFn());
 
-  if (shouldTypeCheckFunctionExpr(CS.TC, CS.DC, fnExpr)) {
+  if (shouldTypeCheckFunctionExpr(*this, CS.DC, fnExpr)) {
 
     // If we are misusing a subscript, diagnose that and provide a fixit.
     // We diagnose this here to have enough context to offer an appropriate fixit.
@@ -5269,7 +5292,7 @@
     fnExpr = callExpr->getFn();
 
     SmallPtrSet<TypeBase *, 4> types;
-    CS.TC.getPossibleTypesOfExpressionWithoutApplying(fnExpr, CS.DC, types);
+    getPossibleTypesOfExpressionWithoutApplying(fnExpr, CS.DC, types);
 
     auto isFunctionType = [getFuncType](Type type) -> bool {
       return type && getFuncType(type)->is<AnyFunctionType>();
@@ -5309,7 +5332,7 @@
              "unexpected declaration reference");
 
       ConcreteDeclRef decl = nullptr;
-      Type type = CS.TC.getTypeOfExpressionWithoutApplying(
+      Type type = getTypeOfExpressionWithoutApplying(
           fnExpr, CS.DC, decl, FreeTypeVariableBinding::UnresolvedType,
           &listener);
 
@@ -5893,7 +5916,7 @@
     ExprTypeSaverAndEraser eraser(srcExpr);
 
     ConcreteDeclRef ref = nullptr;
-    auto type = CS.TC.getTypeOfExpressionWithoutApplying(srcExpr, CS.DC, ref);
+    auto type = getTypeOfExpressionWithoutApplying(srcExpr, CS.DC, ref);
 
     if (type && !type->isEqual(contextualType))
       return diagnoseContextualConversionError(
@@ -6391,7 +6414,7 @@
       // diagnose situations where contextual type expected one result
       // type but actual closure produces a different one without explicitly
       // declaring it (e.g. by using anonymous parameters).
-      auto type = CS.TC.getTypeOfExpressionWithoutApplying(
+      auto type = getTypeOfExpressionWithoutApplying(
           closure, CS.DC, decl, FreeTypeVariableBinding::Disallow);
 
       if (type && resultTypeProcessor(type, expectedResultType))
@@ -6900,7 +6923,7 @@
     KeyPathListener listener(klass, parentType, rootType);
     ConcreteDeclRef concreteDecl;
 
-    auto derivedType = CS.TC.getTypeOfExpressionWithoutApplying(
+    auto derivedType = getTypeOfExpressionWithoutApplying(
         expr, CS.DC, concreteDecl, FreeTypeVariableBinding::Disallow,
         &listener);
 
@@ -8058,7 +8081,7 @@
       // successfully type-checked its type cleanup is going to be disabled
       // (we are allowing unresolved types), and as a side-effect it might
       // also be transformed e.g. OverloadedDeclRefExpr -> DeclRefExpr.
-      auto type = CS.TC.getTypeOfExpressionWithoutApplying(
+      auto type = getTypeOfExpressionWithoutApplying(
           resultExpr, CS.DC, decl, FreeTypeVariableBinding::UnresolvedType);
       if (type)
         resultType = type;
diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp
index 8e7159d..3c030eb 100644
--- a/lib/Sema/CSGen.cpp
+++ b/lib/Sema/CSGen.cpp
@@ -3368,6 +3368,20 @@
       assert(!isa<ImplicitConversionExpr>(expr) &&
              "ImplicitConversionExpr should be eliminated in walkToExprPre");
 
+      auto buildMemberRef = [&](Type memberType, Expr *base, SourceLoc dotLoc,
+                                ConcreteDeclRef member, DeclNameLoc memberLoc,
+                                bool implicit) -> Expr * {
+        auto *memberRef = new (TC.Context)
+            MemberRefExpr(base, dotLoc, member, memberLoc, implicit);
+
+        if (memberType) {
+          memberRef->setType(memberType);
+          return CS.cacheType(memberRef);
+        }
+
+        return memberRef;
+      };
+
       // A DotSyntaxCallExpr is a member reference that has already been
       // type-checked down to a call; turn it back into an overloaded
       // member reference expression.
@@ -3377,21 +3391,23 @@
                                                        memberLoc);
         if (memberAndFunctionRef.first) {
           assert(!isa<ImplicitConversionExpr>(dotCall->getBase()));
-          return new (TC.Context) MemberRefExpr(dotCall->getBase(),
-                                                dotCall->getDotLoc(),
-                                                memberAndFunctionRef.first,
-                                                memberLoc, expr->isImplicit());
+          return buildMemberRef(dotCall->getType(),
+                                dotCall->getBase(),
+                                dotCall->getDotLoc(),
+                                memberAndFunctionRef.first,
+                                memberLoc, expr->isImplicit());
         }
       }
 
       if (auto *dynamicMember = dyn_cast<DynamicMemberRefExpr>(expr)) {
         if (auto memberRef = dynamicMember->getMember()) {
           assert(!isa<ImplicitConversionExpr>(dynamicMember->getBase()));
-          return new (TC.Context) MemberRefExpr(dynamicMember->getBase(),
-                                                dynamicMember->getDotLoc(),
-                                                memberRef,
-                                                dynamicMember->getNameLoc(),
-                                                expr->isImplicit());
+          return buildMemberRef(dynamicMember->getType(),
+                                dynamicMember->getBase(),
+                                dynamicMember->getDotLoc(),
+                                memberRef,
+                                dynamicMember->getNameLoc(),
+                                expr->isImplicit());
         }
       }
 
@@ -3405,10 +3421,11 @@
                                                        memberLoc);
         if (memberAndFunctionRef.first) {
           assert(!isa<ImplicitConversionExpr>(dotIgnored->getLHS()));
-          return new (TC.Context) MemberRefExpr(dotIgnored->getLHS(),
-                                                dotIgnored->getDotLoc(),
-                                                memberAndFunctionRef.first,
-                                                memberLoc, expr->isImplicit());
+          return buildMemberRef(dotIgnored->getType(),
+                                dotIgnored->getLHS(),
+                                dotIgnored->getDotLoc(),
+                                memberAndFunctionRef.first,
+                                memberLoc, expr->isImplicit());
         }
       }
       return expr;
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 61b6fe1..99b24e1 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -1173,6 +1173,17 @@
             !params[0].isVariadic());
   };
 
+  auto canImplodeParams = [&](ArrayRef<AnyFunctionType::Param> params) {
+    if (params.size() == 1)
+      return false;
+
+    for (auto param : params)
+      if (param.isVariadic() || param.isInOut())
+        return false;
+
+    return true;
+  };
+
   auto implodeParams = [&](SmallVectorImpl<AnyFunctionType::Param> &params) {
     auto input = AnyFunctionType::composeInput(getASTContext(), params,
                                                /*canonicalVararg=*/false);
@@ -1193,21 +1204,18 @@
 
     if (last != path.rend()) {
       if (last->getKind() == ConstraintLocator::ApplyArgToParam) {
-        if (isSingleParam(func2Params)) {
-          if (!isSingleParam(func1Params)) {
-            implodeParams(func1Params);
-          }
-        } else if (getASTContext().isSwiftVersionAtLeast(4)
-                   && !getASTContext().isSwiftVersionAtLeast(5)
-                   && !isSingleParam(func2Params)) {
+        if (isSingleParam(func2Params) &&
+            canImplodeParams(func1Params)) {
+          implodeParams(func1Params);
+        } else if (!getASTContext().isSwiftVersionAtLeast(5) &&
+                   isSingleParam(func1Params) &&
+                   canImplodeParams(func2Params)) {
           auto *simplified = locator.trySimplifyToExpr();
           // We somehow let tuple unsplatting function conversions
           // through in some cases in Swift 4, so let's let that
           // continue to work, but only for Swift 4.
           if (simplified && isa<DeclRefExpr>(simplified)) {
-            if (isSingleParam(func1Params)) {
-              implodeParams(func2Params);
-            }
+            implodeParams(func2Params);
           }
         }
       }
diff --git a/lib/Sema/CodeSynthesis.cpp b/lib/Sema/CodeSynthesis.cpp
index 7abc16f..791b63b 100644
--- a/lib/Sema/CodeSynthesis.cpp
+++ b/lib/Sema/CodeSynthesis.cpp
@@ -226,10 +226,10 @@
   getter->setImplicit();
 
   // If we're stealing the 'self' from a lazy initializer, set it now.
-  if (selfDecl) {
+  // Note that we don't re-parent the 'self' declaration to be part of
+  // the getter until we synthesize the body of the getter later.
+  if (selfDecl)
     *getter->getImplicitSelfDeclStorage() = selfDecl;
-    selfDecl->setDeclContext(getter);
-  }
 
   // We need to install the generic environment here because:
   // 1) validating the getter will change the implicit self decl's DC to it,
@@ -1315,6 +1315,7 @@
 
   // Recontextualize any closure declcontexts nested in the initializer to
   // realize that they are in the getter function.
+  Get->getImplicitSelfDecl()->setDeclContext(Get);
   InitValue->walk(RecontextualizeClosures(Get));
 
   // Wrap the initializer in a LazyInitializerExpr to avoid problems with
diff --git a/lib/Sema/MiscDiagnostics.cpp b/lib/Sema/MiscDiagnostics.cpp
index a7f46c2..d13c775 100644
--- a/lib/Sema/MiscDiagnostics.cpp
+++ b/lib/Sema/MiscDiagnostics.cpp
@@ -203,10 +203,6 @@
       while (auto Conv = dyn_cast<ImplicitConversionExpr>(Base))
         Base = Conv->getSubExpr();
 
-      // Record call arguments.
-      if (auto Call = dyn_cast<CallExpr>(Base))
-        CallArgs.insert(Call->getArg());
-
       if (auto *DRE = dyn_cast<DeclRefExpr>(Base)) {
         // Verify metatype uses.
         if (isa<TypeDecl>(DRE->getDecl())) {
@@ -235,7 +231,14 @@
       if (isa<TypeExpr>(Base))
         checkUseOfMetaTypeName(Base);
 
+      if (auto *TSE = dyn_cast<TupleShuffleExpr>(E)) {
+        if (CallArgs.count(TSE))
+          CallArgs.insert(TSE->getSubExpr());
+      }
+
       if (auto *SE = dyn_cast<SubscriptExpr>(E)) {
+        CallArgs.insert(SE->getIndex());
+
         // Implicit InOutExpr's are allowed in the base of a subscript expr.
         if (auto *IOE = dyn_cast<InOutExpr>(SE->getBase()))
           if (IOE->isImplicit())
@@ -248,6 +251,13 @@
         });
       }
 
+      if (auto *KPE = dyn_cast<KeyPathExpr>(E)) {
+        for (auto Comp : KPE->getComponents()) {
+          if (auto *Arg = Comp.getIndexExpr())
+            CallArgs.insert(Arg);
+        }
+      }
+
       if (auto *AE = dyn_cast<CollectionExpr>(E)) {
         visitCollectionElements(AE, [&](unsigned argIndex, Expr *arg) {
           arg = lookThroughArgument(arg);
@@ -266,6 +276,9 @@
       // Check function calls, looking through implicit conversions on the
       // function and inspecting the arguments directly.
       if (auto *Call = dyn_cast<ApplyExpr>(E)) {
+        // Record call arguments.
+        CallArgs.insert(Call->getArg());
+
         // Warn about surprising implicit optional promotions.
         checkOptionalPromotions(Call);
         
@@ -381,6 +394,18 @@
         }
       }
 
+      // Diagnose single-element tuple expressions.
+      if (auto *tupleExpr = dyn_cast<TupleExpr>(E)) {
+        if (!CallArgs.count(tupleExpr)) {
+          if (tupleExpr->getNumElements() == 1) {
+            TC.diagnose(tupleExpr->getElementNameLoc(0),
+                        diag::tuple_single_element)
+              .fixItRemoveChars(tupleExpr->getElementNameLoc(0),
+                                tupleExpr->getElement(0)->getStartLoc());
+          }
+        }
+      }
+
       return { true, E };
     }
 
diff --git a/lib/Sema/TypeCheckCaptures.cpp b/lib/Sema/TypeCheckCaptures.cpp
index fa82ed3..685300e 100644
--- a/lib/Sema/TypeCheckCaptures.cpp
+++ b/lib/Sema/TypeCheckCaptures.cpp
@@ -283,15 +283,14 @@
         // recontextualized into it, so treat it as if it's already there.
         if (auto init = dyn_cast<PatternBindingInitializer>(TmpDC)) {
           if (auto lazyVar = init->getInitializedLazyVar()) {
-            // Referring to the 'self' parameter is fine.
-            if (D == init->getImplicitSelfDecl())
-              return { false, DRE };
-
-            // Otherwise, act as if we're in the getter.
-            auto getter = lazyVar->getGetter();
-            assert(getter && "lazy variable without getter");
-            TmpDC = getter;
-            continue;
+            // If we have a getter with a body, we're already re-parented
+            // everything so pretend we're inside the getter.
+            if (auto getter = lazyVar->getGetter()) {
+              if (getter->getBody(/*canSynthesize=*/false)) {
+                TmpDC = getter;
+                continue;
+              }
+            }
           }
         }
 
diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp
index 0928bcb..13e4f1a 100644
--- a/lib/Sema/TypeCheckDecl.cpp
+++ b/lib/Sema/TypeCheckDecl.cpp
@@ -3563,7 +3563,11 @@
 
 /// Validate the underlying type of the given typealias.
 static void validateTypealiasType(TypeChecker &tc, TypeAliasDecl *typeAlias) {
-  TypeResolutionOptions options(TypeResolverContext::TypeAliasDecl);
+  TypeResolutionOptions options(
+    (typeAlias->getGenericParams() ?
+     TypeResolverContext::GenericTypeAliasDecl :
+     TypeResolverContext::TypeAliasDecl));
+
   if (!typeAlias->getDeclContext()->isCascadingContextForLookup(
         /*functionsAreNonCascading*/true)) {
      options |= TypeResolutionFlags::KnownNonCascadingDependency;
@@ -4566,7 +4570,10 @@
         if (typealias->isBeingValidated()) return;
 
         auto helper = [&] {
-          TypeResolutionOptions options(TypeResolverContext::TypeAliasDecl);
+          TypeResolutionOptions options(
+            (typealias->getGenericParams() ?
+             TypeResolverContext::GenericTypeAliasDecl :
+             TypeResolverContext::TypeAliasDecl));
           if (validateType(typealias->getUnderlyingTypeLoc(),
                            TypeResolution::forStructural(typealias), options)) {
             typealias->setInvalid();
@@ -4844,26 +4851,21 @@
 
 /// Form the interface type of an extension from the raw type and the
 /// extension's list of generic parameters.
-static Type formExtensionInterfaceType(TypeChecker &tc, ExtensionDecl *ext,
-                                       Type type,
-                                       GenericParamList *genericParams,
-                                       bool &mustInferRequirements) {
+static Type formExtensionInterfaceType(
+                         TypeChecker &tc, ExtensionDecl *ext,
+                         Type type,
+                         GenericParamList *genericParams,
+                         SmallVectorImpl<std::pair<Type, Type>> &sameTypeReqs,
+                         bool &mustInferRequirements) {
   if (type->is<ErrorType>())
     return type;
 
   // Find the nominal type declaration and its parent type.
-  Type parentType;
-  GenericTypeDecl *genericDecl;
-  if (auto unbound = type->getAs<UnboundGenericType>()) {
-    parentType = unbound->getParent();
-    genericDecl = unbound->getDecl();
-  } else {
-    if (type->is<ProtocolCompositionType>())
-      type = type->getCanonicalType();
-    auto nominalType = type->castTo<NominalType>();
-    parentType = nominalType->getParent();
-    genericDecl = nominalType->getDecl();
-  }
+  if (type->is<ProtocolCompositionType>())
+    type = type->getCanonicalType();
+
+  Type parentType = type->getNominalParent();
+  GenericTypeDecl *genericDecl = type->getAnyGeneric();
 
   // Reconstruct the parent, if there is one.
   if (parentType) {
@@ -4873,7 +4875,7 @@
                                  : genericParams;
     parentType =
       formExtensionInterfaceType(tc, ext, parentType, parentGenericParams,
-                                 mustInferRequirements);
+                                 sameTypeReqs, mustInferRequirements);
   }
 
   // Find the nominal type.
@@ -4891,9 +4893,20 @@
     resultType = NominalType::get(nominal, parentType,
                                   nominal->getASTContext());
   } else {
+    auto currentBoundType = type->getAs<BoundGenericType>();
+
     // Form the bound generic type with the type parameters provided.
+    unsigned gpIndex = 0;
     for (auto gp : *genericParams) {
-      genericArgs.push_back(gp->getDeclaredInterfaceType());
+      SWIFT_DEFER { ++gpIndex; };
+
+      auto gpType = gp->getDeclaredInterfaceType();
+      genericArgs.push_back(gpType);
+
+      if (currentBoundType) {
+        sameTypeReqs.push_back({gpType,
+                                currentBoundType->getGenericArgs()[gpIndex]});
+      }
     }
 
     resultType = BoundGenericType::get(nominal, parentType, genericArgs);
@@ -4930,8 +4943,9 @@
 
   // Form the interface type of the extension.
   bool mustInferRequirements = false;
+  SmallVector<std::pair<Type, Type>, 4> sameTypeReqs;
   Type extInterfaceType =
-    formExtensionInterfaceType(tc, ext, type, genericParams,
+    formExtensionInterfaceType(tc, ext, type, genericParams, sameTypeReqs,
                                mustInferRequirements);
 
   // Local function used to infer requirements from the extended type.
@@ -4943,6 +4957,13 @@
                               extInterfaceType,
                               nullptr,
                               source);
+
+    for (const auto &sameTypeReq : sameTypeReqs) {
+      builder.addRequirement(
+        Requirement(RequirementKind::SameType, sameTypeReq.first,
+                    sameTypeReq.second),
+        source, ext->getModuleContext());
+    }
   };
 
   // Validate the generic type signature.
@@ -4950,11 +4971,20 @@
                                          ext->getDeclContext(), nullptr,
                                          /*allowConcreteGenericParams=*/true,
                                          ext, inferExtendedTypeReqs,
-                                         mustInferRequirements);
+                                         (mustInferRequirements ||
+                                            !sameTypeReqs.empty()));
 
   return { env, extInterfaceType };
 }
 
+static bool isNonGenericTypeAliasType(Type type) {
+  // A non-generic typealias can extend a specialized type.
+  if (auto *aliasType = dyn_cast<NameAliasType>(type.getPointer()))
+    return aliasType->getDecl()->getGenericParamsOfContext() == nullptr;
+
+  return false;
+}
+
 static void validateExtendedType(ExtensionDecl *ext, TypeChecker &tc) {
   // If we didn't parse a type, fill in an error type and bail out.
   if (!ext->getExtendedTypeLoc().getTypeRepr()) {
@@ -4998,20 +5028,22 @@
     return;
   }
 
-  // Cannot extend a bound generic type.
-  if (extendedType->isSpecialized()) {
-    tc.diagnose(ext->getLoc(), diag::extension_specialization,
-             extendedType->getAnyNominal()->getName())
+  // Cannot extend function types, tuple types, etc.
+  if (!extendedType->getAnyNominal()) {
+    tc.diagnose(ext->getLoc(), diag::non_nominal_extension, extendedType)
       .highlight(ext->getExtendedTypeLoc().getSourceRange());
     ext->setInvalid();
     ext->getExtendedTypeLoc().setInvalidType(tc.Context);
     return;
   }
 
-  // Cannot extend function types, tuple types, etc.
-  if (!extendedType->getAnyNominal()) {
-    tc.diagnose(ext->getLoc(), diag::non_nominal_extension, extendedType)
-      .highlight(ext->getExtendedTypeLoc().getSourceRange());
+  // Cannot extend a bound generic type, unless it's referenced via a
+  // non-generic typealias type.
+  if (extendedType->isSpecialized() &&
+      !isNonGenericTypeAliasType(extendedType)) {
+    tc.diagnose(ext->getLoc(), diag::extension_specialization,
+                extendedType->getAnyNominal()->getName())
+    .highlight(ext->getExtendedTypeLoc().getSourceRange());
     ext->setInvalid();
     ext->getExtendedTypeLoc().setInvalidType(tc.Context);
     return;
diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp
index e60aa87..baf317e 100644
--- a/lib/Sema/TypeCheckType.cpp
+++ b/lib/Sema/TypeCheckType.cpp
@@ -476,19 +476,18 @@
       genericParam->getDeclaredInterfaceType());
   }
 
-  // If we are referring to a type within its own context, and we have either
-  // a generic type with no generic arguments or a non-generic type, use the
-  // type within the context.
-  if (auto nominalType = dyn_cast<NominalTypeDecl>(typeDecl)) {
-    if (!isa<ProtocolDecl>(nominalType) &&
-        (!nominalType->getGenericParams() || !isSpecialized)) {
-      for (auto parentDC = fromDC;
+  if (!isSpecialized) {
+    // If we are referring to a type within its own context, and we have either
+    // a generic type with no generic arguments or a non-generic type, use the
+    // type within the context.
+    if (auto *nominalType = dyn_cast<NominalTypeDecl>(typeDecl)) {
+      for (auto *parentDC = fromDC;
            !parentDC->isModuleScopeContext();
            parentDC = parentDC->getParent()) {
         auto *parentNominal = parentDC->getSelfNominalTypeDecl();
         if (parentNominal == nominalType)
           return resolution.mapTypeIntoContext(
-            parentDC->getSelfInterfaceType());
+            parentDC->getDeclaredInterfaceType());
         if (isa<ExtensionDecl>(parentDC)) {
           auto *extendedType = parentNominal;
           while (extendedType != nullptr) {
@@ -500,6 +499,27 @@
         }
       }
     }
+
+    // If we're inside an extension of a type alias, allow the type alias to be
+    // referenced without generic arguments as well.
+    if (auto *aliasDecl = dyn_cast<TypeAliasDecl>(typeDecl)) {
+      for (auto *parentDC = fromDC;
+            !parentDC->isModuleScopeContext();
+            parentDC = parentDC->getParent()) {
+        if (auto *ext = dyn_cast<ExtensionDecl>(parentDC)) {
+          auto extendedType = ext->getExtendedType();
+          if (auto *aliasType = dyn_cast<NameAliasType>(extendedType.getPointer())) {
+            if (aliasType->getDecl() == aliasDecl) {
+              return resolution.mapTypeIntoContext(
+                  aliasDecl->getDeclaredInterfaceType());
+            }
+
+            extendedType = aliasType->getParent();
+            continue;
+          }
+        }
+      }
+    }
   }
 
   // Simple case -- the type is not nested inside of another type.
@@ -2894,6 +2914,7 @@
   case TypeResolverContext::EnumElementDecl:
   case TypeResolverContext::EnumPatternPayload:
   case TypeResolverContext::TypeAliasDecl:
+  case TypeResolverContext::GenericTypeAliasDecl:
   case TypeResolverContext::GenericRequirement:
   case TypeResolverContext::ImmediateOptionalTypeArgument:
   case TypeResolverContext::InExpression:
diff --git a/lib/Sema/TypeCheckType.h b/lib/Sema/TypeCheckType.h
index 7b3c782..5bff7a6 100644
--- a/lib/Sema/TypeCheckType.h
+++ b/lib/Sema/TypeCheckType.h
@@ -118,9 +118,12 @@
   /// Whether this is the payload subpattern of an enum pattern.
   EnumPatternPayload,
 
-  /// Whether we are checking the underlying type of a typealias.
+  /// Whether we are checking the underlying type of a non-generic typealias.
   TypeAliasDecl,
 
+  /// Whether we are checking the underlying type of a generic typealias.
+  GenericTypeAliasDecl,
+
   /// Whether we are in a requirement of a generic declaration
   GenericRequirement,
 
@@ -207,6 +210,7 @@
     case Context::EnumElementDecl:
     case Context::EnumPatternPayload:
     case Context::TypeAliasDecl:
+    case Context::GenericTypeAliasDecl:
     case Context::GenericRequirement:
     case Context::ImmediateOptionalTypeArgument:
     case Context::AbstractFunctionDecl:
diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp
index e06d4f0..f40a9ad 100644
--- a/lib/Serialization/Serialization.cpp
+++ b/lib/Serialization/Serialization.cpp
@@ -1345,9 +1345,15 @@
 void Serializer::writeInlinableBodyTextIfNeeded(
   const AbstractFunctionDecl *AFD) {
   using namespace decls_block;
+  // Only serialize the text for an inlinable function body if we're emitting
+  // a partial module. It's not needed in the final module file, but it's
+  // needed in partial modules so you can emit a parseable interface after
+  // merging them.
+  if (!SF) return;
 
   if (AFD->getResilienceExpansion() != swift::ResilienceExpansion::Minimal)
     return;
+
   if (!AFD->hasInlinableBodyText()) return;
   SmallString<128> scratch;
   auto body = AFD->getInlinableBodyText(scratch);
diff --git a/stdlib/public/SDK/Foundation/CMakeLists.txt b/stdlib/public/SDK/Foundation/CMakeLists.txt
index 7a38578..4d18d84 100644
--- a/stdlib/public/SDK/Foundation/CMakeLists.txt
+++ b/stdlib/public/SDK/Foundation/CMakeLists.txt
@@ -8,7 +8,13 @@
   Calendar.swift
   CharacterSet.swift
   Codable.swift
+  Collections+DataProtocol.swift
+  ContiguousBytes.swift
   Data.swift
+  DataProtocol.swift
+  DispatchData+DataProtocol.swift
+  NSData+DataProtocol.swift
+  Pointers+DataProtocol.swift
   DataThunks.m
   Date.swift
   DateComponents.swift
diff --git a/stdlib/public/SDK/Foundation/Collections+DataProtocol.swift b/stdlib/public/SDK/Foundation/Collections+DataProtocol.swift
new file mode 100644
index 0000000..3125f9a
--- /dev/null
+++ b/stdlib/public/SDK/Foundation/Collections+DataProtocol.swift
@@ -0,0 +1,61 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+//===--- DataProtocol -----------------------------------------------------===//
+
+extension Array: DataProtocol where Element == UInt8 {
+    public var regions: CollectionOfOne<Array<UInt8>> {
+        return CollectionOfOne(self)
+    }
+}
+
+extension ArraySlice: DataProtocol where Element == UInt8 {
+    public var regions: CollectionOfOne<ArraySlice<UInt8>> {
+        return CollectionOfOne(self)
+    }
+}
+
+extension ContiguousArray: DataProtocol where Element == UInt8 {
+    public var regions: CollectionOfOne<ContiguousArray<UInt8>> {
+        return CollectionOfOne(self)
+    }
+}
+
+// FIXME: This currently crashes compilation in the Late Inliner.
+// extension CollectionOfOne : DataProtocol where Element == UInt8 {
+//     public typealias Regions = CollectionOfOne<Data>
+//
+//     public var regions: CollectionOfOne<Data> {
+//         return CollectionOfOne<Data>(Data(self))
+//     }
+// }
+
+extension EmptyCollection : DataProtocol where Element == UInt8 {
+    public var regions: EmptyCollection<Data> {
+        return EmptyCollection<Data>()
+    }
+}
+
+extension Repeated: DataProtocol where Element == UInt8 {
+    public typealias Regions = Repeated<Data>
+
+    public var regions: Repeated<Data> {
+        guard self.count > 0 else { return repeatElement(Data(), count: 0) }
+        return repeatElement(Data(CollectionOfOne(self.first!)), count: self.count)
+    }
+}
+
+//===--- MutableDataProtocol ----------------------------------------------===//
+
+extension Array: MutableDataProtocol where Element == UInt8 { }
+
+extension ContiguousArray: MutableDataProtocol where Element == UInt8 { }
diff --git a/stdlib/public/SDK/Foundation/ContiguousBytes.swift b/stdlib/public/SDK/Foundation/ContiguousBytes.swift
new file mode 100644
index 0000000..0d1f69b
--- /dev/null
+++ b/stdlib/public/SDK/Foundation/ContiguousBytes.swift
@@ -0,0 +1,100 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+//===--- ContiguousBytes --------------------------------------------------===//
+
+/// Indicates that the conforming type is a contiguous collection of raw bytes
+/// whose underlying storage is directly accessible by withUnsafeBytes.
+public protocol ContiguousBytes {
+    /// Calls the given closure with the contents of underlying storage.
+    ///
+    /// - note: Calling `withUnsafeBytes` multiple times does not guarantee that
+    ///         the same buffer pointer will be passed in every time.
+    /// - warning: The buffer argument to the body should not be stored or used
+    ///            outside of the lifetime of the call to the closure.
+    func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
+}
+
+//===--- Collection Conformances ------------------------------------------===//
+
+// FIXME: When possible, expand conformance to `where Element : Trivial`.
+extension Array : ContiguousBytes where Element == UInt8 { }
+
+// FIXME: When possible, expand conformance to `where Element : Trivial`.
+extension ArraySlice : ContiguousBytes where Element == UInt8 { }
+
+// FIXME: When possible, expand conformance to `where Element : Trivial`.
+extension ContiguousArray : ContiguousBytes where Element == UInt8 { }
+
+//===--- Pointer Conformances ---------------------------------------------===//
+
+extension UnsafeRawBufferPointer : ContiguousBytes {
+    @inlinable
+    public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
+        return try body(self)
+    }
+}
+
+extension UnsafeMutableRawBufferPointer : ContiguousBytes {
+    @inlinable
+    public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
+        return try body(UnsafeRawBufferPointer(self))
+    }
+}
+
+// FIXME: When possible, expand conformance to `where Element : Trivial`.
+extension UnsafeBufferPointer : ContiguousBytes where Element == UInt8 {
+    @inlinable
+    public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
+        return try body(UnsafeRawBufferPointer(self))
+    }
+}
+
+// FIXME: When possible, expand conformance to `where Element : Trivial`.
+extension UnsafeMutableBufferPointer : ContiguousBytes where Element == UInt8 {
+    @inlinable
+    public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
+        return try body(UnsafeRawBufferPointer(self))
+    }
+}
+
+// FIXME: When possible, expand conformance to `where Element : Trivial`.
+extension EmptyCollection : ContiguousBytes where Element == UInt8 {
+    @inlinable
+    public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
+        return try body(UnsafeRawBufferPointer(start: nil, count: 0))
+    }
+}
+
+// FIXME: When possible, expand conformance to `where Element : Trivial`.
+extension CollectionOfOne : ContiguousBytes where Element == UInt8 {
+    @inlinable
+    public func withUnsafeBytes<R>(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R {
+        let element = self.first!
+        return try Swift.withUnsafeBytes(of: element) {
+            return try body($0)
+        }
+    }
+}
+
+//===--- Conditional Conformances -----------------------------------------===//
+
+extension Slice : ContiguousBytes where Base : ContiguousBytes {
+    public func withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
+        let offset = base.distance(from: base.startIndex, to: self.startIndex)
+        return try base.withUnsafeBytes { ptr in
+            let slicePtr = ptr.baseAddress?.advanced(by: offset)
+            let sliceBuffer = UnsafeRawBufferPointer(start: slicePtr, count: self.count)
+            return try body(sliceBuffer)
+        }
+    }
+}
diff --git a/stdlib/public/SDK/Foundation/Data.swift b/stdlib/public/SDK/Foundation/Data.swift
index f666f0f..921f21d 100644
--- a/stdlib/public/SDK/Foundation/Data.swift
+++ b/stdlib/public/SDK/Foundation/Data.swift
@@ -16,6 +16,12 @@
 import Darwin
 #elseif os(Linux)
 import Glibc
+
+@inlinable
+fileprivate func malloc_good_size(_ size: Int) -> Int {
+    return size
+}
+
 #endif
 
 import CoreFoundation
@@ -59,29 +65,11 @@
 @usableFromInline
 internal final class _DataStorage {
     @usableFromInline
-    enum Backing {
-        // A mirror of the Objective-C implementation that is suitable to inline in Swift
-        case swift
-        
-        // these two storage points for immutable and mutable data are reserved for references that are returned by "known"
-        // cases from Foundation in which implement the backing of struct Data, these have signed up for the concept that
-        // the backing bytes/mutableBytes pointer does not change per call (unless mutated) as well as the length is ok
-        // to be cached, this means that as long as the backing reference is retained no further objc_msgSends need to be
-        // dynamically dispatched out to the reference.
-        case immutable(NSData) // This will most often (perhaps always) be NSConcreteData
-        case mutable(NSMutableData) // This will often (perhaps always) be NSConcreteMutableData
-        
-        // These are reserved for foreign sources where neither Swift nor Foundation are fully certain whom they belong
-        // to from an object inheritance standpoint, this means that all bets are off and the values of bytes, mutableBytes,
-        // and length cannot be cached. This also means that all methods are expected to dynamically dispatch out to the
-        // backing reference.
-        case customReference(NSData) // tracks data references that are only known to be immutable
-        case customMutableReference(NSMutableData) // tracks data references that are known to be mutable
-    }
-    
     static let maxSize = Int.max >> 1
+    @usableFromInline
     static let vmOpsThreshold = NSPageSize() * 4
     
+    @inlinable
     static func allocate(_ size: Int, _ clear: Bool) -> UnsafeMutableRawPointer? {
         if clear {
             return calloc(1, size)
@@ -90,7 +78,7 @@
         }
     }
     
-    @usableFromInline
+    @inlinable
     static func move(_ dest_: UnsafeMutableRawPointer, _ source_: UnsafeRawPointer?, _ num_: Int) {
         var dest = dest_
         var source = source_
@@ -107,6 +95,7 @@
         }
     }
     
+    @inlinable
     static func shouldAllocateCleared(_ size: Int) -> Bool {
         return (size > (128 * 1024))
     }
@@ -122,186 +111,152 @@
     @usableFromInline
     var _deallocator: ((UnsafeMutableRawPointer, Int) -> Void)?
     @usableFromInline
-    var _backing: Backing = .swift
-    @usableFromInline
     var _offset: Int
     
-    @usableFromInline
+    @inlinable
     var bytes: UnsafeRawPointer? {
-        @inlinable
-        get {
-            switch _backing {
-            case .swift:
-                return UnsafeRawPointer(_bytes)?.advanced(by: -_offset)
-            case .immutable:
-                return UnsafeRawPointer(_bytes)?.advanced(by: -_offset)
-            case .mutable:
-                return UnsafeRawPointer(_bytes)?.advanced(by: -_offset)
-            case .customReference(let d):
-                return d.bytes.advanced(by: -_offset)
-            case .customMutableReference(let d):
-                return d.bytes.advanced(by: -_offset)
-            @unknown default:
-                fatalError("Unknown Data backing type")
-            }
-        }
+        return UnsafeRawPointer(_bytes)?.advanced(by: -_offset)
     }
 
-    @usableFromInline
+    @inlinable
     @discardableResult
     func withUnsafeBytes<Result>(in range: Range<Int>, apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
-        switch _backing {
-        case .swift: fallthrough
-        case .immutable: fallthrough
-        case .mutable:
-            return try apply(UnsafeRawBufferPointer(start: _bytes?.advanced(by: range.lowerBound - _offset), count: Swift.min(range.count, _length)))
-        case .customReference(let d):
-            if __NSDataIsCompact(d) {
-                let len = d.length
-                guard len > 0 else {
-                    return try apply(UnsafeRawBufferPointer(start: nil, count: 0))
-                }
-                return try apply(UnsafeRawBufferPointer(start: d.bytes.advanced(by: range.lowerBound - _offset), count: Swift.min(range.count, len)))
-            } else {
-                var buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: range.count, alignment: MemoryLayout<UInt>.alignment)
-                defer { buffer.deallocate() }
-
-                let sliceRange = NSRange(location: range.lowerBound - _offset, length: range.count)
-                var enumerated = 0
-                d.enumerateBytes { (ptr, byteRange, stop) in
-                    if byteRange.upperBound - _offset < range.lowerBound {
-                        // before the range that we are looking for...
-                    } else if byteRange.lowerBound - _offset > range.upperBound {
-                        stop.pointee = true // we are past the range in question so we need to stop
-                    } else {
-                        // the byteRange somehow intersects the range in question that we are looking for...
-                        let lower = Swift.max(byteRange.lowerBound - _offset, range.lowerBound)
-                        let upper = Swift.min(byteRange.upperBound - _offset, range.upperBound)
-
-                        let len = upper - lower
-                        memcpy(buffer.baseAddress!.advanced(by: enumerated), ptr.advanced(by: lower - (byteRange.lowerBound - _offset)), len)
-                        enumerated += len
-
-                        if upper == range.upperBound {
-                            stop.pointee = true
-                        }
-                    }
-                }
-                return try apply(UnsafeRawBufferPointer(buffer))
-            }
-        case .customMutableReference(let d):
-            if __NSDataIsCompact(d) {
-                let len = d.length
-                guard len > 0 else {
-                    return try apply(UnsafeRawBufferPointer(start: nil, count: 0))
-                }
-                return try apply(UnsafeRawBufferPointer(start: d.bytes.advanced(by: range.lowerBound - _offset), count: Swift.min(range.count, len)))
-            } else {
-                var buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: range.count, alignment: MemoryLayout<UInt>.alignment)
-                defer { buffer.deallocate() }
-
-                var enumerated = 0
-                d.enumerateBytes { (ptr, byteRange, stop) in
-                    if byteRange.upperBound - _offset < range.lowerBound {
-                        // before the range that we are looking for...
-                    } else if byteRange.lowerBound - _offset > range.upperBound {
-                        stop.pointee = true // we are past the range in question so we need to stop
-                    } else {
-                        // the byteRange somehow intersects the range in question that we are looking for...
-                        let lower = Swift.max(byteRange.lowerBound - _offset, range.lowerBound)
-                        let upper = Swift.min(byteRange.upperBound - _offset, range.upperBound)
-
-                        let len = upper - lower
-                        memcpy(buffer.baseAddress!.advanced(by: enumerated), ptr.advanced(by: lower - (byteRange.lowerBound - _offset)), len)
-                        enumerated += len
-
-                        if upper == range.upperBound {
-                            stop.pointee = true
-                        }
-                    }
-                }
-                return try apply(UnsafeRawBufferPointer(buffer))
-            }
-        }
+        return try apply(UnsafeRawBufferPointer(start: _bytes?.advanced(by: range.lowerBound - _offset), count: Swift.min(range.upperBound - range.lowerBound, _length)))
     }
     
-    @usableFromInline
+    @inlinable
     @discardableResult
     func withUnsafeMutableBytes<Result>(in range: Range<Int>, apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
-        switch _backing {
-        case .swift: fallthrough
-        case .mutable:
-            return try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, _length)))
-        case .customMutableReference(let d):
-            let len = d.length
-            return try apply(UnsafeMutableRawBufferPointer(start: d.mutableBytes.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, len)))
-        case .immutable(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            _backing = .mutable(data)
-            _bytes = data.mutableBytes
-            return try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, _length)))
-        case .customReference(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            _backing = .customMutableReference(data)
-            let len = data.length
-            return try apply(UnsafeMutableRawBufferPointer(start: data.mutableBytes.advanced(by:range.lowerBound - _offset), count: Swift.min(range.count, len)))
-        }
+        return try apply(UnsafeMutableRawBufferPointer(start: _bytes!.advanced(by:range.lowerBound - _offset), count: Swift.min(range.upperBound - range.lowerBound, _length)))
     }
 
+    @inlinable
     var mutableBytes: UnsafeMutableRawPointer? {
-        @inlinable
-        get {
-            switch _backing {
-            case .swift:
-                return _bytes?.advanced(by: -_offset)
-            case .immutable(let d):
-                let data = d.mutableCopy() as! NSMutableData
-                data.length = length
-                _backing = .mutable(data)
-                _bytes = data.mutableBytes
-                return _bytes?.advanced(by: -_offset)
-            case .mutable:
-                return _bytes?.advanced(by: -_offset)
-            case .customReference(let d):
-                let data = d.mutableCopy() as! NSMutableData
-                data.length = length
-                _backing = .customMutableReference(data)
-                return data.mutableBytes.advanced(by: -_offset)
-            case .customMutableReference(let d):
-                return d.mutableBytes.advanced(by: -_offset)
-            @unknown default:
-                fatalError("Unknown Data backing type")
-            }
-        }
+        return _bytes?.advanced(by: -_offset)
     }
+
+    @inlinable
+    var capacity: Int { return _capacity }
     
-    
-    @usableFromInline
+    @inlinable
     var length: Int {
-        @inlinable
         get {
-            switch _backing {
-            case .swift:
-                return _length
-            case .immutable:
-                return _length
-            case .mutable:
-                return _length
-            case .customReference(let d):
-                return d.length
-            case .customMutableReference(let d):
-                return d.length
-            @unknown default:
-                fatalError("Unknown Data backing type")
-            }
+            return _length
         }
-        @inlinable
         set {
             setLength(newValue)
         }
     }
     
+    @inlinable
+    var isExternallyOwned: Bool {
+        // all _DataStorages will have some sort of capacity, because empty cases hit the .empty enum _Representation
+        // anything with 0 capacity means that we have not allocated this pointer and concequently mutation is not ours to make.
+        return _capacity == 0
+    }
     
+    @inlinable
+    func ensureUniqueBufferReference(growingTo newLength: Int = 0, clear: Bool = false) {
+        guard isExternallyOwned || newLength > _capacity else { return }
+
+        if newLength == 0 {
+            if isExternallyOwned {
+                let newCapacity = malloc_good_size(_length)
+                let newBytes = _DataStorage.allocate(newCapacity, false)
+                _DataStorage.move(newBytes!, _bytes!, _length)
+                _freeBytes()
+                _bytes = newBytes
+                _capacity = newCapacity
+                _needToZero = false
+            }
+        } else if isExternallyOwned {
+            let newCapacity = malloc_good_size(newLength)
+            let newBytes = _DataStorage.allocate(newCapacity, clear)
+            if let bytes = _bytes {
+                _DataStorage.move(newBytes!, bytes, _length)
+            }
+            _freeBytes()
+            _bytes = newBytes
+            _capacity = newCapacity
+            _length = newLength
+            _needToZero = true
+        } else {
+            let cap = _capacity
+            var additionalCapacity = (newLength >> (_DataStorage.vmOpsThreshold <= newLength ? 2 : 1))
+            if Int.max - additionalCapacity < newLength {
+                additionalCapacity = 0
+            }
+            var newCapacity = malloc_good_size(Swift.max(cap, newLength + additionalCapacity))
+            let origLength = _length
+            var allocateCleared = clear && _DataStorage.shouldAllocateCleared(newCapacity)
+            var newBytes: UnsafeMutableRawPointer? = nil
+            if _bytes == nil {
+                newBytes = _DataStorage.allocate(newCapacity, allocateCleared)
+                if newBytes == nil {
+                    /* Try again with minimum length */
+                    allocateCleared = clear && _DataStorage.shouldAllocateCleared(newLength)
+                    newBytes = _DataStorage.allocate(newLength, allocateCleared)
+                }
+            } else {
+                let tryCalloc = (origLength == 0 || (newLength / origLength) >= 4)
+                if allocateCleared && tryCalloc {
+                    newBytes = _DataStorage.allocate(newCapacity, true)
+                    if let newBytes = newBytes {
+                        _DataStorage.move(newBytes, _bytes!, origLength)
+                        _freeBytes()
+                    }
+                }
+                /* Where calloc/memmove/free fails, realloc might succeed */
+                if newBytes == nil {
+                    allocateCleared = false
+                    if _deallocator != nil {
+                        newBytes = _DataStorage.allocate(newCapacity, true)
+                        if let newBytes = newBytes {
+                            _DataStorage.move(newBytes, _bytes!, origLength)
+                            _freeBytes()
+                        }
+                    } else {
+                        newBytes = realloc(_bytes!, newCapacity)
+                    }
+                }
+                /* Try again with minimum length */
+                if newBytes == nil {
+                    newCapacity = malloc_good_size(newLength)
+                    allocateCleared = clear && _DataStorage.shouldAllocateCleared(newCapacity)
+                    if allocateCleared && tryCalloc {
+                        newBytes = _DataStorage.allocate(newCapacity, true)
+                        if let newBytes = newBytes {
+                            _DataStorage.move(newBytes, _bytes!, origLength)
+                            _freeBytes()
+                        }
+                    }
+                    if newBytes == nil {
+                        allocateCleared = false
+                        newBytes = realloc(_bytes!, newCapacity)
+                    }
+                }
+            }
+
+            if newBytes == nil {
+                /* Could not allocate bytes */
+                // At this point if the allocation cannot occur the process is likely out of memory
+                // and Bad-Things™ are going to happen anyhow
+                fatalError("unable to allocate memory for length (\(newLength))")
+            }
+
+            if origLength < newLength && clear && !allocateCleared {
+                memset(newBytes!.advanced(by: origLength), 0, newLength - origLength)
+            }
+
+            /* _length set by caller */
+            _bytes = newBytes
+            _capacity = newCapacity
+            /* Realloc/memset doesn't zero out the entire capacity, so we must be safe and clear next time we grow the length */
+            _needToZero = !allocateCleared
+        }
+    }
+
+    @inlinable
     func _freeBytes() {
         if let bytes = _bytes {
             if let dealloc = _deallocator {
@@ -310,186 +265,39 @@
                 free(bytes)
             }
         }
+        _deallocator = nil
     }
-    
+
+    @usableFromInline
     func enumerateBytes(in range: Range<Int>, _ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Data.Index, _ stop: inout Bool) -> Void) {
         var stopv: Bool = false
-        var data: NSData
-        switch _backing {
-        case .swift: fallthrough
-        case .immutable: fallthrough
-        case .mutable:
-            block(UnsafeBufferPointer<UInt8>(start: _bytes?.advanced(by: range.lowerBound - _offset).assumingMemoryBound(to: UInt8.self), count: Swift.min(range.count, _length)), 0, &stopv)
-            return
-        case .customReference(let d):
-            data = d
-            break
-        case .customMutableReference(let d):
-            data = d
-            break
-        }
-        data.enumerateBytes { (ptr, region, stop) in
-            // any region that is not in the range should be skipped
-            guard range.contains(region.lowerBound) || range.contains(region.upperBound) else { return }
-            var regionAdjustment = 0
-            if region.lowerBound < range.lowerBound {
-                regionAdjustment = range.lowerBound - (region.lowerBound - _offset)
-            }
-            let bytePtr  = ptr.advanced(by: regionAdjustment).assumingMemoryBound(to: UInt8.self)
-            let effectiveLength = Swift.min((region.location - _offset) + region.length, range.upperBound) - (region.location - _offset)
-            block(UnsafeBufferPointer(start: bytePtr, count: effectiveLength - regionAdjustment), region.location + regionAdjustment - _offset, &stopv)
-            if stopv {
-                stop.pointee = true
-            }
-        }
-    }
-    
-    @usableFromInline
-    @inline(never)
-    func _grow(_ newLength: Int, _ clear: Bool) {
-        let cap = _capacity
-        var additionalCapacity = (newLength >> (_DataStorage.vmOpsThreshold <= newLength ? 2 : 1))
-        if Int.max - additionalCapacity < newLength {
-            additionalCapacity = 0
-        }
-        var newCapacity = Swift.max(cap, newLength + additionalCapacity)
-        let origLength = _length
-        var allocateCleared = clear && _DataStorage.shouldAllocateCleared(newCapacity)
-        var newBytes: UnsafeMutableRawPointer? = nil
-        if _bytes == nil {
-            newBytes = _DataStorage.allocate(newCapacity, allocateCleared)
-            if newBytes == nil {
-                /* Try again with minimum length */
-                allocateCleared = clear && _DataStorage.shouldAllocateCleared(newLength)
-                newBytes = _DataStorage.allocate(newLength, allocateCleared)
-            }
-        } else {
-            let tryCalloc = (origLength == 0 || (newLength / origLength) >= 4)
-            if allocateCleared && tryCalloc {
-                newBytes = _DataStorage.allocate(newCapacity, true)
-                if let newBytes = newBytes {
-                    _DataStorage.move(newBytes, _bytes!, origLength)
-                    _freeBytes()
-                }
-            }
-            /* Where calloc/memmove/free fails, realloc might succeed */
-            if newBytes == nil {
-                allocateCleared = false
-                if _deallocator != nil {
-                    newBytes = _DataStorage.allocate(newCapacity, true)
-                    if let newBytes = newBytes {
-                        _DataStorage.move(newBytes, _bytes!, origLength)
-                        _freeBytes()
-                        _deallocator = nil
-                    }
-                } else {
-                    newBytes = realloc(_bytes!, newCapacity)
-                }
-            }
-            
-            /* Try again with minimum length */
-            if newBytes == nil {
-                newCapacity = newLength
-                allocateCleared = clear && _DataStorage.shouldAllocateCleared(newCapacity)
-                if allocateCleared && tryCalloc {
-                    newBytes = _DataStorage.allocate(newCapacity, true)
-                    if let newBytes = newBytes {
-                        _DataStorage.move(newBytes, _bytes!, origLength)
-                        _freeBytes()
-                    }
-                }
-                if newBytes == nil {
-                    allocateCleared = false
-                    newBytes = realloc(_bytes!, newCapacity)
-                }
-            }
-        }
-        
-        if newBytes == nil {
-            /* Could not allocate bytes */
-            // At this point if the allocation cannot occur the process is likely out of memory
-            // and Bad-Things™ are going to happen anyhow
-            fatalError("unable to allocate memory for length (\(newLength))")
-        }
-        
-        if origLength < newLength && clear && !allocateCleared {
-            memset(newBytes!.advanced(by: origLength), 0, newLength - origLength)
-        }
-        
-        /* _length set by caller */
-        _bytes = newBytes
-        _capacity = newCapacity
-        /* Realloc/memset doesn't zero out the entire capacity, so we must be safe and clear next time we grow the length */
-        _needToZero = !allocateCleared
+        block(UnsafeBufferPointer<UInt8>(start: _bytes?.advanced(by: range.lowerBound - _offset).assumingMemoryBound(to: UInt8.self), count: Swift.min(range.upperBound - range.lowerBound, _length)), 0, &stopv)
     }
     
     @inlinable
     func setLength(_ length: Int) {
-        switch _backing {
-        case .swift:
-            let origLength = _length
-            let newLength = length
-            if _capacity < newLength || _bytes == nil {
-                _grow(newLength, true)
-            } else if origLength < newLength && _needToZero {
-                memset(_bytes! + origLength, 0, newLength - origLength)
-            } else if newLength < origLength {
-                _needToZero = true
-            }
-            _length = newLength
-        case .immutable(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.length = length
-            _backing = .mutable(data)
-            _length = length
-            _bytes = data.mutableBytes
-        case .mutable(let d):
-            d.length = length
-            _length = length
-            _bytes = d.mutableBytes
-        case .customReference(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.length = length
-            _backing = .customMutableReference(data)
-        case .customMutableReference(let d):
-            d.length = length
-        @unknown default:
-            fatalError("Unknown Data backing type")
+        let origLength = _length
+        let newLength = length
+        if _capacity < newLength || _bytes == nil {
+            ensureUniqueBufferReference(growingTo: newLength, clear: true)
+        } else if origLength < newLength && _needToZero {
+            memset(_bytes! + origLength, 0, newLength - origLength)
+        } else if newLength < origLength {
+            _needToZero = true
         }
+        _length = newLength
     }
     
     @inlinable
     func append(_ bytes: UnsafeRawPointer, length: Int) {
         precondition(length >= 0, "Length of appending bytes must not be negative")
-        switch _backing {
-        case .swift:
-            let origLength = _length
-            let newLength = origLength + length
-            if _capacity < newLength || _bytes == nil {
-                _grow(newLength, false)
-            }
-            _length = newLength
-            _DataStorage.move(_bytes!.advanced(by: origLength), bytes, length)
-        case .immutable(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.append(bytes, length: length)
-            _backing = .mutable(data)
-            _length = data.length
-            _bytes = data.mutableBytes
-        case .mutable(let d):
-            d.append(bytes, length: length)
-            _length = d.length
-            _bytes = d.mutableBytes
-        case .customReference(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.append(bytes, length: length)
-            _backing = .customMutableReference(data)
-        case .customMutableReference(let d):
-            d.append(bytes, length: length)
-        @unknown default:
-            fatalError("Unknown Data backing type")
+        let origLength = _length
+        let newLength = origLength + length
+        if _capacity < newLength || _bytes == nil {
+            ensureUniqueBufferReference(growingTo: newLength, clear: false)
         }
-        
+        _length = newLength
+        _DataStorage.move(_bytes!.advanced(by: origLength), bytes, length)
     }
     
     // fast-path for appending directly from another data storage
@@ -504,131 +312,57 @@
     
     @inlinable
     func append(_ otherData: Data) {
-        otherData.enumerateBytes { (buffer: UnsafeBufferPointer<UInt8>, _, _) in
-            append(buffer.baseAddress!, length: buffer.count)
+        guard otherData.count > 0 else { return }
+        otherData.withUnsafeBytes {
+            append($0.baseAddress!, length: $0.count)
         }
     }
     
     @inlinable
     func increaseLength(by extraLength: Int) {
         if extraLength == 0 { return }
-        switch _backing {
-        case .swift:
-            let origLength = _length
-            let newLength = origLength + extraLength
-            if _capacity < newLength || _bytes == nil {
-                _grow(newLength, true)
-            } else if _needToZero {
-                memset(_bytes!.advanced(by: origLength), 0, extraLength)
-            }
-            _length = newLength
-        case .immutable(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.increaseLength(by: extraLength)
-            _backing = .mutable(data)
-            _length += extraLength
-            _bytes = data.mutableBytes
-        case .mutable(let d):
-            d.increaseLength(by: extraLength)
-            _length += extraLength
-            _bytes = d.mutableBytes
-        case .customReference(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.increaseLength(by: extraLength)
-            _backing = .customReference(data)
-        case .customMutableReference(let d):
-            d.increaseLength(by: extraLength)
-        @unknown default:
-            fatalError("Unknown Data backing type")
-        }
         
+        let origLength = _length
+        let newLength = origLength + extraLength
+        if _capacity < newLength || _bytes == nil {
+            ensureUniqueBufferReference(growingTo: newLength, clear: true)
+        } else if _needToZero {
+            memset(_bytes!.advanced(by: origLength), 0, extraLength)
+        }
+        _length = newLength
     }
 
-    @usableFromInline
+    @inlinable
     func get(_ index: Int) -> UInt8 {
-        switch _backing {
-        case .swift: fallthrough
-        case .immutable: fallthrough
-        case .mutable:
-            return _bytes!.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
-        case .customReference(let d):
-            if __NSDataIsCompact(d) {
-                return d.bytes.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
-            } else {
-                var byte: UInt8 = 0
-                d.enumerateBytes { (ptr, range, stop) in
-                    if NSLocationInRange(index, range) {
-                        let offset = index - range.location - _offset
-                        byte = ptr.advanced(by: offset).assumingMemoryBound(to: UInt8.self).pointee
-                        stop.pointee = true
-                    }
-                }
-                return byte
-            }
-        case .customMutableReference(let d):
-            if __NSDataIsCompact(d) {
-                return d.bytes.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
-            } else {
-                var byte: UInt8 = 0
-                d.enumerateBytes { (ptr, range, stop) in
-                    if NSLocationInRange(index, range) {
-                        let offset = index - range.location - _offset
-                        byte = ptr.advanced(by: offset).assumingMemoryBound(to: UInt8.self).pointee
-                        stop.pointee = true
-                    }
-                }
-                return byte
-            }
-        }
+        return _bytes!.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee
     }
     
     @inlinable
     func set(_ index: Int, to value: UInt8) {
-        switch _backing {
-        case .swift:
-            fallthrough
-        case .mutable:
-            _bytes!.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee = value
-        default:
-            var theByte = value
-            let range = NSRange(location: index, length: 1)
-            replaceBytes(in: range, with: &theByte, length: 1)
-        }
-        
+        ensureUniqueBufferReference()
+        _bytes!.advanced(by: index - _offset).assumingMemoryBound(to: UInt8.self).pointee = value
     }
-    
+
+    @inlinable
+    func copyBytes(to pointer: UnsafeMutableRawPointer, from range: Range<Int>) {
+        let offsetPointer = UnsafeRawBufferPointer(start: _bytes?.advanced(by: range.lowerBound - _offset), count: Swift.min(range.upperBound - range.lowerBound, _length))
+        UnsafeMutableRawBufferPointer(start: pointer, count: range.upperBound - range.lowerBound).copyMemory(from: offsetPointer)
+    }
+
     @inlinable
     func replaceBytes(in range: NSRange, with bytes: UnsafeRawPointer?) {
         if range.length == 0 { return }
-        switch _backing {
-        case .swift:
-            if _length < range.location + range.length {
-                let newLength = range.location + range.length
-                if _capacity < newLength {
-                    _grow(newLength, false)
-                }
-                _length = newLength
+        if _length < range.location + range.length {
+            let newLength = range.location + range.length
+            if _capacity < newLength {
+                ensureUniqueBufferReference(growingTo: newLength, clear: false)
             }
-            _DataStorage.move(_bytes!.advanced(by: range.location - _offset), bytes!, range.length)
-        case .immutable(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.replaceBytes(in: NSRange(location: range.location - _offset, length: range.length), withBytes: bytes!)
-            _backing = .mutable(data)
-            _length = data.length
-            _bytes = data.mutableBytes
-        case .mutable(let d):
-            d.replaceBytes(in: NSRange(location: range.location - _offset, length: range.length), withBytes: bytes!)
-            _length = d.length
-            _bytes = d.mutableBytes
-        case .customReference(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.replaceBytes(in: NSRange(location: range.location - _offset, length: range.length), withBytes: bytes!)
-            _backing = .customMutableReference(data)
-        case .customMutableReference(let d):
-            d.replaceBytes(in: NSRange(location: range.location - _offset, length: range.length), withBytes: bytes!)
-        @unknown default:
-            fatalError("Unknown Data backing type")
+            _length = newLength
+        } else {
+            ensureUniqueBufferReference()
         }
+        _DataStorage.move(_bytes!.advanced(by: range.location - _offset), bytes!, range.length)
+
     }
     
     @inlinable
@@ -636,90 +370,51 @@
         let range = NSRange(location: range_.location - _offset, length: range_.length)
         let currentLength = _length
         let resultingLength = currentLength - range.length + replacementLength
-        switch _backing {
-        case .swift:
-            let shift = resultingLength - currentLength
-            var mutableBytes = _bytes
-            if resultingLength > currentLength {
-                setLength(resultingLength)
-                mutableBytes = _bytes!
+        let shift = resultingLength - currentLength
+        let mutableBytes: UnsafeMutableRawPointer
+        if resultingLength > currentLength {
+            ensureUniqueBufferReference(growingTo: resultingLength)
+            _length = resultingLength
+        } else {
+            ensureUniqueBufferReference()
+        }
+        mutableBytes = _bytes!
+        /* shift the trailing bytes */
+        let start = range.location
+        let length = range.length
+        if shift != 0 {
+            memmove(mutableBytes + start + replacementLength, mutableBytes + start + length, currentLength - start - length)
+        }
+        if replacementLength != 0 {
+            if let replacementBytes = replacementBytes {
+                memmove(mutableBytes + start, replacementBytes, replacementLength)
+            } else {
+                memset(mutableBytes + start, 0, replacementLength)
             }
-            /* shift the trailing bytes */
-            let start = range.location
-            let length = range.length
-            if shift != 0 {
-                memmove(mutableBytes! + start + replacementLength, mutableBytes! + start + length, currentLength - start - length)
-            }
-            if replacementLength != 0 {
-                if let replacementBytes = replacementBytes {
-                    memmove(mutableBytes! + start, replacementBytes, replacementLength)
-                } else {
-                    memset(mutableBytes! + start, 0, replacementLength)
-                }
-            }
-            
-            if resultingLength < currentLength {
-                setLength(resultingLength)
-            }
-        case .immutable(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.replaceBytes(in: range, withBytes: replacementBytes, length: replacementLength)
-            _backing = .mutable(data)
-            _length = data.length
-            _bytes = data.mutableBytes
-        case .mutable(let d):
-            d.replaceBytes(in: range, withBytes: replacementBytes, length: replacementLength)
-            _backing = .mutable(d)
-            _length = d.length
-            _bytes = d.mutableBytes
-        case .customReference(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.replaceBytes(in: range, withBytes: replacementBytes, length: replacementLength)
-            _backing = .customMutableReference(data)
-        case .customMutableReference(let d):
-            d.replaceBytes(in: range, withBytes: replacementBytes, length: replacementLength)
-        @unknown default:
-            fatalError("Unknown Data backing type")
+        }
+        
+        if resultingLength < currentLength {
+            setLength(resultingLength)
         }
     }
     
     @inlinable
-    func resetBytes(in range_: NSRange) {
-        let range = NSRange(location: range_.location - _offset, length: range_.length)
+    func resetBytes(in range_: Range<Int>) {
+        let range = NSRange(location: range_.lowerBound - _offset, length: range_.upperBound - range_.lowerBound)
         if range.length == 0 { return }
-        switch _backing {
-        case .swift:
-            if _length < range.location + range.length {
-                let newLength = range.location + range.length
-                if _capacity < newLength {
-                    _grow(newLength, false)
-                }
-                _length = newLength
+        if _length < range.location + range.length {
+            let newLength = range.location + range.length
+            if _capacity <= newLength {
+                ensureUniqueBufferReference(growingTo: newLength, clear: false)
             }
-            memset(_bytes!.advanced(by: range.location), 0, range.length)
-        case .immutable(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.resetBytes(in: range)
-            _backing = .mutable(data)
-            _length = data.length
-            _bytes = data.mutableBytes
-        case .mutable(let d):
-            d.resetBytes(in: range)
-            _length = d.length
-            _bytes = d.mutableBytes
-        case .customReference(let d):
-            let data = d.mutableCopy() as! NSMutableData
-            data.resetBytes(in: range)
-            _backing = .customMutableReference(data)
-        case .customMutableReference(let d):
-            d.resetBytes(in: range)
-        @unknown default:
-            fatalError("Unknown Data backing type")
+            _length = newLength
+        } else {
+            ensureUniqueBufferReference()
         }
-        
+        memset(_bytes!.advanced(by: range.location), 0, range.length)
     }
-    
-    @usableFromInline
+
+    @inlinable
     convenience init() {
         self.init(capacity: 0)
     }
@@ -826,7 +521,7 @@
             }
         }
     }
-    
+
     @usableFromInline
     init(immutableReference: NSData, offset: Int) {
         _offset = offset
@@ -834,7 +529,9 @@
         _capacity = 0
         _needToZero = false
         _length = immutableReference.length
-        _backing = .immutable(immutableReference)
+        _deallocator = { _, _ in
+            _fixLifetime(immutableReference)
+        }
     }
     
     @usableFromInline
@@ -844,145 +541,67 @@
         _capacity = 0
         _needToZero = false
         _length = mutableReference.length
-        _backing = .mutable(mutableReference)
+        _deallocator = { _, _ in
+            _fixLifetime(mutableReference)
+        }
     }
     
     @usableFromInline
     init(customReference: NSData, offset: Int) {
         _offset = offset
-        _bytes = nil
+        _bytes = UnsafeMutableRawPointer(mutating: customReference.bytes)
         _capacity = 0
         _needToZero = false
-        _length = 0
-        _backing = .customReference(customReference)
+        _length = customReference.length
+        _deallocator = { _, _ in
+            _fixLifetime(customReference)
+        }
     }
     
     @usableFromInline
     init(customMutableReference: NSMutableData, offset: Int) {
         _offset = offset
-        _bytes = nil
+        _bytes = customMutableReference.mutableBytes
         _capacity = 0
         _needToZero = false
-        _length = 0
-        _backing = .customMutableReference(customMutableReference)
+        _length = customMutableReference.length
+        _deallocator = { _, _ in
+            _fixLifetime(customMutableReference)
+        }
     }
     
     deinit {
-        switch _backing {
-        case .swift:
-            _freeBytes()
-        default:
-            break
-        }
+        _freeBytes()
     }
     
     @inlinable
     func mutableCopy(_ range: Range<Int>) -> _DataStorage {
-        switch _backing {
-        case .swift:
-            return _DataStorage(bytes: _bytes?.advanced(by: range.lowerBound - _offset), length: range.count, copy: true, deallocator: nil, offset: range.lowerBound)
-        case .immutable(let d):
-            if range.lowerBound == 0 && range.upperBound == _length {
-                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData, offset: range.lowerBound)
-            } else {
-                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData, offset: range.lowerBound)
-            }
-        case .mutable(let d):
-            if range.lowerBound == 0 && range.upperBound == _length {
-                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData, offset: range.lowerBound)
-            } else {
-                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData, offset: range.lowerBound)
-            }
-        case .customReference(let d):
-            if range.lowerBound == 0 && range.upperBound == _length {
-                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData, offset: range.lowerBound)
-            } else {
-                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData, offset: range.lowerBound)
-            }
-        case .customMutableReference(let d):
-            if range.lowerBound == 0 && range.upperBound == _length {
-                return _DataStorage(mutableReference: d.mutableCopy() as! NSMutableData, offset: range.lowerBound)
-            } else {
-                return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData, offset: range.lowerBound)
-            }
-        @unknown default:
-            fatalError("Unknown Data backing type")
-        }
+        return _DataStorage(bytes: _bytes?.advanced(by: range.lowerBound - _offset), length: range.upperBound - range.lowerBound, copy: true, deallocator: nil, offset: range.lowerBound)
     }
-    
+
+    @inlinable
     func withInteriorPointerReference<T>(_ range: Range<Int>, _ work: (NSData) throws -> T) rethrows -> T {
         if range.isEmpty {
             return try work(NSData()) // zero length data can be optimized as a singleton
         }
-        
-        switch _backing {
-        case .swift:
-            return try work(NSData(bytesNoCopy: _bytes!.advanced(by: range.lowerBound - _offset), length: range.count, freeWhenDone: false))
-        case .immutable(let d):
-            guard range.lowerBound == 0 && range.upperBound == _length else {
-                return try work(NSData(bytesNoCopy: _bytes!.advanced(by: range.lowerBound - _offset), length: range.count, freeWhenDone: false))
-            }
-            return try work(d)
-        case .mutable(let d):
-            guard range.lowerBound == 0 && range.upperBound == _length else {
-                return try work(NSData(bytesNoCopy: _bytes!.advanced(by: range.lowerBound - _offset), length: range.count, freeWhenDone: false))
-            }
-            return try work(d)
-        case .customReference(let d):
-            guard range.lowerBound == 0 && range.upperBound == _length else {
-                
-                return try work(NSData(bytesNoCopy: UnsafeMutableRawPointer(mutating: d.bytes.advanced(by: range.lowerBound - _offset)), length: range.count, freeWhenDone: false))
-            }
-            return try work(d)
-        case .customMutableReference(let d):
-            guard range.lowerBound == 0 && range.upperBound == _length else {
-                return try work(NSData(bytesNoCopy: UnsafeMutableRawPointer(mutating: d.bytes.advanced(by: range.lowerBound - _offset)), length: range.count, freeWhenDone: false))
-            }
-            return try work(d)
-        }
+        return try work(NSData(bytesNoCopy: _bytes!.advanced(by: range.lowerBound - _offset), length: range.upperBound - range.lowerBound, freeWhenDone: false))
     }
-    
+
+    // This is used to create bridged Datas into Objective-C contexts, the class name is private and should not be emitted into clients.
+    // Consequently this should never be inlined.
+    @usableFromInline
+    @inline(never)
     func bridgedReference(_ range: Range<Int>) -> NSData {
         if range.isEmpty {
             return NSData() // zero length data can be optimized as a singleton
         }
-        
-        switch _backing {
-        case .swift:
-            return __NSSwiftData(backing: self, range: range)
-        case .immutable(let d):
-            guard range.lowerBound == 0 && range.upperBound == _length else {
-                return __NSSwiftData(backing: self, range: range)
-            }
-            return d
-        case .mutable(let d):
-            guard range.lowerBound == 0 && range.upperBound == _length else {
-                return __NSSwiftData(backing: self, range: range)
-            }
-            return d
-        case .customReference(let d):
-            guard range.lowerBound == 0 && range.upperBound == d.length else {
-                return __NSSwiftData(backing: self, range: range)
-            }
-            return d
-        case .customMutableReference(let d):
-            guard range.lowerBound == 0 && range.upperBound == d.length else {
-                return d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC()
-            }
-            return d.copy() as! NSData
-        }
+
+        return __NSSwiftData(backing: self, range: range)
     }
-    
-    @usableFromInline
+
+    @inlinable
     func subdata(in range: Range<Data.Index>) -> Data {
-        switch _backing {
-        case .customReference(let d):
-            return d.subdata(with: NSRange(location: range.lowerBound - _offset, length: range.count))
-        case .customMutableReference(let d):
-            return d.subdata(with: NSRange(location: range.lowerBound - _offset, length: range.count))
-        default:
-            return Data(bytes: _bytes!.advanced(by: range.lowerBound - _offset), count: range.count)
-        }
+        return Data(bytes: _bytes!.advanced(by: range.lowerBound - _offset), count: range.upperBound - range.lowerBound)
     }
 }
 
@@ -992,17 +611,17 @@
 internal class __NSSwiftData : NSData {
     var _backing: _DataStorage!
     var _range: Range<Data.Index>!
-    
+
     convenience init(backing: _DataStorage, range: Range<Data.Index>) {
         self.init()
         _backing = backing
         _range = range
     }
-    override var length: Int {
-        return _range.count
+    @objc override var length: Int {
+        return _range.upperBound - _range.lowerBound
     }
-    
-    override var bytes: UnsafeRawPointer {
+
+    @objc override var bytes: UnsafeRawPointer {
         // NSData's byte pointer methods are not annotated for nullability correctly
         // (but assume non-null by the wrapping macro guards). This placeholder value
         // is to work-around this bug. Any indirection to the underlying bytes of an NSData
@@ -1013,25 +632,25 @@
         guard let bytes = _backing.bytes else {
             return UnsafeRawPointer(bitPattern: 0xBAD0)!
         }
-        
+
         return bytes.advanced(by: _range.lowerBound)
     }
-    
-    override func copy(with zone: NSZone? = nil) -> Any {
+
+    @objc override func copy(with zone: NSZone? = nil) -> Any {
         return self
     }
-    
-    override func mutableCopy(with zone: NSZone? = nil) -> Any {
+
+    @objc override func mutableCopy(with zone: NSZone? = nil) -> Any {
         return NSMutableData(bytes: bytes, length: length)
     }
-    
+
 #if !DEPLOYMENT_RUNTIME_SWIFT
     @objc override
     func _isCompact() -> Bool {
         return true
     }
 #endif
-    
+
 #if DEPLOYMENT_RUNTIME_SWIFT
     override func _providesConcreteBacking() -> Bool {
         return true
@@ -1044,21 +663,1206 @@
 #endif
 }
 
-public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessCollection, MutableCollection, RangeReplaceableCollection {
+@_fixed_layout
+public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessCollection, MutableCollection, RangeReplaceableCollection, MutableDataProtocol, ContiguousBytes {
     public typealias ReferenceType = NSData
-    
+
     public typealias ReadingOptions = NSData.ReadingOptions
     public typealias WritingOptions = NSData.WritingOptions
     public typealias SearchOptions = NSData.SearchOptions
     public typealias Base64EncodingOptions = NSData.Base64EncodingOptions
     public typealias Base64DecodingOptions = NSData.Base64DecodingOptions
-    
+
     public typealias Index = Int
     public typealias Indices = Range<Int>
+
+    @usableFromInline
+    @_fixed_layout
+    internal struct InlineData {
+#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
+        @usableFromInline
+        typealias Buffer = (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
+                            UInt8, UInt8, UInt8, UInt8, UInt8, UInt8) //len  //enum
+        @usableFromInline
+        var bytes: Buffer
+#elseif arch(i386) || arch(arm)
+        @usableFromInline
+        typealias Buffer = (UInt8, UInt8, UInt8, UInt8,
+                            UInt8, UInt8) //len  //enum
+        @usableFromInline
+        var bytes: Buffer
+#endif
+        @usableFromInline
+        var length: UInt8
+
+        @inlinable
+        static func canStore(count: Int) -> Bool {
+            return count <= MemoryLayout<Buffer>.size
+        }
+
+        @inlinable
+        init() {
+            self.init(count: 0)
+        }
+
+        @inlinable
+        init(_ srcBuffer: UnsafeRawBufferPointer) {
+            self.init(count: srcBuffer.count)
+            if srcBuffer.count > 0 {
+                Swift.withUnsafeMutableBytes(of: &bytes) { dstBuffer in
+                    dstBuffer.baseAddress?.copyMemory(from: srcBuffer.baseAddress!, byteCount: srcBuffer.count)
+                }
+            }
+        }
+
+        @inlinable
+        init(count: Int) {
+            assert(count <= MemoryLayout<Buffer>.size)
+#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
+            bytes = (UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0), UInt8(0))
+#elseif arch(i386) || arch(arm)
+            bytes = (UInt8(0), UInt8(0), UInt8(0), UInt8(0),
+                     UInt8(0), UInt8(0))
+#endif
+            length = UInt8(count)
+        }
+
+        @inlinable
+        init(_ slice: InlineSlice, count: Int) {
+            self.init(count: count)
+            Swift.withUnsafeMutableBytes(of: &bytes) { dstBuffer in
+                slice.withUnsafeBytes { srcBuffer in
+                    dstBuffer.copyMemory(from: UnsafeRawBufferPointer(start: srcBuffer.baseAddress, count: count))
+                }
+            }
+        }
+
+        @inlinable
+        init(_ slice: LargeSlice, count: Int) {
+            self.init(count: count)
+            Swift.withUnsafeMutableBytes(of: &bytes) { dstBuffer in
+                slice.withUnsafeBytes { srcBuffer in
+                    dstBuffer.copyMemory(from: UnsafeRawBufferPointer(start: srcBuffer.baseAddress, count: count))
+                }
+            }
+        }
+
+        @inlinable
+        var capacity: Int {
+            return MemoryLayout<Buffer>.size
+        }
+
+        @inlinable
+        var count: Int {
+            get {
+                return Int(length)
+            }
+            set(newValue) {
+                assert(newValue <= MemoryLayout<Buffer>.size)
+                length = UInt8(newValue)
+            }
+        }
+
+        @inlinable
+        var startIndex: Int { return 0 }
+
+        @inlinable
+        var endIndex: Int { return count }
+
+        @inlinable
+        func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
+            let count = Int(length)
+            return try Swift.withUnsafeBytes(of: bytes) { (rawBuffer) throws -> Result in
+                return try apply(UnsafeRawBufferPointer(start: rawBuffer.baseAddress, count: count))
+            }
+        }
+
+        @inlinable
+        mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
+            let count = Int(length)
+            return try Swift.withUnsafeMutableBytes(of: &bytes) { (rawBuffer) throws -> Result in
+                return try apply(UnsafeMutableRawBufferPointer(start: rawBuffer.baseAddress, count: count))
+            }
+        }
+
+        @inlinable
+        mutating func append(contentsOf buffer: UnsafeRawBufferPointer) {
+            guard buffer.count > 0 else { return }
+            assert(count + buffer.count <= MemoryLayout<Buffer>.size)
+            let cnt = count
+            _ = Swift.withUnsafeMutableBytes(of: &bytes) { rawBuffer in
+                rawBuffer.baseAddress?.advanced(by: cnt).copyMemory(from: buffer.baseAddress!, byteCount: buffer.count)
+            }
+            length += UInt8(buffer.count)
+
+        }
+
+        @inlinable
+        subscript(index: Index) -> UInt8 {
+            get {
+                assert(index <= MemoryLayout<Buffer>.size)
+                precondition(index < length, "index \(index) is out of bounds of 0..<\(length)")
+                return Swift.withUnsafeBytes(of: bytes) { rawBuffer -> UInt8 in
+                    return rawBuffer[index]
+                }
+            }
+            set(newValue) {
+                assert(index <= MemoryLayout<Buffer>.size)
+                precondition(index < length, "index \(index) is out of bounds of 0..<\(length)")
+                Swift.withUnsafeMutableBytes(of: &bytes) { rawBuffer in
+                    rawBuffer[index] = newValue
+                }
+            }
+        }
+
+        @inlinable
+        mutating func resetBytes(in range: Range<Index>) {
+            assert(range.lowerBound <= MemoryLayout<Buffer>.size)
+            assert(range.upperBound <= MemoryLayout<Buffer>.size)
+            precondition(range.lowerBound <= length, "index \(range.lowerBound) is out of bounds of 0..<\(length)")
+            if count < range.upperBound {
+                count = range.upperBound
+            }
+            let _ = Swift.withUnsafeMutableBytes(of: &bytes) { rawBuffer in
+                memset(rawBuffer.baseAddress?.advanced(by: range.lowerBound), 0, range.upperBound - range.lowerBound)
+            }
+        }
+
+        @inlinable
+        mutating func replaceSubrange(_ subrange: Range<Index>, with replacementBytes: UnsafeRawPointer?, count replacementLength: Int) {
+            assert(subrange.lowerBound <= MemoryLayout<Buffer>.size)
+            assert(subrange.upperBound <= MemoryLayout<Buffer>.size)
+            assert(count - (subrange.upperBound - subrange.lowerBound) + replacementLength <= MemoryLayout<Buffer>.size)
+            precondition(subrange.lowerBound <= length, "index \(subrange.lowerBound) is out of bounds of 0..<\(length)")
+            precondition(subrange.upperBound <= length, "index \(subrange.upperBound) is out of bounds of 0..<\(length)")
+            let currentLength = count
+            let resultingLength = currentLength - (subrange.upperBound - subrange.lowerBound) + replacementLength
+            let shift = resultingLength - currentLength
+            Swift.withUnsafeMutableBytes(of: &bytes) { mutableBytes in
+                /* shift the trailing bytes */
+                let start = subrange.lowerBound
+                let length = subrange.upperBound - subrange.lowerBound
+                if shift != 0 {
+                    memmove(mutableBytes.baseAddress?.advanced(by: start + replacementLength), mutableBytes.baseAddress?.advanced(by: start + length), currentLength - start - length)
+                }
+                if replacementLength != 0 {
+                    memmove(mutableBytes.baseAddress?.advanced(by: start), replacementBytes!, replacementLength)
+                }
+            }
+            count = resultingLength
+        }
+
+        @inlinable
+        func copyBytes(to pointer: UnsafeMutableRawPointer, from range: Range<Int>) {
+            precondition(startIndex <= range.lowerBound, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(range.lowerBound <= endIndex, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(startIndex <= range.upperBound, "index \(range.upperBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(range.upperBound <= endIndex, "index \(range.upperBound) is out of bounds of \(startIndex)..<\(endIndex)")
+
+            Swift.withUnsafeBytes(of: bytes) {
+                let cnt = Swift.min($0.count, range.upperBound - range.lowerBound)
+                guard cnt > 0 else { return }
+                pointer.copyMemory(from: $0.baseAddress!.advanced(by: range.lowerBound), byteCount: cnt)
+            }
+        }
+
+        @inlinable
+        var hashValue: Int {
+            let count = Int(length)
+            return Swift.withUnsafeBytes(of: bytes) { (rawBuffer) -> Int in
+                return Int(bitPattern: CFHashBytes(UnsafeMutablePointer(mutating: rawBuffer.baseAddress?.assumingMemoryBound(to: UInt8.self)), count))
+            }
+        }
+    }
+
+#if arch(x86_64) || arch(arm64) || arch(s390x) || arch(powerpc64) || arch(powerpc64le)
+    @usableFromInline
+    internal typealias HalfInt = Int32
+#elseif arch(i386) || arch(arm)
+    @usableFromInline
+    internal typealias HalfInt = Int16
+#endif
+
+    @usableFromInline
+    @_fixed_layout
+    internal struct InlineSlice {
+        // ***WARNING***
+        // These ivars are specifically laid out so that they cause the enum _Representation to be 16 bytes on 64 bit platforms. This means we _MUST_ have the class type thing last
+        @usableFromInline
+        var slice: Range<HalfInt>
+        @usableFromInline
+        var storage: _DataStorage
+
+        @inlinable
+        static func canStore(count: Int) -> Bool {
+            return count < HalfInt.max
+        }
+
+        @inlinable
+        init(_ buffer: UnsafeRawBufferPointer) {
+            assert(buffer.count < HalfInt.max)
+            self.init(_DataStorage(bytes: buffer.baseAddress, length: buffer.count), count: buffer.count)
+        }
+
+        @inlinable
+        init(capacity: Int) {
+            assert(capacity < HalfInt.max)
+            self.init(_DataStorage(capacity: capacity), count: 0)
+        }
+
+        @inlinable
+        init(count: Int) {
+            assert(count < HalfInt.max)
+            self.init(_DataStorage(length: count), count: count)
+        }
+
+        @inlinable
+        init(_ inline: InlineData) {
+            assert(inline.count < HalfInt.max)
+            self.init(inline.withUnsafeBytes { return _DataStorage(bytes: $0.baseAddress, length: $0.count) }, count: inline.count)
+        }
+
+        @inlinable
+        init(_ inline: InlineData, range: Range<Int>) {
+            assert(range.lowerBound < HalfInt.max)
+            assert(range.upperBound < HalfInt.max)
+            self.init(inline.withUnsafeBytes { return _DataStorage(bytes: $0.baseAddress, length: $0.count) }, range: range)
+        }
+
+        @inlinable
+        init(_ large: LargeSlice) {
+            assert(large.range.lowerBound < HalfInt.max)
+            assert(large.range.upperBound < HalfInt.max)
+            self.init(large.storage, range: large.range)
+        }
+
+        @inlinable
+        init(_ large: LargeSlice, range: Range<Int>) {
+            assert(range.lowerBound < HalfInt.max)
+            assert(range.upperBound < HalfInt.max)
+            self.init(large.storage, range: range)
+        }
+
+        @inlinable
+        init(_ storage: _DataStorage, count: Int) {
+            assert(count < HalfInt.max)
+            self.storage = storage
+            slice = 0..<HalfInt(count)
+        }
+
+        @inlinable
+        init(_ storage: _DataStorage, range: Range<Int>) {
+            assert(range.lowerBound < HalfInt.max)
+            assert(range.upperBound < HalfInt.max)
+            self.storage = storage
+            slice = HalfInt(range.lowerBound)..<HalfInt(range.upperBound)
+        }
+
+        @inlinable
+        mutating func ensureUniqueReference() {
+            if !isKnownUniquelyReferenced(&storage) {
+                storage = storage.mutableCopy(self.range)
+            }
+        }
+
+        @inlinable
+        var startIndex: Int { return Int(slice.lowerBound) }
+        @inlinable
+        var endIndex: Int { return Int(slice.upperBound) }
+
+        @inlinable
+        var capacity: Int {
+            return storage.capacity
+        }
+
+        @inlinable
+        mutating func reserveCapacity(_ minimumCapacity: Int) {
+            ensureUniqueReference()
+            // the current capacity can be zero (representing externally owned buffer), and count can be greater than the capacity
+            storage.ensureUniqueBufferReference(growingTo: Swift.max(minimumCapacity, count))
+        }
+
+        @inlinable
+        var count: Int {
+            get {
+                return Int(slice.upperBound - slice.lowerBound)
+            }
+            set(newValue) {
+                assert(newValue < HalfInt.max)
+                ensureUniqueReference()
+                storage.length = newValue
+                slice = slice.lowerBound..<(slice.lowerBound + HalfInt(newValue))
+            }
+        }
+
+        @inlinable
+        var range: Range<Int> {
+            get {
+                return Int(slice.lowerBound)..<Int(slice.upperBound)
+            }
+            set(newValue) {
+                assert(newValue.lowerBound < HalfInt.max)
+                assert(newValue.upperBound < HalfInt.max)
+                slice = HalfInt(newValue.lowerBound)..<HalfInt(newValue.upperBound)
+            }
+        }
+
+        @inlinable
+        func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
+            return try storage.withUnsafeBytes(in: range, apply: apply)
+        }
+
+        @inlinable
+        mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
+            ensureUniqueReference()
+            return try storage.withUnsafeMutableBytes(in: range, apply: apply)
+        }
+
+        @inlinable
+        mutating func append(contentsOf buffer: UnsafeRawBufferPointer) {
+            assert(endIndex + buffer.count < HalfInt.max)
+            ensureUniqueReference()
+            storage.replaceBytes(in: NSRange(location: range.upperBound, length: storage.length - (range.upperBound - storage._offset)), with: buffer.baseAddress, length: buffer.count)
+            slice = slice.lowerBound..<HalfInt(Int(slice.upperBound) + buffer.count)
+        }
+
+        @inlinable
+        subscript(index: Index) -> UInt8 {
+            get {
+                assert(index < HalfInt.max)
+                precondition(startIndex <= index, "index \(index) is out of bounds of \(startIndex)..<\(endIndex)")
+                precondition(index < endIndex, "index \(index) is out of bounds of \(startIndex)..<\(endIndex)")
+                return storage.get(index)
+            }
+            set(newValue) {
+                assert(index < HalfInt.max)
+                precondition(startIndex <= index, "index \(index) is out of bounds of \(startIndex)..<\(endIndex)")
+                precondition(index < endIndex, "index \(index) is out of bounds of \(startIndex)..<\(endIndex)")
+                ensureUniqueReference()
+                storage.set(index, to: newValue)
+            }
+        }
+
+        @inlinable
+        func bridgedReference() -> NSData {
+            return storage.bridgedReference(self.range)
+        }
+
+        @inlinable
+        mutating func resetBytes(in range: Range<Index>) {
+            assert(range.lowerBound < HalfInt.max)
+            assert(range.upperBound < HalfInt.max)
+            precondition(range.lowerBound <= endIndex, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            ensureUniqueReference()
+            storage.resetBytes(in: range)
+            if slice.upperBound < range.upperBound {
+                slice = slice.lowerBound..<HalfInt(range.upperBound)
+            }
+        }
+
+        @inlinable
+        mutating func replaceSubrange(_ subrange: Range<Index>, with bytes: UnsafeRawPointer?, count cnt: Int) {
+            precondition(startIndex <= subrange.lowerBound, "index \(subrange.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(subrange.lowerBound <= endIndex, "index \(subrange.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(startIndex <= subrange.upperBound, "index \(subrange.upperBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(subrange.upperBound <= endIndex, "index \(subrange.upperBound) is out of bounds of \(startIndex)..<\(endIndex)")
+
+            let nsRange = NSRange(location: subrange.lowerBound, length: subrange.upperBound - subrange.lowerBound)
+            ensureUniqueReference()
+            let upper = range.upperBound
+            storage.replaceBytes(in: nsRange, with: bytes, length: cnt)
+            let resultingUpper = upper - nsRange.length + cnt
+            slice = slice.lowerBound..<HalfInt(resultingUpper)
+        }
+
+        @inlinable
+        func copyBytes(to pointer: UnsafeMutableRawPointer, from range: Range<Int>) {
+            precondition(startIndex <= range.lowerBound, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(range.lowerBound <= endIndex, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(startIndex <= range.upperBound, "index \(range.upperBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(range.upperBound <= endIndex, "index \(range.upperBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            storage.copyBytes(to: pointer, from: range)
+        }
+
+        @inlinable
+        var hashValue: Int {
+            let hashRange = startIndex..<Swift.min(startIndex + 80, endIndex)
+            return storage.withUnsafeBytes(in: hashRange) {
+                return Int(bitPattern: CFHashBytes(UnsafeMutablePointer(mutating: $0.baseAddress?.assumingMemoryBound(to: UInt8.self)), $0.count))
+            }
+        }
+    }
+
+    @usableFromInline
+    @_fixed_layout
+    internal final class RangeReference {
+        @usableFromInline
+        var range: Range<Int>
+
+        @inlinable
+        var lowerBound: Int { return range.lowerBound }
+
+        @inlinable
+        var upperBound: Int { return range.upperBound }
+
+        @inlinable
+        var count: Int { return range.upperBound - range.lowerBound }
+
+        @inlinable
+        init(_ range: Range<Int>) {
+            self.range = range
+        }
+    }
+
+    @usableFromInline
+    @_fixed_layout
+    internal struct LargeSlice {
+        // ***WARNING***
+        // These ivars are specifically laid out so that they cause the enum _Representation to be 16 bytes on 64 bit platforms. This means we _MUST_ have the class type thing last
+        @usableFromInline
+        var slice: RangeReference
+        @usableFromInline
+        var storage: _DataStorage
+
+        @inlinable
+        init(_ buffer: UnsafeRawBufferPointer) {
+            self.init(_DataStorage(bytes: buffer.baseAddress, length: buffer.count), count: buffer.count)
+        }
+
+        @inlinable
+        init(capacity: Int) {
+            self.init(_DataStorage(capacity: capacity), count: 0)
+        }
+
+        @inlinable
+        init(count: Int) {
+            self.init(_DataStorage(length: count), count: count)
+        }
+
+        @inlinable
+        init(_ inline: InlineData) {
+            self.init(inline.withUnsafeBytes { return _DataStorage(bytes: $0.baseAddress, length: $0.count) }, count: inline.count)
+        }
+
+        @inlinable
+        init(_ slice: InlineSlice) {
+            self.storage = slice.storage
+            self.slice = RangeReference(slice.range)
+        }
+
+        @inlinable
+        init(_ storage: _DataStorage, count: Int) {
+            self.storage = storage
+            slice = RangeReference(0..<count)
+        }
+
+        @inlinable
+        mutating func ensureUniqueReference() {
+            if !isKnownUniquelyReferenced(&storage) {
+                storage = storage.mutableCopy(range)
+            }
+            if !isKnownUniquelyReferenced(&slice) {
+                slice = RangeReference(range)
+            }
+        }
+
+        @inlinable
+        var startIndex: Int { return slice.range.lowerBound }
+
+        @inlinable
+        var endIndex: Int { return slice.range.upperBound }
+
+        @inlinable
+        var capacity: Int {
+            return storage.capacity
+        }
+
+        @inlinable
+        mutating func reserveCapacity(_ minimumCapacity: Int) {
+            ensureUniqueReference()
+            // the current capacity can be zero (representing externally owned buffer), and count can be greater than the capacity
+            storage.ensureUniqueBufferReference(growingTo: Swift.max(minimumCapacity, count))
+        }
+
+        @inlinable
+        var count: Int {
+            get {
+                return slice.count
+            }
+            set(newValue) {
+                ensureUniqueReference()
+                storage.length = newValue
+                slice.range = slice.range.lowerBound..<(slice.range.lowerBound + newValue)
+            }
+        }
+
+        @inlinable
+        var range: Range<Int> { return slice.range }
+
+        @inlinable
+        func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
+            return try storage.withUnsafeBytes(in: range, apply: apply)
+        }
+
+        @inlinable
+        mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
+            ensureUniqueReference()
+            return try storage.withUnsafeMutableBytes(in: range, apply: apply)
+        }
+
+        @inlinable
+        mutating func append(contentsOf buffer: UnsafeRawBufferPointer) {
+            ensureUniqueReference()
+            storage.replaceBytes(in: NSRange(location: range.upperBound, length: storage.length - (range.upperBound - storage._offset)), with: buffer.baseAddress, length: buffer.count)
+            slice.range = slice.range.lowerBound..<slice.range.upperBound + buffer.count
+        }
+
+        @inlinable
+        subscript(index: Index) -> UInt8 {
+            get {
+                precondition(startIndex <= index, "index \(index) is out of bounds of \(startIndex)..<\(endIndex)")
+                precondition(index < endIndex, "index \(index) is out of bounds of \(startIndex)..<\(endIndex)")
+                return storage.get(index)
+            }
+            set(newValue) {
+                precondition(startIndex <= index, "index \(index) is out of bounds of \(startIndex)..<\(endIndex)")
+                precondition(index < endIndex, "index \(index) is out of bounds of \(startIndex)..<\(endIndex)")
+                ensureUniqueReference()
+                storage.set(index, to: newValue)
+            }
+        }
+
+        @inlinable
+        func bridgedReference() -> NSData {
+            return storage.bridgedReference(self.range)
+        }
+
+        @inlinable
+        mutating func resetBytes(in range: Range<Int>) {
+            precondition(range.lowerBound <= endIndex, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            ensureUniqueReference()
+            storage.resetBytes(in: range)
+            if slice.range.upperBound < range.upperBound {
+                slice.range = slice.range.lowerBound..<range.upperBound
+            }
+        }
+
+        @inlinable
+        mutating func replaceSubrange(_ subrange: Range<Index>, with bytes: UnsafeRawPointer?, count cnt: Int) {
+            precondition(startIndex <= subrange.lowerBound, "index \(subrange.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(subrange.lowerBound <= endIndex, "index \(subrange.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(startIndex <= subrange.upperBound, "index \(subrange.upperBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(subrange.upperBound <= endIndex, "index \(subrange.upperBound) is out of bounds of \(startIndex)..<\(endIndex)")
+
+            let nsRange = NSRange(location: subrange.lowerBound, length: subrange.upperBound - subrange.lowerBound)
+            ensureUniqueReference()
+            let upper = range.upperBound
+            storage.replaceBytes(in: nsRange, with: bytes, length: cnt)
+            let resultingUpper = upper - nsRange.length + cnt
+            slice.range = slice.range.lowerBound..<resultingUpper
+        }
+
+        @inlinable
+        func copyBytes(to pointer: UnsafeMutableRawPointer, from range: Range<Int>) {
+            precondition(startIndex <= range.lowerBound, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(range.lowerBound <= endIndex, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(startIndex <= range.upperBound, "index \(range.upperBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            precondition(range.upperBound <= endIndex, "index \(range.upperBound) is out of bounds of \(startIndex)..<\(endIndex)")
+            storage.copyBytes(to: pointer, from: range)
+        }
+
+        @inlinable
+        var hashValue: Int {
+            let hashRange = startIndex..<Swift.min(startIndex + 80, endIndex)
+            return storage.withUnsafeBytes(in: hashRange) {
+                return Int(bitPattern: CFHashBytes(UnsafeMutablePointer(mutating: $0.baseAddress?.assumingMemoryBound(to: UInt8.self)), CFIndex($0.count)))
+            }
+        }
+    }
+
+    @usableFromInline
+    @_frozen
+    internal enum _Representation {
+        case empty
+        case inline(InlineData)
+        case slice(InlineSlice)
+        case large(LargeSlice)
+
+        @inlinable
+        init(_ buffer: UnsafeRawBufferPointer) {
+            if buffer.count == 0 {
+                self = .empty
+            } else if InlineData.canStore(count: buffer.count) {
+                self = .inline(InlineData(buffer))
+            } else if InlineSlice.canStore(count: buffer.count) {
+                self = .slice(InlineSlice(buffer))
+            } else {
+                self = .large(LargeSlice(buffer))
+            }
+        }
+
+        @inlinable
+        init(_ buffer: UnsafeRawBufferPointer, owner: AnyObject) {
+            if buffer.count == 0 {
+                self = .empty
+            } else if InlineData.canStore(count: buffer.count) {
+                self = .inline(InlineData(buffer))
+            } else {
+                let count = buffer.count
+                let storage = _DataStorage(bytes: UnsafeMutableRawPointer(mutating: buffer.baseAddress), length: count, copy: false, deallocator: { _, _ in
+                    _fixLifetime(owner)
+                }, offset: 0)
+                if InlineSlice.canStore(count: count) {
+                    self = .slice(InlineSlice(storage, count: count))
+                } else {
+                    self = .large(LargeSlice(storage, count: count))
+                }
+            }
+        }
+
+        @inlinable
+        init(capacity: Int) {
+            if capacity == 0 {
+                self = .empty
+            } else if InlineData.canStore(count: capacity) {
+                self = .inline(InlineData())
+            } else if InlineSlice.canStore(count: capacity) {
+                self = .slice(InlineSlice(capacity: capacity))
+            } else {
+                self = .large(LargeSlice(capacity: capacity))
+            }
+        }
+
+        @inlinable
+        init(count: Int) {
+            if count == 0 {
+                self = .empty
+            } else if InlineData.canStore(count: count) {
+                self = .inline(InlineData(count: count))
+            } else if InlineSlice.canStore(count: count) {
+                self = .slice(InlineSlice(count: count))
+            } else {
+                self = .large(LargeSlice(count: count))
+            }
+        }
+
+        @inlinable
+        init(_ storage: _DataStorage, count: Int) {
+            if count == 0 {
+                self = .empty
+            } else if InlineData.canStore(count: count) {
+                self = .inline(storage.withUnsafeBytes(in: 0..<count) { InlineData($0) })
+            } else if InlineSlice.canStore(count: count) {
+                self = .slice(InlineSlice(storage, count: count))
+            } else {
+                self = .large(LargeSlice(storage, count: count))
+            }
+        }
+
+        @inlinable
+        mutating func reserveCapacity(_ minimumCapacity: Int) {
+            guard minimumCapacity > 0 else { return }
+            switch self {
+            case .empty:
+                if InlineData.canStore(count: minimumCapacity) {
+                    self = .inline(InlineData())
+                } else if InlineSlice.canStore(count: minimumCapacity) {
+                    self = .slice(InlineSlice(capacity: minimumCapacity))
+                } else {
+                    self = .large(LargeSlice(capacity: minimumCapacity))
+                }
+            case .inline(let inline):
+                guard minimumCapacity > inline.capacity else { return }
+                // we know we are going to be heap promoted
+                if InlineSlice.canStore(count: minimumCapacity) {
+                    var slice = InlineSlice(inline)
+                    slice.reserveCapacity(minimumCapacity)
+                    self = .slice(slice)
+                } else {
+                    var slice = LargeSlice(inline)
+                    slice.reserveCapacity(minimumCapacity)
+                    self = .large(slice)
+                }
+            case .slice(var slice):
+                guard minimumCapacity > slice.capacity else { return }
+                if InlineSlice.canStore(count: minimumCapacity) {
+                    self = .empty
+                    slice.reserveCapacity(minimumCapacity)
+                    self = .slice(slice)
+                } else {
+                    var large = LargeSlice(slice)
+                    large.reserveCapacity(minimumCapacity)
+                    self = .large(large)
+                }
+            case .large(var slice):
+                guard minimumCapacity > slice.capacity else { return }
+                self = .empty
+                slice.reserveCapacity(minimumCapacity)
+                self = .large(slice)
+            }
+        }
+
+        @inlinable
+        var count: Int {
+            get {
+                switch self {
+                case .empty: return 0
+                case .inline(let inline): return inline.count
+                case .slice(let slice): return slice.count
+                case .large(let slice): return slice.count
+                }
+            }
+            set(newValue) {
+                @inline(__always)
+                func apply(_ representation: inout _Representation, _ newValue: Int) -> _Representation? {
+                    switch representation {
+                    case .empty:
+                        if newValue == 0 {
+                            return nil
+                        } else if InlineData.canStore(count: newValue) {
+                            return .inline(InlineData())
+                        } else if InlineSlice.canStore(count: newValue) {
+                            return .slice(InlineSlice(count: newValue))
+                        } else {
+                            return .large(LargeSlice(count: newValue))
+                        }
+                    case .inline(var inline):
+                        if newValue == 0 {
+                            return .empty
+                        } else if InlineData.canStore(count: newValue) {
+                            guard inline.count != newValue else { return nil }
+                            inline.count = newValue
+                            return .inline(inline)
+                        } else if InlineSlice.canStore(count: newValue) {
+                            var slice = InlineSlice(inline)
+                            slice.count = newValue
+                            return .slice(slice)
+                        } else {
+                            var slice = LargeSlice(inline)
+                            slice.count = newValue
+                            return .large(slice)
+                        }
+                    case .slice(var slice):
+                        if newValue == 0 && slice.startIndex == 0 {
+                            return .empty
+                        } else if slice.startIndex == 0 && InlineData.canStore(count: newValue) {
+                            return .inline(InlineData(slice, count: newValue))
+                        } else if InlineSlice.canStore(count: newValue + slice.startIndex) {
+                            guard slice.count != newValue else { return nil }
+                            representation = .empty // TODO: remove this when mgottesman lands optimizations
+                            slice.count = newValue
+                            return .slice(slice)
+                        } else {
+                            var newSlice = LargeSlice(slice)
+                            newSlice.count = newValue
+                            return .large(newSlice)
+                        }
+                    case .large(var slice):
+                        if newValue == 0 && slice.startIndex == 0 {
+                            return .empty
+                        } else if slice.startIndex == 0 && InlineData.canStore(count: newValue) {
+                            return .inline(InlineData(slice, count: newValue))
+                        } else {
+                            guard slice.count != newValue else { return nil}
+                            representation = .empty // TODO: remove this when mgottesman lands optimizations
+                            slice.count = newValue
+                            return .large(slice)
+                        }
+                    }
+                }
+
+                if let rep = apply(&self, newValue) {
+                    self = rep
+                }
+            }
+        }
+
+        @inlinable
+        func withUnsafeBytes<Result>(_ apply: (UnsafeRawBufferPointer) throws -> Result) rethrows -> Result {
+            switch self {
+            case .empty:
+                let empty = InlineData()
+                return try empty.withUnsafeBytes(apply)
+            case .inline(let inline):
+                return try inline.withUnsafeBytes(apply)
+            case .slice(let slice):
+                return try slice.withUnsafeBytes(apply)
+            case .large(let slice):
+                return try slice.withUnsafeBytes(apply)
+            }
+        }
+
+        @inlinable
+        mutating func withUnsafeMutableBytes<Result>(_ apply: (UnsafeMutableRawBufferPointer) throws -> Result) rethrows -> Result {
+            switch self {
+            case .empty:
+                var empty = InlineData()
+                return try empty.withUnsafeMutableBytes(apply)
+            case .inline(var inline):
+                defer { self = .inline(inline) }
+                return try inline.withUnsafeMutableBytes(apply)
+            case .slice(var slice):
+                self = .empty
+                defer { self = .slice(slice) }
+                return try slice.withUnsafeMutableBytes(apply)
+            case .large(var slice):
+                self = .empty
+                defer { self = .large(slice) }
+                return try slice.withUnsafeMutableBytes(apply)
+            }
+        }
+
+        @inlinable
+        func withInteriorPointerReference<T>(_ work: (NSData) throws -> T) rethrows -> T {
+            switch self {
+            case .empty:
+                return try work(NSData())
+            case .inline(let inline):
+                return try inline.withUnsafeBytes {
+                    return try work(NSData(bytesNoCopy: UnsafeMutableRawPointer(mutating: $0.baseAddress ?? UnsafeRawPointer(bitPattern: 0xBAD0)!), length: $0.count, freeWhenDone: false))
+                }
+            case .slice(let slice):
+                return try slice.storage.withInteriorPointerReference(slice.range, work)
+            case .large(let slice):
+                return try slice.storage.withInteriorPointerReference(slice.range, work)
+            }
+        }
+
+        @inlinable
+        func enumerateBytes(_ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Index, _ stop: inout Bool) -> Void) {
+            switch self {
+            case .empty:
+                var stop = false
+                block(UnsafeBufferPointer<UInt8>(start: nil, count: 0), 0, &stop)
+            case .inline(let inline):
+                inline.withUnsafeBytes {
+                    var stop = false
+                    block(UnsafeBufferPointer<UInt8>(start: $0.baseAddress?.assumingMemoryBound(to: UInt8.self), count: $0.count), 0, &stop)
+                }
+            case .slice(let slice):
+                slice.storage.enumerateBytes(in: slice.range, block)
+            case .large(let slice):
+                slice.storage.enumerateBytes(in: slice.range, block)
+            }
+        }
+
+        @inlinable
+        mutating func append(contentsOf buffer: UnsafeRawBufferPointer) {
+            switch self {
+            case .empty:
+                self = _Representation(buffer)
+            case .inline(var inline):
+                if InlineData.canStore(count: inline.count + buffer.count) {
+                    inline.append(contentsOf: buffer)
+                    self = .inline(inline)
+                } else if InlineSlice.canStore(count: inline.count + buffer.count) {
+                    var newSlice = InlineSlice(inline)
+                    newSlice.append(contentsOf: buffer)
+                    self = .slice(newSlice)
+                } else {
+                    var newSlice = LargeSlice(inline)
+                    newSlice.append(contentsOf: buffer)
+                    self = .large(newSlice)
+                }
+            case .slice(var slice):
+                if InlineSlice.canStore(count: slice.range.upperBound + buffer.count) {
+                    self = .empty
+                    defer { self = .slice(slice) }
+                    slice.append(contentsOf: buffer)
+                } else {
+                    self = .empty
+                    var newSlice = LargeSlice(slice)
+                    newSlice.append(contentsOf: buffer)
+                    self = .large(newSlice)
+                }
+            case .large(var slice):
+                self = .empty
+                defer { self = .large(slice) }
+                slice.append(contentsOf: buffer)
+            }
+        }
+
+        @inlinable
+        mutating func resetBytes(in range: Range<Index>) {
+            switch self {
+            case .empty:
+                if range.upperBound == 0 {
+                    self = .empty
+                } else if InlineData.canStore(count: range.upperBound) {
+                    precondition(range.lowerBound <= endIndex, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+                    self = .inline(InlineData(count: range.upperBound))
+                } else if InlineSlice.canStore(count: range.upperBound) {
+                    precondition(range.lowerBound <= endIndex, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+                    self = .slice(InlineSlice(count: range.upperBound))
+                } else {
+                    precondition(range.lowerBound <= endIndex, "index \(range.lowerBound) is out of bounds of \(startIndex)..<\(endIndex)")
+                    self = .large(LargeSlice(count: range.upperBound))
+                }
+                break
+            case .inline(var inline):
+
+                if inline.count < range.upperBound {
+                    if InlineSlice.canStore(count: range.upperBound) {
+                        var slice = InlineSlice(inline)
+                        slice.resetBytes(in: range)
+                        self = .slice(slice)
+                    } else {
+                        var slice = LargeSlice(inline)
+                        slice.resetBytes(in: range)
+                        self = .large(slice)
+                    }
+                } else {
+                    inline.resetBytes(in: range)
+                    self = .inline(inline)
+                }
+                break
+            case .slice(var slice):
+                if InlineSlice.canStore(count: range.upperBound) {
+                    self = .empty
+                    slice.resetBytes(in: range)
+                    self = .slice(slice)
+                } else {
+                    self = .empty
+                    var newSlice = LargeSlice(slice)
+                    newSlice.resetBytes(in: range)
+                    self = .large(newSlice)
+                }
+                break
+            case .large(var slice):
+                self = .empty
+                slice.resetBytes(in: range)
+                self = .large(slice)
+            }
+        }
+
+        @inlinable
+        mutating func replaceSubrange(_ subrange: Range<Index>, with bytes: UnsafeRawPointer?, count cnt: Int) {
+            switch self {
+            case .empty:
+                precondition(subrange.lowerBound == 0 && subrange.upperBound == 0, "range \(subrange) out of bounds of 0..<0")
+                if cnt == 0 {
+                    return
+                } else if InlineData.canStore(count: cnt) {
+                    self = .inline(InlineData(UnsafeRawBufferPointer(start: bytes, count: cnt)))
+                } else if InlineSlice.canStore(count: cnt) {
+                    self = .slice(InlineSlice(UnsafeRawBufferPointer(start: bytes, count: cnt)))
+                } else {
+                    self = .large(LargeSlice(UnsafeRawBufferPointer(start: bytes, count: cnt)))
+                }
+                break
+            case .inline(var inline):
+                let resultingCount = inline.count + cnt - (subrange.upperBound - subrange.lowerBound)
+                if resultingCount == 0 {
+                    self = .empty
+                } else if InlineData.canStore(count: resultingCount) {
+                    inline.replaceSubrange(subrange, with: bytes, count: cnt)
+                    self = .inline(inline)
+                } else if InlineSlice.canStore(count: resultingCount) {
+                    var slice = InlineSlice(inline)
+                    slice.replaceSubrange(subrange, with: bytes, count: cnt)
+                    self = .slice(slice)
+                } else {
+                    var slice = LargeSlice(inline)
+                    slice.replaceSubrange(subrange, with: bytes, count: cnt)
+                    self = .large(slice)
+                }
+                break
+            case .slice(var slice):
+                let resultingUpper = slice.endIndex + cnt - (subrange.upperBound - subrange.lowerBound)
+                if slice.startIndex == 0 && resultingUpper == 0 {
+                    self = .empty
+                } else if slice.startIndex == 0 && InlineData.canStore(count: resultingUpper) {
+                    self = .empty
+                    slice.replaceSubrange(subrange, with: bytes, count: cnt)
+                    self = .inline(InlineData(slice, count: slice.count))
+                } else if InlineSlice.canStore(count: resultingUpper) {
+                    self = .empty
+                    slice.replaceSubrange(subrange, with: bytes, count: cnt)
+                    self = .slice(slice)
+                } else {
+                    self = .empty
+                    var newSlice = LargeSlice(slice)
+                    newSlice.replaceSubrange(subrange, with: bytes, count: cnt)
+                    self = .large(newSlice)
+                }
+            case .large(var slice):
+                let resultingUpper = slice.endIndex + cnt - (subrange.upperBound - subrange.lowerBound)
+                if slice.startIndex == 0 && resultingUpper == 0 {
+                    self = .empty
+                } else if slice.startIndex == 0 && InlineData.canStore(count: resultingUpper) {
+                    var inline = InlineData(count: resultingUpper)
+                    inline.withUnsafeMutableBytes { inlineBuffer in
+                        if cnt > 0 {
+                            inlineBuffer.baseAddress?.advanced(by: subrange.lowerBound).copyMemory(from: bytes!, byteCount: cnt)
+                        }
+                        slice.withUnsafeBytes { buffer in
+                            if subrange.lowerBound > 0 {
+                                inlineBuffer.baseAddress?.copyMemory(from: buffer.baseAddress!, byteCount: subrange.lowerBound)
+                            }
+                            if subrange.upperBound < resultingUpper {
+                                inlineBuffer.baseAddress?.advanced(by: subrange.upperBound).copyMemory(from: buffer.baseAddress!.advanced(by: subrange.upperBound), byteCount: resultingUpper - subrange.upperBound)
+                            }
+                        }
+                    }
+                    self = .inline(inline)
+                } else if InlineSlice.canStore(count: slice.startIndex) && InlineSlice.canStore(count: resultingUpper) {
+                    self = .empty
+                    var newSlice = InlineSlice(slice)
+                    newSlice.replaceSubrange(subrange, with: bytes, count: cnt)
+                    self = .slice(newSlice)
+                } else {
+                    self = .empty
+                    slice.replaceSubrange(subrange, with: bytes, count: cnt)
+                    self = .large(slice)
+                }
+            }
+        }
+
+        @inlinable
+        subscript(index: Index) -> UInt8 {
+            get {
+                switch self {
+                case .empty: preconditionFailure("index \(index) out of range of 0")
+                case .inline(let inline): return inline[index]
+                case .slice(let slice): return slice[index]
+                case .large(let slice): return slice[index]
+                }
+            }
+            set(newValue) {
+                switch self {
+                case .empty: preconditionFailure("index \(index) out of range of 0")
+                case .inline(var inline):
+                    inline[index] = newValue
+                    self = .inline(inline)
+                case .slice(var slice):
+                    self = .empty
+                    slice[index] = newValue
+                    self = .slice(slice)
+                case .large(var slice):
+                    self = .empty
+                    slice[index] = newValue
+                    self = .large(slice)
+                }
+            }
+        }
+        
+        @inlinable
+        subscript(bounds: Range<Index>) -> Data {
+            get {
+                switch self {
+                case .empty:
+                    precondition(bounds.lowerBound == 0 && (bounds.upperBound - bounds.lowerBound) == 0, "Range \(bounds) out of bounds 0..<0")
+                    return Data()
+                case .inline(let inline):
+                    precondition(bounds.upperBound <= inline.count, "Range \(bounds) out of bounds 0..<\(inline.count)")
+                    if bounds.lowerBound == 0 {
+                        var newInline = inline
+                        newInline.count = bounds.upperBound
+                        return Data(representation: .inline(newInline))
+                    } else {
+                        return Data(representation: .slice(InlineSlice(inline, range: bounds)))
+                    }
+                case .slice(let slice):
+                    precondition(slice.startIndex <= bounds.lowerBound, "Range \(bounds) out of bounds \(slice.range)")
+                    precondition(bounds.lowerBound <= slice.endIndex, "Range \(bounds) out of bounds \(slice.range)")
+                    precondition(slice.startIndex <= bounds.upperBound, "Range \(bounds) out of bounds \(slice.range)")
+                    precondition(bounds.upperBound <= slice.endIndex, "Range \(bounds) out of bounds \(slice.range)")
+                    if bounds.lowerBound == 0 && bounds.upperBound == 0 {
+                        return Data()
+                    } else if bounds.lowerBound == 0 && InlineData.canStore(count: bounds.count) {
+                        return Data(representation: .inline(InlineData(slice, count: bounds.count)))
+                    } else {
+                        var newSlice = slice
+                        newSlice.range = bounds
+                        return Data(representation: .slice(newSlice))
+                    }
+                case .large(let slice):
+                    precondition(slice.startIndex <= bounds.lowerBound, "Range \(bounds) out of bounds \(slice.range)")
+                    precondition(bounds.lowerBound <= slice.endIndex, "Range \(bounds) out of bounds \(slice.range)")
+                    precondition(slice.startIndex <= bounds.upperBound, "Range \(bounds) out of bounds \(slice.range)")
+                    precondition(bounds.upperBound <= slice.endIndex, "Range \(bounds) out of bounds \(slice.range)")
+                    if bounds.lowerBound == 0 && bounds.upperBound == 0 {
+                        return Data()
+                    } else if bounds.lowerBound == 0 && InlineData.canStore(count: bounds.upperBound) {
+                        return Data(representation: .inline(InlineData(slice, count: bounds.upperBound)))
+                    } else if InlineSlice.canStore(count: bounds.lowerBound) && InlineSlice.canStore(count: bounds.upperBound) {
+                        return Data(representation: .slice(InlineSlice(slice, range: bounds)))
+                    } else {
+                        var newSlice = slice
+                        newSlice.slice = RangeReference(bounds)
+                        return Data(representation: .large(newSlice))
+                    }
+                }
+            }
+        }
+
+        @inlinable
+        var startIndex: Int {
+            switch self {
+            case .empty: return 0
+            case .inline: return 0
+            case .slice(let slice): return slice.startIndex
+            case .large(let slice): return slice.startIndex
+            }
+        }
+
+        @inlinable
+        var endIndex: Int {
+            switch self {
+            case .empty: return 0
+            case .inline(let inline): return inline.count
+            case .slice(let slice): return slice.endIndex
+            case .large(let slice): return slice.endIndex
+            }
+        }
+
+        @inlinable
+        func bridgedReference() -> NSData {
+            switch self {
+            case .empty: return NSData()
+            case .inline(let inline):
+                return inline.withUnsafeBytes {
+                    return NSData(bytes: $0.baseAddress, length: $0.count)
+                }
+            case .slice(let slice):
+                return slice.bridgedReference()
+            case .large(let slice):
+                return slice.bridgedReference()
+            }
+        }
+
+        @inlinable
+        func copyBytes(to pointer: UnsafeMutableRawPointer, from range: Range<Int>) {
+            switch self {
+            case .empty:
+                precondition(range.lowerBound == 0 && range.upperBound == 0, "Range \(range) out of bounds 0..<0")
+                return
+            case .inline(let inline):
+                inline.copyBytes(to: pointer, from: range)
+                break
+            case .slice(let slice):
+                slice.copyBytes(to: pointer, from: range)
+            case .large(let slice):
+                slice.copyBytes(to: pointer, from: range)
+            }
+        }
+        
+        @inlinable
+        var hashValue: Int {
+            switch self {
+            case .empty:
+                return Int(bitPattern: CFHashBytes(nil, 0))
+            case .inline(let inline):
+                return inline.hashValue
+            case .slice(let slice):
+                return slice.hashValue
+            case .large(let slice):
+                return slice.hashValue
+            }
+        }
+    }
     
-    @usableFromInline internal var _backing : _DataStorage
-    @usableFromInline internal var _sliceRange: Range<Index>
-    
+    @usableFromInline internal var _representation: _Representation
     
     // A standard or custom deallocator for `Data`.
     ///
@@ -1081,7 +1885,8 @@
         /// A custom deallocator.
         case custom((UnsafeMutableRawPointer, Int) -> Void)
         
-        fileprivate var _deallocator : ((UnsafeMutableRawPointer, Int) -> Void) {
+        @usableFromInline
+        internal var _deallocator : ((UnsafeMutableRawPointer, Int) -> Void) {
 #if DEPLOYMENT_RUNTIME_SWIFT
             switch self {
             case .unmap:
@@ -1091,9 +1896,7 @@
             case .none:
                 return { _, _ in }
             case .custom(let b):
-                return { (ptr, len) in
-                    b(ptr, len)
-                }
+                return b
             }
 #else
             switch self {
@@ -1106,9 +1909,7 @@
             case .none:
                 return { _, _ in }
             case .custom(let b):
-                return { (ptr, len) in
-                    b(ptr, len)
-                }
+                return b
             }
 #endif
         }
@@ -1121,37 +1922,36 @@
     ///
     /// - parameter bytes: A pointer to the memory. It will be copied.
     /// - parameter count: The number of bytes to copy.
+    @inlinable
     public init(bytes: UnsafeRawPointer, count: Int) {
-        _backing = _DataStorage(bytes: bytes, length: count)
-        _sliceRange = 0..<count
+        _representation = _Representation(UnsafeRawBufferPointer(start: bytes, count: count))
     }
-    
+
     /// Initialize a `Data` with copied memory content.
     ///
     /// - parameter buffer: A buffer pointer to copy. The size is calculated from `SourceType` and `buffer.count`.
+    @inlinable
     public init<SourceType>(buffer: UnsafeBufferPointer<SourceType>) {
-        let count = MemoryLayout<SourceType>.stride * buffer.count
-        _backing = _DataStorage(bytes: buffer.baseAddress, length: count)
-        _sliceRange = 0..<count
+        _representation = _Representation(UnsafeRawBufferPointer(buffer))
     }
     
     /// Initialize a `Data` with copied memory content.
     ///
     /// - parameter buffer: A buffer pointer to copy. The size is calculated from `SourceType` and `buffer.count`.
+    @inlinable
     public init<SourceType>(buffer: UnsafeMutableBufferPointer<SourceType>) {
-        let count = MemoryLayout<SourceType>.stride * buffer.count
-        _backing = _DataStorage(bytes: buffer.baseAddress, length: count)
-        _sliceRange = 0..<count
+        _representation = _Representation(UnsafeRawBufferPointer(buffer))
     }
     
     /// Initialize a `Data` with a repeating byte pattern
     ///
     /// - parameter repeatedValue: A byte to initialize the pattern
     /// - parameter count: The number of bytes the data initially contains initialized to the repeatedValue
+    @inlinable
     public init(repeating repeatedValue: UInt8, count: Int) {
         self.init(count: count)
-        withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> Void in
-            memset(bytes, Int32(repeatedValue), count)
+        withUnsafeMutableBytes { (buffer: UnsafeMutableRawBufferPointer) -> Void in
+            memset(buffer.baseAddress, Int32(repeatedValue), buffer.count)
         }
     }
     
@@ -1164,23 +1964,23 @@
     /// If the capacity specified in `capacity` is greater than four memory pages in size, this may round the amount of requested memory up to the nearest full page.
     ///
     /// - parameter capacity: The size of the data.
+    @inlinable
     public init(capacity: Int) {
-        _backing = _DataStorage(capacity: capacity)
-        _sliceRange = 0..<0
+        _representation = _Representation(capacity: capacity)
     }
     
     /// Initialize a `Data` with the specified count of zeroed bytes.
     ///
     /// - parameter count: The number of bytes the data initially contains.
+    @inlinable
     public init(count: Int) {
-        _backing = _DataStorage(length: count)
-        _sliceRange = 0..<count
+        _representation = _Representation(count: count)
     }
     
     /// Initialize an empty `Data`.
+    @inlinable
     public init() {
-        _backing = _DataStorage(length: 0)
-        _sliceRange = 0..<0
+        _representation = .empty
     }
     
     
@@ -1190,10 +1990,15 @@
     /// - parameter bytes: A pointer to the bytes.
     /// - parameter count: The size of the bytes.
     /// - parameter deallocator: Specifies the mechanism to free the indicated buffer, or `.none`.
+    @inlinable
     public init(bytesNoCopy bytes: UnsafeMutableRawPointer, count: Int, deallocator: Deallocator) {
         let whichDeallocator = deallocator._deallocator
-        _backing = _DataStorage(bytes: bytes, length: count, copy: false, deallocator: whichDeallocator, offset: 0)
-        _sliceRange = 0..<count
+        if count == 0 {
+            deallocator._deallocator(bytes, count)
+            _representation = .empty
+        } else {
+            _representation = _Representation(_DataStorage(bytes: bytes, length: count, copy: false, deallocator: whichDeallocator, offset: 0), count: count)
+        }
     }
     
     /// Initialize a `Data` with the contents of a `URL`.
@@ -1201,10 +2006,10 @@
     /// - parameter url: The `URL` to read.
     /// - parameter options: Options for the read operation. Default value is `[]`.
     /// - throws: An error in the Cocoa domain, if `url` cannot be read.
+    @inlinable
     public init(contentsOf url: __shared URL, options: Data.ReadingOptions = []) throws {
         let d = try NSData(contentsOf: url, options: ReadingOptions(rawValue: options.rawValue))
-        _backing = _DataStorage(immutableReference: d, offset: 0)
-        _sliceRange = 0..<d.length
+        self.init(bytes: d.bytes, count: d.length)
     }
     
     /// Initialize a `Data` from a Base-64 encoded String using the given options.
@@ -1212,10 +2017,10 @@
     /// Returns nil when the input is not recognized as valid Base-64.
     /// - parameter base64String: The string to parse.
     /// - parameter options: Encoding options. Default value is `[]`.
+    @inlinable
     public init?(base64Encoded base64String: __shared String, options: Data.Base64DecodingOptions = []) {
         if let d = NSData(base64Encoded: base64String, options: Base64DecodingOptions(rawValue: options.rawValue)) {
-            _backing = _DataStorage(immutableReference: d, offset: 0)
-            _sliceRange = 0..<d.length
+            self.init(bytes: d.bytes, count: d.length)
         } else {
             return nil
         }
@@ -1227,10 +2032,10 @@
     ///
     /// - parameter base64Data: Base-64, UTF-8 encoded input data.
     /// - parameter options: Decoding options. Default value is `[]`.
+    @inlinable
     public init?(base64Encoded base64Data: __shared Data, options: Data.Base64DecodingOptions = []) {
         if let d = NSData(base64Encoded: base64Data, options: Base64DecodingOptions(rawValue: options.rawValue)) {
-            _backing = _DataStorage(immutableReference: d, offset: 0)
-            _sliceRange = 0..<d.length
+            self.init(bytes: d.bytes, count: d.length)
         } else {
             return nil
         }
@@ -1244,35 +2049,71 @@
     ///
     /// - parameter reference: The instance of `NSData` that you wish to wrap. This instance will be copied by `struct Data`.
     public init(referencing reference: __shared NSData) {
-#if DEPLOYMENT_RUNTIME_SWIFT
-        let providesConcreteBacking = reference._providesConcreteBacking()
-#else
-        let providesConcreteBacking = (reference as AnyObject)._providesConcreteBacking?() ?? false
-#endif
-        if providesConcreteBacking {
-            _backing = _DataStorage(immutableReference: reference.copy() as! NSData, offset: 0)
-            _sliceRange = 0..<reference.length
+        // This is not marked as inline because _providesConcreteBacking would need to be marked as usable from inline however that is a dynamic lookup in objc contexts.
+        let length = reference.length
+        if length == 0 {
+            _representation = .empty
         } else {
-            _backing = _DataStorage(customReference: reference.copy() as! NSData, offset: 0)
-            _sliceRange = 0..<reference.length
+#if DEPLOYMENT_RUNTIME_SWIFT
+            let providesConcreteBacking = reference._providesConcreteBacking()
+#else
+            let providesConcreteBacking = (reference as AnyObject)._providesConcreteBacking?() ?? false
+#endif
+            if providesConcreteBacking {
+                _representation = _Representation(_DataStorage(immutableReference: reference.copy() as! NSData, offset: 0), count: length)
+            } else {
+                _representation = _Representation(_DataStorage(customReference: reference.copy() as! NSData, offset: 0), count: length)
+            }
         }
         
     }
     
     // slightly faster paths for common sequences
     @inlinable
-    public init<S: Sequence>(_ elements: S) where S.Iterator.Element == UInt8 {
-        let backing = _DataStorage(capacity: Swift.max(elements.underestimatedCount, 1))
-        var (iter, endIndex) = elements._copyContents(initializing: UnsafeMutableBufferPointer(start: backing._bytes?.bindMemory(to: UInt8.self, capacity: backing._capacity), count: backing._capacity))
-        backing._length = endIndex
-        while var element = iter.next() {
-            backing.append(&element, length: 1)
+    @inline(__always)
+    public init<S: Sequence>(_ elements: S) where S.Element == UInt8 {
+        // If the sequence is already contiguous, access the underlying raw memory directly.
+        if let contiguous = elements as? ContiguousBytes {
+            _representation = contiguous.withUnsafeBytes { return _Representation($0) }
+            return
         }
-        self.init(backing: backing, range: 0..<backing._length)
+
+        // The sequence might still be able to provide direct access to typed memory.
+        // NOTE: It's safe to do this because we're already guarding on S's element as `UInt8`. This would not be safe on arbitrary sequences.
+        let representation = elements.withContiguousStorageIfAvailable {
+            return _Representation(UnsafeRawBufferPointer($0))
+        }
+
+        if let representation = representation {
+            _representation = representation
+        } else {
+            // Dummy assignment so we can capture below.
+            _representation = _Representation(capacity: 0)
+
+            // Copy as much as we can in one shot from the sequence.
+            let underestimatedCount = Swift.max(elements.underestimatedCount, 1)
+            _withStackOrHeapBuffer(underestimatedCount) { (buffer) in
+                // In order to copy from the sequence, we have to bind the buffer to UInt8.
+                // This is safe since we'll copy out of this buffer as raw memory later.
+                let capacity = buffer.pointee.capacity
+                let base = buffer.pointee.memory.bindMemory(to: UInt8.self, capacity: capacity)
+                var (iter, endIndex) = elements._copyContents(initializing: UnsafeMutableBufferPointer(start: base, count: capacity))
+
+                // Copy the contents of buffer...
+                _representation = _Representation(UnsafeRawBufferPointer(start: base, count: endIndex))
+
+                // ... and append the rest byte-wise.
+                while let element = iter.next() {
+                    Swift.withUnsafeBytes(of: element) {
+                        _representation.append(contentsOf: $0)
+                    }
+                }
+            }
+        }
     }
     
     @available(swift, introduced: 4.2)
-    @inlinable
+    @available(swift, deprecated: 5, message: "use `init(_:)` instead")
     public init<S: Sequence>(bytes elements: S) where S.Iterator.Element == UInt8 {
         self.init(elements)
     }
@@ -1286,68 +2127,67 @@
     public init(bytes: ArraySlice<UInt8>) {
        self.init(bytes)
     }
-
-    @usableFromInline
-    internal init(backing: _DataStorage, range: Range<Index>) {
-        _backing = backing
-        _sliceRange = range
-    }
     
-    @usableFromInline
-    internal func _validateIndex(_ index: Int, message: String? = nil) {
-        precondition(_sliceRange.contains(index), message ?? "Index \(index) is out of bounds of range \(_sliceRange)")
-    }
-    
-    @usableFromInline
-    internal func _validateRange<R: RangeExpression>(_ range: R) where R.Bound == Int {
-        let lower = R.Bound(_sliceRange.lowerBound)
-        let upper = R.Bound(_sliceRange.upperBound)
-        let r = range.relative(to: lower..<upper)
-        precondition(r.lowerBound >= _sliceRange.lowerBound && r.lowerBound <= _sliceRange.upperBound, "Range \(r) is out of bounds of range \(_sliceRange)")
-        precondition(r.upperBound >= _sliceRange.lowerBound && r.upperBound <= _sliceRange.upperBound, "Range \(r) is out of bounds of range \(_sliceRange)")
+    @inlinable
+    internal init(representation: _Representation) {
+        _representation = representation
     }
     
     // -----------------------------------
     // MARK: - Properties and Functions
+
+    @inlinable
+    public mutating func reserveCapacity(_ minimumCapacity: Int) {
+        _representation.reserveCapacity(minimumCapacity)
+    }
     
     /// The number of bytes in the data.
-    
+    @inlinable
     public var count: Int {
         get {
-            return _sliceRange.count
+            return _representation.count
         }
-        set {
-            precondition(count >= 0, "count must not be negative")
-            if !isKnownUniquelyReferenced(&_backing) {
-                _backing = _backing.mutableCopy(_sliceRange)
-            }
-            _backing.length = newValue
-            _sliceRange = _sliceRange.lowerBound..<(_sliceRange.lowerBound + newValue)
+        set(newValue) {
+            precondition(newValue >= 0, "count must not be negative")
+            _representation.count = newValue
         }
     }
+
+    @inlinable
+    public var regions: CollectionOfOne<Data> {
+        return CollectionOfOne(self)
+    }
     
     /// Access the bytes in the data.
     ///
     /// - warning: The byte pointer argument should not be stored and used outside of the lifetime of the call to the closure.
+    @available(swift, deprecated: 5, message: "use `withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R` instead")
     public func withUnsafeBytes<ResultType, ContentType>(_ body: (UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType {
-        return try _backing.withUnsafeBytes(in: _sliceRange) {
+        return try _representation.withUnsafeBytes {
             return try body($0.baseAddress?.assumingMemoryBound(to: ContentType.self) ?? UnsafePointer<ContentType>(bitPattern: 0xBAD0)!)
         }
     }
     
-    
+    @inlinable
+    public func withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
+        return try _representation.withUnsafeBytes(body)
+    }
+
     /// Mutate the bytes in the data.
     ///
     /// This function assumes that you are mutating the contents.
     /// - warning: The byte pointer argument should not be stored and used outside of the lifetime of the call to the closure.
+    @available(swift, deprecated: 5, message: "use `withUnsafeMutableBytes<R>(_: (UnsafeMutableRawBufferPointer) throws -> R) rethrows -> R` instead")
     public mutating func withUnsafeMutableBytes<ResultType, ContentType>(_ body: (UnsafeMutablePointer<ContentType>) throws -> ResultType) rethrows -> ResultType {
-        if !isKnownUniquelyReferenced(&_backing) {
-            _backing = _backing.mutableCopy(_sliceRange)
-        }
-        return try _backing.withUnsafeMutableBytes(in: _sliceRange) {
+        return try _representation.withUnsafeMutableBytes {
             return try body($0.baseAddress?.assumingMemoryBound(to: ContentType.self) ?? UnsafeMutablePointer<ContentType>(bitPattern: 0xBAD0)!)
         }
     }
+
+    @inlinable
+    public mutating func withUnsafeMutableBytes<ResultType>(_ body: (UnsafeMutableRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
+        return try _representation.withUnsafeMutableBytes(body)
+    }
     
     // MARK: -
     // MARK: Copy Bytes
@@ -1357,19 +2197,17 @@
     /// - parameter pointer: A pointer to the buffer you wish to copy the bytes into.
     /// - parameter count: The number of bytes to copy.
     /// - warning: This method does not verify that the contents at pointer have enough space to hold `count` bytes.
+    @inlinable
     public func copyBytes(to pointer: UnsafeMutablePointer<UInt8>, count: Int) {
         precondition(count >= 0, "count of bytes to copy must not be negative")
         if count == 0 { return }
-        _backing.withUnsafeBytes(in: _sliceRange) {
-            memcpy(UnsafeMutableRawPointer(pointer), $0.baseAddress!, Swift.min(count, $0.count))
-        }
+        _copyBytesHelper(to: UnsafeMutableRawPointer(pointer), from: startIndex..<(startIndex + count))
     }
     
-    private func _copyBytesHelper(to pointer: UnsafeMutableRawPointer, from range: NSRange) {
-        if range.length == 0 { return }
-        _backing.withUnsafeBytes(in: range.lowerBound..<range.upperBound) {
-            memcpy(UnsafeMutableRawPointer(pointer), $0.baseAddress!, Swift.min(range.length, $0.count))
-        }
+    @inlinable
+    internal func _copyBytesHelper(to pointer: UnsafeMutableRawPointer, from range: Range<Int>) {
+        if range.isEmpty { return }
+        _representation.copyBytes(to: pointer, from: range)
     }
     
     /// Copy a subset of the contents of the data to a pointer.
@@ -1377,8 +2215,9 @@
     /// - parameter pointer: A pointer to the buffer you wish to copy the bytes into.
     /// - parameter range: The range in the `Data` to copy.
     /// - warning: This method does not verify that the contents at pointer have enough space to hold the required number of bytes.
+    @inlinable
     public func copyBytes(to pointer: UnsafeMutablePointer<UInt8>, from range: Range<Index>) {
-        _copyBytesHelper(to: pointer, from: NSRange(range))
+        _copyBytesHelper(to: pointer, from: range)
     }
     
     // Copy the contents of the data into a buffer.
@@ -1388,6 +2227,7 @@
     /// - parameter buffer: A buffer to copy the data into.
     /// - parameter range: A range in the data to copy into the buffer. If the range is empty, this function will return 0 without copying anything. If the range is nil, as much data as will fit into `buffer` is copied.
     /// - returns: Number of bytes copied into the destination buffer.
+    @inlinable
     public func copyBytes<DestinationType>(to buffer: UnsafeMutableBufferPointer<DestinationType>, from range: Range<Index>? = nil) -> Int {
         let cnt = count
         guard cnt > 0 else { return 0 }
@@ -1395,17 +2235,15 @@
         let copyRange : Range<Index>
         if let r = range {
             guard !r.isEmpty else { return 0 }
-            copyRange = r.lowerBound..<(r.lowerBound + Swift.min(buffer.count * MemoryLayout<DestinationType>.stride, r.count))
+            copyRange = r.lowerBound..<(r.lowerBound + Swift.min(buffer.count * MemoryLayout<DestinationType>.stride, r.upperBound - r.lowerBound))
         } else {
             copyRange = 0..<Swift.min(buffer.count * MemoryLayout<DestinationType>.stride, cnt)
         }
-        _validateRange(copyRange)
         
         guard !copyRange.isEmpty else { return 0 }
         
-        let nsRange = NSRange(location: copyRange.lowerBound, length: copyRange.upperBound - copyRange.lowerBound)
-        _copyBytesHelper(to: buffer.baseAddress!, from: nsRange)
-        return copyRange.count
+        _copyBytesHelper(to: buffer.baseAddress!, from: copyRange)
+        return copyRange.upperBound - copyRange.lowerBound
     }
     
     // MARK: -
@@ -1431,7 +2269,8 @@
     /// - parameter options: Options for writing the data. Default value is `[]`.
     /// - throws: An error in the Cocoa domain, if there is an error writing to the `URL`.
     public func write(to url: URL, options: Data.WritingOptions = []) throws {
-        try _backing.withInteriorPointerReference(_sliceRange) {
+        // this should not be marked as inline since in objc contexts we correct atomicity via _shouldUseNonAtomicWriteReimplementation
+        try _representation.withInteriorPointerReference {
 #if DEPLOYMENT_RUNTIME_SWIFT
             try $0.write(to: url, options: WritingOptions(rawValue: options.rawValue))
 #else
@@ -1454,15 +2293,15 @@
     /// - parameter range: The range of this data in which to perform the search. Default value is `nil`, which means the entire content of this data.
     /// - returns: A `Range` specifying the location of the found data, or nil if a match could not be found.
     /// - precondition: `range` must be in the bounds of the Data.
+    @inlinable
     public func range(of dataToFind: Data, options: Data.SearchOptions = [], in range: Range<Index>? = nil) -> Range<Index>? {
         let nsRange : NSRange
         if let r = range {
-            _validateRange(r)
             nsRange = NSRange(location: r.lowerBound - startIndex, length: r.upperBound - r.lowerBound)
         } else {
             nsRange = NSRange(location: 0, length: count)
         }
-        let result = _backing.withInteriorPointerReference(_sliceRange) {
+        let result = _representation.withInteriorPointerReference {
             $0.range(of: dataToFind, options: options, in: nsRange)
         }
         if result.location == NSNotFound {
@@ -1475,38 +2314,40 @@
     ///
     /// In some cases, (for example, a `Data` backed by a `dispatch_data_t`, the bytes may be stored discontiguously. In those cases, this function invokes the closure for each contiguous region of bytes.
     /// - parameter block: The closure to invoke for each region of data. You may stop the enumeration by setting the `stop` parameter to `true`.
+    @available(swift, deprecated: 5, message: "use `regions` or `for-in` instead")
     public func enumerateBytes(_ block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Index, _ stop: inout Bool) -> Void) {
-        _backing.enumerateBytes(in: _sliceRange, block)
+        _representation.enumerateBytes(block)
     }
 
     @inlinable
     internal mutating func _append<SourceType>(_ buffer : UnsafeBufferPointer<SourceType>) {
         if buffer.isEmpty { return }
-        if !isKnownUniquelyReferenced(&_backing) {
-            _backing = _backing.mutableCopy(_sliceRange)
-        }
-        _backing.replaceBytes(in: NSRange(location: _sliceRange.upperBound, length: _backing.length - (_sliceRange.upperBound - _backing._offset)), with: buffer.baseAddress, length: buffer.count * MemoryLayout<SourceType>.stride)
-        _sliceRange = _sliceRange.lowerBound..<(_sliceRange.upperBound + buffer.count * MemoryLayout<SourceType>.stride)
+        _representation.append(contentsOf: UnsafeRawBufferPointer(buffer))
     }
     
+    @inlinable
     public mutating func append(_ bytes: UnsafePointer<UInt8>, count: Int) {
         if count == 0 { return }
         _append(UnsafeBufferPointer(start: bytes, count: count))
     }
     
+    @inlinable
     public mutating func append(_ other: Data) {
-        other.enumerateBytes { (buffer, _, _) in
-            _append(buffer)
+        guard other.count > 0 else { return }
+        other.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) in
+            _representation.append(contentsOf: buffer)
         }
     }
     
     /// Append a buffer of bytes to the data.
     ///
     /// - parameter buffer: The buffer of bytes to append. The size is calculated from `SourceType` and `buffer.count`.
+    @inlinable
     public mutating func append<SourceType>(_ buffer : UnsafeBufferPointer<SourceType>) {
         _append(buffer)
     }
 
+    @inlinable
     public mutating func append(contentsOf bytes: [UInt8]) {
         bytes.withUnsafeBufferPointer { (buffer: UnsafeBufferPointer<UInt8>) -> Void in
             _append(buffer)
@@ -1514,15 +2355,44 @@
     }
 
     @inlinable
-    public mutating func append<S : Sequence>(contentsOf newElements: S) where S.Iterator.Element == Iterator.Element {
-        let underestimatedCount = Swift.max(newElements.underestimatedCount, 1)
+    public mutating func append<S: Sequence>(contentsOf elements: S) where S.Element == Element {
+        // If the sequence is already contiguous, access the underlying raw memory directly.
+        if let contiguous = elements as? ContiguousBytes {
+            contiguous.withUnsafeBytes {
+                _representation.append(contentsOf: $0)
+            }
+
+            return
+        }
+
+        // The sequence might still be able to provide direct access to typed memory.
+        // NOTE: It's safe to do this because we're already guarding on S's element as `UInt8`. This would not be safe on arbitrary sequences.
+        var appended = false
+        elements.withContiguousStorageIfAvailable {
+            _representation.append(contentsOf: UnsafeRawBufferPointer($0))
+            appended = true
+        }
+
+        guard !appended else { return }
+
+        // The sequence is really not contiguous.
+        // Copy as much as we can in one shot.
+        let underestimatedCount = Swift.max(elements.underestimatedCount, 1)
         _withStackOrHeapBuffer(underestimatedCount) { (buffer) in
+            // In order to copy from the sequence, we have to bind the temporary buffer to `UInt8`.
+            // This is safe since we're the only owners of the buffer and we copy out as raw memory below anyway.
             let capacity = buffer.pointee.capacity
             let base = buffer.pointee.memory.bindMemory(to: UInt8.self, capacity: capacity)
-            var (iter, endIndex) = newElements._copyContents(initializing: UnsafeMutableBufferPointer(start: base, count: capacity))
-            _append(UnsafeBufferPointer(start: base, count: endIndex))
-            while var element = iter.next() {
-                append(&element, count: 1)
+            var (iter, endIndex) = elements._copyContents(initializing: UnsafeMutableBufferPointer(start: base, count: capacity))
+
+            // Copy the contents of the buffer...
+            _representation.append(contentsOf: UnsafeRawBufferPointer(start: base, count: endIndex))
+
+            /// ... and append the rest byte-wise.
+            while let element = iter.next() {
+                Swift.withUnsafeBytes(of: element) {
+                    _representation.append(contentsOf: $0)
+                }
             }
         }
     }
@@ -1533,18 +2403,12 @@
     ///
     /// If `range` exceeds the bounds of the data, then the data is resized to fit.
     /// - parameter range: The range in the data to set to `0`.
+    @inlinable
     public mutating func resetBytes(in range: Range<Index>) {
         // it is worth noting that the range here may be out of bounds of the Data itself (which triggers a growth)
         precondition(range.lowerBound >= 0, "Ranges must not be negative bounds")
         precondition(range.upperBound >= 0, "Ranges must not be negative bounds")
-        let range = NSRange(location: range.lowerBound, length: range.upperBound - range.lowerBound)
-        if !isKnownUniquelyReferenced(&_backing) {
-            _backing = _backing.mutableCopy(_sliceRange)
-        }
-        _backing.resetBytes(in: range)
-        if _sliceRange.upperBound < range.upperBound {
-            _sliceRange = _sliceRange.lowerBound..<range.upperBound
-        }
+        _representation.resetBytes(in: range)
     }
     
     /// Replace a region of bytes in the data with new data.
@@ -1554,10 +2418,10 @@
     /// - precondition: The bounds of `subrange` must be valid indices of the collection.
     /// - parameter subrange: The range in the data to replace. If `subrange.lowerBound == data.count && subrange.count == 0` then this operation is an append.
     /// - parameter data: The replacement data.
+    @inlinable
     public mutating func replaceSubrange(_ subrange: Range<Index>, with data: Data) {
-        let cnt = data.count
-        data.withUnsafeBytes {
-            replaceSubrange(subrange, with: $0, count: cnt)
+        data.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) in
+            _representation.replaceSubrange(subrange, with: buffer.baseAddress, count: buffer.count)
         }
     }
     
@@ -1568,6 +2432,7 @@
     /// - precondition: The bounds of `subrange` must be valid indices of the collection.
     /// - parameter subrange: The range in the data to replace.
     /// - parameter buffer: The replacement bytes.
+    @inlinable
     public mutating func replaceSubrange<SourceType>(_ subrange: Range<Index>, with buffer: UnsafeBufferPointer<SourceType>) {
         guard !buffer.isEmpty  else { return }
         replaceSubrange(subrange, with: buffer.baseAddress!, count: buffer.count * MemoryLayout<SourceType>.stride)
@@ -1580,9 +2445,9 @@
     /// - precondition: The bounds of `subrange` must be valid indices of the collection.
     /// - parameter subrange: The range in the data to replace.
     /// - parameter newElements: The replacement bytes.
+    @inlinable
     public mutating func replaceSubrange<ByteCollection : Collection>(_ subrange: Range<Index>, with newElements: ByteCollection) where ByteCollection.Iterator.Element == Data.Iterator.Element {
-        _validateRange(subrange)
-        let totalCount: Int = numericCast(newElements.count)
+        let totalCount = Int(newElements.count)
         _withStackOrHeapBuffer(totalCount) { conditionalBuffer in
             let buffer = UnsafeMutableBufferPointer(start: conditionalBuffer.pointee.memory.assumingMemoryBound(to: UInt8.self), count: totalCount)
             var (iterator, index) = newElements._copyContents(initializing: buffer)
@@ -1594,27 +2459,24 @@
         }
     }
     
+    @inlinable
     public mutating func replaceSubrange(_ subrange: Range<Index>, with bytes: UnsafeRawPointer, count cnt: Int) {
-        _validateRange(subrange)
-        let nsRange = NSRange(location: subrange.lowerBound, length: subrange.upperBound - subrange.lowerBound)
-        if !isKnownUniquelyReferenced(&_backing) {
-            _backing = _backing.mutableCopy(_sliceRange)
-        }
-        let upper = _sliceRange.upperBound
-        _backing.replaceBytes(in: nsRange, with: bytes, length: cnt)
-        let resultingUpper = upper - nsRange.length + cnt
-        _sliceRange = _sliceRange.lowerBound..<resultingUpper
+        _representation.replaceSubrange(subrange, with: bytes, count: cnt)
     }
     
     /// Return a new copy of the data in a specified range.
     ///
     /// - parameter range: The range to copy.
+    @inlinable
     public func subdata(in range: Range<Index>) -> Data {
-        _validateRange(range)
-        if isEmpty {
+        if isEmpty || range.upperBound - range.lowerBound == 0 {
             return Data()
         }
-        return _backing.subdata(in: range)
+        let slice = self[range]
+
+        return slice.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) -> Data in
+            return Data(bytes: buffer.baseAddress!, count: buffer.count)
+        }
     }
     
     // MARK: -
@@ -1624,8 +2486,9 @@
     ///
     /// - parameter options: The options to use for the encoding. Default value is `[]`.
     /// - returns: The Base-64 encoded string.
+    @inlinable
     public func base64EncodedString(options: Data.Base64EncodingOptions = []) -> String {
-        return _backing.withInteriorPointerReference(_sliceRange) {
+        return _representation.withInteriorPointerReference {
             return $0.base64EncodedString(options: options)
         }
     }
@@ -1634,8 +2497,9 @@
     ///
     /// - parameter options: The options to use for the encoding. Default value is `[]`.
     /// - returns: The Base-64 encoded data.
+    @inlinable
     public func base64EncodedData(options: Data.Base64EncodingOptions = []) -> Data {
-        return _backing.withInteriorPointerReference(_sliceRange) {
+        return _representation.withInteriorPointerReference {
             return $0.base64EncodedData(options: options)
         }
     }
@@ -1644,26 +2508,17 @@
     //
     
     /// The hash value for the data.
+    @inlinable
     public var hashValue: Int {
-        var hashValue = 0
-        let hashRange: Range<Int> = _sliceRange.lowerBound..<Swift.min(_sliceRange.lowerBound + 80, _sliceRange.upperBound)
-        _withStackOrHeapBuffer(hashRange.count + 1) { buffer in
-            if !hashRange.isEmpty {
-                _backing.withUnsafeBytes(in: hashRange) {
-                    memcpy(buffer.pointee.memory, $0.baseAddress!, hashRange.count)
-                }
-            }
-            hashValue = Int(bitPattern: CFHashBytes(buffer.pointee.memory.assumingMemoryBound(to: UInt8.self), hashRange.count))
-        }
-        return hashValue
+        return _representation.hashValue
     }
     
+    @inlinable
     public func advanced(by amount: Int) -> Data {
-        _validateIndex(startIndex + amount)
         let length = count - amount
         precondition(length > 0)
-        return withUnsafeBytes { (ptr: UnsafePointer<UInt8>) -> Data in
-            return Data(bytes: ptr.advanced(by: amount), count: length)
+        return withUnsafeBytes { (ptr: UnsafeRawBufferPointer) -> Data in
+            return Data(bytes: ptr.baseAddress!.advanced(by: amount), count: length)
         }
     }
     
@@ -1673,149 +2528,156 @@
     // MARK: Index and Subscript
     
     /// Sets or returns the byte at the specified index.
+    @inlinable
     public subscript(index: Index) -> UInt8 {
         get {
-            _validateIndex(index)
-            return _backing.get(index)
+            return _representation[index]
         }
-        set {
-            _validateIndex(index)
-            if !isKnownUniquelyReferenced(&_backing) {
-                _backing = _backing.mutableCopy(_sliceRange)
-            }
-            _backing.set(index, to: newValue)
+        set(newValue) {
+            _representation[index] = newValue
         }
     }
     
+    @inlinable
     public subscript(bounds: Range<Index>) -> Data {
         get {
-            _validateRange(bounds)
-            return Data(backing: _backing, range: bounds)
+            return _representation[bounds]
         }
         set {
             replaceSubrange(bounds, with: newValue)
         }
     }
     
+    @inlinable
     public subscript<R: RangeExpression>(_ rangeExpression: R) -> Data
         where R.Bound: FixedWidthInteger {
         get {
-            let lower = R.Bound(_sliceRange.lowerBound)
-            let upper = R.Bound(_sliceRange.upperBound)
+            let lower = R.Bound(startIndex)
+            let upper = R.Bound(endIndex)
             let range = rangeExpression.relative(to: lower..<upper)
-            let start: Int = numericCast(range.lowerBound)
-            let end: Int = numericCast(range.upperBound)
+            let start = Int(range.lowerBound)
+            let end = Int(range.upperBound)
             let r: Range<Int> = start..<end
-            _validateRange(r)
-            return Data(backing: _backing, range: r)
+            return _representation[r]
         }
         set {
-            let lower = R.Bound(_sliceRange.lowerBound)
-            let upper = R.Bound(_sliceRange.upperBound)
+            let lower = R.Bound(startIndex)
+            let upper = R.Bound(endIndex)
             let range = rangeExpression.relative(to: lower..<upper)
-            let start: Int = numericCast(range.lowerBound)
-            let end: Int = numericCast(range.upperBound)
+            let start = Int(range.lowerBound)
+            let end = Int(range.upperBound)
             let r: Range<Int> = start..<end
-            _validateRange(r)
             replaceSubrange(r, with: newValue)
         }
-        
     }
     
     /// The start `Index` in the data.
+    @inlinable
     public var startIndex: Index {
         get {
-            return _sliceRange.lowerBound
+            return _representation.startIndex
         }
     }
     
     /// The end `Index` into the data.
     ///
     /// This is the "one-past-the-end" position, and will always be equal to the `count`.
+    @inlinable
     public var endIndex: Index {
         get {
-            return _sliceRange.upperBound
+            return _representation.endIndex
         }
     }
     
+    @inlinable
     public func index(before i: Index) -> Index {
         return i - 1
     }
     
+    @inlinable
     public func index(after i: Index) -> Index {
         return i + 1
     }
     
+    @inlinable
     public var indices: Range<Int> {
         get {
             return startIndex..<endIndex
         }
     }
     
+    @inlinable
     public func _copyContents(initializing buffer: UnsafeMutableBufferPointer<UInt8>) -> (Iterator, UnsafeMutableBufferPointer<UInt8>.Index) {
         guard !isEmpty else { return (makeIterator(), buffer.startIndex) }
-        guard let p = buffer.baseAddress else {
-            preconditionFailure("Attempt to copy contents into nil buffer pointer")
+        let cnt = Swift.min(count, buffer.count)
+        
+        withUnsafeBytes { (bytes: UnsafeRawBufferPointer) in
+            _ = memcpy(UnsafeMutableRawPointer(buffer.baseAddress), bytes.baseAddress, cnt)
         }
-        let cnt = count
-        precondition(cnt <= buffer.count, "Insufficient space allocated to copy Data contents")
         
-        withUnsafeBytes { p.initialize(from: $0, count: cnt) }
-        
-        return (Iterator(endOf: self), buffer.index(buffer.startIndex, offsetBy: cnt))
+        return (Iterator(self, at: startIndex + cnt), buffer.index(buffer.startIndex, offsetBy: cnt))
     }
     
     /// An iterator over the contents of the data.
     ///
     /// The iterator will increment byte-by-byte.
+    @inlinable
     public func makeIterator() -> Data.Iterator {
-        return Iterator(self)
+        return Iterator(self, at: startIndex)
     }
     
     public struct Iterator : IteratorProtocol {
-        // Both _data and _endIdx should be 'let' rather than 'var'.
-        // They are 'var' so that the stored properties can be read
-        // independently of the other contents of the struct. This prevents
-        // an exclusivity violation when reading '_endIdx' and '_data'
-        // while simultaneously mutating '_buffer' with the call to
-        // withUnsafeMutablePointer(). Once we support accessing struct
-        // let properties independently we should make these variables
-        // 'let' again.
+        @usableFromInline
+        internal typealias Buffer = (
+            UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
+            UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
+            UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
+            UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)
 
-        private var _data: Data
-        private var _buffer: (
-        UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
-        UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
-        UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8,
-        UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)
-        private var _idx: Data.Index
-        private var _endIdx: Data.Index
+        @usableFromInline internal let _data: Data
+        @usableFromInline internal var _buffer: Buffer
+        @usableFromInline internal var _idx: Data.Index
+        @usableFromInline internal let _endIdx: Data.Index
         
-        fileprivate init(_ data: Data) {
+        @usableFromInline
+        internal init(_ data: Data, at loc: Data.Index) {
+            // The let vars prevent this from being marked as @inlinable
             _data = data
             _buffer = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
-            _idx = data.startIndex
+            _idx = loc
             _endIdx = data.endIndex
+
+            let bufferSize = MemoryLayout<Buffer>.size
+            Swift.withUnsafeMutableBytes(of: &_buffer) {
+                let ptr = $0.bindMemory(to: UInt8.self)
+                let bufferIdx = (loc - data.startIndex) % bufferSize
+                data.copyBytes(to: ptr, from: (loc - bufferIdx)..<(data.endIndex - (loc - bufferIdx) > bufferSize ? (loc - bufferIdx) + bufferSize : data.endIndex))
+            }
         }
         
-        fileprivate init(endOf data: Data) {
-            self._data = data
-            _buffer = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
-            _idx = data.endIndex
-            _endIdx = data.endIndex
-        }
-        
+        @inlinable
         public mutating func next() -> UInt8? {
-            guard _idx < _endIdx else { return nil }
-            defer { _idx += 1 }
-            let bufferSize = MemoryLayout.size(ofValue: _buffer)
-            return withUnsafeMutablePointer(to: &_buffer) { ptr_ in
-                let ptr = UnsafeMutableRawPointer(ptr_).assumingMemoryBound(to: UInt8.self)
-                let bufferIdx = (_idx - _data.startIndex) % bufferSize
-                if bufferIdx == 0 {
+            let idx = _idx
+            let bufferSize = MemoryLayout<Buffer>.size
+
+            guard idx < _endIdx else { return nil }
+            _idx += 1
+
+            let bufferIdx = (idx - _data.startIndex) % bufferSize
+
+
+            if bufferIdx == 0 {
+                var buffer = _buffer
+                Swift.withUnsafeMutableBytes(of: &buffer) {
+                    let ptr = $0.bindMemory(to: UInt8.self)
                     // populate the buffer
-                    _data.copyBytes(to: ptr, from: _idx..<(_endIdx - _idx > bufferSize ? _idx + bufferSize : _endIdx))
+                    _data.copyBytes(to: ptr, from: idx..<(_endIdx - idx > bufferSize ? idx + bufferSize : _endIdx))
                 }
+                _buffer = buffer
+            }
+
+            return Swift.withUnsafeMutableBytes(of: &_buffer) {
+                let ptr = $0.bindMemory(to: UInt8.self)
                 return ptr[bufferIdx]
             }
         }
@@ -1837,27 +2699,16 @@
     public var mutableBytes: UnsafeMutableRawPointer { fatalError() }
     
     /// Returns `true` if the two `Data` arguments are equal.
+    @inlinable
     public static func ==(d1 : Data, d2 : Data) -> Bool {
-        let backing1 = d1._backing
-        let backing2 = d2._backing
-        if backing1 === backing2 {
-            if d1._sliceRange == d2._sliceRange {
-                return true
-            }
-        }
         let length1 = d1.count
         if length1 != d2.count {
             return false
         }
-        if backing1.bytes == backing2.bytes {
-            if d1._sliceRange == d2._sliceRange {
-                return true
-            }
-        }
         if length1 > 0 {
-            return d1.withUnsafeBytes { (b1) in
-                return d2.withUnsafeBytes { (b2) in
-                    return memcmp(b1, b2, length1) == 0
+            return d1.withUnsafeBytes { (b1: UnsafeRawBufferPointer) in
+                return d2.withUnsafeBytes { (b2: UnsafeRawBufferPointer) in
+                    return memcmp(b1.baseAddress!, b2.baseAddress!, b2.count) == 0
                 }
             }
         }
@@ -1882,8 +2733,8 @@
         var children: [(label: String?, value: Any)] = []
         children.append((label: "count", value: nBytes))
         
-        self.withUnsafeBytes { (bytes : UnsafePointer<UInt8>) in
-            children.append((label: "pointer", value: bytes))
+        self.withUnsafeBytes { (bytes : UnsafeRawBufferPointer) in
+            children.append((label: "pointer", value: bytes.baseAddress!))
         }
         
         // Minimal size data is output as an array
@@ -1909,7 +2760,7 @@
 extension Data : _ObjectiveCBridgeable {
     @_semantics("convertToObjectiveC")
     public func _bridgeToObjectiveC() -> NSData {
-        return _backing.bridgedReference(_sliceRange)
+        return _representation.bridgedReference()
     }
     
     public static func _forceBridgeFromObjectiveC(_ input: NSData, result: inout Data?) {
@@ -1923,7 +2774,7 @@
         return true
     }
 
-    @_effects(readonly)
+//    @_effects(readonly)
     public static func _unconditionallyBridgeFromObjectiveC(_ source: NSData?) -> Data {
         guard let src = source else { return Data() }
         return Data(referencing: src)
@@ -1964,20 +2815,8 @@
     
     public func encode(to encoder: Encoder) throws {
         var container = encoder.unkeyedContainer()
-        
-        // Since enumerateBytes does not rethrow, we need to catch the error, stow it away, and rethrow if we stopped.
-        var caughtError: Error? = nil
-        self.enumerateBytes { (buffer: UnsafeBufferPointer<UInt8>, byteIndex: Data.Index, stop: inout Bool) in
-            do {
-                try container.encode(contentsOf: buffer)
-            } catch {
-                caughtError = error
-                stop = true
-            }
-        }
-        
-        if let error = caughtError {
-            throw error
+        try withUnsafeBytes { (buffer: UnsafeRawBufferPointer) in
+            try container.encode(contentsOf: buffer)
         }
     }
 }
diff --git a/stdlib/public/SDK/Foundation/DataProtocol.swift b/stdlib/public/SDK/Foundation/DataProtocol.swift
new file mode 100644
index 0000000..00f3a03
--- /dev/null
+++ b/stdlib/public/SDK/Foundation/DataProtocol.swift
@@ -0,0 +1,299 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+#if os(macOS) || os(iOS)
+import Darwin
+#elseif os(Linux)
+import Glibc
+#endif
+
+//===--- DataProtocol -----------------------------------------------------===//
+
+public protocol DataProtocol : RandomAccessCollection where Element == UInt8, SubSequence : DataProtocol {
+    // FIXME: Remove in favor of opaque type on `regions`.
+    associatedtype Regions: BidirectionalCollection where Regions.Element : DataProtocol & ContiguousBytes, Regions.Element.SubSequence : ContiguousBytes
+
+    /// A `BidirectionalCollection` of `DataProtocol` elements which compose a
+    /// discontiguous buffer of memory.  Each region is a contiguous buffer of
+    /// bytes.
+    ///
+    /// The sum of the lengths of the associated regions must equal `self.count`
+    /// (such that iterating `regions` and iterating `self` produces the same
+    /// sequence of indices in the same number of index advancements).
+    var regions: Regions { get }
+
+    /// Returns the first found range of the given data buffer.
+    ///
+    /// A default implementation is given in terms of `self.regions`.
+    func firstRange<D: DataProtocol, R: RangeExpression>(of: D, in: R) -> Range<Index>? where R.Bound == Index
+
+    /// Returns the last found range of the given data buffer.
+    ///
+    /// A default implementation is given in terms of `self.regions`.
+    func lastRange<D: DataProtocol, R: RangeExpression>(of: D, in: R) -> Range<Index>? where R.Bound == Index
+
+    /// Copies `count` bytes from the start of the buffer to the destination
+    /// buffer.
+    ///
+    /// A default implementation is given in terms of `copyBytes(to:from:)`.
+    @discardableResult
+    func copyBytes(to: UnsafeMutableRawBufferPointer, count: Int) -> Int
+
+    /// Copies `count` bytes from the start of the buffer to the destination
+    /// buffer.
+    ///
+    /// A default implementation is given in terms of `copyBytes(to:from:)`.
+    @discardableResult
+    func copyBytes<DestinationType>(to: UnsafeMutableBufferPointer<DestinationType>, count: Int) -> Int
+
+    /// Copies the bytes from the given range to the destination buffer.
+    ///
+    /// A default implementation is given in terms of `self.regions`.
+    @discardableResult
+    func copyBytes<R: RangeExpression>(to: UnsafeMutableRawBufferPointer, from: R) -> Int where R.Bound == Index
+
+    /// Copies the bytes from the given range to the destination buffer.
+    ///
+    /// A default implementation is given in terms of `self.regions`.
+    @discardableResult
+    func copyBytes<DestinationType, R: RangeExpression>(to: UnsafeMutableBufferPointer<DestinationType>, from: R) -> Int where R.Bound == Index
+}
+
+//===--- MutableDataProtocol ----------------------------------------------===//
+
+public protocol MutableDataProtocol : DataProtocol, MutableCollection, RangeReplaceableCollection {
+    /// Replaces the contents of the buffer at the given range with zeroes.
+    ///
+    /// A default implementation is given in terms of
+    /// `replaceSubrange(_:with:)`.
+    mutating func resetBytes<R: RangeExpression>(in range: R) where R.Bound == Index
+}
+
+//===--- DataProtocol Extensions ------------------------------------------===//
+
+extension DataProtocol {
+    public func firstRange<D: DataProtocol>(of data: D) -> Range<Index>? {
+        return self.firstRange(of: data, in: self.startIndex ..< self.endIndex)
+    }
+
+    public func lastRange<D: DataProtocol>(of data: D) -> Range<Index>? {
+        return self.lastRange(of: data, in: self.startIndex ..< self.endIndex)
+    }
+
+    @discardableResult
+    public func copyBytes(to ptr: UnsafeMutableRawBufferPointer) -> Int {
+        return copyBytes(to: ptr, from: self.startIndex ..< self.endIndex)
+    }
+
+    @discardableResult
+    public func copyBytes<DestinationType>(to ptr: UnsafeMutableBufferPointer<DestinationType>) -> Int {
+        return copyBytes(to: ptr, from: self.startIndex ..< self.endIndex)
+    }
+
+    @discardableResult
+    public func copyBytes(to ptr: UnsafeMutableRawBufferPointer, count: Int) -> Int {
+        return copyBytes(to: ptr, from: self.startIndex ..< self.index(self.startIndex, offsetBy: count))
+    }
+
+    @discardableResult
+    public func copyBytes<DestinationType>(to ptr: UnsafeMutableBufferPointer<DestinationType>, count: Int) -> Int {
+        return copyBytes(to: ptr, from: self.startIndex ..< self.index(self.startIndex, offsetBy: count))
+    }
+
+    @discardableResult
+    public func copyBytes<R: RangeExpression>(to ptr: UnsafeMutableRawBufferPointer, from range: R) -> Int where R.Bound == Index {
+        precondition(ptr.baseAddress != nil)
+
+        let concreteRange = range.relative(to: self)
+        let slice = self[concreteRange]
+
+        // The type isn't contiguous, so we need to copy one region at a time.
+        var offset = 0
+        let rangeCount = distance(from: concreteRange.lowerBound, to: concreteRange.upperBound)
+        var amountToCopy = Swift.min(ptr.count, rangeCount)
+        for region in slice.regions {
+            guard amountToCopy > 0 else {
+                break
+            }
+
+            region.withUnsafeBytes { buffer in
+                let offsetPtr = UnsafeMutableRawBufferPointer(rebasing: ptr[offset...])
+                let buf = UnsafeRawBufferPointer(start: buffer.baseAddress, count: Swift.min(buffer.count, amountToCopy))
+                offsetPtr.copyMemory(from: buf)
+                offset += buf.count
+                amountToCopy -= buf.count
+            }
+        }
+
+        return offset
+    }
+
+    @discardableResult
+    public func copyBytes<DestinationType, R: RangeExpression>(to ptr: UnsafeMutableBufferPointer<DestinationType>, from range: R) -> Int where R.Bound == Index {
+        return self.copyBytes(to: UnsafeMutableRawBufferPointer(start: ptr.baseAddress, count: ptr.count * MemoryLayout<DestinationType>.stride), from: range)
+    }
+
+    public func firstRange<D: DataProtocol, R: RangeExpression>(of data: D, in range: R) -> Range<Index>? where R.Bound == Index {
+        let r = range.relative(to: self)
+        let rangeCount = distance(from: r.lowerBound, to: r.upperBound)
+        if rangeCount < data.count {
+            return nil
+        }
+        var haystackIndex = r.lowerBound
+        let haystackEnd = index(r.upperBound, offsetBy: -data.count)
+        while haystackIndex < haystackEnd {
+            var compareIndex = haystackIndex
+            var needleIndex = data.startIndex
+            let needleEnd = data.endIndex
+            var matched = true
+            while compareIndex < haystackEnd && needleIndex < needleEnd {
+                if self[compareIndex] != data[needleIndex] {
+                    matched = false
+                    break
+                }
+                needleIndex = data.index(after: needleIndex)
+                compareIndex = index(after: compareIndex)
+            }
+            if matched {
+                return haystackIndex..<compareIndex
+            }
+            haystackIndex = index(after: haystackIndex)
+        }
+        return nil
+    }
+
+    public func lastRange<D: DataProtocol, R: RangeExpression>(of data: D, in range: R) -> Range<Index>? where R.Bound == Index {
+        let r = range.relative(to: self)
+        let rangeCount = distance(from: r.lowerBound, to: r.upperBound)
+        if rangeCount < data.count {
+            return nil
+        }
+        var haystackIndex = r.upperBound
+        let haystackStart = index(r.lowerBound, offsetBy: data.count)
+        while haystackIndex > haystackStart {
+            var compareIndex = haystackIndex
+            var needleIndex = data.endIndex
+            let needleStart = data.startIndex
+            var matched = true
+            while compareIndex > haystackStart && needleIndex > needleStart {
+                if self[compareIndex] != data[needleIndex] {
+                    matched = false
+                    break
+                }
+                needleIndex = data.index(before: needleIndex)
+                compareIndex = index(before: compareIndex)
+            }
+            if matched {
+                return compareIndex..<haystackIndex
+            }
+            haystackIndex = index(before: haystackIndex)
+        }
+        return nil
+    }
+}
+
+extension DataProtocol where Self : ContiguousBytes {
+    public func copyBytes<DestinationType, R: RangeExpression>(to ptr: UnsafeMutableBufferPointer<DestinationType>, from range: R) where R.Bound == Index {
+        precondition(ptr.baseAddress != nil)
+
+        let concreteRange = range.relative(to: self)
+        withUnsafeBytes { fullBuffer in
+            let adv = distance(from: startIndex, to: concreteRange.lowerBound)
+            let delta = distance(from: concreteRange.lowerBound, to: concreteRange.upperBound)
+            memcpy(ptr.baseAddress!, fullBuffer.baseAddress?.advanced(by: adv), delta)
+        }
+    }
+}
+
+//===--- MutableDataProtocol Extensions -----------------------------------===//
+
+extension MutableDataProtocol {
+    public mutating func resetBytes<R: RangeExpression>(in range: R) where R.Bound == Index {
+        let r = range.relative(to: self)
+        let count = distance(from: r.lowerBound, to: r.upperBound)
+        replaceSubrange(r, with: repeatElement(UInt8(0), count: count))
+    }
+}
+
+//===--- DataProtocol Conditional Conformances ----------------------------===//
+
+extension Slice : DataProtocol where Base : DataProtocol {
+    public typealias Regions = [Base.Regions.Element.SubSequence]
+
+    public var regions: [Base.Regions.Element.SubSequence] {
+        let sliceLowerBound = startIndex
+        let sliceUpperBound = endIndex
+        var regionUpperBound = base.startIndex
+
+        return base.regions.compactMap { (region) -> Base.Regions.Element.SubSequence? in
+            let regionLowerBound = regionUpperBound
+            regionUpperBound = base.index(regionUpperBound, offsetBy: region.count)
+
+            /*
+             [------ Region ------]
+             [--- Slice ---] =>
+
+                      OR
+
+             [------ Region ------]
+                 <= [--- Slice ---]
+             */
+            if sliceLowerBound >= regionLowerBound && sliceUpperBound <= regionUpperBound {
+                let regionRelativeSliceLowerBound = region.index(region.startIndex, offsetBy: base.distance(from: regionLowerBound, to: sliceLowerBound))
+                let regionRelativeSliceUpperBound = region.index(region.startIndex, offsetBy: base.distance(from: regionLowerBound, to: sliceUpperBound))
+                return region[regionRelativeSliceLowerBound..<regionRelativeSliceUpperBound]
+            }
+
+            /*
+             [--- Region ---] =>
+             [------ Slice ------]
+
+                      OR
+
+               <= [--- Region ---]
+             [------ Slice ------]
+             */
+            if regionLowerBound >= sliceLowerBound && regionUpperBound <= sliceUpperBound {
+                return region[region.startIndex..<region.endIndex]
+            }
+
+            /*
+             [------ Region ------]
+                 [------ Slice ------]
+             */
+            if sliceLowerBound >= regionLowerBound && sliceLowerBound <= regionUpperBound {
+                let regionRelativeSliceLowerBound = region.index(region.startIndex, offsetBy: base.distance(from: regionLowerBound, to: sliceLowerBound))
+                return region[regionRelativeSliceLowerBound..<region.endIndex]
+            }
+
+            /*
+                 [------ Region ------]
+             [------ Slice ------]
+             */
+            if regionLowerBound >= sliceLowerBound && regionLowerBound <= sliceUpperBound {
+                let regionRelativeSliceUpperBound = region.index(region.startIndex, offsetBy: base.distance(from: regionLowerBound, to: sliceUpperBound))
+                return region[region.startIndex..<regionRelativeSliceUpperBound]
+            }
+
+            /*
+             [--- Region ---]
+                              [--- Slice ---]
+
+                      OR
+
+                             [--- Region ---]
+             [--- Slice ---]
+             */
+            return nil
+        }
+    }
+}
diff --git a/stdlib/public/SDK/Foundation/DispatchData+DataProtocol.swift b/stdlib/public/SDK/Foundation/DispatchData+DataProtocol.swift
new file mode 100644
index 0000000..97b82e4
--- /dev/null
+++ b/stdlib/public/SDK/Foundation/DispatchData+DataProtocol.swift
@@ -0,0 +1,56 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+
+import Dispatch
+
+extension DispatchData : DataProtocol {
+    public struct Region : DataProtocol, ContiguousBytes {
+        internal let bytes: UnsafeBufferPointer<UInt8>
+        internal let index: DispatchData.Index
+        internal let owner: DispatchData
+        internal init(bytes: UnsafeBufferPointer<UInt8>, index: DispatchData.Index, owner: DispatchData) {
+            self.bytes = bytes
+            self.index = index
+            self.owner = owner
+        }
+
+        public var regions: CollectionOfOne<Region> {
+            return CollectionOfOne(self)
+        }
+
+        public subscript(position: DispatchData.Index) -> UInt8 {
+            precondition(index <= position && position <= index + bytes.count)
+            return bytes[position - index]
+        }
+
+        public var startIndex: DispatchData.Index {
+            return index
+        }
+
+        public var endIndex: DispatchData.Index {
+            return index + bytes.count
+        }
+
+        public func withUnsafeBytes<ResultType>(_ body: (UnsafeRawBufferPointer) throws -> ResultType) rethrows -> ResultType {
+            return try body(UnsafeRawBufferPointer(bytes))
+        }
+    }
+
+    public var regions: [Region] {
+        var regions = [Region]()
+        enumerateBytes { (bytes, index, stop) in
+            regions.append(Region(bytes: bytes, index: index, owner: self))
+        }
+        return regions
+    }
+}
diff --git a/stdlib/public/SDK/Foundation/NSData+DataProtocol.swift b/stdlib/public/SDK/Foundation/NSData+DataProtocol.swift
new file mode 100644
index 0000000..cc467dc
--- /dev/null
+++ b/stdlib/public/SDK/Foundation/NSData+DataProtocol.swift
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+
+extension NSData : DataProtocol {
+
+    @nonobjc
+    public var startIndex: Int { return 0 }
+
+    @nonobjc
+    public var endIndex: Int { return length }
+
+    @nonobjc
+    public func lastRange<D, R>(of data: D, in r: R) -> Range<Int>? where D : DataProtocol, R : RangeExpression, NSData.Index == R.Bound {
+        return Range<Int>(range(of: Data(data), options: .backwards, in: NSRange(r)))
+    }
+
+    @nonobjc
+    public func firstRange<D, R>(of data: D, in r: R) -> Range<Int>? where D : DataProtocol, R : RangeExpression, NSData.Index == R.Bound {
+        return Range<Int>(range(of: Data(data), in: NSRange(r)))
+    }
+
+    @nonobjc
+    public var regions: [Data] {
+        var datas = [Data]()
+        enumerateBytes { (ptr, range, stop) in
+            datas.append(Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: ptr), count: range.length, deallocator: .custom({ (ptr: UnsafeMutableRawPointer, count: Int) -> Void in
+                withExtendedLifetime(self) { }
+            })))
+        }
+        return datas
+    }
+
+    @nonobjc
+    public subscript(position: Int) -> UInt8 {
+        var byte = UInt8(0)
+        enumerateBytes { (ptr, range, stop) in
+            if range.location <= position && position < range.upperBound {
+                byte = ptr.load(fromByteOffset: range.location - position, as: UInt8.self)
+                stop.pointee = true
+            }
+        }
+        return byte
+    }
+}
diff --git a/stdlib/public/SDK/Foundation/Pointers+DataProtocol.swift b/stdlib/public/SDK/Foundation/Pointers+DataProtocol.swift
new file mode 100644
index 0000000..059fe87
--- /dev/null
+++ b/stdlib/public/SDK/Foundation/Pointers+DataProtocol.swift
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+
+extension UnsafeRawBufferPointer : DataProtocol {
+    public var regions: CollectionOfOne<UnsafeRawBufferPointer> {
+        return CollectionOfOne(self)
+    }
+}
+
+extension UnsafeBufferPointer : DataProtocol where Element == UInt8 {
+    public var regions: CollectionOfOne<UnsafeBufferPointer<Element>> {
+        return CollectionOfOne(self)
+    }
+}
diff --git a/stdlib/public/SDK/MediaPlayer/CMakeLists.txt b/stdlib/public/SDK/MediaPlayer/CMakeLists.txt
index 4fd2c10..0efa5ae 100644
--- a/stdlib/public/SDK/MediaPlayer/CMakeLists.txt
+++ b/stdlib/public/SDK/MediaPlayer/CMakeLists.txt
@@ -8,7 +8,7 @@
   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 Metal ObjectiveC QuartzCore simd SIMDOperators UIKit os CoreData # auto-updated
+  SWIFT_MODULE_DEPENDS_IOS Darwin AVFoundation CoreAudio CoreFoundation CoreGraphics CoreImage CoreMedia Dispatch Foundation Metal 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/simd/Quaternion.swift.gyb b/stdlib/public/SDK/simd/Quaternion.swift.gyb
index c20d44e..4ac5f95 100644
--- a/stdlib/public/SDK/simd/Quaternion.swift.gyb
+++ b/stdlib/public/SDK/simd/Quaternion.swift.gyb
@@ -14,7 +14,6 @@
 
 import Swift
 import Darwin
-import SIMDOperators
 @_exported import simd
 
 %for scalar in ['Float','Double']:
diff --git a/stdlib/public/SDK/simd/simd.swift.gyb b/stdlib/public/SDK/simd/simd.swift.gyb
index b805db8..340fbbe 100644
--- a/stdlib/public/SDK/simd/simd.swift.gyb
+++ b/stdlib/public/SDK/simd/simd.swift.gyb
@@ -14,7 +14,6 @@
 
 import Swift
 import Darwin
-@_exported import SIMDOperators
 @_exported import simd
 
 public extension SIMD {
diff --git a/stdlib/public/SIMDOperators/Operators.swift b/stdlib/public/SIMDOperators/Operators.swift
index 797c100..68007d8 100644
--- a/stdlib/public/SIMDOperators/Operators.swift
+++ b/stdlib/public/SIMDOperators/Operators.swift
@@ -1,325 +1 @@
-//  Implementations of integer operations. These should eventually all
-//  be replaced with @_semantics to lower directly to vector IR nodes.
-public extension SIMD where Scalar : FixedWidthInteger {
-  @_transparent
-  var leadingZeroBitCount: Self {
-    var result = Self()
-    for i in indices { result[i] = Scalar(self[i].leadingZeroBitCount) }
-    return result
-  }
-  
-  @_transparent
-  var trailingZeroBitCount: Self {
-    var result = Self()
-    for i in indices { result[i] = Scalar(self[i].trailingZeroBitCount) }
-    return result
-  }
-  
-  @_transparent
-  var nonzeroBitCount: Self {
-    var result = Self()
-    for i in indices { result[i] = Scalar(self[i].nonzeroBitCount) }
-    return result
-  }
-  
-  @_transparent
-  static prefix func ~(rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = ~rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func &(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] & rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func ^(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] ^ rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func |(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] | rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func &<<(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] &<< rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func &>>(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] &>> rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func &+(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] &+ rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func &-(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] &- rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func &*(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] &* rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func /(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] / rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func %(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] % rhs[i] }
-    return result
-  }
-}
-
-//  Implementations of floating-point operations. These should eventually all
-//  be replaced with @_semantics to lower directly to vector IR nodes.
-public extension SIMD where Scalar : FloatingPoint {
-  @_transparent
-  static func +(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] + rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func -(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] - rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func *(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] * rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  static func /(lhs: Self, rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = lhs[i] / rhs[i] }
-    return result
-  }
-  
-  @_transparent
-  func addingProduct(_ lhs: Self, _ rhs: Self) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = self[i].addingProduct(lhs[i], rhs[i]) }
-    return result
-  }
-  
-  @_transparent
-  func squareRoot( ) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = self[i].squareRoot() }
-    return result
-  }
-  
-  @_transparent
-  func rounded(_ rule: FloatingPointRoundingRule) -> Self {
-    var result = Self()
-    for i in result.indices { result[i] = self[i].rounded(rule) }
-    return result
-  }
-}
-
-public extension SIMDMask {
-  @_transparent
-  static prefix func .!(rhs: SIMDMask) -> SIMDMask {
-    return SIMDMask(~rhs._storage)
-  }
-  
-  @_transparent
-  static func .&(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
-    return SIMDMask(lhs._storage & rhs._storage)
-  }
-  
-  @_transparent
-  static func .^(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
-    return SIMDMask(lhs._storage ^ rhs._storage)
-  }
-  
-  @_transparent
-  static func .|(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
-    return SIMDMask(lhs._storage | rhs._storage)
-  }
-}
-
-//  These operations should never need @_semantics; they should be trivial
-//  wrappers around the core operations defined above.
-public extension SIMD where Scalar : FixedWidthInteger {
-  @_transparent static func &(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) & rhs }
-  @_transparent static func ^(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) ^ rhs }
-  @_transparent static func |(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) | rhs }
-  @_transparent static func &<<(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &<< rhs }
-  @_transparent static func &>>(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &>> rhs }
-  @_transparent static func &+(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &+ rhs }
-  @_transparent static func &-(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &- rhs }
-  @_transparent static func &*(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &* rhs }
-  @_transparent static func /(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) / rhs }
-  @_transparent static func %(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) % rhs }
-  
-  @_transparent static func &(lhs: Self, rhs: Scalar) -> Self { return lhs & Self(repeating: rhs) }
-  @_transparent static func ^(lhs: Self, rhs: Scalar) -> Self { return lhs ^ Self(repeating: rhs) }
-  @_transparent static func |(lhs: Self, rhs: Scalar) -> Self { return lhs | Self(repeating: rhs) }
-  @_transparent static func &<<(lhs: Self, rhs: Scalar) -> Self { return lhs &<< Self(repeating: rhs) }
-  @_transparent static func &>>(lhs: Self, rhs: Scalar) -> Self { return lhs &>> Self(repeating: rhs) }
-  @_transparent static func &+(lhs: Self, rhs: Scalar) -> Self { return lhs &+ Self(repeating: rhs) }
-  @_transparent static func &-(lhs: Self, rhs: Scalar) -> Self { return lhs &- Self(repeating: rhs) }
-  @_transparent static func &*(lhs: Self, rhs: Scalar) -> Self { return lhs &* Self(repeating: rhs) }
-  @_transparent static func /(lhs: Self, rhs: Scalar) -> Self { return lhs / Self(repeating: rhs) }
-  @_transparent static func %(lhs: Self, rhs: Scalar) -> Self { return lhs % Self(repeating: rhs) }
-  
-  @_transparent static func &=(lhs: inout Self, rhs: Self) { lhs = lhs & rhs }
-  @_transparent static func ^=(lhs: inout Self, rhs: Self) { lhs = lhs ^ rhs }
-  @_transparent static func |=(lhs: inout Self, rhs: Self) { lhs = lhs | rhs }
-  @_transparent static func &<<=(lhs: inout Self, rhs: Self) { lhs = lhs &<< rhs }
-  @_transparent static func &>>=(lhs: inout Self, rhs: Self) { lhs = lhs &>> rhs }
-  @_transparent static func &+=(lhs: inout Self, rhs: Self) { lhs = lhs &+ rhs }
-  @_transparent static func &-=(lhs: inout Self, rhs: Self) { lhs = lhs &- rhs }
-  @_transparent static func &*=(lhs: inout Self, rhs: Self) { lhs = lhs &* rhs }
-  @_transparent static func /=(lhs: inout Self, rhs: Self) { lhs = lhs / rhs }
-  @_transparent static func %=(lhs: inout Self, rhs: Self) { lhs = lhs % rhs }
-  
-  @_transparent static func &=(lhs: inout Self, rhs: Scalar) { lhs = lhs & rhs }
-  @_transparent static func ^=(lhs: inout Self, rhs: Scalar) { lhs = lhs ^ rhs }
-  @_transparent static func |=(lhs: inout Self, rhs: Scalar) { lhs = lhs | rhs }
-  @_transparent static func &<<=(lhs: inout Self, rhs: Scalar) { lhs = lhs &<< rhs }
-  @_transparent static func &>>=(lhs: inout Self, rhs: Scalar) { lhs = lhs &>> rhs }
-  @_transparent static func &+=(lhs: inout Self, rhs: Scalar) { lhs = lhs &+ rhs }
-  @_transparent static func &-=(lhs: inout Self, rhs: Scalar) { lhs = lhs &- rhs }
-  @_transparent static func &*=(lhs: inout Self, rhs: Scalar) { lhs = lhs &* rhs }
-  @_transparent static func /=(lhs: inout Self, rhs: Scalar) { lhs = lhs / rhs }
-  @_transparent static func %=(lhs: inout Self, rhs: Scalar) { lhs = lhs % rhs }
-  
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
-  static func +(lhs: Self, rhs: Self) -> Self { fatalError() }
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
-  static func -(lhs: Self, rhs: Self) -> Self { fatalError() }
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
-  static func *(lhs: Self, rhs: Self) -> Self { fatalError() }
-  
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
-  static func +(lhs: Self, rhs: Scalar) -> Self { fatalError() }
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
-  static func -(lhs: Self, rhs: Scalar) -> Self { fatalError() }
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
-  static func *(lhs: Self, rhs: Scalar) -> Self { fatalError() }
-  
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
-  static func +(lhs: Scalar, rhs: Self) -> Self { fatalError() }
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
-  static func -(lhs: Scalar, rhs: Self) -> Self { fatalError() }
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
-  static func *(lhs: Scalar, rhs: Self) -> Self { fatalError() }
-  
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+=' instead")
-  static func +=(lhs: inout Self, rhs: Self) { fatalError() }
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-=' instead")
-  static func -=(lhs: inout Self, rhs: Self) { fatalError() }
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*=' instead")
-  static func *=(lhs: inout Self, rhs: Self) { fatalError() }
-  
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+=' instead")
-  static func +=(lhs: inout Self, rhs: Scalar) { fatalError() }
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-=' instead")
-  static func -=(lhs: inout Self, rhs: Scalar) { fatalError() }
-  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*=' instead")
-  static func *=(lhs: inout Self, rhs: Scalar) { fatalError() }
-}
-
-public extension SIMD where Scalar : FloatingPoint {
-  @_transparent static prefix func -(rhs: Self) -> Self { return 0 - rhs }
-  
-  @_transparent static func +(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) + rhs }
-  @_transparent static func -(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) - rhs }
-  @_transparent static func *(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) * rhs }
-  @_transparent static func /(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) / rhs }
-  
-  @_transparent static func +(lhs: Self, rhs: Scalar) -> Self { return lhs + Self(repeating: rhs) }
-  @_transparent static func -(lhs: Self, rhs: Scalar) -> Self { return lhs - Self(repeating: rhs) }
-  @_transparent static func *(lhs: Self, rhs: Scalar) -> Self { return lhs * Self(repeating: rhs) }
-  @_transparent static func /(lhs: Self, rhs: Scalar) -> Self { return lhs / Self(repeating: rhs) }
-  
-  @_transparent static func +=(lhs: inout Self, rhs: Self) { lhs = lhs + rhs }
-  @_transparent static func -=(lhs: inout Self, rhs: Self) { lhs = lhs - rhs }
-  @_transparent static func *=(lhs: inout Self, rhs: Self) { lhs = lhs * rhs }
-  @_transparent static func /=(lhs: inout Self, rhs: Self) { lhs = lhs / rhs }
-  
-  @_transparent static func +=(lhs: inout Self, rhs: Scalar) { lhs = lhs + rhs }
-  @_transparent static func -=(lhs: inout Self, rhs: Scalar) { lhs = lhs - rhs }
-  @_transparent static func *=(lhs: inout Self, rhs: Scalar) { lhs = lhs * rhs }
-  @_transparent static func /=(lhs: inout Self, rhs: Scalar) { lhs = lhs / rhs }
-  
-  @_transparent func addingProduct(_ lhs: Scalar, _ rhs: Self) -> Self {
-    return self.addingProduct(Self(repeating: lhs), rhs)
-  }
-  @_transparent func addingProduct(_ lhs: Self, _ rhs: Scalar) -> Self {
-    return self.addingProduct(lhs, Self(repeating: rhs))
-  }
-  @_transparent mutating func addProduct(_ lhs: Self, _ rhs: Self) {
-    self = self.addingProduct(lhs, rhs)
-  }
-  @_transparent mutating func addProduct(_ lhs: Scalar, _ rhs: Self) {
-    self = self.addingProduct(lhs, rhs)
-  }
-  @_transparent mutating func addProduct(_ lhs: Self, _ rhs: Scalar) {
-    self = self.addingProduct(lhs, rhs)
-  }
-  
-  @_transparent mutating func formSquareRoot( ) {
-    self = self.squareRoot()
-  }
-  
-  @_transparent mutating func round(_ rule: FloatingPointRoundingRule) {
-    self = self.rounded(rule)
-  }
-}
-
-public extension SIMDMask {
-  @_transparent static func .&(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .& rhs }
-  @_transparent static func .^(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .^ rhs }
-  @_transparent static func .|(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .| rhs }
-  
-  @_transparent static func .&(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .& SIMDMask(repeating: rhs) }
-  @_transparent static func .^(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .^ SIMDMask(repeating: rhs) }
-  @_transparent static func .|(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .| SIMDMask(repeating: rhs) }
-  
-  @_transparent static func .&=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .& rhs }
-  @_transparent static func .^=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .^ rhs }
-  @_transparent static func .|=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .| rhs }
-  
-  @_transparent static func .&=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .& rhs }
-  @_transparent static func .^=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .^ rhs }
-  @_transparent static func .|=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .| rhs }
-}
+// This file intentionally left blank.
diff --git a/stdlib/public/core/CMakeLists.txt b/stdlib/public/core/CMakeLists.txt
index 1e4500e..169941c 100644
--- a/stdlib/public/core/CMakeLists.txt
+++ b/stdlib/public/core/CMakeLists.txt
@@ -116,6 +116,7 @@
   ReflectionMirror.swift
   Repeat.swift
   REPL.swift
+  Result.swift
   Reverse.swift
   Runtime.swift.gyb
   RuntimeFunctionCounters.swift
diff --git a/stdlib/public/core/GroupInfo.json b/stdlib/public/core/GroupInfo.json
index cd66c3e..55d01d5 100644
--- a/stdlib/public/core/GroupInfo.json
+++ b/stdlib/public/core/GroupInfo.json
@@ -223,5 +223,8 @@
     "Comparable.swift",
     "Codable.swift",
     "MigrationSupport.swift"
+  ],
+  "Result": [
+    "Result.swift"
   ]
 }
diff --git a/stdlib/public/core/Result.swift b/stdlib/public/core/Result.swift
new file mode 100644
index 0000000..fdd742e
--- /dev/null
+++ b/stdlib/public/core/Result.swift
@@ -0,0 +1,168 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2018 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+/// A value that represents either a success or a failure, including an
+/// associated value in each case.
+@_frozen
+public enum Result<Success, Failure: Error> {
+  /// A success, storing a `Success` value.
+  case success(Success)
+  
+  /// A failure, storing a `Failure` value.
+  case failure(Failure)
+  
+  /// Returns a new result, mapping any success value using the given
+  /// transformation.
+  ///
+  /// Use this method when you need to transform the value of a `Result`
+  /// instance when it represents a success. The following example transforms
+  /// the integer success value of a result into a string:
+  ///
+  ///     func getNextInteger() -> Result<Int, Error> { ... }
+  ///
+  ///     let integerResult = getNextInteger()
+  ///     // integerResult == .success(5)
+  ///     let stringResult = integerResult.map({ String($0) })
+  ///     // stringResult == .success("5")
+  ///
+  /// - Parameter transform: A closure that takes the success value of this
+  ///   instance.
+  /// - Returns: A `Result` instance with the result of evaluating `transform`
+  ///   as the new success value if this instance represents a success.
+  public func map<NewSuccess>(
+    _ transform: (Success) -> NewSuccess
+  ) -> Result<NewSuccess, Failure> {
+    switch self {
+    case let .success(success):
+      return .success(transform(success))
+    case let .failure(failure):
+      return .failure(failure)
+    }
+  }
+  
+  /// Returns a new result, mapping any failure value using the given
+  /// transformation.
+  ///
+  /// Use this method when you need to transform the value of a `Result`
+  /// instance when it represents a failure. The following example transforms
+  /// the error value of a result by wrapping it in a custom `Error` type:
+  ///
+  ///     struct DatedError: Error {
+  ///         var error: Error
+  ///         var date: Date
+  ///
+  ///         init(_ error: Error) {
+  ///             self.error = error
+  ///             self.date = Date()
+  ///         }
+  ///     }
+  ///
+  ///     let result: Result<Int, Error> = ...
+  ///     // result == .failure(<error value>)
+  ///     let resultWithDatedError = result.mapError({ e in DatedError(e) })
+  ///     // result == .failure(DatedError(error: <error value>, date: <date>))
+  ///
+  /// - Parameter transform: A closure that takes the failure value of the
+  ///   instance.
+  /// - Returns: A `Result` instance with the result of evaluating `transform`
+  ///   as the new failure value if this instance represents a failure.
+  public func mapError<NewFailure>(
+    _ transform: (Failure) -> NewFailure
+  ) -> Result<Success, NewFailure> {
+    switch self {
+    case let .success(success):
+      return .success(success)
+    case let .failure(failure):
+      return .failure(transform(failure))
+    }
+  }
+  
+  /// Returns a new result, mapping any success value using the given
+  /// transformation and unwrapping the produced result.
+  ///
+  /// - Parameter transform: A closure that takes the success value of the
+  ///   instance.
+  /// - Returns: A `Result` instance with the result of evaluating `transform`
+  ///   as the new failure value if this instance represents a failure.
+  public func flatMap<NewSuccess>(
+    _ transform: (Success) -> Result<NewSuccess, Failure>
+  ) -> Result<NewSuccess, Failure> {
+    switch self {
+    case let .success(success):
+      return transform(success)
+    case let .failure(failure):
+      return .failure(failure)
+    }
+  }
+  
+  /// Returns a new result, mapping any failure value using the given
+  /// transformation and unwrapping the produced result.
+  ///
+  /// - Parameter transform: A closure that takes the failure value of the
+  ///   instance.
+  /// - Returns: A `Result` instance, either from the closure or the previous 
+  ///   `.success`.
+  public func flatMapError<NewFailure>(
+    _ transform: (Failure) -> Result<Success, NewFailure>
+  ) -> Result<Success, NewFailure> {
+    switch self {
+    case let .success(success):
+      return .success(success)
+    case let .failure(failure):
+      return transform(failure)
+    }
+  }
+  
+  /// Returns the success value as a throwing expression.
+  ///
+  /// Use this method to retrieve the value of this result if it represents a
+  /// success, or to catch the value if it represents a failure.
+  ///
+  ///     let integerResult: Result<Int, Error> = .success(5)
+  ///     do {
+  ///         let value = try integerResult.get()
+  ///         print("The value is \(value).")
+  ///     } catch error {
+  ///         print("Error retrieving the value: \(error)")
+  ///     }
+  ///     // Prints "The value is 5."
+  ///
+  /// - Returns: The success value, if the instance represent a success.
+  /// - Throws: The failure value, if the instance represents a failure.
+  public func get() throws -> Success {
+    switch self {
+    case let .success(success):
+      return success
+    case let .failure(failure):
+      throw failure
+    }
+  }
+}
+
+extension Result where Failure == Swift.Error {
+  /// Creates a new result by evaluating a throwing closure, capturing the
+  /// returned value as a success, or any thrown error as a failure.
+  ///
+  /// - Parameter body: A throwing closure to evaluate.
+  @_transparent
+  public init(catching body: () throws -> Success) {
+    do {
+      self = .success(try body())
+    } catch {
+      self = .failure(error)
+    }
+  }
+}
+
+extension Result: Equatable where Success: Equatable, Failure: Equatable { }
+
+extension Result: Hashable where Success: Hashable, Failure: Hashable { }
diff --git a/stdlib/public/core/SIMDVector.swift b/stdlib/public/core/SIMDVector.swift
index 540796a..e1ccb42 100644
--- a/stdlib/public/core/SIMDVector.swift
+++ b/stdlib/public/core/SIMDVector.swift
@@ -326,3 +326,329 @@
     return SIMDMask.random(using: &g)
   }
 }
+
+//  Implementations of integer operations. These should eventually all
+//  be replaced with @_semantics to lower directly to vector IR nodes.
+public extension SIMD where Scalar : FixedWidthInteger {
+  @_transparent
+  var leadingZeroBitCount: Self {
+    var result = Self()
+    for i in indices { result[i] = Scalar(self[i].leadingZeroBitCount) }
+    return result
+  }
+  
+  @_transparent
+  var trailingZeroBitCount: Self {
+    var result = Self()
+    for i in indices { result[i] = Scalar(self[i].trailingZeroBitCount) }
+    return result
+  }
+  
+  @_transparent
+  var nonzeroBitCount: Self {
+    var result = Self()
+    for i in indices { result[i] = Scalar(self[i].nonzeroBitCount) }
+    return result
+  }
+  
+  @_transparent
+  static prefix func ~(rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = ~rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func &(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] & rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func ^(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] ^ rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func |(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] | rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func &<<(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] &<< rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func &>>(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] &>> rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func &+(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] &+ rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func &-(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] &- rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func &*(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] &* rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func /(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] / rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func %(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] % rhs[i] }
+    return result
+  }
+}
+
+//  Implementations of floating-point operations. These should eventually all
+//  be replaced with @_semantics to lower directly to vector IR nodes.
+public extension SIMD where Scalar : FloatingPoint {
+  @_transparent
+  static func +(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] + rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func -(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] - rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func *(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] * rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  static func /(lhs: Self, rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = lhs[i] / rhs[i] }
+    return result
+  }
+  
+  @_transparent
+  func addingProduct(_ lhs: Self, _ rhs: Self) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = self[i].addingProduct(lhs[i], rhs[i]) }
+    return result
+  }
+  
+  @_transparent
+  func squareRoot( ) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = self[i].squareRoot() }
+    return result
+  }
+  
+  @_transparent
+  func rounded(_ rule: FloatingPointRoundingRule) -> Self {
+    var result = Self()
+    for i in result.indices { result[i] = self[i].rounded(rule) }
+    return result
+  }
+}
+
+public extension SIMDMask {
+  @_transparent
+  static prefix func .!(rhs: SIMDMask) -> SIMDMask {
+    return SIMDMask(~rhs._storage)
+  }
+  
+  @_transparent
+  static func .&(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
+    return SIMDMask(lhs._storage & rhs._storage)
+  }
+  
+  @_transparent
+  static func .^(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
+    return SIMDMask(lhs._storage ^ rhs._storage)
+  }
+  
+  @_transparent
+  static func .|(lhs: SIMDMask, rhs: SIMDMask) -> SIMDMask {
+    return SIMDMask(lhs._storage | rhs._storage)
+  }
+}
+
+//  These operations should never need @_semantics; they should be trivial
+//  wrappers around the core operations defined above.
+public extension SIMD where Scalar : FixedWidthInteger {
+  @_transparent static func &(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) & rhs }
+  @_transparent static func ^(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) ^ rhs }
+  @_transparent static func |(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) | rhs }
+  @_transparent static func &<<(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &<< rhs }
+  @_transparent static func &>>(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &>> rhs }
+  @_transparent static func &+(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &+ rhs }
+  @_transparent static func &-(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &- rhs }
+  @_transparent static func &*(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) &* rhs }
+  @_transparent static func /(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) / rhs }
+  @_transparent static func %(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) % rhs }
+  
+  @_transparent static func &(lhs: Self, rhs: Scalar) -> Self { return lhs & Self(repeating: rhs) }
+  @_transparent static func ^(lhs: Self, rhs: Scalar) -> Self { return lhs ^ Self(repeating: rhs) }
+  @_transparent static func |(lhs: Self, rhs: Scalar) -> Self { return lhs | Self(repeating: rhs) }
+  @_transparent static func &<<(lhs: Self, rhs: Scalar) -> Self { return lhs &<< Self(repeating: rhs) }
+  @_transparent static func &>>(lhs: Self, rhs: Scalar) -> Self { return lhs &>> Self(repeating: rhs) }
+  @_transparent static func &+(lhs: Self, rhs: Scalar) -> Self { return lhs &+ Self(repeating: rhs) }
+  @_transparent static func &-(lhs: Self, rhs: Scalar) -> Self { return lhs &- Self(repeating: rhs) }
+  @_transparent static func &*(lhs: Self, rhs: Scalar) -> Self { return lhs &* Self(repeating: rhs) }
+  @_transparent static func /(lhs: Self, rhs: Scalar) -> Self { return lhs / Self(repeating: rhs) }
+  @_transparent static func %(lhs: Self, rhs: Scalar) -> Self { return lhs % Self(repeating: rhs) }
+  
+  @_transparent static func &=(lhs: inout Self, rhs: Self) { lhs = lhs & rhs }
+  @_transparent static func ^=(lhs: inout Self, rhs: Self) { lhs = lhs ^ rhs }
+  @_transparent static func |=(lhs: inout Self, rhs: Self) { lhs = lhs | rhs }
+  @_transparent static func &<<=(lhs: inout Self, rhs: Self) { lhs = lhs &<< rhs }
+  @_transparent static func &>>=(lhs: inout Self, rhs: Self) { lhs = lhs &>> rhs }
+  @_transparent static func &+=(lhs: inout Self, rhs: Self) { lhs = lhs &+ rhs }
+  @_transparent static func &-=(lhs: inout Self, rhs: Self) { lhs = lhs &- rhs }
+  @_transparent static func &*=(lhs: inout Self, rhs: Self) { lhs = lhs &* rhs }
+  @_transparent static func /=(lhs: inout Self, rhs: Self) { lhs = lhs / rhs }
+  @_transparent static func %=(lhs: inout Self, rhs: Self) { lhs = lhs % rhs }
+  
+  @_transparent static func &=(lhs: inout Self, rhs: Scalar) { lhs = lhs & rhs }
+  @_transparent static func ^=(lhs: inout Self, rhs: Scalar) { lhs = lhs ^ rhs }
+  @_transparent static func |=(lhs: inout Self, rhs: Scalar) { lhs = lhs | rhs }
+  @_transparent static func &<<=(lhs: inout Self, rhs: Scalar) { lhs = lhs &<< rhs }
+  @_transparent static func &>>=(lhs: inout Self, rhs: Scalar) { lhs = lhs &>> rhs }
+  @_transparent static func &+=(lhs: inout Self, rhs: Scalar) { lhs = lhs &+ rhs }
+  @_transparent static func &-=(lhs: inout Self, rhs: Scalar) { lhs = lhs &- rhs }
+  @_transparent static func &*=(lhs: inout Self, rhs: Scalar) { lhs = lhs &* rhs }
+  @_transparent static func /=(lhs: inout Self, rhs: Scalar) { lhs = lhs / rhs }
+  @_transparent static func %=(lhs: inout Self, rhs: Scalar) { lhs = lhs % rhs }
+  
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
+  static func +(lhs: Self, rhs: Self) -> Self { fatalError() }
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
+  static func -(lhs: Self, rhs: Self) -> Self { fatalError() }
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
+  static func *(lhs: Self, rhs: Self) -> Self { fatalError() }
+  
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
+  static func +(lhs: Self, rhs: Scalar) -> Self { fatalError() }
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
+  static func -(lhs: Self, rhs: Scalar) -> Self { fatalError() }
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
+  static func *(lhs: Self, rhs: Scalar) -> Self { fatalError() }
+  
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+' instead")
+  static func +(lhs: Scalar, rhs: Self) -> Self { fatalError() }
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-' instead")
+  static func -(lhs: Scalar, rhs: Self) -> Self { fatalError() }
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*' instead")
+  static func *(lhs: Scalar, rhs: Self) -> Self { fatalError() }
+  
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+=' instead")
+  static func +=(lhs: inout Self, rhs: Self) { fatalError() }
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-=' instead")
+  static func -=(lhs: inout Self, rhs: Self) { fatalError() }
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*=' instead")
+  static func *=(lhs: inout Self, rhs: Self) { fatalError() }
+  
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&+=' instead")
+  static func +=(lhs: inout Self, rhs: Scalar) { fatalError() }
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&-=' instead")
+  static func -=(lhs: inout Self, rhs: Scalar) { fatalError() }
+  @available(*, unavailable, message: "integer vector types do not support checked arithmetic; use the wrapping operator '&*=' instead")
+  static func *=(lhs: inout Self, rhs: Scalar) { fatalError() }
+}
+
+public extension SIMD where Scalar : FloatingPoint {
+  @_transparent static prefix func -(rhs: Self) -> Self { return 0 - rhs }
+  
+  @_transparent static func +(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) + rhs }
+  @_transparent static func -(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) - rhs }
+  @_transparent static func *(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) * rhs }
+  @_transparent static func /(lhs: Scalar, rhs: Self) -> Self { return Self(repeating: lhs) / rhs }
+  
+  @_transparent static func +(lhs: Self, rhs: Scalar) -> Self { return lhs + Self(repeating: rhs) }
+  @_transparent static func -(lhs: Self, rhs: Scalar) -> Self { return lhs - Self(repeating: rhs) }
+  @_transparent static func *(lhs: Self, rhs: Scalar) -> Self { return lhs * Self(repeating: rhs) }
+  @_transparent static func /(lhs: Self, rhs: Scalar) -> Self { return lhs / Self(repeating: rhs) }
+  
+  @_transparent static func +=(lhs: inout Self, rhs: Self) { lhs = lhs + rhs }
+  @_transparent static func -=(lhs: inout Self, rhs: Self) { lhs = lhs - rhs }
+  @_transparent static func *=(lhs: inout Self, rhs: Self) { lhs = lhs * rhs }
+  @_transparent static func /=(lhs: inout Self, rhs: Self) { lhs = lhs / rhs }
+  
+  @_transparent static func +=(lhs: inout Self, rhs: Scalar) { lhs = lhs + rhs }
+  @_transparent static func -=(lhs: inout Self, rhs: Scalar) { lhs = lhs - rhs }
+  @_transparent static func *=(lhs: inout Self, rhs: Scalar) { lhs = lhs * rhs }
+  @_transparent static func /=(lhs: inout Self, rhs: Scalar) { lhs = lhs / rhs }
+  
+  @_transparent func addingProduct(_ lhs: Scalar, _ rhs: Self) -> Self {
+    return self.addingProduct(Self(repeating: lhs), rhs)
+  }
+  @_transparent func addingProduct(_ lhs: Self, _ rhs: Scalar) -> Self {
+    return self.addingProduct(lhs, Self(repeating: rhs))
+  }
+  @_transparent mutating func addProduct(_ lhs: Self, _ rhs: Self) {
+    self = self.addingProduct(lhs, rhs)
+  }
+  @_transparent mutating func addProduct(_ lhs: Scalar, _ rhs: Self) {
+    self = self.addingProduct(lhs, rhs)
+  }
+  @_transparent mutating func addProduct(_ lhs: Self, _ rhs: Scalar) {
+    self = self.addingProduct(lhs, rhs)
+  }
+  
+  @_transparent mutating func formSquareRoot( ) {
+    self = self.squareRoot()
+  }
+  
+  @_transparent mutating func round(_ rule: FloatingPointRoundingRule) {
+    self = self.rounded(rule)
+  }
+}
+
+public extension SIMDMask {
+  @_transparent static func .&(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .& rhs }
+  @_transparent static func .^(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .^ rhs }
+  @_transparent static func .|(lhs: Bool, rhs: SIMDMask) -> SIMDMask { return SIMDMask(repeating: lhs) .| rhs }
+  
+  @_transparent static func .&(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .& SIMDMask(repeating: rhs) }
+  @_transparent static func .^(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .^ SIMDMask(repeating: rhs) }
+  @_transparent static func .|(lhs: SIMDMask, rhs: Bool) -> SIMDMask { return lhs .| SIMDMask(repeating: rhs) }
+  
+  @_transparent static func .&=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .& rhs }
+  @_transparent static func .^=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .^ rhs }
+  @_transparent static func .|=(lhs: inout SIMDMask, rhs: SIMDMask) { lhs = lhs .| rhs }
+  
+  @_transparent static func .&=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .& rhs }
+  @_transparent static func .^=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .^ rhs }
+  @_transparent static func .|=(lhs: inout SIMDMask, rhs: Bool) { lhs = lhs .| rhs }
+}
diff --git a/stdlib/public/core/SIMDVectorTypes.swift.gyb b/stdlib/public/core/SIMDVectorTypes.swift.gyb
index b5d91ce..a2ed3f5 100644
--- a/stdlib/public/core/SIMDVectorTypes.swift.gyb
+++ b/stdlib/public/core/SIMDVectorTypes.swift.gyb
@@ -109,6 +109,13 @@
   }
 }
 
+extension SIMD${n} : CustomDebugStringConvertible {
+  public var debugDescription: String {
+    return "SIMD${n}<\(Scalar.self)>(${', '.join(map(lambda c:
+                       '\\(self['+ str(c) + '])',
+                       xrange(n)))})"
+  }
+}
 
 public extension SIMD${n} where Scalar : BinaryFloatingPoint {
   @inlinable
diff --git a/test/ClangImporter/ctypes_parse_objc.swift b/test/ClangImporter/ctypes_parse_objc.swift
index 415eb49..9a5e396 100644
--- a/test/ClangImporter/ctypes_parse_objc.swift
+++ b/test/ClangImporter/ctypes_parse_objc.swift
@@ -70,8 +70,17 @@
 }
 
 func testImportCFTypes() {
-  let t1_unqual: Int = CFIndex_test
-  _ = t1_unqual as CoreFoundation.CFIndex
+  let t1_unqual: UInt = CFTypeID_test
+  _ = t1_unqual as CoreFoundation.CFTypeID
+
+  let t2_unqual: UInt = CFOptionFlags_test
+  _ = t2_unqual as CoreFoundation.CFOptionFlags
+
+  let t3_unqual: UInt = CFHashCode_test
+  _ = t3_unqual as CoreFoundation.CFHashCode
+
+  let t4_unqual: Int = CFIndex_test
+  _ = t4_unqual as CoreFoundation.CFIndex
 }
 
 func testImportSEL() {
diff --git a/test/Compatibility/tuple_arguments_4.swift b/test/Compatibility/tuple_arguments_4.swift
index dfc7026..bb15989 100644
--- a/test/Compatibility/tuple_arguments_4.swift
+++ b/test/Compatibility/tuple_arguments_4.swift
@@ -1,7 +1,5 @@
 // RUN: %target-typecheck-verify-swift -swift-version 4
 
-// See test/Compatibility/tuple_arguments_3.swift for the Swift 3 behavior.
-
 func concrete(_ x: Int) {}
 func concreteLabeled(x: Int) {}
 func concreteTwo(_ x: Int, _ y: Int) {} // expected-note 5 {{'concreteTwo' declared here}}
@@ -1671,7 +1669,6 @@
   h() // expected-error {{missing argument for parameter #1 in call}}
 }
 
-
 // https://bugs.swift.org/browse/SR-7191
 class Mappable<T> {
   init(_: T) { }
@@ -1680,3 +1677,9 @@
 
 let x = Mappable(())
 _ = x.map { (_: Void) in return () }
+
+// https://bugs.swift.org/browse/SR-9470
+do {
+  func f(_: Int...) {}
+  let _ = [(1, 2, 3)].map(f) // expected-error {{cannot invoke 'map' with an argument list of type '((Int...) -> ())'}}
+}
\ No newline at end of file
diff --git a/test/Constraints/tuple.swift b/test/Constraints/tuple.swift
index 6e8df0f..b951841 100644
--- a/test/Constraints/tuple.swift
+++ b/test/Constraints/tuple.swift
@@ -56,7 +56,7 @@
 // Tuples with existentials
 var any : Any = ()
 any = (1, 2)
-any = (label: 4)
+any = (label: 4) // expected-error {{cannot create a single-element tuple with an element label}}
 
 // Scalars don't have .0/.1/etc
 i = j.0 // expected-error{{value of type 'Int' has no member '0'}}
@@ -153,7 +153,7 @@
   var a = a
   var b = b
   (a, b) = (b, a % b)  // expected-error {{binary operator '%' cannot be applied to two 'T' operands}}
-  // expected-note @-1 {{overloads for '%' exist with these partially matching parameter lists: (UInt8, UInt8), (Int8, Int8), (UInt16, UInt16), (Int16, Int16), (UInt32, UInt32), (Int32, Int32), (UInt64, UInt64), (Int64, Int64), (UInt, UInt), (Int, Int)}}
+  // expected-note @-1 {{overloads for '%' exist with these partially matching parameter lists}}
 }
 
 // <rdar://problem/24210190>
@@ -252,3 +252,11 @@
   let y = ""
   return b ? (x, y) : nil
 }
+
+// Single element tuple expressions
+func singleElementTuple() {
+  let _ = (label: 123) // expected-error {{cannot create a single-element tuple with an element label}} {{12-19=}}
+  let _ = (label: 123).label // expected-error {{cannot create a single-element tuple with an element label}} {{12-19=}}
+  let _ = ((label: 123)) // expected-error {{cannot create a single-element tuple with an element label}} {{13-20=}}
+  let _ = ((label: 123)).label // expected-error {{cannot create a single-element tuple with an element label}} {{13-20=}}
+}
diff --git a/test/Constraints/tuple_arguments.swift b/test/Constraints/tuple_arguments.swift
index 2dfe694..4ad4c93 100644
--- a/test/Constraints/tuple_arguments.swift
+++ b/test/Constraints/tuple_arguments.swift
@@ -1671,3 +1671,18 @@
   func h(_: ()) {} // expected-note {{'h' declared here}}
   h() // expected-error {{missing argument for parameter #1 in call}}
 }
+
+// https://bugs.swift.org/browse/SR-7191
+class Mappable<T> {
+  init(_: T) { }
+  func map<U>(_ body: (T) -> U) -> U { fatalError() }
+}
+
+let x = Mappable(())
+_ = x.map { (_: Void) in return () }
+
+// https://bugs.swift.org/browse/SR-9470
+do {
+  func f(_: Int...) {}
+  let _ = [(1, 2, 3)].map(f) // expected-error {{cannot invoke 'map' with an argument list of type '((Int...) -> ())'}}
+}
\ No newline at end of file
diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt
index 1fcab70..4ff70e7 100644
--- a/test/Demangle/Inputs/manglings.txt
+++ b/test/Demangle/Inputs/manglings.txt
@@ -301,7 +301,7 @@
 _T0So11CrappyColorVs16RawRepresentableSCMA ---> reflection metadata associated type descriptor __C.CrappyColor : Swift.RawRepresentable in __C_Synthesized
 $S28protocol_conformance_records15NativeValueTypeVAA8RuncibleAAMc ---> protocol conformance descriptor for protocol_conformance_records.NativeValueType : protocol_conformance_records.Runcible in protocol_conformance_records
 $SSC9SomeErrorLeVD ---> __C_Synthesized.related decl 'e' for SomeError
-$s20mangling_retroactive5test1yyAA2Z2V5InnerVy12RetroactiveB1XV_AG1YVAI0F1A1PAAyHCg_AkL1QAAyHCg0_GF ---> mangling_retroactive.test1(mangling_retroactive.Z2<RetroactiveB.X>.Inner<RetroactiveB.Y>) -> ()
+$s20mangling_retroactive5test0yyAA1ZVy12RetroactiveB1XVSiAE1YVAG0D1A1PAAHPyHCg_AiJ1QAAHPyHCg1_GF ---> mangling_retroactive.test0(mangling_retroactive.Z<RetroactiveB.X, Swift.Int, RetroactiveB.Y>) -> ()
 _T0LiteralAByxGxd_tcfC ---> _T0LiteralAByxGxd_tcfC
 _T0XZ ---> _T0XZ
 _TTSf0os___TFVs17_LegacyStringCore15_invariantCheckfT_T_ ---> function signature specialization <Arg[0] = Guaranteed To Owned and Exploded> of Swift._LegacyStringCore._invariantCheck() -> ()
diff --git a/test/IRGen/lazy_field_metadata.swift b/test/IRGen/lazy_field_metadata.swift
new file mode 100644
index 0000000..702957e
--- /dev/null
+++ b/test/IRGen/lazy_field_metadata.swift
@@ -0,0 +1,18 @@
+// RUN: %target-swift-frontend -emit-ir -wmo -O %s | %FileCheck %s
+
+// Both should be emitted:
+
+// CHECK: @"$s19lazy_field_metadata011GenericWithD5FieldVMn" = hidden constant
+// CHECK: @"$s19lazy_field_metadata24GenericWithConcreteFieldVMn" = hidden constant
+
+struct GenericWithConcreteField<T> {
+  let z = 123
+}
+
+struct GenericWithGenericField<T> {
+  var field = GenericWithConcreteField<T>()
+}
+
+public func forceMetadata() -> Any.Type {
+  return GenericWithGenericField<Int>.self
+}
\ No newline at end of file
diff --git a/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h b/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
index 508e499..51cd769 100644
--- a/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
+++ b/test/Inputs/clang-importer-sdk/usr/include/CoreFoundation.h
@@ -18,8 +18,21 @@
 
 typedef CFTypeRef CFAliasForTypeRef;
 
-
+#if __LLP64__
+typedef unsigned long long CFTypeID;
+typedef unsigned long long CFOptionFlags;
+typedef unsigned long long CFHashCode;
+typedef signed long long CFIndex;
+#else
+typedef unsigned long CFTypeID;
+typedef unsigned long CFOptionFlags;
+typedef unsigned long CFHashCode;
 typedef signed long CFIndex;
+#endif
+
+extern CFTypeID CFTypeID_test;
+extern CFOptionFlags CFOptionFlags_test;
+extern CFHashCode CFHashCode_test;
 extern CFIndex CFIndex_test;
 
 #define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
diff --git a/test/Migrator/stdlib_rename.swift b/test/Migrator/stdlib_rename.swift
new file mode 100644
index 0000000..20397f3
--- /dev/null
+++ b/test/Migrator/stdlib_rename.swift
@@ -0,0 +1,12 @@
+// REQUIRES: objc_interop
+// RUN: %empty-directory(%t) && %target-swift-frontend -c -update-code -primary-file %s -F %S/mock-sdk -emit-migrated-file-path %t/stdlib_rename.swift.result -emit-remap-file-path %t/stdlib_rename.swift.remap -o /dev/null
+// RUN: diff -u %S/stdlib_rename.swift.expected %t/stdlib_rename.swift.result
+// RUN: %empty-directory(%t) && %target-swift-frontend -c -update-code -primary-file %s -F %S/mock-sdk -emit-migrated-file-path %t/stdlib_rename.swift.result -emit-remap-file-path %t/stdlib_rename.swift.remap -o /dev/null -swift-version 4.2
+// RUN: diff -u %S/stdlib_rename.swift.expected %t/stdlib_rename.swift.result
+
+func test1(_ a: [String], s: String) {
+  _ = a.index(of: s)
+}
+func test2(_ s: String, c: Character) {
+  _ = s.index(of: c)
+}
\ No newline at end of file
diff --git a/test/Migrator/stdlib_rename.swift.expected b/test/Migrator/stdlib_rename.swift.expected
new file mode 100644
index 0000000..f721bf8
--- /dev/null
+++ b/test/Migrator/stdlib_rename.swift.expected
@@ -0,0 +1,12 @@
+// REQUIRES: objc_interop
+// RUN: %empty-directory(%t) && %target-swift-frontend -c -update-code -primary-file %s -F %S/mock-sdk -emit-migrated-file-path %t/stdlib_rename.swift.result -emit-remap-file-path %t/stdlib_rename.swift.remap -o /dev/null
+// RUN: diff -u %S/stdlib_rename.swift.expected %t/stdlib_rename.swift.result
+// RUN: %empty-directory(%t) && %target-swift-frontend -c -update-code -primary-file %s -F %S/mock-sdk -emit-migrated-file-path %t/stdlib_rename.swift.result -emit-remap-file-path %t/stdlib_rename.swift.remap -o /dev/null -swift-version 4.2
+// RUN: diff -u %S/stdlib_rename.swift.expected %t/stdlib_rename.swift.result
+
+func test1(_ a: [String], s: String) {
+  _ = a.firstIndex(of: s)
+}
+func test2(_ s: String, c: Character) {
+  _ = s.firstIndex(of: c)
+}
\ No newline at end of file
diff --git a/test/NameBinding/Inputs/HasResult.swift b/test/NameBinding/Inputs/HasResult.swift
new file mode 100644
index 0000000..6fcc1dd
--- /dev/null
+++ b/test/NameBinding/Inputs/HasResult.swift
@@ -0,0 +1,4 @@
+public enum Result<Value, Error> {
+case success(Value)
+case failure(Error)
+}
diff --git a/test/NameBinding/Inputs/MemberTypesInClasses.swift b/test/NameBinding/Inputs/MemberTypesInClasses.swift
new file mode 100644
index 0000000..1e9ed6f
--- /dev/null
+++ b/test/NameBinding/Inputs/MemberTypesInClasses.swift
@@ -0,0 +1,7 @@
+public class RootClass {
+}
+
+public class SubClass: RootClass {
+  public typealias Member = Int
+}
+
diff --git a/test/NameBinding/member_type_shadowing.swift b/test/NameBinding/member_type_shadowing.swift
new file mode 100644
index 0000000..b9231a1
--- /dev/null
+++ b/test/NameBinding/member_type_shadowing.swift
@@ -0,0 +1,15 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/MemberTypesInClasses.swift
+// RUN: %target-swift-frontend -typecheck %s -I %t -verify
+
+import MemberTypesInClasses
+
+protocol P {
+  associatedtype Member
+}
+
+extension RootClass: P {
+  typealias Member = SubClass.Member
+}
+
+
diff --git a/test/NameBinding/stdlib_shadowing.swift b/test/NameBinding/stdlib_shadowing.swift
new file mode 100644
index 0000000..ccbb824
--- /dev/null
+++ b/test/NameBinding/stdlib_shadowing.swift
@@ -0,0 +1,9 @@
+// RUN: %empty-directory(%t)
+// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/HasResult.swift
+// RUN: %target-swift-frontend -typecheck %s -I %t -verify
+
+import HasResult
+
+func foo() -> Result<Int, Error> {
+  return Result<Int, Error>.success(42)
+}
diff --git a/test/Parse/try.swift b/test/Parse/try.swift
index 54a2aa2..f58f4a0 100644
--- a/test/Parse/try.swift
+++ b/test/Parse/try.swift
@@ -258,3 +258,14 @@
 let _: Int?? = try? producer.produceDoubleOptionalInt() // expected-error {{value of optional type 'Int???' not unwrapped; did you mean to use 'try!' or chain with '?'?}}
 let _: Int??? = try? producer.produceDoubleOptionalInt() // good
 let _: String = try? producer.produceDoubleOptionalInt() // expected-error {{cannot convert value of type 'Int???' to specified type 'String'}}
+
+// rdar://problem/46742002
+protocol Dummy : class {}
+
+class F<T> {
+  func wait() throws -> T { fatalError() }
+}
+
+func bar(_ a: F<Dummy>, _ b: F<Dummy>) {
+  _ = (try? a.wait()) === (try? b.wait())
+}
diff --git a/test/Parse/try_swift5.swift b/test/Parse/try_swift5.swift
index 6d463a0..ec05752 100644
--- a/test/Parse/try_swift5.swift
+++ b/test/Parse/try_swift5.swift
@@ -261,3 +261,14 @@
 let _: Int?? = try? producer.produceDoubleOptionalInt() // good
 let _: Int??? = try? producer.produceDoubleOptionalInt() // good
 let _: String = try? producer.produceDoubleOptionalInt() // expected-error {{cannot convert value of type 'Int??' to specified type 'String'}}
+
+// rdar://problem/46742002
+protocol Dummy : class {}
+
+class F<T> {
+  func wait() throws -> T { fatalError() }
+}
+
+func bar(_ a: F<Dummy>, _ b: F<Dummy>) {
+  _ = (try? a.wait()) === (try? b.wait())
+}
diff --git a/test/ParseableInterface/fixed-layout-property-initializers.swift b/test/ParseableInterface/fixed-layout-property-initializers.swift
index 0b817bc..099a214 100644
--- a/test/ParseableInterface/fixed-layout-property-initializers.swift
+++ b/test/ParseableInterface/fixed-layout-property-initializers.swift
@@ -1,16 +1,16 @@
 // RUN: %empty-directory(%t)
 
 // RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t.swiftinterface %s
-// RUN: %FileCheck %s < %t.swiftinterface
+// RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix CHECK < %t.swiftinterface
 
 // RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t-resilient.swiftinterface -enable-resilience %s
-// RUN: %FileCheck %s < %t-resilient.swiftinterface
+// RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix CHECK < %t-resilient.swiftinterface
 
 // RUN: %target-swift-frontend -emit-module -o %t/Test.swiftmodule %t.swiftinterface -disable-objc-attr-requires-foundation-module
-// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -module-name Test -emit-parseable-module-interface-path - | %FileCheck %s
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -module-name Test -emit-parseable-module-interface-path - | %FileCheck %s --check-prefix FROMMODULE --check-prefix CHECK
 
 // RUN: %target-swift-frontend -emit-module -o %t/TestResilient.swiftmodule -enable-resilience %t-resilient.swiftinterface -disable-objc-attr-requires-foundation-module
-// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/TestResilient.swiftmodule -module-name TestResilient -enable-resilience -emit-parseable-module-interface-path - | %FileCheck %s
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/TestResilient.swiftmodule -module-name TestResilient -enable-resilience -emit-parseable-module-interface-path - | %FileCheck %s --check-prefix FROMMODULE --check-prefix CHECK
 
 // CHECK: @_fixed_layout public struct MyStruct {
 @_fixed_layout
@@ -34,7 +34,8 @@
   // CHECK: @_hasInitialValue public static var staticVar: [[BOOL]]
   public static var staticVar: Bool = Bool(true && false)
 
-  // CHECK: @inlinable internal init() {}
+  // FROMSOURCE: @inlinable internal init() {}
+  // FROMMODULE: @inlinable internal init(){{$}}
   @inlinable init() {}
 }
 
@@ -57,7 +58,8 @@
   // CHECK: @_hasInitialValue public static var staticVar: [[BOOL]]
   public static var staticVar: Bool = Bool(true && false)
 
-  // CHECK: @inlinable internal init() {}
+  // FROMSOURCE: @inlinable internal init() {}
+  // FROMMODULE: @inlinable internal init(){{$}}
   @inlinable init() {}
 }
 
diff --git a/test/ParseableInterface/inlinable-function.swift b/test/ParseableInterface/inlinable-function.swift
index 3bb0589..f22e63d 100644
--- a/test/ParseableInterface/inlinable-function.swift
+++ b/test/ParseableInterface/inlinable-function.swift
@@ -1,15 +1,17 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -o %t/Test.swiftmodule -emit-parseable-module-interface-path %t/Test.swiftinterface -module-name Test %s
-// RUN: %FileCheck %s < %t/Test.swiftinterface
-// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -disable-objc-attr-requires-foundation-module -emit-parseable-module-interface-path - -module-name Test | %FileCheck %s
+// RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix CHECK < %t/Test.swiftinterface
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -disable-objc-attr-requires-foundation-module -emit-parseable-module-interface-path %t/TestFromModule.swiftinterface -module-name Test
+// RUN: %FileCheck %s --check-prefix FROMMODULE --check-prefix CHECK < %t/TestFromModule.swiftinterface
 
 // CHECK: public struct Foo : Hashable {
 public struct Foo: Hashable {
   // CHECK: public var inlinableGetPublicSet: [[INT:(Swift.)?Int]] {
   public var inlinableGetPublicSet: Int {
-  // CHECK: @inlinable get {
-  // CHECK-NEXT: return 3
-  // CHECK-NEXT: }
+  // FROMSOURCE: @inlinable get {
+  // FROMMODULE: @inlinable get{{$}}
+  // FROMSOURCE-NEXT: return 3
+  // FROMSOURCE-NEXT: }
     @inlinable
     get {
       return 3
@@ -35,11 +37,11 @@
     // CHECK-NEXT: {{^}}  }
   }
 
-
   // CHECK: @_transparent public var transparent: [[INT]] {
-  // CHECK-NEXT:   get {
-  // CHECK-NEXT:   return 34
-  // CHECK-NEXT: }
+  // FROMMODULE-NEXT: get{{$}}
+  // FROMSOURCE-NEXT: get {
+  // FROMSOURCE-NEXT:   return 34
+  // FROMSOURCE-NEXT: }
   // CHECK-NEXT: }
   @_transparent
   public var transparent: Int {
@@ -52,17 +54,18 @@
     get {
       return 34
     }
-    // CHECK-NEXT: @_transparent set[[NEWVALUE]] {
-    // CHECK-NOT:   #if false
-    // CHECK-NOT:   print("I should not appear")
-    // CHECK-NOT:   #else
-    // CHECK-NOT:   #if false
-    // CHECK-NOT:   print("I also should not")
-    // CHECK-NOT:   #else
-    // CHECK:       print("I am set to \(newValue)")
-    // CHECK-NOT:   #endif
-    // CHECK-NOT:   #endif
-    // CHECK-NEXT: }
+    // FROMMODULE-NEXT: @_transparent set[[NEWVALUE]]{{$}}
+    // FROMSOURCE-NEXT: @_transparent set[[NEWVALUE]] {
+    // FROMSOURCE-NOT:   #if false
+    // FROMSOURCE-NOT:   print("I should not appear")
+    // FROMSOURCE-NOT:   #else
+    // FROMSOURCE-NOT:   #if false
+    // FROMSOURCE-NOT:   print("I also should not")
+    // FROMSOURCE-NOT:   #else
+    // FROMSOURCE:       print("I am set to \(newValue)")
+    // FROMSOURCE-NOT:   #endif
+    // FROMSOURCE-NOT:   #endif
+    // FROMSOURCE-NEXT: }
     @_transparent
     set {
       #if false
@@ -80,20 +83,22 @@
   // CHECK: @inlinable public var inlinableProperty: [[INT]] {
   @inlinable
   public var inlinableProperty: Int {
-    // CHECK: get {
-    // CHECK:   return 32
-    // CHECK: }
+    // FROMMODULE:      get{{$}}
+    // FROMSOURCE:      get {
+    // FROMSOURCE-NEXT:   return 32
+    // FROMSOURCE-NEXT: }
     get {
       return 32
     }
 
-    // CHECK: set[[NEWVALUE]] {
-    // CHECK-NOT: #if true
-    // CHECK:     print("I am set to \(newValue)")
-    // CHECK-NOT: #else
-    // CHECK-NOT: print("I should not appear")
-    // CHECK-NOT  #endif
-    // CHECK: }
+    // FROMMODULE: set[[NEWVALUE]]{{$}}
+    // FROMSOURCE: set[[NEWVALUE]] {
+    // FROMSOURCE-NOT: #if true
+    // FROMSOURCE:     print("I am set to \(newValue)")
+    // FROMSOURCE-NOT: #else
+    // FROMSOURCE-NOT: print("I should not appear")
+    // FROMSOURCE-NOT  #endif
+    // FROMSOURCE: }
     set {
       #if true
       print("I am set to \(newValue)")
@@ -107,16 +112,18 @@
   // CHECK: @inlinable public var inlinableReadAndModify: [[INT]] {
   @inlinable
   public var inlinableReadAndModify: Int {
-    // CHECK: _read {
-    // CHECK-NEXT: yield 0
-    // CHECK-NEXT: }
+    // FROMMODULE:      _read{{$}}
+    // FROMSOURCE:      _read {
+    // FROMSOURCE-NEXT:   yield 0
+    // FROMSOURCE-NEXT: }
     _read {
       yield 0
     }
-    // CHECK: _modify {
-    // CHECK-NEXT: var x = 0
-    // CHECK-NEXT: yield &x
-    // CHECK-NEXT: }
+    // FROMMODULE:      _modify{{$}}
+    // FROMSOURCE:      _modify {
+    // FROMSOURCE-NEXT:   var x = 0
+    // FROMSOURCE-NEXT:   yield &x
+    // FROMSOURCE-NEXT: }
     _modify {
       var x = 0
       yield &x
@@ -126,9 +133,10 @@
 
   // CHECK: public var inlinableReadNormalModify: [[INT]] {
   public var inlinableReadNormalModify: Int {
-    // CHECK: @inlinable _read {
-    // CHECK-NEXT: yield 0
-    // CHECK-NEXT: }
+    // FROMMODULE: @inlinable _read{{$}}
+    // FROMSOURCE: @inlinable _read {
+    // FROMSOURCE-NEXT: yield 0
+    // FROMSOURCE-NEXT: }
     @inlinable _read {
       yield 0
     }
@@ -153,10 +161,11 @@
       yield 0
     }
 
-    // CHECK: @inlinable _modify {
-    // CHECK-NEXT: var x = 0
-    // CHECK-NEXT: yield &x
-    // CHECK-NEXT: }
+    // FROMMODULE: @inlinable _modify{{$}}
+    // FROMSOURCE: @inlinable _modify {
+    // FROMSOURCE-NEXT: var x = 0
+    // FROMSOURCE-NEXT: yield &x
+    // FROMSOURCE-NEXT: }
     @inlinable _modify {
       var x = 0
       yield &x
@@ -176,12 +185,13 @@
     // CHECK-NEXT: }
   }
 
-  // CHECK: @inlinable public func inlinableMethod() {
-  // CHECK-NOT: #if NO
-  // CHECK-NOT: print("Hello, world!")
-  // CHECK-NOT: #endif
-  // CHECK:     print("Goodbye, world!")
-  // CHECK-NEXT: }
+  // FROMMODULE: @inlinable public func inlinableMethod(){{$}}
+  // FROMSOURCE: @inlinable public func inlinableMethod() {
+  // FROMSOURCE-NOT: #if NO
+  // FROMSOURCE-NOT: print("Hello, world!")
+  // FROMSOURCE-NOT: #endif
+  // FROMSOURCE:     print("Goodbye, world!")
+  // FROMSOURCE-NEXT: }
   @inlinable
   public func inlinableMethod() {
     #if NO
@@ -191,9 +201,10 @@
   }
 
 
-  // CHECK: @_transparent [[ATTRS:(mutating public|public mutating)]] func transparentMethod() {
-  // CHECK-NEXT:   inlinableProperty = 4
-  // CHECK-NEXT: }
+  // FROMMODULE: @_transparent [[ATTRS:(mutating public|public mutating)]] func transparentMethod(){{$}}
+  // FROMSOURCE: @_transparent [[ATTRS:(mutating public|public mutating)]] func transparentMethod() {
+  // FROMSOURCE-NEXT:   inlinableProperty = 4
+  // FROMSOURCE-NEXT: }
   @_transparent
   mutating public func transparentMethod() {
     inlinableProperty = 4
@@ -207,7 +218,8 @@
 
   // CHECK: public subscript(i: [[INT]]) -> [[INT]] {
   // CHECK-NEXT:   get{{$}}
-  // CHECK-NEXT:   @inlinable set[[NEWVALUE]] { print("set") }
+  // FROMSOURCE-NEXT:   @inlinable set[[NEWVALUE]] { print("set") }
+  // FROMMODULE-NEXT:   @inlinable set[[NEWVALUE]]{{$}}
   // CHECK-NEXT: }
   public subscript(i: Int) -> Int {
     get { return 0 }
@@ -215,7 +227,8 @@
   }
 
   // CHECK: public subscript(j: [[INT]], k: [[INT]]) -> [[INT]] {
-  // CHECK-NEXT:   @inlinable get { return 0 }
+  // FROMMODULE-NEXT:   @inlinable get{{$}}
+  // FROMSOURCE-NEXT:   @inlinable get { return 0 }
   // CHECK-NEXT:   set[[NEWVALUE]]{{$}}
   // CHECK-NEXT: }
   public subscript(j: Int, k: Int) -> Int {
@@ -224,8 +237,10 @@
   }
 
   // CHECK: @inlinable public subscript(l: [[INT]], m: [[INT]], n: [[INT]]) -> [[INT]] {
-  // CHECK-NEXT:   get { return 0 }
-  // CHECK-NEXT:   set[[NEWVALUE]] { print("set") }
+  // FROMMODULE-NEXT:   get{{$}}
+  // FROMSOURCE-NEXT:   get { return 0 }
+  // FROMMODULE-NEXT:   set[[NEWVALUE]]{{$}}
+  // FROMSOURCE-NEXT:   set[[NEWVALUE]] { print("set") }
   // CHECK-NEXT: }
   @inlinable
   public subscript(l: Int, m: Int, n: Int) -> Int {
@@ -233,11 +248,12 @@
     set { print("set") }
   }
 
-  // CHECK: public init(value: [[INT]]) {
-  // CHECK-NEXT: topLevelUsableFromInline()
-  // CHECK-NEXT: noAccessors = value
-  // CHECK-NEXT: hasDidSet = value
-  // CHECK-NEXT: }
+  // FROMMODULE: @inlinable public init(value: [[INT]]){{$}}
+  // FROMSOURCE: @inlinable public init(value: [[INT]]) {
+  // FROMSOURCE-NEXT: topLevelUsableFromInline()
+  // FROMSOURCE-NEXT: noAccessors = value
+  // FROMSOURCE-NEXT: hasDidSet = value
+  // FROMSOURCE-NEXT: }
   @inlinable public init(value: Int) {
     topLevelUsableFromInline()
     noAccessors = value
@@ -266,9 +282,10 @@
   topLevelPrivate()
 }
 
-// CHECK: @inlinable public func topLevelInlinable() {
-// CHECK-NEXT:  topLevelUsableFromInline()
-// CHECK-NEXT: }
+// FROMMODULE: @inlinable public func topLevelInlinable(){{$}}
+// FROMSOURCE: @inlinable public func topLevelInlinable() {
+// FROMSOURCE-NEXT:  topLevelUsableFromInline()
+// FROMSOURCE-NEXT: }
 @inlinable public func topLevelInlinable() {
   topLevelUsableFromInline()
 }
@@ -278,9 +295,10 @@
   // CHECK: public init(){{$}}
   public init() {}
 
-  // CHECK: [[OBJC:(@objc )?]]@inlinable deinit {
-  // CHECK-NEXT: print("goodbye")
-  // CHECK-NEXT: }
+  // FROMMODULE: [[OBJC:(@objc )?]]@inlinable deinit{{$}}
+  // FROMSOURCE: [[OBJC:(@objc )?]]@inlinable deinit {
+  // FROMSOURCE-NEXT: print("goodbye")
+  // FROMSOURCE-NEXT: }
   @inlinable deinit {
     print("goodbye")
   }
diff --git a/test/ParseableInterface/modifiers.swift b/test/ParseableInterface/modifiers.swift
index d63a46a..c0576b0 100644
--- a/test/ParseableInterface/modifiers.swift
+++ b/test/ParseableInterface/modifiers.swift
@@ -1,14 +1,15 @@
 // RUN: %empty-directory(%t)
 // RUN: %target-swift-frontend -emit-module -o %t/Test.swiftmodule -emit-parseable-module-interface-path %t/Test.swiftinterface -module-name Test -disable-objc-attr-requires-foundation-module -enable-objc-interop %s
-// RUN: %FileCheck %s < %t/Test.swiftinterface
-// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -disable-objc-attr-requires-foundation-module -emit-parseable-module-interface-path - -module-name Test -enable-objc-interop | %FileCheck %s
+// RUN: %FileCheck %s --check-prefix FROMSOURCE --check-prefix CHECK < %t/Test.swiftinterface
+// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules %t/Test.swiftmodule -disable-objc-attr-requires-foundation-module -emit-parseable-module-interface-path - -module-name Test -enable-objc-interop | %FileCheck %s --check-prefix FROMMODULE --check-prefix CHECK
 
 // CHECK-LABEL: final public class FinalClass {
 public final class FinalClass {
   // CHECK: @inlinable final public class var a: [[INT:(Swift.)?Int]] {
-  // CHECK-NEXT: {{^}} get {
-  // CHECK-NEXT: return 3
-  // CHECK-NEXT: }
+  // FROMSOURCE-NEXT: {{^}} get {
+  // FROMSOURCE-NEXT: return 3
+  // FROMSOURCE-NEXT: }
+  // FROMMODULE-NEXT: get{{$}}
   // CHECK-NEXT: }
   @inlinable
   public final class var a: Int {
@@ -16,9 +17,10 @@
   }
 
   // CHECK: final public class var b: [[INT]] {
-  // CHECK-NEXT:   {{^}} @inlinable get {
-  // CHECK-NEXT:     return 3
-  // CHECK-NEXT:   }
+  // FROMSOURCE-NEXT: {{^}} @inlinable get {
+  // FROMSOURCE-NEXT:   return 3
+  // FROMSOURCE-NEXT: }
+  // FROMMODULE-NEXT: {{^}} @inlinable get{{$}}
   // CHECK-NEXT:   set[[NEWVALUE:(\(newValue\))?]]{{$}}
   // CHECK-NEXT: }
   public final class var b: Int {
@@ -32,7 +34,8 @@
 
   // CHECK: public static var c: [[INT]] {
   // CHECK-NEXT: {{^}} get
-  // CHECK-NEXT:   @inlinable set[[NEWVALUE]] {}
+  // FROMSOURCE-NEXT:   @inlinable set[[NEWVALUE]] {}
+  // FROMMODULE-NEXT:   @inlinable set[[NEWVALUE]]{{$}}
   // CHECK-NEXT: }
   public static var c: Int {
     get {
@@ -85,7 +88,8 @@
 public struct MyStruct {
   // CHECK: public var e: [[INT]] {
   // CHECK-NEXT: {{^}} mutating get{{$}}
-  // CHECK-NEXT: {{^}} @inlinable nonmutating set[[NEWVALUE]] {}
+  // FROMSOURCE-NEXT: {{^}} @inlinable nonmutating set[[NEWVALUE]] {}
+  // FROMMODULE-NEXT: {{^}} @inlinable nonmutating set[[NEWVALUE]]{{$}}
   // CHECK-NEXT: }
   public var e: Int {
     mutating get { return 0 }
diff --git a/test/ParseableInterface/stored-properties-client.swift b/test/ParseableInterface/stored-properties-client.swift
index a7e04fd..914815b 100644
--- a/test/ParseableInterface/stored-properties-client.swift
+++ b/test/ParseableInterface/stored-properties-client.swift
@@ -15,7 +15,7 @@
 // COMMON: %[[BAGOFVARIABLES:T16StoredProperties14BagOfVariablesV]] = type <{ %TSi, %TSb, [{{(3|7)}} x i8], %TSi }>
 
 // This type is non-@_fixed_layout, so it becomes opaque in a resilient module
-// CHECK: %[[HASSTOREDPROPERTIES:T16StoredProperties03HasaB0V]] = type <{ %TSi, %TSi, %TSb, [{{(3|7)}} x i8], %TSi, %TSb }>
+// CHECK: %[[HASSTOREDPROPERTIES:T16StoredProperties03HasaB0V]] = type <{ %TSi, %TSi, %TSb, [{{(3|7)}} x i8], %TSi, %TSb, [{{3|7}} x i8], %TSi }>
 // RESILIENT: %[[HASSTOREDPROPERTIES:swift.opaque]] = type opaque
 
 // COMMON: %[[HASSTOREDPROPERTIESFIXEDLAYOUT:T16StoredProperties03HasaB11FixedLayoutV]] = type <{ %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]] }>
diff --git a/test/ParseableInterface/stored-properties.swift b/test/ParseableInterface/stored-properties.swift
index 35e7682..774553e 100644
--- a/test/ParseableInterface/stored-properties.swift
+++ b/test/ParseableInterface/stored-properties.swift
@@ -52,6 +52,15 @@
   // CHECK: private var _: [[BOOL]]
   private var privateVar: Bool
 
+  // CHECK: @_hasStorage @_hasInitialValue public var storedWithObserversInitialValue: [[INT]] {
+  // RESILIENT: {{^}}  @_hasInitialValue public var storedWithObserversInitialValue: [[INT]] {
+  // COMMON-NEXT: get
+  // COMMON-NEXT: set
+  // COMMON-NEXT: }
+  public var storedWithObserversInitialValue: Int = 0 {
+    didSet {}
+  }
+
   // COMMON: public init(){{$}}
   public init() {
     self.simpleStoredImmutable = 0
diff --git a/test/SILGen/mangling_retroactive.swift b/test/SILGen/mangling_retroactive.swift
index ee95ccd..2c865b1 100644
--- a/test/SILGen/mangling_retroactive.swift
+++ b/test/SILGen/mangling_retroactive.swift
@@ -12,14 +12,14 @@
 extension X: P { } // retroactive
 extension Y: Q { } // retroactive
 
-// CHECK: sil hidden @$s20mangling_retroactive5test0yyAA1ZVy12RetroactiveB1XVSiAE1YVAG0D1A1PAAyHCg_AiJ1QAAyHCg1_GF
+// CHECK: sil hidden @$s20mangling_retroactive5test0yyAA1ZVy12RetroactiveB1XVSiAE1YVAG0D1A1PAAHPyHCg_AiJ1QAAHPyHCg1_GF
 func test0(_: Z<X, Int, Y>) { }
 
 struct Z2<T: P> {
   struct Inner<V: Q> { }
 }
 
-// CHECK: sil hidden @$s20mangling_retroactive5test1yyAA2Z2V5InnerVy12RetroactiveB1XV_AG1YVAI0F1A1PAAyHCg_AkL1QAAyHCg0_GF
+// CHECK: sil hidden @$s20mangling_retroactive5test1yyAA2Z2V5InnerVy12RetroactiveB1XV_AG1YVAI0F1A1PAAHPyHCg_AkL1QAAHPyHCg0_GF
 func test1(_: Z2<X>.Inner<Y>) { }
 
 extension X: Hashable {
@@ -38,5 +38,5 @@
 struct RequiresEquatable<T: Equatable> { }
 
 // Conditional requirement involves retroactive conformances.
-// CHECK: sil hidden @$s20mangling_retroactive5test2yyAA17RequiresEquatableVyAA1ZVy12RetroactiveB1XVSiAG1YVAI0F1A1PAAyHCg_AkL1QAAyHCg1_GAOSQAISHAAyHC_AKSQAAyHCHCg_GF
+// CHECK: sil hidden @$s20mangling_retroactive5test2yyAA17RequiresEquatableVyAA1ZVy12RetroactiveB1XVSiAG1YVAI0F1A1PAAHPyHCg_AkL1QAAHPyHCg1_GAOSQHPAISHAAHPyHC_AKSQAAHPyHCHCg_GF
 func test2(_: RequiresEquatable<Z<X, Int, Y>>) { }
diff --git a/test/SILOptimizer/sil_combine.sil b/test/SILOptimizer/sil_combine.sil
index 08fda37..2cfe911 100644
--- a/test/SILOptimizer/sil_combine.sil
+++ b/test/SILOptimizer/sil_combine.sil
@@ -614,6 +614,30 @@
   return %2 : $Builtin.RawPointer
 }
 
+sil @test_closure : $@convention(thin) (@guaranteed C) -> ()
+
+// CHECK-LABEL: sil @dead_closure_elimination
+// CHECK:      bb0(%0 : $C):
+// CHECK-NEXT:   cond_br
+// CHECK-NOT:  strong_release
+// CHECK:      bb2:
+// CHECK-NEXT:   strong_release %0
+// CHECK         return
+sil @dead_closure_elimination : $@convention(thin) (@owned C) -> () {
+bb0(%0 : $C):
+  %1 = function_ref @test_closure : $@convention(thin) (@guaranteed C) -> ()
+  %2 = partial_apply [callee_guaranteed] %1(%0) : $@convention(thin) (@guaranteed C) -> ()
+  cond_br undef, bb1, bb2
+bb1:
+  strong_retain %2 : $@callee_guaranteed () -> ()
+  strong_release %2 : $@callee_guaranteed () -> ()
+  br bb2
+bb2:
+  release_value %2 : $@callee_guaranteed () -> ()
+  %5 = tuple()
+  return %5 : $()
+}
+
 ////////////////////////////////////////////
 // Load Proj To GEP Load Canonicalization //
 ////////////////////////////////////////////
diff --git a/test/Sema/complex_expressions.swift b/test/Sema/complex_expressions.swift
index 2fee412..788919b 100644
--- a/test/Sema/complex_expressions.swift
+++ b/test/Sema/complex_expressions.swift
@@ -1,11 +1,5 @@
 // RUN: %target-typecheck-verify-swift
 
-// SR-139:
-// Infinite recursion parsing bitwise operators
-// Temporarily disable to get SIMD stuff working. Ideally we can reinstate this
-// with Mark's changes.
-// let x = UInt32(0x1FF)&0xFF << 24 | UInt32(0x1FF)&0xFF << 16 | UInt32(0x1FF)&0xFF << 8 | (UInt32(0x1FF)&0xFF);
-
 // SR-838:
 // expression test_seconds() was too complex to be solved in reasonable time
 struct Nano : CustomStringConvertible {
diff --git a/test/decl/enum/enumtest.swift b/test/decl/enum/enumtest.swift
index c04ae3f..ae86aed 100644
--- a/test/decl/enum/enumtest.swift
+++ b/test/decl/enum/enumtest.swift
@@ -164,9 +164,9 @@
   // Dot syntax.
   _ = x2.origin.x
   _ = x1.size.area()
-  _ = (r : x1.size).r.area()
+  _ = (r : x1.size).r.area() // expected-error {{cannot create a single-element tuple with an element label}}
   _ = x1.size.area()
-  _ = (r : x1.size).r.area()
+  _ = (r : x1.size).r.area() // expected-error {{cannot create a single-element tuple with an element label}}
   
   _ = x1.area
 
diff --git a/test/decl/ext/generic.swift b/test/decl/ext/generic.swift
index 1ffb543..66327d3 100644
--- a/test/decl/ext/generic.swift
+++ b/test/decl/ext/generic.swift
@@ -30,7 +30,7 @@
 
 typealias GGG = X<Int, Double, String>
 
-extension GGG { } // expected-error{{constrained extension must be declared on the unspecialized generic type 'X' with constraints specified by a 'where' clause}}
+extension GGG { } // okay through a typealias
 
 // Lvalue check when the archetypes are not the same.
 struct LValueCheck<T> {
@@ -210,3 +210,16 @@
   func g() { }
 }
 
+// rdar://problem/43955962
+struct OldGeneric<T> {}
+typealias NewGeneric<T> = OldGeneric<T>
+
+extension NewGeneric {
+  static func oldMember() -> OldGeneric {
+    return OldGeneric()
+  }
+
+  static func newMember() -> NewGeneric {
+    return NewGeneric()
+  }
+}
diff --git a/test/decl/ext/typealias.swift b/test/decl/ext/typealias.swift
new file mode 100644
index 0000000..c5917a0
--- /dev/null
+++ b/test/decl/ext/typealias.swift
@@ -0,0 +1,80 @@
+// RUN: %target-typecheck-verify-swift
+
+struct Foo<T> {
+  var maybeT: T? { return nil }
+}
+
+extension Foo {
+  struct Bar<U, V> {
+    var maybeT: T? { return nil }
+    var maybeU: U? { return nil }
+    var maybeV: V? { return nil }
+
+    struct Inner {
+      var maybeT: T? { return nil }
+      var maybeU: U? { return nil }
+      var maybeV: V? { return nil }
+    }
+  }
+}
+
+typealias FooInt = Foo<Int>
+
+extension FooInt {
+  func goodT() -> Int {
+    return maybeT!
+  }
+
+  func badT() -> Float {
+    return maybeT! // expected-error{{cannot convert return expression of type 'Int' to return type 'Float'}}
+  }
+}
+
+typealias FooIntBarFloatDouble = Foo<Int>.Bar<Float, Double>
+
+extension FooIntBarFloatDouble {
+  func goodT() -> Int {
+    return maybeT!
+  }
+  func goodU() -> Float {
+    return maybeU!
+  }
+  func goodV() -> Double {
+    return maybeV!
+  }
+
+  func badT() -> Float {
+    return maybeT! // expected-error{{cannot convert return expression of type 'Int' to return type 'Float'}}
+  }
+  func badU() -> Int {
+    return maybeU! // expected-error{{cannot convert return expression of type 'Float' to return type 'Int'}}
+  }
+  func badV() -> Int {
+    return maybeV! // expected-error{{cannot convert return expression of type 'Double' to return type 'Int'}}
+  }
+}
+
+typealias FooIntBarFloatDoubleInner = Foo<Int>.Bar<Float, Double>.Inner
+
+extension FooIntBarFloatDoubleInner {
+  func goodT() -> Int {
+    return maybeT!
+  }
+  func goodU() -> Float {
+    return maybeU!
+  }
+  func goodV() -> Double {
+    return maybeV!
+  }
+
+  func badT() -> Float {
+    return maybeT! // expected-error{{cannot convert return expression of type 'Int' to return type 'Float'}}
+  }
+  func badU() -> Int {
+    return maybeU! // expected-error{{cannot convert return expression of type 'Float' to return type 'Int'}}
+  }
+  func badV() -> Int {
+    return maybeV! // expected-error{{cannot convert return expression of type 'Double' to return type 'Int'}}
+  }
+}
+
diff --git a/test/decl/nested/type_in_type.swift b/test/decl/nested/type_in_type.swift
index 978408c..6543b11 100644
--- a/test/decl/nested/type_in_type.swift
+++ b/test/decl/nested/type_in_type.swift
@@ -298,9 +298,9 @@
   func takesAssocType(first: D, second: F) {}
 }
 
-typealias OuterGenericMidGeneric<T> = OuterGeneric<T>.MidGeneric
+typealias OuterGenericMidNonGeneric<T> = OuterGeneric<T>.MidNonGeneric
 
-extension OuterGenericMidGeneric {
+extension OuterGenericMidNonGeneric {
 
 }
 
diff --git a/test/decl/typealias/generic.swift b/test/decl/typealias/generic.swift
index 1821572..6fa96bd 100644
--- a/test/decl/typealias/generic.swift
+++ b/test/decl/typealias/generic.swift
@@ -1,6 +1,6 @@
 // RUN: %target-typecheck-verify-swift
 
-struct MyType<TyA, TyB> {
+struct MyType<TyA, TyB> { // expected-note {{generic type 'MyType' declared here}}
   var a : TyA, b : TyB
 }
 
@@ -105,6 +105,9 @@
 _ = G(a: "foo", b: 42)
 _ = G<Int, String>(a: "foo", b: 42)
 
+// Generic typealias cannot have unbound generic type.
+typealias VeryBad1<T> = MyType // expected-error {{reference to generic type 'MyType' requires arguments in <...>}}
+typealias VeryBad2<T> = Swift.Array // expected-error {{reference to generic type 'Array' requires arguments in <...>}}
 
 struct MyTypeWithHashable<TyA, TyB : Hashable> {
 }
diff --git a/test/multifile/Inputs/external_lazy_property.swift b/test/multifile/Inputs/external_lazy_property.swift
index 80d597b..2093a96 100644
--- a/test/multifile/Inputs/external_lazy_property.swift
+++ b/test/multifile/Inputs/external_lazy_property.swift
@@ -1,3 +1,12 @@
 public struct Test1 {
-    lazy var property: String = "help"
+  lazy var property: String = "help"
+}
+
+public class Test2 {
+  var x = 0
+  var y = 1
+
+  lazy var property = {
+    return [self.x, self.y]
+  }()
 }
diff --git a/test/multifile/lazy.swift b/test/multifile/lazy.swift
index b107ed7..9d7c478 100644
--- a/test/multifile/lazy.swift
+++ b/test/multifile/lazy.swift
@@ -1,6 +1,11 @@
 // RUN: %target-swift-frontend -emit-sil -verify -primary-file %s %S/Inputs/external_lazy_property.swift
+// RUN: %target-swift-frontend -emit-sil -verify -primary-file %s -primary-file %S/Inputs/external_lazy_property.swift
 
 // rdar://45712204
 func test1(s: Test1) {
-  s.property // expected-error {{cannot use mutating getter on immutable value: 's' is a 'let' constant}}
+  _ = s.property // expected-error {{cannot use mutating getter on immutable value: 's' is a 'let' constant}}
+}
+
+func test2(s: Test2) {
+  _ = s.property
 }
diff --git a/test/multifile/typealias/two-modules/main.swift b/test/multifile/typealias/two-modules/main.swift
index bcab552..a48c80a 100644
--- a/test/multifile/typealias/two-modules/main.swift
+++ b/test/multifile/typealias/two-modules/main.swift
@@ -10,6 +10,7 @@
 // RUN: %target-build-swift -g %S/main.swift %t/linker/library.o -I %t/linker/ -L %t/linker/ -o %t/linker/main
 
 import library
+import enum library.Result
 
 func testFunction<T>(withCompletion completion: (Result<T, Error>) -> Void) { }
 testFunction { (result: GenericResult<Int>) in }
diff --git a/test/stdlib/ErrorBridged.swift b/test/stdlib/ErrorBridged.swift
index 2d502e4..6a90d1c 100644
--- a/test/stdlib/ErrorBridged.swift
+++ b/test/stdlib/ErrorBridged.swift
@@ -70,6 +70,8 @@
   }
 }
 
+// Gated on the availability of NSKeyedArchiver.archivedData(withRootObject:).
+@available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)
 func archiveAndUnarchiveObject<T: NSCoding>(
   _ object: T
 ) -> T?
@@ -81,11 +83,13 @@
   return unarchiver.decodeObject(of: T.self, forKey: "root")
 }
 ErrorBridgingTests.test("NSCoding") {
-  autoreleasepool {
-    let orig = EnumError.ReallyBadError as NSError
-    let unarchived = archiveAndUnarchiveObject(orig)!
-    expectEqual(orig, unarchived)
-    expectTrue(type(of: unarchived) == NSError.self)
+  if #available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
+    autoreleasepool {
+      let orig = EnumError.ReallyBadError as NSError
+      let unarchived = archiveAndUnarchiveObject(orig)!
+      expectEqual(orig, unarchived)
+      expectTrue(type(of: unarchived) == NSError.self)
+    }
   }
 }
 
diff --git a/test/stdlib/Result.swift b/test/stdlib/Result.swift
new file mode 100644
index 0000000..d584f6c
--- /dev/null
+++ b/test/stdlib/Result.swift
@@ -0,0 +1,188 @@
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import Swift
+
+let ResultTests = TestSuite("Result")
+
+fileprivate enum Err: Error, Equatable {
+  case err
+  case derr
+}
+
+fileprivate let string = "string"
+
+fileprivate extension Result {
+  var success: Success? {
+    switch self {
+    case let .success(success):
+      return success
+    case .failure:
+      return nil
+    }
+  }
+  
+  var failure: Failure? {
+    switch self {
+    case .success:
+      return nil
+    case let .failure(failure):
+      return failure
+    }
+  }
+}
+
+ResultTests.test("Construction") {
+  let result1: Result<String, Err> = .success(string)
+  let result2: Result<String, Err> = .failure(.err)
+  let string1: String? = {
+    switch result1 {
+      case let .success(string): 
+        return string
+      case .failure: 
+        expectUnreachable()
+        return nil
+    }
+  }()
+  let error: Err? = {
+    switch result2 {
+      case let .failure(failure): 
+        return failure
+      case .success: 
+        expectUnreachable()
+        return nil
+    }
+  }()
+
+  expectEqual(string, string1)
+  expectEqual(.err, error)
+}
+
+ResultTests.test("Throwing Initialization and Unwrapping") {
+  func notThrowing() throws -> String {
+    return string
+  }
+
+  func throwing() throws -> String {
+    throw Err.err
+  }
+    
+  let result1 = Result { try throwing() }
+  let result2 = Result { try notThrowing() }
+  
+  expectEqual(result1.failure as? Err, Err.err)
+  expectEqual(result2.success, string)
+    
+  do {
+    _ = try result1.get()
+  } catch let error as Err {
+    expectEqual(error, Err.err)
+  } catch {
+    expectUnreachable()
+  }
+    
+  do {
+    let unwrapped = try result2.get()
+    expectEqual(unwrapped, string)
+  } catch {
+    expectUnreachable()
+  }
+    
+  // Test unwrapping strongly typed error.
+  let result3 = Result<String, Err>.failure(Err.err)
+  do {
+    _ = try result3.get()
+  } catch let error as Err {
+    expectEqual(error, Err.err)
+  } catch {
+    expectUnreachable()
+  }
+}
+
+ResultTests.test("Functional Transforms") {
+  func transformDouble(_ int: Int) -> Int {
+    return 2 * int
+  }
+  
+  func transformTriple(_ int: Int) -> Int {
+    return 3 * int
+  }
+  
+  func transformError(_ err: Err) -> Err {
+    if err == .err {
+      return .derr
+    } else {
+      return .err
+    }
+  }
+
+  func resultValueTransform(_ int: Int) -> Result<Int, Err> {
+    return .success(transformDouble(int))
+  }
+  
+  func resultErrorTransform(_ err: Err) -> Result<Int, Err> {
+    return .failure(transformError(err))
+  }
+    
+  let result1: Result<Int, Err> = .success(1)
+  let newResult1 = result1.map(transformDouble)
+    
+  expectEqual(newResult1, .success(2))
+    
+  let result2: Result<Int, Err> = .failure(.err)
+  let newResult2 = result2.mapError(transformError)
+    
+  expectEqual(newResult2, .failure(.derr))
+    
+  let result3: Result<Int, Err> = .success(1)
+  let newResult3 = result3.flatMap(resultValueTransform)
+    
+  expectEqual(newResult3, .success(2))
+    
+  let result4: Result<Int, Err> = .failure(.derr)
+  let newResult4 = result4.flatMapError(resultErrorTransform)
+    
+  expectEqual(newResult4, .failure(.err))
+}
+
+ResultTests.test("Equatable") {
+  let result1: Result<Int, Err> = .success(1)
+  let result2: Result<Int, Err> = .failure(.err)
+
+  expectEqual(result1, .success(1))
+  expectNotEqual(result1, .success(2))
+  expectNotEqual(result1, .failure(.err))
+  expectNotEqual(result1, .failure(.derr))
+
+  expectNotEqual(result2, .success(1))
+  expectNotEqual(result2, .success(2))
+  expectEqual(result2, .failure(.err))
+  expectNotEqual(result2, .failure(.derr))
+  
+  let confusables: [Result<Err, Err>] = [
+    .success(.err),
+    .success(.derr),
+    .failure(.err),
+    .failure(.derr)
+  ]
+  
+  checkEquatable(confusables, oracle: { $0 == $1 })
+}
+
+ResultTests.test("Hashable") {
+  let result1: Result<Int, Err> = .success(1)
+  let result2: Result<Int, Err> = .success(2)
+  let result3: Result<Int, Err> = .failure(.err)
+  checkHashable([result1, result2, result3], equalityOracle: { $0 == $1 })
+
+  let confusables: [Result<Err, Err>] = [
+    .success(.err),
+    .success(.derr),
+    .failure(.err),
+    .failure(.derr)
+  ]
+  checkHashable(confusables, equalityOracle: { $0 == $1 })
+}
+
+runAllTests()
diff --git a/test/stdlib/TestData.swift b/test/stdlib/TestData.swift
index 7b3d1e7..ec8606f 100644
--- a/test/stdlib/TestData.swift
+++ b/test/stdlib/TestData.swift
@@ -805,14 +805,6 @@
         object.verifier.reset()
         expectTrue(data.count == object.length)
         expectFalse(object.verifier.wasCopied, "Expected an invocation to copy")
-
-        object.verifier.reset()
-        data.append("test", count: 4)
-        expectTrue(object.verifier.wasMutableCopied, "Expected an invocation to mutableCopy")
-
-        let d = data as NSData
-        let preservedObjectness = d is ImmutableDataVerifier
-        expectTrue(preservedObjectness, "Expected ImmutableDataVerifier but got \(object_getClass(d))")
     }
 
     func test_basicMutableDataMutation() {
@@ -826,20 +818,6 @@
         object.verifier.reset()
         expectTrue(data.count == object.length)
         expectFalse(object.verifier.wasCopied, "Expected an invocation to copy")
-        
-        object.verifier.reset()
-        data.append("test", count: 4)
-        expectTrue(object.verifier.wasMutableCopied, "Expected an invocation to mutableCopy")
-        object.verifier.dump()
-
-        let d = data as NSData
-        let preservedObjectness = d is ImmutableDataVerifier
-        expectTrue(preservedObjectness, "Expected ImmutableDataVerifier but got \(object_getClass(d))")
-    }
-
-    func test_roundTrip() {
-        let data = returnsData()
-        expectTrue(identityOfData(data))
     }
 
     func test_passing() {
@@ -966,12 +944,13 @@
     }
 
     func test_noCopyBehavior() {
-        let ptr = UnsafeMutableRawPointer(bitPattern: 0x1)!
+        let ptr = UnsafeMutableRawPointer.allocate(byteCount: 17, alignment: 1)
         
         var deallocated = false
         autoreleasepool {
-            let data = Data(bytesNoCopy: ptr, count: 1, deallocator: .custom({ (bytes, length) in
+            let data = Data(bytesNoCopy: ptr, count: 17, deallocator: .custom({ (bytes, length) in
                 deallocated = true
+                ptr.deallocate()
             }))
             expectFalse(deallocated)
             let equal = data.withUnsafeBytes { (bytes: UnsafePointer<UInt8>) -> Bool in
@@ -980,7 +959,6 @@
             
             expectTrue(equal)
         }
-        
         expectTrue(deallocated)
     }
 
@@ -1013,10 +991,6 @@
         for i in 0..<d.count {
             for j in i..<d.count {
                 let slice = d[i..<j]
-                if i == 1 && j == 2 {
-                    print("here")
-                    
-                }
                 expectEqual(slice.count, j - i, "where index range is \(i)..<\(j)")
                 expectEqual(slice.map { $0 }, a[i..<j].map { $0 }, "where index range is \(i)..<\(j)")
                 expectEqual(slice.startIndex, i, "where index range is \(i)..<\(j)")
@@ -3641,28 +3615,6 @@
         expectEqual(data, Data(bytes: [4, 5, 6, 7, 0, 0]))
     }
 
-    func test_sliceEnumeration() {
-        var base = DispatchData.empty
-        let bytes: [UInt8] = [0, 1, 2, 3, 4]
-        base.append(bytes.withUnsafeBytes { DispatchData(bytes: $0) })
-        base.append(bytes.withUnsafeBytes { DispatchData(bytes: $0) })
-        base.append(bytes.withUnsafeBytes { DispatchData(bytes: $0) })
-        let data = ((base as AnyObject) as! Data)[3..<11]
-        var regionRanges: [Range<Int>] = []
-        var regionData: [Data] = []
-        data.enumerateBytes { (buffer, index, _) in
-            regionData.append(Data(bytes: buffer.baseAddress!, count: buffer.count))
-            regionRanges.append(index..<index + buffer.count)
-        }
-        expectEqual(regionRanges.count, 3)
-        expectEqual(3..<5, regionRanges[0])
-        expectEqual(5..<10, regionRanges[1])
-        expectEqual(10..<11, regionRanges[2])
-        expectEqual(Data(bytes: [3, 4]), regionData[0]) //fails
-        expectEqual(Data(bytes: [0, 1, 2, 3, 4]), regionData[1]) //passes
-        expectEqual(Data(bytes: [0]), regionData[2]) //fails
-    }
-
     func test_hashEmptyData() {
         let d1 = Data()
         let h1 = d1.hashValue
@@ -3783,7 +3735,6 @@
 DataTests.test("test_genericBuffers") { TestData().test_genericBuffers() }
 DataTests.test("test_basicDataMutation") { TestData().test_basicDataMutation() }
 DataTests.test("test_basicMutableDataMutation") { TestData().test_basicMutableDataMutation() }
-DataTests.test("test_roundTrip") { TestData().test_roundTrip() }
 DataTests.test("test_passing") { TestData().test_passing() }
 DataTests.test("test_bufferSizeCalculation") { TestData().test_bufferSizeCalculation() }
 DataTests.test("test_classForCoder") { TestData().test_classForCoder() }
@@ -4056,7 +4007,6 @@
 DataTests.test("test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithBytes") { TestData().test_validateMutation_slice_cow_customMutableBacking_replaceSubrangeWithBytes() }
 DataTests.test("test_sliceHash") { TestData().test_sliceHash() }
 DataTests.test("test_slice_resize_growth") { TestData().test_slice_resize_growth() }
-DataTests.test("test_sliceEnumeration") { TestData().test_sliceEnumeration() }
 DataTests.test("test_hashEmptyData") { TestData().test_hashEmptyData() }
 DataTests.test("test_validateMutation_slice_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_withUnsafeMutableBytes_lengthLessThanLowerBound() }
 DataTests.test("test_validateMutation_slice_immutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound") { TestData().test_validateMutation_slice_immutableBacking_withUnsafeMutableBytes_lengthLessThanLowerBound() }
diff --git a/test/stdlib/TestUserInfo.swift b/test/stdlib/TestUserInfo.swift
index 2c2df74..272962e 100644
--- a/test/stdlib/TestUserInfo.swift
+++ b/test/stdlib/TestUserInfo.swift
@@ -130,12 +130,16 @@
     func test_classForCoder() {
         // confirm internal bridged impl types are not exposed to archival machinery
         // we have to be circuitous here, as bridging makes it very difficult to confirm this
-        let note = Notification(name: Notification.Name(rawValue: "TestSwiftNotification"), userInfo: [AnyHashable("key"):"value"])
-        let archivedNote = NSKeyedArchiver.archivedData(withRootObject: note)
-        let noteAsPlist = try! PropertyListSerialization.propertyList(from: archivedNote, options: [], format: nil)
-        let plistAsData = try! PropertyListSerialization.data(fromPropertyList: noteAsPlist, format: .xml, options: 0)
-        let xml = NSString(data: plistAsData, encoding: String.Encoding.utf8.rawValue)!
-        expectEqual(xml.range(of: "_NSUserInfoDictionary").location, NSNotFound)
+        //
+        // Gated on the availability of NSKeyedArchiver.archivedData(withRootObject:).
+        if #available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *) {
+            let note = Notification(name: Notification.Name(rawValue: "TestSwiftNotification"), userInfo: [AnyHashable("key"):"value"])
+            let archivedNote = NSKeyedArchiver.archivedData(withRootObject: note)
+            let noteAsPlist = try! PropertyListSerialization.propertyList(from: archivedNote, options: [], format: nil)
+            let plistAsData = try! PropertyListSerialization.data(fromPropertyList: noteAsPlist, format: .xml, options: 0)
+            let xml = NSString(data: plistAsData, encoding: String.Encoding.utf8.rawValue)!
+            expectEqual(xml.range(of: "_NSUserInfoDictionary").location, NSNotFound)
+        }
     }
 
     func test_AnyHashableContainingNotification() {
diff --git a/test/stdlib/simd.swift.gyb b/test/stdlib/simd.swift.gyb
index afadc16..84bedf3 100644
--- a/test/stdlib/simd.swift.gyb
+++ b/test/stdlib/simd.swift.gyb
@@ -313,5 +313,10 @@
 % end # for type
 }
 
+simdTestSuite.test("debug description") {
+  expectEqual("SIMD2<Float>(1.0, 2.5)",
+    SIMD2<Float>(1.0, 2.5).debugDescription)
+}
+
 runAllTests()
 
diff --git a/validation-test/Sema/type_checker_perf/fast/rdar21720888.swift.gyb b/validation-test/Sema/type_checker_perf/fast/rdar21720888.swift.gyb
index 89bcfbb..6d90e69 100644
--- a/validation-test/Sema/type_checker_perf/fast/rdar21720888.swift.gyb
+++ b/validation-test/Sema/type_checker_perf/fast/rdar21720888.swift.gyb
@@ -4,6 +4,6 @@
 
 _ = [
 %for i in range(0, N):
-  (label: "string"),
+  (label: "string", another: 123),
 %end
 ]
diff --git a/validation-test/Sema/type_checker_perf/slow/sr139.swift b/validation-test/Sema/type_checker_perf/slow/sr139.swift
new file mode 100644
index 0000000..f783409
--- /dev/null
+++ b/validation-test/Sema/type_checker_perf/slow/sr139.swift
@@ -0,0 +1,6 @@
+// RUN: %target-typecheck-verify-swift
+
+// SR-139:
+// Infinite recursion parsing bitwise operators
+let x = UInt32(0x1FF)&0xFF << 24 | UInt32(0x1FF)&0xFF << 16 | UInt32(0x1FF)&0xFF << 8 | (UInt32(0x1FF)&0xFF);  // expected-error {{reasonable time}}
+
diff --git a/validation-test/compiler_crashers_2_fixed/0186-rdar46497155.swift b/validation-test/compiler_crashers_2_fixed/0186-rdar46497155.swift
new file mode 100644
index 0000000..ed07326
--- /dev/null
+++ b/validation-test/compiler_crashers_2_fixed/0186-rdar46497155.swift
@@ -0,0 +1,32 @@
+// RUN: %target-typecheck-verify-swift
+
+protocol P {
+  func isEqual(_ other: P) -> Bool
+}
+
+struct A {
+  var value: P? = nil
+}
+
+struct B {
+  func foo() throws -> A {}
+}
+
+struct E {
+  func getB(_ flag: inout Bool) throws -> B {
+    return B()
+  }
+}
+
+func foo(arr: [E], other: P) -> Bool {
+  return arr.compactMap { i in
+    // expected-error@-1 {{unable to infer complex closure return type; add explicit type to disambiguate}} {{29-29=-> B? }}
+    var flag = false
+    return try? i.getB(&flag)
+  }.compactMap { u -> P? in
+    guard let a = try? u.foo() else { return nil }
+    return a.value!
+  }.contains {
+    $0.isEqual(other)
+  }
+}
diff --git a/validation-test/compiler_crashers_fixed/28815-formprotocolrelativetype-swift-protocoldecl-swift-genericsignaturebuilder-potent.swift b/validation-test/compiler_crashers_fixed/28815-formprotocolrelativetype-swift-protocoldecl-swift-genericsignaturebuilder-potent.swift
index 2941688..92e41c1 100644
--- a/validation-test/compiler_crashers_fixed/28815-formprotocolrelativetype-swift-protocoldecl-swift-genericsignaturebuilder-potent.swift
+++ b/validation-test/compiler_crashers_fixed/28815-formprotocolrelativetype-swift-protocoldecl-swift-genericsignaturebuilder-potent.swift
@@ -6,5 +6,8 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 
 // RUN: not %target-swift-frontend %s -emit-ir
+
+// XFAIL: *
+
 extension CountableRange{{}{}protocol P{typealias a:A{}func 丏
 protocol A:CountableRange