Skip to content

Commit 55a92da

Browse files
committed
Diagnose @Sendable on actor-isolated synchronous functions.
There is no way for these functions to be Sendable, so diagnose attempts to make them so. This closes a hole in Sendable checking. Fixes rdar://94623729.
1 parent 104271c commit 55a92da

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4563,6 +4563,9 @@ ERROR(effectful_keypath_component,none,
45634563
ERROR(local_function_executed_concurrently,none,
45644564
"concurrently-executed %0 %1 must be marked as '@Sendable'",
45654565
(DescriptiveDeclKind, DeclName))
4566+
ERROR(sendable_isolated_sync_function,none,
4567+
"%0 synchronous %1 %2 cannot be marked as '@Sendable'",
4568+
(ActorIsolation, DescriptiveDeclKind, DeclName))
45664569
ERROR(concurrent_access_of_local_capture,none,
45674570
"%select{mutation of|reference to}0 captured %1 %2 in "
45684571
"concurrently-executing code",

lib/Sema/TypeCheckAttr.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
149149
IGNORED_ATTR(OriginallyDefinedIn)
150150
IGNORED_ATTR(NoDerivative)
151151
IGNORED_ATTR(SpecializeExtension)
152-
IGNORED_ATTR(Sendable)
153152
IGNORED_ATTR(NonSendable)
154153
IGNORED_ATTR(AtRethrows)
155154
IGNORED_ATTR(AtReasync)
@@ -321,6 +320,8 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
321320
void checkBackDeployAttrs(ArrayRef<BackDeployAttr *> Attrs);
322321

323322
void visitKnownToBeLocalAttr(KnownToBeLocalAttr *attr);
323+
324+
void visitSendableAttr(SendableAttr *attr);
324325
};
325326

326327
} // end anonymous namespace
@@ -5842,6 +5843,21 @@ void AttributeChecker::visitKnownToBeLocalAttr(KnownToBeLocalAttr *attr) {
58425843
}
58435844
}
58445845

5846+
void AttributeChecker::visitSendableAttr(SendableAttr *attr) {
5847+
5848+
if ((isa<AbstractFunctionDecl>(D) || isa<AbstractStorageDecl>(D)) &&
5849+
!isAsyncDecl(cast<ValueDecl>(D))) {
5850+
auto value = cast<ValueDecl>(D);
5851+
ActorIsolation isolation = getActorIsolation(value);
5852+
if (isolation.isActorIsolated()) {
5853+
diagnoseAndRemoveAttr(
5854+
attr, diag::sendable_isolated_sync_function,
5855+
isolation, value->getDescriptiveKind(), value->getName())
5856+
.warnUntilSwiftVersion(6);
5857+
}
5858+
}
5859+
}
5860+
58455861
void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
58465862
// 'nonisolated' can be applied to global and static/class variables
58475863
// that do not have storage.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-typecheck-verify-swift
2+
// REQUIRES: concurrency
3+
4+
5+
@Sendable func globalFunc() { }
6+
7+
actor A {
8+
var state: Bool = false
9+
10+
@Sendable func f() { // expected-warning{{actor-isolated synchronous instance method 'f()' cannot be marked as '@Sendable'}}
11+
state = true
12+
}
13+
14+
@Sendable nonisolated func g() { }
15+
16+
@Sendable func fAsync() async {
17+
state = true
18+
}
19+
}
20+
21+
@MainActor @Sendable func globalActorFunc() { } // expected-warning{{main actor-isolated synchronous global function 'globalActorFunc()' cannot be marked as '@Sendable'}}
22+
23+
@MainActor @Sendable func globalActorFuncAsync() async { }

0 commit comments

Comments
 (0)