AsyncStream.Iterator.next and TaskGroup.Iterator.next don't rethrow.
Instead, to get
async throws -> Element?
instead of
async -> Element?
, you need the throwing variants. (AsyncThrowingStream and ThrowingTaskGroup).
But the rest of the AsyncIteratorProtocol adopters in the standard library, while also having throwing and non-throwing variants, use this pair of signatures instead:
async rethrows -> Element?
async throws -> Element?
1. When does that rethrows get used?
2. Why the inconsistency?
I was looking at the "AnyAsyncSequence" thread, and thinking that, at this point, we're always working with "some AsyncNonThrowingSequence<Element>" or "some AsyncThrowingSequence<Element>":
public protocol AsyncNonThrowingSequence<Element>: AsyncSequence
where AsyncIterator: Swift.AsyncIterator { }
public protocol AsyncIterator<Element>: AsyncIteratorProtocol {
associatedtype Element
mutating func next() async -> Element?
}
public protocol AsyncThrowingSequence<Element>: AsyncSequence
where AsyncIterator: AsyncThrowingIterator { }
public protocol AsyncThrowingIterator<Element>: AsyncIteratorProtocol {
associatedtype Element
mutating func next() async throws -> Element?
}
…but while that idea works with Streams…
extension AsyncStream: AsyncNonThrowingSequence { }
extension AsyncStream.Iterator: AsyncIterator { }
extension AsyncThrowingStream: AsyncThrowingSequence { }
extension AsyncThrowingStream.Iterator: AsyncThrowingIterator { }
…it doesn't work with anything else, because rethrows doesn't propagate into the type system.