Skip to content

Commit b528658

Browse files
committed
[Concurrency] Diagnose actor-isolated witnesses to nonisolated protocol
requirements for explicitly isolated types under minimal checking.
1 parent 575514e commit b528658

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
@@ -4912,6 +4912,14 @@ bool swift::contextRequiresStrictConcurrencyChecking(
49124912
if (hasExplicitIsolationAttribute(decl))
49134913
return true;
49144914

4915+
// Extensions of explicitly isolated types are using concurrency
4916+
// features.
4917+
if (auto *extension = dyn_cast<ExtensionDecl>(decl)) {
4918+
auto *nominal = extension->getExtendedNominal();
4919+
if (nominal && hasExplicitIsolationAttribute(nominal))
4920+
return true;
4921+
}
4922+
49154923
if (auto func = dyn_cast<AbstractFunctionDecl>(decl)) {
49164924
// Async and concurrent functions use concurrency features.
49174925
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)