Merge pull request #7431 from moiseev/split-3.1

Avoid timeout issues on the 3.1 branch.
diff --git a/test/stdlib/Inputs/CommonArrayTests.gyb b/test/stdlib/Inputs/CommonArrayTests.gyb
new file mode 100644
index 0000000..f0a2e1f
--- /dev/null
+++ b/test/stdlib/Inputs/CommonArrayTests.gyb
@@ -0,0 +1,408 @@
+% # This template was extracted from the Arrays.swift.gyb in order to split
+% # that file into multiple to parallelize test execution.
+%
+% # Template caller should define the following context:
+% #   - Suite -- an identifier for the test suite to append tests to.
+% #   - ArrayType -- the type being tested.
+
+
+extension ${ArrayType} {
+  typealias _BufferID = UnsafeRawPointer?
+  var _bufferID: _BufferID {
+    return unsafeBitCast(_owner, to: _BufferID.self)
+  }
+}
+
+protocol TestProtocol1 {}
+
+extension ${ArrayType} where Element : TestProtocol1 {
+  var _elementIsTestProtocol1: Bool {
+    fatalError("not implemented")
+  }
+}
+
+/// Returns an ${ArrayType} that does not share its buffer with other arrays.
+func getFresh${ArrayType}<S : Sequence>(_ sequence: S)
+  -> ${ArrayType}<S.Iterator.Element> {
+  var result: ${ArrayType}<S.Iterator.Element> = []
+  result.reserveCapacity(sequence.underestimatedCount)
+  for element in sequence {
+    result.append(element)
+  }
+  return result
+}
+
+struct SequenceWithCustomUnderestimatedCount : Sequence {
+  init(_ data: [Int]) {
+    self._data = MinimalSequence(elements: data.map(OpaqueValue.init))
+  }
+
+  func makeIterator() -> MinimalSequence<OpaqueValue<Int>>.Iterator {
+    return _data.makeIterator()
+  }
+
+  var underestimatedCount: Int {
+    SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled += 1
+    return _data.underestimatedCount
+  }
+
+  static var timesUnderestimatedCountWasCalled: Int = 0
+
+  let _data: MinimalSequence<OpaqueValue<Int>>
+}
+
+${Suite}.test("${ArrayType}/init(Sequence)") {
+  let base = SequenceWithCustomUnderestimatedCount(
+    [ 0, 30, 10, 90 ])
+
+  SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled = 0
+
+  let result = ${ArrayType}(base)
+
+  expectEqual([ 0, 30, 10, 90 ], result.map { $0.value })
+
+  expectEqual(1, SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled)
+
+  expectEqualSequence(
+    [], Array(base).map { $0.value }, "sequence should be consumed")
+}
+
+enum EnumWithoutPayloads : Equatable {
+  case A, B, C, D
+}
+
+func == (lhs: EnumWithoutPayloads, rhs: EnumWithoutPayloads) -> Bool {
+  switch (lhs, rhs) {
+  case (.A, .A), (.B, .B), (.C, .C), (.D, .D):
+    return true
+
+  default:
+    return false
+  }
+}
+
+${Suite}.test("${ArrayType}/Sliceable/Enums") {
+  typealias E = EnumWithoutPayloads
+
+  do {
+    let expected = [E.A, E.B, E.C, E.D]
+    let sliceable = ${ArrayType}(expected)
+    checkSliceableWithBidirectionalIndex(expected, sliceable)
+  }
+
+  /*
+  FIXME: add this test when Array<T> can be conditionally Equatable.
+  do {
+    let expected = [[E.A, E.B], [E.B, E.C], [E.D], [E.A, E.B, E.D]]
+    let sliceable = ${ArrayType}(expected)
+    checkSliceableWithBidirectionalIndex(
+      expected, sliceable, SourceLocStack().withCurrentLoc())
+  }
+  */
+}
+
+${Suite}.test("${ArrayType}/appendNonUnique") {
+  var x: ${ArrayType}<Int> = []
+  x.reserveCapacity(10002)
+  let capacity = x.capacity
+  for _ in 1...10000 {
+    let y = x
+    x.append(1)
+    expectTrue(x.capacity == capacity)
+    let z = x
+    x.remove(at: 0)
+  }
+}
+
+${Suite}.test("${ArrayType}/appendUndercountedCollection") {
+  // test that the array safely handles a
+  // collection that understates its count
+  var i = 0
+  let l = repeatElement(42, count: 10_000).lazy
+         // capture i by reference and change behavior
+         // between first pass (for count) and second
+         .filter { _ in i += 1; return i > 10_000 }
+  var a: ${ArrayType}<Int> = []
+  a.append(contentsOf: l)
+}
+
+${Suite}.test("${ArrayType}/emptyAllocation") {
+  let arr0 = ${ArrayType}<Int>()
+  let arr1 = ${ArrayType}<LifetimeTracked>(repeating: LifetimeTracked(0), count: 0)
+  // Empty arrays all use the same buffer
+  expectEqual(arr0._bufferID, arr1._bufferID)
+
+  let arr2: ${ArrayType}<LifetimeTracked> = []
+  let emptyLiteralsShareBuffer = arr0._bufferID == arr2._bufferID
+  expectTrue(emptyLiteralsShareBuffer)
+}
+
+${Suite}.test("${ArrayType}/filter") {
+  do {
+    let arr: ${ArrayType}<Int> = []
+    var result = arr.filter() {
+      (x: Int) -> Bool in
+      expectUnreachable()
+      return true
+    }
+    expectType(Array<Int>.self, &result)
+    expectEqual([], result)
+    expectEqual(0, result.capacity)
+  }
+  do {
+    let arr: ${ArrayType}<Int> = [ 0, 30, 10, 90 ]
+    let result = arr.filter() { (x: Int) -> Bool in true }
+    expectEqual([ 0, 30, 10, 90 ], result)
+    expectGE(2 * result.count, result.capacity)
+  }
+  do {
+    let arr: ${ArrayType}<Int> = [ 0, 30, 10, 90 ]
+    let result = arr.filter() { (x: Int) -> Bool in false }
+    expectEqual([], result)
+    expectGE(2 * result.count, result.capacity)
+  }
+  do {
+    let arr: ${ArrayType}<Int> = [ 0, 30, 10, 90 ]
+    let result = arr.filter() { $0 % 3 == 0 }
+    expectEqual([ 0, 30, 90 ], result)
+    expectGE(2 * result.count, result.capacity)
+  }
+}
+
+${Suite}.test("${ArrayType}/map") {
+  do {
+    let arr: ${ArrayType}<Int> = []
+    var result = arr.map() {
+      (x: Int) -> Int16 in
+      expectUnreachable()
+      return 42
+    }
+    expectType(Array<Int16>.self, &result)
+    expectEqual([], result)
+    expectEqual(0, result.capacity)
+  }
+  do {
+    let arr: ${ArrayType}<Int> = [ 0, 30, 10, 90 ]
+    let result = arr.map() { $0 + 1 }
+    expectEqual([ 1, 31, 11, 91 ], result)
+    expectGE(2 * result.count, result.capacity)
+  }
+}
+
+${Suite}.test("${ArrayType}/flatMap") {
+  let enumerate : (Int) -> ${ArrayType}<Int> =
+    { return ${ArrayType}(1..<($0 + 1)) }
+  expectEqualSequence([], ${ArrayType}().flatMap(enumerate))
+  expectEqualSequence([ 1 ], ${ArrayType}([ 1 ]).flatMap(enumerate))
+  expectEqualSequence(
+    [ 1, 1, 2 ],
+    ${ArrayType}([ 1, 2 ]).flatMap(enumerate))
+  expectEqualSequence(
+    [ 1, 1, 1, 2 ],
+    ${ArrayType}([ 1, 2 ]).flatMap(enumerate).flatMap(enumerate))
+}
+
+${Suite}.test("${ArrayType}/Mirror") {
+  do {
+    let input: ${ArrayType}<Int> = []
+    var output = ""
+    dump(input, to: &output)
+
+    let expected =
+      "- 0 elements\n"
+
+    expectEqual(expected, output)
+  }
+  do {
+    let input: ${ArrayType}<Int> = [ 10, 20, 30, 40 ]
+    var output = ""
+    dump(input, to: &output)
+
+    let expected =
+      "▿ 4 elements\n" +
+      "  - 10\n" +
+      "  - 20\n" +
+      "  - 30\n" +
+      "  - 40\n"
+
+    expectEqual(expected, output)
+  }
+%   if ArrayType == 'ArraySlice':
+  do {
+    let base = [ 10, 20, 30, 40 ]
+    let input: ArraySlice<Int> = base[1..<3]
+    var output = ""
+    dump(input, to: &output)
+
+    let expected =
+      "▿ 2 elements\n" +
+      "  - 20\n" +
+      "  - 30\n"
+
+    expectEqual(expected, output)
+  }
+%   end
+}
+
+//===----------------------------------------------------------------------===//
+// _withUnsafeMutableBufferPointerIfSupported()
+//===----------------------------------------------------------------------===//
+
+struct WithUnsafeMutableBufferPointerIfSupportedTest {
+  let sequence: [Int]
+  let loc: SourceLoc
+
+  init(
+    _ sequence: [Int],
+    file: String = #file, line: UInt = #line
+  ) {
+    self.sequence = sequence
+    self.loc = SourceLoc(file, line, comment: "test data")
+  }
+}
+
+let withUnsafeMutableBufferPointerIfSupportedTests = [
+  WithUnsafeMutableBufferPointerIfSupportedTest([]),
+  WithUnsafeMutableBufferPointerIfSupportedTest([ 10 ]),
+  WithUnsafeMutableBufferPointerIfSupportedTest([ 10, 20, 30, 40, 50 ]),
+]
+
+${Suite}.test("${ArrayType}/_withUnsafeMutableBufferPointerIfSupported") {
+  for test in withUnsafeMutableBufferPointerIfSupportedTests {
+    var a = getFresh${ArrayType}(test.sequence.map(OpaqueValue.init))
+    do {
+      // Read.
+      var result = a._withUnsafeMutableBufferPointerIfSupported {
+        (baseAddress, count) -> OpaqueValue<[OpaqueValue<Int>]> in
+        let bufferPointer =
+          UnsafeMutableBufferPointer(start: baseAddress, count: count)
+        return OpaqueValue(Array(bufferPointer))
+      }
+      expectType(Optional<OpaqueValue<Array<OpaqueValue<Int>>>>.self, &result)
+      expectEqualSequence(test.sequence, result!.value.map { $0.value })
+      expectEqualSequence(test.sequence, a.map { $0.value })
+    }
+    do {
+      // Read and write.
+      var result = a._withUnsafeMutableBufferPointerIfSupported {
+        (baseAddress, count) -> OpaqueValue<Array<OpaqueValue<Int>>> in
+        let bufferPointer =
+          UnsafeMutableBufferPointer(start: baseAddress, count: count)
+        let result = OpaqueValue(Array(bufferPointer))
+        for i in bufferPointer.indices {
+          bufferPointer[i] = OpaqueValue(bufferPointer[i].value * 10)
+        }
+        return result
+      }
+      expectType(Optional<OpaqueValue<Array<OpaqueValue<Int>>>>.self, &result)
+      expectEqualSequence(test.sequence, result!.value.map { $0.value })
+      expectEqualSequence(
+        test.sequence.map { $0 * 10 },
+        a.map { $0.value })
+    }
+  }
+  // FIXME: tests for arrays bridged from Objective-C.
+}
+
+${Suite}.test("${ArrayType}/_withUnsafeMutableBufferPointerIfSupported/ReplacingTheBufferTraps/1") {
+  var a = getFresh${ArrayType}([ OpaqueValue(10) ])
+  var result = a._withUnsafeMutableBufferPointerIfSupported {
+    (baseAddress, count) -> OpaqueValue<Int> in
+    // buffer = UnsafeMutableBufferPointer(start: buffer.baseAddress, count: 0)
+    // FIXME: does not trap since the buffer is not passed inout.
+    // expectCrashLater()
+    return OpaqueValue(42)
+  }
+}
+
+${Suite}.test("${ArrayType}/_withUnsafeMutableBufferPointerIfSupported/ReplacingTheBufferTraps/2") {
+  var a = getFresh${ArrayType}([ OpaqueValue(10) ])
+  var result = a._withUnsafeMutableBufferPointerIfSupported {
+    (baseAddress, count) -> OpaqueValue<Int> in
+    // buffer = UnsafeMutableBufferPointer(start: nil, count: 1)
+    // FIXME: does not trap since the buffer is not passed inout.
+    // expectCrashLater()
+    return OpaqueValue(42)
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// withUnsafeMutableBytes
+//===----------------------------------------------------------------------===//
+
+// Test the uniqueness of the raw buffer.
+${Suite}.test("${ArrayType}/withUnsafeMutableBytes") {
+  var a = getFresh${ArrayType}([UInt8](repeating: 10, count: 1))
+  let b = a
+  a.withUnsafeMutableBytes { bytes in
+    bytes[0] = 42
+  }
+  expectEqual(42, a[0])
+  expectEqual(10, b[0])
+}
+
+//===---
+// Check that iterators traverse a snapshot of the collection.
+//===---
+
+${Suite}.test(
+  "${ArrayType}/mutationDoesNotAffectIterator/subscript/store") {
+  var arr: ${ArrayType}<Int> = [ 1010, 1020, 1030 ]
+  var iter = arr.makeIterator()
+  arr[0] = 1011
+  expectEqual([ 1010, 1020, 1030 ], Array(IteratorSequence(iter)))
+}
+
+${Suite}.test(
+  "${ArrayType}/mutationDoesNotAffectIterator/subscript/append") {
+  var arr: ${ArrayType}<Int> = [ 1010, 1020, 1030 ]
+  var iter = arr.makeIterator()
+  arr.append(1040)
+  expectEqual([ 1010, 1020, 1030 ], Array(IteratorSequence(iter)))
+}
+
+${Suite}.test(
+  "${ArrayType}/mutationDoesNotAffectIterator/subscript/replaceSubrange") {
+  var arr: ${ArrayType}<Int> = [ 1010, 1020, 1030 ]
+  var iter = arr.makeIterator()
+  arr.replaceSubrange(1..<3, with: [ 1040, 1050, 1060 ])
+  expectEqual([ 1010, 1020, 1030 ], Array(IteratorSequence(iter)))
+}
+
+//===----------------------------------------------------------------------===//
+// Special cases and one-off tests.
+//===----------------------------------------------------------------------===//
+
+${Suite}.test("${ArrayType}<Void>/map") {
+  // This code used to crash because it generated an array of Void with
+  // stride == 0.
+  do {
+    let input: ${ArrayType}<Void> = [ (), (), () ]
+    let result = input.map { (_) -> Void in return () }
+    expectEqual(3, result.count)
+  }
+
+  do {
+    let input: ${ArrayType}<OpaqueValue<Int>> = [
+      OpaqueValue(10), OpaqueValue(20), OpaqueValue(30)
+    ]
+    let result = input.map { (_) -> Void in return () }
+    expectEqual(3, result.count)
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// MutableCollectionType and RangeReplaceableCollectionType conformance tests.
+//===----------------------------------------------------------------------===//
+
+${Suite}.test("${ArrayType}/AssociatedTypes") {
+  typealias Collection = ${ArrayType}<OpaqueValue<Int>>
+  typealias CollectionSlice = ArraySlice<OpaqueValue<Int>>
+  expectCollectionAssociatedTypes(
+    collectionType: Collection.self,
+    iteratorType: IndexingIterator<Collection>.self,
+    subSequenceType: CollectionSlice.self,
+    indexType: Int.self,
+    indexDistanceType: Int.self,
+    indicesType: CountableRange<Int>.self)
+}
diff --git a/validation-test/stdlib/Array.swift.gyb b/validation-test/stdlib/Array.swift.gyb
new file mode 100644
index 0000000..aa00b1d
--- /dev/null
+++ b/validation-test/stdlib/Array.swift.gyb
@@ -0,0 +1,18 @@
+// RUN: %target-run-simple-swiftgyb
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+% import os.path
+% import gyb
+% ArrayType = 'Array'
+
+var ${ArrayType}TestSuite = TestSuite("${ArrayType}")
+
+% CommonTestsTemplate = gyb.parse_template(os.path.join(os.path.dirname(__file__), "Inputs/CommonArrayTests.gyb"))
+% CommonTests = gyb.execute_template(CommonTestsTemplate, Suite=ArrayType+'TestSuite', ArrayType=ArrayType)
+
+${CommonTests}
+
+runAllTests()
diff --git a/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_MutableRandomAccessCollectionRef.swift b/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_MutableRandomAccessCollectionRef.swift
new file mode 100644
index 0000000..194bcfd
--- /dev/null
+++ b/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_MutableRandomAccessCollectionRef.swift
@@ -0,0 +1,60 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ArraySliceWithNonZeroStartIndex_MutableRandomAccessCollectionRef")
+
+
+func ArraySliceWithNonZeroStartIndex<T>(_ elements: [T]) -> ArraySlice<T> {
+  var r = ArraySlice<T>(_startIndex: 1000)
+  r.append(contentsOf: elements)
+  expectEqual(1000, r.startIndex)
+  return r
+}
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test MutableCollectionType conformance with reference type elements.
+  tests.addMutableRandomAccessCollectionTests(
+    "ArraySliceWithNonZeroStartIndex.",
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return ArraySliceWithNonZeroStartIndex(elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ArraySliceWithNonZeroStartIndex(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ArraySliceWithNonZeroStartIndex(elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks,
+    withUnsafeMutableBufferPointerIsSupported: true,
+    isFixedLengthCollection: false)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_MutableRandomAccessCollectionVal.swift b/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_MutableRandomAccessCollectionVal.swift
new file mode 100644
index 0000000..50dde39
--- /dev/null
+++ b/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_MutableRandomAccessCollectionVal.swift
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ArraySliceWithNonZeroStartIndex_MutableRandomAccessCollectionVal")
+
+
+func ArraySliceWithNonZeroStartIndex<T>(_ elements: [T]) -> ArraySlice<T> {
+  var r = ArraySlice<T>(_startIndex: 1000)
+  r.append(contentsOf: elements)
+  expectEqual(1000, r.startIndex)
+  return r
+}
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test MutableCollectionType conformance with value type elements.
+  tests.addMutableRandomAccessCollectionTests(
+    "ArraySliceWithNonZeroStartIndex.",
+    makeCollection: { (elements: [OpaqueValue<Int>]) in
+      return ArraySliceWithNonZeroStartIndex(elements)
+    },
+    wrapValue: identity,
+    extractValue: identity,
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      return ArraySliceWithNonZeroStartIndex(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      return ArraySliceWithNonZeroStartIndex(elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks,
+    withUnsafeMutableBufferPointerIsSupported: true,
+    isFixedLengthCollection: false)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_RangeReplaceableRandomAccessCollectionRef.swift b/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_RangeReplaceableRandomAccessCollectionRef.swift
new file mode 100644
index 0000000..7d9a41b
--- /dev/null
+++ b/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_RangeReplaceableRandomAccessCollectionRef.swift
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ArraySliceWithNonZeroStartIndex_RangeReplaceableRandomAccessCollectionRef")
+
+
+func ArraySliceWithNonZeroStartIndex<T>(_ elements: [T]) -> ArraySlice<T> {
+  var r = ArraySlice<T>(_startIndex: 1000)
+  r.append(contentsOf: elements)
+  expectEqual(1000, r.startIndex)
+  return r
+}
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test RangeReplaceableCollectionType conformance with reference type elements.
+  tests.addRangeReplaceableRandomAccessSliceTests(
+    "ArraySliceWithNonZeroStartIndex.",
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return ArraySliceWithNonZeroStartIndex(elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in LifetimeTracked(element.value) },
+    extractValue: { (element: LifetimeTracked) in OpaqueValue(element.value) },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ArraySliceWithNonZeroStartIndex(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_RangeReplaceableRandomAccessCollectionVal.swift b/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_RangeReplaceableRandomAccessCollectionVal.swift
new file mode 100644
index 0000000..7761e38
--- /dev/null
+++ b/validation-test/stdlib/Array/ArraySliceWithNonZeroStartIndex_RangeReplaceableRandomAccessCollectionVal.swift
@@ -0,0 +1,47 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ArraySliceWithNonZeroStartIndex_RangeReplaceableRandomAccessCollectionVal")
+
+
+func ArraySliceWithNonZeroStartIndex<T>(_ elements: [T]) -> ArraySlice<T> {
+  var r = ArraySlice<T>(_startIndex: 1000)
+  r.append(contentsOf: elements)
+  expectEqual(1000, r.startIndex)
+  return r
+}
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test RangeReplaceableCollectionType conformance with value type elements.
+  tests.addRangeReplaceableRandomAccessSliceTests(
+    "ArraySliceWithNonZeroStartIndex.",
+    makeCollection: { (elements: [OpaqueValue<Int>]) in
+      return ArraySliceWithNonZeroStartIndex(elements)
+    },
+    wrapValue: identity,
+    extractValue: identity,
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      return ArraySliceWithNonZeroStartIndex(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ArraySlice_MutableRandomAccessCollectionRef.swift b/validation-test/stdlib/Array/ArraySlice_MutableRandomAccessCollectionRef.swift
new file mode 100644
index 0000000..f79cc6b
--- /dev/null
+++ b/validation-test/stdlib/Array/ArraySlice_MutableRandomAccessCollectionRef.swift
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ArraySlice_MutableRandomAccessCollectionRef")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test MutableCollectionType conformance with reference type elements.
+  tests.addMutableRandomAccessCollectionTests(
+    "ArraySlice.",
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return ArraySlice(elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ArraySlice(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ArraySlice(elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks,
+    withUnsafeMutableBufferPointerIsSupported: true,
+    isFixedLengthCollection: false)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ArraySlice_MutableRandomAccessCollectionVal.swift b/validation-test/stdlib/Array/ArraySlice_MutableRandomAccessCollectionVal.swift
new file mode 100644
index 0000000..281169b
--- /dev/null
+++ b/validation-test/stdlib/Array/ArraySlice_MutableRandomAccessCollectionVal.swift
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ArraySlice_MutableRandomAccessCollectionVal")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test MutableCollectionType conformance with value type elements.
+  tests.addMutableRandomAccessCollectionTests(
+    "ArraySlice.",
+    makeCollection: { (elements: [OpaqueValue<Int>]) in
+      return ArraySlice(elements)
+    },
+    wrapValue: identity,
+    extractValue: identity,
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      return ArraySlice(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      return ArraySlice(elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks,
+    withUnsafeMutableBufferPointerIsSupported: true,
+    isFixedLengthCollection: false)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ArraySlice_RangeReplaceableRandomAccessCollectionRef.swift b/validation-test/stdlib/Array/ArraySlice_RangeReplaceableRandomAccessCollectionRef.swift
new file mode 100644
index 0000000..732923b
--- /dev/null
+++ b/validation-test/stdlib/Array/ArraySlice_RangeReplaceableRandomAccessCollectionRef.swift
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ArraySlice_RangeReplaceableRandomAccessCollectionRef")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test RangeReplaceableCollectionType conformance with reference type elements.
+  tests.addRangeReplaceableRandomAccessSliceTests(
+    "ArraySlice.",
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return ArraySlice(elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in LifetimeTracked(element.value) },
+    extractValue: { (element: LifetimeTracked) in OpaqueValue(element.value) },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ArraySlice(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ArraySlice_RangeReplaceableRandomAccessCollectionVal.swift b/validation-test/stdlib/Array/ArraySlice_RangeReplaceableRandomAccessCollectionVal.swift
new file mode 100644
index 0000000..d8a8c00
--- /dev/null
+++ b/validation-test/stdlib/Array/ArraySlice_RangeReplaceableRandomAccessCollectionVal.swift
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ArraySlice_RangeReplaceableRandomAccessCollectionVal")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test RangeReplaceableCollectionType conformance with value type elements.
+  tests.addRangeReplaceableRandomAccessSliceTests(
+    "ArraySlice.",
+    makeCollection: { (elements: [OpaqueValue<Int>]) in
+      return ArraySlice(elements)
+    },
+    wrapValue: identity,
+    extractValue: identity,
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      return ArraySlice(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/Array_MutableRandomAccessCollectionRef.swift b/validation-test/stdlib/Array/Array_MutableRandomAccessCollectionRef.swift
new file mode 100644
index 0000000..264c4d9
--- /dev/null
+++ b/validation-test/stdlib/Array/Array_MutableRandomAccessCollectionRef.swift
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("Array_MutableRandomAccessCollectionRef")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test MutableCollectionType conformance with reference type elements.
+  tests.addMutableRandomAccessCollectionTests(
+    "Array.",
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return Array(elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return Array(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return Array(elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks,
+    withUnsafeMutableBufferPointerIsSupported: true,
+    isFixedLengthCollection: false)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/Array_MutableRandomAccessCollectionVal.swift b/validation-test/stdlib/Array/Array_MutableRandomAccessCollectionVal.swift
new file mode 100644
index 0000000..5caad2f
--- /dev/null
+++ b/validation-test/stdlib/Array/Array_MutableRandomAccessCollectionVal.swift
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("Array_MutableRandomAccessCollectionVal")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test MutableCollectionType conformance with value type elements.
+  tests.addMutableRandomAccessCollectionTests(
+    "Array.",
+    makeCollection: { (elements: [OpaqueValue<Int>]) in
+      return Array(elements)
+    },
+    wrapValue: identity,
+    extractValue: identity,
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      return Array(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      return Array(elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks,
+    withUnsafeMutableBufferPointerIsSupported: true,
+    isFixedLengthCollection: false)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/Array_RangeReplaceableRandomAccessCollectionRef.swift b/validation-test/stdlib/Array/Array_RangeReplaceableRandomAccessCollectionRef.swift
new file mode 100644
index 0000000..c6dea31
--- /dev/null
+++ b/validation-test/stdlib/Array/Array_RangeReplaceableRandomAccessCollectionRef.swift
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("Array_RangeReplaceableRandomAccessCollectionRef")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test RangeReplaceableCollectionType conformance with reference type elements.
+  tests.addRangeReplaceableRandomAccessCollectionTests(
+    "Array.",
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return Array(elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in LifetimeTracked(element.value) },
+    extractValue: { (element: LifetimeTracked) in OpaqueValue(element.value) },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return Array(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/Array_RangeReplaceableRandomAccessCollectionVal.swift b/validation-test/stdlib/Array/Array_RangeReplaceableRandomAccessCollectionVal.swift
new file mode 100644
index 0000000..214ef56
--- /dev/null
+++ b/validation-test/stdlib/Array/Array_RangeReplaceableRandomAccessCollectionVal.swift
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("Array_RangeReplaceableRandomAccessCollectionVal")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test RangeReplaceableCollectionType conformance with value type elements.
+  tests.addRangeReplaceableRandomAccessCollectionTests(
+    "Array.",
+    makeCollection: { (elements: [OpaqueValue<Int>]) in
+      return Array(elements)
+    },
+    wrapValue: identity,
+    extractValue: identity,
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      return Array(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ContiguousArray_MutableRandomAccessCollectionRef.swift b/validation-test/stdlib/Array/ContiguousArray_MutableRandomAccessCollectionRef.swift
new file mode 100644
index 0000000..73f2526
--- /dev/null
+++ b/validation-test/stdlib/Array/ContiguousArray_MutableRandomAccessCollectionRef.swift
@@ -0,0 +1,54 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ContiguousArray_MutableRandomAccessCollectionRef")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test MutableCollectionType conformance with reference type elements.
+  tests.addMutableRandomAccessCollectionTests(
+    "ContiguousArray.",
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return ContiguousArray(elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ContiguousArray(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ContiguousArray(elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks,
+    withUnsafeMutableBufferPointerIsSupported: true,
+    isFixedLengthCollection: false)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ContiguousArray_MutableRandomAccessCollectionVal.swift b/validation-test/stdlib/Array/ContiguousArray_MutableRandomAccessCollectionVal.swift
new file mode 100644
index 0000000..67affd6
--- /dev/null
+++ b/validation-test/stdlib/Array/ContiguousArray_MutableRandomAccessCollectionVal.swift
@@ -0,0 +1,48 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ContiguousArray_MutableRandomAccessCollectionVal")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test MutableCollectionType conformance with value type elements.
+  tests.addMutableRandomAccessCollectionTests(
+    "ContiguousArray.",
+    makeCollection: { (elements: [OpaqueValue<Int>]) in
+      return ContiguousArray(elements)
+    },
+    wrapValue: identity,
+    extractValue: identity,
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      return ContiguousArray(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      return ContiguousArray(elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks,
+    withUnsafeMutableBufferPointerIsSupported: true,
+    isFixedLengthCollection: false)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ContiguousArray_RangeReplaceableRandomAccessCollectionRef.swift b/validation-test/stdlib/Array/ContiguousArray_RangeReplaceableRandomAccessCollectionRef.swift
new file mode 100644
index 0000000..e4f0988
--- /dev/null
+++ b/validation-test/stdlib/Array/ContiguousArray_RangeReplaceableRandomAccessCollectionRef.swift
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ContiguousArray_RangeReplaceableRandomAccessCollectionRef")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test RangeReplaceableCollectionType conformance with reference type elements.
+  tests.addRangeReplaceableRandomAccessCollectionTests(
+    "ContiguousArray.",
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return ContiguousArray(elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in LifetimeTracked(element.value) },
+    extractValue: { (element: LifetimeTracked) in OpaqueValue(element.value) },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ContiguousArray(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/ContiguousArray_RangeReplaceableRandomAccessCollectionVal.swift b/validation-test/stdlib/Array/ContiguousArray_RangeReplaceableRandomAccessCollectionVal.swift
new file mode 100644
index 0000000..9600b05
--- /dev/null
+++ b/validation-test/stdlib/Array/ContiguousArray_RangeReplaceableRandomAccessCollectionVal.swift
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("ContiguousArray_RangeReplaceableRandomAccessCollectionVal")
+
+
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+
+  // Test RangeReplaceableCollectionType conformance with value type elements.
+  tests.addRangeReplaceableRandomAccessCollectionTests(
+    "ContiguousArray.",
+    makeCollection: { (elements: [OpaqueValue<Int>]) in
+      return ContiguousArray(elements)
+    },
+    wrapValue: identity,
+    extractValue: identity,
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      return ContiguousArray(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks)
+
+
+} // do
+
+runAllTests()
+
diff --git a/validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb b/validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
new file mode 100644
index 0000000..829645a
--- /dev/null
+++ b/validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
@@ -0,0 +1,144 @@
+%{
+# This is a template for validation-test/stdlib/Array/*.swift
+#
+# Run it as follows:
+# cd validation-test/stdlib/Array
+# ../../../utils/gyb --line-directive="" Inputs/ArrayConformanceTests.swift.gyb | ../../../utils/split_file.py
+}%
+
+% all_array_types = ['ContiguousArray', 'ArraySlice', 'Array', 'ArraySliceWithNonZeroStartIndex']
+
+% for array_type in all_array_types:
+%   for conformance in [
+%     'MutableRandomAccessCollectionVal',
+%     'MutableRandomAccessCollectionRef',
+%     'RangeReplaceableRandomAccessCollectionVal',
+%     'RangeReplaceableRandomAccessCollectionRef']:
+%     collection_or_slice = 'Slice' if 'Slice' in array_type else 'Collection'
+%     test_name = array_type + '_' + conformance
+%     file_name = test_name + '.swift'
+// BEGIN ${file_name}
+//===----------------------------------------------------------------------===//
+// Automatically Generated From validation-test/stdlib/Array/Inputs/ArrayConformanceTests.swift.gyb
+// Do Not Edit Directly!
+//===----------------------------------------------------------------------===//
+
+// RUN: %target-run-simple-swift
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+
+let tests = TestSuite("${test_name}")
+
+
+%     if array_type == 'ArraySliceWithNonZeroStartIndex':
+func ArraySliceWithNonZeroStartIndex<T>(_ elements: [T]) -> ArraySlice<T> {
+  var r = ArraySlice<T>(_startIndex: 1000)
+  r.append(contentsOf: elements)
+  expectEqual(1000, r.startIndex)
+  return r
+}
+%     end
+
+do {
+  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
+  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
+
+%     if conformance == 'MutableRandomAccessCollectionVal':
+
+  // Test MutableCollectionType conformance with value type elements.
+  tests.addMutableRandomAccessCollectionTests(
+    "${array_type}.",
+    makeCollection: { (elements: [OpaqueValue<Int>]) in
+      return ${array_type}(elements)
+    },
+    wrapValue: identity,
+    extractValue: identity,
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      return ${array_type}(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      return ${array_type}(elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks,
+    withUnsafeMutableBufferPointerIsSupported: true,
+    isFixedLengthCollection: false)
+
+%     elif conformance == 'MutableRandomAccessCollectionRef':
+
+  // Test MutableCollectionType conformance with reference type elements.
+  tests.addMutableRandomAccessCollectionTests(
+    "${array_type}.",
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return ${array_type}(elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in
+      LifetimeTracked(element.value, identity: element.identity)
+    },
+    extractValue: { (element: LifetimeTracked) in
+      OpaqueValue(element.value, identity: element.identity)
+    },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ${array_type}(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ${array_type}(elements)
+    },
+    wrapValueIntoComparable: identityComp,
+    extractValueFromComparable: identityComp,
+    resiliencyChecks: resiliencyChecks,
+    withUnsafeMutableBufferPointerIsSupported: true,
+    isFixedLengthCollection: false)
+
+%     elif conformance == 'RangeReplaceableRandomAccessCollectionVal':
+
+  // Test RangeReplaceableCollectionType conformance with value type elements.
+  tests.addRangeReplaceableRandomAccess${collection_or_slice}Tests(
+    "${array_type}.",
+    makeCollection: { (elements: [OpaqueValue<Int>]) in
+      return ${array_type}(elements)
+    },
+    wrapValue: identity,
+    extractValue: identity,
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      return ${array_type}(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks)
+
+%     else: # conformance == 'RangeReplaceableRandomAccessCollectionRef'
+
+  // Test RangeReplaceableCollectionType conformance with reference type elements.
+  tests.addRangeReplaceableRandomAccess${collection_or_slice}Tests(
+    "${array_type}.",
+    makeCollection: { (elements: [LifetimeTracked]) in
+      return ${array_type}(elements)
+    },
+    wrapValue: { (element: OpaqueValue<Int>) in LifetimeTracked(element.value) },
+    extractValue: { (element: LifetimeTracked) in OpaqueValue(element.value) },
+    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
+      // FIXME: use LifetimeTracked.
+      return ${array_type}(elements)
+    },
+    wrapValueIntoEquatable: identityEq,
+    extractValueFromEquatable: identityEq,
+    resiliencyChecks: resiliencyChecks)
+
+%     end
+
+} // do
+
+runAllTests()
+
+% end
diff --git a/validation-test/stdlib/ArraySlice.swift.gyb b/validation-test/stdlib/ArraySlice.swift.gyb
new file mode 100644
index 0000000..6a401e5
--- /dev/null
+++ b/validation-test/stdlib/ArraySlice.swift.gyb
@@ -0,0 +1,18 @@
+// RUN: %target-run-simple-swiftgyb
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+% import os.path
+% import gyb
+% ArrayType = 'ArraySlice'
+
+var ${ArrayType}TestSuite = TestSuite("${ArrayType}")
+
+% CommonTestsTemplate = gyb.parse_template(os.path.join(os.path.dirname(__file__), "Inputs/CommonArrayTests.gyb"))
+% CommonTests = gyb.execute_template(CommonTestsTemplate, Suite=ArrayType+'TestSuite', ArrayType=ArrayType)
+
+${CommonTests}
+
+runAllTests()
diff --git a/validation-test/stdlib/Arrays.swift.gyb b/validation-test/stdlib/Arrays.swift.gyb
index fbf79fb..d80a413 100644
--- a/validation-test/stdlib/Arrays.swift.gyb
+++ b/validation-test/stdlib/Arrays.swift.gyb
@@ -73,15 +73,6 @@
 all_array_types = ['ContiguousArray', 'ArraySlice', 'Array']
 }%
 
-%for Self in all_array_types:
-extension ${Self} {
-  typealias _BufferID = UnsafeRawPointer?
-  var _bufferID: _BufferID {
-    return unsafeBitCast(_owner, to: _BufferID.self)
-  }
-}
-%end
-
 var ArrayTestSuite = TestSuite("Array")
 
 ArrayTestSuite.test("sizeof") {
@@ -125,246 +116,6 @@
   expectFalse(a.isEmpty)
 }
 
-protocol TestProtocol1 {}
-
-% for array_type in all_array_types:
-
-// Check that the generic parameter is called 'Element'.
-extension ${array_type} where Element : TestProtocol1 {
-  var _elementIsTestProtocol1: Bool {
-    fatalError("not implemented")
-  }
-}
-
-/// Returns an ${array_type} that does not share its buffer with other arrays.
-func getFresh${array_type}<S : Sequence>(_ sequence: S)
-  -> ${array_type}<S.Iterator.Element> {
-  var result: ${array_type}<S.Iterator.Element> = []
-  result.reserveCapacity(sequence.underestimatedCount)
-  for element in sequence {
-    result.append(element)
-  }
-  return result
-}
-
-% end
-
-enum EnumWithoutPayloads : Equatable {
-  case A, B, C, D
-}
-
-func == (lhs: EnumWithoutPayloads, rhs: EnumWithoutPayloads) -> Bool {
-  switch (lhs, rhs) {
-  case (.A, .A), (.B, .B), (.C, .C), (.D, .D):
-    return true
-
-  default:
-    return false
-  }
-}
-
-struct SequenceWithCustomUnderestimatedCount : Sequence {
-  init(_ data: [Int]) {
-    self._data = MinimalSequence(elements: data.map(OpaqueValue.init))
-  }
-
-  func makeIterator() -> MinimalSequence<OpaqueValue<Int>>.Iterator {
-    return _data.makeIterator()
-  }
-
-  var underestimatedCount: Int {
-    SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled += 1
-    return _data.underestimatedCount
-  }
-
-  static var timesUnderestimatedCountWasCalled: Int = 0
-
-  let _data: MinimalSequence<OpaqueValue<Int>>
-}
-
-% for array_type in all_array_types:
-
-ArrayTestSuite.test("${array_type}/init(Sequence)") {
-  let base = SequenceWithCustomUnderestimatedCount(
-    [ 0, 30, 10, 90 ])
-
-  SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled = 0
-
-  let result = ${array_type}(base)
-
-  expectEqual([ 0, 30, 10, 90 ], result.map { $0.value })
-
-  expectEqual(1, SequenceWithCustomUnderestimatedCount.timesUnderestimatedCountWasCalled)
-
-  expectEqualSequence(
-    [], Array(base).map { $0.value }, "sequence should be consumed")
-}
-
-ArrayTestSuite.test("${array_type}/Sliceable/Enums") {
-  typealias E = EnumWithoutPayloads
-
-  do {
-    let expected = [E.A, E.B, E.C, E.D]
-    let sliceable = ${array_type}(expected)
-    checkSliceableWithBidirectionalIndex(expected, sliceable)
-  }
-
-  /*
-  FIXME: add this test when Array<T> can be conditionally Equatable.
-  do {
-    let expected = [[E.A, E.B], [E.B, E.C], [E.D], [E.A, E.B, E.D]]
-    let sliceable = ${array_type}(expected)
-    checkSliceableWithBidirectionalIndex(
-      expected, sliceable, SourceLocStack().withCurrentLoc())
-  }
-  */
-}
-
-ArrayTestSuite.test("${array_type}/appendNonUnique") {
-  var x: ${array_type}<Int> = []
-  x.reserveCapacity(10002)
-  let capacity = x.capacity
-  for _ in 1...10000 {
-    let y = x
-    x.append(1)
-    expectTrue(x.capacity == capacity)
-    let z = x
-    x.remove(at: 0)
-  }
-}
-
-ArrayTestSuite.test("${array_type}/appendUndercountedCollection") {
-  // test that the array safely handles a
-  // collection that understates its count
-  var i = 0
-  let l = repeatElement(42, count: 10_000).lazy
-         // capture i by reference and change behavior 
-         // between first pass (for count) and second
-         .filter { _ in i += 1; return i > 10_000 }
-  var a: ${array_type}<Int> = []
-  a.append(contentsOf: l)
-}
-
-ArrayTestSuite.test("${array_type}/emptyAllocation") {
-  let arr0 = ${array_type}<Int>()
-  let arr1 = ${array_type}<LifetimeTracked>(repeating: LifetimeTracked(0), count: 0)
-  // Empty arrays all use the same buffer
-  expectEqual(arr0._bufferID, arr1._bufferID)
-
-  let arr2: ${array_type}<LifetimeTracked> = []
-  let emptyLiteralsShareBuffer = arr0._bufferID == arr2._bufferID
-  expectTrue(emptyLiteralsShareBuffer)
-}
-
-ArrayTestSuite.test("${array_type}/filter") {
-  do {
-    let arr: ${array_type}<Int> = []
-    var result = arr.filter() {
-      (x: Int) -> Bool in
-      expectUnreachable()
-      return true
-    }
-    expectType(Array<Int>.self, &result)
-    expectEqual([], result)
-    expectEqual(0, result.capacity)
-  }
-  do {
-    let arr: ${array_type}<Int> = [ 0, 30, 10, 90 ]
-    let result = arr.filter() { (x: Int) -> Bool in true }
-    expectEqual([ 0, 30, 10, 90 ], result)
-    expectGE(2 * result.count, result.capacity)
-  }
-  do {
-    let arr: ${array_type}<Int> = [ 0, 30, 10, 90 ]
-    let result = arr.filter() { (x: Int) -> Bool in false }
-    expectEqual([], result)
-    expectGE(2 * result.count, result.capacity)
-  }
-  do {
-    let arr: ${array_type}<Int> = [ 0, 30, 10, 90 ]
-    let result = arr.filter() { $0 % 3 == 0 }
-    expectEqual([ 0, 30, 90 ], result)
-    expectGE(2 * result.count, result.capacity)
-  }
-}
-
-ArrayTestSuite.test("${array_type}/map") {
-  do {
-    let arr: ${array_type}<Int> = []
-    var result = arr.map() {
-      (x: Int) -> Int16 in
-      expectUnreachable()
-      return 42
-    }
-    expectType(Array<Int16>.self, &result)
-    expectEqual([], result)
-    expectEqual(0, result.capacity)
-  }
-  do {
-    let arr: ${array_type}<Int> = [ 0, 30, 10, 90 ]
-    let result = arr.map() { $0 + 1 }
-    expectEqual([ 1, 31, 11, 91 ], result)
-    expectGE(2 * result.count, result.capacity)
-  }
-}
-
-ArrayTestSuite.test("${array_type}/flatMap") {
-  let enumerate : (Int) -> ${array_type}<Int> =
-    { return ${array_type}(1..<($0 + 1)) }
-  expectEqualSequence([], ${array_type}().flatMap(enumerate))
-  expectEqualSequence([ 1 ], ${array_type}([ 1 ]).flatMap(enumerate))
-  expectEqualSequence(
-    [ 1, 1, 2 ],
-    ${array_type}([ 1, 2 ]).flatMap(enumerate))
-  expectEqualSequence(
-    [ 1, 1, 1, 2 ],
-    ${array_type}([ 1, 2 ]).flatMap(enumerate).flatMap(enumerate))
-}
-
-ArrayTestSuite.test("${array_type}/Mirror") {
-  do {
-    let input: ${array_type}<Int> = []
-    var output = ""
-    dump(input, to: &output)
-
-    let expected =
-      "- 0 elements\n"
-
-    expectEqual(expected, output)
-  }
-  do {
-    let input: ${array_type}<Int> = [ 10, 20, 30, 40 ]
-    var output = ""
-    dump(input, to: &output)
-
-    let expected =
-      "▿ 4 elements\n" +
-      "  - 10\n" +
-      "  - 20\n" +
-      "  - 30\n" +
-      "  - 40\n"
-
-    expectEqual(expected, output)
-  }
-%   if array_type == 'ArraySlice':
-  do {
-    let base = [ 10, 20, 30, 40 ]
-    let input: ArraySlice<Int> = base[1..<3]
-    var output = ""
-    dump(input, to: &output)
-
-    let expected =
-      "▿ 2 elements\n" +
-      "  - 20\n" +
-      "  - 30\n"
-
-    expectEqual(expected, output)
-  }
-%   end
-}
-
-% end
-
 % for Kind in ['Array', 'ContiguousArray']:
 ArrayTestSuite.test("${Kind}/popLast") {
   // Empty
@@ -421,135 +172,6 @@
 }
 
 //===----------------------------------------------------------------------===//
-// _withUnsafeMutableBufferPointerIfSupported()
-//===----------------------------------------------------------------------===//
-
-struct WithUnsafeMutableBufferPointerIfSupportedTest {
-  let sequence: [Int]
-  let loc: SourceLoc
-
-  init(
-    _ sequence: [Int],
-    file: String = #file, line: UInt = #line
-  ) {
-    self.sequence = sequence
-    self.loc = SourceLoc(file, line, comment: "test data")
-  }
-}
-
-let withUnsafeMutableBufferPointerIfSupportedTests = [
-  WithUnsafeMutableBufferPointerIfSupportedTest([]),
-  WithUnsafeMutableBufferPointerIfSupportedTest([ 10 ]),
-  WithUnsafeMutableBufferPointerIfSupportedTest([ 10, 20, 30, 40, 50 ]),
-]
-
-% for array_type in all_array_types:
-
-ArrayTestSuite.test("${array_type}/_withUnsafeMutableBufferPointerIfSupported") {
-  for test in withUnsafeMutableBufferPointerIfSupportedTests {
-    var a = getFresh${array_type}(test.sequence.map(OpaqueValue.init))
-    do {
-      // Read.
-      var result = a._withUnsafeMutableBufferPointerIfSupported {
-        (baseAddress, count) -> OpaqueValue<[OpaqueValue<Int>]> in
-        let bufferPointer =
-          UnsafeMutableBufferPointer(start: baseAddress, count: count)
-        return OpaqueValue(Array(bufferPointer))
-      }
-      expectType(Optional<OpaqueValue<Array<OpaqueValue<Int>>>>.self, &result)
-      expectEqualSequence(test.sequence, result!.value.map { $0.value })
-      expectEqualSequence(test.sequence, a.map { $0.value })
-    }
-    do {
-      // Read and write.
-      var result = a._withUnsafeMutableBufferPointerIfSupported {
-        (baseAddress, count) -> OpaqueValue<Array<OpaqueValue<Int>>> in
-        let bufferPointer =
-          UnsafeMutableBufferPointer(start: baseAddress, count: count)
-        let result = OpaqueValue(Array(bufferPointer))
-        for i in bufferPointer.indices {
-          bufferPointer[i] = OpaqueValue(bufferPointer[i].value * 10)
-        }
-        return result
-      }
-      expectType(Optional<OpaqueValue<Array<OpaqueValue<Int>>>>.self, &result)
-      expectEqualSequence(test.sequence, result!.value.map { $0.value })
-      expectEqualSequence(
-        test.sequence.map { $0 * 10 },
-        a.map { $0.value })
-    }
-  }
-  // FIXME: tests for arrays bridged from Objective-C.
-}
-
-ArrayTestSuite.test("${array_type}/_withUnsafeMutableBufferPointerIfSupported/ReplacingTheBufferTraps/1") {
-  var a = getFresh${array_type}([ OpaqueValue(10) ])
-  var result = a._withUnsafeMutableBufferPointerIfSupported {
-    (baseAddress, count) -> OpaqueValue<Int> in
-    // buffer = UnsafeMutableBufferPointer(start: buffer.baseAddress, count: 0)
-    // FIXME: does not trap since the buffer is not passed inout.
-    // expectCrashLater()
-    return OpaqueValue(42)
-  }
-}
-
-ArrayTestSuite.test("${array_type}/_withUnsafeMutableBufferPointerIfSupported/ReplacingTheBufferTraps/2") {
-  var a = getFresh${array_type}([ OpaqueValue(10) ])
-  var result = a._withUnsafeMutableBufferPointerIfSupported {
-    (baseAddress, count) -> OpaqueValue<Int> in
-    // buffer = UnsafeMutableBufferPointer(start: nil, count: 1)
-    // FIXME: does not trap since the buffer is not passed inout.
-    // expectCrashLater()
-    return OpaqueValue(42)
-  }
-}
-
-//===----------------------------------------------------------------------===//
-// withUnsafeMutableBytes
-//===----------------------------------------------------------------------===//
-
-// Test the uniqueness of the raw buffer.
-ArrayTestSuite.test("${array_type}/withUnsafeMutableBytes") {
-  var a = getFresh${array_type}([UInt8](repeating: 10, count: 1))
-  let b = a
-  a.withUnsafeMutableBytes { bytes in
-    bytes[0] = 42
-  }
-  expectEqual(42, a[0])
-  expectEqual(10, b[0])
-}
-
-//===---
-// Check that iterators traverse a snapshot of the collection.
-//===---
-
-ArrayTestSuite.test(
-  "${array_type}/mutationDoesNotAffectIterator/subscript/store") {
-  var arr: ${array_type}<Int> = [ 1010, 1020, 1030 ]
-  var iter = arr.makeIterator()
-  arr[0] = 1011
-  expectEqual([ 1010, 1020, 1030 ], Array(IteratorSequence(iter)))
-}
-
-ArrayTestSuite.test(
-  "${array_type}/mutationDoesNotAffectIterator/subscript/append") {
-  var arr: ${array_type}<Int> = [ 1010, 1020, 1030 ]
-  var iter = arr.makeIterator()
-  arr.append(1040)
-  expectEqual([ 1010, 1020, 1030 ], Array(IteratorSequence(iter)))
-}
-
-ArrayTestSuite.test(
-  "${array_type}/mutationDoesNotAffectIterator/subscript/replaceSubrange") {
-  var arr: ${array_type}<Int> = [ 1010, 1020, 1030 ]
-  var iter = arr.makeIterator()
-  arr.replaceSubrange(1..<3, with: [ 1040, 1050, 1060 ])
-  expectEqual([ 1010, 1020, 1030 ], Array(IteratorSequence(iter)))
-}
-
-% end
-
-//===----------------------------------------------------------------------===//
 // Array and EvilCollection that changes its size while we are not looking
 //===----------------------------------------------------------------------===//
 
@@ -754,153 +376,4 @@
   }
 }
 
-
-//===----------------------------------------------------------------------===//
-// Special cases and one-off tests.
-//===----------------------------------------------------------------------===//
-
-% for array_type in all_array_types:
-
-ArrayTestSuite.test("${array_type}<Void>/map") {
-  // This code used to crash because it generated an array of Void with
-  // stride == 0.
-  do {
-    let input: ${array_type}<Void> = [ (), (), () ]
-    let result = input.map { (_) -> Void in return () }
-    expectEqual(3, result.count)
-  }
-
-  do {
-    let input: ${array_type}<OpaqueValue<Int>> = [
-      OpaqueValue(10), OpaqueValue(20), OpaqueValue(30)
-    ]
-    let result = input.map { (_) -> Void in return () }
-    expectEqual(3, result.count)
-  }
-}
-
-% end
-
-//===----------------------------------------------------------------------===//
-// MutableCollectionType and RangeReplaceableCollectionType conformance tests.
-//===----------------------------------------------------------------------===//
-
-% for array_type in all_array_types:
-ArrayTestSuite.test("${array_type}/AssociatedTypes") {
-  typealias Collection = ${array_type}<OpaqueValue<Int>>
-  typealias CollectionSlice = ArraySlice<OpaqueValue<Int>>
-  expectCollectionAssociatedTypes(
-    collectionType: Collection.self,
-    iteratorType: IndexingIterator<Collection>.self,
-    subSequenceType: CollectionSlice.self,
-    indexType: Int.self,
-    indexDistanceType: Int.self,
-    indicesType: CountableRange<Int>.self)
-}
-% end
-
-func ArraySliceWithNonZeroStartIndex<T>(_ elements: [T]) -> ArraySlice<T> {
-  var r = ArraySlice<T>(_startIndex: 1000)
-  r.append(contentsOf: elements)
-  expectEqual(1000, r.startIndex)
-  return r
-}
-
-% for array_type in all_array_types + ['ArraySliceWithNonZeroStartIndex']:
-%   collection_or_slice = 'Slice' if 'Slice' in array_type else 'Collection'
-
-do {
-  // `Array`, `ArraySlice`, and `ContiguousArrayBuffer` have no expectation of
-  // failure for advancing their indexes "out of bounds", because they are just
-  // `Int`.
-  var resiliencyChecks = CollectionMisuseResiliencyChecks.all
-  resiliencyChecks.creatingOutOfBoundsIndicesBehavior = .none
-
-  // Test MutableCollectionType conformance with value type elements.
-  ArrayTestSuite.addMutableRandomAccessCollectionTests(
-    "${array_type}.",
-    makeCollection: { (elements: [OpaqueValue<Int>]) in
-      return ${array_type}(elements)
-    },
-    wrapValue: identity,
-    extractValue: identity,
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      return ${array_type}(elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      return ${array_type}(elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks,
-    withUnsafeMutableBufferPointerIsSupported: true,
-    isFixedLengthCollection: false)
-
-
-  // Test MutableCollectionType conformance with reference type elements.
-  ArrayTestSuite.addMutableRandomAccessCollectionTests(
-    "${array_type}.",
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return ${array_type}(elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in
-      LifetimeTracked(element.value, identity: element.identity)
-    },
-    extractValue: { (element: LifetimeTracked) in
-      OpaqueValue(element.value, identity: element.identity)
-    },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return ${array_type}(elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    makeCollectionOfComparable: { (elements: [MinimalComparableValue]) in
-      // FIXME: use LifetimeTracked.
-      return ${array_type}(elements)
-    },
-    wrapValueIntoComparable: identityComp,
-    extractValueFromComparable: identityComp,
-    resiliencyChecks: resiliencyChecks,
-    withUnsafeMutableBufferPointerIsSupported: true,
-    isFixedLengthCollection: false)
-
-
-  // Test RangeReplaceableCollectionType conformance with value type elements.
-  ArrayTestSuite.addRangeReplaceableRandomAccess${collection_or_slice}Tests(
-    "${array_type}.",
-    makeCollection: { (elements: [OpaqueValue<Int>]) in
-      return ${array_type}(elements)
-    },
-    wrapValue: identity,
-    extractValue: identity,
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      return ${array_type}(elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks)
-
-
-  // Test RangeReplaceableCollectionType conformance with reference type elements.
-  ArrayTestSuite.addRangeReplaceableRandomAccess${collection_or_slice}Tests(
-    "${array_type}.",
-    makeCollection: { (elements: [LifetimeTracked]) in
-      return ${array_type}(elements)
-    },
-    wrapValue: { (element: OpaqueValue<Int>) in LifetimeTracked(element.value) },
-    extractValue: { (element: LifetimeTracked) in OpaqueValue(element.value) },
-    makeCollectionOfEquatable: { (elements: [MinimalEquatableValue]) in
-      // FIXME: use LifetimeTracked.
-      return ${array_type}(elements)
-    },
-    wrapValueIntoEquatable: identityEq,
-    extractValueFromEquatable: identityEq,
-    resiliencyChecks: resiliencyChecks)
-}
-
-% end
-
 runAllTests()
diff --git a/validation-test/stdlib/ContiguousArray.swift.gyb b/validation-test/stdlib/ContiguousArray.swift.gyb
new file mode 100644
index 0000000..0fc9eb8
--- /dev/null
+++ b/validation-test/stdlib/ContiguousArray.swift.gyb
@@ -0,0 +1,18 @@
+// RUN: %target-run-simple-swiftgyb
+// REQUIRES: executable_test
+
+import StdlibUnittest
+import StdlibCollectionUnittest
+
+% import os.path
+% import gyb
+% ArrayType = 'ContiguousArray'
+
+var ${ArrayType}TestSuite = TestSuite("${ArrayType}")
+
+% CommonTestsTemplate = gyb.parse_template(os.path.join(os.path.dirname(__file__), "Inputs/CommonArrayTests.gyb"))
+% CommonTests = gyb.execute_template(CommonTestsTemplate, Suite=ArrayType+'TestSuite', ArrayType=ArrayType)
+
+${CommonTests}
+
+runAllTests()