Skip to content

Commit bfffb9d

Browse files
committed
Sema: Expand isolated conformance inference to consider conformances to inherited protocols
Otherwise, if PDerived inherits from P and P's requirements are witnessed by @MainActor-isolated members, we fail to infer @mainactor isolation on the conformance to PDerived. - Fixes #82222. - Fixes rdar://153219831.
1 parent 25c2359 commit bfffb9d

5 files changed

+35
-5
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8239,16 +8239,28 @@ ActorIsolation swift::inferConformanceIsolation(
82398239
return nominalIsolation;
82408240
}
82418241

8242-
bool anyIsolatedWitness = false;
82438242
auto protocol = conformance->getProtocol();
8244-
for (auto requirement : protocol->getMembers()) {
8245-
if (isa<TypeDecl>(requirement))
8243+
8244+
// Also check the value witnesses of each implied conformance to every
8245+
// inherited protocol, recursively.
8246+
for (auto req : protocol->getRequirementSignature().getRequirements()) {
8247+
if (req.getKind() != RequirementKind::Conformance ||
8248+
!req.getFirstType()->isEqual(ctx.TheSelfType))
82468249
continue;
82478250

8248-
auto valueReq = dyn_cast<ValueDecl>(requirement);
8249-
if (!valueReq)
8251+
auto *assocConf = conformance->getAssociatedConformance(
8252+
req.getFirstType(), req.getProtocolDecl()).getConcrete();
8253+
auto isolation = assocConf->getIsolation();
8254+
if (isolation.isGlobalActor())
8255+
return isolation;
8256+
}
8257+
8258+
bool anyIsolatedWitness = false;
8259+
for (auto requirement : protocol->getProtocolRequirements()) {
8260+
if (isa<TypeDecl>(requirement))
82508261
continue;
82518262

8263+
auto valueReq = cast<ValueDecl>(requirement);
82528264
auto witness = conformance->getWitnessDecl(valueReq);
82538265
if (!witness)
82548266
continue;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
public protocol P {
2+
func f()
3+
}
4+
5+
public protocol PDerived: P {}

test/Concurrency/isolated_conformance_default_actor.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.1-abi-triple -swift-version 6 -default-isolation MainActor %s
22

33
// REQUIRES: concurrency
4+
// REQUIRES: swift_feature_InferIsolatedConformances
45

56
nonisolated
67
protocol P {

test/Concurrency/isolated_conformance_inference.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,7 @@ class InferMeDefaults {
9292
var someGlobalActorState: any P2.Type = DifferingConformances.self // expected-error{{global actor 'SomeGlobalActor'-isolated default value in a main actor-isolated context}}
9393
var bothState: any (P & P2).Type = DifferingConformances.self // expected-error{{default argument cannot be both main actor-isolated and global actor 'SomeGlobalActor'-isolated}}
9494
}
95+
96+
protocol PDerived: P {}
97+
98+
@MainActor struct ImpliedConformanceInference: PDerived { func f() {} }
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/isolated_conformance_other.swiftmodule %S/Inputs/isolated_conformance_other.swift -swift-version 6
3+
// RUN: %target-typecheck-verify-swift -I %t -swift-version 6 -enable-upcoming-feature InferIsolatedConformances -default-isolation MainActor -swift-version 6
4+
5+
import isolated_conformance_other
6+
7+
struct S1: P { func f() {} }
8+
struct S2: PDerived { func f() {} }

0 commit comments

Comments
 (0)