Skip to content

Commit d6f328b

Browse files
committed
[Sema] Check that all callee decls in a function scope have attribute before downgrading diagnostic to warning
1 parent 0daad82 commit d6f328b

File tree

2 files changed

+42
-17
lines changed

2 files changed

+42
-17
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,11 +2145,13 @@ namespace {
21452145
DiagnosticList errors = list.getSecond();
21462146
ActorIsolation isolation = key.second;
21472147

2148-
auto behavior = DiagnosticBehavior::Error;
2149-
2150-
// Limit behavior if @preconcurrency detected
2151-
if (errors.front().preconcurrency)
2152-
behavior = DiagnosticBehavior::Warning;
2148+
auto behavior = DiagnosticBehavior::Warning;
2149+
// Upgrade behavior if @preconcurrency not detected
2150+
if (llvm::any_of(errors, [&](IsolationError error) {
2151+
return !error.preconcurrency;
2152+
})) {
2153+
behavior = DiagnosticBehavior::Error;
2154+
}
21532155

21542156
// Add Fix-it for missing @SomeActor annotation
21552157
if (isolation.isGlobalActor()) {
@@ -2174,11 +2176,14 @@ namespace {
21742176
DiagnosticList errors = list.getSecond();
21752177
ActorIsolation isolation = key.first;
21762178

2177-
auto behavior = DiagnosticBehavior::Error;
2179+
auto behavior = DiagnosticBehavior::Warning;
2180+
// Upgrade behavior if @preconcurrency not detected
2181+
if (llvm::any_of(errors, [&](IsolationError error) {
2182+
return !error.preconcurrency;
2183+
})) {
2184+
behavior = DiagnosticBehavior::Error;
2185+
}
21782186

2179-
// Limit behavior if @preconcurrency detected
2180-
if (errors.front().preconcurrency)
2181-
behavior = DiagnosticBehavior::Warning;
21822187

21832188
// Add Fix-it for missing @SomeActor annotation
21842189
if (isolation.isGlobalActor()) {
@@ -2194,7 +2199,7 @@ namespace {
21942199
// Diagnose actor_isolated_call as note if
21952200
// if there are multiple actor-isolated function calls
21962201
// from outside the actor
2197-
ctx.Diags.diagnose(error.loc, error.diag)
2202+
ctx.Diags.diagnose(error.loc, error.diag)
21982203
.limitBehaviorUntilSwiftVersion(behavior, 6);
21992204
}
22002205
}
@@ -3458,7 +3463,8 @@ namespace {
34583463

34593464
IsolationError mismatch([calleeDecl, apply, unsatisfiedIsolation, getContextIsolation]() {
34603465
if (calleeDecl) {
3461-
auto preconcurrency = getContextIsolation().preconcurrency() || getActorIsolation(calleeDecl).preconcurrency();
3466+
auto preconcurrency = getContextIsolation().preconcurrency() ||
3467+
getActorIsolation(calleeDecl).preconcurrency();
34623468

34633469
return IsolationError(
34643470
apply->getLoc(),
@@ -3488,7 +3494,8 @@ namespace {
34883494
}
34893495
} else {
34903496
if (calleeDecl) {
3491-
auto preconcurrency = getContextIsolation().preconcurrency() || getActorIsolation(calleeDecl).preconcurrency();
3497+
auto preconcurrency = getContextIsolation().preconcurrency() ||
3498+
getActorIsolation(calleeDecl).preconcurrency();
34923499

34933500
ctx.Diags.diagnose(
34943501
apply->getLoc(), diag::actor_isolated_call_decl,

test/Concurrency/grouped_actor_isolation_diagnostics.swift

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature GroupActorErrors
1+
// RUN: %target-typecheck-verify-swift -disable-availability-checking -enable-experimental-feature GroupActorErrors -strict-concurrency=complete
22
// REQUIRES: concurrency
33

44
@MainActor
@@ -7,19 +7,25 @@ protocol P {
77
nonisolated func g()
88
}
99

10+
@preconcurrency @MainActor
11+
protocol Q {
12+
func f()
13+
nonisolated func g()
14+
}
15+
1016
struct S: P {
1117
func f() { }
1218
func g() { }
1319
}
1420

15-
@preconcurrency struct NonConcurrentS: P {
21+
@preconcurrency
22+
struct NonConcurrentS: Q {
1623
func f() { }
1724
func g() { }
1825
}
1926

2027
// expected-note@+1{{add '@MainActor' to make global function 'testP(s:p:)' part of global actor 'MainActor'}}
2128
func testP(s: S, p: P) { // expected-error {{calls to '@MainActor'-isolated' code in global function 'testP(s:p:)'}}
22-
2329
p.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
2430
p.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
2531
p.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
@@ -29,8 +35,20 @@ func testP(s: S, p: P) { // expected-error {{calls to '@MainActor'-isolated' cod
2935
s.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
3036
s.g() // OKAY
3137
}
32-
// expected-note @+1{{add '@MainActor' to make global function 'testPreconcurrencyP(ncs:)' part of global actor 'MainActor'}}
33-
func testPreconcurrencyP(ncs: NonConcurrentS) { // expected-error {{calls to '@MainActor'-isolated' code in global function 'testPreconcurrencyP(ncs:)'}}
38+
// expected-note @+1{{add '@MainActor' to make global function 'testPreconcurrency(ncs:s:)' part of global actor 'MainActor'}}
39+
func testPreconcurrency(ncs: NonConcurrentS, s:S ) { // expected-error {{calls to '@MainActor'-isolated' code in global function 'testPreconcurrency(ncs:s:)'}}
40+
ncs.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
41+
ncs.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
42+
ncs.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
43+
ncs.g() // OKAY
44+
s.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
45+
s.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
46+
s.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
47+
s.g() // OKAY
48+
}
49+
50+
// expected-note @+1{{add '@MainActor' to make global function 'testOnlyPreconcurrency(ncs:)' part of global actor 'MainActor'}}
51+
func testOnlyPreconcurrency(ncs: NonConcurrentS) { // expected-warning {{calls to '@MainActor'-isolated' code in global function 'testOnlyPreconcurrency(ncs:)'}}
3452
ncs.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
3553
ncs.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
3654
ncs.f() // expected-note{{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}

0 commit comments

Comments
 (0)