// RUN: %target-swift-frontend -parse-as-library -emit-sil %s -module-name test | %FileCheck %s // REQUIRES: concurrency nonisolated(nonsending) func nonisolatedNonsending() async { let iso = #isolation take(iso: iso) } func take(iso: (any Actor)?) {} func takeDefaulted(iso: isolated (any Actor)? = #isolation) {} // CHECK-LABEL: // nonisolatedNonsending() // CHECK-NEXT: // Isolation: caller_isolation_inheriting // CHECK-NEXT: sil hidden @$s4test21nonisolatedNonsendingyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> () { // CHECK: bb0([[IMPLICIT_ACTOR:%.*]] : $Builtin.ImplicitActor): // CHECK: [[ACTOR:%.*]] = implicitactor_to_opaqueisolation_cast [[IMPLICIT_ACTOR]] // CHECK: retain_value [[ACTOR]] // CHECK: debug_value [[ACTOR]], let, name "iso" // CHECK: [[FUNC:%.*]] = function_ref @$s4test4take3isoyScA_pSg_tF : $@convention(thin) (@guaranteed Optional) -> () // CHECK: apply [[FUNC]]([[ACTOR]]) : $@convention(thin) (@guaranteed Optional) -> () // CHECK: release_value [[ACTOR]] // CHECK: } // end sil function '$s4test21nonisolatedNonsendingyyYaF' // Check that we emit #isolation correctly in closures. // CHECK-LABEL: // closure #1 in containsClosure() // CHECK-NEXT: // Isolation: caller_isolation_inheriting // CHECK-LABEL: sil private @$s4test15containsClosureyyFyyYaYCcfU_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> () { // CHECK: bb0(%0 : $Builtin.ImplicitActor): // CHECK: [[ACTOR:%.*]] = implicitactor_to_opaqueisolation_cast %0 // CHECK-NEXT: // function_ref take(iso:) // CHECK-NEXT: [[FN:%.*]] = function_ref @ // CHECK-NEXT: apply [[FN]]([[ACTOR]]) // CHECK: } // end sil function '$s4test15containsClosureyyFyyYaYCcfU_' func containsClosure() { let closure: nonisolated(nonsending) () async -> Void = { take(iso: #isolation) } } // Check that we capture variables as necessary to emit #isolation // correctly in defer bodies. func deferWithIsolatedParam(_ iso: isolated (any Actor)) { defer { take(iso: #isolation) } do {} } // CHECK-LABEL: sil hidden @$s4test22deferWithIsolatedParamyyScA_pYiF : // CHECK: bb0(%0 : $any Actor) // CHECK: [[DEFER:%.*]] = function_ref @$s4test22deferWithIsolatedParamyyScA_pYiF6$deferL_yyF : // CHECK-NEXT: apply [[DEFER]](%0) // CHECK: } // end sil function '$s4test22deferWithIsolatedParamyyScA_pYiF' // CHECK-LABEL: sil private @$s4test22deferWithIsolatedParamyyScA_pYiF6$deferL_yyF : // CHECK: bb0(%0 : @closureCapture $any Actor): // CHECK: [[T0:%.*]] = enum $Optional, #Optional.some!enumelt, %0 // CHECK: [[FN:%.*]] = function_ref @$s4test4take3isoyScA_pSg_tF : // CHECK-NEXT: apply [[FN]]([[T0]]) // CHECK: } // end sil function '$s4test22deferWithIsolatedParamyyScA_pYiF6$deferL_yyF' // Check that that happens even with uses in caller-side default // arguments, which capture analysis was not previously walking into. func deferWithIsolatedParam_defaultedUse(_ iso: isolated (any Actor)) { defer { takeDefaulted() } do {} } // CHECK-LABEL: sil hidden @$s4test35deferWithIsolatedParam_defaultedUseyyScA_pYiF : // CHECK: bb0(%0 : $any Actor): // CHECK: [[DEFER:%.*]] = function_ref @$s4test35deferWithIsolatedParam_defaultedUseyyScA_pYiF6$deferL_yyF : // CHECK-NEXT: apply [[DEFER]](%0) // CHECK: } // end sil function '$s4test35deferWithIsolatedParam_defaultedUseyyScA_pYiF' // CHECK-LABEL: sil private @$s4test35deferWithIsolatedParam_defaultedUseyyScA_pYiF6$deferL_yyF : // CHECK: bb0(%0 : @closureCapture $any Actor): // CHECK: [[T0:%.*]] = enum $Optional, #Optional.some!enumelt, %0 // CHECK: [[FN:%.*]] = function_ref @$s4test13takeDefaulted3isoyScA_pSgYi_tF : // CHECK-NEXT: apply [[FN]]([[T0]]) // CHECK: } // end sil function '$s4test35deferWithIsolatedParam_defaultedUseyyScA_pYiF6$deferL_yyF' // TODO: we can't currently call nonisolated(nonsending) functions in // defer bodies because they have to be async, but that should be // tested here as well. // Check that we emit #isolation correctly in defer bodies. nonisolated(nonsending) func hasDefer() async { defer { take(iso: #isolation) } do {} } // CHECK-LABEL: sil hidden @$s4test8hasDeferyyYaF : // CHECK: bb0(%0 : $Builtin.ImplicitActor): // CHECK: // function_ref $defer // CHECK-NEXT: [[DEFER:%.*]] = function_ref // CHECK-NEXT: apply [[DEFER]](%0) // CHECK: } // end sil function '$s4test8hasDeferyyYaF' // CHECK-LABEL: // $defer #1 () in hasDefer() // CHECK-NEXT: // Isolation: caller_isolation_inheriting // CHECK: bb0(%0 : $Builtin.ImplicitActor): // CHECK-NEXT: [[ACTOR:%.*]] = implicitactor_to_opaqueisolation_cast %0 // CHECK-NEXT: // function_ref take(iso:) // CHECK-NEXT: [[FN:%.*]] = function_ref @ // CHECK-NEXT: apply [[FN]]([[ACTOR]]) // Check that we emit #isolation correctly in nested defer bodies. nonisolated(nonsending) func hasNestedDefer() async { defer { defer { take(iso: #isolation) } do {} } do {} } // CHECK-LABEL: sil hidden @$s4test14hasNestedDeferyyYaF : // CHECK: bb0(%0 : $Builtin.ImplicitActor): // CHECK: // function_ref $defer #1 () in hasNestedDefer() // CHECK-NEXT: [[DEFER:%.*]] = function_ref // CHECK-NEXT: apply [[DEFER]](%0) // CHECK: } // end sil function '$s4test14hasNestedDeferyyYaF' // CHECK-LABEL: // $defer #1 () in hasNestedDefer() // CHECK-NEXT: // Isolation: caller_isolation_inheriting // CHECK: bb0(%0 : $Builtin.ImplicitActor): // CHECK: // function_ref $defer #1 () in $defer #1 () in hasNestedDefer() // CHECK-NEXT: [[DEFER:%.*]] = function_ref // CHECK-NEXT: apply [[DEFER]](%0) // CHECK: } // end sil function '$s4test14hasNestedDeferyyYaF6$deferL_yyF' // CHECK-LABEL: // $defer #1 () in $defer #1 () in hasNestedDefer() // CHECK-NEXT: // Isolation: caller_isolation_inheriting // CHECK-NEXT: sil private @$s4test14hasNestedDeferyyYaF6$deferL_yyFACL_yyF : $@convention(thin) (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> () { // CHECK: bb0(%0 : $Builtin.ImplicitActor): // CHECK-NEXT: [[ACTOR:%.*]] = implicitactor_to_opaqueisolation_cast %0 // CHECK-NEXT: // function_ref take(iso:) // CHECK-NEXT: [[FN:%.*]] = function_ref @ // CHECK-NEXT: apply [[FN]]([[ACTOR]]) // CHECK: } // end sil function '$s4test14hasNestedDeferyyYaF6$deferL_yyFACL_yyF'