@@ -263,15 +263,6 @@ public func testConcurrentCallerLocalVariables(_ x: @escaping @concurrent () asy
263
263
264
264
// CHECK: } // end sil function '$s21attr_execution_silgen22globalActorConversionsyyyyYac_yyYaYCctYaF'
265
265
266
- // FIVE-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sScA_pSgIegHgIL_IegH_TRScMTU : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> () {
267
- // FIVE: bb0([[FUNC:%.*]] : @guaranteed
268
- // FIVE: [[ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
269
- // FIVE: [[E:%.*]] = init_existential_ref [[ACTOR]] : $MainActor : $MainActor, $any Actor
270
- // FIVE: [[E_OPT:%.*]] = enum $Optional<any Actor>, #Optional.some!enumelt, [[E]]
271
- // FIVE: hop_to_executor [[E_OPT]]
272
- // FIVE: apply [[FUNC]]([[E_OPT]]) : $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
273
- // FIVE: } // end sil function '$sScA_pSgIegHgIL_IegH_TRScMTU'
274
-
275
266
// SIX-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sScA_pSgIetHgIL_IeghH_TRScMTU : $@convention(thin) @Sendable @async (@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> () {
276
267
// SIX: bb0([[FUNC:%.*]] : $@convention(thin) @async (@sil_isolated
277
268
// SIX: [[ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
@@ -515,7 +506,7 @@ func conversionsFromSyncToAsync(_ x: @escaping @Sendable (NonSendableKlass) -> V
515
506
}
516
507
517
508
func testThatClosuresAssumeIsolation( fn: inout nonisolated( nonsending ) ( Int ) async -> Void ) {
518
- // CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYacfU_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
509
+ // CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaYCcfU_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
519
510
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>):
520
511
// CHECK: hop_to_executor [[EXECUTOR]]
521
512
let _: nonisolated( nonsending ) ( ) async -> Void = {
@@ -524,31 +515,24 @@ func testThatClosuresAssumeIsolation(fn: inout nonisolated(nonsending) (Int) asy
524
515
525
516
func testParam( _: nonisolated( nonsending ) ( ) async throws -> Void ) { }
526
517
527
- // CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaXEfU0_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
518
+ // 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 {
528
519
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>):
529
520
// CHECK: hop_to_executor [[EXECUTOR]]
530
- // CHECK: } // end sil function '$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaXEfU0_'
521
+ // CHECK: } // end sil function '$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaYCXEfU0_'
522
+ testParam { 42 }
531
523
532
- // FIVE-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sScA_pSgIetHgIL_IegH_TR : $@convention(thin) @async (@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> () {
533
- // FIVE: bb0([[FUNC:%.*]] : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()):
534
- // FIVE: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
535
- // FIVE: hop_to_executor [[ACTOR]]
536
- // FIVE: apply [[FUNC]]([[ACTOR]])
537
- // FIVE: } // end sil function '$sScA_pSgIetHgIL_IegH_TR'
524
+ // CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaXEfU1_ : $@convention(thin) @async () -> ()
525
+ // CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
526
+ // CHECK: hop_to_executor [[GENERIC_EXECUTOR]]
527
+ testParam { @concurrent in 42 }
538
528
539
529
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIgH_ScA_pSgs5Error_pIegHgILzo_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed @noescape @async @callee_guaranteed () -> ()) -> @error any Error {
540
530
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[FUNC:%.*]] : @guaranteed $@noescape @async @callee_guaranteed () -> ()):
541
531
// CHECK: apply [[FUNC]]()
542
532
// CHECK: hop_to_executor [[ACTOR]]
543
533
// CHECK: } // end sil function '$sIgH_ScA_pSgs5Error_pIegHgILzo_TR'
544
- testParam { 42 }
545
534
546
- // CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaXEfU1_ : $@convention(thin) @async () -> ()
547
- // CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
548
- // CHECK: hop_to_executor [[GENERIC_EXECUTOR]]
549
- testParam { @concurrent in 42 }
550
-
551
- // CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFySiYacfU2_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, Int) -> () {
535
+ // CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFySiYaYCcfU2_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, Int) -> () {
552
536
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>, %1 : $Int):
553
537
// CHECK: hop_to_executor [[EXECUTOR]]
554
538
fn = { _ in }
@@ -588,3 +572,44 @@ func testClosuresDontAssumeGlobalActorWithMarkedAsConcurrent() {
588
572
test { @Sendable @concurrent in
589
573
}
590
574
}
575
+
576
+ nonisolated ( nonsending)
577
+ public func takesCallerIsolatedThrowingFunction< T> (
578
+ _ operation: nonisolated( nonsending ) ( ) async throws -> T
579
+ ) async rethrows -> T {
580
+ try await operation ( )
581
+ }
582
+
583
+ func observe( ) { }
584
+
585
+ // Test that we emit closures with nonisolated(nonsending) isolation without
586
+ // introducing an intermediate @concurrent closure function.
587
+ func testConvertToThrowing( isolation: isolated ( any Actor ) ? = #isolation) async {
588
+ // CHECK-LABEL: sil hidden [ossa] @$s21attr_execution_silgen21testConvertToThrowing9isolationyScA_pSgYi_tYaF :
589
+ // CHECK: [[ACTOR_COPY:%.*]] = copy_value %0
590
+ // CHECK-NEXT: [[ACTOR_BORROW:%.*]] = begin_borrow [[ACTOR_COPY]]
591
+ // CHECK-NEXT: hop_to_executor [[ACTOR_BORROW]]
592
+ // CHECK: [[CLOSURE:%.*]] = function_ref @$s21attr_execution_silgen21testConvertToThrowing9isolationyScA_pSgYi_tYaFyyYaYCXEfU_ :
593
+ // CHECK-NEXT: [[CLOSURE_VALUE:%.*]] = thin_to_thick_function [[CLOSURE]] to
594
+ // CHECK-NEXT: // function_ref
595
+ // CHECK-NEXT: [[FN:%.*]] = function_ref
596
+ // CHECK-NEXT: try_apply [[FN]]<()>({{%.*}}, {{%.*}}, [[CLOSURE_VALUE]]) {{.*}}, normal bb1, error bb2
597
+ // CHECK: bb1(
598
+ // This hop is unnecessary because nonisolated(nonsending) should
599
+ // preserve isolation on return.
600
+ // CHECK-NEXT: hop_to_executor [[ACTOR_BORROW]]
601
+
602
+ // CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen21testConvertToThrowing9isolationyScA_pSgYi_tYaFyyYaYCXEfU_ : $@convention(thin) @async @substituted <τ_0_0> (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> (@out τ_0_0, @error any Error) for <()>
603
+ // CHECK: bb0(
604
+ // CHECK-NEXT: debug_value
605
+ // This hop is unnecessary because nonisolated(nonsending) should
606
+ // ensure isolation before call.
607
+ // CHECK-NEXT: hop_to_executor %1
608
+ // CHECK-NEXT: // function_ref observe()
609
+ // CHECK-NEXT: [[FN:%.*]] = function_ref @$s21attr_execution_silgen7observeyyF :
610
+ // CHECK-NEXT: apply [[FN]]()
611
+
612
+ await takesCallerIsolatedThrowingFunction {
613
+ observe ( )
614
+ }
615
+ }
0 commit comments