Skip to content

Commit 5143a40

Browse files
committed
[Concurrency] Make sure to still infer global actor if the conformance kind is explicit.
1 parent 1bfe5e9 commit 5143a40

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5209,7 +5209,10 @@ getIsolationFromConformances(NominalTypeDecl *nominal) {
52095209
llvm_unreachable("protocol cannot have erased isolation");
52105210

52115211
case ActorIsolation::GlobalActor:
5212-
if (!foundIsolation) {
5212+
// If we encountered an explicit globally isolated conformance, allow it
5213+
// to override the nonisolated isolation kind.
5214+
if (!foundIsolation ||
5215+
conformance->getSourceKind() == ConformanceEntryKind::Explicit) {
52135216
foundIsolation = {
52145217
protoIsolation,
52155218
IsolationSource(proto, IsolationSource::Conformance)

test/Concurrency/nonisolated_rules.swift

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ nonisolated struct S1: GloballyIsolated {
100100
// MARK: - Protocols
101101

102102
nonisolated protocol Refined: GloballyIsolated {}
103+
nonisolated protocol WhyNot {}
103104

104105
struct A: Refined {
105106
var x: NonSendable
@@ -116,12 +117,30 @@ struct A: Refined {
116117

117118
@MainActor protocol ExplicitGlobalActor: Refined {}
118119

119-
struct IsolatedStruct: ExplicitGlobalActor {
120+
struct IsolatedA: ExplicitGlobalActor {
120121
// expected-note@+2 {{main actor isolation inferred from conformance to protocol 'ExplicitGlobalActor'}}
121122
// expected-note@+1 {{calls to instance method 'g()' from outside of its actor context are implicitly asynchronous}}
122123
func g() {}
123124
}
124125

126+
struct IsolatedB: Refined, ExplicitGlobalActor {
127+
// expected-note@+2 {{calls to instance method 'h()' from outside of its actor context are implicitly asynchronous}}
128+
// expected-note@+1 {{main actor isolation inferred from conformance to protocol 'ExplicitGlobalActor'}}
129+
func h() {}
130+
}
131+
132+
struct IsolatedC: WhyNot, GloballyIsolated {
133+
// expected-note@+2 {{calls to instance method 'k()' from outside of its actor context are implicitly asynchronous}}
134+
// expected-note@+1 {{main actor isolation inferred from conformance to protocol 'GloballyIsolated'}}
135+
func k() {}
136+
}
137+
138+
struct IsolatedCFlipped: GloballyIsolated, WhyNot {
139+
// expected-note@+2 {{calls to instance method 'k2()' from outside of its actor context are implicitly asynchronous}}
140+
// expected-note@+1 {{main actor isolation inferred from conformance to protocol 'GloballyIsolated'}}
141+
func k2() {}
142+
}
143+
125144
struct NonisolatedStruct {
126145
func callF() {
127146
return A().f() // okay, 'A' is non-isolated.
@@ -130,7 +149,25 @@ struct NonisolatedStruct {
130149
// expected-note@+1 {{add '@MainActor' to make instance method 'callG()' part of global actor 'MainActor'}}
131150
func callG() {
132151
// expected-error@+1{{call to main actor-isolated instance method 'g()' in a synchronous nonisolated context}}
133-
return IsolatedStruct().g()
152+
return IsolatedA().g()
153+
}
154+
155+
// expected-note@+1 {{add '@MainActor' to make instance method 'callH()' part of global actor 'MainActor'}}
156+
func callH() {
157+
// expected-error@+1 {{call to main actor-isolated instance method 'h()' in a synchronous nonisolated context}}
158+
return IsolatedB().h()
159+
}
160+
161+
// expected-note@+1 {{add '@MainActor' to make instance method 'callK()' part of global actor 'MainActor'}}
162+
func callK() {
163+
// expected-error@+1 {{call to main actor-isolated instance method 'k()' in a synchronous nonisolated context}}
164+
return IsolatedC().k()
165+
}
166+
167+
// expected-note@+1 {{add '@MainActor' to make instance method 'callK2()' part of global actor 'MainActor'}}
168+
func callK2() {
169+
// expected-error@+1 {{call to main actor-isolated instance method 'k2()' in a synchronous nonisolated context}}
170+
return IsolatedCFlipped().k2()
134171
}
135172
}
136173

0 commit comments

Comments
 (0)