Skip to content

Commit a57f06f

Browse files
committed
[Concurrency] Disallow Sendable annotation on methods of non-Sendable types
1 parent d6c681e commit a57f06f

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5248,6 +5248,9 @@ ERROR(local_function_executed_concurrently,none,
52485248
ERROR(sendable_isolated_sync_function,none,
52495249
"%0 synchronous %kind1 cannot be marked as '@Sendable'",
52505250
(ActorIsolation, const ValueDecl *))
5251+
ERROR(nonsendable_instance_method,none,
5252+
"instance methods of non-Sendable types cannot be marked as '@Sendable'",
5253+
())
52515254
ERROR(concurrent_access_of_local_capture,none,
52525255
"%select{mutation of|reference to}0 captured %kind1 in "
52535256
"concurrently-executing code",

lib/Sema/TypeCheckAttr.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6560,6 +6560,8 @@ void AttributeChecker::visitKnownToBeLocalAttr(KnownToBeLocalAttr *attr) {
65606560

65616561
void AttributeChecker::visitSendableAttr(SendableAttr *attr) {
65626562

6563+
auto dc = D->getDeclContext();
6564+
65636565
if ((isa<AbstractFunctionDecl>(D) || isa<AbstractStorageDecl>(D)) &&
65646566
!isAsyncDecl(cast<ValueDecl>(D))) {
65656567
auto value = cast<ValueDecl>(D);
@@ -6571,6 +6573,15 @@ void AttributeChecker::visitSendableAttr(SendableAttr *attr) {
65716573
.warnUntilSwiftVersion(6);
65726574
}
65736575
}
6576+
// Prevent Sendable Attr from being added to methods of non-sendable types
6577+
if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(D)) {
6578+
if (auto selfdecl = funcDecl->getImplicitSelfDecl()) {
6579+
if (!isSendableType(dc->getParentModule(), selfdecl->getTypeInContext())) {
6580+
diagnose(attr->getLocation(), diag::nonsendable_instance_method)
6581+
.warnUntilSwiftVersion(6);
6582+
}
6583+
}
6584+
}
65746585
}
65756586

65766587
void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {

test/Concurrency/sendable_functions.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,24 @@ actor A {
2323
}
2424
}
2525

26+
class NonSendableC {
27+
var x: Int = 0
28+
29+
@Sendable func inc() { // expected-warning{{instance methods of non-Sendable types cannot be marked as '@Sendable'}}
30+
x += 1
31+
}
32+
}
33+
34+
struct S<T> {
35+
let t: T
36+
37+
@Sendable func test() {} // expected-warning{{instance methods of non-Sendable types cannot be marked as '@Sendable'}}
38+
}
39+
40+
extension S: Sendable where T: Sendable {
41+
@Sendable func test2() {}
42+
}
43+
2644
@available(SwiftStdlib 5.1, *)
2745
@MainActor @Sendable func globalActorFunc() { } // expected-warning{{main actor-isolated synchronous global function 'globalActorFunc()' cannot be marked as '@Sendable'}}
2846

0 commit comments

Comments
 (0)