Skip to content

Commit 904f542

Browse files
committed
[Concurrency] Diagnose redundant (unsafe) for a public actor-isolated Sendable immutable storage.
1 parent 0815dbf commit 904f542

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5733,6 +5733,10 @@ WARNING(nonisolated_unsafe_sendable_constant,none,
57335733
"'nonisolated(unsafe)' is unnecessary for a constant with 'Sendable' type "
57345734
"%0, consider removing it",
57355735
(Type))
5736+
WARNING(unsafe_sendable_actor_constant,none,
5737+
"'(unsafe)' is unnecessary for a constant public actor property with "
5738+
"'Sendable' type %0, consider removing it",
5739+
(Type))
57365740
ERROR(nonisolated_non_sendable,none,
57375741
"'nonisolated' can not be applied to variable with non-'Sendable' "
57385742
"type %0",

lib/Sema/TypeCheckAttr.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6975,9 +6975,28 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
69756975
if (attr->isUnsafe() &&
69766976
type->isSendableType() &&
69776977
var->isLet()) {
6978-
diagnose(attr->getLocation(),
6979-
diag::nonisolated_unsafe_sendable_constant, type)
6980-
.fixItRemove(attr->getRange());
6978+
6979+
// '(unsafe)' is redundant for a public actor-isolated 'Sendable'
6980+
// immutable.
6981+
auto nominal = dyn_cast<NominalTypeDecl>(dc);
6982+
if (nominal && nominal->isActor()) {
6983+
auto access = nominal->getFormalAccessScope(
6984+
/*useDC=*/nullptr,
6985+
/*treatUsableFromInlineAsPublic=*/true);
6986+
if (access.isPublic()) {
6987+
// Get the location where '(unsafe)' starts.
6988+
SourceLoc unsafeStart = Lexer::getLocForEndOfToken(
6989+
Ctx.SourceMgr, attr->getRange().Start);
6990+
diagnose(unsafeStart, diag::unsafe_sendable_actor_constant, type)
6991+
.fixItRemoveChars(unsafeStart,
6992+
attr->getRange().End.getAdvancedLoc(1));
6993+
}
6994+
6995+
} else {
6996+
diagnose(attr->getLocation(),
6997+
diag::nonisolated_unsafe_sendable_constant, type)
6998+
.fixItRemove(attr->getRange());
6999+
}
69817000
}
69827001
}
69837002

test/Concurrency/global_variables.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ struct TestStatics {
5656
// expected-note@-1{{isolate 'wrapped' to a global actor, or convert it to a 'let' constant and conform it to 'Sendable'}}
5757
}
5858

59+
public actor TestPublicActor {
60+
nonisolated(unsafe) let immutableNonisolatedUnsafeSendable = TestSendable()
61+
// expected-warning@-1 {{'(unsafe)' is unnecessary for a constant public actor property with 'Sendable' type 'TestSendable', consider removing it}} {{14-22=}}
62+
}
63+
5964
@TestGlobalActor
6065
func f() {
6166
print(TestStatics.immutableExplicitSendable)

0 commit comments

Comments
 (0)