Skip to content

Commit b41a21a

Browse files
authored
Merge pull request #82465 from xedin/rdar-154202375
[Concurrency] Global actor isolated conformances are only allowed to …
2 parents 17ae36e + 2e1fe44 commit b41a21a

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5389,13 +5389,12 @@ getIsolationFromConformances(NominalTypeDecl *nominal) {
53895389

53905390
case ActorIsolation::GlobalActor:
53915391
// If we encountered an explicit globally isolated conformance, allow it
5392-
// to override the nonisolated isolation kind.
5392+
// to override the _nonisolated_ isolation.
53935393
if (!foundIsolation ||
5394-
conformance->getSourceKind() == ConformanceEntryKind::Explicit) {
5395-
foundIsolation = {
5396-
protoIsolation,
5397-
IsolationSource(proto, IsolationSource::Conformance)
5398-
};
5394+
(foundIsolation->isolation.isNonisolated() &&
5395+
conformance->getSourceKind() == ConformanceEntryKind::Explicit)) {
5396+
foundIsolation = {protoIsolation,
5397+
IsolationSource(proto, IsolationSource::Conformance)};
53995398
continue;
54005399
}
54015400

test/Concurrency/nonisolated_rules.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@
55
@MainActor
66
protocol GloballyIsolated {}
77

8+
@globalActor
9+
actor Test {
10+
static let shared: Test = Test()
11+
}
12+
13+
@Test
14+
protocol TestIsolatedProto {
15+
}
16+
17+
@Test
18+
protocol RedeclaredIsolationProto : GloballyIsolated {
19+
}
20+
821
// expected-note@+1 {{class 'NonSendable' does not conform to the 'Sendable' protocol}}
922
class NonSendable {}
1023

@@ -312,3 +325,25 @@ func rdar147965036() {
312325
// expected-error@-2 {{'nonisolated' is not supported on a closure}}
313326
}
314327
}
328+
329+
// Test that clash in isolation from protocols results in nonisolated conforming type
330+
func testProtocolIsolationClash() {
331+
struct A: GloballyIsolated, TestIsolatedProto {
332+
}
333+
334+
struct B: RedeclaredIsolationProto {
335+
}
336+
337+
struct C: GloballyIsolated, TestIsolatedProto, WhyNot {
338+
}
339+
340+
struct D: WhyNot, GloballyIsolated, TestIsolatedProto {
341+
}
342+
343+
nonisolated func test() {
344+
_ = A() // Ok
345+
_ = B() // Ok
346+
_ = C() // Ok
347+
_ = D() // Ok
348+
}
349+
}

0 commit comments

Comments
 (0)