Skip to content

Change note for non marked with main actor global variables #75235

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -5393,7 +5393,7 @@ NOTE(note_add_distributed_to_decl,none,
ERROR(invalid_isolated_calls_in_body,none,
"calls to '@%0'-isolated' code in %kind1",
(StringRef, const ValueDecl *))
NOTE(add_globalactor_to_function,none,
NOTE(add_globalactor_to_decl,none,
"add '@%0' to make %kind1 part of global actor %2",
(StringRef, const ValueDecl *, Type))
FIXIT(insert_globalactor_attr, "@%0 ", (Type))
Expand Down Expand Up @@ -5645,8 +5645,6 @@ ERROR(shared_immutable_state_decl,none,
NOTE(shared_state_make_immutable,none,
"convert %0 to a 'let' constant to make 'Sendable' shared state immutable",
(const ValueDecl *))
NOTE(shared_state_main_actor_node,none,
"annotate %0 with '@MainActor' if property should only be accessed from the main actor", (const ValueDecl *))
NOTE(shared_state_nonisolated_unsafe,none,
"disable concurrency-safety checks if accesses are protected by an external synchronization mechanism", (const ValueDecl *))
ERROR(actor_isolated_witness,none,
Expand Down
16 changes: 10 additions & 6 deletions lib/Sema/TypeCheckConcurrency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2436,7 +2436,7 @@ namespace {
if (fn->getOverriddenDecl())
return false;

fn->diagnose(diag::add_globalactor_to_function,
fn->diagnose(diag::add_globalactor_to_decl,
globalActor->getWithoutParens().getString(),
fn, globalActor)
.fixItInsert(fn->getAttributeInsertionLoc(false),
Expand Down Expand Up @@ -5403,7 +5403,7 @@ ActorIsolation ActorIsolationRequest::evaluate(

// Diagnose global state that is not either immutable plus Sendable or
// isolated to a global actor.
auto checkGlobalIsolation = [var = dyn_cast<VarDecl>(value)](
auto checkGlobalIsolation = [var = dyn_cast<VarDecl>(value), &ctx](
ActorIsolation isolation) {
// Diagnose only declarations in the same module.
//
Expand Down Expand Up @@ -5447,10 +5447,14 @@ ActorIsolation ActorIsolationRequest::evaluate(
}
}

diagVar->diagnose(diag::shared_state_main_actor_node,
diagVar)
.fixItInsert(diagVar->getAttributeInsertionLoc(false),
"@MainActor ");
auto mainActor = ctx.getMainActorType();
if (mainActor) {
diagVar->diagnose(diag::add_globalactor_to_decl,
mainActor->getWithoutParens().getString(),
diagVar, mainActor)
.fixItInsert(diagVar->getAttributeInsertionLoc(false),
diag::insert_globalactor_attr, mainActor);
}
diagVar->diagnose(diag::shared_state_nonisolated_unsafe,
diagVar)
.fixItInsert(diagVar->getAttributeInsertionLoc(true),
Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/Inputs/sendable_cycle_other.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
struct Foo {
static let member = Bar() // expected-complete-warning {{static property 'member' is not concurrency-safe because non-'Sendable' type 'Bar' may have shared mutable state; this is an error in the Swift 6 language mode}}
// expected-complete-note@-1 {{annotate 'member' with '@MainActor' if property should only be accessed from the main actor}}
// expected-complete-note@-1 {{add '@MainActor' to make static property 'member' part of global actor 'MainActor'}}
// expected-complete-note@-2{{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}
}
2 changes: 1 addition & 1 deletion test/Concurrency/concurrency_warnings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class GlobalCounter { // expected-note{{class 'GlobalCounter' does not conform t

let rs = GlobalCounter() // expected-warning {{let 'rs' is not concurrency-safe because non-'Sendable' type 'GlobalCounter' may have shared mutable state; this is an error in the Swift 6 language mode}}
// expected-note@-1 {{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}
// expected-note@-2 {{annotate 'rs' with '@MainActor' if property should only be accessed from the main actor}}
// expected-note@-2 {{add '@MainActor' to make let 'rs' part of global actor 'MainActor'}}

import GlobalVariables

Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/concurrent_value_checking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ typealias BadGenericCF<T> = @Sendable () -> T?
typealias GoodGenericCF<T: Sendable> = @Sendable () -> T? // okay

var concurrentFuncVar: (@Sendable (NotConcurrent) -> Void)? = nil // expected-warning{{var 'concurrentFuncVar' is not concurrency-safe because it is nonisolated global shared mutable state; this is an error in the Swift 6 language mode}}
// expected-note@-1 {{annotate 'concurrentFuncVar' with '@MainActor' if property should only be accessed from the main actor}}
// expected-note@-1 {{add '@MainActor' to make var 'concurrentFuncVar' part of global actor 'MainActor'}}
// expected-note@-2 {{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}
// expected-note@-3 {{convert 'concurrentFuncVar' to a 'let' constant to make 'Sendable' shared state immutable}}

Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/flow_isolation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ struct CardboardBox<T> {

@available(SwiftStdlib 5.1, *)
var globalVar: EscapeArtist? // expected-warning {{var 'globalVar' is not concurrency-safe because it is nonisolated global shared mutable state; this is an error in the Swift 6 language mode}}
// expected-note@-1 {{annotate 'globalVar' with '@MainActor' if property should only be accessed from the main actor}}
// expected-note@-1 {{add '@MainActor' to make var 'globalVar' part of global actor 'MainActor'}}
// expected-note@-2 {{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}
// expected-note@-3 {{convert 'globalVar' to a 'let' constant to make 'Sendable' shared state immutable}}

Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/freestanding_top_level.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// RUN: %target-swift-frontend -concurrency-model=task-to-thread -typecheck -verify -verify-additional-prefix complete- -strict-concurrency=complete %s

// expected-complete-warning@+4 {{var 'global' is not concurrency-safe because it is nonisolated global shared mutable state; this is an error in the Swift 6 language mode}}
// expected-complete-note@+3 {{annotate 'global' with '@MainActor' if property should only be accessed from the main actor}}{{1-1=@MainActor }}
// expected-complete-note@+3 {{add '@MainActor' to make var 'global' part of global actor 'MainActor'}}{{1-1=@MainActor }}
// expected-complete-note@+2 {{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}{{1-1=nonisolated(unsafe) }}
// expected-complete-note@+1 {{convert 'global' to a 'let' constant to make 'Sendable' shared state immutable}}{{1-4=let}}
var global = 10
Expand Down
10 changes: 5 additions & 5 deletions test/Concurrency/global_variables.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ actor TestGlobalActor {
var mutableIsolatedGlobal = 1

var mutableNonisolatedGlobal = 1 // expected-error{{var 'mutableNonisolatedGlobal' is not concurrency-safe because it is nonisolated global shared mutable state}}
// expected-note@-1{{annotate 'mutableNonisolatedGlobal' with '@MainActor' if property should only be accessed from the main actor}}{{1-1=@MainActor }}
// expected-note@-1{{add '@MainActor' to make var 'mutableNonisolatedGlobal' part of global actor 'MainActor'}}{{1-1=@MainActor }}
// expected-note@-2{{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}{{1-1=nonisolated(unsafe) }}
// expected-note@-3{{convert 'mutableNonisolatedGlobal' to a 'let' constant to make 'Sendable' shared state immutable}}{{1-4=let}}

Expand Down Expand Up @@ -48,25 +48,25 @@ actor TestActor {
struct TestStatics {
static let immutableExplicitSendable = TestSendable()
static let immutableNonsendable = TestNonsendable() // expected-error{{static property 'immutableNonsendable' is not concurrency-safe because non-'Sendable' type 'TestNonsendable' may have shared mutable state}}
// expected-note@-1 {{annotate 'immutableNonsendable' with '@MainActor' if property should only be accessed from the main actor}}
// expected-note@-1 {{add '@MainActor' to make static property 'immutableNonsendable' part of global actor 'MainActor'}}
// expected-note@-2 {{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}
static nonisolated(unsafe) let immutableNonisolatedUnsafe = TestNonsendable()
static nonisolated let immutableNonisolated = TestNonsendable() // expected-error{{static property 'immutableNonisolated' is not concurrency-safe because non-'Sendable' type 'TestNonsendable' may have shared mutable state}}
// expected-note@-1 {{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}
// expected-error@-2 {{'nonisolated' can not be applied to variable with non-'Sendable' type 'TestNonsendable'}}
// expected-note@-3{{annotate 'immutableNonisolated' with '@MainActor' if property should only be accessed from the main actor}}
// expected-note@-3{{add '@MainActor' to make static property 'immutableNonisolated' part of global actor 'MainActor'}}
static nonisolated(unsafe) let immutableNonisolatedUnsafeSendable = TestSendable()
// expected-warning@-1 {{'nonisolated(unsafe)' is unnecessary for a constant with 'Sendable' type 'TestSendable', consider removing it}} {{10-30=}}
static let immutableInferredSendable = 0
static var mutable = 0 // expected-error{{static property 'mutable' is not concurrency-safe because it is nonisolated global shared mutable state}}
// expected-note@-1{{convert 'mutable' to a 'let' constant to make 'Sendable' shared state immutable}}
// expected-note@-2{{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}
// expected-note@-3{{annotate 'mutable' with '@MainActor' if property should only be accessed from the main actor}}
// expected-note@-3{{add '@MainActor' to make static property 'mutable' part of global actor 'MainActor'}}
static var computedProperty: Int { 0 } // computed property that, though static, has no storage so is not a global
@TestWrapper static var wrapped: Int // expected-error{{static property 'wrapped' is not concurrency-safe because it is nonisolated global shared mutable state}}
// expected-note@-1{{convert 'wrapped' to a 'let' constant to make 'Sendable' shared state immutable}}{{23-26=let}}
// expected-note@-2{{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}{{16-16=nonisolated(unsafe) }}
// expected-note@-3{{annotate 'wrapped' with '@MainActor' if property should only be accessed from the main actor}}{{3-3=@MainActor }}
// expected-note@-3{{add '@MainActor' to make static property 'wrapped' part of global actor 'MainActor'}}{{3-3=@MainActor }}
}

public actor TestPublicActor {
Expand Down
4 changes: 2 additions & 2 deletions test/Concurrency/predates_concurrency_import.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ let nonStrictGlobal = NonStrictClass() // no warning

let strictGlobal = StrictStruct() // expected-warning{{let 'strictGlobal' is not concurrency-safe because non-'Sendable' type 'StrictStruct' may have shared mutable state}}
// expected-note@-1{{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}
// expected-note@-2{{annotate 'strictGlobal' with '@MainActor' if property should only be accessed from the main actor}}
// expected-note@-2{{add '@MainActor' to make let 'strictGlobal' part of global actor 'MainActor'}}

extension NonStrictClass {
@Sendable func f() { }
Expand All @@ -62,7 +62,7 @@ struct HasStatics {
// expected-warning@-1{{'nonisolated' can not be applied to variable with non-'Sendable' type 'StrictStruct'}}
// expected-warning@-2{{static property 'ss' is not concurrency-safe because non-'Sendable' type 'StrictStruct' may have shared mutable state}}
// expected-note@-3{{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}
// expected-note@-4{{annotate 'ss' with '@MainActor' if property should only be accessed from the main actor}}
// expected-note@-4{{add '@MainActor' to make static property 'ss' part of global actor 'MainActor'}}
}

extension NonStrictClass2: @retroactive MySendableProto { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func test(ss: StrictStruct, ns: NonStrictClass) {

let nonStrictGlobal = NonStrictClass()
let strictGlobal = StrictStruct() // expected-warning{{let 'strictGlobal' is not concurrency-safe because non-'Sendable' type 'StrictStruct' may have shared mutable state}}
// expected-note@-1{{annotate 'strictGlobal' with '@MainActor' if property should only be accessed from the main actor}}
// expected-note@-1{{add '@MainActor' to make let 'strictGlobal' part of global actor 'MainActor'}}
// expected-note@-2{{disable concurrency-safety checks if accesses are protected by an external synchronization mechanism}}

extension NonStrictClass {
Expand Down