Skip to content

Commit 0a687c6

Browse files
[4.0] Add recursive where clauses to Collection protocols (#9404)
* Add Collection constraints via protocol where clauses (#9374) * Merge pull request #9379 from airspeedswift/redundant-where
1 parent 09c15f0 commit 0a687c6

14 files changed

+34
-112
lines changed

stdlib/private/StdlibCollectionUnittest/CheckCollectionInstance.swift.gyb

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,7 @@ public func checkCollection<${genericParam}, C : Collection>(
257257
${TRACE},
258258
resiliencyChecks: CollectionMisuseResiliencyChecks = .all,
259259
sameValue: (${Element}, ${Element}) -> Bool
260-
) where C.Iterator.Element == ${Element},
261-
C.SubSequence : Collection {
260+
) where C.Iterator.Element == ${Element} {
262261

263262
checkForwardCollection(expected, collection, message(),
264263
stackTrace: stackTrace, showFrame: showFrame, file: file, line: line,
@@ -278,7 +277,6 @@ public func check${Traversal}Collection<
278277
resiliencyChecks: CollectionMisuseResiliencyChecks = .all
279278
) where
280279
C.Iterator.Element == ${Element},
281-
C.SubSequence : ${TraversalCollection},
282280
${Element} : Equatable {
283281

284282
check${Traversal}Collection(
@@ -298,8 +296,7 @@ public func check${Traversal}Collection<
298296
resiliencyChecks: CollectionMisuseResiliencyChecks = .all,
299297
sameValue: (${Element}, ${Element}) -> Bool
300298
) where
301-
C.Iterator.Element == ${Element},
302-
C.SubSequence : ${TraversalCollection} {
299+
C.Iterator.Element == ${Element} {
303300

304301
checkOneLevelOf${Traversal}Collection(expected, collection, ${trace},
305302
resiliencyChecks: resiliencyChecks, sameValue: sameValue)
@@ -504,8 +501,7 @@ ${genericParam}, S : ${TraversalCollection}
504501
resiliencyChecks: CollectionMisuseResiliencyChecks = .all,
505502
sameValue: (${Element}, ${Element}) -> Bool
506503
) where
507-
S.Iterator.Element == ${Element},
508-
S.SubSequence : ${TraversalCollection} {
504+
S.Iterator.Element == ${Element} {
509505

510506
let expectedArray = Array(expected)
511507

stdlib/private/StdlibCollectionUnittest/CheckCollectionType.swift.gyb

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -471,16 +471,9 @@ internal enum _SubSequenceSubscriptOnRangeMode {
471471
%{
472472
from gyb_stdlib_support import collectionForTraversal
473473
def testConstraints(protocol):
474-
if protocol == 'Collection':
475-
subseq_as_collection = 'CollectionWithEquatableElement.SubSequence : Collection,'
476-
else:
477-
subseq_as_collection=''
478474
return '''
479475
C : %(protocol)s,
480476
CollectionWithEquatableElement : %(protocol)s,
481-
%(subseq_as_collection)s
482-
C.SubSequence : %(protocol)s,
483-
C.Indices : %(protocol)s,
484477
CollectionWithEquatableElement.Iterator.Element : Equatable
485478
''' % locals()
486479

@@ -494,6 +487,7 @@ internal enum _SubSequenceSubscriptOnRangeMode {
494487
[CollectionWithEquatableElement.Iterator.Element]
495488
) -> CollectionWithEquatableElement,
496489

490+
497491
wrapValueIntoEquatable: @escaping (
498492
MinimalEquatableValue) -> CollectionWithEquatableElement.Iterator.Element,
499493

stdlib/private/StdlibCollectionUnittest/CheckMutableCollectionType.swift.gyb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,6 @@ extension TestSuite {
121121
isFixedLengthCollection: Bool,
122122
collectionIsBidirectional: Bool = false
123123
) where
124-
C.SubSequence : MutableCollection,
125-
C.Indices : Collection,
126124
CollectionWithEquatableElement.Iterator.Element : Equatable,
127125
CollectionWithComparableElement.Iterator.Element : Comparable {
128126

@@ -783,8 +781,6 @@ self.test("\(testNamePrefix).partition/InvalidOrderings") {
783781
withUnsafeMutableBufferPointerIsSupported: Bool,
784782
isFixedLengthCollection: Bool
785783
) where
786-
C.SubSequence : BidirectionalCollection & MutableCollection,
787-
C.Indices : BidirectionalCollection,
788784
CollectionWithEquatableElement.Iterator.Element : Equatable,
789785
CollectionWithComparableElement.Iterator.Element : Comparable {
790786

@@ -929,8 +925,6 @@ self.test("\(testNamePrefix).partition/DispatchesThrough_withUnsafeMutableBuffer
929925
withUnsafeMutableBufferPointerIsSupported: Bool,
930926
isFixedLengthCollection: Bool
931927
) where
932-
C.SubSequence : RandomAccessCollection & MutableCollection,
933-
C.Indices : RandomAccessCollection,
934928
CollectionWithEquatableElement.Iterator.Element : Equatable,
935929
CollectionWithComparableElement.Iterator.Element : Comparable {
936930

stdlib/private/StdlibCollectionUnittest/CheckRangeReplaceableCollectionType.swift

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -462,10 +462,7 @@ extension TestSuite {
462462
outOfBoundsIndexOffset: Int = 1,
463463
collectionIsBidirectional: Bool = false
464464
) where
465-
C.SubSequence : Collection,
466-
C.Indices : Collection,
467-
CollectionWithEquatableElement.Iterator.Element : Equatable,
468-
CollectionWithEquatableElement.SubSequence : Collection {
465+
CollectionWithEquatableElement.Iterator.Element : Equatable {
469466

470467
var testNamePrefix = testNamePrefix
471468

@@ -1180,8 +1177,6 @@ self.test("\(testNamePrefix).OperatorPlus") {
11801177
resiliencyChecks: CollectionMisuseResiliencyChecks = .all,
11811178
outOfBoundsIndexOffset: Int = 1
11821179
) where
1183-
C.SubSequence : BidirectionalCollection & RangeReplaceableCollection,
1184-
C.Indices : BidirectionalCollection,
11851180
CollectionWithEquatableElement.Iterator.Element : Equatable {
11861181

11871182
var testNamePrefix = testNamePrefix
@@ -1302,8 +1297,6 @@ self.test("\(testNamePrefix).removeLast(n: Int)/whereIndexIsBidirectional/remove
13021297
resiliencyChecks: CollectionMisuseResiliencyChecks = .all,
13031298
outOfBoundsIndexOffset: Int = 1
13041299
) where
1305-
C.SubSequence : RandomAccessCollection & RangeReplaceableCollection,
1306-
C.Indices : RandomAccessCollection,
13071300
CollectionWithEquatableElement.Iterator.Element : Equatable {
13081301

13091302
var testNamePrefix = testNamePrefix

stdlib/private/StdlibCollectionUnittest/CheckRangeReplaceableSliceType.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ extension TestSuite {
3333
collectionIsBidirectional: Bool = false
3434
) where
3535
C.SubSequence == C,
36-
C.Indices : Collection,
3736
CollectionWithEquatableElement.SubSequence == CollectionWithEquatableElement,
3837
CollectionWithEquatableElement.Iterator.Element : Equatable {
3938

@@ -165,7 +164,6 @@ extension TestSuite {
165164
outOfBoundsIndexOffset: Int = 1
166165
) where
167166
C.SubSequence == C,
168-
C.Indices : BidirectionalCollection,
169167
CollectionWithEquatableElement.SubSequence == CollectionWithEquatableElement,
170168
CollectionWithEquatableElement.Iterator.Element : Equatable {
171169

@@ -310,7 +308,6 @@ extension TestSuite {
310308
outOfBoundsIndexOffset: Int = 1
311309
) where
312310
C.SubSequence == C,
313-
C.Indices : RandomAccessCollection,
314311
CollectionWithEquatableElement.SubSequence == CollectionWithEquatableElement,
315312
CollectionWithEquatableElement.Iterator.Element : Equatable {
316313

stdlib/private/StdlibUnittest/StdlibUnittest.swift.gyb

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,7 @@ public func expectSequenceType<X : Sequence>(_ x: X) -> X
376376
% for Mutable in ['', 'Mutable']:
377377
public func expect${Mutable}CollectionType<X : ${Mutable}Collection>(
378378
_ x: X.Type
379-
) where
380-
// FIXME(ABI)#2 (Associated Types with where clauses): there should be no constraints in
381-
// the 'where' clause, all of these should be required by the protocol.
382-
% if Mutable == '':
383-
X.SubSequence : Collection,
384-
% end
385-
// X.SubSequence.Indices == X.Indices, // FIXME(ABI)#3 (Recursive Protocol Constraints): can't have this constraint now.
386-
X.Indices : Collection {}
379+
) { }
387380
% end
388381

389382
/// A slice is a `Collection` that when sliced returns an instance of
@@ -421,12 +414,7 @@ public func expectCollectionAssociatedTypes<X : Collection>(
421414
indexType: X.Index.Type,
422415
indexDistanceType: X.IndexDistance.Type,
423416
indicesType: X.Indices.Type
424-
) where
425-
// FIXME(ABI)#6 (Associated Types with where clauses): there should be no constraints in
426-
// the 'where' clause, all of these should be required by the protocol.
427-
X.SubSequence : Collection,
428-
// X.SubSequence.Indices == X.Indices, // FIXME(ABI)#7 (Recursive Protocol Constraints): can't have this constraint now.
429-
X.Indices : Collection {}
417+
) { }
430418

431419
/// Check that all associated types of a `BidirectionalCollection` are what we
432420
/// expect them to be.
@@ -437,12 +425,7 @@ public func expectBidirectionalCollectionAssociatedTypes<X : BidirectionalCollec
437425
indexType: X.Index.Type,
438426
indexDistanceType: X.IndexDistance.Type,
439427
indicesType: X.Indices.Type
440-
) where
441-
// FIXME(ABI)#8 (Associated Types with where clauses): there should be no constraints in
442-
// the 'where' clause, all of these should be required by the protocol.
443-
X.SubSequence : BidirectionalCollection,
444-
// X.SubSequence.Indices == X.Indices, // FIXME(ABI)#9 (Recursive Protocol Constraints): can't have this constraint now.
445-
X.Indices : BidirectionalCollection {}
428+
) { }
446429

447430
/// Check that all associated types of a `RandomAccessCollection` are what we
448431
/// expect them to be.
@@ -453,12 +436,7 @@ public func expectRandomAccessCollectionAssociatedTypes<X : RandomAccessCollecti
453436
indexType: X.Index.Type,
454437
indexDistanceType: X.IndexDistance.Type,
455438
indicesType: X.Indices.Type
456-
) where
457-
// FIXME(ABI)#10 (Associated Types with where clauses): there should be no constraints in
458-
// the 'where' clause, all of these should be required by the protocol.
459-
X.SubSequence : RandomAccessCollection,
460-
// X.SubSequence.Indices == X.Indices, // FIXME(ABI)#11 (Recursive Protocol Constraints): can't have this constraint now.
461-
X.Indices : RandomAccessCollection {}
439+
) { }
462440

463441
public struct AssertionResult : CustomStringConvertible {
464442
init(isPass: Bool) {

stdlib/public/core/ArrayBufferProtocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
internal protocol _ArrayBufferProtocol
1717
: MutableCollection, RandomAccessCollection {
1818

19-
associatedtype Indices : RandomAccessCollection = CountableRange<Int>
19+
associatedtype Indices = CountableRange<Int>
2020

2121
/// The type of elements stored in the buffer.
2222
associatedtype Element

stdlib/public/core/BidirectionalCollection.swift

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ public protocol _BidirectionalIndexable : _Indexable {
6565
/// `c.index(before: c.index(after: i)) == i`.
6666
/// - If `i > c.startIndex && i <= c.endIndex`
6767
/// `c.index(after: c.index(before: i)) == i`.
68-
public protocol BidirectionalCollection
69-
: _BidirectionalIndexable, Collection {
68+
public protocol BidirectionalCollection : _BidirectionalIndexable, Collection
69+
where SubSequence: BidirectionalCollection, Indices: BidirectionalCollection {
7070

7171
// TODO: swift-3-indexing-model - replaces functionality in BidirectionalIndex
7272
/// Returns the position immediately before the given index.
@@ -84,17 +84,11 @@ public protocol BidirectionalCollection
8484

8585
/// A sequence that can represent a contiguous subrange of the collection's
8686
/// elements.
87-
associatedtype SubSequence : _BidirectionalIndexable, Collection
88-
= BidirectionalSlice<Self>
89-
// FIXME(ABI)#93 (Recursive Protocol Constraints):
90-
// associatedtype SubSequence : BidirectionalCollection
87+
associatedtype SubSequence = BidirectionalSlice<Self>
9188

9289
/// A type that represents the indices that are valid for subscripting the
9390
/// collection, in ascending order.
94-
associatedtype Indices : _BidirectionalIndexable, Collection
95-
= DefaultBidirectionalIndices<Self>
96-
// FIXME(ABI)#95 (Recursive Protocol Constraints):
97-
// associatedtype Indices : BidirectionalCollection
91+
associatedtype Indices = DefaultBidirectionalIndices<Self>
9892

9993
/// The indices that are valid for subscripting the collection, in ascending
10094
/// order.

stdlib/public/core/Collection.swift

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,10 @@ public struct IndexingIterator<
642642
/// forward or bidirectional collection must traverse the entire collection to
643643
/// count the number of contained elements, accessing its `count` property is
644644
/// an O(*n*) operation.
645-
public protocol Collection : _Indexable, Sequence {
645+
public protocol Collection : _Indexable, Sequence
646+
where SubSequence: Collection, Indices: Collection,
647+
SubSequence.Index == Index
648+
{
646649
/// A type that represents the number of steps between a pair of
647650
/// indices.
648651
associatedtype IndexDistance = Int
@@ -668,10 +671,10 @@ public protocol Collection : _Indexable, Sequence {
668671
/// This associated type appears as a requirement in the `Sequence`
669672
/// protocol, but it is restated here with stricter constraints. In a
670673
/// collection, the subsequence should also conform to `Collection`.
671-
associatedtype SubSequence : _IndexableBase, Sequence = Slice<Self>
672-
where Self.SubSequence.Index == Index,
673-
Self.Iterator.Element == Self.SubSequence.Iterator.Element,
674+
associatedtype SubSequence = Slice<Self>
675+
where Iterator.Element == SubSequence.Iterator.Element,
674676
SubSequence.SubSequence == SubSequence
677+
675678
// FIXME(ABI)#98 (Recursive Protocol Constraints):
676679
// FIXME(ABI)#99 (Associated Types with where clauses):
677680
// associatedtype SubSequence : Collection
@@ -732,10 +735,9 @@ public protocol Collection : _Indexable, Sequence {
732735

733736
/// A type that represents the indices that are valid for subscripting the
734737
/// collection, in ascending order.
735-
associatedtype Indices : _Indexable, Sequence = DefaultIndices<Self>
738+
associatedtype Indices = DefaultIndices<Self>
736739
where Indices.Iterator.Element == Index,
737-
Indices.Index == Index,
738-
Indices.SubSequence == Indices
740+
Indices.Index == Index
739741

740742
// FIXME(ABI)#100 (Recursive Protocol Constraints):
741743
// associatedtype Indices : Collection

stdlib/public/core/ExistentialCollection.swift.gyb

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -426,14 +426,11 @@ internal class _AnyRandomAccessCollectionBox<Element>
426426
@_fixed_layout
427427
@_versioned
428428
internal final class _${Kind}Box<S : ${Kind}> : _Any${Kind}Box<S.Iterator.Element>
429+
% if Kind == 'Sequence':
429430
where
430431
S.SubSequence : ${Kind},
431-
% if Kind == 'Sequence':
432432
S.SubSequence.Iterator.Element == S.Iterator.Element,
433433
S.SubSequence.SubSequence == S.SubSequence
434-
% else:
435-
S.SubSequence.Indices : ${Kind},
436-
S.Indices : ${Kind}
437434
% end
438435
{
439436
internal typealias Element = S.Iterator.Element
@@ -1040,10 +1037,7 @@ public struct ${Self}<Element>
10401037
where
10411038
// FIXME(ABI)#101 (Associated Types with where clauses): these constraints should be applied to
10421039
// associated types of Collection.
1043-
C.SubSequence : ${SubProtocol},
1044-
C.SubSequence.Iterator.Element == Element,
1045-
C.SubSequence.Indices : ${SubProtocol},
1046-
C.Indices : ${SubProtocol}
1040+
C.SubSequence.Iterator.Element == Element
10471041
{
10481042
// Traversal: ${Traversal}
10491043
// SubTraversal: ${SubTraversal}

stdlib/public/core/Mirror.swift

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,7 @@ public struct Mirror {
214214
children: C,
215215
displayStyle: DisplayStyle? = nil,
216216
ancestorRepresentation: AncestorRepresentation = .generated
217-
) where
218-
C.Iterator.Element == Child,
219-
// FIXME(ABI)#47 (Associated Types with where clauses): these constraints should be applied to
220-
// associated types of Collection.
221-
C.SubSequence : Collection,
222-
C.SubSequence.Indices : Collection,
223-
C.Indices : Collection {
217+
) where C.Iterator.Element == Child {
224218

225219
self.subjectType = Subject.self
226220
self._makeSuperclassMirror = Mirror._superclassIterator(
@@ -267,11 +261,7 @@ public struct Mirror {
267261
unlabeledChildren: C,
268262
displayStyle: DisplayStyle? = nil,
269263
ancestorRepresentation: AncestorRepresentation = .generated
270-
) where
271-
// FIXME(ABI)#48 (Associated Types with where clauses): these constraints should be applied to
272-
// associated types of Collection.
273-
C.SubSequence : Collection,
274-
C.Indices : Collection {
264+
) {
275265

276266
self.subjectType = Subject.self
277267
self._makeSuperclassMirror = Mirror._superclassIterator(

stdlib/public/core/MutableCollection.swift

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,9 @@ public protocol _MutableIndexable : _Indexable {
217217
/// // Must be equivalent to:
218218
/// a[i] = x
219219
/// let y = x
220-
public protocol MutableCollection : _MutableIndexable, Collection {
221-
// FIXME(ABI)#181: should be constrained to MutableCollection
222-
// (<rdar://problem/20715009> Implement recursive protocol
223-
// constraints)
224-
/// A collection that represents a contiguous subrange of the collection's
225-
/// elements.
226-
associatedtype SubSequence : Collection /*: MutableCollection*/
227-
= MutableSlice<Self>
220+
public protocol MutableCollection : _MutableIndexable, Collection
221+
where SubSequence: MutableCollection {
222+
associatedtype SubSequence = MutableSlice<Self>
228223

229224
/// Accesses the element at the specified position.
230225
///

stdlib/public/core/RandomAccessCollection.swift

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,15 @@ public protocol _RandomAccessIndexable : _BidirectionalIndexable {
4848
/// `distance(from:to:)` methods with O(1) efficiency.
4949
public protocol RandomAccessCollection :
5050
_RandomAccessIndexable, BidirectionalCollection
51+
where SubSequence: RandomAccessCollection, Indices: RandomAccessCollection
5152
{
5253
/// A collection that represents a contiguous subrange of the collection's
5354
/// elements.
54-
associatedtype SubSequence : _RandomAccessIndexable, BidirectionalCollection
55-
= RandomAccessSlice<Self>
56-
// FIXME(ABI)#102 (Recursive Protocol Constraints):
57-
// associatedtype SubSequence : RandomAccessCollection
55+
associatedtype SubSequence = RandomAccessSlice<Self>
5856

5957
/// A type that represents the indices that are valid for subscripting the
6058
/// collection, in ascending order.
61-
associatedtype Indices : _RandomAccessIndexable, BidirectionalCollection
62-
= DefaultRandomAccessIndices<Self>
63-
// FIXME(ABI)#103 (Recursive Protocol Constraints):
64-
// associatedtype Indices : RandomAccessCollection
59+
associatedtype Indices = DefaultRandomAccessIndices<Self>
6560

6661
/// The indices that are valid for subscripting the collection, in ascending
6762
/// order.

validation-test/stdlib/CollectionDiagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ struct CollectionWithBadSubSequence : Collection {
2323
fatalError("unreachable")
2424
}
2525

26-
// expected-note@+3 {{possibly intended match 'CollectionWithBadSubSequence.SubSequence' (aka 'OpaqueValue<Int8>') does not conform to 'Sequence'}}
26+
// expected-note@+3 {{possibly intended match}}
2727
// expected-note@+2 {{possibly intended match}}
2828
// expected-note@+1 {{possibly intended match}}
2929
typealias SubSequence = OpaqueValue<Int8>

0 commit comments

Comments
 (0)