I've been playing with SE-0433 Mutex with non Sendable types.

The proposal API Design defines this signature

public borrowing func withLock<Result: ~Copyable, E: Error>(
   _ body: (transferring inout State) throws(E) -> transferring Result
) throws(E) -> transferring Result

But on Darwin platforms the body closure is marked @Sendable preventing non sendable values being transferred in to replace the protected state:

let state = Mutex(NonSendable())
let ns = NonSendable()
state.withLock { $0 = ns } // ❌ Capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` closure

On Linux the closure is not marked @Sendable but, but a different error:

:x: error: 'inout sending' parameter '$0' cannot be task-isolated at end of function

Is this a bug or a case of using it incorrectly?

1 Like