ARTICLE AD BOX
I happened to need to consume only one element of an async sequence, so rather than a `for await` loop, I thought I'd call makeAsyncIterator and then call next to make it very clear that I'm not looping at all.
@MainActor // this method needs to be main actor isolated func f(seq: some AsyncSequence<Int, any Error>) async throws { var iter = seq.makeAsyncIterator() print(try await iter.next()) }This produces an error,
Sending 'iter' risks causing data races
I understand what it is saying - next is a nonisolated function, so I am effectively sending the main actor isolated iter to not-the-main-actor. Since the async iterator is not sendable, this is an error.
But if I use a for await loop, the code compiles!
@MainActor func f(seq: some AsyncSequence<Int, any Error>) async throws { for try await x in seq { print(x) break } }The for await loop should just be syntactic sugar for a while loop that calls iter.next() repeatedly, so what does for await do differently?
Side note, I also tried
print(try await seq.first(where: { _ in true }))which also doesn't compile - first(where:) is nonisolated, so I am sending the non-sendable seq.
