Skip to content

Commit 7e42a19

Browse files
simanerushxedin
authored andcommitted
[Concurrency] Make sure to still infer global actor if the conformance kind is explicit.
1 parent 4fca62a commit 7e42a19

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
@@ -5282,7 +5282,10 @@ getIsolationFromConformances(NominalTypeDecl *nominal) {
52825282
llvm_unreachable("protocol cannot have erased isolation");
52835283

52845284
case ActorIsolation::GlobalActor:
5285-
if (!foundIsolation) {
5285+
// If we encountered an explicit globally isolated conformance, allow it
5286+
// to override the nonisolated isolation kind.
5287+
if (!foundIsolation ||
5288+
conformance->getSourceKind() == ConformanceEntryKind::Explicit) {
52865289
foundIsolation = {
52875290
protoIsolation,
52885291
IsolationSource(proto, IsolationSource::Conformance)

test/Concurrency/nonisolated_rules.swift

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

100100
nonisolated protocol Refined: GloballyIsolated {}
101+
nonisolated protocol WhyNot {}
101102

102103
struct A: Refined {
103104
var x: NonSendable
@@ -114,12 +115,30 @@ struct A: Refined {
114115

115116
@MainActor protocol ExplicitGlobalActor: Refined {}
116117

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

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

0 commit comments

Comments
 (0)