Skip to content

Commit 41a8029

Browse files
committed
[Concurrency] Allow globally isolated closures to capture non-Sendable values.
1 parent 0abcf8d commit 41a8029

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4181,15 +4181,21 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
41814181
if (useIsolation == defIsolation)
41824182
return false;
41834183

4184+
auto &ctx = useContext->getASTContext();
4185+
bool regionIsolationEnabled =
4186+
ctx.LangOpts.hasFeature(Feature::RegionBasedIsolation);
4187+
4188+
// Globally-isolated closures may never be executed concurrently.
4189+
if (ctx.LangOpts.hasFeature(Feature::GlobalActorIsolatedTypesUsability) &&
4190+
regionIsolationEnabled && useIsolation.isGlobalActor())
4191+
return false;
4192+
41844193
// If the local function is not Sendable, its isolation differs
41854194
// from that of the context, and both contexts are actor isolated,
41864195
// then capturing non-Sendable values allows the closure to stash
41874196
// those values into actor isolated state. The original context
41884197
// may also stash those values into isolated state, enabling concurrent
41894198
// access later on.
4190-
auto &ctx = useContext->getASTContext();
4191-
bool regionIsolationEnabled =
4192-
ctx.LangOpts.hasFeature(Feature::RegionBasedIsolation);
41934199
isolatedStateMayEscape =
41944200
(!regionIsolationEnabled &&
41954201
useIsolation.isActorIsolated() && defIsolation.isActorIsolated());

test/Concurrency/global_actor_sendable_fn_type_inference.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,12 @@ func inferSendableFunctionType() {
1010
await closure() // okay
1111
}
1212
}
13+
14+
class NonSendable {}
15+
16+
func allowNonSendableCaptures() {
17+
let nonSendable = NonSendable()
18+
let _: @MainActor () -> Void = {
19+
let _ = nonSendable // okay
20+
}
21+
}

0 commit comments

Comments
 (0)