Skip to content

Commit 5e58aa6

Browse files
committed
[region-isolation] When emitting an error for an isolated closure use of a never transferrable value, use the dynamic isolation. Do not assume it is task isolated.
rdar://125372336
1 parent 3450cf6 commit 5e58aa6

File tree

3 files changed

+38
-8
lines changed

3 files changed

+38
-8
lines changed

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1023,8 +1023,13 @@ class TransferNonTransferrableDiagnosticEmitter {
10231023

10241024
void emitFunctionArgumentClosure(SourceLoc loc, Type type,
10251025
ApplyIsolationCrossing crossing) {
1026+
SmallString<64> descriptiveKindStr;
1027+
{
1028+
llvm::raw_svector_ostream os(descriptiveKindStr);
1029+
getIsolationRegionInfo().printForDiagnostics(os);
1030+
}
10261031
diagnoseError(loc, diag::regionbasedisolation_arg_transferred,
1027-
"task-isolated", type, crossing.getCalleeIsolation())
1032+
descriptiveKindStr, type, crossing.getCalleeIsolation())
10281033
.highlight(getOperand()->getUser()->getLoc().getSourceRange());
10291034
}
10301035

test/Concurrency/transfernonsendable_global_actor.swift

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// MARK: Declarations //
99
////////////////////////
1010

11-
class NonSendableKlass {}
11+
class NonSendableKlass {} // expected-complete-note {{}}
1212
final class SendableKlass : Sendable {}
1313

1414
actor CustomActorInstance {}
@@ -24,6 +24,8 @@ func transferToNonIsolated<T>(_ t: T) async {}
2424
func useValue<T>(_ t: T) {}
2525

2626
var booleanFlag: Bool { false }
27+
@MainActor var mainActorIsolatedGlobal = NonSendableKlass()
28+
@CustomActor var customActorIsolatedGlobal = NonSendableKlass()
2729

2830
/////////////////
2931
// MARK: Tests //
@@ -170,3 +172,25 @@ struct Clock {
170172
try! await c.sleep()
171173
}
172174
}
175+
176+
@CustomActor func testGlobalAndGlobalIsolatedPartialApplyMismatch() {
177+
let ns = customActorIsolatedGlobal
178+
179+
let _ = { @MainActor in
180+
print(ns) // expected-tns-warning {{global actor 'CustomActor'-isolated value of type 'NonSendableKlass' transferred to main actor-isolated context}}
181+
// expected-complete-warning @-1 {{capture of 'ns' with non-sendable type 'NonSendableKlass' in an isolated closure}}
182+
}
183+
184+
useValue(ns)
185+
}
186+
187+
@MainActor func testGlobalAndGlobalIsolatedPartialApplyMatch() {
188+
let ns = mainActorIsolatedGlobal
189+
190+
// TODO: We should not consider this to be a transfer.
191+
let _ = { @MainActor in
192+
print(ns) // expected-tns-warning {{main actor-isolated value of type 'NonSendableKlass' transferred to main actor-isolated context}}
193+
}
194+
195+
useValue(ns)
196+
}

test/Concurrency/transfernonsendable_isolationcrossing_partialapply.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,19 @@ func doSomething(_ x: NonSendableKlass, _ y: NonSendableKlass) { }
3636
actor ProtectsNonSendable {
3737
var ns: NonSendableKlass = .init()
3838

39-
nonisolated func testParameter(_ ns: NonSendableKlass) async {
39+
nonisolated func testParameter(_ nsArg: NonSendableKlass) async {
40+
// TODO: This is wrong, we should get an error saying that nsArg is task
41+
// isolated since this is nonisolated.
4042
self.assumeIsolated { isolatedSelf in
41-
isolatedSelf.ns = ns // expected-warning {{task-isolated value of type 'NonSendableKlass' transferred to actor-isolated context; later accesses to value could race}}
43+
isolatedSelf.ns = nsArg // expected-warning {{actor-isolated value of type 'NonSendableKlass' transferred to actor-isolated context; later accesses to value could race}}
4244
}
4345
}
4446

45-
// This should get the note since l is different from 'ns'.
46-
nonisolated func testParameterMergedIntoLocal(_ ns: NonSendableKlass) async {
47+
nonisolated func testParameterMergedIntoLocal(_ nsArg: NonSendableKlass) async {
4748
let l = NonSendableKlass()
48-
doSomething(l, ns)
49+
doSomething(l, nsArg)
4950
self.assumeIsolated { isolatedSelf in
50-
isolatedSelf.ns = l // expected-warning {{task-isolated value of type 'NonSendableKlass' transferred to actor-isolated context; later accesses to value could race}}
51+
isolatedSelf.ns = l // expected-warning {{actor-isolated value of type 'NonSendableKlass' transferred to actor-isolated context; later accesses to value could race}}
5152
}
5253
}
5354

0 commit comments

Comments
 (0)