diff --git a/stdlib/private/StdlibCollectionUnittest/CheckCollectionInstance.swift.gyb b/stdlib/private/StdlibCollectionUnittest/CheckCollectionInstance.swift.gyb index 3bb4871b296ed..f30f439e05cec 100644 --- a/stdlib/private/StdlibCollectionUnittest/CheckCollectionInstance.swift.gyb +++ b/stdlib/private/StdlibCollectionUnittest/CheckCollectionInstance.swift.gyb @@ -40,8 +40,8 @@ public struct CollectionMisuseResiliencyChecks { } % for inc, protocol, direction, end in ( -% ('inc', '_Indexable', 'after', 'end'), -% ('dec', '_BidirectionalIndexable', 'before', 'start')): +% ('inc', 'Collection', 'after', 'end'), +% ('dec', 'BidirectionalCollection', 'before', 'start')): /// Test that the elements of `instances` satisfy /// ${'some of ' if inc == 'dec' else ''}the semantic @@ -88,7 +88,7 @@ internal func _checkIncrementalAdvance( ${TRACE} ) where Instances : Collection, - BaseCollection : _Indexable, + BaseCollection : Collection, Instances.Iterator.Element == BaseCollection.Index { for i in instances { let d: BaseCollection.IndexDistance = sign > 0 ? @@ -122,7 +122,7 @@ public func checkForwardIndex( endIndex: Instances.Iterator.Element, ${TRACE} ) where Instances : Collection, - BaseCollection : _Indexable, + BaseCollection : Collection, Instances.Iterator.Element == BaseCollection.Index { checkIncrementable(instances, of: baseCollection, @@ -149,7 +149,7 @@ public func checkBidirectionalIndex( ${TRACE} ) where Instances: Collection, - BaseCollection : _BidirectionalIndexable, + BaseCollection : BidirectionalCollection, Instances.Iterator.Element == BaseCollection.Index { checkForwardIndex(instances, of: baseCollection, @@ -185,7 +185,7 @@ public func checkRandomAccessIndex( ) where Instances : Collection, Distances : Collection, - BaseCollection : _RandomAccessIndexable, + BaseCollection : RandomAccessCollection, Instances.Iterator.Element == BaseCollection.Index, Distances.Iterator.Element == BaseCollection.IndexDistance { @@ -214,7 +214,7 @@ public func checkAdvancesAndDistances( ) where Instances : Collection, Distances : Collection, - BaseCollection : _Indexable, + BaseCollection : Collection, Instances.Iterator.Element == BaseCollection.Index, Distances.Iterator.Element == BaseCollection.IndexDistance { @@ -257,8 +257,7 @@ public func checkCollection<${genericParam}, C : Collection>( ${TRACE}, resiliencyChecks: CollectionMisuseResiliencyChecks = .all, sameValue: (${Element}, ${Element}) -> Bool -) where C.Iterator.Element == ${Element}, - C.SubSequence : Collection { +) where C.Iterator.Element == ${Element} { checkForwardCollection(expected, collection, message(), stackTrace: stackTrace, showFrame: showFrame, file: file, line: line, @@ -278,7 +277,6 @@ public func check${Traversal}Collection< resiliencyChecks: CollectionMisuseResiliencyChecks = .all ) where C.Iterator.Element == ${Element}, - C.SubSequence : ${TraversalCollection}, ${Element} : Equatable { check${Traversal}Collection( @@ -298,8 +296,7 @@ public func check${Traversal}Collection< resiliencyChecks: CollectionMisuseResiliencyChecks = .all, sameValue: (${Element}, ${Element}) -> Bool ) where - C.Iterator.Element == ${Element}, - C.SubSequence : ${TraversalCollection} { + C.Iterator.Element == ${Element} { checkOneLevelOf${Traversal}Collection(expected, collection, ${trace}, resiliencyChecks: resiliencyChecks, sameValue: sameValue) @@ -504,8 +501,7 @@ ${genericParam}, S : ${TraversalCollection} resiliencyChecks: CollectionMisuseResiliencyChecks = .all, sameValue: (${Element}, ${Element}) -> Bool ) where - S.Iterator.Element == ${Element}, - S.SubSequence : ${TraversalCollection} { + S.Iterator.Element == ${Element} { let expectedArray = Array(expected) diff --git a/stdlib/private/StdlibCollectionUnittest/CheckCollectionType.swift.gyb b/stdlib/private/StdlibCollectionUnittest/CheckCollectionType.swift.gyb index e0886c4dbdfbe..9db5c1fe8f56f 100644 --- a/stdlib/private/StdlibCollectionUnittest/CheckCollectionType.swift.gyb +++ b/stdlib/private/StdlibCollectionUnittest/CheckCollectionType.swift.gyb @@ -471,16 +471,9 @@ internal enum _SubSequenceSubscriptOnRangeMode { %{ from gyb_stdlib_support import collectionForTraversal def testConstraints(protocol): - if protocol == 'Collection': - subseq_as_collection = 'CollectionWithEquatableElement.SubSequence : Collection,' - else: - subseq_as_collection='' return ''' C : %(protocol)s, CollectionWithEquatableElement : %(protocol)s, - %(subseq_as_collection)s - C.SubSequence : %(protocol)s, - C.Indices : %(protocol)s, CollectionWithEquatableElement.Iterator.Element : Equatable ''' % locals() diff --git a/stdlib/private/StdlibCollectionUnittest/CheckMutableCollectionType.swift.gyb b/stdlib/private/StdlibCollectionUnittest/CheckMutableCollectionType.swift.gyb index 84ef5bf4650f2..0674c8dc6488d 100644 --- a/stdlib/private/StdlibCollectionUnittest/CheckMutableCollectionType.swift.gyb +++ b/stdlib/private/StdlibCollectionUnittest/CheckMutableCollectionType.swift.gyb @@ -121,8 +121,6 @@ extension TestSuite { isFixedLengthCollection: Bool, collectionIsBidirectional: Bool = false ) where - C.SubSequence : MutableCollection, - C.Indices : Collection, CollectionWithEquatableElement.Iterator.Element : Equatable, CollectionWithComparableElement.Iterator.Element : Comparable { @@ -776,8 +774,6 @@ self.test("\(testNamePrefix).partition/InvalidOrderings") { withUnsafeMutableBufferPointerIsSupported: Bool, isFixedLengthCollection: Bool ) where - C.SubSequence : BidirectionalCollection & MutableCollection, - C.Indices : BidirectionalCollection, CollectionWithEquatableElement.Iterator.Element : Equatable, CollectionWithComparableElement.Iterator.Element : Comparable { @@ -922,8 +918,6 @@ self.test("\(testNamePrefix).partition/DispatchesThrough_withUnsafeMutableBuffer withUnsafeMutableBufferPointerIsSupported: Bool, isFixedLengthCollection: Bool ) where - C.SubSequence : RandomAccessCollection & MutableCollection, - C.Indices : RandomAccessCollection, CollectionWithEquatableElement.Iterator.Element : Equatable, CollectionWithComparableElement.Iterator.Element : Comparable { diff --git a/stdlib/private/StdlibCollectionUnittest/CheckRangeReplaceableCollectionType.swift b/stdlib/private/StdlibCollectionUnittest/CheckRangeReplaceableCollectionType.swift index 14363c64c71c1..245f486a4a3a8 100644 --- a/stdlib/private/StdlibCollectionUnittest/CheckRangeReplaceableCollectionType.swift +++ b/stdlib/private/StdlibCollectionUnittest/CheckRangeReplaceableCollectionType.swift @@ -462,10 +462,7 @@ extension TestSuite { outOfBoundsIndexOffset: Int = 1, collectionIsBidirectional: Bool = false ) where - C.SubSequence : Collection, - C.Indices : Collection, - CollectionWithEquatableElement.Iterator.Element : Equatable, - CollectionWithEquatableElement.SubSequence : Collection { + CollectionWithEquatableElement.Iterator.Element : Equatable { var testNamePrefix = testNamePrefix @@ -1180,8 +1177,6 @@ self.test("\(testNamePrefix).OperatorPlus") { resiliencyChecks: CollectionMisuseResiliencyChecks = .all, outOfBoundsIndexOffset: Int = 1 ) where - C.SubSequence : BidirectionalCollection & RangeReplaceableCollection, - C.Indices : BidirectionalCollection, CollectionWithEquatableElement.Iterator.Element : Equatable { var testNamePrefix = testNamePrefix @@ -1302,8 +1297,6 @@ self.test("\(testNamePrefix).removeLast(n: Int)/whereIndexIsBidirectional/remove resiliencyChecks: CollectionMisuseResiliencyChecks = .all, outOfBoundsIndexOffset: Int = 1 ) where - C.SubSequence : RandomAccessCollection & RangeReplaceableCollection, - C.Indices : RandomAccessCollection, CollectionWithEquatableElement.Iterator.Element : Equatable { var testNamePrefix = testNamePrefix diff --git a/stdlib/private/StdlibCollectionUnittest/CheckRangeReplaceableSliceType.swift b/stdlib/private/StdlibCollectionUnittest/CheckRangeReplaceableSliceType.swift index fb10e306fed93..28a802ee73e14 100644 --- a/stdlib/private/StdlibCollectionUnittest/CheckRangeReplaceableSliceType.swift +++ b/stdlib/private/StdlibCollectionUnittest/CheckRangeReplaceableSliceType.swift @@ -33,7 +33,6 @@ extension TestSuite { collectionIsBidirectional: Bool = false ) where C.SubSequence == C, - C.Indices : Collection, CollectionWithEquatableElement.SubSequence == CollectionWithEquatableElement, CollectionWithEquatableElement.Iterator.Element : Equatable { @@ -165,7 +164,6 @@ extension TestSuite { outOfBoundsIndexOffset: Int = 1 ) where C.SubSequence == C, - C.Indices : BidirectionalCollection, CollectionWithEquatableElement.SubSequence == CollectionWithEquatableElement, CollectionWithEquatableElement.Iterator.Element : Equatable { @@ -310,7 +308,6 @@ extension TestSuite { outOfBoundsIndexOffset: Int = 1 ) where C.SubSequence == C, - C.Indices : RandomAccessCollection, CollectionWithEquatableElement.SubSequence == CollectionWithEquatableElement, CollectionWithEquatableElement.Iterator.Element : Equatable { diff --git a/stdlib/private/StdlibCollectionUnittest/CheckSequenceType.swift b/stdlib/private/StdlibCollectionUnittest/CheckSequenceType.swift index e5ba6d949355d..721cba0a6a974 100644 --- a/stdlib/private/StdlibCollectionUnittest/CheckSequenceType.swift +++ b/stdlib/private/StdlibCollectionUnittest/CheckSequenceType.swift @@ -1536,13 +1536,7 @@ extension TestSuite { resiliencyChecks: CollectionMisuseResiliencyChecks = .all ) where - SequenceWithEquatableElement.Iterator.Element : Equatable, - SequenceWithEquatableElement.SubSequence : Sequence, - SequenceWithEquatableElement.SubSequence.Iterator.Element - == SequenceWithEquatableElement.Iterator.Element, - S.SubSequence : Sequence, - S.SubSequence.Iterator.Element == S.Iterator.Element, - S.SubSequence.SubSequence == S.SubSequence { + SequenceWithEquatableElement.Iterator.Element : Equatable { var testNamePrefix = testNamePrefix diff --git a/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb b/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb index ad172aae26095..51fe0101a7482 100644 --- a/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb +++ b/stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb @@ -378,25 +378,14 @@ public func expectTrapping( public func expectType(_: T.Type, _ x: inout T) {} public func expectEqualType(_: T.Type, _: T.Type) {} -public func expectSequenceType(_ x: X) -> X - where - X.SubSequence : Sequence, - X.SubSequence.Iterator.Element == X.Iterator.Element, - X.SubSequence.SubSequence == X.SubSequence { +public func expectSequenceType(_ x: X) -> X { return x } % for Mutable in ['', 'Mutable']: public func expect${Mutable}CollectionType( _ x: X.Type -) where - // FIXME(ABI)#2 (Associated Types with where clauses): there should be no constraints in - // the 'where' clause, all of these should be required by the protocol. -% if Mutable == '': - X.SubSequence : Collection, -% end - // X.SubSequence.Indices == X.Indices, // FIXME(ABI)#3 (Recursive Protocol Constraints): can't have this constraint now. - X.Indices : Collection {} +) {} % end /// A slice is a `Collection` that when sliced returns an instance of @@ -417,13 +406,7 @@ public func expectSequenceAssociatedTypes( sequenceType: X.Type, iteratorType: X.Iterator.Type, subSequenceType: X.SubSequence.Type -) where - // FIXME(ABI)#4 (Associated Types with where clauses): there should be no constraints in - // the 'where' clause, all of these should be required by the protocol. - X.SubSequence : Sequence, - X.SubSequence.Iterator.Element == X.Iterator.Element, - // X.SubSequence.Indices == X.Indices, // FIXME(ABI)#5 (Recursive Protocol Constraints): can't have this constraint now. - X.SubSequence.SubSequence == X.SubSequence {} +) {} /// Check that all associated types of a `Collection` are what we expect them /// to be. @@ -434,12 +417,7 @@ public func expectCollectionAssociatedTypes( indexType: X.Index.Type, indexDistanceType: X.IndexDistance.Type, indicesType: X.Indices.Type -) where - // FIXME(ABI)#6 (Associated Types with where clauses): there should be no constraints in - // the 'where' clause, all of these should be required by the protocol. - X.SubSequence : Collection, - // X.SubSequence.Indices == X.Indices, // FIXME(ABI)#7 (Recursive Protocol Constraints): can't have this constraint now. - X.Indices : Collection {} +) {} /// Check that all associated types of a `BidirectionalCollection` are what we /// expect them to be. @@ -450,12 +428,7 @@ public func expectBidirectionalCollectionAssociatedTypes) -> Bool { return self.intersects(integersIn: Range(range)) } // MARK: - - // Indexable + // Collection public func index(after i: Index) -> Index { if i.value + 1 == i.extent.upperBound { diff --git a/stdlib/public/core/ArrayBufferProtocol.swift b/stdlib/public/core/ArrayBufferProtocol.swift index 74d993a765680..7ac8aa38dfa77 100644 --- a/stdlib/public/core/ArrayBufferProtocol.swift +++ b/stdlib/public/core/ArrayBufferProtocol.swift @@ -16,10 +16,7 @@ internal protocol _ArrayBufferProtocol : MutableCollection, RandomAccessCollection { - associatedtype Indices - // FIXME(ABI) (Revert Where Clauses): Remove this conformance - : RandomAccessCollection - = CountableRange + associatedtype Indices = CountableRange /// Create an empty buffer. init() diff --git a/stdlib/public/core/BidirectionalCollection.swift b/stdlib/public/core/BidirectionalCollection.swift index 6ae6339d9c204..5abd3eb53a88d 100644 --- a/stdlib/public/core/BidirectionalCollection.swift +++ b/stdlib/public/core/BidirectionalCollection.swift @@ -17,28 +17,7 @@ /// `BidirectionalCollection` protocol instead, because it has a more complete /// interface. @available(*, deprecated, message: "it will be removed in Swift 4.0. Please use 'BidirectionalCollection' instead") -public typealias BidirectionalIndexable = _BidirectionalIndexable -public protocol _BidirectionalIndexable : _Indexable { - // FIXME(ABI)#22 (Recursive Protocol Constraints): there is no reason for this protocol - // to exist apart from missing compiler features that we emulate with it. - // rdar://problem/20531108 - // - // This protocol is almost an implementation detail of the standard - // library. - - /// Returns the position immediately before the given index. - /// - /// - Parameter i: A valid index of the collection. `i` must be greater than - /// `startIndex`. - /// - Returns: The index value immediately before `i`. - func index(before i: Index) -> Index - - /// Replaces the given index with its predecessor. - /// - /// - Parameter i: A valid index of the collection. `i` must be greater than - /// `startIndex`. - func formIndex(before i: inout Index) -} +public typealias BidirectionalIndexable = BidirectionalCollection /// A collection that supports backward as well as forward traversal. /// @@ -65,12 +44,14 @@ public protocol _BidirectionalIndexable : _Indexable { /// `c.index(before: c.index(after: i)) == i`. /// - If `i > c.startIndex && i <= c.endIndex` /// `c.index(after: c.index(before: i)) == i`. -public protocol BidirectionalCollection : _BidirectionalIndexable, Collection -// FIXME(ABI) (Revert Where Clauses): Restore these -// where SubSequence: BidirectionalCollection, Indices: BidirectionalCollection +public protocol BidirectionalCollection : Collection { + // FIXME(ABI): Associated type inference requires this. + associatedtype Element + + // FIXME(ABI): Associated type inference requires this. + associatedtype Index -// TODO: swift-3-indexing-model - replaces functionality in BidirectionalIndex /// Returns the position immediately before the given index. /// /// - Parameter i: A valid index of the collection. `i` must be greater than @@ -86,16 +67,12 @@ public protocol BidirectionalCollection : _BidirectionalIndexable, Collection /// A sequence that can represent a contiguous subrange of the collection's /// elements. - associatedtype SubSequence - // FIXME(ABI) (Revert Where Clauses): Remove these conformances - : _BidirectionalIndexable, Collection + associatedtype SubSequence : BidirectionalCollection = BidirectionalSlice /// A type that represents the indices that are valid for subscripting the /// collection, in ascending order. - associatedtype Indices - // FIXME(ABI) (Revert Where Clauses): Remove these conformances - : _BidirectionalIndexable, Collection + associatedtype Indices : BidirectionalCollection = DefaultBidirectionalIndices /// The indices that are valid for subscripting the collection, in ascending @@ -153,10 +130,19 @@ public protocol BidirectionalCollection : _BidirectionalIndexable, Collection /// - Parameter bounds: A range of the collection's indices. The bounds of /// the range must be valid indices of the collection. subscript(bounds: Range) -> SubSequence { get } + + // FIXME(ABI): Associated type inference requires this. + subscript(position: Index) -> Element { get } + + // FIXME(ABI): Associated type inference requires this. + var startIndex: Index { get } + + // FIXME(ABI): Associated type inference requires this. + var endIndex: Index { get } } /// Default implementation for bidirectional collections. -extension _BidirectionalIndexable { +extension BidirectionalCollection { @_inlineable // FIXME(sil-serialize-all) @inline(__always) diff --git a/stdlib/public/core/Collection.swift b/stdlib/public/core/Collection.swift index fc932993f2173..c8bdfd4895e63 100644 --- a/stdlib/public/core/Collection.swift +++ b/stdlib/public/core/Collection.swift @@ -16,143 +16,7 @@ /// In most cases, it's best to ignore this protocol and use the `Collection` /// protocol instead, because it has a more complete interface. @available(*, deprecated, message: "it will be removed in Swift 4.0. Please use 'Collection' instead") -public typealias IndexableBase = _IndexableBase -public protocol _IndexableBase { - // FIXME(ABI)#24 (Recursive Protocol Constraints): there is no reason for this protocol - // to exist apart from missing compiler features that we emulate with it. - // rdar://problem/20531108 - // - // This protocol is almost an implementation detail of the standard - // library; it is used to deduce things like the `SubSequence` and - // `Iterator` type from a minimal collection, but it is also used in - // exposed places like as a constraint on `IndexingIterator`. - - /// A type that represents a position in the collection. - /// - /// Valid indices consist of the position of every element and a - /// "past the end" position that's not valid for use as a subscript - /// argument. - associatedtype Index : Comparable - - /// The position of the first element in a nonempty collection. - /// - /// If the collection is empty, `startIndex` is equal to `endIndex`. - var startIndex: Index { get } - - /// The collection's "past the end" position---that is, the position one - /// greater than the last valid subscript argument. - /// - /// When you need a range that includes the last element of a collection, use - /// the half-open range operator (`..<`) with `endIndex`. The `..<` operator - /// creates a range that doesn't include the upper bound, so it's always - /// safe to use with `endIndex`. For example: - /// - /// let numbers = [10, 20, 30, 40, 50] - /// if let index = numbers.index(of: 30) { - /// print(numbers[index ..< numbers.endIndex]) - /// } - /// // Prints "[30, 40, 50]" - /// - /// If the collection is empty, `endIndex` is equal to `startIndex`. - var endIndex: Index { get } - - associatedtype Element - - /// Accesses the element at the specified position. - /// - /// The following example accesses an element of an array through its - /// subscript to print its value: - /// - /// var streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"] - /// print(streets[1]) - /// // Prints "Bryant" - /// - /// You can subscript a collection with any valid index other than the - /// collection's end index. The end index refers to the position one past - /// the last element of a collection, so it doesn't correspond with an - /// element. - /// - /// - Parameter position: The position of the element to access. `position` - /// must be a valid index of the collection that is not equal to the - /// `endIndex` property. - /// - /// - Complexity: O(1) - subscript(position: Index) -> Element { get } - - // WORKAROUND: rdar://25214066 - // FIXME(ABI)#178 (Type checker) - /// A sequence that represents a contiguous subrange of the collection's - /// elements. - associatedtype SubSequence - - /// Accesses the subsequence bounded by the given range. - /// - /// - Parameter bounds: A range of the collection's indices. The upper and - /// lower bounds of the range must be valid indices of the collection. - /// - /// - Complexity: O(1) - subscript(bounds: Range) -> SubSequence { get } - - /// Performs a range check in O(1), or a no-op when a range check is not - /// implementable in O(1). - /// - /// The range check, if performed, is equivalent to: - /// - /// precondition(bounds.contains(index)) - /// - /// Use this function to perform a cheap range check for QoI purposes when - /// memory safety is not a concern. Do not rely on this range check for - /// memory safety. - /// - /// The default implementation for forward and bidirectional indices is a - /// no-op. The default implementation for random access indices performs a - /// range check. - /// - /// - Complexity: O(1). - func _failEarlyRangeCheck(_ index: Index, bounds: Range) - - func _failEarlyRangeCheck(_ index: Index, bounds: ClosedRange) - - /// Performs a range check in O(1), or a no-op when a range check is not - /// implementable in O(1). - /// - /// The range check, if performed, is equivalent to: - /// - /// precondition( - /// bounds.contains(range.lowerBound) || - /// range.lowerBound == bounds.upperBound) - /// precondition( - /// bounds.contains(range.upperBound) || - /// range.upperBound == bounds.upperBound) - /// - /// Use this function to perform a cheap range check for QoI purposes when - /// memory safety is not a concern. Do not rely on this range check for - /// memory safety. - /// - /// The default implementation for forward and bidirectional indices is a - /// no-op. The default implementation for random access indices performs a - /// range check. - /// - /// - Complexity: O(1). - func _failEarlyRangeCheck(_ range: Range, bounds: Range) - - /// Returns the position immediately after the given index. - /// - /// The successor of an index must be well defined. For an index `i` into a - /// collection `c`, calling `c.index(after: i)` returns the same index every - /// time. - /// - /// - Parameter i: A valid index of the collection. `i` must be less than - /// `endIndex`. - /// - Returns: The index value immediately after `i`. - func index(after i: Index) -> Index - - /// Replaces the given index with its successor. - /// - /// - Parameter i: A valid index of the collection. `i` must be less than - /// `endIndex`. - func formIndex(after i: inout Index) -} +public typealias IndexableBase = Collection /// A type that provides subscript access to its elements, with forward index /// traversal. @@ -160,144 +24,7 @@ public protocol _IndexableBase { /// In most cases, it's best to ignore this protocol and use the `Collection` /// protocol instead, because it has a more complete interface. @available(*, deprecated, message: "it will be removed in Swift 4.0. Please use 'Collection' instead") -public typealias Indexable = _Indexable -public protocol _Indexable : _IndexableBase { - /// A type that represents the number of steps between two indices, where - /// one value is reachable from the other. - /// - /// In Swift, *reachability* refers to the ability to produce one value from - /// the other through zero or more applications of `index(after:)`. - associatedtype IndexDistance : SignedInteger = Int - - /// Returns an index that is the specified distance from the given index. - /// - /// The following example obtains an index advanced four positions from a - /// string's starting index and then prints the character at that position. - /// - /// let s = "Swift" - /// let i = s.index(s.startIndex, offsetBy: 4) - /// print(s[i]) - /// // Prints "t" - /// - /// The value passed as `n` must not offset `i` beyond the bounds of the - /// collection. - /// - /// - Parameters: - /// - i: A valid index of the collection. - /// - n: The distance to offset `i`. `n` must not be negative unless the - /// collection conforms to the `BidirectionalCollection` protocol. - /// - Returns: An index offset by `n` from the index `i`. If `n` is positive, - /// this is the same value as the result of `n` calls to `index(after:)`. - /// If `n` is negative, this is the same value as the result of `-n` calls - /// to `index(before:)`. - /// - /// - Complexity: O(1) if the collection conforms to - /// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the absolute - /// value of `n`. - func index(_ i: Index, offsetBy n: IndexDistance) -> Index - - /// Returns an index that is the specified distance from the given index, - /// unless that distance is beyond a given limiting index. - /// - /// The following example obtains an index advanced four positions from a - /// string's starting index and then prints the character at that position. - /// The operation doesn't require going beyond the limiting `s.endIndex` - /// value, so it succeeds. - /// - /// let s = "Swift" - /// if let i = s.index(s.startIndex, offsetBy: 4, limitedBy: s.endIndex) { - /// print(s[i]) - /// } - /// // Prints "t" - /// - /// The next example attempts to retrieve an index six positions from - /// `s.startIndex` but fails, because that distance is beyond the index - /// passed as `limit`. - /// - /// let j = s.index(s.startIndex, offsetBy: 6, limitedBy: s.endIndex) - /// print(j) - /// // Prints "nil" - /// - /// The value passed as `n` must not offset `i` beyond the bounds of the - /// collection, unless the index passed as `limit` prevents offsetting - /// beyond those bounds. - /// - /// - Parameters: - /// - i: A valid index of the collection. - /// - n: The distance to offset `i`. `n` must not be negative unless the - /// collection conforms to the `BidirectionalCollection` protocol. - /// - limit: A valid index of the collection to use as a limit. If `n > 0`, - /// a limit that is less than `i` has no effect. Likewise, if `n < 0`, a - /// limit that is greater than `i` has no effect. - /// - Returns: An index offset by `n` from the index `i`, unless that index - /// would be beyond `limit` in the direction of movement. In that case, - /// the method returns `nil`. - /// - /// - Complexity: O(1) if the collection conforms to - /// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the absolute - /// value of `n`. - func index( - _ i: Index, offsetBy n: IndexDistance, limitedBy limit: Index - ) -> Index? - - /// Offsets the given index by the specified distance. - /// - /// The value passed as `n` must not offset `i` beyond the bounds of the - /// collection. - /// - /// - Parameters: - /// - i: A valid index of the collection. - /// - n: The distance to offset `i`. `n` must not be negative unless the - /// collection conforms to the `BidirectionalCollection` protocol. - /// - /// - Complexity: O(1) if the collection conforms to - /// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the absolute - /// value of `n`. - func formIndex(_ i: inout Index, offsetBy n: IndexDistance) - - /// Offsets the given index by the specified distance, or so that it equals - /// the given limiting index. - /// - /// The value passed as `n` must not offset `i` beyond the bounds of the - /// collection, unless the index passed as `limit` prevents offsetting - /// beyond those bounds. - /// - /// - Parameters: - /// - i: A valid index of the collection. - /// - n: The distance to offset `i`. `n` must not be negative unless the - /// collection conforms to the `BidirectionalCollection` protocol. - /// - limit: A valid index of the collection to use as a limit. If `n > 0`, - /// a limit that is less than `i` has no effect. Likewise, if `n < 0`, a - /// limit that is greater than `i` has no effect. - /// - Returns: `true` if `i` has been offset by exactly `n` steps without - /// going beyond `limit`; otherwise, `false`. When the return value is - /// `false`, the value of `i` is equal to `limit`. - /// - /// - Complexity: O(1) if the collection conforms to - /// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the absolute - /// value of `n`. - func formIndex( - _ i: inout Index, offsetBy n: IndexDistance, limitedBy limit: Index - ) -> Bool - - /// Returns the distance between two indices. - /// - /// Unless the collection conforms to the `BidirectionalCollection` protocol, - /// `start` must be less than or equal to `end`. - /// - /// - Parameters: - /// - start: A valid index of the collection. - /// - end: Another valid index of the collection. If `end` is equal to - /// `start`, the result is zero. - /// - Returns: The distance between `start` and `end`. The result can be - /// negative only if the collection conforms to the - /// `BidirectionalCollection` protocol. - /// - /// - Complexity: O(1) if the collection conforms to - /// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the - /// resulting distance. - func distance(from start: Index, to end: Index) -> IndexDistance -} +public typealias Indexable = Collection /// A type that iterates over a collection using its indices. /// @@ -356,10 +83,7 @@ public protocol _Indexable : _IndexableBase { /// // Prints "20.0" @_fixed_layout public struct IndexingIterator< - Elements : _IndexableBase - // FIXME(ABI)#97 (Recursive Protocol Constraints): - // Should be written as: - // Elements : Collection + Elements : Collection > : IteratorProtocol, Sequence { @_inlineable @@ -621,13 +345,43 @@ public struct IndexingIterator< /// or bidirectional collection must traverse the entire collection to count /// the number of contained elements, accessing its `count` property is an /// O(*n*) operation. -public protocol Collection : _Indexable, Sequence -// FIXME(ABI) (Revert Where Clauses): Restore these -// where SubSequence: Collection, Indices: Collection, +public protocol Collection : Sequence { + // FIXME(ABI): Associated type inference requires this. + associatedtype Element + + /// A type that represents a position in the collection. + /// + /// Valid indices consist of the position of every element and a + /// "past the end" position that's not valid for use as a subscript + /// argument. + associatedtype Index : Comparable + + /// The position of the first element in a nonempty collection. + /// + /// If the collection is empty, `startIndex` is equal to `endIndex`. + var startIndex: Index { get } + + /// The collection's "past the end" position---that is, the position one + /// greater than the last valid subscript argument. + /// + /// When you need a range that includes the last element of a collection, use + /// the half-open range operator (`..<`) with `endIndex`. The `..<` operator + /// creates a range that doesn't include the upper bound, so it's always + /// safe to use with `endIndex`. For example: + /// + /// let numbers = [10, 20, 30, 40, 50] + /// if let index = numbers.index(of: 30) { + /// print(numbers[index ..< numbers.endIndex]) + /// } + /// // Prints "[30, 40, 50]" + /// + /// If the collection is empty, `endIndex` is equal to `startIndex`. + var endIndex: Index { get } + /// A type that represents the number of steps between a pair of /// indices. - associatedtype IndexDistance = Int + associatedtype IndexDistance : SignedInteger = Int /// A type that provides the collection's iteration interface and /// encapsulates its iteration state. @@ -649,26 +403,8 @@ public protocol Collection : _Indexable, Sequence /// This associated type appears as a requirement in the `Sequence` /// protocol, but it is restated here with stricter constraints. In a /// collection, the subsequence should also conform to `Collection`. - associatedtype SubSequence - // FIXME(ABI) (Revert Where Clauses): remove these conformances: - : _IndexableBase, Sequence - = Slice - where SubSequence.SubSequence == SubSequence - // FIXME(ABI) (Revert Where Clauses): and this where clause: - , Element == SubSequence.Element - , SubSequence.Index == Index - - // FIXME(ABI)#98 (Recursive Protocol Constraints): - // FIXME(ABI)#99 (Associated Types with where clauses): - // associatedtype SubSequence : Collection - // where - // SubSequence.Indices == Indices, - // - // ( Implement recursive protocol - // constraints) - // - // These constraints allow processing collections in generic code by - // repeatedly slicing them in a loop. + associatedtype SubSequence : Collection = Slice + where SubSequence.Index == Index /// Accesses the element at the specified position. /// @@ -718,20 +454,11 @@ public protocol Collection : _Indexable, Sequence /// A type that represents the indices that are valid for subscripting the /// collection, in ascending order. - associatedtype Indices - // FIXME(ABI) (Revert Where Clauses): Remove these two conformances - : _Indexable, Sequence - = DefaultIndices + associatedtype Indices : Collection = DefaultIndices where Indices.Element == Index, - Indices.Index == Index - // FIXME(ABI) (Revert Where Clauses): Remove this where clause - , Indices.SubSequence == Indices + Indices.Index == Index, + Indices.SubSequence == Indices - // FIXME(ABI)#100 (Recursive Protocol Constraints): - // associatedtype Indices : Collection - // where - // = DefaultIndices - /// The indices that are valid for subscripting the collection, in ascending /// order. /// @@ -992,10 +719,70 @@ public protocol Collection : _Indexable, Sequence /// `RandomAccessCollection`; otherwise, O(*n*), where *n* is the /// resulting distance. func distance(from start: Index, to end: Index) -> IndexDistance + + /// Performs a range check in O(1), or a no-op when a range check is not + /// implementable in O(1). + /// + /// The range check, if performed, is equivalent to: + /// + /// precondition(bounds.contains(index)) + /// + /// Use this function to perform a cheap range check for QoI purposes when + /// memory safety is not a concern. Do not rely on this range check for + /// memory safety. + /// + /// The default implementation for forward and bidirectional indices is a + /// no-op. The default implementation for random access indices performs a + /// range check. + /// + /// - Complexity: O(1). + func _failEarlyRangeCheck(_ index: Index, bounds: Range) + + func _failEarlyRangeCheck(_ index: Index, bounds: ClosedRange) + + /// Performs a range check in O(1), or a no-op when a range check is not + /// implementable in O(1). + /// + /// The range check, if performed, is equivalent to: + /// + /// precondition( + /// bounds.contains(range.lowerBound) || + /// range.lowerBound == bounds.upperBound) + /// precondition( + /// bounds.contains(range.upperBound) || + /// range.upperBound == bounds.upperBound) + /// + /// Use this function to perform a cheap range check for QoI purposes when + /// memory safety is not a concern. Do not rely on this range check for + /// memory safety. + /// + /// The default implementation for forward and bidirectional indices is a + /// no-op. The default implementation for random access indices performs a + /// range check. + /// + /// - Complexity: O(1). + func _failEarlyRangeCheck(_ range: Range, bounds: Range) + + /// Returns the position immediately after the given index. + /// + /// The successor of an index must be well defined. For an index `i` into a + /// collection `c`, calling `c.index(after: i)` returns the same index every + /// time. + /// + /// - Parameter i: A valid index of the collection. `i` must be less than + /// `endIndex`. + /// - Returns: The index value immediately after `i`. + func index(after i: Index) -> Index + + /// Replaces the given index with its successor. + /// + /// - Parameter i: A valid index of the collection. `i` must be less than + /// `endIndex`. + func formIndex(after i: inout Index) } /// Default implementation for forward collections. -extension _Indexable { +extension Collection { /// Replaces the given index with its successor. /// /// - Parameter i: A valid index of the collection. `i` must be less than @@ -1913,7 +1700,7 @@ extension Collection { public typealias Generator = Iterator } -extension _IndexableBase { +extension Collection { @available(swift, deprecated: 3.2, renamed: "Element") public typealias _Element = Element } diff --git a/stdlib/public/core/ExistentialCollection.swift.gyb b/stdlib/public/core/ExistentialCollection.swift.gyb index e803049c7653c..709f167caa035 100644 --- a/stdlib/public/core/ExistentialCollection.swift.gyb +++ b/stdlib/public/core/ExistentialCollection.swift.gyb @@ -450,17 +450,6 @@ internal class _AnyRandomAccessCollectionBox @_fixed_layout @_versioned internal final class _${Kind}Box : _Any${Kind}Box - where - S.SubSequence : ${Kind}, -// FIXME(ABI) (Revert Where Clauses): apply all this only to Sequence: -% if Kind == 'Sequence': - S.SubSequence.Element == S.Element, - S.SubSequence.SubSequence == S.SubSequence -// FIXME(ABI) (Revert Where Clauses): remove this else clause: -% else: - S.SubSequence.Indices : ${Kind}, - S.Indices : ${Kind} -% end { internal typealias Element = S.Element @@ -764,10 +753,7 @@ public struct AnySequence : Sequence { @_inlineable public init(_ base: S) where - S.Element == Element, - S.SubSequence : Sequence, - S.SubSequence.Element == Element, - S.SubSequence.SubSequence == S.SubSequence { + S.Element == Element { self._box = _SequenceBox(_base: base) } @@ -1041,8 +1027,8 @@ protocol _AnyCollectionProtocol : Collection { public struct ${Self} : _AnyCollectionProtocol, ${SelfProtocol} { -// public typealias Indices -// = Default${Traversal.replace('Forward', '')}Indices<${Self}> + public typealias Indices + = Default${Traversal.replace('Forward', '')}Indices<${Self}> public typealias Iterator = AnyIterator @@ -1061,14 +1047,8 @@ public struct ${Self} /// - Complexity: O(1). @_inlineable public init(_ base: C) - where - // FIXME(ABI) (Revert Where Clauses): remove next 3 lines - C.SubSequence : ${SubProtocol}, - C.SubSequence.Indices : ${SubProtocol}, - C.Indices : ${SubProtocol}, - // FIXME(ABI)#101 (Associated Types with where clauses): these constraints - // should be applied to associated types of Collection. - C.SubSequence.Element == Element + where + C.Element == Element { // Traversal: ${Traversal} // SubTraversal: ${SubTraversal} diff --git a/stdlib/public/core/Filter.swift.gyb b/stdlib/public/core/Filter.swift.gyb index 7387465ff95df..33895019599c0 100644 --- a/stdlib/public/core/Filter.swift.gyb +++ b/stdlib/public/core/Filter.swift.gyb @@ -12,8 +12,7 @@ %{ from gyb_stdlib_support import ( - collectionForTraversal, - sliceTypeName + collectionForTraversal ) }% @@ -115,7 +114,6 @@ public typealias LazyFilterIndex = Base.Index % for Traversal in ['Forward', 'Bidirectional']: % Self = "LazyFilter" + collectionForTraversal(Traversal) -% Slice = sliceTypeName(traversal=Traversal, mutable=False, rangeReplaceable=False) /// A lazy `Collection` wrapper that includes the elements of an /// underlying collection that satisfy a predicate. @@ -224,9 +222,11 @@ public struct ${Self}< return _base[position] } + public typealias SubSequence = ${Self} + @_inlineable // FIXME(sil-serialize-all) - public subscript(bounds: Range) -> ${Slice}<${Self}> { - return ${Slice}(base: self, bounds: bounds) + public subscript(bounds: Range) -> SubSequence { + return SubSequence(_base: _base[bounds], _predicate) } // Any estimate of the number of elements that pass `_predicate` requires @@ -247,16 +247,6 @@ public struct ${Self}< return _copySequenceToContiguousArray(self) } - // FIXME(ABI)#28 (Associated Types with where clauses): we actually want to add: - // - // typealias SubSequence = ${Self} - // - // so that all slicing optimizations of the base collection can kick in. - // - // We can't do that right now though, because that would force a lot of - // constraints on `Base.SubSequence`, limiting the possible contexts where - // the `.lazy.filter` API can be used. - /// Returns an iterator over the elements of this sequence. /// /// - Complexity: O(1). diff --git a/stdlib/public/core/Indices.swift.gyb b/stdlib/public/core/Indices.swift.gyb index 5a5d8f131d6e1..e6ecc55e120da 100644 --- a/stdlib/public/core/Indices.swift.gyb +++ b/stdlib/public/core/Indices.swift.gyb @@ -31,10 +31,7 @@ from gyb_stdlib_support import ( /// A collection of indices for an arbitrary ${collection}. @_fixed_layout public struct ${Self}< - Elements : _${collectionForTraversal(Traversal).replace('Collection', 'Indexable')} - // FIXME(ABI)#43 (Recursive Protocol Constraints): - // Elements : Collection - // rdar://problem/20531108 + Elements : ${collectionForTraversal(Traversal)} > : ${collectionForTraversal(Traversal)} { // FIXME(compiler limitation): this typealias should be inferred. diff --git a/stdlib/public/core/Integers.swift.gyb b/stdlib/public/core/Integers.swift.gyb index f9e2b91750bed..a453704ac2c81 100644 --- a/stdlib/public/core/Integers.swift.gyb +++ b/stdlib/public/core/Integers.swift.gyb @@ -989,11 +989,9 @@ public protocol Numeric : Equatable, ExpressibleByIntegerLiteral { /// - Parameter source: A value to convert to this type. init?(exactly source: T) - // FIXME(ABI)#44 (Recursive Protocol Constraints): should be just - // Numeric, Comparable /// A type that can represent the absolute value of any possible value of the /// conforming type. - associatedtype Magnitude : Comparable, ExpressibleByIntegerLiteral + associatedtype Magnitude : Comparable, Numeric /// The magnitude of this value. /// diff --git a/stdlib/public/core/Map.swift.gyb b/stdlib/public/core/Map.swift.gyb index c665382a27f16..2e71bb26070e2 100644 --- a/stdlib/public/core/Map.swift.gyb +++ b/stdlib/public/core/Map.swift.gyb @@ -13,8 +13,7 @@ %{ from gyb_stdlib_support import ( TRAVERSALS, - collectionForTraversal, - sliceTypeName + collectionForTraversal ) }% @@ -104,7 +103,6 @@ public struct LazyMapSequence % for Traversal in TRAVERSALS: % Self = "LazyMap" + collectionForTraversal(Traversal) -% Slice = sliceTypeName(traversal=Traversal, mutable=False, rangeReplaceable=False) /// A `Collection` whose elements consist of those in a `Base` /// `Collection` passed through a transform function returning `Element`. @@ -150,21 +148,13 @@ public struct ${Self}< return _transform(_base[position]) } + public typealias SubSequence = ${Self} + @_inlineable - public subscript(bounds: Range) -> ${Slice}<${Self}> { - return ${Slice}(base: self, bounds: bounds) + public subscript(bounds: Range) -> SubSequence { + return SubSequence(_base: _base[bounds], transform: _transform) } - // FIXME(ABI)#46 (Associated Types with where clauses): we actually want to add: - // - // typealias SubSequence = ${Self} - // - // so that all slicing optimizations of the base collection can kick in. - // - // We can't do that right now though, because that would force a lot of - // constraints on `Base.SubSequence`, limiting the possible contexts where - // the `.lazy.map` API can be used. - public typealias IndexDistance = Base.IndexDistance public typealias Indices = Base.Indices diff --git a/stdlib/public/core/Mirror.swift b/stdlib/public/core/Mirror.swift index cdb6ac33da3bf..95079ce5bae25 100644 --- a/stdlib/public/core/Mirror.swift +++ b/stdlib/public/core/Mirror.swift @@ -225,8 +225,6 @@ public struct Mirror { displayStyle: DisplayStyle? = nil, ancestorRepresentation: AncestorRepresentation = .generated ) where C.Element == Child - // FIXME(ABI) (Revert Where Clauses): Remove these - , C.SubSequence : Collection, C.SubSequence.Indices : Collection, C.Indices : Collection { self.subjectType = Subject.self @@ -276,8 +274,6 @@ public struct Mirror { displayStyle: DisplayStyle? = nil, ancestorRepresentation: AncestorRepresentation = .generated ) - // FIXME(ABI) (Revert Where Clauses): Remove these two clauses - where C.SubSequence : Collection, C.Indices : Collection { self.subjectType = Subject.self diff --git a/stdlib/public/core/MutableCollection.swift b/stdlib/public/core/MutableCollection.swift index e2cf4372252f4..15860eccc24fc 100644 --- a/stdlib/public/core/MutableCollection.swift +++ b/stdlib/public/core/MutableCollection.swift @@ -16,139 +16,8 @@ /// `MutableCollection` protocol instead, because it has a more complete /// interface. @available(*, deprecated, message: "it will be removed in Swift 4.0. Please use 'MutableCollection' instead") -public typealias MutableIndexable = _MutableIndexable -public protocol _MutableIndexable : _Indexable { - // FIXME(ABI)#52 (Recursive Protocol Constraints): there is no reason for this protocol - // to exist apart from missing compiler features that we emulate with it. - // rdar://problem/20531108 - // - // This protocol is almost an implementation detail of the standard - // library; it is used to deduce things like the `SubSequence` and - // `Iterator` type from a minimal collection, but it is also used in - // exposed places like as a constraint on `IndexingIterator`. +public typealias MutableIndexable = MutableCollection - /// The position of the first element in a nonempty collection. - /// - /// If the collection is empty, `startIndex` is equal to `endIndex`. - var startIndex: Index { get } - - /// The collection's "past the end" position---that is, the position one - /// greater than the last valid subscript argument. - /// - /// When you need a range that includes the last element of a collection, use - /// the half-open range operator (`..<`) with `endIndex`. The `..<` operator - /// creates a range that doesn't include the upper bound, so it's always - /// safe to use with `endIndex`. For example: - /// - /// let numbers = [10, 20, 30, 40, 50] - /// if let index = numbers.index(of: 30) { - /// print(numbers[index ..< numbers.endIndex]) - /// } - /// // Prints "[30, 40, 50]" - /// - /// If the collection is empty, `endIndex` is equal to `startIndex`. - var endIndex: Index { get } - - /// Accesses the element at the specified position. - /// - /// For example, you can replace an element of an array by using its - /// subscript. - /// - /// var streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"] - /// streets[1] = "Butler" - /// print(streets[1]) - /// // Prints "Butler" - /// - /// You can subscript a collection with any valid index other than the - /// collection's end index. The end index refers to the position one - /// past the last element of a collection, so it doesn't correspond with an - /// element. - /// - /// - Parameter position: The position of the element to access. `position` - /// must be a valid index of the collection that is not equal to the - /// `endIndex` property. - subscript(position: Index) -> Element { get set } - - /// Accesses a contiguous subrange of the collection's elements. - /// - /// The accessed slice uses the same indices for the same elements as the - /// original collection. Always use the slice's `startIndex` property - /// instead of assuming that its indices start at a particular value. - /// - /// This example demonstrates getting a slice of an array of strings, finding - /// the index of one of the strings in the slice, and then using that index - /// in the original array. - /// - /// let streets = ["Adams", "Bryant", "Channing", "Douglas", "Evarts"] - /// let streetsSlice = streets[2 ..< streets.endIndex] - /// print(streetsSlice) - /// // Prints "["Channing", "Douglas", "Evarts"]" - /// - /// let index = streetsSlice.index(of: "Evarts") // 4 - /// streets[index!] = "Eustace" - /// print(streets[index!]) - /// // Prints "Eustace" - /// - /// - Parameter bounds: A range of the collection's indices. The bounds of - /// the range must be valid indices of the collection. - subscript(bounds: Range) -> SubSequence { get set } - - /// Performs a range check in O(1), or a no-op when a range check is not - /// implementable in O(1). - /// - /// The range check, if performed, is equivalent to: - /// - /// precondition(bounds.contains(index)) - /// - /// Use this function to perform a cheap range check for QoI purposes when - /// memory safety is not a concern. Do not rely on this range check for - /// memory safety. - /// - /// The default implementation for forward and bidirectional indices is a - /// no-op. The default implementation for random access indices performs a - /// range check. - /// - /// - Complexity: O(1). - func _failEarlyRangeCheck(_ index: Index, bounds: Range) - - /// Performs a range check in O(1), or a no-op when a range check is not - /// implementable in O(1). - /// - /// The range check, if performed, is equivalent to: - /// - /// precondition( - /// bounds.contains(range.lowerBound) || - /// range.lowerBound == bounds.upperBound) - /// precondition( - /// bounds.contains(range.upperBound) || - /// range.upperBound == bounds.upperBound) - /// - /// Use this function to perform a cheap range check for QoI purposes when - /// memory safety is not a concern. Do not rely on this range check for - /// memory safety. - /// - /// The default implementation for forward and bidirectional indices is a - /// no-op. The default implementation for random access indices performs a - /// range check. - /// - /// - Complexity: O(1). - func _failEarlyRangeCheck(_ range: Range, bounds: Range) - - /// Returns the position immediately after the given index. - /// - /// - Parameter i: A valid index of the collection. `i` must be less than - /// `endIndex`. - /// - Returns: The index value immediately after `i`. - func index(after i: Index) -> Index - - /// Replaces the given index with its successor. - /// - /// - Parameter i: A valid index of the collection. `i` must be less than - /// `endIndex`. - func formIndex(after i: inout Index) -} - -// TODO: swift-3-indexing-model - review the following /// A collection that supports subscript assignment. /// /// Collections that conform to `MutableCollection` gain the ability to @@ -196,14 +65,15 @@ public protocol _MutableIndexable : _Indexable { /// // Must be equivalent to: /// a[i] = x /// let y = x -public protocol MutableCollection : _MutableIndexable, Collection -// FIXME(ABI) (Revert Where Clauses): restore this: -// where SubSequence: MutableCollection +public protocol MutableCollection : Collection { - associatedtype SubSequence - // FIXME(ABI) (Revert Where Clauses): remove this conformance: - : Collection - = MutableSlice + // FIXME(ABI): Associated type inference requires this. + associatedtype Element + + // FIXME(ABI): Associated type inference requires this. + associatedtype Index + + associatedtype SubSequence : MutableCollection = MutableSlice /// Accesses the element at the specified position. /// @@ -223,7 +93,7 @@ public protocol MutableCollection : _MutableIndexable, Collection /// - Parameter position: The position of the element to access. `position` /// must be a valid index of the collection that is not equal to the /// `endIndex` property. - subscript(position: Index) -> Element {get set} + subscript(position: Index) -> Element { get set } /// Accesses a contiguous subrange of the collection's elements. /// @@ -247,7 +117,7 @@ public protocol MutableCollection : _MutableIndexable, Collection /// /// - Parameter bounds: A range of the collection's indices. The bounds of /// the range must be valid indices of the collection. - subscript(bounds: Range) -> SubSequence {get set} + subscript(bounds: Range) -> SubSequence { get set } /// Reorders the elements of the collection such that all the elements /// that match the given predicate are after all the elements that don't @@ -311,7 +181,7 @@ public protocol MutableCollection : _MutableIndexable, Collection /// same algorithm on `body`\ 's argument lets you trade safety for /// speed. mutating func _withUnsafeMutableBufferPointerIfSupported( - _ body: (inout UnsafeMutableBufferPointer) throws -> R + _ body: (inout UnsafeMutableBufferPointer) throws -> R ) rethrows -> R? } @@ -319,7 +189,7 @@ public protocol MutableCollection : _MutableIndexable, Collection extension MutableCollection { @_inlineable public mutating func _withUnsafeMutableBufferPointerIfSupported( - _ body: (inout UnsafeMutableBufferPointer) throws -> R + _ body: (inout UnsafeMutableBufferPointer) throws -> R ) rethrows -> R? { return nil } diff --git a/stdlib/public/core/RandomAccessCollection.swift b/stdlib/public/core/RandomAccessCollection.swift index fcbfa39005227..d3f5f3ab30736 100644 --- a/stdlib/public/core/RandomAccessCollection.swift +++ b/stdlib/public/core/RandomAccessCollection.swift @@ -16,15 +16,7 @@ /// `RandomAccessCollection` protocol instead, because it has a more complete /// interface. @available(*, deprecated, message: "it will be removed in Swift 4.0. Please use 'RandomAccessCollection' instead") -public typealias RandomAccessIndexable = _RandomAccessIndexable -public protocol _RandomAccessIndexable : _BidirectionalIndexable { - // FIXME(ABI)#54 (Recursive Protocol Constraints): there is no reason for this protocol - // to exist apart from missing compiler features that we emulate with it. - // rdar://problem/20531108 - // - // This protocol is almost an implementation detail of the standard - // library. -} +public typealias RandomAccessIndexable = RandomAccessCollection /// A collection that supports efficient random-access index traversal. /// @@ -46,24 +38,23 @@ public protocol _RandomAccessIndexable : _BidirectionalIndexable { /// collection, either the index for your custom type must conform to the /// `Strideable` protocol or you must implement the `index(_:offsetBy:)` and /// `distance(from:to:)` methods with O(1) efficiency. -public protocol RandomAccessCollection : - _RandomAccessIndexable, BidirectionalCollection -// FIXME(ABI) (Revert Where Clauses): Restore this: -// where SubSequence: RandomAccessCollection, Indices: RandomAccessCollection +public protocol RandomAccessCollection : BidirectionalCollection { + // FIXME(ABI): Associated type inference requires this. + associatedtype Element + + // FIXME(ABI): Associated type inference requires this. + associatedtype Index + /// A collection that represents a contiguous subrange of the collection's /// elements. - associatedtype SubSequence - // FIXME(ABI) (Revert Where Clauses): Remove these two constraints: - : _RandomAccessIndexable, BidirectionalCollection - = RandomAccessSlice + associatedtype SubSequence : RandomAccessCollection + = RandomAccessSlice /// A type that represents the indices that are valid for subscripting the /// collection, in ascending order. - associatedtype Indices - // FIXME(ABI) (Revert Where Clauses): Remove these two constraints: - : _RandomAccessIndexable, BidirectionalCollection - = DefaultRandomAccessIndices + associatedtype Indices : RandomAccessCollection + = DefaultRandomAccessIndices /// The indices that are valid for subscripting the collection, in ascending /// order. @@ -106,6 +97,15 @@ public protocol RandomAccessCollection : /// - Parameter bounds: A range of the collection's indices. The bounds of /// the range must be valid indices of the collection. subscript(bounds: Range) -> SubSequence { get } + + // FIXME(ABI): Associated type inference requires this. + subscript(position: Index) -> Element { get } + + // FIXME(ABI): Associated type inference requires this. + var startIndex: Index { get } + + // FIXME(ABI): Associated type inference requires this. + var endIndex: Index { get } } /// Supply the default "slicing" `subscript` for `RandomAccessCollection` @@ -149,7 +149,7 @@ extension RandomAccessCollection where SubSequence == RandomAccessSlice { // wrong complexity. /// Default implementation for random access collections. -extension _RandomAccessIndexable { +extension RandomAccessCollection { /// Returns an index that is the specified distance from the given index, /// unless that distance is beyond a given limiting index. /// diff --git a/stdlib/public/core/Range.swift.gyb b/stdlib/public/core/Range.swift.gyb index f21e15ab8f72c..d0066b7901cba 100644 --- a/stdlib/public/core/Range.swift.gyb +++ b/stdlib/public/core/Range.swift.gyb @@ -60,7 +60,7 @@ public protocol RangeExpression { /// is *not* guaranteed to be inside the bounds of `collection`. Callers /// should apply the same preconditions to the return value as they would /// to a range provided directly by the user. - func relative( + func relative( to collection: C ) -> Range where C.Index == Bound @@ -590,7 +590,7 @@ extension ${Self} { extension ${Self}: RangeExpression { @_inlineable // FIXME(sil-serialize-all) - public func relative(to collection: C) -> Range + public func relative(to collection: C) -> Range where C.Index == Bound { % if 'Closed' in Self: return Range( @@ -821,7 +821,7 @@ public struct PartialRangeUpTo: RangeExpression { @_inlineable // FIXME(sil-serialize-all) @_transparent - public func relative(to collection: C) -> Range + public func relative(to collection: C) -> Range where C.Index == Bound { return collection.startIndex..: RangeExpression { @_inlineable // FIXME(sil-serialize-all) @_transparent - public func relative(to collection: C) -> Range + public func relative(to collection: C) -> Range where C.Index == Bound { return collection.startIndex..: RangeExpression { @_inlineable // FIXME(sil-serialize-all) @_transparent - public func relative(to collection: C) -> Range + public func relative(to collection: C) -> Range where C.Index == Bound { return self.lowerBound..( + public func relative( to collection: C ) -> Range where C.Index == Bound { return self.lowerBound..() -extension _Indexable { +extension Collection { @_inlineable public subscript(r: R) -> SubSequence where R.Bound == Index { @@ -1226,7 +1226,7 @@ extension _Indexable { return self[startIndex...] } } -extension _MutableIndexable { +extension MutableCollection { @_inlineable public subscript(r: R) -> SubSequence where R.Bound == Index { diff --git a/stdlib/public/core/RangeReplaceableCollection.swift.gyb b/stdlib/public/core/RangeReplaceableCollection.swift.gyb index c9a7b652d12c4..eda9d20187bdd 100644 --- a/stdlib/public/core/RangeReplaceableCollection.swift.gyb +++ b/stdlib/public/core/RangeReplaceableCollection.swift.gyb @@ -14,8 +14,6 @@ // //===----------------------------------------------------------------------===// -// FIXME: swift-3-indexing-model: synchronize _Indexable with the actual -// protocol. /// A type that supports replacement of an arbitrary subrange of elements with /// the elements of another collection. /// @@ -23,176 +21,7 @@ /// `RangeReplaceableCollection` protocol instead, because it has a more /// complete interface. @available(*, deprecated, message: "it will be removed in Swift 4.0. Please use 'RandomAccessCollection' instead") -public typealias RangeReplaceableIndexable = _RangeReplaceableIndexable -public protocol _RangeReplaceableIndexable : _Indexable { - // FIXME(ABI)#58 (Recursive Protocol Constraints): there is no reason for this protocol - // to exist apart from missing compiler features that we emulate with it. - // rdar://problem/20531108 - // - // This protocol is almost an implementation detail of the standard - // library. - - /// Creates an empty instance. - init() - - /// Creates a new collection containing the specified number of a single, - /// repeated value. - /// - /// Here's an example of creating an array initialized with five strings - /// containing the letter *Z*. - /// - /// let fiveZs = Array(repeating: "Z", count: 5) - /// print(fiveZs) - /// // Prints "["Z", "Z", "Z", "Z", "Z"]" - /// - /// - Parameters: - /// - repeatedValue: The element to repeat. - /// - count: The number of times to repeat the value passed in the - /// `repeating` parameter. `count` must be zero or greater. - init(repeating repeatedValue: Element, count: Int) - - /// Creates a new instance of a collection containing the elements of a - /// sequence. - /// - /// - Parameter elements: The sequence of elements for the new collection. - /// `elements` must be finite. - init(_ elements: S) where S.Element == Element - - /// Replaces the specified subrange of elements with the given collection. - /// - /// This method has the effect of removing the specified range of elements - /// from the collection and inserting the new elements at the same location. - /// The number of new elements need not match the number of elements being - /// removed. - /// - /// In this example, three elements in the middle of an array of integers are - /// replaced by the five elements of a `Repeated` instance. - /// - /// var nums = [10, 20, 30, 40, 50] - /// nums.replaceSubrange(1...3, with: repeatElement(1, count: 5)) - /// print(nums) - /// // Prints "[10, 1, 1, 1, 1, 1, 50]" - /// - /// If you pass a zero-length range as the `subrange` parameter, this method - /// inserts the elements of `newElements` at `subrange.startIndex`. Calling - /// the `insert(contentsOf:at:)` method instead is preferred. - /// - /// Likewise, if you pass a zero-length collection as the `newElements` - /// parameter, this method removes the elements in the given subrange - /// without replacement. Calling the `removeSubrange(_:)` method instead is - /// preferred. - /// - /// Calling this method may invalidate any existing indices for use with this - /// collection. - /// - /// - Parameters: - /// - subrange: The subrange of the collection to replace. The bounds of - /// the range must be valid indices of the collection. - /// - newElements: The new elements to add to the collection. - /// - /// - Complexity: O(*m*), where *m* is the combined length of the collection - /// and `newElements`. If the call to `replaceSubrange` simply appends the - /// contents of `newElements` to the collection, the complexity is O(*n*), - /// where *n* is the length of `newElements`. - mutating func replaceSubrange( - _ subrange: Range, - with newElements: C - ) where C : Collection, C.Element == Element - - /// Inserts a new element into the collection at the specified position. - /// - /// The new element is inserted before the element currently at the specified - /// index. If you pass the collection's `endIndex` property as the `index` - /// parameter, the new element is appended to the collection. - /// - /// var numbers = [1, 2, 3, 4, 5] - /// numbers.insert(100, at: 3) - /// numbers.insert(200, at: numbers.endIndex) - /// - /// print(numbers) - /// // Prints "[1, 2, 3, 100, 4, 5, 200]" - /// - /// Calling this method may invalidate any existing indices for use with this - /// collection. - /// - /// - Parameters: - /// - newElement: The new element to insert into the collection. - /// - i: The position at which to insert the new element. `index` must be a - /// valid index into the collection. - /// - /// - Complexity: O(*n*), where *n* is the length of the collection. - mutating func insert(_ newElement: Element, at i: Index) - - /// Inserts the elements of a sequence into the collection at the specified - /// position. - /// - /// The new elements are inserted before the element currently at the - /// specified index. If you pass the collection's `endIndex` property as the - /// `index` parameter, the new elements are appended to the collection. - /// - /// Here's an example of inserting a range of integers into an array of the - /// same type: - /// - /// var numbers = [1, 2, 3, 4, 5] - /// numbers.insert(contentsOf: 100...103, at: 3) - /// print(numbers) - /// // Prints "[1, 2, 3, 100, 101, 102, 103, 4, 5]" - /// - /// Calling this method may invalidate any existing indices for use with this - /// collection. - /// - /// - Parameters: - /// - newElements: The new elements to insert into the collection. - /// - i: The position at which to insert the new elements. `index` must be - /// a valid index of the collection. - /// - /// - Complexity: O(*m*), where *m* is the combined length of the collection - /// and `newElements`. If `i` is equal to the collection's `endIndex` - /// property, the complexity is O(*n*), where *n* is the length of - /// `newElements`. - mutating func insert( - contentsOf newElements: S, at i: Index - ) where S.Element == Element - - /// Removes and returns the element at the specified position. - /// - /// All the elements following the specified position are moved to close the - /// gap. This example removes the middle element from an array of - /// measurements. - /// - /// var measurements = [1.2, 1.5, 2.9, 1.2, 1.6] - /// let removed = measurements.remove(at: 2) - /// print(measurements) - /// // Prints "[1.2, 1.5, 1.2, 1.6]" - /// - /// Calling this method may invalidate any existing indices for use with this - /// collection. - /// - /// - Parameter i: The position of the element to remove. `index` must be - /// a valid index of the collection that is not equal to the collection's - /// end index. - /// - Returns: The removed element. - /// - /// - Complexity: O(*n*), where *n* is the length of the collection. - @discardableResult - mutating func remove(at i: Index) -> Element - - /// Removes the specified subrange of elements from the collection. - /// - /// var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"] - /// bugs.removeSubrange(1...3) - /// print(bugs) - /// // Prints "["Aphid", "Earwig"]" - /// - /// Calling this method may invalidate any existing indices for use with this - /// collection. - /// - /// - Parameter bounds: The subrange of the collection to remove. The bounds - /// of the range must be valid indices of the collection. - /// - /// - Complexity: O(*n*), where *n* is the length of the collection. - mutating func removeSubrange(_ bounds: Range) -} +public typealias RangeReplaceableIndexable = RangeReplaceableCollection /// A collection that supports replacement of an arbitrary subrange of elements /// with the elements of another collection. @@ -241,11 +70,9 @@ public protocol _RangeReplaceableIndexable : _Indexable { /// `replaceSubrange(_:with:)` with an empty collection for the `newElements` /// parameter. You can override any of the protocol's required methods to /// provide your own custom implementation. -public protocol RangeReplaceableCollection - : _RangeReplaceableIndexable, Collection +public protocol RangeReplaceableCollection : Collection { - // FIXME(ABI)#165 (Recursive Protocol Constraints): should require `RangeReplaceableCollection`. - associatedtype SubSequence : _RangeReplaceableIndexable /*: RangeReplaceableCollection*/ + associatedtype SubSequence : RangeReplaceableCollection = RangeReplaceableSlice //===--- Fundamental Requirements ---------------------------------------===// @@ -449,6 +276,22 @@ public protocol RangeReplaceableCollection @discardableResult mutating func remove(at i: Index) -> Element + /// Removes the specified subrange of elements from the collection. + /// + /// var bugs = ["Aphid", "Bumblebee", "Cicada", "Damselfly", "Earwig"] + /// bugs.removeSubrange(1...3) + /// print(bugs) + /// // Prints "["Aphid", "Earwig"]" + /// + /// Calling this method may invalidate any existing indices for use with this + /// collection. + /// + /// - Parameter bounds: The subrange of the collection to remove. The bounds + /// of the range must be valid indices of the collection. + /// + /// - Complexity: O(*n*), where *n* is the length of the collection. + mutating func removeSubrange(_ bounds: Range) + /// Customization point for `removeLast()`. Implement this function if you /// want to replace the default implementation. /// @@ -509,6 +352,9 @@ public protocol RangeReplaceableCollection /// /// - Complexity: O(*n*), where *n* is the length of the collection. mutating func removeAll(keepingCapacity keepCapacity: Bool /*= false*/) + + // FIXME(ABI): Associated type inference requires this. + subscript(bounds: Range) -> SubSequence { get } } //===----------------------------------------------------------------------===// @@ -813,7 +659,6 @@ extension RangeReplaceableCollection { % for capability in ['', 'Bidirectional', 'RandomAccess']: % if capability: extension RangeReplaceableCollection where - Self: ${capability}Collection, Self.SubSequence == RangeReplaceable${capability}Slice { @_inlineable // FIXME(sil-serialize-all) public subscript(bounds: Range) @@ -824,10 +669,6 @@ extension RangeReplaceableCollection where % end extension RangeReplaceableCollection where - Self: MutableCollection, -% if capability: - Self: ${capability}Collection, -% end Self.SubSequence == MutableRangeReplaceable${capability}Slice { @_inlineable // FIXME(sil-serialize-all) diff --git a/stdlib/public/core/Reverse.swift b/stdlib/public/core/Reverse.swift index 28c20482a4756..98bfd52aecbbb 100644 --- a/stdlib/public/core/Reverse.swift +++ b/stdlib/public/core/Reverse.swift @@ -380,6 +380,9 @@ public struct ReversedRandomAccessCollection< public typealias IndexDistance = Base.IndexDistance + public typealias Indices = + DefaultRandomAccessIndices> + /// A type that provides the sequence's iteration interface and /// encapsulates its iteration state. public typealias Iterator = IndexingIterator< diff --git a/stdlib/public/core/Sequence.swift b/stdlib/public/core/Sequence.swift index d81cfa8b3bb78..61a52b59d37e4 100644 --- a/stdlib/public/core/Sequence.swift +++ b/stdlib/public/core/Sequence.swift @@ -331,19 +331,9 @@ public protocol Sequence { associatedtype Iterator : IteratorProtocol where Iterator.Element == Element /// A type that represents a subsequence of some of the sequence's elements. - associatedtype SubSequence - // FIXME(ABI)#104 (Recursive Protocol Constraints): - // FIXME(ABI)#105 (Associated Types with where clauses): - // associatedtype SubSequence : Sequence - // where - // Element == SubSequence.Element, - // SubSequence.SubSequence == SubSequence - // - // ( Implement recursive protocol - // constraints) - // - // These constraints allow processing collections in generic code by - // repeatedly slicing them in a loop. + associatedtype SubSequence : Sequence + where Element == SubSequence.Element, + SubSequence.SubSequence == SubSequence /// Returns an iterator over the elements of this sequence. func makeIterator() -> Iterator @@ -1194,10 +1184,7 @@ extension Sequence where Element : Equatable { } } -extension Sequence where - SubSequence : Sequence, - SubSequence.Element == Element, - SubSequence.SubSequence == SubSequence { +extension Sequence { /// Returns a subsequence containing all but the given number of initial /// elements. diff --git a/stdlib/public/core/SequenceWrapper.swift b/stdlib/public/core/SequenceWrapper.swift index a06981f320165..f89c407cfaf12 100644 --- a/stdlib/public/core/SequenceWrapper.swift +++ b/stdlib/public/core/SequenceWrapper.swift @@ -19,7 +19,7 @@ @_show_in_interface public // @testable protocol _SequenceWrapper : Sequence { - associatedtype Base : Sequence + associatedtype Base : Sequence where Base.Element == Element associatedtype Iterator = Base.Iterator associatedtype SubSequence = Base.SubSequence @@ -55,7 +55,7 @@ extension _SequenceWrapper where Iterator == Base.Iterator { } } -extension _SequenceWrapper where Element == Base.Element { +extension _SequenceWrapper { @_inlineable // FIXME(sil-serialize-all) public func map( _ transform: (Element) throws -> T @@ -106,10 +106,6 @@ extension _SequenceWrapper where SubSequence == Base.SubSequence { public func suffix(_ maxLength: Int) -> SubSequence { return _base.suffix(maxLength) } -} - -extension _SequenceWrapper - where SubSequence == Base.SubSequence, Element == Base.Element { @_inlineable // FIXME(sil-serialize-all) public func drop( @@ -125,11 +121,6 @@ extension _SequenceWrapper return try _base.prefix(while: predicate) } - @_inlineable // FIXME(sil-serialize-all) - public func suffix(_ maxLength: Int) -> SubSequence { - return _base.suffix(maxLength) - } - @_inlineable // FIXME(sil-serialize-all) public func split( maxSplits: Int, omittingEmptySubsequences: Bool, diff --git a/stdlib/public/core/Slice.swift.gyb b/stdlib/public/core/Slice.swift.gyb index 68a80672b1244..9665e51146dea 100644 --- a/stdlib/public/core/Slice.swift.gyb +++ b/stdlib/public/core/Slice.swift.gyb @@ -15,6 +15,7 @@ from gyb_stdlib_support import ( TRAVERSALS, collectionForTraversal, + defaultIndicesForTraversal, sliceTypeName, protocolsForCollectionFeatures ) @@ -96,13 +97,9 @@ def get_slice_doc_comment(Self): % for Mutable in [ False, True ]: % for RangeReplaceable in [ False, True ]: % Self = sliceTypeName(traversal=Traversal, mutable=Mutable, rangeReplaceable=RangeReplaceable) -% BaseRequirements = ['_' + collectionForTraversal(Traversal).replace('Collection', 'Indexable')] -% if Mutable: -% BaseRequirements.append('_MutableIndexable') -% if RangeReplaceable: -% BaseRequirements.append('_RangeReplaceableIndexable') -% BaseRequirements = ' & '.join(BaseRequirements) +% BaseRequirements = ' & '.join(protocolsForCollectionFeatures(traversal=Traversal, mutable=Mutable, rangeReplaceable=RangeReplaceable)) % SelfProtocols = ', '.join(protocolsForCollectionFeatures(traversal=Traversal, mutable=Mutable, rangeReplaceable=RangeReplaceable)) +% Indices = defaultIndicesForTraversal(Traversal) ${get_slice_doc_comment(Self)} % if Mutable: @@ -119,6 +116,7 @@ public struct ${Self} public typealias Index = Base.Index public typealias IndexDistance = Base.IndexDistance + public typealias Indices = ${Indices}<${Self}> public var _startIndex: Index public var _endIndex: Index diff --git a/stdlib/public/core/String.swift b/stdlib/public/core/String.swift index 3094471a58d89..85dce6284bf67 100644 --- a/stdlib/public/core/String.swift +++ b/stdlib/public/core/String.swift @@ -21,7 +21,7 @@ public protocol StringProtocol TextOutputStream, TextOutputStreamable, LosslessStringConvertible, ExpressibleByStringLiteral, Hashable, Comparable - where Iterator.Element == Character { + where Iterator.Element == Character, SubSequence : StringProtocol { associatedtype UTF8View : /*Bidirectional*/Collection where UTF8View.Element == UInt8 // Unicode.UTF8.CodeUnit diff --git a/stdlib/public/core/UnsafeBufferPointer.swift.gyb b/stdlib/public/core/UnsafeBufferPointer.swift.gyb index 8504cb3ba698b..fb947be559fdf 100644 --- a/stdlib/public/core/UnsafeBufferPointer.swift.gyb +++ b/stdlib/public/core/UnsafeBufferPointer.swift.gyb @@ -59,7 +59,7 @@ public struct UnsafeBufferPointerIterator /// referenced memory and into the new collection. @_fixed_layout public struct Unsafe${Mutable}BufferPointer - : _${Mutable}Indexable, ${Mutable}Collection, RandomAccessCollection { + : ${Mutable}Collection, RandomAccessCollection { // FIXME: rdar://18157434 - until this is fixed, this has to be fixed layout // to avoid a hang in Foundation, which has the following setup: // struct A { struct B { let x: UnsafeMutableBufferPointer<...> } let b: B } diff --git a/test/Generics/requirement_inference.swift b/test/Generics/requirement_inference.swift index e96db636179fa..1342d298a5a8e 100644 --- a/test/Generics/requirement_inference.swift +++ b/test/Generics/requirement_inference.swift @@ -168,7 +168,6 @@ func sameTypeConcrete2(_: T) where T.B : X3, T.C == T.B, T.C == X3 // CHECK-LABEL: RangeReplaceableCollection // CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : MutableCollection, τ_0_0 : RangeReplaceableCollection, τ_0_0.SubSequence == MutableRangeReplaceableSlice<τ_0_0>> extension RangeReplaceableCollection where - Self: MutableCollection, Self.SubSequence == MutableRangeReplaceableSlice { func f() { } @@ -177,7 +176,7 @@ extension RangeReplaceableCollection where // CHECK-LABEL: X14.recursiveConcreteSameType // CHECK: Generic signature: > // CHECK-NEXT: Canonical generic signature: <τ_0_0, τ_1_0 where τ_0_0 == CountableRange> -struct X14 where T.Iterator == IndexingIterator { +struct X14 where T.Iterator == IndexingIterator { func recursiveConcreteSameType(_: V) where T == CountableRange { } } diff --git a/test/SourceKit/InterfaceGen/gen_swift_module.swift b/test/SourceKit/InterfaceGen/gen_swift_module.swift index 33c441896d70d..7df6ce9408994 100644 --- a/test/SourceKit/InterfaceGen/gen_swift_module.swift +++ b/test/SourceKit/InterfaceGen/gen_swift_module.swift @@ -15,12 +15,12 @@ func f(s : inout [Int]) { // RUN: %swift -emit-module -o %t.mod/swift_mod_syn.swiftmodule %S/Inputs/swift_mod_syn.swift -parse-as-library // RUN: %sourcekitd-test -req=interface-gen-open -module swift_mod_syn -- -I %t.mod == -req=cursor -pos=4:7 %s -- %s -I %t.mod | %FileCheck -check-prefix=SYNTHESIZED-USR1 %s -// SYNTHESIZED-USR1: s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements8SequencePRpzlE4sortyyF::SYNTHESIZED::s:Sa +// SYNTHESIZED-USR1: s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements013BidirectionalB0PRpzlE4sortyyF::SYNTHESIZED::s:Sa // RUN: %sourcekitd-test -req=interface-gen-open -module Swift -synthesized-extension \ -// RUN: == -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements8SequencePRpzlE4sortyyF::SYNTHESIZED::s:Sa" | %FileCheck -check-prefix=SYNTHESIZED-USR2 %s +// RUN: == -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements013BidirectionalB0PRpzlE4sortyyF::SYNTHESIZED::s:Sa" | %FileCheck -check-prefix=SYNTHESIZED-USR2 %s // SYNTHESIZED-USR2-NOT: USR NOT FOUND // RUN: %sourcekitd-test -req=interface-gen-open -module Swift \ -// RUN: == -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements8SequencePRpzlE4sortyyF::SYNTHESIZED::s:Sa::SYNTHESIZED::USRDOESNOTEXIST" | %FileCheck -check-prefix=SYNTHESIZED-USR3 %s +// RUN: == -req=find-usr -usr "s:s17MutableCollectionPssAARzs012RandomAccessB0Rzs10Comparable7Elements013BidirectionalB0PRpzlE4sortyyF::SYNTHESIZED::s:Sa::SYNTHESIZED::USRDOESNOTEXIST" | %FileCheck -check-prefix=SYNTHESIZED-USR3 %s // SYNTHESIZED-USR3-NOT: USR NOT FOUND diff --git a/test/stdlib/StringCompatibility.swift b/test/stdlib/StringCompatibility.swift index 9780d215f4154..b4ee7933e7198 100644 --- a/test/stdlib/StringCompatibility.swift +++ b/test/stdlib/StringCompatibility.swift @@ -18,10 +18,14 @@ extension MyString : BidirectionalCollection { typealias Iterator = String.Iterator typealias Index = String.Index typealias IndexDistance = String.IndexDistance + typealias SubSequence = MyString func makeIterator() -> Iterator { return base.makeIterator() } var startIndex: String.Index { return base.startIndex } var endIndex: String.Index { return base.startIndex } subscript(i: Index) -> Character { return base[i] } + subscript(indices: Range) -> MyString { + return MyString(base: String(self.base[indices])) + } func index(after i: Index) -> Index { return base.index(after: i) } func index(before i: Index) -> Index { return base.index(before: i) } func index(_ i: Index, offsetBy n: IndexDistance) -> Index { diff --git a/validation-test/compiler_crashers_2_fixed/0089-sr4458.swift b/validation-test/compiler_crashers_2_fixed/0089-sr4458.swift index 25e0ec7f55252..86d9c05951bca 100644 --- a/validation-test/compiler_crashers_2_fixed/0089-sr4458.swift +++ b/validation-test/compiler_crashers_2_fixed/0089-sr4458.swift @@ -4,7 +4,7 @@ import Foundation -extension _MutableIndexable { +extension MutableCollection { typealias SubSequence = MutableRangeReplaceableRandomAccessSlice } diff --git a/validation-test/compiler_crashers/28796-result-second.swift b/validation-test/compiler_crashers_fixed/28796-result-second.swift similarity index 89% rename from validation-test/compiler_crashers/28796-result-second.swift rename to validation-test/compiler_crashers_fixed/28796-result-second.swift index 581543953baea..316ac8c00aa00 100644 --- a/validation-test/compiler_crashers/28796-result-second.swift +++ b/validation-test/compiler_crashers_fixed/28796-result-second.swift @@ -6,5 +6,5 @@ // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // REQUIRES: asserts -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir class a @@ -59,30 +57,27 @@ struct GoodIndexable : Indexable { var endIndex: Int { return 0 } subscript(pos: Int) -> Int { return 0 } - subscript(bounds: Range) -> [Int] { return [] } + subscript(bounds: Range) -> ArraySlice { return [] } } -// expected-warning@+2 {{'Indexable' is deprecated: it will be removed in Swift 4.0. Please use 'Collection' instead}} -// expected-error@+1 {{type 'BadIndexable1' does not conform to protocol '_IndexableBase'}} -struct BadIndexable1 : Indexable { +// expected-warning@+1 {{'Indexable' is deprecated: it will be removed in Swift 4.0. Please use 'Collection' instead}} +struct AnotherGoodIndexable1 : Indexable { func index(after i: Int) -> Int { return i + 1 } var startIndex: Int { return 0 } var endIndex: Int { return 0 } subscript(pos: Int) -> Int { return 0 } - - // Missing 'subscript(_:) -> SubSequence'. } // expected-warning@+2 {{'Indexable' is deprecated: it will be removed in Swift 4.0. Please use 'Collection' instead}} -// expected-error@+1 {{type 'BadIndexable2' does not conform to protocol '_IndexableBase'}} +// expected-error@+1 {{type 'BadIndexable2' does not conform to protocol 'Collection'}} struct BadIndexable2 : Indexable { var startIndex: Int { return 0 } var endIndex: Int { return 0 } subscript(pos: Int) -> Int { return 0 } - subscript(bounds: Range) -> [Int] { return [] } + subscript(bounds: Range) -> ArraySlice { return [] } // Missing index(after:) -> Int } @@ -94,7 +89,7 @@ struct GoodBidirectionalIndexable1 : BidirectionalIndexable { func index(before i: Int) -> Int { return i - 1 } subscript(pos: Int) -> Int { return 0 } - subscript(bounds: Range) -> [Int] { return [] } + subscript(bounds: Range) -> ArraySlice { return [] } } // We'd like to see: {{type 'BadBidirectionalIndexable' does not conform to protocol 'BidirectionalIndexable'}} @@ -105,12 +100,12 @@ struct BadBidirectionalIndexable : BidirectionalIndexable { var endIndex: Int { return 0 } subscript(pos: Int) -> Int { return 0 } - subscript(bounds: Range) -> [Int] { return [] } + subscript(bounds: Range) -> ArraySlice { return [] } // This is a poor error message; it would be better to get a message // that index(before:) was missing. // - // expected-error@+1 {{'index(after:)' has different argument labels from those required by protocol '_BidirectionalIndexable' ('index(before:)'}} + // expected-error@+1 {{'index(after:)' has different argument labels from those required by protocol 'BidirectionalCollection' ('index(before:)'}} func index(after i: Int) -> Int { return 0 } } diff --git a/validation-test/stdlib/Lazy.swift.gyb b/validation-test/stdlib/Lazy.swift.gyb index b91833b189fa2..56c716bd776ec 100644 --- a/validation-test/stdlib/Lazy.swift.gyb +++ b/validation-test/stdlib/Lazy.swift.gyb @@ -874,8 +874,7 @@ tests.test("LazyMapCollection/AssociatedTypes") { expectCollectionAssociatedTypes( collectionType: Subject.self, iteratorType: LazyMapIterator>.self, - // FIXME(ABI)#77 (Associated Types with where clauses): SubSequence should be `LazyMapCollection`. - subSequenceType: Slice.self, + subSequenceType: LazyMapCollection>.self, indexType: Base.Index.self, indexDistanceType: Base.IndexDistance.self, indicesType: Base.Indices.self) @@ -887,8 +886,7 @@ tests.test("LazyMapBidirectionalCollection/AssociatedTypes") { expectBidirectionalCollectionAssociatedTypes( collectionType: Subject.self, iteratorType: LazyMapIterator>.self, - // FIXME(ABI)#78 (Associated Types with where clauses): SubSequence should be `LazyMapBidirectionalCollection`. - subSequenceType: BidirectionalSlice.self, + subSequenceType: LazyMapBidirectionalCollection>.self, indexType: Base.Index.self, indexDistanceType: Base.IndexDistance.self, indicesType: Base.Indices.self) @@ -900,8 +898,7 @@ tests.test("LazyMapRandomAccessCollection/AssociatedTypes") { expectRandomAccessCollectionAssociatedTypes( collectionType: Subject.self, iteratorType: LazyMapIterator>.self, - // FIXME(ABI)#79 (Associated Types with where clauses): SubSequence should be `LazyMapRandomAccessCollection`. - subSequenceType: RandomAccessSlice.self, + subSequenceType: LazyMapRandomAccessCollection>.self, indexType: Base.Index.self, indexDistanceType: Base.IndexDistance.self, indicesType: Base.Indices.self) @@ -1167,8 +1164,7 @@ tests.test("LazyFilterCollection/AssociatedTypes") { expectCollectionAssociatedTypes( collectionType: Subject.self, iteratorType: LazyFilterIterator.self, - // FIXME(ABI)#80 (Associated Types with where clauses): SubSequence should be `LazyFilterCollection`. - subSequenceType: Slice.self, + subSequenceType: LazyFilterCollection.self, indexType: LazyFilterIndex.self, indexDistanceType: Base.IndexDistance.self, indicesType: DefaultIndices.self) @@ -1180,8 +1176,7 @@ tests.test("LazyFilterBidirectionalCollection/AssociatedTypes") { expectBidirectionalCollectionAssociatedTypes( collectionType: Subject.self, iteratorType: LazyFilterIterator.self, - // FIXME(ABI)#81 (Associated Types with where clauses): SubSequence should be `LazyFilterBidirectionalCollection`. - subSequenceType: BidirectionalSlice.self, + subSequenceType: LazyFilterBidirectionalCollection.self, indexType: LazyFilterIndex.self, indexDistanceType: Base.IndexDistance.self, indicesType: DefaultBidirectionalIndices.self)