Skip to content

Commit a9819a6

Browse files
authored
Merge pull request #82383 from slavapestov/implied-isolated-conformance
Sema: Expand isolated conformance inference to consider conformances to inherited protocols
2 parents 897e14a + b0b23a0 commit a9819a6

File tree

4 files changed

+35
-5
lines changed

4 files changed

+35
-5
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8227,16 +8227,28 @@ ActorIsolation swift::inferConformanceIsolation(
82278227
return nominalIsolation;
82288228
}
82298229

8230-
bool anyIsolatedWitness = false;
82318230
auto protocol = conformance->getProtocol();
8232-
for (auto requirement : protocol->getMembers()) {
8233-
if (isa<TypeDecl>(requirement))
8231+
8232+
// Also check the value witnesses of each implied conformance to every
8233+
// inherited protocol, recursively.
8234+
for (auto req : protocol->getRequirementSignature().getRequirements()) {
8235+
if (req.getKind() != RequirementKind::Conformance ||
8236+
!req.getFirstType()->isEqual(ctx.TheSelfType))
82348237
continue;
82358238

8236-
auto valueReq = dyn_cast<ValueDecl>(requirement);
8237-
if (!valueReq)
8239+
auto *assocConf = conformance->getAssociatedConformance(
8240+
req.getFirstType(), req.getProtocolDecl()).getConcrete();
8241+
auto isolation = assocConf->getIsolation();
8242+
if (isolation.isGlobalActor())
8243+
return isolation;
8244+
}
8245+
8246+
bool anyIsolatedWitness = false;
8247+
for (auto requirement : protocol->getProtocolRequirements()) {
8248+
if (isa<TypeDecl>(requirement))
82388249
continue;
82398250

8251+
auto valueReq = cast<ValueDecl>(requirement);
82408252
auto witness = conformance->getWitnessDecl(valueReq);
82418253
if (!witness)
82428254
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_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: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
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+
// REQUIRES: swift_feature_InferIsolatedConformances
5+
6+
import isolated_conformance_other
7+
8+
struct S1: P { func f() {} }
9+
struct S2: PDerived { func f() {} }

0 commit comments

Comments
 (0)