Sajjon
(Alexander Cyon)
1
When using compilation flag -warn-concurrency and -enable-actor-data-race-checks (possibly without? Not tried...)
actor ConnectorActor {
struct Config {}
private let config: Config
init(config: Config) {
self.config = config
}
func connect() async {
await withThrowingTaskGroup(of: Void.self) { group in
group.addTask {
/* ... */
}
}
}
}
Non-sendable type '(inout ThrowingTaskGroup<Void, any Error>) async throws -> ()' exiting actor-isolated context in call to non-isolated global function 'withThrowingTaskGroup(of:returning:body:)' cannot cross actor boundary
But if I wrap the withThrowingTaskGroup within a Task the warning goes away, like so:
func connect() async {
Task {
await withThrowingTaskGroup(of: Void.self) { group in
group.addTask {
/* ... */
}
}
}
}
What is the best practices here?
3 Likes
Joe_Groff
(Joe Groff)
2
This was recently fixed in top-of-tree:
You should be able to ignore the warning for now.
2 Likes
nh7a
3
With Xcode 14.1 Beta 2 (swiftlang-5.7.1.131.4 clang-1400.0.29.51), I see the same warning for reduce(into:) when I use it in MainActor as below.
Is this related and I should ignore it for now or this is legit?
Sajjon
(Alexander Cyon)
4
I have seen this warning to, and it felt a bit too overly strict
1 Like
nh7a
5
With the release of Xcode 15.3, this warning now occurs by default. I'm not sure how to fix this.
actor MyActor {
func foo() async throws -> [String] {
try await withThrowingTaskGroup(of: String.self) { group in
group.addTask { await self.bar() }
return try await group.reduce(into: [String]()) { (result, elem) in // Passing argument of non-sendable type 'ThrowingTaskGroup<String, any Error>' outside of actor-isolated context may introduce data races
result.append(elem)
}
}
}
func bar() async -> String { "" }
}
2 Likes
Jon_Shier
(Jon Shier)
6
Don't use reduce directly onto group. Accumulate the results, then reduce. Though you don't really seem to be reducing anything here anyway.
ktoso
(Konrad 'ktoso' Malawski 🐟🏴☠️)
7
We’re aware of the warning and will be fixing it with the new currently under review isolation controls.
2 Likes
bestwnh
(Galvin)
9
Any way we can track this issue status? Is there any related Github issue or pr link?
1 Like
I assume this counsel is just a temporary “this is how you can avoid this warning for now, until it is fixed”, and not intended as anything more than that. Is that correct?
1 Like
Jon_Shier
(Jon Shier)
11
Yes, it's just a workaround.
3 Likes
nh7a
12
Whether using reduce() or not, neither way build with Swift 6, as of Xcode 16 beta 2.
For reduce(), it's "Sending 'group' risks causing data races" and for for-in, it's "Sending '$value$generator' risks causing data races".
ktoso
(Konrad 'ktoso' Malawski 🐟🏴☠️)
13
The fix is a combination of very recent changes, I don't expect it to be in beta 2 but we expect this error to go away in subsequent releases.
I can't comment on exact release dates though, sorry about that.
5 Likes
vanvoorden
(Rick van Voorden)
14
actor MyActor {
func iterate<Sequence>(over sequence: Sequence) async rethrows where Sequence : AsyncSequence, Sequence.Element : Sendable {
// Sending '$ns$generator' risks causing data races
for try await ns in sequence {
print(ns)
}
}
}
I'm not sure this is a problem specifically with TaskGroup… I see a similar problem with an arbitrary AsyncSequence.
If I'm building from a new OS… I have this option from SE-0420:
actor MyActor {
func iterate<Sequence>(over sequence: Sequence) async rethrows where Sequence : AsyncSequence, Sequence.Element : Sendable {
var iterator = sequence.makeAsyncIterator()
while let ns = try await iterator.next(isolation: #isolation) {
print(ns)
}
}
}
This silences the error… but I still would like to support legacy OS versions (while building from the 6.0 toolchain).
@ktoso Would you know if we have any legit workarounds for that from Xcode_16_beta_2 that would also deploy back to the last OS releases (other than potentially not building from Swift 6 Strict Concurrency Checking)?
No longer errors for me from Xcode_16_beta_3.
nh7a
15
As of Xcode 16 beta 3, for in group no longer produces the warning, but group.reduce() still does.
nh7a
16
With Xcode 16 beta 5, group.reduce() still produces the same warning 
@MainActor struct S {
func f() async {
await withTaskGroup(of: Int.self) { group in
let arr = await group.reduce(into: [Int]()) { $0.append($1) } // ❌ Sending 'group' risks causing data races
}
}
}
ktoso
(Konrad 'ktoso' Malawski 🐟🏴☠️)
17
Heh, this made me realize that none of those APIs adopted #isolation and indeed will be getting such warnings... We'll have to re-evaluate more async sequence APIs and if they should take #isolation.
Thanks for the ping on it, I've added it a list of things to look into.
3 Likes