Skip to content

Commit e8a0829

Browse files
committed
Implement new Sequence associatedtype/requirement
This includes a default associated type for the BorrowingIterator and a `NeverIterator` for types with noncopyable elements.
1 parent d92c5ce commit e8a0829

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

stdlib/public/core/Optional.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,3 +1016,22 @@ extension Optional: _ObjectiveCBridgeable {
10161016
}
10171017
}
10181018
#endif
1019+
1020+
extension Optional where Wrapped: ~Copyable {
1021+
@available(SwiftStdlib 6.3, *)
1022+
@_alwaysEmitIntoClient
1023+
public var _span: Span<Wrapped> {
1024+
@_addressableSelf
1025+
@lifetime(borrow self)
1026+
get {
1027+
guard self != nil else {
1028+
return Span()
1029+
}
1030+
1031+
let ptr = Builtin.unprotectedAddressOfBorrow(self)
1032+
return unsafe _overrideLifetime(
1033+
Span(_unsafeStart: UnsafePointer(ptr), count: 1),
1034+
borrowing: self)
1035+
}
1036+
}
1037+
}

stdlib/public/core/Sequence.swift

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,14 +322,18 @@ public protocol IteratorProtocol<Element> {
322322
/// makes no other requirements about element access, so routines that
323323
/// traverse a sequence should be considered O(*n*) unless documented
324324
/// otherwise.
325-
public protocol Sequence<Element> {
325+
public protocol Sequence<Element> /* : ~Copyable, ~Escapable */ {
326326
/// A type representing the sequence's elements.
327327
associatedtype Element
328328

329329
/// A type that provides the sequence's iteration interface and
330330
/// encapsulates its iteration state.
331-
associatedtype Iterator: IteratorProtocol where Iterator.Element == Element
331+
associatedtype Iterator: IteratorProtocol<Element>
332332

333+
@available(SwiftStdlib 6.3, *)
334+
associatedtype BorrowingIterator: BorrowingIteratorProtocol & ~Copyable & ~Escapable /* where BorrowingIterator.Element == Element */
335+
= BorrowingIteratorAdapter<Self>
336+
333337
// FIXME: <rdar://problem/34142121>
334338
// This typealias should be removed as it predates the source compatibility
335339
// guarantees of Swift 3, but it cannot due to a bug.
@@ -345,6 +349,10 @@ public protocol Sequence<Element> {
345349
/// Returns an iterator over the elements of this sequence.
346350
__consuming func makeIterator() -> Iterator
347351

352+
@available(SwiftStdlib 6.3, *)
353+
@lifetime(borrow self)
354+
func makeBorrowingIterator() -> BorrowingIterator
355+
348356
/// A value less than or equal to the number of elements in the sequence,
349357
/// calculated nondestructively.
350358
///
@@ -451,6 +459,38 @@ public protocol Sequence<Element> {
451459
) rethrows -> R?
452460
}
453461

462+
@available(SwiftStdlib 6.3, *)
463+
public struct BorrowingIteratorAdapter<S: Sequence>: /* & ~Copyable & ~Escapable */
464+
BorrowingIteratorProtocol where S.Element: Copyable
465+
{
466+
var iterator: S.Iterator
467+
var curValue: S.Element?
468+
469+
@lifetime(&self)
470+
public mutating func nextSpan(maximumCount: Int) -> Span<S.Element> {
471+
curValue = iterator.next()
472+
return curValue._span
473+
}
474+
}
475+
476+
@available(SwiftStdlib 6.3, *)
477+
public enum NeverIterator<Element: ~Copyable> {}
478+
479+
@available(SwiftStdlib 6.3, *)
480+
extension NeverIterator: IteratorProtocol { /* where Element: ~Copyable */
481+
public typealias Element = Element
482+
public func next() -> Element? {
483+
fatalError()
484+
}
485+
}
486+
487+
@available(SwiftStdlib 6.3, *)
488+
extension Sequence where BorrowingIterator == BorrowingIteratorAdapter<Self> {
489+
public func makeBorrowingIterator() -> BorrowingIterator {
490+
BorrowingIteratorAdapter(iterator: makeIterator())
491+
}
492+
}
493+
454494
// Provides a default associated type witness for Iterator when the
455495
// Self type is both a Sequence and an Iterator.
456496
extension Sequence where Self: IteratorProtocol {

0 commit comments

Comments
 (0)