Skip to content

Commit 06d1224

Browse files
committed
[Concurrency] SE-0449: nonisolated on a type should prevent isolation inference from protocol requirements
If a `nonisolated` type conforms to a global-isolated protocol the witnesses to the protocol requirements should infer the isolation from the protocol but instead be `nonisolated`. Resolves: rdar://145519840 (cherry picked from commit e50acbf)
1 parent 7d0e2b5 commit 06d1224

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5148,6 +5148,13 @@ getIsolationFromWitnessedRequirements(ValueDecl *value) {
51485148
if (dc->getSelfProtocolDecl())
51495149
return std::nullopt;
51505150

5151+
// Prevent isolation inference from requirements if the conforming type
5152+
// has an explicit `nonisolated` attribute.
5153+
if (auto *NTD = dc->getSelfNominalTypeDecl()) {
5154+
if (NTD->getAttrs().hasAttribute<NonisolatedAttr>())
5155+
return std::nullopt;
5156+
}
5157+
51515158
// Walk through each of the conformances in this context, collecting any
51525159
// requirements that have actor isolation.
51535160
auto conformances = idc->getLocalConformances( // note this

test/Concurrency/nonisolated_rules.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,34 @@ nonisolated class K: GloballyIsolated {
242242
}
243243
}
244244

245+
@MainActor
246+
protocol GloballyIsolatedWithRequirements {
247+
var x: NonSendable { get set } // expected-note {{property declared here}}
248+
func test() // expected-note {{calls to instance method 'test()' from outside of its actor context are implicitly asynchronous}}
249+
}
250+
251+
nonisolated class K2: GloballyIsolatedWithRequirements {
252+
var x: NonSendable
253+
254+
func test() {}
255+
256+
func testNonWitness() {}
257+
258+
init(x: NonSendable) {
259+
self.x = x // okay
260+
test() // okay
261+
testNonWitness() // okay
262+
}
263+
264+
func test<T: GloballyIsolatedWithRequirements>(t: T, s: K2) {
265+
_ = s.x // okay
266+
_ = t.x // expected-error {{main actor-isolated property 'x' can not be referenced from a nonisolated context}}
267+
268+
s.test() // okay
269+
t.test() // expected-error {{call to main actor-isolated instance method 'test()' in a synchronous nonisolated context}}
270+
}
271+
}
272+
245273
// MARK: - Storage of non-Sendable
246274

247275
class KlassA {

0 commit comments

Comments
 (0)