Skip to content

Commit e779b05

Browse files
committed
[Concurrency] Disallow Sendable annotation on methods of non-Sendable types
1 parent 229398c commit e779b05

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
@@ -5302,6 +5302,9 @@ ERROR(local_function_executed_concurrently,none,
53025302
ERROR(sendable_isolated_sync_function,none,
53035303
"%0 synchronous %kind1 cannot be marked as '@Sendable'",
53045304
(ActorIsolation, const ValueDecl *))
5305+
ERROR(nonsendable_instance_method,none,
5306+
"instance methods of non-Sendable types cannot be marked as '@Sendable'",
5307+
())
53055308
ERROR(concurrent_access_of_local_capture,none,
53065309
"%select{mutation of|reference to}0 captured %kind1 in "
53075310
"concurrently-executing code",

lib/Sema/TypeCheckAttr.cpp

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

66156615
void AttributeChecker::visitSendableAttr(SendableAttr *attr) {
66166616

6617+
auto dc = D->getDeclContext();
6618+
66176619
if ((isa<AbstractFunctionDecl>(D) || isa<AbstractStorageDecl>(D)) &&
66186620
!isAsyncDecl(cast<ValueDecl>(D))) {
66196621
auto value = cast<ValueDecl>(D);
@@ -6625,6 +6627,15 @@ void AttributeChecker::visitSendableAttr(SendableAttr *attr) {
66256627
.warnUntilSwiftVersion(6);
66266628
}
66276629
}
6630+
// Prevent Sendable Attr from being added to methods of non-sendable types
6631+
if (auto *funcDecl = dyn_cast<AbstractFunctionDecl>(D)) {
6632+
if (auto selfdecl = funcDecl->getImplicitSelfDecl()) {
6633+
if (!isSendableType(dc->getParentModule(), selfdecl->getTypeInContext())) {
6634+
diagnose(attr->getLocation(), diag::nonsendable_instance_method)
6635+
.warnUntilSwiftVersion(6);
6636+
}
6637+
}
6638+
}
66286639
}
66296640

66306641
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)