Skip to content

Commit

Permalink
[Concurrency] Diagnose redundant (unsafe) for a public actor-isolat…
Browse files Browse the repository at this point in the history
…ed `Sendable` immutable storage.
  • Loading branch information
simanerush committed Mar 7, 2024
1 parent b6b28dd commit c9b5791
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 2 deletions.
4 changes: 4 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -5690,6 +5690,10 @@ WARNING(nonisolated_unsafe_sendable_constant,none,
"'nonisolated(unsafe)' is unnecessary for a constant with 'Sendable' type "
"%0, consider removing it",
(Type))
WARNING(unsafe_sendable_actor_constant,none,
"'(unsafe)' is unnecessary for a constant public actor property with "
"'Sendable' type %0, consider removing it",
(Type))
ERROR(nonisolated_non_sendable,none,
"'nonisolated' can not be applied to variable with non-'Sendable' "
"type %0",
Expand Down
23 changes: 21 additions & 2 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6926,8 +6926,27 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
if (attr->isUnsafe() &&
type->isSendableType() &&
var->isLet()) {
diagnoseAndRemoveAttr(
attr, diag::nonisolated_unsafe_sendable_constant, type);

// '(unsafe)' is redundant for a public actor-isolated 'Sendable'
// immutable.
auto nominal = dyn_cast<NominalTypeDecl>(dc);
if (nominal && nominal->isActor()) {
auto access = nominal->getFormalAccessScope(
/*useDC=*/nullptr,
/*treatUsableFromInlineAsPublic=*/true);
if (access.isPublic()) {
// Get the location where '(unsafe)' starts.
SourceLoc unsafeStart = Lexer::getLocForEndOfToken(
Ctx.SourceMgr, attr->getRange().Start);
diagnose(unsafeStart, diag::unsafe_sendable_actor_constant, type)
.fixItRemoveChars(unsafeStart,
attr->getRange().End.getAdvancedLoc(1));
}

} else {
diagnoseAndRemoveAttr(
attr, diag::nonisolated_unsafe_sendable_constant, type);
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions test/Concurrency/global_variables.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ struct TestStatics {
// expected-note@-1{{isolate 'wrapped' to a global actor, or convert it to a 'let' constant and conform it to 'Sendable'}}
}

public actor TestPublicActor {
nonisolated(unsafe) let immutableNonisolatedUnsafeSendable = TestSendable()
// expected-warning@-1 {{'(unsafe)' is unnecessary for a constant public actor property with 'Sendable' type 'TestSendable', consider removing it}} {{14-22=}}
}

@TestGlobalActor
func f() {
print(TestStatics.immutableExplicitSendable)
Expand Down

0 comments on commit c9b5791

Please sign in to comment.