Skip to content

Commit c7d24e0

Browse files
committed
[region-isolation] Convert the typed strongly transferred value diagnostic into a short error, longer note diagnostic.
Just finishing these diagnostics.
1 parent 2febd26 commit c7d24e0

File tree

4 files changed

+63
-12
lines changed

4 files changed

+63
-12
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -948,9 +948,6 @@ ERROR(regionbasedisolation_unknown_pattern, none,
948948
// Old Transfer Non Sendable Diagnostics
949949
//
950950

951-
ERROR(regionbasedisolation_transfer_yields_race_stronglytransferred_binding, none,
952-
"value of non-Sendable type %0 accessed after being transferred; later accesses could race",
953-
(Type))
954951
ERROR(regionbasedisolation_arg_transferred, none,
955952
"sending %0 value of type %1 with later accesses to %2 context risks causing data races",
956953
(StringRef, Type, ActorIsolation))
@@ -1037,6 +1034,13 @@ NOTE(regionbasedisolation_named_transfer_nt_asynclet_capture, none,
10371034
"sending %1 %0 into async let risks causing data races between nonisolated and %1 uses",
10381035
(Identifier, StringRef))
10391036

1037+
NOTE(regionbasedisolation_typed_use_after_sending, none,
1038+
"Passing value of non-Sendable type %0 as a 'sending' argument risks causing races in between local and caller code",
1039+
(Type))
1040+
NOTE(regionbasedisolation_typed_use_after_sending_callee, none,
1041+
"Passing value of non-Sendable type %0 as a 'sending' argument to %1 %2 risks causing races in between local and caller code",
1042+
(Type, DescriptiveDeclKind, DeclName))
1043+
10401044
// Misc Error.
10411045
ERROR(regionbasedisolation_task_or_actor_isolated_transferred, none,
10421046
"task or actor isolated value cannot be sent", ())

lib/SILOptimizer/Mandatory/TransferNonSendable.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -739,13 +739,17 @@ class UseAfterTransferDiagnosticEmitter {
739739

740740
void emitTypedUseOfStronglyTransferredValue(SILLocation loc,
741741
Type inferredType) {
742-
diagnoseError(
743-
loc,
744-
diag::
745-
regionbasedisolation_transfer_yields_race_stronglytransferred_binding,
746-
inferredType)
747-
.highlight(loc.getSourceRange())
742+
diagnoseError(loc, diag::regionbasedisolation_type_transfer_yields_race,
743+
inferredType)
748744
.limitBehaviorIf(getBehaviorLimit());
745+
if (auto calleeInfo = getTransferringCalleeInfo()) {
746+
diagnoseNote(loc,
747+
diag::regionbasedisolation_typed_use_after_sending_callee,
748+
inferredType, calleeInfo->first, calleeInfo->second);
749+
} else {
750+
diagnoseNote(loc, diag::regionbasedisolation_typed_use_after_sending,
751+
inferredType);
752+
}
749753
emitRequireInstDiagnostics();
750754
}
751755

@@ -1108,9 +1112,18 @@ void UseAfterTransferDiagnosticInferrer::infer() {
11081112
baseLoc, rootValueAndName->first);
11091113
}
11101114

1115+
// See if we have an ApplyExpr and if we can infer a better type.
1116+
Type type = baseInferredType;
1117+
if (auto *applyExpr =
1118+
transferOp->getUser()->getLoc().getAsASTNode<ApplyExpr>()) {
1119+
if (auto *foundExpr =
1120+
inferArgumentExprFromApplyExpr(applyExpr, fas, transferOp))
1121+
type = foundExpr->findOriginalType();
1122+
}
1123+
11111124
// Otherwise, emit the typed diagnostic.
1112-
return diagnosticEmitter.emitTypedUseOfStronglyTransferredValue(
1113-
baseLoc, baseInferredType);
1125+
return diagnosticEmitter.emitTypedUseOfStronglyTransferredValue(baseLoc,
1126+
type);
11141127
}
11151128
}
11161129

test/Concurrency/transfernonsendable.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1762,7 +1762,8 @@ extension MyActor {
17621762
_ = self
17631763
_ = sc
17641764

1765-
Task { // expected-tns-warning {{value of non-Sendable type '@isolated(any) @async @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <()>' accessed after being transferred}}
1765+
Task { // expected-tns-warning {{sending value of non-Sendable type '() async -> ()' risks causing data races}}
1766+
// expected-tns-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument risks causing races in between local and caller code}}
17661767
_ = sc
17671768
}
17681769

test/Concurrency/transfernonsendable_typed_errors.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
class NonSendableKlass {}
1919

20+
actor MyActor {}
21+
2022
@MainActor func transferToMain<T>(_ t: T) async {}
2123

2224
/////////////////
@@ -38,3 +40,34 @@ func isolatedClosureTest() async {
3840
}
3941
print(x) // expected-note {{access can happen concurrently}}
4042
}
43+
44+
func sendingError() async {
45+
func test(_ x: sending NonSendableKlass) {}
46+
let x = NonSendableKlass()
47+
test(x) // expected-error {{sending value of non-Sendable type 'NonSendableKlass' risks causing data races}}
48+
// expected-note @-1 {{Passing value of non-Sendable type 'NonSendableKlass' as a 'sending' argument to local function 'test' risks causing races in between local and caller code}}
49+
print(x) // expected-note {{access can happen concurrently}}
50+
}
51+
52+
extension MyActor {
53+
func testNonSendableCaptures(sc: NonSendableKlass) {
54+
Task {
55+
_ = self
56+
_ = sc
57+
58+
Task { [sc,self] in
59+
_ = self
60+
_ = sc
61+
62+
Task { // expected-error {{sending value of non-Sendable type '() async -> ()' risks causing data races}}
63+
// expected-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument risks causing races in between local and caller code}}
64+
_ = sc
65+
}
66+
67+
Task { // expected-note {{access can happen concurrently}}
68+
_ = sc
69+
}
70+
}
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)