Skip to content

Commit 1f5abe0

Browse files
authored
Merge pull request #70153 from hborla/discoverable-isolated-witness
[Concurrency] Make actor-isolated witness diagnostics more discoverable.
2 parents d9d07e7 + b528658 commit 1f5abe0

File tree

4 files changed

+29
-7
lines changed

4 files changed

+29
-7
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4935,6 +4935,14 @@ bool swift::contextRequiresStrictConcurrencyChecking(
49354935
if (hasExplicitIsolationAttribute(decl))
49364936
return true;
49374937

4938+
// Extensions of explicitly isolated types are using concurrency
4939+
// features.
4940+
if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
4941+
auto *nominal = extension->getExtendedNominal();
4942+
if (nominal && hasExplicitIsolationAttribute(nominal))
4943+
return true;
4944+
}
4945+
49384946
if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
49394947
// Async and concurrent functions use concurrency features.
49404948
if (func->hasAsync() || func->isSendable())

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3225,9 +3225,10 @@ ConformanceChecker::checkActorIsolation(ValueDecl *requirement,
32253225
refResult.isolation.isGlobalActor() ||
32263226
requirementIsolation.isGlobalActor()) {
32273227
// If the witness or requirement has global actor isolation, downgrade
3228-
// based on context.
3228+
// based on context. Use the witness itself as the context, because
3229+
// an explicitly isolated witness should not suppress diagnostics.
32293230
behavior = SendableCheckContext(
3230-
Conformance->getDeclContext()).defaultDiagnosticBehavior();
3231+
witness->getInnermostDeclContext()).defaultDiagnosticBehavior();
32313232
}
32323233

32333234
// Complain that this witness cannot conform to the requirement due to

test/Concurrency/actor_isolation_unsafe.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ actor SomeGlobalActor {
2020
// Witnessing and unsafe global actor
2121
// ----------------------------------------------------------------------
2222
protocol P1 {
23-
@MainActor(unsafe) func onMainActor() // expected-note{{mark the protocol requirement 'onMainActor()' 'async' to allow actor-isolated conformances}}
24-
// expected-complete-tns-note @-1 {{mark the protocol requirement 'onMainActor()' 'async' to allow actor-isolated conformances}}
23+
@MainActor(unsafe) func onMainActor() // expected-note 2{{mark the protocol requirement 'onMainActor()' 'async' to allow actor-isolated conformances}}
2524
}
2625

2726
struct S1_P1: P1 {
@@ -36,9 +35,9 @@ struct S3_P1: P1 {
3635
nonisolated func onMainActor() { }
3736
}
3837

39-
struct S4_P1_quietly: P1 {
38+
struct S4_P1_not_quietly: P1 {
4039
@SomeGlobalActor func onMainActor() { }
41-
// expected-complete-tns-warning @-1 {{global actor 'SomeGlobalActor'-isolated instance method 'onMainActor()' cannot be used to satisfy main actor-isolated protocol requirement}}
40+
// expected-warning @-1 {{global actor 'SomeGlobalActor'-isolated instance method 'onMainActor()' cannot be used to satisfy main actor-isolated protocol requirement}}
4241
}
4342

4443
@SomeGlobalActor

test/decl/class/actor/global_actor_conformance.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %target-typecheck-verify-swift -disable-availability-checking -warn-concurrency
1+
// RUN: %target-typecheck-verify-swift -disable-availability-checking
2+
23
// REQUIRES: concurrency
34

45
actor SomeActor { }
@@ -42,3 +43,16 @@ class C1 : P1, P2 {
4243
@GenericGlobalActor<String> func asyncMethod2() async { }
4344
@GlobalActor func asyncMethod3() async { }
4445
}
46+
47+
protocol NonIsolatedRequirement {
48+
// expected-note@+1 {{mark the protocol requirement 'requirement()' 'async' to allow actor-isolated conformances}}
49+
func requirement()
50+
}
51+
52+
@MainActor class OnMain {}
53+
54+
extension OnMain: NonIsolatedRequirement {
55+
// expected-warning@+2 {{main actor-isolated instance method 'requirement()' cannot be used to satisfy nonisolated protocol requirement}}
56+
// expected-note@+1 {{add 'nonisolated' to 'requirement()' to make this instance method not isolated to the actor}}
57+
func requirement() {}
58+
}

0 commit comments

Comments
 (0)