Merge pull request #4079 from practicalswift/swiftc-28388-swift-typebase-getcanonicaltype

[swiftc (41 vs. 5156)] Add crasher in swift::TypeBase::getCanonicalType(...)
diff --git a/docs/Testing.rst b/docs/Testing.rst
index aadea8e..75f3474 100644
--- a/docs/Testing.rst
+++ b/docs/Testing.rst
@@ -273,7 +273,7 @@
   ``armv7``, ``armv7k``, ``arm64``).
 
 * ``%target-os``: the target operating system (``macosx``, ``darwin``,
-  ``linux``, ``freebsd``).
+  ``linux``, ``freebsd``, ``windows-cygnus``, ``windows-gnu``).
 
 * ``%target-object-format``: the platform's object format (``elf``, ``macho``,
   ``coff``).
diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def
index 66e3fd7..ae0d379 100644
--- a/include/swift/AST/DiagnosticsSema.def
+++ b/include/swift/AST/DiagnosticsSema.def
@@ -78,6 +78,9 @@
 NOTE(did_you_mean_raw_type,none,
      "did you mean to specify a raw type on the enum declaration?", ())
 
+NOTE(any_as_anyobject_fixit, none,
+     "cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members", ())
+
 ERROR(expected_argument_in_contextual_member,none,
       "contextual member %0 expects argument of type %1", (DeclName, Type))
 
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 294b0b1..14a443a 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -1316,7 +1316,8 @@
   if (OI.shouldLink() && !AllLinkerInputs.empty()) {
     auto *LinkAction = new LinkJobAction(AllLinkerInputs, OI.LinkAction);
 
-    if (TC.getTriple().getObjectFormat() == llvm::Triple::ELF) {
+    if (TC.getTriple().getObjectFormat() == llvm::Triple::ELF ||
+        TC.getTriple().isOSCygMing()) {
       // On ELF platforms there's no built in autolinking mechanism, so we
       // pull the info we need from the .o files directly and pass them as an
       // argument input file to the linker.
diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp
index 41d6b52..ea63bec 100644
--- a/lib/Sema/CSDiag.cpp
+++ b/lib/Sema/CSDiag.cpp
@@ -2523,6 +2523,14 @@
           diagnose(loc, diag::did_you_mean_raw_type);
           return; // Always prefer this over typo corrections.
         }
+      } else if (baseObjTy->isAny()) {
+        if (auto DRE = dyn_cast<DeclRefExpr>(baseExpr)) {
+          auto name = DRE->getDecl()->getName().str().str();
+          std::string replacement = "(" + name + " as AnyObject)";
+          diagnose(loc, diag::any_as_anyobject_fixit)
+            .fixItReplace(baseExpr->getSourceRange(), replacement);
+          return;
+        }
       }
     }
 
diff --git a/stdlib/private/StdlibUnittest/CMakeLists.txt b/stdlib/private/StdlibUnittest/CMakeLists.txt
index 2eb32e9..e18d39f 100644
--- a/stdlib/private/StdlibUnittest/CMakeLists.txt
+++ b/stdlib/private/StdlibUnittest/CMakeLists.txt
@@ -15,6 +15,7 @@
   # filename.
   StdlibUnittest.swift.gyb
 
+  CheckStrideable.swift.gyb
   InspectValue.cpp
   InspectValue.swift
   InterceptTraps.cpp
diff --git a/stdlib/private/StdlibUnittest/CheckStrideable.swift.gyb b/stdlib/private/StdlibUnittest/CheckStrideable.swift.gyb
new file mode 100644
index 0000000..fbbe590
--- /dev/null
+++ b/stdlib/private/StdlibUnittest/CheckStrideable.swift.gyb
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See http://swift.org/LICENSE.txt for license information
+// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+//===----------------------------------------------------------------------===//
+
+%{
+from gyb_stdlib_unittest_support import TRACE, stackTrace, trace
+}%
+
+public func checkStrideable<S : Strideable>(
+  instances: [S],
+  distances: [S.Stride],
+  distanceOracle: (Int, Int) -> S.Stride,
+  ${TRACE}
+) {
+  for i in instances.indices {
+    let first = instances[i]
+    for j in instances.indices {
+      let second = instances[j]
+      expectEqual(distanceOracle(i, j), first.distance(to: second))
+      expectEqual(second, first.advanced(by: distanceOracle(i, j)))
+    }
+  }
+}
+
diff --git a/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb b/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb
index ba3731d..05d87c1 100644
--- a/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb
+++ b/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb
@@ -150,6 +150,14 @@
   expectEqualTest(expected.2, actual.2, ${trace}, showFrame: false) {$0 == $1}
 }
 
