Skip to content

Commit 6c911f5

Browse files
committed
[SIL] Add isolation captured by @_inheritActorContext(always) while lowering captures
`getLoweredLocalCaptures` seems the best place to do it because during Sema there is a chicken and an egg situation where isolation depends on captures and in this case captures depend on isolation.
1 parent a4f6d71 commit 6c911f5

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

lib/SIL/IR/TypeLowering.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4676,6 +4676,24 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
46764676

46774677
collectConstantCaptures(fn);
46784678

4679+
// @_inheritActorContext(always) attribute allows implicit
4680+
// capture of isolation parameter from the context. This
4681+
// cannot be done as part of computing captures because
4682+
// isolation is not available at that point because it in
4683+
// turn depends on captures sometimes.
4684+
if (auto *closure = fn.getClosureExpr()) {
4685+
if (closure->alwaysInheritsActorContext()) {
4686+
auto isolation = closure->getActorIsolation();
4687+
if (isolation.isActorInstanceIsolated()) {
4688+
if (auto *var = isolation.getActorInstance()) {
4689+
recordCapture(CapturedValue(var, /*flags=*/0, SourceLoc()));
4690+
} else if (auto *actorExpr = isolation.getActorInstanceExpr()) {
4691+
recordCapture(CapturedValue(actorExpr, /*flags=*/0));
4692+
}
4693+
}
4694+
}
4695+
}
4696+
46794697
SmallVector<CapturedValue, 4> resultingCaptures;
46804698
for (auto capturePair : varCaptures) {
46814699
resultingCaptures.push_back(capturePair.second);

test/SILGen/hop_to_executor.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ func testGlobalActorFuncValue(_ fn: @RedActor () -> Void) async {
324324
}
325325

326326
func acceptAsyncSendableClosureInheriting<T>(@_inheritActorContext _: @Sendable () async -> T) { }
327+
func acceptAsyncSendableClosureAlwaysInheriting<T>(@_inheritActorContext(always) _: @Sendable () async -> T) { }
327328

328329
extension MyActor {
329330
func synchronous() { }
@@ -338,6 +339,50 @@ extension MyActor {
338339
synchronous()
339340
}
340341
}
342+
343+
// CHECK-LABEL: sil private [ossa] @$s4test7MyActorC0A16AlwaysInheritingyyFyyYaYbXEfU_
344+
// CHECK: debug_value [[SELF:%[0-9]+]] : $MyActor
345+
// CHECK-NEXT: [[COPY:%[0-9]+]] = copy_value [[SELF]] : $MyActor
346+
// CHECK-NEXT: [[BORROW:%[0-9]+]] = begin_borrow [[COPY]] : $MyActor
347+
// CHECK-NEXT: hop_to_executor [[BORROW]] : $MyActor
348+
func testAlwaysInheriting() {
349+
acceptAsyncSendableClosureAlwaysInheriting {
350+
}
351+
}
352+
}
353+
354+
func testIsolatedParameterWithInheritActorContext(_ isolation: isolated (any Actor)?) {
355+
// CHECK-LABEL: sil private [ossa] @$s4test0A40IsolatedParameterWithInheritActorContextyyScA_pSgYiFyyYaYbXEfU_
356+
// CHECK: debug_value [[ISOLATION:%[0-9]+]] : $Optional<any Actor>
357+
// CHECK-NEXT: [[COPY:%[0-9]+]] = copy_value [[ISOLATION]] : $Optional<any Actor>
358+
// CHECK-NEXT: [[BORROW:%[0-9]+]] = begin_borrow [[COPY]] : $Optional<any Actor>
359+
// CHECK-NEXT: hop_to_executor [[BORROW]] : $Optional<any Actor>
360+
acceptAsyncSendableClosureAlwaysInheriting {
361+
}
362+
363+
// CHECK-LABEL: sil private [ossa] @$s4test0A40IsolatedParameterWithInheritActorContextyyScA_pSgYiFyyYaYbScMYcXEfU0_
364+
// CHECK: hop_to_executor {{.*}} : $MainActor
365+
acceptAsyncSendableClosureAlwaysInheriting { @MainActor in
366+
// CHECK-LABEL: sil private [ossa] @$s4test0A40IsolatedParameterWithInheritActorContextyyScA_pSgYiFyyYaYbScMYcXEfU0_yyYaYbXEfU_
367+
// CHECK: hop_to_executor {{.*}} : $MainActor
368+
acceptAsyncSendableClosureAlwaysInheriting {
369+
}
370+
}
371+
372+
// CHECK-LABEL: sil private [ossa] @$s4test0A40IsolatedParameterWithInheritActorContextyyScA_pSgYiFyyYaYbXEfU1_
373+
// CHECK: debug_value [[ISOLATION:%[0-9]+]] : $Optional<any Actor>
374+
// CHECK-NEXT: [[COPY:%[0-9]+]] = copy_value [[ISOLATION]] : $Optional<any Actor>
375+
// CHECK-NEXT: [[BORROW:%[0-9]+]] = begin_borrow [[COPY]] : $Optional<any Actor>
376+
// CHECK-NEXT: hop_to_executor [[BORROW]] : $Optional<any Actor>
377+
acceptAsyncSendableClosureAlwaysInheriting {
378+
// CHECK-LABEL: sil private [ossa] @$s4test0A40IsolatedParameterWithInheritActorContextyyScA_pSgYiFyyYaYbXEfU1_yyYaYbXEfU_
379+
// CHECK: debug_value [[ISOLATION:%[0-9]+]] : $Optional<any Actor>
380+
// CHECK-NEXT: [[COPY:%[0-9]+]] = copy_value [[ISOLATION]] : $Optional<any Actor>
381+
// CHECK-NEXT: [[BORROW:%[0-9]+]] = begin_borrow [[COPY]] : $Optional<any Actor>
382+
// CHECK-NEXT: hop_to_executor [[BORROW]] : $Optional<any Actor>
383+
acceptAsyncSendableClosureAlwaysInheriting {
384+
}
385+
}
341386
}
342387

343388
func acceptAsyncClosure(_: () async -> Void) { }

0 commit comments

Comments
 (0)