Skip to content

Commit 241e245

Browse files
committed
[Concurrency] Diagnose redundant nonisolated(unsafe) for a Sendable immutable storage.
1 parent 6fbc06e commit 241e245

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
@@ -5686,6 +5686,10 @@ NOTE(nonisolated_mutable_storage_note,none,
56865686
"convert %0 to a 'let' constant or consider declaring it "
56875687
"'nonisolated(unsafe)' if manually managing concurrency safety",
56885688
(const VarDecl *))
5689+
WARNING(nonisolated_unsafe_sendable_constant,none,
5690+
"'nonisolated(unsafe)' is unnecessary for a constant with 'Sendable' type "
5691+
"%0, consider removing it",
5692+
(Type))
56895693
ERROR(nonisolated_non_sendable,none,
56905694
"'nonisolated' can not be applied to variable with non-'Sendable' "
56915695
"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
@@ -41,6 +41,8 @@ struct TestStatics {
4141
static let immutableExplicitSendable = TestSendable()
4242
static let immutableNonsendable = TestNonsendable() // expected-error{{static property 'immutableNonsendable' is not concurrency-safe because it is not either conforming to 'Sendable' or isolated to a global actor}}
4343
static nonisolated(unsafe) let immutableNonisolatedUnsafe = TestNonsendable()
44+
static nonisolated(unsafe) let immutableNonisolatedUnsafeSendable = TestSendable()
45+
// expected-warning@-1 {{'nonisolated(unsafe)' is unnecessary for a constant with 'Sendable' type 'TestSendable', consider removing it}} {{10-30=}}
4446
static nonisolated let immutableNonisolated = TestNonsendable() // expected-error{{static property 'immutableNonisolated' is not concurrency-safe because it is not either conforming to 'Sendable' or isolated to a global actor}}
4547
// expected-error@-1 {{'nonisolated' can not be applied to variable with non-'Sendable' type 'TestNonsendable'}}
4648
static let immutableInferredSendable = 0
@@ -61,6 +63,9 @@ func f() {
6163
}
6264

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

0 commit comments

Comments
 (0)