Skip to content

Commit e06ee1a

Browse files
authored
Merge pull request #86112 from xedin/rdar-163792371-6.2
[6.2][Concurrency] Allow transferring `nonisolated(nonsending)` to isolati…
2 parents bf60dbc + e25cacf commit e06ee1a

File tree

3 files changed

+40
-11
lines changed

3 files changed

+40
-11
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5025,6 +5025,10 @@ ActorIsolation ActorIsolationChecker::determineClosureIsolation(
50255025
auto normalIsolation = computeClosureIsolationFromParent(
50265026
closure, parentIsolation, checkIsolatedCapture);
50275027

5028+
bool isIsolationBoundary =
5029+
isIsolationInferenceBoundaryClosure(closure,
5030+
/*canInheritActorContext=*/true);
5031+
50285032
// The solver has to be conservative and produce a conversion to
50295033
// `nonisolated(nonsending)` because at solution application time
50305034
// we don't yet know whether there are any captures which would
@@ -5035,7 +5039,7 @@ ActorIsolation ActorIsolationChecker::determineClosureIsolation(
50355039
// isolated parameters. If our closure is nonisolated and we have a
50365040
// conversion to nonisolated(nonsending), then we should respect that.
50375041
if (auto *explicitClosure = dyn_cast<ClosureExpr>(closure);
5038-
!normalIsolation.isGlobalActor()) {
5042+
isIsolationBoundary || !normalIsolation.isGlobalActor()) {
50395043
if (auto *fce =
50405044
dyn_cast_or_null<FunctionConversionExpr>(Parent.getAsExpr())) {
50415045
auto expectedIsolation =
@@ -5054,8 +5058,7 @@ ActorIsolation ActorIsolationChecker::determineClosureIsolation(
50545058
// NOTE: Since we already checked for global actor isolated things, we
50555059
// know that all Sendable closures must be nonisolated. That is why it is
50565060
// safe to rely on this path to handle Sendable closures.
5057-
if (isIsolationInferenceBoundaryClosure(closure,
5058-
/*canInheritActorContext=*/true))
5061+
if (isIsolationBoundary)
50595062
return ActorIsolation::forNonisolated(/*unsafe=*/false);
50605063

50615064
return normalIsolation;

test/Concurrency/attr_execution/conversions_silgen.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,3 +659,29 @@ func testSendableToSendableConversionWithNonisilatedNonsending() {
659659
nonisolated(nonsending) @escaping (String) async throws -> String
660660
) async throws -> Void = test
661661
}
662+
663+
func testNonisolatedNonsendingClosureInGlobalActorContext() {
664+
class NonSendable {
665+
var state = ""
666+
}
667+
668+
struct S {
669+
static func compute(closure: nonisolated(nonsending) @Sendable @escaping (sending NonSendable) async -> Void) async {}
670+
}
671+
672+
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen52testNonisolatedNonsendingClosureInGlobalActorContextyyF0D0L_yyYaF : $@convention(thin) @async () -> ()
673+
// CHECK: [[CLOSURE:%.*]] = function_ref @$s21attr_execution_silgen52testNonisolatedNonsendingClosureInGlobalActorContextyyF0D0L_yyYaFyAaByyF11NonSendableL_CYuYaYbYCcfU_ : $@convention(thin) @Sendable @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @guaranteed NonSendable) -> ()
674+
// CHECK: [[THICK_CLOSURE:%.*]] = thin_to_thick_function [[CLOSURE]] to $@Sendable @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @guaranteed NonSendable) -> ()
675+
// CHECK: [[CLOSURE_THUNK:%.*]] = function_ref @$sBA21attr_execution_silgen52testNonisolatedNonsendingClosureInGlobalActorContextyyF11NonSendableL_CIeghHgILgT_BAADIeghHgILxT_TR : $@convention(thin) @Sendable @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @owned NonSendable, @guaranteed @Sendable @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @guaranteed NonSendable) -> ()) -> ()
676+
// CHECK: [[THUNKED_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE_THUNK]]([[THICK_CLOSURE]])
677+
// CHECK: [[COMPUTE:%.*]] = function_ref @$s21attr_execution_silgen52testNonisolatedNonsendingClosureInGlobalActorContextyyF1SL_V7compute7closureyyAaByyF11NonSendableL_CnYuYaYbYCc_tYaFZ : $@convention(method) @async (@guaranteed @Sendable @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @owned NonSendable) -> (), @thin S.Type) -> ()
678+
// CHECK: apply [[COMPUTE]]([[THUNKED_CLOSURE]], {{.*}}) : $@convention(method) @async (@guaranteed @Sendable @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @owned NonSendable) -> (), @thin S.Type) -> ()
679+
// CHECK: } // end sil function '$s21attr_execution_silgen52testNonisolatedNonsendingClosureInGlobalActorContextyyF0D0L_yyYaF'
680+
@MainActor
681+
func test() async {
682+
// CHECK: // closure #1 in test #1 () in testNonisolatedNonsendingClosureInGlobalActorContext()
683+
// CHECK: // Isolation: caller_isolation_inheriting
684+
await S.compute { _ in
685+
}
686+
}
687+
}

test/Concurrency/transfernonsendable_closureliterals_isolationinference.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,11 @@ func test_CallerSyncNormal_CalleeAsyncNonIsolated() async {
143143
normalAcceptsAsyncClosure { }
144144

145145
// CHECK-LABEL: closure #2 in test_CallerSyncNormal_CalleeAsyncNonIsolated()
146-
// CHECK-NEXT: Isolation: nonisolated
146+
// CHECK-NEXT: Isolation: {{nonisolated|caller_isolation_inheriting}}
147147
normalAcceptsSendingAsyncClosure { }
148148

149149
// CHECK-LABEL: // closure #3 in test_CallerSyncNormal_CalleeAsyncNonIsolated()
150-
// CHECK-NEXT: // Isolation: nonisolated
150+
// CHECK-NEXT: // Isolation: {{nonisolated|caller_isolation_inheriting}}
151151
normalAcceptsSendableAsyncClosure { }
152152
}
153153

@@ -174,11 +174,11 @@ func test_CallerSyncNormal_CalleeAsyncMainActorIsolated() async {
174174
// expected-note @-1 {{sending global actor 'CustomActor'-isolated value of non-Sendable type '() async -> ()' to main actor-isolated global function 'normalGlobalActorAcceptsAsyncClosure' risks causing races in between global actor 'CustomActor'-isolated and main actor-isolated uses}}
175175

176176
// CHECK-LABEL: // closure #2 in test_CallerSyncNormal_CalleeAsyncMainActorIsolated()
177-
// CHECK-NEXT: // Isolation: nonisolated
177+
// CHECK-NEXT: Isolation: {{nonisolated|caller_isolation_inheriting}}
178178
await normalGlobalActorAcceptsSendingAsyncClosure { }
179179

180180
// CHECK-LABEL: // closure #3 in test_CallerSyncNormal_CalleeAsyncMainActorIsolated()
181-
// CHECK-NEXT: // Isolation: nonisolated
181+
// CHECK-NEXT: // Isolation: {{nonisolated|caller_isolation_inheriting}}
182182
await normalGlobalActorAcceptsSendableAsyncClosure { }
183183
}
184184

@@ -251,11 +251,11 @@ func test_CallerAsyncNormal_CalleeAsyncNonIsolated() async {
251251
// expected-ni-note @-1 {{sending global actor 'CustomActor'-isolated value of non-Sendable type '() async -> ()' to nonisolated global function 'asyncNormalAcceptsAsyncClosure' risks causing races in between global actor 'CustomActor'-isolated and nonisolated uses}}
252252

253253
// CHECK-LABEL: closure #2 in test_CallerAsyncNormal_CalleeAsyncNonIsolated()
254-
// CHECK-NEXT: Isolation: nonisolated
254+
// CHECK-NEXT: Isolation: {{nonisolated|caller_isolation_inheriting}}
255255
await asyncNormalAcceptsSendingAsyncClosure { }
256256

257257
// CHECK-LABEL: // closure #3 in test_CallerAsyncNormal_CalleeAsyncNonIsolated()
258-
// CHECK-NEXT: // Isolation: nonisolated
258+
// CHECK-NEXT: // Isolation: {{nonisolated|caller_isolation_inheriting}}
259259
await asyncNormalAcceptsSendableAsyncClosure { }
260260
}
261261

@@ -290,11 +290,11 @@ func test_CallerAsyncNormal_CalleeAsyncMainActorIsolated() async {
290290
// expected-note @-1 {{sending global actor 'CustomActor'-isolated value of non-Sendable type '() async -> ()' to main actor-isolated global function 'asyncNormalGlobalActorAcceptsAsyncClosure' risks causing races in between global actor 'CustomActor'-isolated and main actor-isolated uses}}
291291

292292
// CHECK-LABEL: // closure #2 in test_CallerAsyncNormal_CalleeAsyncMainActorIsolated()
293-
// CHECK-NEXT: // Isolation: nonisolated
293+
// CHECK-NEXT: Isolation: {{nonisolated|caller_isolation_inheriting}}
294294
await asyncNormalGlobalActorAcceptsSendingAsyncClosure { }
295295

296296
// CHECK-LABEL: // closure #3 in test_CallerAsyncNormal_CalleeAsyncMainActorIsolated()
297-
// CHECK-NEXT: // Isolation: nonisolated
297+
// CHECK-NEXT: // Isolation: {{nonisolated|caller_isolation_inheriting}}
298298
await asyncNormalGlobalActorAcceptsSendableAsyncClosure { }
299299
}
300300

0 commit comments

Comments
 (0)