Skip to content

Commit 46cd1b7

Browse files
committed
stdlib: Make data structure protocols ready for future move-only types.
We would like to eventually extend Array, Dictionary, and Set to support move-only element types when the language does. To that end, we need to get the `consuming`-ness of protocol requirements on Sequence, Collection, and related protocols right for forward compatibility so that a future version of Swift that extends these types to support move-only data structures remains ABI- and API-compatible with older versions of the language. Mark requirements as `__consuming` where it would be necessary for a move-only implementation of one of these types.
1 parent 586eda9 commit 46cd1b7

File tree

4 files changed

+39
-29
lines changed

4 files changed

+39
-29
lines changed

stdlib/public/core/Collection.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ public protocol Collection: Sequence where SubSequence: Collection {
522522
/// - Returns: A subsequence up to, but not including, the `end` position.
523523
///
524524
/// - Complexity: O(1)
525-
func prefix(upTo end: Index) -> SubSequence
525+
__consuming func prefix(upTo end: Index) -> SubSequence
526526

527527
/// Returns a subsequence from the specified position to the end of the
528528
/// collection.
@@ -557,7 +557,7 @@ public protocol Collection: Sequence where SubSequence: Collection {
557557
/// - Returns: A subsequence starting at the `start` position.
558558
///
559559
/// - Complexity: O(1)
560-
func suffix(from start: Index) -> SubSequence
560+
__consuming func suffix(from start: Index) -> SubSequence
561561

562562
/// Returns a subsequence from the start of the collection through the
563563
/// specified position.
@@ -588,7 +588,7 @@ public protocol Collection: Sequence where SubSequence: Collection {
588588
/// - Returns: A subsequence up to, and including, the `end` position.
589589
///
590590
/// - Complexity: O(1)
591-
func prefix(through position: Index) -> SubSequence
591+
__consuming func prefix(through position: Index) -> SubSequence
592592

593593
/// A Boolean value indicating whether the collection is empty.
594594
///
@@ -643,6 +643,11 @@ public protocol Collection: Sequence where SubSequence: Collection {
643643
/// - Complexity: Hopefully less than O(`count`).
644644
func _customLastIndexOfEquatableElement(_ element: Element) -> Index??
645645

646+
// FIXME(move-only types): `first` might not be implementable by collections
647+
// with move-only elements, since they would need to be able to somehow form
648+
// a temporary `Optional<Element>` value from a non-optional Element without
649+
// modifying the collection.
650+
646651
/// The first element of the collection.
647652
///
648653
/// If the collection is empty, the value of this property is `nil`.
@@ -818,7 +823,7 @@ public protocol Collection: Sequence where SubSequence: Collection {
818823
/// a random element.
819824
/// - Returns: A random element from the collection. If the collection is
820825
/// empty, the method returns `nil`.
821-
func randomElement<T: RandomNumberGenerator>(
826+
__consuming func randomElement<T: RandomNumberGenerator>(
822827
using generator: inout T
823828
) -> Element?
824829

stdlib/public/core/RangeReplaceableCollection.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public protocol RangeReplaceableCollection : Collection
175175
///
176176
/// - Complexity: O(1) on average, over many additions to the same
177177
/// collection.
178-
mutating func append(_ newElement: Element)
178+
mutating func append(_ newElement: __owned Element)
179179

180180
/// Adds the elements of a sequence or collection to the end of this
181181
/// collection.
@@ -197,7 +197,7 @@ public protocol RangeReplaceableCollection : Collection
197197
/// collection.
198198
// FIXME(ABI)#166 (Evolution): Consider replacing .append(contentsOf) with +=
199199
// suggestion in SE-91
200-
mutating func append<S : Sequence>(contentsOf newElements: S)
200+
mutating func append<S : Sequence>(contentsOf newElements: __owned S)
201201
where S.Element == Element
202202

203203
/// Inserts a new element into the collection at the specified position.
@@ -222,7 +222,7 @@ public protocol RangeReplaceableCollection : Collection
222222
/// `index` must be a valid index into the collection.
223223
///
224224
/// - Complexity: O(*n*), where *n* is the length of the collection.
225-
mutating func insert(_ newElement: Element, at i: Index)
225+
mutating func insert(_ newElement: __owned Element, at i: Index)
226226

227227
/// Inserts the elements of a sequence into the collection at the specified
228228
/// position.
@@ -250,7 +250,7 @@ public protocol RangeReplaceableCollection : Collection
250250
/// and `newElements`. If `i` is equal to the collection's `endIndex`
251251
/// property, the complexity is O(*n*), where *n* is the length of
252252
/// `newElements`.
253-
mutating func insert<S : Collection>(contentsOf newElements: S, at i: Index)
253+
mutating func insert<S : Collection>(contentsOf newElements: __owned S, at i: Index)
254254
where S.Element == Element
255255

256256
/// Removes and returns the element at the specified position.

stdlib/public/core/Sequence.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ public protocol Sequence {
336336
SubSequence.SubSequence == SubSequence
337337

338338
/// Returns an iterator over the elements of this sequence.
339-
func makeIterator() -> Iterator
339+
__consuming func makeIterator() -> Iterator
340340

341341
/// A value less than or equal to the number of elements in the sequence,
342342
/// calculated nondestructively.
@@ -384,7 +384,7 @@ public protocol Sequence {
384384
/// sequence as its argument and returns a Boolean value indicating
385385
/// whether the element should be included in the returned array.
386386
/// - Returns: An array of the elements that `isIncluded` allowed.
387-
func filter(
387+
__consuming func filter(
388388
_ isIncluded: (Element) throws -> Bool
389389
) rethrows -> [Element]
390390

@@ -442,7 +442,7 @@ public protocol Sequence {
442442
///
443443
/// - Complexity: O(*n*), where *n* is the number of elements to drop from
444444
/// the beginning of the sequence.
445-
func dropFirst(_ n: Int) -> SubSequence
445+
__consuming func dropFirst(_ n: Int) -> SubSequence
446446

447447
/// Returns a subsequence containing all but the specified number of final
448448
/// elements.
@@ -462,7 +462,7 @@ public protocol Sequence {
462462
/// - Returns: A subsequence leaving off the specified number of elements.
463463
///
464464
/// - Complexity: O(*n*), where *n* is the length of the sequence.
465-
func dropLast(_ n: Int) -> SubSequence
465+
__consuming func dropLast(_ n: Int) -> SubSequence
466466

467467
/// Returns a subsequence by skipping elements while `predicate` returns
468468
/// `true` and returning the remaining elements.
@@ -472,7 +472,7 @@ public protocol Sequence {
472472
/// whether the element is a match.
473473
///
474474
/// - Complexity: O(*n*), where *n* is the length of the collection.
475-
func drop(
475+
__consuming func drop(
476476
while predicate: (Element) throws -> Bool
477477
) rethrows -> SubSequence
478478

@@ -492,7 +492,7 @@ public protocol Sequence {
492492
/// `maxLength` must be greater than or equal to zero.
493493
/// - Returns: A subsequence starting at the beginning of this sequence
494494
/// with at most `maxLength` elements.
495-
func prefix(_ maxLength: Int) -> SubSequence
495+
__consuming func prefix(_ maxLength: Int) -> SubSequence
496496

497497
/// Returns a subsequence containing the initial, consecutive elements that
498498
/// satisfy the given predicate.
@@ -516,7 +516,7 @@ public protocol Sequence {
516516
/// satisfy `predicate`.
517517
///
518518
/// - Complexity: O(*n*), where *n* is the length of the collection.
519-
func prefix(
519+
__consuming func prefix(
520520
while predicate: (Element) throws -> Bool
521521
) rethrows -> SubSequence
522522

@@ -539,7 +539,7 @@ public protocol Sequence {
539539
/// at most `maxLength` elements.
540540
///
541541
/// - Complexity: O(*n*), where *n* is the length of the sequence.
542-
func suffix(_ maxLength: Int) -> SubSequence
542+
__consuming func suffix(_ maxLength: Int) -> SubSequence
543543

544544
/// Returns the longest possible subsequences of the sequence, in order, that
545545
/// don't contain elements satisfying the given predicate.
@@ -590,7 +590,7 @@ public protocol Sequence {
590590
/// - isSeparator: A closure that returns `true` if its argument should be
591591
/// used to split the sequence; otherwise, `false`.
592592
/// - Returns: An array of subsequences, split from this sequence's elements.
593-
func split(
593+
__consuming func split(
594594
maxSplits: Int, omittingEmptySubsequences: Bool,
595595
whereSeparator isSeparator: (Element) throws -> Bool
596596
) rethrows -> [SubSequence]
@@ -607,11 +607,11 @@ public protocol Sequence {
607607

608608
/// Create a native array buffer containing the elements of `self`,
609609
/// in the same order.
610-
func _copyToContiguousArray() -> ContiguousArray<Element>
610+
__consuming func _copyToContiguousArray() -> ContiguousArray<Element>
611611

612612
/// Copy `self` into an unsafe buffer, returning a partially-consumed
613613
/// iterator with any elements that didn't fit remaining.
614-
func _copyContents(
614+
__consuming func _copyContents(
615615
initializing ptr: UnsafeMutableBufferPointer<Element>
616616
) -> (Iterator,UnsafeMutableBufferPointer<Element>.Index)
617617
}

stdlib/public/core/SetAlgebra.swift

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
115115
/// - Note: if this set and `other` contain elements that are equal but
116116
/// distinguishable (e.g. via `===`), which of these elements is present
117117
/// in the result is unspecified.
118-
func union(_ other: Self) -> Self
118+
__consuming func union(_ other: __owned Self) -> Self
119119

120120
/// Returns a new set with the elements that are common to both this set and
121121
/// the given set.
@@ -137,7 +137,7 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
137137
/// - Note: if this set and `other` contain elements that are equal but
138138
/// distinguishable (e.g. via `===`), which of these elements is present
139139
/// in the result is unspecified.
140-
func intersection(_ other: Self) -> Self
140+
__consuming func intersection(_ other: __owned Self) -> Self
141141

142142
/// Returns a new set with the elements that are either in this set or in the
143143
/// given set, but not in both.
@@ -155,7 +155,12 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
155155
///
156156
/// - Parameter other: A set of the same type as the current set.
157157
/// - Returns: A new set.
158-
func symmetricDifference(_ other: Self) -> Self
158+
__consuming func symmetricDifference(_ other: __owned Self) -> Self
159+
160+
// FIXME(move-only types): SetAlgebra.insert is not implementable by a
161+
// set with move-only Element type, since it would be necessary to copy
162+
// the argument in order to both store it inside the set and return it as
163+
// the `memberAfterInsert`.
159164

160165
/// Inserts the given element in the set if it is not already present.
161166
///
@@ -189,7 +194,7 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
189194
/// other means.
190195
@discardableResult
191196
mutating func insert(
192-
_ newMember: Element
197+
_ newMember: __owned Element
193198
) -> (inserted: Bool, memberAfterInsert: Element)
194199

195200
/// Removes the given element and any elements subsumed by the given element.
@@ -231,7 +236,7 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
231236
/// `OptionSet` types, this method returns any intersection between the
232237
/// set and `[newMember]`, or `nil` if the intersection is empty.
233238
@discardableResult
234-
mutating func update(with newMember: Element) -> Element?
239+
mutating func update(with newMember: __owned Element) -> Element?
235240

236241
/// Adds the elements of the given set to the set.
237242
///
@@ -253,7 +258,7 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
253258
/// // Prints "[2, 4, 6, 7, 0, 1, 3]"
254259
///
255260
/// - Parameter other: A set of the same type as the current set.
256-
mutating func formUnion(_ other: Self)
261+
mutating func formUnion(_ other: __owned Self)
257262

258263
/// Removes the elements of this set that aren't also in the given set.
259264
///
@@ -268,7 +273,7 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
268273
/// // Prints "["Bethany", "Eric"]"
269274
///
270275
/// - Parameter other: A set of the same type as the current set.
271-
mutating func formIntersection(_ other: Self)
276+
mutating func formIntersection(_ other: __owned Self)
272277

273278
/// Removes the elements of the set that are also in the given set and adds
274279
/// the members of the given set that are not already in the set.
@@ -286,7 +291,7 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
286291
/// // Prints "["Diana", "Forlani", "Alicia"]"
287292
///
288293
/// - Parameter other: A set of the same type.
289-
mutating func formSymmetricDifference(_ other: Self)
294+
mutating func formSymmetricDifference(_ other: __owned Self)
290295

291296
//===--- Requirements with default implementations ----------------------===//
292297
/// Returns a new set containing the elements of this set that do not occur
@@ -303,7 +308,7 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
303308
///
304309
/// - Parameter other: A set of the same type as the current set.
305310
/// - Returns: A new set.
306-
func subtracting(_ other: Self) -> Self
311+
__consuming func subtracting(_ other: Self) -> Self
307312

308313
/// Returns a Boolean value that indicates whether the set is a subset of
309314
/// another set.
@@ -365,7 +370,7 @@ public protocol SetAlgebra : Equatable, ExpressibleByArrayLiteral {
365370
/// // Prints "[6, 0, 1, 3]"
366371
///
367372
/// - Parameter sequence: The elements to use as members of the new set.
368-
init<S : Sequence>(_ sequence: S) where S.Element == Element
373+
init<S : Sequence>(_ sequence: __owned S) where S.Element == Element
369374

370375
/// Removes the elements of the given set from this set.
371376
///

0 commit comments

Comments
 (0)