Skip to content

Commit 6a4c789

Browse files
committed
[Concurrency] Diagnose non-sendable 'self' arguments crossing isolation boundaries.
1 parent 77e694a commit 6a4c789

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,6 +1834,18 @@ bool swift::diagnoseApplyArgSendability(ApplyExpr *apply, const DeclContext *dec
18341834
if (!fnExprType)
18351835
return false;
18361836

1837+
// Check the 'self' argument.
1838+
if (auto *selfApply = dyn_cast<SelfApplyExpr>(apply->getFn())) {
1839+
auto *base = selfApply->getBase();
1840+
if (diagnoseNonSendableTypes(
1841+
base->getType(),
1842+
declContext, base->getStartLoc(),
1843+
diag::non_sendable_call_argument,
1844+
isolationCrossing.value().exitsIsolation(),
1845+
isolationCrossing.value().getDiagnoseIsolation()))
1846+
return true;
1847+
}
1848+
18371849
auto fnType = fnExprType->getAs<FunctionType>();
18381850
if (!fnType)
18391851
return false;

test/Concurrency/isolated_parameters.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ struct S: P {
145145
func checkConformer(_ s: S, _ p: any P, _ ma: MyActor) async {
146146
s.m(thing: ma)
147147
await p.m(thing: ma)
148+
// expected-warning@-1 {{passing argument of non-sendable type 'any P' into actor-isolated context may introduce data races}}
148149
}
149150

150151

test/Concurrency/sendable_checking.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,3 +230,29 @@ func testConversionsAndSendable(a: MyActor, s: any Sendable, f: @Sendable () ->
230230
await a.f(s)
231231
await a.g(f)
232232
}
233+
234+
@available(SwiftStdlib 5.1, *)
235+
final class NonSendable {
236+
// expected-note@-1 3 {{class 'NonSendable' does not conform to the 'Sendable' protocol}}
237+
var value = ""
238+
239+
@MainActor
240+
func update() {
241+
value = "update"
242+
}
243+
244+
func call() async {
245+
await update()
246+
// expected-warning@-1 {{passing argument of non-sendable type 'NonSendable' into main actor-isolated context may introduce data races}}
247+
248+
await self.update()
249+
// expected-warning@-1 {{passing argument of non-sendable type 'NonSendable' into main actor-isolated context may introduce data races}}
250+
}
251+
}
252+
253+
@available(SwiftStdlib 5.1, *)
254+
func testNonSendableBaseArg() async {
255+
let t = NonSendable()
256+
await t.update()
257+
// expected-warning@-1 {{passing argument of non-sendable type 'NonSendable' into main actor-isolated context may introduce data races}}
258+
}

0 commit comments

Comments
 (0)