Skip to content

Commit 9fc5b7e

Browse files
committed
[Concurrency] Diagnose redundant nonisolated(unsafe) for a Sendable immutable storage.
1 parent 663865c commit 9fc5b7e

File tree

3 files changed

+18
-0
lines changed

3 files changed

+18
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5696,6 +5696,10 @@ NOTE(nonisolated_mutable_storage_note,none,
56965696
"convert %0 to a 'let' constant or consider declaring it "
56975697
"'nonisolated(unsafe)' if manually managing concurrency safety",
56985698
(const VarDecl *))
5699+
WARNING(nonisolated_unsafe_sendable_constant,none,
5700+
"'nonisolated(unsafe)' is unnecessary for a constant with 'Sendable' type "
5701+
"%0, consider removing it",
5702+
(Type))
56995703
ERROR(nonisolated_non_sendable,none,
57005704
"'nonisolated' can not be applied to variable with non-'Sendable' "
57015705
"type %0",

lib/Sema/TypeCheckAttr.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6921,6 +6921,15 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
69216921
return;
69226922
}
69236923
}
6924+
6925+
// 'nonisolated(unsafe)' is redundant for 'Sendable' immutables.
6926+
if (attr->isUnsafe() &&
6927+
type->isSendableType() &&
6928+
var->isLet()) {
6929+
diagnose(attr->getLocation(),
6930+
diag::nonisolated_unsafe_sendable_constant, type)
6931+
.fixItRemove(attr->getRange());
6932+
}
69246933
}
69256934

69266935
// Using 'nonisolated' with wrapped properties is unsupported, because

test/Concurrency/global_variables.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ struct TestStatics {
4545
static nonisolated let immutableNonisolated = TestNonsendable() // expected-error{{static property 'immutableNonisolated' is not concurrency-safe because non-'Sendable' type 'TestNonsendable' may have shared mutable state}}
4646
// expected-note@-1 {{isolate 'immutableNonisolated' to a global actor, or conform 'TestNonsendable' to 'Sendable'}}
4747
// expected-error@-2 {{'nonisolated' can not be applied to variable with non-'Sendable' type 'TestNonsendable'}}
48+
static nonisolated(unsafe) let immutableNonisolatedUnsafeSendable = TestSendable()
49+
// expected-warning@-1 {{'nonisolated(unsafe)' is unnecessary for a constant with 'Sendable' type 'TestSendable', consider removing it}} {{10-30=}}
4850
static let immutableInferredSendable = 0
4951
static var mutable = 0 // expected-error{{static property 'mutable' is not concurrency-safe because it is non-isolated global shared mutable state}}
5052
// expected-note@-1{{isolate 'mutable' to a global actor, or convert it to a 'let' constant and conform it to 'Sendable'}}
@@ -63,6 +65,9 @@ func f() {
6365
}
6466

6567
func testLocalNonisolatedUnsafe() async {
68+
nonisolated(unsafe) let immutable = 1
69+
// expected-warning@-1{{'nonisolated(unsafe)' is unnecessary for a constant with 'Sendable' type 'Int', consider removing it}} {{3-23=}}
70+
// expected-warning@-2{{initialization of immutable value 'immutable' was never used; consider replacing with assignment to '_' or removing it}}
6671
nonisolated(unsafe) var value = 1
6772
let task = Task {
6873
value = 2

0 commit comments

Comments
 (0)