Skip to content

Commit 42d0e4d

Browse files
authored
Merge pull request #40092 from DougGregor/closure-isolated-param-isolation
Isolate closures to their 'isolated' parameters.
2 parents 8ed71f0 + f4ac02f commit 42d0e4d

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,6 +2611,13 @@ namespace {
26112611
return ClosureActorIsolation::forGlobalActor(globalActorType);
26122612
}
26132613

2614+
// If a closure has an isolated parameter, it is isolated to that
2615+
// parameter.
2616+
for (auto param : *closure->getParameters()) {
2617+
if (param->isIsolated())
2618+
return ClosureActorIsolation::forActorInstance(param);
2619+
}
2620+
26142621
// Sendable closures are actor-independent unless the closure has
26152622
// specifically opted into inheriting actor isolation.
26162623
if (isSendableClosure(closure, /*forActorIsolation=*/true))

test/Concurrency/isolated_parameters.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,19 @@ func testExistentialIsolated(a: isolated P2, b: P2) async {
144144
b.m() // expected-error{{expression is 'async' but is not marked with 'await'}}
145145
// expected-note@-1{{calls to instance method 'm()' from outside of its actor context are implicitly asynchronous}}
146146
}
147+
148+
// "isolated" parameters of closures make the closure itself isolated.
149+
extension TestActor {
150+
func isolatedMethod() { }
151+
}
152+
153+
@available(SwiftStdlib 5.1, *)
154+
func isolatedClosures() {
155+
let _: (isolated TestActor) -> Void = { (ta: isolated TestActor) in
156+
ta.isolatedMethod() // okay, isolated to ta
157+
158+
_ = {
159+
ta.isolatedMethod() // okay, isolated to ta
160+
}
161+
}
162+
}

0 commit comments

Comments
 (0)