Skip to content

Commit 22e79c2

Browse files
authored
Merge pull request #69177 from angela-laar/prevent-sendable-attribute
[Concurrency] Disallow Sendable annotation on methods of non-Sendable types
2 parents 9e52a8c + e779b05 commit 22e79c2

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
@@ -5304,6 +5304,9 @@ ERROR(local_function_executed_concurrently,none,
53045304
ERROR(sendable_isolated_sync_function,none,
53055305
"%0 synchronous %kind1 cannot be marked as '@Sendable'",
53065306
(ActorIsolation, const ValueDecl *))
5307+
ERROR(nonsendable_instance_method,none,
5308+
"instance methods of non-Sendable types cannot be marked as '@Sendable'",
5309+
())
53075310
ERROR(concurrent_access_of_local_capture,none,
53085311
"%select{mutation of|reference to}0 captured %kind1 in "
53095312
"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)