mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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:
@@ -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;
|
||||
|
||||
5
test/Concurrency/Inputs/isolated_conformance_other.swift
Normal file
5
test/Concurrency/Inputs/isolated_conformance_other.swift
Normal file
@@ -0,0 +1,5 @@
|
||||
public protocol P {
|
||||
func f()
|
||||
}
|
||||
|
||||
public protocol PDerived: P {}
|
||||
@@ -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() {} }
|
||||
|
||||
@@ -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() {} }
|
||||
Reference in New Issue
Block a user