So, is AsyncStream Sendable or not?

so, AsyncStream is not supposed to be Sendable, yet it compiles as if it were:

class C 
{
    var x:Int
    
    init()
    {
        self.x = 0
    }
}
actor A 
{
    init() 
    {
    }
    
    func foo(_ x:AsyncStream<Int>) async 
    {
        for await y:Int in x
        {
            print(y)
        }
    }
    func bar(_:C) 
    {
    }
}
@main 
enum Main 
{
    static
    func main() async 
    {
        let a:A = .init()
        let c:C = .init()
        let stream:AsyncStream<Int> = .init 
        {
            (continuation:AsyncStream<Int>.Continuation) in 
            
            ...
        }
        
        await a.foo(stream)
        await a.bar(c)
    }
}
$ swiftc -parse-as-library concurrency-boundaries.swift
concurrency-boundaries.swift:53:17: warning: cannot pass argument of non-sendable type 'C' across actors
        await a.bar(c)
                ^
concurrency-boundaries.swift:1:7: note: class 'C' does not conform to the 'Sendable' protocol
class C 

is this a bug, or intended behavior?

I know it has been a bit since this was posted: but after some rumination and experimentation - I pushed a fix to make this be Sendable; previously we restricted it because it had a weird behavior if you iterated the iterator on two tasks. However I was able to resolve that - Enable Sendability for AsyncStream and AsyncThrowingStream by phausler · Pull Request #41713 · apple/swift · GitHub

9 Likes

@Philippe_Hausler I'm just fighting Sendable checks in my application and I run into an error that states AsyncStream.Iterator is not Sendable. Why is there no conditional conformance to @unchecked Sendable on the Iterator type?

It seems like all other async stream types and their iterator types have a conditional conformance, but Async[Throwing]Stream.Iterator don't.

This is a huge pain point right now.

1 Like

Okay my bad. It took me just two hours to realize that my AsyncAlgorithms reference is set to version 0.0.3 but the sequences I use had their conformance to Sendable on their iterator types reverted, which should solve the complier errors for me.

Maybe it's time for version 0.0.4?

I have the list of things to make async-algorithms for 1.0; that is nearly complete but in the mean time I can tag a 0.4 for the time being (should be ready for 1.0 hopefully this week).

3 Likes

is the idea to align S-A-A with the 5.8 release date?

They are independent of each other.