Skip to content

Commit bb62e96

Browse files
committed
[SILGen] Concurrency: Fix caller isolated closures to hop to the right actor
Closures that are caller isolated used to still hop to the generic executor, which is incorrect.
1 parent 3de72c5 commit bb62e96

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

lib/SILGen/SILGenConcurrency.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,10 +206,14 @@ void SILGenFunction::emitExpectedExecutorProlog() {
206206
switch (actorIsolation.getKind()) {
207207
case ActorIsolation::Unspecified:
208208
case ActorIsolation::Nonisolated:
209-
case ActorIsolation::CallerIsolationInheriting:
210209
case ActorIsolation::NonisolatedUnsafe:
211210
break;
212211

212+
case ActorIsolation::CallerIsolationInheriting:
213+
assert(F.isAsync());
214+
setExpectedExecutorForParameterIsolation(*this, actorIsolation);
215+
break;
216+
213217
case ActorIsolation::Erased:
214218
llvm_unreachable("closure cannot have erased isolation");
215219

test/Concurrency/attr_execution/conversions_silgen.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,21 +428,31 @@ func conversionsFromSyncToAsync(_ x: @escaping @Sendable (NonSendableKlass) -> V
428428

429429
func testThatClosuresAssumeIsolation(fn: inout nonisolated(nonsending) (Int) async -> Void) {
430430
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaYCcfU_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
431+
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>):
432+
// CHECK: hop_to_executor [[EXECUTOR]]
431433
let _: nonisolated(nonsending) () async -> Void = {
432434
42
433435
}
434436

435437
func testParam(_: nonisolated(nonsending) () async throws -> Void) {}
436438

437439
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaYCXEfU0_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> @error any Error
440+
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>):
441+
// CHECK: hop_to_executor [[EXECUTOR]]
438442
testParam { 42 }
439443

440444
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaXEfU1_ : $@convention(thin) @async () -> ()
445+
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
446+
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]]
441447
testParam { @concurrent in 42 }
442448

443449
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFySiYaYCcfU2_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, Int) -> ()
450+
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>, %1 : $Int):
451+
// CHECK: hop_to_executor [[EXECUTOR]]
444452
fn = { _ in }
445453

446454
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFySiYacfU3_ : $@convention(thin) @async (Int) -> ()
455+
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
456+
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]]
447457
fn = { @concurrent _ in }
448458
}

0 commit comments

Comments
 (0)