@@ -263,15 +263,6 @@ public func testConcurrentCallerLocalVariables(_ x: @escaping @concurrent () asy
263263
264264// CHECK: } // end sil function '$s21attr_execution_silgen22globalActorConversionsyyyyYac_yyYaYCctYaF'
265265
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-
275266// 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>) -> ()) -> () {
276267// SIX: bb0([[FUNC:%.*]] : $@convention(thin) @async (@sil_isolated
277268// SIX: [[ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
@@ -515,7 +506,7 @@ func conversionsFromSyncToAsync(_ x: @escaping @Sendable (NonSendableKlass) -> V
515506}
516507
517508func 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>) -> () {
519510 // CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>):
520511 // CHECK: hop_to_executor [[EXECUTOR]]
521512 let _: nonisolated( nonsending ) ( ) async -> Void = {
@@ -524,31 +515,24 @@ func testThatClosuresAssumeIsolation(fn: inout nonisolated(nonsending) (Int) asy
524515
525516 func testParam( _: nonisolated( nonsending ) ( ) async throws -> Void ) { }
526517
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 {
528519 // CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>):
529520 // 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 }
531523
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 }
538528
539529 // 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 {
540530 // CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[FUNC:%.*]] : @guaranteed $@noescape @async @callee_guaranteed () -> ()):
541531 // CHECK: apply [[FUNC]]()
542532 // CHECK: hop_to_executor [[ACTOR]]
543533 // CHECK: } // end sil function '$sIgH_ScA_pSgs5Error_pIegHgILzo_TR'
544- testParam { 42 }
545534
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) -> () {
552536 // CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>, %1 : $Int):
553537 // CHECK: hop_to_executor [[EXECUTOR]]
554538 fn = { _ in }
@@ -588,3 +572,44 @@ func testClosuresDontAssumeGlobalActorWithMarkedAsConcurrent() {
588572 test { @Sendable @concurrent in
589573 }
590574}
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