Skip to content

Commit 2eb61de

Browse files
authored
Merge pull request #74611 from hborla/6.0-isolation-from-superclass-requirement
[6.0][Concurrency] Infer protocol isolation from superclass requirements.
2 parents 4869496 + 505cd00 commit 2eb61de

File tree

2 files changed

+54
-7
lines changed

2 files changed

+54
-7
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4586,30 +4586,43 @@ getIsolationFromConformances(NominalTypeDecl *nominal) {
45864586
static std::optional<ActorIsolation>
45874587
getIsolationFromInheritedProtocols(ProtocolDecl *protocol) {
45884588
std::optional<ActorIsolation> foundIsolation;
4589-
for (auto inherited : protocol->getInheritedProtocols()) {
4590-
switch (auto protoIsolation = getActorIsolation(inherited)) {
4589+
bool conflict = false;
4590+
4591+
auto inferIsolation = [&](ValueDecl *decl) {
4592+
switch (auto protoIsolation = getActorIsolation(decl)) {
45914593
case ActorIsolation::ActorInstance:
45924594
case ActorIsolation::Unspecified:
45934595
case ActorIsolation::Nonisolated:
45944596
case ActorIsolation::NonisolatedUnsafe:
4595-
break;
4597+
return;
45964598

45974599
case ActorIsolation::Erased:
45984600
llvm_unreachable("protocol cannot have erased isolation");
45994601

46004602
case ActorIsolation::GlobalActor:
46014603
if (!foundIsolation) {
46024604
foundIsolation = protoIsolation;
4603-
continue;
4605+
return;
46044606
}
46054607

46064608
if (*foundIsolation != protoIsolation)
4607-
return std::nullopt;
4609+
conflict = true;
46084610

4609-
break;
4611+
return;
46104612
}
4613+
};
4614+
4615+
for (auto inherited : protocol->getInheritedProtocols()) {
4616+
inferIsolation(inherited);
46114617
}
46124618

4619+
if (auto *superclass = protocol->getSuperclassDecl()) {
4620+
inferIsolation(superclass);
4621+
}
4622+
4623+
if (conflict)
4624+
return std::nullopt;
4625+
46134626
return foundIsolation;
46144627
}
46154628

test/Concurrency/global_actor_inference_swift6.swift

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// RUN: %target-swift-frontend -swift-version 6 -emit-module -emit-module-path %t/other_global_actor_inference.swiftmodule -module-name other_global_actor_inference -strict-concurrency=complete %S/Inputs/other_global_actor_inference.swift
44

5-
// RUN: %target-swift-frontend -swift-version 6 -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -enable-upcoming-feature GlobalActorIsolatedTypesUsability
5+
// RUN: %target-swift-frontend -swift-version 6 -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify
66

77
// REQUIRES: concurrency
88

@@ -179,3 +179,37 @@ extension S3 {
179179
// expected-error@-1{{global actor 'SomeGlobalActor'-isolated instance method 'f()' cannot be used to satisfy main actor-isolated protocol requirement}}
180180
//expected-note@-2{{add 'nonisolated' to 'f()' to make this instance method not isolated to the actor}}
181181
}
182+
183+
@MainActor
184+
func onMain() {}
185+
186+
@MainActor
187+
class MainActorSuperclass {}
188+
189+
protocol InferMainFromSuperclass: MainActorSuperclass {
190+
func f()
191+
}
192+
193+
class C1: MainActorSuperclass, InferMainFromSuperclass {
194+
func f() {
195+
onMain() // okay
196+
}
197+
}
198+
199+
protocol InferenceConflictWithSuperclass: MainActorSuperclass, InferSomeGlobalActor {
200+
func g()
201+
// expected-note@-1 {{mark the protocol requirement 'g()' 'async' to allow actor-isolated conformances}}
202+
}
203+
204+
205+
class C2: MainActorSuperclass, InferenceConflictWithSuperclass {
206+
//expected-note@-1 {{add '@preconcurrency' to the 'InferenceConflictWithSuperclass' conformance to defer isolation checking to run time}}
207+
208+
func f() {}
209+
210+
func g() {}
211+
// expected-error@-1 {{main actor-isolated instance method 'g()' cannot be used to satisfy nonisolated protocol requirement}}
212+
// expected-note@-2 {{add 'nonisolated' to 'g()' to make this instance method not isolated to the actor}}
213+
}
214+
215+

0 commit comments

Comments
 (0)