The Swift 6 compiler emits the following error
Sending value of non-Sendable type '() async throws -> ()' risks causing data races
when explicitly specifying an actor as the isolation for the closure in the addTask function of the task group:
func test() async throws {
try await withThrowingTaskGroup { group in
group.addTask { @MainActor in // <== Error
try await Task.sleep(nanoseconds: 1_000_000)
}
try await group.waitForAll()
}
}
I don't see why the closure should not be sendable. Why is the compiler considering the given closure as not sendable?
Info: the signature of addTask is
mutating func addTask(
priority: TaskPriority? = nil,
operation: sending @escaping @isolated(any) () async throws -> ChildTaskResult
)
What I'm trying to do is the following (where the compiler issues the same error):
@Sendable
func requiresIsolation(isolated: isolated any Actor = #isolation) async throws {}
(this function is sendable, so @Sendable is redundant and just for emphasising the fact)
and then:
func test() async throws {
try await withThrowingTaskGroup { group in
group.addTask { @SomeActor in
try await requiresIsolation()
}
try await group.waitForAll()
}
}
Update:
My suspicion is, that the closure needs an explicit @Sendable annotation.
The following code makes the compiler happy:
func test() async throws {
try await withThrowingTaskGroup { group in
group.addTask { @Sendable @MainActor in // <== add `@Sendable`
try await requiresIsolation()
}
try await group.waitForAll()
}
}
Still, I'm a bit unsure whether this is correct.