Skip to content

Commit 01b2789

Browse files
committed
Do not infer conformance isolation to an isolated protocol
1 parent c7fd48a commit 01b2789

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7918,6 +7918,11 @@ ConformanceIsolationRequest::evaluate(Evaluator &evaluator, ProtocolConformance
79187918
if (!ctx.LangOpts.hasFeature(Feature::IsolatedConformances))
79197919
return ActorIsolation::forNonisolated(false);
79207920

7921+
// If the protocol itself is isolated, don't infer isolation for the
7922+
// conformance.
7923+
if (getActorIsolation(rootNormal->getProtocol()).isActorIsolated())
7924+
return ActorIsolation::forNonisolated(false);
7925+
79217926
// In a context where we are inferring @MainActor, if the conforming type
79227927
// is on the main actor, then the conformance is, too.
79237928
auto nominal = dc->getSelfNominalTypeDecl();

test/Concurrency/isolated_conformance_default_actor.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ protocol P {
99
func f() // expected-note{{mark the protocol requirement 'f()' 'async' to allow actor-isolated conformances}}
1010
}
1111

12+
@MainActor
13+
protocol Q {
14+
func g()
15+
}
16+
1217
class CImplicitMainActorNonisolatedConformance: nonisolated P {
1318
func f() { } // error: explicitly nonisolated conformance
1419
}
@@ -23,18 +28,32 @@ class CImplicitMainActor: P {
2328
func f() { } // okay! conformance above is isolated
2429
}
2530

31+
// If the protocol itself is isolated, don't do anything.
32+
extension CExplicitMainActor: Q {
33+
func g() { }
34+
}
35+
36+
extension CImplicitMainActor: Q {
37+
func g() { }
38+
}
39+
2640
// expected-note@+2{{add '@preconcurrency' to the 'P' conformance to defer isolation checking to run time}}
2741
// expected-note@+1{{add '@MainActor' to the 'P' conformance to restrict it to main actor-isolated code}}
2842
nonisolated class CNonIsolated: P {
2943
@MainActor func f() { } // expected-error{{main actor-isolated instance method 'f()' cannot be used to satisfy nonisolated requirement from protocol 'P'}}
3044
}
3145

3246
func acceptSendablePMeta<T: Sendable & P>(_: T.Type) { }
47+
func acceptSendableQMeta<T: Sendable & Q>(_: T.Type) { }
3348

3449
nonisolated func testConformancesFromNonisolated() {
3550
let _: any P = CExplicitMainActor() // expected-error{{main actor-isolated conformance of 'CExplicitMainActor' to 'P' cannot be used in nonisolated context}}
3651
let _: any P = CImplicitMainActor() // expected-error{{main actor-isolated conformance of 'CImplicitMainActor' to 'P' cannot be used in nonisolated context}}
3752

3853
let _: any P = CNonIsolated()
3954
let _: any P = CImplicitMainActorNonisolatedConformance()
55+
56+
// Okay, these are nonisolated conformances.
57+
let _: any Q = CExplicitMainActor()
58+
let _: any Q = CImplicitMainActor()
4059
}

0 commit comments

Comments
 (0)