Skip to content

Commit 131ab89

Browse files
authored
Merge pull request #76920 from gottesmm/pr-4ab85a74d0641a99b3a480971f93b2f98f726e31
[region-isolation] Add a special error for when a closure captures a non-Sendable box.
2 parents 81c6102 + ce7a0db commit 131ab89

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,9 @@ NOTE(regionbasedisolation_typed_tns_passed_to_sending_closure_helper_have_value,
10391039
NOTE(regionbasedisolation_typed_tns_passed_to_sending_closure_helper_have_value_task_isolated, none,
10401040
"closure captures %0 which is accessible to code in the current task",
10411041
(DeclName))
1042+
NOTE(regionbasedisolation_typed_tns_passed_to_sending_closure_helper_have_boxed_value_task_isolated, none,
1043+
"closure captures reference to mutable %1 %0 which is accessible to code in the current task",
1044+
(DeclName, DescriptiveDeclKind))
10421045
NOTE(regionbasedisolation_typed_tns_passed_to_sending_closure_helper_have_value_region, none,
10431046
"closure captures %1 which is accessible to %0 code",
10441047
(StringRef, DeclName))

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,19 @@ class TransferNonTransferrableDiagnosticEmitter {
14561456

14571457
auto capturedLoc = RegularLocation(capturedValue.getLoc());
14581458
if (getIsolationRegionInfo().getIsolationInfo().isTaskIsolated()) {
1459+
// If we have a closure capture box, emit a special diagnostic.
1460+
if (auto *fArg = dyn_cast<SILFunctionArgument>(
1461+
getIsolationRegionInfo().getIsolationInfo().getIsolatedValue())) {
1462+
if (fArg->isClosureCapture() && fArg->getType().is<SILBoxType>()) {
1463+
auto diag = diag::
1464+
regionbasedisolation_typed_tns_passed_to_sending_closure_helper_have_boxed_value_task_isolated;
1465+
auto *decl = capturedValue.getDecl();
1466+
diagnoseNote(capturedLoc, diag, decl->getName(),
1467+
decl->getDescriptiveKind());
1468+
return;
1469+
}
1470+
}
1471+
14591472
auto diag = diag::
14601473
regionbasedisolation_typed_tns_passed_to_sending_closure_helper_have_value_task_isolated;
14611474
diagnoseNote(capturedLoc, diag, capturedValue.getDecl()->getName());

test/Concurrency/transfernonsendable.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1866,3 +1866,25 @@ extension MyActor {
18661866
}
18671867
}
18681868

1869+
func nonSendableAllocBoxConsumingParameter(x: consuming SendableKlass) async throws {
1870+
try await withThrowingTaskGroup(of: Void.self) { group in
1871+
group.addTask { // expected-tns-warning {{passing closure as a 'sending' parameter risks causing data races between code in the current task and concurrent execution of the closure}}
1872+
useValue(x) // expected-tns-note {{closure captures reference to mutable parameter 'x' which is accessible to code in the current task}}
1873+
}
1874+
1875+
try await group.waitForAll()
1876+
}
1877+
}
1878+
1879+
func nonSendableAllocBoxConsumingVar() async throws {
1880+
var x = SendableKlass()
1881+
x = SendableKlass()
1882+
1883+
try await withThrowingTaskGroup(of: Void.self) { group in
1884+
group.addTask { // expected-tns-warning {{passing closure as a 'sending' parameter risks causing data races between code in the current task and concurrent execution of the closure}}
1885+
useValue(x) // expected-tns-note {{closure captures reference to mutable var 'x' which is accessible to code in the current task}}
1886+
}
1887+
1888+
try await group.waitForAll()
1889+
}
1890+
}

0 commit comments

Comments
 (0)