Skip to content

Commit da3cf4d

Browse files
committed
[Concurrency] Allow globally isolated closures to capture non-Sendable values.
1 parent ae8cf7b commit da3cf4d

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
@@ -4195,15 +4195,21 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
41954195
if (useIsolation == defIsolation)
41964196
return false;
41974197

4198+
auto &ctx = useContext->getASTContext();
4199+
bool regionIsolationEnabled =
4200+
ctx.LangOpts.hasFeature(Feature::RegionBasedIsolation);
4201+
4202+
// Globally-isolated closures may never be executed concurrently.
4203+
if (ctx.LangOpts.hasFeature(Feature::GlobalActorIsolatedTypesUsability) &&
4204+
regionIsolationEnabled && useIsolation.isGlobalActor())
4205+
return false;
4206+
41984207
// If the local function is not Sendable, its isolation differs
41994208
// from that of the context, and both contexts are actor isolated,
42004209
// then capturing non-Sendable values allows the closure to stash
42014210
// those values into actor isolated state. The original context
42024211
// may also stash those values into isolated state, enabling concurrent
42034212
// access later on.
4204-
auto &ctx = useContext->getASTContext();
4205-
bool regionIsolationEnabled =
4206-
ctx.LangOpts.hasFeature(Feature::RegionBasedIsolation);
42074213
isolatedStateMayEscape =
42084214
(!regionIsolationEnabled &&
42094215
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)