Skip to content

Commit d0d2f2d

Browse files
committed
[region-isolation] Change the transfer non-transferrable value due to capture by an isolated closure diagnostic to be a named diagnostic.
rdar://125372790
1 parent 5e58aa6 commit d0d2f2d

File tree

6 files changed

+30
-19
lines changed

6 files changed

+30
-19
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,7 @@ NOTE(regionbasedisolation_named_stronglytransferred_binding, none,
987987
"%0 used after being passed as a transferring parameter; Later uses could race",
988988
(Identifier))
989989
NOTE(regionbasedisolation_named_isolated_closure_yields_race, none,
990-
"%0 %1 is captured by %2 closure. %2 uses in closure may race against later %3 uses",
990+
"%0 %1 is captured by a %2 closure. %2 uses in closure may race against later %3 uses",
991991
(StringRef, Identifier, ActorIsolation, ActorIsolation))
992992

993993
// Misc Error.

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,16 +1021,19 @@ class TransferNonTransferrableDiagnosticEmitter {
10211021
.highlight(getOperand()->getUser()->getLoc().getSourceRange());
10221022
}
10231023

1024-
void emitFunctionArgumentClosure(SourceLoc loc, Type type,
1025-
ApplyIsolationCrossing crossing) {
1024+
void emitNamedFunctionArgumentClosure(SILLocation loc, Identifier name,
1025+
ApplyIsolationCrossing crossing) {
1026+
emitNamedOnlyError(loc, name);
10261027
SmallString<64> descriptiveKindStr;
10271028
{
10281029
llvm::raw_svector_ostream os(descriptiveKindStr);
10291030
getIsolationRegionInfo().printForDiagnostics(os);
10301031
}
1031-
diagnoseError(loc, diag::regionbasedisolation_arg_transferred,
1032-
descriptiveKindStr, type, crossing.getCalleeIsolation())
1033-
.highlight(getOperand()->getUser()->getLoc().getSourceRange());
1032+
diagnoseNote(loc,
1033+
diag::regionbasedisolation_named_isolated_closure_yields_race,
1034+
descriptiveKindStr, name, crossing.getCalleeIsolation(),
1035+
crossing.getCallerIsolation())
1036+
.highlight(loc.getSourceRange());
10341037
}
10351038

10361039
void emitFunctionArgumentApplyStronglyTransferred(SILLocation loc,
@@ -1165,9 +1168,9 @@ bool TransferNonTransferrableDiagnosticInferrer::initForIsolatedPartialApply(
11651168
unsigned opIndex = ApplySite(op->getUser()).getAppliedArgIndex(*op);
11661169
for (auto &p : foundCapturedIsolationCrossing) {
11671170
if (std::get<1>(p) == opIndex) {
1168-
Type type = std::get<0>(p).getDecl()->getInterfaceType();
1169-
diagnosticEmitter.emitFunctionArgumentClosure(std::get<0>(p).getLoc(),
1170-
type, std::get<2>(p));
1171+
auto loc = RegularLocation(std::get<0>(p).getLoc());
1172+
diagnosticEmitter.emitNamedFunctionArgumentClosure(
1173+
loc, std::get<0>(p).getDecl()->getBaseIdentifier(), std::get<2>(p));
11711174
return true;
11721175
}
11731176
}

test/Concurrency/transfernonsendable.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1502,6 +1502,7 @@ final actor FinalActorWithSetter {
15021502

15031503
func functionArgumentIntoClosure(_ x: @escaping () -> ()) async {
15041504
let _ = { @MainActor in
1505-
let _ = x // expected-tns-warning {{task-isolated value of type '() -> ()' transferred to main actor-isolated context}}
1505+
let _ = x // expected-tns-warning {{transferring 'x' may cause a race}}
1506+
// expected-tns-note @-1 {{task-isolated 'x' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
15061507
}
15071508
}

test/Concurrency/transfernonsendable_global_actor.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,11 @@ struct Clock {
177177
let ns = customActorIsolatedGlobal
178178

179179
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}}
180+
// TODO: The type checker seems to think that the isolation here is
181+
// nonisolated instead of custom actor isolated.
182+
print(ns) // expected-tns-warning {{transferring 'ns' may cause a race}}
183+
// expected-tns-note @-1 {{global actor 'CustomActor'-isolated 'ns' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
184+
// expected-complete-warning @-2 {{capture of 'ns' with non-sendable type 'NonSendableKlass' in an isolated closure}}
182185
}
183186

184187
useValue(ns)
@@ -189,7 +192,8 @@ struct Clock {
189192

190193
// TODO: We should not consider this to be a transfer.
191194
let _ = { @MainActor in
192-
print(ns) // expected-tns-warning {{main actor-isolated value of type 'NonSendableKlass' transferred to main actor-isolated context}}
195+
print(ns) // expected-tns-warning {{transferring 'ns' may cause a race}}
196+
// expected-tns-note @-1 {{main actor-isolated 'ns' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
193197
}
194198

195199
useValue(ns)

test/Concurrency/transfernonsendable_isolationcrossing_partialapply.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,17 @@ actor ProtectsNonSendable {
4040
// TODO: This is wrong, we should get an error saying that nsArg is task
4141
// isolated since this is nonisolated.
4242
self.assumeIsolated { isolatedSelf in
43-
isolatedSelf.ns = nsArg // expected-warning {{actor-isolated value of type 'NonSendableKlass' transferred to actor-isolated context; later accesses to value could race}}
43+
isolatedSelf.ns = nsArg // expected-warning {{transferring 'nsArg' may cause a race}}
44+
// expected-note @-1 {{actor-isolated 'nsArg' is captured by a actor-isolated closure. actor-isolated uses in closure may race against later nonisolated uses}}
4445
}
4546
}
4647

4748
nonisolated func testParameterMergedIntoLocal(_ nsArg: NonSendableKlass) async {
4849
let l = NonSendableKlass()
4950
doSomething(l, nsArg)
5051
self.assumeIsolated { isolatedSelf in
51-
isolatedSelf.ns = l // expected-warning {{actor-isolated value of type 'NonSendableKlass' transferred to actor-isolated context; later accesses to value could race}}
52+
isolatedSelf.ns = l // expected-warning {{transferring 'l' may cause a race}}
53+
// expected-note @-1 {{actor-isolated 'l' is captured by a actor-isolated closure. actor-isolated uses in closure may race against later nonisolated uses}}
5254
}
5355
}
5456

@@ -67,7 +69,7 @@ actor ProtectsNonSendable {
6769
// This is not safe since we use l later.
6870
self.assumeIsolated { isolatedSelf in
6971
isolatedSelf.ns = l // expected-warning {{transferring 'l' may cause a race}}
70-
// expected-note @-1 {{disconnected 'l' is captured by actor-isolated closure. actor-isolated uses in closure may race against later nonisolated uses}}
72+
// expected-note @-1 {{disconnected 'l' is captured by a actor-isolated closure. actor-isolated uses in closure may race against later nonisolated uses}}
7173
}
7274

7375
useValue(l) // expected-note {{use here could race}}
@@ -85,7 +87,7 @@ func normalFunc_testLocal_2() {
8587
let x = NonSendableKlass()
8688
let _ = { @MainActor in
8789
useValue(x) // expected-warning {{transferring 'x' may cause a race}}
88-
// expected-note @-1 {{disconnected 'x' is captured by main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
90+
// expected-note @-1 {{disconnected 'x' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
8991
}
9092
useValue(x) // expected-note {{use here could race}}
9193
}

test/Concurrency/transfernonsendable_warning_until_swift6.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,15 @@ func testIsolationCrossingDueToCapture() async {
5050
let x = NonSendableType()
5151
let _ = { @MainActor in
5252
print(x) // expected-error {{transferring 'x' may cause a race}}
53-
// expected-note @-1 {{disconnected 'x' is captured by main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
53+
// expected-note @-1 {{disconnected 'x' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
5454
}
5555
useValue(x) // expected-note {{use here could race}}
5656
}
5757

5858
func testIsolationCrossingDueToCaptureParameter(_ x: NonSendableType) async {
5959
let _ = { @MainActor in
60-
print(x) // expected-error {{task-isolated value of type 'NonSendableType' transferred to main actor-isolated context; later accesses to value could race}}
60+
print(x) // expected-error {{transferring 'x' may cause a race}}
61+
// expected-note @-1 {{task-isolated 'x' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
6162
}
6263
useValue(x)
6364
}

0 commit comments

Comments
 (0)