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 https://github.com/swiftlang/swift/issues/82222.
- Fixes rdar://153219831.
This commit is contained in:
Slava Pestov
2025-06-20 14:26:42 -04:00
parent 19af3bc295
commit b0b23a070b
4 changed files with 36 additions and 6 deletions

View File

@@ -8155,16 +8155,28 @@ ActorIsolation swift::inferConformanceIsolation(
return nominalIsolation;
}
bool anyIsolatedWitness = false;
auto protocol = conformance->getProtocol();
for (auto requirement : protocol->getMembers()) {
// Also check the value witnesses of each implied conformance to every
// inherited protocol, recursively.
for (auto req : protocol->getRequirementSignature().getRequirements()) {
if (req.getKind() != RequirementKind::Conformance ||
!req.getFirstType()->isEqual(ctx.TheSelfType))
continue;
auto *assocConf = conformance->getAssociatedConformance(
req.getFirstType(), req.getProtocolDecl()).getConcrete();
auto isolation = assocConf->getIsolation();
if (isolation.isGlobalActor())
return isolation;
}
bool anyIsolatedWitness = false;
for (auto requirement : protocol->getProtocolRequirements()) {
if (isa<TypeDecl>(requirement))
continue;
auto valueReq = dyn_cast<ValueDecl>(requirement);
if (!valueReq)
continue;
auto valueReq = cast<ValueDecl>(requirement);
auto witness = conformance->getWitnessDecl(valueReq);
if (!witness)
continue;

View File

@@ -0,0 +1,5 @@
public protocol P {
func f()
}
public protocol PDerived: P {}

View File

@@ -92,3 +92,7 @@ class InferMeDefaults {
var someGlobalActorState: any P2.Type = DifferingConformances.self // expected-error{{global actor 'SomeGlobalActor'-isolated default value in a main actor-isolated context}}
var bothState: any (P & P2).Type = DifferingConformances.self // expected-error{{default argument cannot be both main actor-isolated and global actor 'SomeGlobalActor'-isolated}}
}
protocol PDerived: P {}
@MainActor struct ImpliedConformanceInference: PDerived { func f() {} }

View File

@@ -0,0 +1,9 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/isolated_conformance_other.swiftmodule %S/Inputs/isolated_conformance_other.swift -swift-version 6
// RUN: %target-typecheck-verify-swift -I %t -swift-version 6 -enable-upcoming-feature InferIsolatedConformances -default-isolation MainActor -swift-version 6
// REQUIRES: swift_feature_InferIsolatedConformances
import isolated_conformance_other
struct S1: P { func f() {} }
struct S2: PDerived { func f() {} }