When I compile the following code with this command:
swiftc -parse-as-library -default-isolation nonisolated -warn-concurrency -strict-concurrency=complete 1.swift
Code
// 1.swift
import Synchronization
@main
enum Driver {
static func main () async throws {
// Number of tasks to spawn
let N = Int (CommandLine.arguments [1])!
// Work load bounds
let L = 1_000
let U = 1_000_000
print (#function, "starting \(N) tasks...")
let mutex = Mutex <Int> (0)
for i in 0..<N {
Task {@concurrent in
let M = Int.random (in: L...U)
print (i, "starting - load = \(M)...")
try await work (load: M)
print (i, "finished");
mutex.withLock {
$0 += 1
}
}
}
let u = await ContinuousClock ().measure {
while true {
let v = mutex.withLock {
print ("-->", $0, N)
return $0 == N
}
if v {
break
}
await hibernate (seconds: 5)
}
}
print (#function, "finished", u)
}
}
func work (load M: Int) async throws {
var u = 0
for i in 1...M {
u += I
await hibernate (seconds: 0.000001)
}
assert (u == (M * (M + 1)) / 2)
}
nonisolated
func hibernate (seconds t: Double) async {
try! await Task.sleep (until: .now + .seconds (t))
}
I get this warning:
1.swift:18:10: warning: sending value of non-Sendable type '() async throws -> ()' risks causing data races; this is an error in the Swift 6 language mode [#SendingRisksDataRace]
16 |
17 | for i in 0..<N {
18 | Task {@concurrent in
| |- warning: sending value of non-Sendable type '() async throws -> ()' risks causing data races; this is an error in the Swift 6 language mode [#SendingRisksDataRace]
| |- note: Passing value of non-Sendable type '() async throws -> ()' as a 'sending' argument to initializer 'init(name:priority:operation:)' risks causing races in between local and caller code
| `- note: access can happen concurrently
19 | let M = Int.random (in: L...U)
20 | print (i, "starting - load = \(M)...")
[#SendingRisksDataRace]: <https://docs.swift.org/compiler/documentation/diagnostics/sending-risks-data-race>
I don't understand the reason behind this warning because there is no mutable state crossing concurrency-domain boundaries.
If I remove the @concurrent attribute from the closure or replace the attribute with @MainActor the warning is not emitted.
What is the reason for the warning?