+public func expectEqual<T : Equatable, U : Equatable, V : Equatable, W : Equatable>(
+  _ expected: (T, U, V, W), _ actual: (T, U, V, W), ${TRACE}) {
+  expectEqualTest(expected.0, actual.0, ${trace}, showFrame: false) {$0 == $1}
+  expectEqualTest(expected.1, actual.1, ${trace}, showFrame: false) {$0 == $1}
+  expectEqualTest(expected.2, actual.2, ${trace}, showFrame: false) {$0 == $1}
+  expectEqualTest(expected.3, actual.3, ${trace}, showFrame: false) {$0 == $1}
+}
+
 public func expectationFailure(
   _ reason: String,
   trace message: String,
diff --git a/stdlib/private/StdlibUnittestFoundationExtras/StdlibUnittestFoundationExtras.swift b/stdlib/private/StdlibUnittestFoundationExtras/StdlibUnittestFoundationExtras.swift
index 2cc4380..4337546 100644
--- a/stdlib/private/StdlibUnittestFoundationExtras/StdlibUnittestFoundationExtras.swift
+++ b/stdlib/private/StdlibUnittestFoundationExtras/StdlibUnittestFoundationExtras.swift
@@ -82,6 +82,7 @@
   rangeLength: Int)
 
 extension NSArray {
+  @nonobjc // FIXME: there should be no need in this attribute.
   public func available_getObjects(
     _ objects: AutoreleasingUnsafeMutablePointer<AnyObject?>?, range: NSRange
   ) {
@@ -101,6 +102,7 @@
 )
 
 extension NSDictionary {
+  @nonobjc // FIXME: there should be no need in this attribute.
   public func available_getObjects(
     _ objects: AutoreleasingUnsafeMutablePointer<AnyObject?>?,
     andKeys keys: AutoreleasingUnsafeMutablePointer<AnyObject?>?
diff --git a/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift b/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift
index cb79880..607199e 100644
--- a/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift
+++ b/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift
@@ -21,7 +21,7 @@
   }
 
   public func distance(to other: String.UTF16View.Index) -> Int {
-    return other._offset.distance(to: _offset)
+    return _offset.distance(to: other._offset)
   }
 
   public func advanced(by n: Int) -> String.UTF16View.Index {
diff --git a/stdlib/public/SDK/Foundation/Foundation.swift b/stdlib/public/SDK/Foundation/Foundation.swift
index d06016a..bfd1ffe 100644
--- a/stdlib/public/SDK/Foundation/Foundation.swift
+++ b/stdlib/public/SDK/Foundation/Foundation.swift
@@ -501,7 +501,7 @@
 
   @_semantics("convertToObjectiveC")
   public func _bridgeToObjectiveC() -> NSArray {
-    return unsafeBitCast(self._buffer._asCocoaArray() as AnyObject, to: NSArray.self)
+    return unsafeBitCast(self._bridgeToObjectiveCImpl(), to: NSArray.self)
   }
 
   public static func _forceBridgeFromObjectiveC(
diff --git a/stdlib/public/core/ArrayBuffer.swift b/stdlib/public/core/ArrayBuffer.swift
index 82b31e8..4ec63b9 100644
--- a/stdlib/public/core/ArrayBuffer.swift
+++ b/stdlib/public/core/ArrayBuffer.swift
@@ -22,14 +22,14 @@
   = _BridgeStorage<_ContiguousArrayStorageBase, _NSArrayCore>
 
 @_fixed_layout
-public struct _ArrayBuffer<Element> : _ArrayBufferProtocol {
+internal struct _ArrayBuffer<Element> : _ArrayBufferProtocol {
 
   /// Create an empty buffer.
-  public init() {
+  internal init() {
     _storage = _ArrayBridgeStorage(native: _emptyArrayStorage)
   }
 
-  public init(nsArray: _NSArrayCore) {
+  internal init(nsArray: _NSArrayCore) {
     _sanityCheck(_isClassOrObjCExistential(Element.self))
     _storage = _ArrayBridgeStorage(objC: nsArray)
   }
@@ -46,7 +46,7 @@
 
   /// The spare bits that are set when a native array needs deferred
   /// element type checking.
-  var deferredTypeCheckMask: Int { return 1 }
+  internal var deferredTypeCheckMask: Int { return 1 }
   
   /// Returns an `_ArrayBuffer<U>` containing the same elements,
   /// deferring checking each element's `U`-ness until it is accessed.
@@ -68,7 +68,7 @@
         native: _native._storage, bits: deferredTypeCheckMask))
   }
 
-  var needsElementTypeCheck: Bool {
+  internal var needsElementTypeCheck: Bool {
     // NSArray's need an element typecheck when the element type isn't AnyObject
     return !_isNativeTypeChecked && !(AnyObject.self is Element.Type)
   }
@@ -83,18 +83,18 @@
 
 extension _ArrayBuffer {
   /// Adopt the storage of `source`.
-  public init(_ source: NativeBuffer, shiftedToStartIndex: Int) {
+  internal init(_buffer source: NativeBuffer, shiftedToStartIndex: Int) {
     _sanityCheck(shiftedToStartIndex == 0, "shiftedToStartIndex must be 0")
     _storage = _ArrayBridgeStorage(native: source._storage)
   }
 
   /// `true`, if the array is native and does not need a deferred type check.
-  var arrayPropertyIsNativeTypeChecked: Bool {
+  internal var arrayPropertyIsNativeTypeChecked: Bool {
     return _isNativeTypeChecked
   }
 
   /// Returns `true` iff this buffer's storage is uniquely-referenced.
-  mutating func isUniquelyReferenced() -> Bool {
+  internal mutating func isUniquelyReferenced() -> Bool {
     if !_isClassOrObjCExistential(Element.self) {
       return _storage.isUniquelyReferenced_native_noSpareBits()
     }
@@ -103,7 +103,7 @@
 
   /// Returns `true` iff this buffer's storage is either
   /// uniquely-referenced or pinned.
-  mutating func isUniquelyReferencedOrPinned() -> Bool {
+  internal mutating func isUniquelyReferencedOrPinned() -> Bool {
     if !_isClassOrObjCExistential(Element.self) {
       return _storage.isUniquelyReferencedOrPinned_native_noSpareBits()
     }
@@ -113,7 +113,7 @@
   /// Convert to an NSArray.
   ///
   /// O(1) if the element type is bridged verbatim, O(N) otherwise.
-  public func _asCocoaArray() -> _NSArrayCore {
+  internal func _asCocoaArray() -> _NSArrayCore {
     return _fastPath(_isNative) ? _native._asCocoaArray() : _nonNative
   }
 
@@ -121,7 +121,7 @@
   /// `_ContiguousArrayBuffer` that can be grown in-place to allow the self
   /// buffer store minimumCapacity elements, returns that buffer.
   /// Otherwise, returns `nil`.
-  public mutating func requestUniqueMutableBackingBuffer(minimumCapacity: Int)
+  internal mutating func requestUniqueMutableBackingBuffer(minimumCapacity: Int)
   -> NativeBuffer? {
     if _fastPath(isUniquelyReferenced()) {
       let b = _native
@@ -132,18 +132,18 @@
     return nil
   }
 
-  public mutating func isMutableAndUniquelyReferenced() -> Bool {
+  internal mutating func isMutableAndUniquelyReferenced() -> Bool {
     return isUniquelyReferenced()
   }
 
-  public mutating func isMutableAndUniquelyReferencedOrPinned() -> Bool {
+  internal mutating func isMutableAndUniquelyReferencedOrPinned() -> Bool {
     return isUniquelyReferencedOrPinned()
   }
 
   /// If this buffer is backed by a `_ContiguousArrayBuffer`
   /// containing the same number of elements as `self`, return it.
   /// Otherwise, return `nil`.
-  public func requestNativeBuffer() -> NativeBuffer? {
+  internal func requestNativeBuffer() -> NativeBuffer? {
     if !_isClassOrObjCExistential(Element.self) {
       return _native
     }
@@ -170,7 +170,7 @@
     }
   }
 
-  func _typeCheck(_ subRange: Range<Int>) {
+  internal func _typeCheck(_ subRange: Range<Int>) {
     if !_isClassOrObjCExistential(Element.self) {
       return
     }
@@ -189,7 +189,7 @@
   /// memory starting at `target`.  Return a pointer "past the end" of the
   /// just-initialized memory.
   @discardableResult
-  public func _copyContents(
+  internal func _copyContents(
     subRange bounds: Range<Int>,
     initializing target: UnsafeMutablePointer<Element>
   ) -> UnsafeMutablePointer<Element> {
@@ -221,7 +221,7 @@
 
   /// Returns a `_SliceBuffer` containing the given sub-range of elements in
   /// `bounds` from this buffer.
-  public subscript(bounds: Range<Int>) -> _SliceBuffer<Element> {
+  internal subscript(bounds: Range<Int>) -> _SliceBuffer<Element> {
     get {
       _typeCheck(bounds)
 
@@ -232,7 +232,7 @@
       let boundsCount = bounds.count
       if boundsCount == 0 {
         return _SliceBuffer(
-          _ContiguousArrayBuffer<Element>(),
+          _buffer: _ContiguousArrayBuffer<Element>(),
           shiftedToStartIndex: bounds.lowerBound)
       }
 
@@ -254,7 +254,7 @@
 
       // No contiguous storage found; we must allocate
       let result = _ContiguousArrayBuffer<Element>(
-        uninitializedCount: boundsCount, minimumCapacity: 0)
+        _uninitializedCount: boundsCount, minimumCapacity: 0)
 
       // Tell Cocoa to copy the objects into our storage
       cocoa.buffer.getObjects(
@@ -262,7 +262,8 @@
           .assumingMemoryBound(to: AnyObject.self),
         range: _SwiftNSRange(location: bounds.lowerBound, length: boundsCount))
 
-      return _SliceBuffer(result, shiftedToStartIndex: bounds.lowerBound)
+      return _SliceBuffer(
+        _buffer: result, shiftedToStartIndex: bounds.lowerBound)
     }
     set {
       fatalError("not implemented")
@@ -272,17 +273,17 @@
   /// A pointer to the first element.
   ///
   /// - Precondition: The elements are known to be stored contiguously.
-  public var firstElementAddress: UnsafeMutablePointer<Element> {
+  internal var firstElementAddress: UnsafeMutablePointer<Element> {
     _sanityCheck(_isNative, "must be a native buffer")
     return _native.firstElementAddress
   }
 
-  public var firstElementAddressIfContiguous: UnsafeMutablePointer<Element>? {
+  internal var firstElementAddressIfContiguous: UnsafeMutablePointer<Element>? {
     return _fastPath(_isNative) ? firstElementAddress : nil
   }
 
   /// The number of elements the buffer stores.
-  public var count: Int {
+  internal var count: Int {
     @inline(__always)
     get {
       return _fastPath(_isNative) ? _native.count : _nonNative.count
@@ -330,13 +331,13 @@
   }
 
   /// The number of elements the buffer can store without reallocation.
-  public var capacity: Int {
+  internal var capacity: Int {
     return _fastPath(_isNative) ? _native.capacity : _nonNative.count
   }
 
   @_versioned
   @inline(__always)
-  func getElement(_ i: Int, wasNativeTypeChecked: Bool) -> Element {
+  internal func getElement(_ i: Int, wasNativeTypeChecked: Bool) -> Element {
     if _fastPath(wasNativeTypeChecked) {
       return _nativeTypeChecked[i]
     }
@@ -345,7 +346,7 @@
 
   @_versioned
   @inline(never)
-  func _getElementSlowPath(_ i: Int) -> AnyObject {
+  internal func _getElementSlowPath(_ i: Int) -> AnyObject {
     _sanityCheck(
       _isClassOrObjCExistential(Element.self),
       "Only single reference elements can be indexed here.")
@@ -371,7 +372,7 @@
   }
 
   /// Get or set the value of the ith element.
-  public subscript(i: Int) -> Element {
+  internal subscript(i: Int) -> Element {
     get {
       return getElement(i, wasNativeTypeChecked: _isNativeTypeChecked)
     }
@@ -393,7 +394,7 @@
   /// Call `body(p)`, where `p` is an `UnsafeBufferPointer` over the
   /// underlying contiguous storage.  If no such storage exists, it is
   /// created on-demand.
-  public func withUnsafeBufferPointer<R>(
+  internal func withUnsafeBufferPointer<R>(
     _ body: (UnsafeBufferPointer<Element>) throws -> R
   ) rethrows -> R {
     if _fastPath(_isNative) {
@@ -408,7 +409,7 @@
   /// over the underlying contiguous storage.
   ///
   /// - Precondition: Such contiguous storage exists or the buffer is empty.
-  public mutating func withUnsafeMutableBufferPointer<R>(
+  internal mutating func withUnsafeMutableBufferPointer<R>(
     _ body: (UnsafeMutableBufferPointer<Element>) throws -> R
   ) rethrows -> R {
     _sanityCheck(
@@ -421,14 +422,14 @@
   }
   
   /// An object that keeps the elements stored in this buffer alive.
-  public var owner: AnyObject {
+  internal var owner: AnyObject {
     return _fastPath(_isNative) ? _native._storage : _nonNative
   }
   
   /// An object that keeps the elements stored in this buffer alive.
   ///
   /// - Precondition: This buffer is backed by a `_ContiguousArrayBuffer`.
-  public var nativeOwner: AnyObject {
+  internal var nativeOwner: AnyObject {
     _sanityCheck(_isNative, "Expect a native array")
     return _native._storage
   }
@@ -436,7 +437,7 @@
   /// A value that identifies the storage used by the buffer.  Two
   /// buffers address the same elements when they have the same
   /// identity and count.
-  public var identity: UnsafeRawPointer {
+  internal var identity: UnsafeRawPointer {
     if _isNative {
       return _native.identity
     }
@@ -449,7 +450,7 @@
   /// The position of the first element in a non-empty collection.
   ///
   /// In an empty collection, `startIndex == endIndex`.
-  public var startIndex: Int {
+  internal var startIndex: Int {
     return 0
   }
 
@@ -458,18 +459,18 @@
   /// `endIndex` is not a valid argument to `subscript`, and is always
   /// reachable from `startIndex` by zero or more applications of
   /// `index(after:)`.
-  public var endIndex: Int {
+  internal var endIndex: Int {
     return count
   }
 
-  public typealias Indices = CountableRange<Int>
+  internal typealias Indices = CountableRange<Int>
 
   //===--- private --------------------------------------------------------===//
-  typealias Storage = _ContiguousArrayStorage<Element>
-  public typealias NativeBuffer = _ContiguousArrayBuffer<Element>
+  internal typealias Storage = _ContiguousArrayStorage<Element>
+  internal typealias NativeBuffer = _ContiguousArrayBuffer<Element>
 
   @_versioned
-  var _isNative: Bool {
+  internal var _isNative: Bool {
     if !_isClassOrObjCExistential(Element.self) {
       return true
     } else {
@@ -478,7 +479,7 @@
   }
 
   /// `true`, if the array is native and does not need a deferred type check.
-  var _isNativeTypeChecked: Bool {
+  internal var _isNativeTypeChecked: Bool {
     if !_isClassOrObjCExistential(Element.self) {
       return true
     } else {
@@ -490,7 +491,7 @@
   ///
   /// - Precondition: `_isNative`.
   @_versioned
-  var _native: NativeBuffer {
+  internal var _native: NativeBuffer {
     return NativeBuffer(
       _isClassOrObjCExistential(Element.self)
       ? _storage.nativeInstance : _storage.nativeInstance_noSpareBits)
@@ -500,12 +501,12 @@
   ///
   /// - Precondition: `_isNativeTypeChecked`.
   @_versioned
-  var _nativeTypeChecked: NativeBuffer {
+  internal var _nativeTypeChecked: NativeBuffer {
     return NativeBuffer(_storage.nativeInstance_noSpareBits)
   }
 
   @_versioned
-  var _nonNative: _NSArrayCore {
+  internal var _nonNative: _NSArrayCore {
     @inline(__always)
     get {
       _sanityCheck(_isClassOrObjCExistential(Element.self))
diff --git a/stdlib/public/core/ArrayBufferProtocol.swift b/stdlib/public/core/ArrayBufferProtocol.swift
index 5cd21fd..6bfef6f 100644
--- a/stdlib/public/core/ArrayBufferProtocol.swift
+++ b/stdlib/public/core/ArrayBufferProtocol.swift
@@ -12,7 +12,7 @@
 
 /// The underlying buffer for an ArrayType conforms to
 /// `_ArrayBufferProtocol`.  This buffer does not provide value semantics.
-public protocol _ArrayBufferProtocol
+internal protocol _ArrayBufferProtocol
   : MutableCollection, RandomAccessCollection {
 
   associatedtype Indices : RandomAccessCollection = CountableRange<Int>
@@ -24,7 +24,7 @@
   init()
 
   /// Adopt the entire buffer, presenting it at the provided `startIndex`.
-  init(_ buffer: _ContiguousArrayBuffer<Element>, shiftedToStartIndex: Int)
+  init(_buffer: _ContiguousArrayBuffer<Element>, shiftedToStartIndex: Int)
 
   /// Copy the elements in `bounds` from this buffer into uninitialized
   /// memory starting at `target`.  Return a pointer "past the end" of the
@@ -127,11 +127,11 @@
 
 extension _ArrayBufferProtocol where Index == Int {
 
-  public var subscriptBaseAddress: UnsafeMutablePointer<Element> {
+  internal var subscriptBaseAddress: UnsafeMutablePointer<Element> {
     return firstElementAddress
   }
 
-  public mutating func replace<C>(
+  internal mutating func replace<C>(
     subRange: Range<Int>,
     with newCount: Int,
     elementsOf newValues: C
diff --git a/stdlib/public/core/ArrayType.swift b/stdlib/public/core/ArrayType.swift
index ee2ca36..fa73850 100644
--- a/stdlib/public/core/ArrayType.swift
+++ b/stdlib/public/core/ArrayType.swift
@@ -10,8 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-public // @testable
-protocol _ArrayProtocol
+internal protocol _ArrayProtocol
   : RangeReplaceableCollection,
     ExpressibleByArrayLiteral
 {
diff --git a/stdlib/public/core/Arrays.swift.gyb b/stdlib/public/core/Arrays.swift.gyb
index d2e00a4..4913744 100644
--- a/stdlib/public/core/Arrays.swift.gyb
+++ b/stdlib/public/core/Arrays.swift.gyb
@@ -782,11 +782,12 @@
   // FIXME(ABI): move to an initializer on _Buffer.
   static internal func _copyBuffer(_ buffer: inout _Buffer) {
     let newBuffer = _ContiguousArrayBuffer<Element>(
-      uninitializedCount: buffer.count, minimumCapacity: buffer.count)
+      _uninitializedCount: buffer.count, minimumCapacity: buffer.count)
     buffer._copyContents(
       subRange: Range(buffer.indices),
       initializing: newBuffer.firstElementAddress)
-    buffer = _Buffer(newBuffer, shiftedToStartIndex: buffer.startIndex)
+    buffer = _Buffer(
+      _buffer: newBuffer, shiftedToStartIndex: buffer.startIndex)
   }
 
   @_semantics("array.make_mutable")
@@ -864,33 +865,32 @@
 
 %if Self == 'Array':
 #if _runtime(_ObjC)
-  public typealias _Buffer = _ArrayBuffer<Element>
+  internal typealias _Buffer = _ArrayBuffer<Element>
 #else
-  public typealias _Buffer = _ContiguousArrayBuffer<Element>
+  internal typealias _Buffer = _ContiguousArrayBuffer<Element>
 #endif
 %elif Self == 'ArraySlice':
-  public typealias _Buffer = _SliceBuffer<Element>
+  internal typealias _Buffer = _SliceBuffer<Element>
 %else:
-  public typealias _Buffer = _${Self.strip('_')}Buffer<Element>
+  internal typealias _Buffer = _${Self.strip('_')}Buffer<Element>
 %end
 
   /// Initialization from an existing buffer does not have "array.init"
   /// semantics because the caller may retain an alias to buffer.
-  public // @testable
-  init(_buffer: _Buffer) {
+  internal init(_buffer: _Buffer) {
     self._buffer = _buffer
   }
 
 %if Self == 'ArraySlice':
   /// Initialization from an existing buffer does not have "array.init"
   /// semantics because the caller may retain an alias to buffer.
-  public // @testable
-  init(_buffer: _ContiguousArrayBuffer<Element>) {
-    self.init(_buffer: _Buffer(_buffer, shiftedToStartIndex: 0))
+  internal init(_buffer buffer: _ContiguousArrayBuffer<Element>) {
+    self.init(_buffer: _Buffer(_buffer: buffer, shiftedToStartIndex: 0))
   }
 %end
 
-  public var _buffer: _Buffer
+  @_versioned
+  internal var _buffer: _Buffer
 }
 
 extension ${Self} : ExpressibleByArrayLiteral {
@@ -1031,7 +1031,7 @@
 
     self = ${Self}(
       _buffer: _Buffer(
-        s._copyToContiguousArray()._buffer,
+        _buffer: s._copyToContiguousArray()._buffer,
         shiftedToStartIndex: 0))
   }
 
@@ -1064,8 +1064,8 @@
     minimumCapacity: Int
   ) -> _Buffer {
     let newBuffer = _ContiguousArrayBuffer<Element>(
-      uninitializedCount: 0, minimumCapacity: minimumCapacity)
-    return _Buffer(newBuffer, shiftedToStartIndex: 0)
+      _uninitializedCount: 0, minimumCapacity: minimumCapacity)
+    return _Buffer(_buffer: newBuffer, shiftedToStartIndex: 0)
   }
 
   /// Construct a ${Self} of `count` uninitialized elements.
@@ -1118,7 +1118,8 @@
         storage, to: _ContiguousArrayStorage<Element>.self))
     
     return (
-      Array(_buffer: _Buffer(innerBuffer, shiftedToStartIndex: 0)),
+      Array(
+        _buffer: _Buffer(_buffer: innerBuffer, shiftedToStartIndex: 0)),
         innerBuffer.firstElementAddress)
   }
 
@@ -1198,12 +1199,13 @@
       minimumCapacity: minimumCapacity) == nil {
 
       let newBuffer = _ContiguousArrayBuffer<Element>(
-        uninitializedCount: count, minimumCapacity: minimumCapacity)
+        _uninitializedCount: count, minimumCapacity: minimumCapacity)
 
       _buffer._copyContents(
         subRange: Range(_buffer.indices),
         initializing: newBuffer.firstElementAddress)
-      _buffer = _Buffer(newBuffer, shiftedToStartIndex: _buffer.startIndex)
+      _buffer = _Buffer(
+        _buffer: newBuffer, shiftedToStartIndex: _buffer.startIndex)
     }
     _sanityCheck(capacity >= minimumCapacity)
   }
@@ -1623,6 +1625,25 @@
     // Invoke the body.
     return try body(&inoutBufferPointer)
   }
+
+  @discardableResult
+  public func _copyContents(
+    initializing ptr: UnsafeMutablePointer<Element>
+  ) -> UnsafeMutablePointer<Element> {
+    if let s = self._baseAddressIfContiguous {
+      let count = self.count
+      ptr.initialize(from: s, count: count)
+      _fixLifetime(self._owner)
+      return ptr + count
+    } else {
+      var p = ptr
+      for x in self {
+        p.initialize(to: x)
+        p += 1
+      }
+      return p
+    }
+  }
 }
 %end
 
@@ -1850,7 +1871,7 @@
       ? _growArrayCapacity(source.capacity) : source.capacity)
 
   return _ContiguousArrayBuffer(
-    uninitializedCount: countForBuffer, minimumCapacity: minimumCapacity)
+    _uninitializedCount: countForBuffer, minimumCapacity: minimumCapacity)
 }
 
 internal protocol _PointerFunction {
@@ -1933,7 +1954,7 @@
     let tailEnd = source.endIndex
     source._copyContents(subRange: tailStart..<tailEnd, initializing: newEnd)
   }
-  source = _Buffer(dest, shiftedToStartIndex: source.startIndex)
+  source = _Buffer(_buffer: dest, shiftedToStartIndex: source.startIndex)
 }
 
 internal struct _InitializePointer<T> : _PointerFunction {
@@ -2091,6 +2112,11 @@
 
 #if _runtime(_ObjC)
 extension Array {
+  public // @SPI(Foundation)
+  func _bridgeToObjectiveCImpl() -> AnyObject {
+    return _buffer._asCocoaArray()
+  }
+
   /// Tries to downcast the source `NSArray` as our native buffer type.
   /// If it succeeds, creates a new `Array` around it and returns that.
   /// Returns `nil` otherwise.
@@ -2154,7 +2180,7 @@
   init(_startIndex: Int) {
     self.init(
       _buffer: _Buffer(
-        ContiguousArray()._buffer,
+        _buffer: ContiguousArray()._buffer,
         shiftedToStartIndex: _startIndex))
   }
 }
diff --git a/stdlib/public/core/Collection.swift b/stdlib/public/core/Collection.swift
index e69b144..f46a11f 100644
--- a/stdlib/public/core/Collection.swift
+++ b/stdlib/public/core/Collection.swift
@@ -1649,30 +1649,6 @@
   }
 }
 
-// TODO: swift-3-indexing-model - review the following
-extension Sequence
-  where Self : _ArrayProtocol, Self.Element == Self.Iterator.Element {
-  // A fast implementation for when you are backed by a contiguous array.
-  @discardableResult
-  public func _copyContents(
-    initializing ptr: UnsafeMutablePointer<Iterator.Element>
-  ) -> UnsafeMutablePointer<Iterator.Element> {
-    if let s = self._baseAddressIfContiguous {
-      let count = self.count
-      ptr.initialize(from: s, count: count)
-      _fixLifetime(self._owner)
-      return ptr + count
-    } else {
-      var p = ptr
-      for x in self {
-        p.initialize(to: x)
-        p += 1
-      }
-      return p
-    }
-  }
-}
-
 extension Collection {
   public func _preprocessingPass<R>(
     _ preprocess: () throws -> R
diff --git a/stdlib/public/core/ContiguousArrayBuffer.swift b/stdlib/public/core/ContiguousArrayBuffer.swift
index ffa7fbf..85add43 100644
--- a/stdlib/public/core/ContiguousArrayBuffer.swift
+++ b/stdlib/public/core/ContiguousArrayBuffer.swift
@@ -184,14 +184,16 @@
 }
 
 @_fixed_layout
-public // @testable
-struct _ContiguousArrayBuffer<Element> : _ArrayBufferProtocol {
+internal struct _ContiguousArrayBuffer<Element> : _ArrayBufferProtocol {
 
   /// Make a buffer with uninitialized elements.  After using this
   /// method, you must either initialize the `count` elements at the
   /// result's `.firstElementAddress` or set the result's `.count`
   /// to zero.
-  public init(uninitializedCount: Int, minimumCapacity: Int) {
+  internal init(
+    _uninitializedCount uninitializedCount: Int,
+    minimumCapacity: Int
+  ) {
     let realMinimumCapacity = Swift.max(uninitializedCount, minimumCapacity)
     if realMinimumCapacity == 0 {
       self = _ContiguousArrayBuffer<Element>()
@@ -248,22 +250,22 @@
   }
 
   /// True, if the array is native and does not need a deferred type check.
-  var arrayPropertyIsNativeTypeChecked: Bool {
+  internal var arrayPropertyIsNativeTypeChecked: Bool {
     return true
   }
 
   /// A pointer to the first element.
-  public var firstElementAddress: UnsafeMutablePointer<Element> {
+  internal var firstElementAddress: UnsafeMutablePointer<Element> {
     return __bufferPointer._elementPointer
   }
 
-  public var firstElementAddressIfContiguous: UnsafeMutablePointer<Element>? {
+  internal var firstElementAddressIfContiguous: UnsafeMutablePointer<Element>? {
     return firstElementAddress
   }
 
   /// Call `body(p)`, where `p` is an `UnsafeBufferPointer` over the
   /// underlying contiguous storage.
-  public func withUnsafeBufferPointer<R>(
+  internal func withUnsafeBufferPointer<R>(
     _ body: (UnsafeBufferPointer<Element>) throws -> R
   ) rethrows -> R {
     defer { _fixLifetime(self) }
@@ -273,7 +275,7 @@
 
   /// Call `body(p)`, where `p` is an `UnsafeMutableBufferPointer`
   /// over the underlying contiguous storage.
-  public mutating func withUnsafeMutableBufferPointer<R>(
+  internal mutating func withUnsafeMutableBufferPointer<R>(
     _ body: (UnsafeMutableBufferPointer<Element>) throws -> R
   ) rethrows -> R {
     defer { _fixLifetime(self) }
@@ -283,17 +285,17 @@
 
   //===--- _ArrayBufferProtocol conformance -----------------------------------===//
   /// Create an empty buffer.
-  public init() {
+  internal init() {
     __bufferPointer = ManagedBufferPointer(
       _uncheckedUnsafeBufferObject: _emptyArrayStorage)
   }
 
-  public init(_ buffer: _ContiguousArrayBuffer, shiftedToStartIndex: Int) {
+  internal init(_buffer buffer: _ContiguousArrayBuffer, shiftedToStartIndex: Int) {
     _sanityCheck(shiftedToStartIndex == 0, "shiftedToStartIndex must be 0")
     self = buffer
   }
 
-  public mutating func requestUniqueMutableBackingBuffer(
+  internal mutating func requestUniqueMutableBackingBuffer(
     minimumCapacity: Int
   ) -> _ContiguousArrayBuffer<Element>? {
     if _fastPath(isUniquelyReferenced() && capacity >= minimumCapacity) {
@@ -302,29 +304,29 @@
     return nil
   }
 
-  public mutating func isMutableAndUniquelyReferenced() -> Bool {
+  internal mutating func isMutableAndUniquelyReferenced() -> Bool {
     return isUniquelyReferenced()
   }
 
-  public mutating func isMutableAndUniquelyReferencedOrPinned() -> Bool {
+  internal mutating func isMutableAndUniquelyReferencedOrPinned() -> Bool {
     return isUniquelyReferencedOrPinned()
   }
 
   /// If this buffer is backed by a `_ContiguousArrayBuffer`
   /// containing the same number of elements as `self`, return it.
   /// Otherwise, return `nil`.
-  public func requestNativeBuffer() -> _ContiguousArrayBuffer<Element>? {
+  internal func requestNativeBuffer() -> _ContiguousArrayBuffer<Element>? {
     return self
   }
 
   @_versioned
-  func getElement(_ i: Int) -> Element {
+  internal func getElement(_ i: Int) -> Element {
     _sanityCheck(i >= 0 && i < count, "Array index out of range")
     return firstElementAddress[i]
   }
 
   /// Get or set the value of the ith element.
-  public subscript(i: Int) -> Element {
+  internal subscript(i: Int) -> Element {
     get {
       return getElement(i)
     }
@@ -342,7 +344,7 @@
   }
 
   /// The number of elements the buffer stores.
-  public var count: Int {
+  internal var count: Int {
     get {
       return __bufferPointer.header.count
     }
@@ -368,7 +370,7 @@
   }
 
   /// The number of elements the buffer can store without reallocation.
-  public var capacity: Int {
+  internal var capacity: Int {
     return __bufferPointer.header.capacity
   }
 
@@ -376,7 +378,7 @@
   /// memory starting at `target`.  Return a pointer "past the end" of the
   /// just-initialized memory.
   @discardableResult
-  public func _copyContents(
+  internal func _copyContents(
     subRange bounds: Range<Int>,
     initializing target: UnsafeMutablePointer<Element>
   ) -> UnsafeMutablePointer<Element> {
@@ -393,7 +395,7 @@
 
   /// Returns a `_SliceBuffer` containing the given `bounds` of values
   /// from this buffer.
-  public subscript(bounds: Range<Int>) -> _SliceBuffer<Element> {
+  internal subscript(bounds: Range<Int>) -> _SliceBuffer<Element> {
     get {
       return _SliceBuffer(
         owner: __bufferPointer.buffer,
@@ -411,14 +413,14 @@
   /// - Note: This does not mean the buffer is mutable.  Other factors
   ///   may need to be considered, such as whether the buffer could be
   ///   some immutable Cocoa container.
-  public mutating func isUniquelyReferenced() -> Bool {
+  internal mutating func isUniquelyReferenced() -> Bool {
     return __bufferPointer.isUniqueReference()
   }
 
   /// Returns `true` iff this buffer's storage is either
   /// uniquely-referenced or pinned.  NOTE: this does not mean
   /// the buffer is mutable; see the comment on isUniquelyReferenced.
-  public mutating func isUniquelyReferencedOrPinned() -> Bool {
+  internal mutating func isUniquelyReferencedOrPinned() -> Bool {
     return __bufferPointer._isUniqueOrPinnedReference()
   }
 
@@ -428,7 +430,7 @@
   /// - Precondition: `Element` is bridged to Objective-C.
   ///
   /// - Complexity: O(1).
-  public func _asCocoaArray() -> _NSArrayCore {
+  internal func _asCocoaArray() -> _NSArrayCore {
     if count == 0 {
       return _emptyArrayStorage
     }
@@ -440,12 +442,12 @@
 #endif
 
   /// An object that keeps the elements stored in this buffer alive.
-  public var owner: AnyObject {
+  internal var owner: AnyObject {
     return _storage
   }
 
   /// An object that keeps the elements stored in this buffer alive.
-  public var nativeOwner: AnyObject {
+  internal var nativeOwner: AnyObject {
     return _storage
   }
 
@@ -453,7 +455,7 @@
   ///
   /// Two buffers address the same elements when they have the same
   /// identity and count.
-  public var identity: UnsafeRawPointer {
+  internal var identity: UnsafeRawPointer {
     return UnsafeRawPointer(firstElementAddress)
   }
   
@@ -495,7 +497,7 @@
 }
 
 /// Append the elements of `rhs` to `lhs`.
-public func += <Element, C : Collection>(
+internal func += <Element, C : Collection>(
   lhs: inout _ContiguousArrayBuffer<Element>, rhs: C
 ) where C.Iterator.Element == Element {
 
@@ -508,7 +510,7 @@
   }
   else {
     var newLHS = _ContiguousArrayBuffer<Element>(
-      uninitializedCount: newCount,
+      _uninitializedCount: newCount,
       minimumCapacity: _growArrayCapacity(lhs.capacity))
 
     newLHS.firstElementAddress.moveInitialize(
@@ -523,7 +525,7 @@
   /// The position of the first element in a non-empty collection.
   ///
   /// In an empty collection, `startIndex == endIndex`.
-  public var startIndex: Int {
+  internal var startIndex: Int {
     return 0
   }
   /// The collection's "past the end" position.
@@ -531,11 +533,11 @@
   /// `endIndex` is not a valid argument to `subscript`, and is always
   /// reachable from `startIndex` by zero or more applications of
   /// `index(after:)`.
-  public var endIndex: Int {
+  internal var endIndex: Int {
     return count
   }
 
-  public typealias Indices = CountableRange<Int>
+  internal typealias Indices = CountableRange<Int>
 }
 
 extension Sequence {
@@ -576,7 +578,7 @@
 }
 
 extension _ContiguousArrayBuffer {
-  public func _copyToContiguousArray() -> ContiguousArray<Element> {
+  internal func _copyToContiguousArray() -> ContiguousArray<Element> {
     return ContiguousArray(_buffer: self)
   }
 }
@@ -599,7 +601,7 @@
   }
 
   let result = _ContiguousArrayBuffer<C.Iterator.Element>(
-    uninitializedCount: count,
+    _uninitializedCount: count,
     minimumCapacity: 0)
 
   var p = result.firstElementAddress
@@ -632,7 +634,7 @@
       result = _ContiguousArrayBuffer()
     } else {
       result = _ContiguousArrayBuffer(
-        uninitializedCount: initialCapacity,
+        _uninitializedCount: initialCapacity,
         minimumCapacity: 0)
     }
 
@@ -647,7 +649,7 @@
       // Reallocate.
       let newCapacity = max(_growArrayCapacity(result.capacity), 1)
       var newResult = _ContiguousArrayBuffer<Element>(
-        uninitializedCount: newCapacity, minimumCapacity: 0)
+        _uninitializedCount: newCapacity, minimumCapacity: 0)
       p = newResult.firstElementAddress + result.capacity
       remainingCapacity = newResult.capacity - result.capacity
       newResult.firstElementAddress.moveInitialize(
diff --git a/stdlib/public/core/HashedCollectionsAnyHashableExtensions.swift.gyb b/stdlib/public/core/HashedCollectionsAnyHashableExtensions.swift.gyb
index 8844d49..18e3c0f 100644
--- a/stdlib/public/core/HashedCollectionsAnyHashableExtensions.swift.gyb
+++ b/stdlib/public/core/HashedCollectionsAnyHashableExtensions.swift.gyb
@@ -28,16 +28,6 @@
 // properly expressed in the language.
 extension Set {
   @inline(__always)
-  internal func _concreteElement_contains(_ member: Element) -> Bool {
-    return contains(member)
-  }
-
-  @inline(__always)
-  internal func _concreteElement_index(of member: Element) -> Index? {
-    return index(of: member)
-  }
-
-  @inline(__always)
   internal mutating func _concreteElement_insert(
     _ newMember: Element
   ) -> (inserted: Bool, memberAfterInsert: Element) {
@@ -61,18 +51,6 @@
 
 // FIXME(ABI)(compiler limitation): replace with `where Element == AnyHashable`.
 extension Set where Element : _AnyHashableProtocol {
-  public func contains<ConcreteElement : Hashable>(
-    _ member: ConcreteElement
-  ) -> Bool {
-    return _concreteElement_contains(AnyHashable(member) as! Element)
-  }
-
-  public func index<ConcreteElement : Hashable>(
-    of member: ConcreteElement
-  ) -> SetIndex<Element>? {
-    return _concreteElement_index(of: AnyHashable(member) as! Element)
-  }
-
   public mutating func insert<ConcreteElement : Hashable>(
     _ newMember: ConcreteElement
   ) -> (inserted: Bool, memberAfterInsert: ConcreteElement) {
@@ -107,11 +85,6 @@
 // FIXME: remove these trampolines when extensions below can be
 // properly expressed in the language.
 extension Dictionary {
-  @inline(__always)
-  internal func _concreteKey_index(forKey key: Key) -> Index? {
-    return index(forKey: key)
-  }
-
   internal subscript(_concreteKey key: Key) -> Value? {
     @inline(__always)
     get {
@@ -138,12 +111,6 @@
 
 // FIXME(ABI)(compiler limitation): replace with `where Element == AnyHashable`.
 extension Dictionary where Key : _AnyHashableProtocol {
-  public func index<ConcreteKey : Hashable>(forKey key: ConcreteKey)
-    -> DictionaryIndex<Key, Value>?
-  {
-    return _concreteKey_index(forKey: AnyHashable(key) as! Key)
-  }
-
   public subscript(_ key: _Hashable) -> Value? {
     // FIXME(ABI)(compiler limitation): replace this API with a
     // generic subscript.
diff --git a/stdlib/public/core/SliceBuffer.swift b/stdlib/public/core/SliceBuffer.swift
index cf66905..94db40e 100644
--- a/stdlib/public/core/SliceBuffer.swift
+++ b/stdlib/public/core/SliceBuffer.swift
@@ -11,12 +11,14 @@
 //===----------------------------------------------------------------------===//
 
 /// Buffer type for `ArraySlice<Element>`.
-public // @testable
-struct _SliceBuffer<Element> : _ArrayBufferProtocol, RandomAccessCollection {
+internal struct _SliceBuffer<Element>
+  : _ArrayBufferProtocol,
+    RandomAccessCollection
+{
   internal typealias NativeStorage = _ContiguousArrayStorage<Element>
-  public typealias NativeBuffer = _ContiguousArrayBuffer<Element>
+  internal typealias NativeBuffer = _ContiguousArrayBuffer<Element>
 
-  init(
+  internal init(
     owner: AnyObject, subscriptBaseAddress: UnsafeMutablePointer<Element>,
     indices: Range<Int>, hasNativeBuffer: Bool
   ) {
@@ -28,7 +30,7 @@
     _invariantCheck()
   }
 
-  public init() {
+  internal init() {
     let empty = _ContiguousArrayBuffer<Element>()
     self.owner = empty.owner
     self.subscriptBaseAddress = empty.firstElementAddress
@@ -37,7 +39,7 @@
     _invariantCheck()
   }
 
-  public init(_ buffer: NativeBuffer, shiftedToStartIndex: Int) {
+  internal init(_buffer buffer: NativeBuffer, shiftedToStartIndex: Int) {
     let shift = buffer.startIndex - shiftedToStartIndex
     self.init(
       owner: buffer.owner,
@@ -46,7 +48,7 @@
       hasNativeBuffer: true)
   }
 
-  func _invariantCheck() {
+  internal func _invariantCheck() {
     let isNative = _hasNativeBuffer
     let isNativeStorage: Bool = (owner as? _ContiguousArrayStorageBase) != nil
     _sanityCheck(isNativeStorage == isNative)
@@ -55,17 +57,17 @@
     }
   }
 
-  var _hasNativeBuffer: Bool {
+  internal var _hasNativeBuffer: Bool {
     return (endIndexAndFlags & 1) != 0
   }
 
-  var nativeBuffer: NativeBuffer {
+  internal var nativeBuffer: NativeBuffer {
     _sanityCheck(_hasNativeBuffer)
     return NativeBuffer(
       owner as? _ContiguousArrayStorageBase ?? _emptyArrayStorage)
   }
 
-  public var nativeOwner: AnyObject {
+  internal var nativeOwner: AnyObject {
     _sanityCheck(_hasNativeBuffer, "Expect a native array")
     return owner
   }
@@ -76,7 +78,7 @@
   /// - Precondition: This buffer is backed by a uniquely-referenced
   ///   `_ContiguousArrayBuffer` and
   ///   `insertCount <= numericCast(newValues.count)`.
-  public mutating func replace<C>(
+  internal mutating func replace<C>(
     subRange: Range<Int>,
     with insertCount: Int,
     elementsOf newValues: C
@@ -111,28 +113,28 @@
   /// A value that identifies the storage used by the buffer.  Two
   /// buffers address the same elements when they have the same
   /// identity and count.
-  public var identity: UnsafeRawPointer {
+  internal var identity: UnsafeRawPointer {
     return UnsafeRawPointer(firstElementAddress)
   }
 
   /// An object that keeps the elements stored in this buffer alive.
-  public var owner: AnyObject
-  public let subscriptBaseAddress: UnsafeMutablePointer<Element>
+  internal var owner: AnyObject
+  internal let subscriptBaseAddress: UnsafeMutablePointer<Element>
 
-  public var firstElementAddress: UnsafeMutablePointer<Element> {
+  internal var firstElementAddress: UnsafeMutablePointer<Element> {
     return subscriptBaseAddress + startIndex
   }
 
-  public var firstElementAddressIfContiguous: UnsafeMutablePointer<Element>? {
+  internal var firstElementAddressIfContiguous: UnsafeMutablePointer<Element>? {
     return firstElementAddress
   }
 
   /// [63:1: 63-bit index][0: has a native buffer]
-  var endIndexAndFlags: UInt
+  internal var endIndexAndFlags: UInt
 
   //===--- Non-essential bits ---------------------------------------------===//
 
-  public mutating func requestUniqueMutableBackingBuffer(
+  internal mutating func requestUniqueMutableBackingBuffer(
     minimumCapacity: Int
   ) -> NativeBuffer? {
     _invariantCheck()
@@ -161,18 +163,18 @@
     return nil
   }
 
-  public mutating func isMutableAndUniquelyReferenced() -> Bool {
+  internal mutating func isMutableAndUniquelyReferenced() -> Bool {
     return _hasNativeBuffer && isUniquelyReferenced()
   }
 
-  public mutating func isMutableAndUniquelyReferencedOrPinned() -> Bool {
+  internal mutating func isMutableAndUniquelyReferencedOrPinned() -> Bool {
     return _hasNativeBuffer && isUniquelyReferencedOrPinned()
   }
 
   /// If this buffer is backed by a `_ContiguousArrayBuffer`
   /// containing the same number of elements as `self`, return it.
   /// Otherwise, return `nil`.
-  public func requestNativeBuffer() -> _ContiguousArrayBuffer<Element>? {
+  internal func requestNativeBuffer() -> _ContiguousArrayBuffer<Element>? {
     _invariantCheck()
     if _fastPath(_hasNativeBuffer && nativeBuffer.count == count) {
       return nativeBuffer
@@ -181,7 +183,7 @@
   }
 
   @discardableResult
-  public func _copyContents(
+  internal func _copyContents(
     subRange bounds: Range<Int>,
     initializing target: UnsafeMutablePointer<Element>
   ) -> UnsafeMutablePointer<Element> {
@@ -195,12 +197,11 @@
   }
 
   /// True, if the array is native and does not need a deferred type check.
-  var arrayPropertyIsNativeTypeChecked: Bool {
+  internal var arrayPropertyIsNativeTypeChecked: Bool {
     return _hasNativeBuffer
   }
 
-  public
-  var count: Int {
+  internal var count: Int {
     get {
       return endIndex - startIndex
     }
@@ -221,7 +222,7 @@
       index >= startIndex && index < endIndex, "Index out of bounds")
   }
 
-  public var capacity: Int {
+  internal var capacity: Int {
     let count = self.count
     if _slowPath(!_hasNativeBuffer) {
       return count
@@ -234,16 +235,16 @@
     return count
   }
 
-  mutating func isUniquelyReferenced() -> Bool {
+  internal mutating func isUniquelyReferenced() -> Bool {
     return isKnownUniquelyReferenced(&owner)
   }
 
-  mutating func isUniquelyReferencedOrPinned() -> Bool {
+  internal mutating func isUniquelyReferencedOrPinned() -> Bool {
     return _isKnownUniquelyReferencedOrPinned(&owner)
   }
 
   @_versioned
-  func getElement(_ i: Int) -> Element {
+  internal func getElement(_ i: Int) -> Element {
     _sanityCheck(i >= startIndex, "negative slice index is out of range")
     _sanityCheck(i < endIndex, "slice index out of range")
     return subscriptBaseAddress[i]
@@ -253,7 +254,7 @@
   ///
   /// - Precondition: `position` is a valid position in `self` and
   ///   `position != endIndex`.
-  public subscript(position: Int) -> Element {
+  internal subscript(position: Int) -> Element {
     get {
       return getElement(position)
     }
@@ -264,7 +265,7 @@
     }
   }
 
-  public subscript(bounds: Range<Int>) -> _SliceBuffer {
+  internal subscript(bounds: Range<Int>) -> _SliceBuffer {
     get {
       _sanityCheck(bounds.lowerBound >= startIndex)
       _sanityCheck(bounds.upperBound >= bounds.lowerBound)
@@ -284,14 +285,14 @@
   /// The position of the first element in a non-empty collection.
   ///
   /// In an empty collection, `startIndex == endIndex`.
-  public var startIndex: Int
+  internal var startIndex: Int
 
   /// The collection's "past the end" position---that is, the position one
   /// greater than the last valid subscript argument.
   ///
   /// `endIndex` is always reachable from `startIndex` by zero or more
   /// applications of `index(after:)`.
-  public var endIndex: Int {
+  internal var endIndex: Int {
     get {
       return Int(endIndexAndFlags >> 1)
     }
@@ -300,13 +301,12 @@
     }
   }
 
-  public typealias Indices = CountableRange<Int>
+  internal typealias Indices = CountableRange<Int>
 
   //===--- misc -----------------------------------------------------------===//
   /// Call `body(p)`, where `p` is an `UnsafeBufferPointer` over the
   /// underlying contiguous storage.
-  public
-  func withUnsafeBufferPointer<R>(
+  internal func withUnsafeBufferPointer<R>(
     _ body: (UnsafeBufferPointer<Element>) throws -> R
   ) rethrows -> R {
     defer { _fixLifetime(self) }
@@ -316,8 +316,7 @@
 
   /// Call `body(p)`, where `p` is an `UnsafeMutableBufferPointer`
   /// over the underlying contiguous storage.
-  public
-  mutating func withUnsafeMutableBufferPointer<R>(
+  internal mutating func withUnsafeMutableBufferPointer<R>(
     _ body: (UnsafeMutableBufferPointer<Element>) throws -> R
   ) rethrows -> R {
     defer { _fixLifetime(self) }
@@ -327,7 +326,7 @@
 }
 
 extension _SliceBuffer {
-  public func _copyToContiguousArray() -> ContiguousArray<Element> {
+  internal func _copyToContiguousArray() -> ContiguousArray<Element> {
     if _hasNativeBuffer {
       let n = nativeBuffer
       if count == n.count {
@@ -336,7 +335,7 @@
     }
 
     let result = _ContiguousArrayBuffer<Element>(
-      uninitializedCount: count,
+      _uninitializedCount: count,
       minimumCapacity: 0)
     result.firstElementAddress.initialize(
       from: firstElementAddress, count: count)
diff --git a/test/1_stdlib/BridgeNonVerbatim.swift b/test/1_stdlib/BridgeNonVerbatim.swift
index 9400740..67bb904 100644
--- a/test/1_stdlib/BridgeNonVerbatim.swift
+++ b/test/1_stdlib/BridgeNonVerbatim.swift
@@ -23,8 +23,9 @@
 
 import Swift
 import SwiftShims
-import ObjectiveC
+import Foundation
 import StdlibUnittest
+import StdlibUnittestFoundationExtras
 
 struct X : _ObjectiveCBridgeable {
   init(_ value: Int) {
@@ -65,7 +66,7 @@
 
 func testScope() {
   let a = [X(1), X(2), X(3)]
-  let nsx = a._buffer._asCocoaArray()
+  let nsx: NSArray = a._bridgeToObjectiveC()
 
   // construction of these tracked objects is lazy
   // CHECK-NEXT: trackedCount = 0 .
@@ -73,12 +74,12 @@
 
   // We can get a single element out
   // CHECK-NEXT: nsx[0]: 1 .
-  let one = nsx.objectAt(0) as! LifetimeTracked
+  let one = nsx.object(at: 0) as! LifetimeTracked
   print("nsx[0]: \(one.value) .")
 
   // We can get the element again, but it may not have the same identity
   // CHECK-NEXT: object identity matches?
-  let anotherOne = nsx.objectAt(0) as! LifetimeTracked
+  let anotherOne = nsx.object(at: 0) as! LifetimeTracked
   print("object identity matches? \(one === anotherOne)")
 
   // Because the elements come back at +0, we really don't want to
@@ -88,9 +89,10 @@
   objects.withUnsafeMutableBufferPointer {
     // FIXME: Can't elide signature and use $0 here <rdar://problem/17770732> 
     (buf: inout UnsafeMutableBufferPointer<Int>) -> () in
-    let objPtr = UnsafeMutableRawPointer(buf.baseAddress!).bindMemory(
-      to: AnyObject.self, capacity: 2)
-    nsx.getObjects(objPtr, range: _SwiftNSRange(location: 1, length: 2))
+    nsx.available_getObjects(
+      AutoreleasingUnsafeMutablePointer(buf.baseAddress!),
+      range: NSRange(location: 1, length: 2))
+    return
   }
 
   // CHECK-NEXT: getObjects yields them at +0: true
diff --git a/test/AutolinkExtract/empty.swift b/test/AutolinkExtract/empty.swift
index 8dd98ea..2e32546 100644
--- a/test/AutolinkExtract/empty.swift
+++ b/test/AutolinkExtract/empty.swift
@@ -4,3 +4,4 @@
 // REQUIRES: autolink-extract
 
 // CHECK-elf: -lswiftCore
+// CHECK-coff: -lswiftCore
diff --git a/test/AutolinkExtract/empty_archive.swift b/test/AutolinkExtract/empty_archive.swift
index 54ebece..030ef63 100644
--- a/test/AutolinkExtract/empty_archive.swift
+++ b/test/AutolinkExtract/empty_archive.swift
@@ -6,3 +6,4 @@
 // REQUIRES: autolink-extract
 
 // CHECK-elf: -lswiftCore
+// CHECK-coff: -lswiftCore
diff --git a/test/AutolinkExtract/import.swift b/test/AutolinkExtract/import.swift
index 225dfff..c87a7bc 100644
--- a/test/AutolinkExtract/import.swift
+++ b/test/AutolinkExtract/import.swift
@@ -9,4 +9,7 @@
 // CHECK-elf-DAG: -lswiftCore
 // CHECK-elf-DAG: -lempty
 
+// CHECK-coff-DAG: -lswiftCore
+// CHECK-coff-DAG: -lempty
+
 import empty
diff --git a/test/AutolinkExtract/import_archive.swift b/test/AutolinkExtract/import_archive.swift
index 0cba4a1..d3fa6a6 100644
--- a/test/AutolinkExtract/import_archive.swift
+++ b/test/AutolinkExtract/import_archive.swift
@@ -10,4 +10,7 @@
 // CHECK-elf-DAG: -lswiftCore
 // CHECK-elf-DAG: -lempty
 
+// CHECK-coff-DAG: -lswiftCore
+// CHECK-coff-DAG: -lempty
+
 import empty
diff --git a/test/AutolinkExtract/linker-order.ll b/test/AutolinkExtract/linker-order.ll
index 8f84a20..7da7d60 100644
--- a/test/AutolinkExtract/linker-order.ll
+++ b/test/AutolinkExtract/linker-order.ll
@@ -1,4 +1,6 @@
 ; RUN: llc -mtriple armv7--linux-gnueabihf -filetype obj -o - %s | %target-swift-autolink-extract -o - - | FileCheck %s
+; RUN: llc -mtriple x86_64--windows-gnu -filetype obj -o - %s | %target-swift-autolink-extract -o - - | FileCheck %s
+; RUN: llc -mtriple x86_64--windows-cygnus -filetype obj -o - %s | %target-swift-autolink-extract -o - - | FileCheck %s
 ; REQUIRES: autolink-extract
 
 ; Ensure that the options in the object file preserve ordering.  The linker
diff --git a/test/Constraints/dynamic_lookup.swift b/test/Constraints/dynamic_lookup.swift
index 116d90c..eefa295 100644
--- a/test/Constraints/dynamic_lookup.swift
+++ b/test/Constraints/dynamic_lookup.swift
@@ -219,3 +219,9 @@
 // Should not be able to see private or internal @objc methods.
 uopt.privateFoo!() // expected-error{{'privateFoo' is inaccessible due to 'private' protection level}}
 uopt.internalFoo!() // expected-error{{'internalFoo' is inaccessible due to 'internal' protection level}}
+
+let anyValue: Any = X()
+_ = anyValue.bar() // expected-error {{value of type 'Any' has no member 'bar'}}
+// expected-note@-1 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}{{5-13=(anyValue as AnyObject)}}
+_ = (anyValue as AnyObject).bar()
+_ = (anyValue as! X).bar()
diff --git a/test/Constraints/tuple.swift b/test/Constraints/tuple.swift
index 02ef3d2..b67dc84 100644
--- a/test/Constraints/tuple.swift
+++ b/test/Constraints/tuple.swift
@@ -61,6 +61,9 @@
 // Scalars don't have .0/.1/etc
 i = j.0 // expected-error{{value of type 'Int' has no member '0'}}
 any.1 // expected-error{{value of type 'Any' has no member '1'}}
+// expected-note@-1{{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}
+any = (5.0, 6.0) as (Float, Float)
+_ = (any as! (Float, Float)).1
 
 // Fun with tuples
 protocol PosixErrorReturn {
diff --git a/test/Interpreter/SDK/objc_fast_enumeration.swift b/test/Interpreter/SDK/objc_fast_enumeration.swift
index 53e90c3..fba5d7d 100644
--- a/test/Interpreter/SDK/objc_fast_enumeration.swift
+++ b/test/Interpreter/SDK/objc_fast_enumeration.swift
@@ -91,7 +91,7 @@
 // CHECK: 2
 // CHECK: 1
 var a2 = [3, 2, 1]
-var nsa2 = (a2._buffer._asCocoaArray() as AnyObject) as! NSArray
+var nsa2: NSArray = a2._bridgeToObjectiveC()
 for x in nsa2 {
   print(x)
 }
@@ -107,7 +107,7 @@
 // CHECK: X(2)
 // CHECK: X(1)
 var a3 = [X(3), X(2), X(1)]
-var nsa3 = (a3._buffer._asCocoaArray() as AnyObject) as! NSArray
+var nsa3: NSArray = a3._bridgeToObjectiveC()
 for x in nsa3 {
   print(x)
 }
diff --git a/test/Misc/misc_diagnostics.swift b/test/Misc/misc_diagnostics.swift
index 7987284..c1845b6 100644
--- a/test/Misc/misc_diagnostics.swift
+++ b/test/Misc/misc_diagnostics.swift
@@ -99,11 +99,11 @@
   var col = 2
   var coord = (row, col)
 
-  match += (1, 2) // expected-error{{argument type '(Int, Int)' does not conform to expected type 'Sequence'}}
+  match += (1, 2) // expected-error{{binary operator '+=' cannot be applied to operands of type '[(Int, Int)]' and '(Int, Int)'}} expected-note {{overloads for '+=' exist}}
 
-  match += (row, col) // expected-error{{argument type '(@lvalue Int, @lvalue Int)' does not conform to expected type 'Sequence'}}
+  match += (row, col) // expected-error{{binary operator '+=' cannot be applied to operands of type '[(Int, Int)]' and '(Int, Int)'}} expected-note {{overloads for '+=' exist}}
 
-  match += coord // expected-error{{argument type '@lvalue (Int, Int)' does not conform to expected type 'Sequence'}}
+  match += coord // expected-error{{binary operator '+=' cannot be applied to operands of type '[(Int, Int)]' and '(Int, Int)'}} expected-note {{overloads for '+=' exist}}
 
   match.append(row, col) // expected-error{{extra argument in call}}
 
diff --git a/test/lit.cfg b/test/lit.cfg
index a6a34af..2e1ed5f 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -691,17 +691,30 @@
         "%s clang++ %s" %
         (xcrun_prefix, config.target_cc_options))
 
-elif run_os == 'linux-gnu' or run_os == 'linux-gnueabihf' or run_os == 'freebsd':
-    # Linux/FreeBSD
-    if run_os == 'freebsd':
+elif run_os in ['linux-gnu', 'linux-gnueabihf', 'freebsd', 'windows-cygnus', 'windows-gnu']:
+    # Linux/FreeBSD/Cygwin
+    if run_os == 'windows-cygnus':
+      lit_config.note("Testing Cygwin " + config.variant_triple)
+      config.target_object_format = "coff"
+      config.target_dylib_extension = "dll"
+      config.target_sdk_name = "cygwin"
+    elif run_os == 'windows-gnu':
+      lit_config.note("Testing MinGW " + config.variant_triple)
+      config.target_object_format = "coff"
+      config.target_dylib_extension = "dll"
+      config.target_sdk_name = "mingw"
+    elif run_os == 'freebsd':
       lit_config.note("Testing FreeBSD " + config.variant_triple)
+      config.target_object_format = "elf"
+      config.target_dylib_extension = "so"
+      config.target_sdk_name = "freebsd"
     else:
       lit_config.note("Testing Linux " + config.variant_triple)
-    config.target_object_format = "elf"
-    config.target_dylib_extension = "so"
+      config.target_object_format = "elf"
+      config.target_dylib_extension = "so"
+      config.target_sdk_name = "linux"
     config.target_runtime = "native"
     config.target_swift_autolink_extract = inferSwiftBinary("swift-autolink-extract")
-    config.target_sdk_name = "freebsd" if run_os == "freebsd" else "linux"
     config.target_build_swift = (
         '%s -target %s %s %s %s %s'
         % (config.swiftc, config.variant_triple, resource_dir_opt, mcp_opt,
diff --git a/tools/driver/autolink_extract_main.cpp b/tools/driver/autolink_extract_main.cpp
index 949aca3..64cca89 100644
--- a/tools/driver/autolink_extract_main.cpp
+++ b/tools/driver/autolink_extract_main.cpp
@@ -31,6 +31,7 @@
 #include "llvm/Option/Option.h"
 #include "llvm/Object/Archive.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/COFF.h"
 #include "llvm/Object/ELFObjectFile.h"
 
 using namespace swift;
@@ -106,32 +107,44 @@
   }
 };
 
-// Look inside the binary 'Bin' and append any linker flags found in its
-// ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive,
-// recursively look inside all children within the archive. Return 'true' if
-// there was an error, and 'false' otherwise.
+/// Look inside the object file 'ObjectFile' and append any linker flags found in
+/// its ".swift1_autolink_entries" section to 'LinkerFlags'.
+static void
+extractLinkerFlagsFromObjectFile(const llvm::object::ObjectFile *ObjectFile,
+                                 std::vector<std::string> &LinkerFlags) {
+  // Search for the section we hold autolink entries in
+  for (auto &Section : ObjectFile->sections()) {
+    llvm::StringRef SectionName;
+    Section.getName(SectionName);
+    if (SectionName == ".swift1_autolink_entries") {
+      llvm::StringRef SectionData;
+      Section.getContents(SectionData);
+
+      // entries are null-terminated, so extract them and push them into
+      // the set.
+      llvm::SmallVector<llvm::StringRef, 4> SplitFlags;
+      SectionData.split(SplitFlags, llvm::StringRef("\0", 1), -1,
+                        /*KeepEmpty=*/false);
+      for (const auto &Flag : SplitFlags)
+        LinkerFlags.push_back(Flag);
+    }
+  }
+}
+
+/// Look inside the binary 'Bin' and append any linker flags found in its
+/// ".swift1_autolink_entries" section to 'LinkerFlags'. If 'Bin' is an archive,
+/// recursively look inside all children within the archive. Return 'true' if
+/// there was an error, and 'false' otherwise.
 static bool extractLinkerFlags(const llvm::object::Binary *Bin,
                                CompilerInstance &Instance,
                                StringRef BinaryFileName,
                                std::vector<std::string> &LinkerFlags) {
   if (auto *ObjectFile = llvm::dyn_cast<llvm::object::ELFObjectFileBase>(Bin)) {
-    // Search for the section we hold autolink entries in
-    for (auto &Section : ObjectFile->sections()) {
-      llvm::StringRef SectionName;
-      Section.getName(SectionName);
-      if (SectionName == ".swift1_autolink_entries") {
-        llvm::StringRef SectionData;
-        Section.getContents(SectionData);
-
-        // entries are null-terminated, so extract them and push them into
-        // the set.
-        llvm::SmallVector<llvm::StringRef, 4> SplitFlags;
-        SectionData.split(SplitFlags, llvm::StringRef("\0", 1), -1,
-                          /*KeepEmpty=*/false);
-        for (const auto &Flag : SplitFlags)
-          LinkerFlags.push_back(Flag);
-      }
-    }
+    extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags);
+    return false;
+  } else if (auto *ObjectFile =
+                 llvm::dyn_cast<llvm::object::COFFObjectFile>(Bin)) {
+    extractLinkerFlagsFromObjectFile(ObjectFile, LinkerFlags);
     return false;
   } else if (auto *Archive = llvm::dyn_cast<llvm::object::Archive>(Bin)) {
     for (const auto &Child : Archive->children()) {
diff --git a/validation-test/StdlibUnittest/Assertions.swift.gyb b/validation-test/StdlibUnittest/Assertions.swift.gyb
index e66b9e4..ea73f2d 100644
--- a/validation-test/StdlibUnittest/Assertions.swift.gyb
+++ b/validation-test/StdlibUnittest/Assertions.swift.gyb
@@ -219,5 +219,36 @@
   }
 }
 
+AssertionsTestSuite.test("expectEqual<T : Equatable, U : Equatable, V : Equatable, W : Equatable>") {
+  let _0 = MinimalEquatableValue(0)
+  let _1 = MinimalEquatableValue(1)
+
+  for a in [_0, _1] {
+    for b in [_0, _1] {
+      for c in [_0, _1] {
+        for d in [_0, _1] {
+          for e in [_0, _1] {
+            for f in [_0, _1] {
+              for g in [_0, _1] {
+                for h in [_0, _1] {
+                  let lhs = (a, b, c, d)
+                  let rhs = (e, f, g, h)
+                  if lhs == rhs {
+                    expectEqual(lhs, rhs)
+                  } else {
+                    expectFailure {
+                      expectEqual(lhs, rhs)
+                    }
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
 runAllTests()
 
diff --git a/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift b/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift
index 7feed32..54eb70c 100644
--- a/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift
+++ b/validation-test/compiler_crashers_2_fixed/0022-rdar21625478.swift
@@ -35,8 +35,8 @@
     _ preprocess: (Self) -> R
   ) -> R?
 
-  func _copyToNativeArrayBuffer()
-    -> _ContiguousArrayBuffer<Iterator.Element>
+  func _copyToContiguousArray()
+    -> ContiguousArray<Iterator.Element>
 
   func _copyContents(
     initializing ptr: UnsafeMutablePointer<Iterator.Element>
@@ -71,8 +71,8 @@
     return nil
   }
 
-  public func _copyToNativeArrayBuffer()
-    -> _ContiguousArrayBuffer<Iterator.Element> {
+  public func _copyToContiguousArray()
+    -> ContiguousArray<Iterator.Element> {
     fatalError()
   }
 
@@ -224,7 +224,7 @@
   public static var filter = TypeIndexed(0)
   public static var _customContainsEquatableElement = TypeIndexed(0)
   public static var _preprocessingPass = TypeIndexed(0)
-  public static var _copyToNativeArrayBuffer = TypeIndexed(0)
+  public static var _copyToContiguousArray = TypeIndexed(0)
   public static var _copyContents = TypeIndexed(0)
 }
 
@@ -281,10 +281,10 @@
 
   /// Create a native array buffer containing the elements of `self`,
   /// in the same order.
-  public func _copyToNativeArrayBuffer()
-    -> _ContiguousArrayBuffer<Base.Iterator.Element> {
-    Log._copyToNativeArrayBuffer[selfType] += 1
-    return base._copyToNativeArrayBuffer()
+  public func _copyToContiguousArray()
+    -> ContiguousArray<Base.Iterator.Element> {
+    Log._copyToContiguousArray[selfType] += 1
+    return base._copyToContiguousArray()
   }
 
   /// Copy a Sequence into an array.
diff --git a/validation-test/stdlib/ArrayNew.swift.gyb b/validation-test/stdlib/ArrayNew.swift.gyb
index 542f6bd..e5b6bcc 100644
--- a/validation-test/stdlib/ArrayNew.swift.gyb
+++ b/validation-test/stdlib/ArrayNew.swift.gyb
@@ -19,23 +19,14 @@
 all_array_types = ['ContiguousArray', 'ArraySlice', 'Array']
 }%
 
-extension Array {
-  var identity: UnsafeRawPointer {
-    return self._buffer.identity
+%for Self in all_array_types:
+extension ${Self} {
+  typealias _BufferID = UnsafeRawPointer?
+  var _bufferID: _BufferID {
+    return unsafeBitCast(_owner, to: _BufferID.self)
   }
 }
-
-extension ArraySlice {
-  var identity: UnsafeRawPointer {
-    return self._buffer.identity
-  }
-}
-
-extension ContiguousArray {
-  var identity: UnsafeRawPointer {
-    return self._buffer.identity
-  }
-}
+%end
 
 var ArrayTestSuite = TestSuite("Array")
 
@@ -64,21 +55,21 @@
     ${element_type}(40), ${element_type}(50), ${element_type}(60),
     ${element_type}(70)
   ]]
-  let identityOuter = a.identity
-  var identityInner = a[0].identity
+  let identityOuter = a._bufferID
+  var identityInner = a[0]._bufferID
 
   func checkIdentity(_ stackTrace: SourceLocStack) {
 %     if element_type == 'TestValueTy':
     // Does not reallocate storage because we changed a property based on a
     // reference; array storage was not changed.  Writeback of the inner array
     // does not happen.
-    expectEqual(identityOuter, a.identity, stackTrace: stackTrace)
-    expectEqual(identityInner, a[0].identity, stackTrace: stackTrace)
+    expectEqual(identityOuter, a._bufferID, stackTrace: stackTrace)
+    expectEqual(identityInner, a[0]._bufferID, stackTrace: stackTrace)
 %     else:
-    expectEqual(identityOuter, a.identity, stackTrace: stackTrace)
+    expectEqual(identityOuter, a._bufferID, stackTrace: stackTrace)
 
     // Should not reallocate storage.
-    expectEqual(identityInner, a[0].identity, stackTrace: stackTrace)
+    expectEqual(identityInner, a[0]._bufferID, stackTrace: stackTrace)
 %     end
   }
 
@@ -134,23 +125,23 @@
     ${element_type}(40), ${element_type}(50), ${element_type}(60),
     ${element_type}(70), ${element_type}(80), ${element_type}(90),
   ]]
-  let identityOuter = a.identity
-  var identityInner = a[0].identity
+  let identityOuter = a._bufferID
+  var identityInner = a[0]._bufferID
 
   func checkIdentity(_ stackTrace: SourceLocStack) {
 %     if element_type == 'TestValueTy':
     // Does not reallocate storage because we changed a property based on a
     // reference; array storage was not changed.
-    expectEqual(identityOuter, a.identity, stackTrace: stackTrace)
-    expectEqual(identityInner, a[0].identity, stackTrace: stackTrace)
+    expectEqual(identityOuter, a._bufferID, stackTrace: stackTrace)
+    expectEqual(identityInner, a[0]._bufferID, stackTrace: stackTrace)
 %     else:
-    expectEqual(identityOuter, a.identity, stackTrace: stackTrace)
+    expectEqual(identityOuter, a._bufferID, stackTrace: stackTrace)
     // Writeback happens in subscript(Range<Int>), but array notices that the new
     // value did not change.
     // Another writeback happens in Array.subscript(Int), but this is not what we
     // want.
-    expectNotEqual(identityInner, a[0].identity, stackTrace: stackTrace)
-    identityInner = a[0].identity
+    expectNotEqual(identityInner, a[0]._bufferID, stackTrace: stackTrace)
+    identityInner = a[0]._bufferID
 %     end
   }
 
@@ -158,9 +149,9 @@
   a[0..<1][0][0] = ${element_type}(1010)
 
   // Reallocates storage because of the writeback in Array.subscript(Int).
-  expectEqual(identityOuter, a.identity)
-  expectNotEqual(identityInner, a[0].identity)
-  identityInner = a[0].identity
+  expectEqual(identityOuter, a._bufferID)
+  expectNotEqual(identityInner, a[0]._bufferID)
+  identityInner = a[0]._bufferID
 
   a[0..<1][0][1].value = 1020
 
@@ -195,9 +186,9 @@
   // Reallocates storage because of the writeback in Array.subscript(Int)
   // (writeback is being requested for the array element even though it is not
   // needed).
-  expectEqual(identityOuter, a.identity)
-  expectNotEqual(identityInner, a[0].identity)
-  identityInner = a[0].identity
+  expectEqual(identityOuter, a._bufferID)
+  expectNotEqual(identityInner, a[0]._bufferID)
+  identityInner = a[0]._bufferID
 
   withInoutT(&a[0..<1][0][6].value) {
     (x: inout Int) in
diff --git a/validation-test/stdlib/Arrays.swift.gyb b/validation-test/stdlib/Arrays.swift.gyb
index 6c56286..def3a35 100644
--- a/validation-test/stdlib/Arrays.swift.gyb
+++ b/validation-test/stdlib/Arrays.swift.gyb
@@ -73,23 +73,14 @@
 all_array_types = ['ContiguousArray', 'ArraySlice', 'Array']
 }%
 
-extension Array {
-  var identity: UnsafeRawPointer {
-    return self._buffer.identity
+%for Self in all_array_types:
+extension ${Self} {
+  typealias _BufferID = UnsafeRawPointer?
+  var _bufferID: _BufferID {
+    return unsafeBitCast(_owner, to: _BufferID.self)
   }
 }
-
-extension ArraySlice {
-  var identity: UnsafeRawPointer {
-    return self._buffer.identity
-  }
-}
-
-extension ContiguousArray {
-  var identity: UnsafeRawPointer {
-    return self._buffer.identity
-  }
-}
+%end
 
 var ArrayTestSuite = TestSuite("Array")
 
@@ -246,10 +237,10 @@
   let arr0 = ${array_type}<Int>()
   let arr1 = ${array_type}<LifetimeTracked>(repeating: LifetimeTracked(0), count: 0)
   // Empty arrays all use the same buffer
-  expectEqual(arr0._buffer.identity, arr1._buffer.identity)
+  expectEqual(arr0._bufferID, arr1._bufferID)
 
   let arr2: ${array_type}<LifetimeTracked> = []
-  let emptyLiteralsShareBuffer = arr0._buffer.identity == arr2._buffer.identity
+  let emptyLiteralsShareBuffer = arr0._bufferID == arr2._bufferID
   expectTrue(emptyLiteralsShareBuffer)
 }
 
diff --git a/validation-test/stdlib/NewArray.swift.gyb b/validation-test/stdlib/NewArray.swift.gyb
index 1e3a19a..80e33c2 100644
--- a/validation-test/stdlib/NewArray.swift.gyb
+++ b/validation-test/stdlib/NewArray.swift.gyb
@@ -32,16 +32,39 @@
   print("]")
 }
 
-typealias BufferID = UnsafeRawPointer?
+typealias _BufferID = UnsafeRawPointer?
 
-func bufferID<T : _ArrayProtocol>(_ x: T) -> BufferID {
-  return x._buffer.identity
+protocol MyArrayProtocol
+  : RandomAccessCollection,
+    RangeReplaceableCollection,
+    MutableCollection,
+    ArrayLiteralConvertible {
+
+  associatedtype Iterator : IteratorProtocol
+
+  var _owner: AnyObject? { get }
+
+  var capacity: Int { get }
+
+  func += <
+    S : Sequence
+    where
+    S.Iterator.Element == Iterator.Element
+  >(lhs: inout Self, rhs: S)
 }
+extension MyArrayProtocol {
+  var _bufferID: _BufferID {
+    return unsafeBitCast(_owner, to: _BufferID.self)
+  }
+}
+extension Array : MyArrayProtocol {}
+extension ArraySlice : MyArrayProtocol {}
+extension ContiguousArray : MyArrayProtocol {}
 
-func checkReallocation<T : _ArrayProtocol>(
-  _ x: T, _ lastBuffer: BufferID, _ reallocationExpected: Bool
-) -> BufferID {
-  let currentBuffer = bufferID(x)
+func checkReallocation<T : MyArrayProtocol>(
+  _ x: T, _ lastBuffer: _BufferID, _ reallocationExpected: Bool
+) -> _BufferID {
+  let currentBuffer = x._bufferID
   if (currentBuffer != lastBuffer) != reallocationExpected {
     let message = reallocationExpected ? "lack of" : ""
     print("unexpected \(message) reallocation")
@@ -62,13 +85,12 @@
 }
 
 func test<
-  T : _ArrayProtocol
+  T : MyArrayProtocol
   where
-  T.Iterator.Element == T._Buffer.Element,
-  T._Buffer.Element == T.Element,
-  T.Element == LifetimeTracked,
+  T.Iterator.Element == LifetimeTracked,
+  T.Iterator.Element == T.Element,
   T.Index == Int,
-  T : RandomAccessCollection
+  T.IndexDistance == Int
 >(_: T.Type, _ label: String) {
   print("test: \(label)...", terminator: "")
 
@@ -85,7 +107,7 @@
   x.reserveCapacity(x.count + 2)
   checkEqual(x, LifetimeTracked(1)...LifetimeTracked(5), true)
   
-  let bufferId0 = bufferID(x)
+  let bufferId0 = x._bufferID
 
   // Append a range of integers
   x += LifetimeTracked(0)..<LifetimeTracked(2)
@@ -113,9 +135,9 @@
     // has shown that using 1.5, the other popular growth factor,
     // slows things down.
     for _ in a.count..<(a.capacity * 4) {
-      let oldId = bufferID(a)
+      let oldId = a._bufferID
       growBy1(&a)
-      if oldId != bufferID(a) {
+      if oldId != a._bufferID {
         reallocations += 1
       }
     }
@@ -156,29 +178,29 @@
   // CHECK: == AsArray == 
   
   let x = ContiguousArray(w)
-  print(bufferID(w) == bufferID(x))
+  print(w._bufferID == x._bufferID)
   // CHECK-NEXT: true
   
   let y = Array(x)
-  print(bufferID(x) == bufferID(y))
+  print(x._bufferID == y._bufferID)
   // CHECK-NEXT: true
 
   // Because of their indirection, arrays of classes can share
   // buffers.  
   let y1 = Array(y)
-  print(bufferID(y1) == bufferID(y))
+  print(y1._bufferID == y._bufferID)
   // CHECK-NEXT: true
   
   let z = ArraySlice(y)
-  print(bufferID(y) == bufferID(z))
+  print(y._bufferID == z._bufferID)
   // CHECK-NEXT: true
 
   w = ContiguousArray(z)
-  print(bufferID(w) == bufferID(z))
+  print(w._bufferID == z._bufferID)
   // CHECK-NEXT: true
 
   let zz = y[0..<2]
-  print(bufferID(zz))
+  print(zz._bufferID)
   // CHECK-NEXT: 0x
 }
 testAsArray()
diff --git a/validation-test/stdlib/StringViews.swift b/validation-test/stdlib/StringViews.swift
index ef0cc6a..3f8da63 100644
--- a/validation-test/stdlib/StringViews.swift
+++ b/validation-test/stdlib/StringViews.swift
@@ -14,6 +14,7 @@
 
 import Swift
 import StdlibUnittest
+import StdlibCollectionUnittest
 
 #if _runtime(_ObjC)
 // FIXME: Foundation leaks through StdlibUnittest.  It adds some conformances
@@ -740,5 +741,123 @@
   }
 }
 
+struct StringViewTest {
+  var string: String
+  var utf8: [UInt8]
+  var utf16: [UInt16]
+  var unicodeScalars: [UnicodeScalar]
+
+  init(string: String, utf8: [UInt8], utf16: [UInt16], utf32: [UInt32]) {
+    self.string = string
+    self.utf8 = utf8
+    self.utf16 = utf16
+    self.unicodeScalars = utf32.map { UnicodeScalar($0)! }
+  }
+}
+
+var stringViewTests: [StringViewTest] = [
+  StringViewTest(
+    string: "",
+    utf8: [],
+    utf16: [],
+    utf32: []),
+  StringViewTest(
+    string: "\u{0000}",
+    utf8: [0x00],
+    utf16: [0x00],
+    utf32: [0x00]),
+  StringViewTest(
+    string: "a",
+    utf8: [0x61],
+    utf16: [0x61],
+    utf32: [0x61]),
+  StringViewTest(
+    string: "aa",
+    utf8: [0x61, 0x61],
+    utf16: [0x61, 0x61],
+    utf32: [0x61, 0x61]),
+  StringViewTest(
+    string: "ab",
+    utf8: [0x61, 0x62],
+    utf16: [0x61, 0x62],
+    utf32: [0x61, 0x62]),
+  StringViewTest(
+    string: "abc",
+    utf8: [0x61, 0x62, 0x63],
+    utf16: [0x61, 0x62, 0x63],
+    utf32: [0x61, 0x62, 0x63]),
+  StringViewTest(
+    string: "\u{007f}",
+    utf8: [0x7f],
+    utf16: [0x7f],
+    utf32: [0x7f]),
+  StringViewTest(
+    string: "\u{0430}",
+    utf8: [0xd0, 0xb0],
+    utf16: [0x0430],
+    utf32: [0x0430]),
+  StringViewTest(
+    string: "\u{0430}\u{0431}\u{0432}",
+    utf8: [0xd0, 0xb0, 0xd0, 0xb1, 0xd0, 0xb2],
+    utf16: [0x0430, 0x0431, 0x0432],
+    utf32: [0x0430, 0x0431, 0x0432]),
+  StringViewTest(
+    string: "\u{1f425}",
+    utf8: [0xf0, 0x9f, 0x90, 0xa5],
+    utf16: [0xd83d, 0xdc25],
+    utf32: [0x1f425]),
+]
+
+#if _runtime(_ObjC)
+tests.test("String.UTF16View.Index/Strideable")
+  .forEach(in: stringViewTests) {
+  test in
+
+  func allIndices<C : Collection>(of c: C) -> [C.Index]
+  where C.Indices.Iterator.Element == C.Index
+  {
+    var result = Array(c.indices)
+    result.append(c.endIndex)
+    return result
+  }
+
+  checkStrideable(
+    instances: allIndices(of: test.string.utf16),
+    distances: Array(0..<test.string.utf16.count),
+    distanceOracle: { $1 - $0 })
+}
+#endif
+
+tests.test("String.UTF8View/Collection")
+  .forEach(in: stringViewTests) {
+  test in
+
+  // FIXME(ABI): should be `checkBidirectionalCollection`.
+  checkForwardCollection(test.utf8, test.string.utf8) { $0 == $1 }
+}
+
+#if _runtime(_Native)
+tests.test("String.UTF16View/BidirectionalCollection")
+  .forEach(in: stringViewTests) {
+  test in
+
+  checkBidirectionalCollection(test.utf16, test.string.utf16) { $0 == $1 }
+}
+#else
+tests.test("String.UTF16View/RandomAccessCollection")
+  .forEach(in: stringViewTests) {
+  test in
+
+  checkRandomAccessCollection(test.utf16, test.string.utf16) { $0 == $1 }
+}
+#endif
+
+tests.test("String.UTF32View/BidirectionalCollection")
+  .forEach(in: stringViewTests) {
+  test in
+
+  checkBidirectionalCollection(
+    test.unicodeScalars, test.string.unicodeScalars) { $0 == $1 }
+}
 
 runAllTests()