mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Isolation boundary closures don't assume parent isolation and should be able to get `nonisolated(nonsending)` transferred to them jus like regular nonisolated closures do. Resolves: rdar://163792371
688 lines
52 KiB
Swift
688 lines
52 KiB
Swift
// RUN: %target-swift-emit-silgen %s -module-name attr_execution_silgen -target %target-swift-5.1-abi-triple -DSWIFT_FIVE | %FileCheck -check-prefix CHECK -check-prefix FIVE %s
|
|
// RUN: %target-swift-emit-silgen %s -swift-version 6 -module-name attr_execution_silgen -target %target-swift-5.1-abi-triple | %FileCheck -check-prefix CHECK -check-prefix SIX %s
|
|
|
|
// We codegen slightly differently for swift 5 vs swift 6, so we need to check
|
|
// both.
|
|
|
|
// REQUIRES: asserts
|
|
// REQUIRES: concurrency
|
|
|
|
////////////////////////
|
|
// MARK: Declarations //
|
|
////////////////////////
|
|
|
|
nonisolated(nonsending)
|
|
func globalCallerFunc() async -> () {}
|
|
|
|
@concurrent
|
|
func globalConcurrentFunc() async -> () {}
|
|
|
|
class NonSendableKlass {
|
|
init() {}
|
|
}
|
|
class SendableKlass : @unchecked Sendable {
|
|
init() {}
|
|
}
|
|
|
|
nonisolated(nonsending)
|
|
func globalCallerFuncSendableKlass(_ x: SendableKlass) async -> () {}
|
|
|
|
@concurrent
|
|
func globalConcurrentFuncSendableKlass(_ x: SendableKlass) async -> () {}
|
|
|
|
nonisolated(nonsending)
|
|
func globalCallerFuncSendableKlass(_ x: SendableKlass) async -> SendableKlass { fatalError() }
|
|
|
|
@concurrent
|
|
func globalConcurrentFuncSendableKlass(_ x: SendableKlass) async -> SendableKlass { fatalError() }
|
|
|
|
|
|
/////////////////
|
|
// MARK: Tests //
|
|
/////////////////
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen33testCallerToConcurrentNonIsolatedyyyyYaYCcYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()):
|
|
// CHECK: [[FUNC_COPY:%.*]] = copy_value [[FUNC]]
|
|
// CHECK: [[THUNK:%.*]] = function_ref @$sBAIegHgIL_IegH_TR : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> ()
|
|
// CHECK: partial_apply [callee_guaranteed] [[THUNK]]([[FUNC_COPY]])
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen33testCallerToConcurrentNonIsolatedyyyyYaYCcYaF'
|
|
public func testCallerToConcurrentNonIsolated(_ x: nonisolated(nonsending) @escaping () async -> ()) async {
|
|
let y: @concurrent () async -> () = x
|
|
await y()
|
|
}
|
|
|
|
// This thunk is used to convert a caller to a concurrent function. So, we pass in .none as the
|
|
// isolated parameter.
|
|
//
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sBAIegHgIL_IegH_TR : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()):
|
|
// CHECK: [[ENUM:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK: hop_to_executor [[ENUM]]
|
|
// CHECK: [[CAST:%.*]] = unchecked_value_cast [[ENUM]] to $Builtin.ImplicitActor
|
|
// CHECK: apply [[FUNC]]([[CAST]])
|
|
// CHECK: } // end sil function '$sBAIegHgIL_IegH_TR'
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen31testCallerToConcurrentMainActoryyyyYaYCcYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()):
|
|
// CHECK: [[FUNC_COPY:%.*]] = copy_value [[FUNC]]
|
|
// CHECK: [[THUNK:%.*]] = function_ref @$sBAIegHgIL_IegH_TR : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> ()
|
|
// CHECK: partial_apply [callee_guaranteed] [[THUNK]]([[FUNC_COPY]])
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen31testCallerToConcurrentMainActoryyyyYaYCcYaF'
|
|
@MainActor
|
|
public func testCallerToConcurrentMainActor(_ x: nonisolated(nonsending) @escaping () async -> ()) async {
|
|
let y: @concurrent () async -> () = x
|
|
await y()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen33testConcurrentToCallerNonIsolatedyyyyYacYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed () -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed () -> ()):
|
|
// CHECK: [[FUNC_COPY:%.*]] = copy_value [[FUNC]]
|
|
// CHECK: [[THUNK:%.*]] = function_ref @$sIegH_BAIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed @async @callee_guaranteed () -> ()) -> ()
|
|
// CHECK: partial_apply [callee_guaranteed] [[THUNK]]([[FUNC_COPY]])
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen33testConcurrentToCallerNonIsolatedyyyyYacYaF'
|
|
public func testConcurrentToCallerNonIsolated(_ x: @escaping @concurrent () async -> ()) async {
|
|
let y: nonisolated(nonsending) () async -> () = x
|
|
await y()
|
|
}
|
|
|
|
// This thunk has the "surface" of an @caller function, but just ignores the
|
|
// isolated parameter and calls the concurrent funciton.
|
|
//
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIegH_BAIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed @async @callee_guaranteed () -> ()) -> () {
|
|
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Builtin.ImplicitActor, [[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed () -> ()):
|
|
// CHECK: apply [[FUNC]]
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: } // end sil function '$sIegH_BAIegHgIL_TR'
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen42testConcurrentToCallerNonIsolatedMainActoryyyyYacYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed () -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] :
|
|
// CHECK: [[FUNC_COPY:%.*]] = copy_value [[FUNC]]
|
|
// CHECK: [[THUNK:%.*]] = function_ref @$sIegH_BAIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed @async @callee_guaranteed () -> ()) -> ()
|
|
// CHECK: partial_apply [callee_guaranteed] [[THUNK]]([[FUNC_COPY]])
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen42testConcurrentToCallerNonIsolatedMainActoryyyyYacYaF'
|
|
@MainActor
|
|
public func testConcurrentToCallerNonIsolatedMainActor(_ x: @escaping @concurrent () async -> ()) async {
|
|
let y: nonisolated(nonsending) () async -> () = x
|
|
await y()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen016testConcurrentToE0yyyyYacYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed () -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed () -> ()):
|
|
// CHECK: [[COPY:%.*]] = copy_value [[FUNC]]
|
|
// CHECK: [[Y:%.*]] = move_value [lexical] [var_decl] [[COPY]]
|
|
// CHECK: [[BORROW_Y:%.*]] = begin_borrow [[Y]]
|
|
// CHECK: [[COPY_Y:%.*]] = copy_value [[BORROW_Y]]
|
|
// CHECK: [[BORROW_COPY_Y:%.*]] = begin_borrow [[COPY_Y]]
|
|
// CHECK: apply [[BORROW_COPY_Y]]()
|
|
// CHECK: [[FUNC:%.*]] = function_ref @$s21attr_execution_silgen20globalConcurrentFuncyyYaF : $@convention(thin) @async () -> ()
|
|
// CHECK: [[TTFI:%.*]] = thin_to_thick_function [[FUNC]]
|
|
// FIVE: [[Z:%.*]] = move_value [lexical] [var_decl] [[TTFI]]
|
|
// SIX: [[CVT_1:%.*]] = convert_function [[TTFI]] to $@Sendable @async
|
|
// SIX: [[CVT_2:%.*]] = convert_function [[CVT_1]] to $@async
|
|
// SIX: [[Z:%.*]] = move_value [lexical] [var_decl] [[CVT_2]]
|
|
// CHECK: [[BORROW_Z:%.*]] = begin_borrow [[Z]]
|
|
// CHECK: [[COPY_Z:%.*]] = copy_value [[BORROW_Z]]
|
|
// CHECK: [[BORROW_COPY_Z:%.*]] = begin_borrow [[COPY_Z]]
|
|
// CHECK: apply [[BORROW_COPY_Z]]()
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen016testConcurrentToE0yyyyYacYaF'
|
|
public func testConcurrentToConcurrent(_ x: @escaping @concurrent () async -> ()) async {
|
|
let y: @concurrent () async -> () = x
|
|
await y()
|
|
let z: @concurrent () async -> () = globalConcurrentFunc
|
|
await z()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen012testCallerToE0yyyyYaYCcYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()):
|
|
// CHECK: [[COPY:%.*]] = copy_value [[FUNC]]
|
|
// CHECK: [[Y:%.*]] = move_value [lexical] [var_decl] [[COPY]]
|
|
// CHECK: [[BORROW_Y:%.*]] = begin_borrow [[Y]]
|
|
// CHECK: [[COPY_Y:%.*]] = copy_value [[BORROW_Y]]
|
|
// CHECK: [[BORROW_COPY_Y:%.*]] = begin_borrow [[COPY_Y]]
|
|
// CHECK: apply [[BORROW_COPY_Y]]({{%.*}})
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen012testCallerToE0yyyyYaYCcYaF'
|
|
//
|
|
// z has a round trip issue.
|
|
public func testCallerToCaller(_ x: nonisolated(nonsending) @escaping () async -> ()) async {
|
|
let y: nonisolated(nonsending) () async -> () = x
|
|
await y()
|
|
let z: nonisolated(nonsending) () async -> () = globalCallerFunc
|
|
await z()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen24testCallerLocalVariablesyyyyYaYCcYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> () {
|
|
// CHECK: bb0([[PARAM:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()):
|
|
// CHECK: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: [[PARAM_COPY:%.*]] = copy_value [[PARAM]]
|
|
// CHECK: [[Y:%.*]] = move_value [lexical] [var_decl] [[PARAM_COPY]]
|
|
// CHECK: [[Y_B:%.*]] = begin_borrow [[Y]]
|
|
// CHECK: [[Y_B_C:%.*]] = copy_value [[Y_B]]
|
|
// CHECK: [[Y2:%.*]] = move_value [lexical] [var_decl] [[Y_B_C]]
|
|
// CHECK: [[Y2_B:%.*]] = begin_borrow [[Y2]]
|
|
// CHECK: [[Y2_B_C:%.*]] = copy_value [[Y2_B]]
|
|
// CHECK: [[ACTOR_CAST:%.*]] = unchecked_value_cast [[ACTOR]] to $Builtin.ImplicitActor
|
|
// CHECK: [[Y2_B_C_B:%.*]] = begin_borrow [[Y2_B_C]]
|
|
// CHECK: apply [[Y2_B_C_B]]([[ACTOR_CAST]])
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen24testCallerLocalVariablesyyyyYaYCcYaF'
|
|
public func testCallerLocalVariables(_ x: nonisolated(nonsending) @escaping () async -> ()) async {
|
|
let y: nonisolated(nonsending) () async -> () = x
|
|
let y2: nonisolated(nonsending) () async -> () = y
|
|
await y2()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen28testConcurrentLocalVariablesyyyyYacYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed () -> ()) -> () {
|
|
// CHECK: [[PARAM_COPY:%.*]] = copy_value [[PARAM]]
|
|
// CHECK: [[Y:%.*]] = move_value [lexical] [var_decl] [[PARAM_COPY]]
|
|
// CHECK: [[Y_B:%.*]] = begin_borrow [[Y]]
|
|
// CHECK: [[Y_B_C:%.*]] = copy_value [[Y_B]]
|
|
// CHECK: [[Y2:%.*]] = move_value [lexical] [var_decl] [[Y_B_C]]
|
|
// CHECK: [[Y2_B:%.*]] = begin_borrow [[Y2]]
|
|
// CHECK: [[Y2_B_C:%.*]] = copy_value [[Y2_B]]
|
|
// CHECK: [[Y2_B_C_B:%.*]] = begin_borrow [[Y2_B_C]]
|
|
// CHECK: apply [[Y2_B_C_B]]()
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen28testConcurrentLocalVariablesyyyyYacYaF'
|
|
public func testConcurrentLocalVariables(_ x: @escaping @concurrent () async -> ()) async {
|
|
let y: @concurrent () async -> () = x
|
|
let y2: @concurrent () async -> () = y
|
|
await y2()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen34testCallerConcurrentLocalVariablesyyyyYaYCcYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> () {
|
|
// CHECK: bb0([[PARAM:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()):
|
|
// CHECK: [[PARAM_COPY:%.*]] = copy_value [[PARAM]]
|
|
// CHECK: [[THUNK_1:%.*]] = function_ref @$sBAIegHgIL_IegH_TR : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> ()
|
|
// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK_1]]([[PARAM_COPY]])
|
|
// CHECK: [[Y:%.*]] = move_value [lexical] [var_decl] [[PA]]
|
|
// CHECK: [[Y_B:%.*]] = begin_borrow [[Y]]
|
|
// CHECK: [[Y_B_C:%.*]] = copy_value [[Y_B]]
|
|
// CHECK: [[THUNK_2:%.*]] = function_ref @$sIegH_BAIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed @async @callee_guaranteed () -> ()) -> ()
|
|
// CHECK: [[PA_2:%.*]] = partial_apply [callee_guaranteed] [[THUNK_2]]([[Y_B_C]])
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen34testCallerConcurrentLocalVariablesyyyyYaYCcYaF'
|
|
public func testCallerConcurrentLocalVariables(_ x: nonisolated(nonsending) @escaping () async -> ()) async {
|
|
let y: @concurrent () async -> () = x
|
|
let y2: nonisolated(nonsending) () async -> () = y
|
|
await y2()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen34testConcurrentCallerLocalVariablesyyyyYacYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed () -> ()) -> () {
|
|
// CHECK: bb0([[PARAM:%.*]] : @guaranteed $@async @callee_guaranteed () -> ()):
|
|
// CHECK: [[PARAM_C:%.*]] = copy_value [[PARAM]]
|
|
// CHECK: [[THUNK_1:%.*]] = function_ref @$sIegH_BAIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed @async @callee_guaranteed () -> ()) -> ()
|
|
// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK_1]]([[PARAM_C]])
|
|
// CHECK: [[Y:%.*]] = move_value [lexical] [var_decl] [[PA]]
|
|
// CHECK: [[Y_B:%.*]] = begin_borrow [[Y]]
|
|
// CHECK: [[Y_B_C:%.*]] = copy_value [[Y_B]]
|
|
// CHECK: [[THUNK_2:%.*]] = function_ref @$sBAIegHgIL_IegH_TR : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> ()
|
|
// CHECK: [[PA_2:%.*]] = partial_apply [callee_guaranteed] [[THUNK_2]]([[Y_B_C]])
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen34testConcurrentCallerLocalVariablesyyyyYacYaF'
|
|
public func testConcurrentCallerLocalVariables(_ x: @escaping @concurrent () async -> ()) async {
|
|
let y: nonisolated(nonsending) () async -> () = x
|
|
let y2: @concurrent () async -> () = y
|
|
await y2()
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s21attr_execution_silgen22globalActorConversionsyyyyYac_yyYaYCctYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed () -> (), @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> () {
|
|
// CHECK: bb0([[X:%.*]] : @guaranteed $@async @callee_guaranteed () -> (), [[Y:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()):
|
|
// CHECK: [[GLOBAL_CALLER_FUNC:%.*]] = function_ref @$s21attr_execution_silgen16globalCallerFuncyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
// FIVE: [[TTFI:%.*]] = thin_to_thick_function [[GLOBAL_CALLER_FUNC]] to $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
// FIVE: [[THUNK:%.*]] = function_ref @$sBAIegHgIL_IegH_TRScMTU : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> ()
|
|
// FIVE: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[TTFI]]) :
|
|
// SIX: [[THUNK:%.*]] = function_ref @$sBAIetHgIL_IeghH_TRScMTU : $@convention(thin) @Sendable @async (@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> ()
|
|
// SIX: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[GLOBAL_CALLER_FUNC]]) :
|
|
// CHECK: [[V1:%.*]] = move_value [lexical] [var_decl] [[PA]]
|
|
// CHECK: [[V1_B:%.*]] = begin_borrow [[V1]]
|
|
// CHECK: [[V1_B_C:%.*]] = copy_value [[V1_B]]
|
|
// CHECK: [[V1_B_C_B:%.*]] = begin_borrow [[V1_B_C]]
|
|
// FIVE: apply [[V1_B_C_B]]() : $@async @callee_guaranteed () -> ()
|
|
// SIX: apply [[V1_B_C_B]]() : $@Sendable @async @callee_guaranteed () -> ()
|
|
|
|
// CHECK: [[GLOBAL_CONCURRENT_FUNC:%.*]] = function_ref @$s21attr_execution_silgen20globalConcurrentFuncyyYaF : $@convention(thin) @async () -> ()
|
|
// CHECK: [[TTFI:%.*]] = thin_to_thick_function [[GLOBAL_CONCURRENT_FUNC]]
|
|
// FIVE: [[V2:%.*]] = move_value [lexical] [var_decl] [[TTFI]]
|
|
// SIX: [[CVT:%.*]] = convert_function [[TTFI]] to $@Sendable @async @callee_guaranteed () -> ()
|
|
// SIX: [[V2:%.*]] = move_value [lexical] [var_decl] [[CVT]]
|
|
// CHECK: [[V2_B:%.*]] = begin_borrow [[V2]]
|
|
// CHECK: [[V2_B_C:%.*]] = copy_value [[V2_B]]
|
|
// CHECK: [[V2_B_C_B:%.*]] = begin_borrow [[V2_B_C]]
|
|
// CHECK: apply [[V2_B_C_B]]()
|
|
|
|
// FIVE: [[X_C:%.*]] = copy_value [[X]]
|
|
// FIVE: [[V3:%.*]] = move_value [lexical] [var_decl] [[X_C]]
|
|
// FIVE: [[V3_B:%.*]] = begin_borrow [[V3]]
|
|
// FIVE: [[V3_B_C:%.*]] = copy_value [[V3_B]]
|
|
// FIVE: [[V3_B_C_B:%.*]] = begin_borrow [[V3_B_C]]
|
|
// FIVE: apply [[V3_B_C_B]]()
|
|
|
|
// FIVE: [[Y_C:%.*]] = copy_value [[Y]]
|
|
// FIVE: [[THUNK:%.*]] = function_ref @$sBAIegHgIL_IegH_TRScMTU : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> ()
|
|
// FIVE: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[Y_C]])
|
|
// FIVE: [[V4:%.*]] = move_value [lexical] [var_decl] [[PA]]
|
|
// FIVE: [[V4_B:%.*]] = begin_borrow [[V4]]
|
|
// FIVE: [[V4_B_C:%.*]] = copy_value [[V4_B]]
|
|
// FIVE: [[V4_B_C_B:%.*]] = begin_borrow [[V4_B_C]]
|
|
// FIVE: apply [[V4_B_C_B]]()
|
|
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen22globalActorConversionsyyyyYac_yyYaYCctYaF'
|
|
|
|
// SIX-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sBAIetHgIL_IeghH_TRScMTU : $@convention(thin) @Sendable @async (@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()) -> () {
|
|
// SIX: bb0([[FUNC:%.*]] : $@convention(thin) @async (@sil_isolated
|
|
// SIX: [[ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
|
|
// SIX: [[E:%.*]] = init_existential_ref [[ACTOR]] : $MainActor : $MainActor, $any Actor
|
|
// SIX: [[E_OPT:%.*]] = enum $Optional<any Actor>, #Optional.some!enumelt, [[E]]
|
|
// SIX: hop_to_executor [[E_OPT]]
|
|
// SIX: [[E_OPT_B:%.*]] = begin_borrow [[E_OPT]]
|
|
// SIX: [[E_OPT_B_CAST:%.*]] = unchecked_value_cast [[E_OPT_B]] to $Builtin.ImplicitActor
|
|
// SIX: apply [[FUNC]]([[E_OPT_B_CAST]]) : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> ()
|
|
// SIX: } // end sil function '$sBAIetHgIL_IeghH_TRScMTU'
|
|
|
|
func globalActorConversions(_ x: @escaping @concurrent () async -> (),
|
|
_ y: nonisolated(nonsending) @escaping () async -> ()) async {
|
|
let v1: @MainActor () async -> Void = globalCallerFunc
|
|
await v1()
|
|
let v2: @MainActor () async -> Void = globalConcurrentFunc
|
|
await v2()
|
|
|
|
// These are invalid in swift 6 since x is not Sendable and this @MainActor
|
|
// is.
|
|
#if SWIFT_FIVE
|
|
let v3: @MainActor () async -> Void = x
|
|
await v3()
|
|
let v4: @MainActor () async -> Void = y
|
|
await v4()
|
|
#endif
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s21attr_execution_silgen23globalActorConversions2yyyAA13SendableKlassCYac_yADYaYCctYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@guaranteed SendableKlass) -> (), @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()) -> () {
|
|
// CHECK: bb0([[X:%.*]] : @guaranteed $@async @callee_guaranteed (@guaranteed SendableKlass) -> (), [[Y:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()):
|
|
// CHECK: [[GLOBAL_CALLER_FUNC:%.*]] = function_ref @$s21attr_execution_silgen29globalCallerFuncSendableKlassyyAA0gH0CYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()
|
|
// FIVE: [[TTFI:%.*]] = thin_to_thick_function [[GLOBAL_CALLER_FUNC]] to $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()
|
|
// FIVE: [[THUNK:%.*]] = function_ref @$sBA21attr_execution_silgen13SendableKlassCIegHgILg_ACIegHg_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()) -> ()
|
|
// FIVE: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[TTFI]]) :
|
|
// SIX: [[THUNK:%.*]] = function_ref @$sBA21attr_execution_silgen13SendableKlassCIetHgILg_ACIeghHg_TRScMTU : $@convention(thin) @Sendable @async (@guaranteed SendableKlass, @convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()) -> ()
|
|
// SIX: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[GLOBAL_CALLER_FUNC]]) :
|
|
// CHECK: [[V1:%.*]] = move_value [lexical] [var_decl] [[PA]]
|
|
// CHECK: [[V1_B:%.*]] = begin_borrow [[V1]]
|
|
// CHECK: [[V1_B_C:%.*]] = copy_value [[V1_B]]
|
|
// CHECK: [[V1_B_C_B:%.*]] = begin_borrow [[V1_B_C]]
|
|
// FIVE: apply [[V1_B_C_B]]({{%.*}}) : $@async @callee_guaranteed (@guaranteed SendableKlass) -> ()
|
|
// SIX: apply [[V1_B_C_B]]({{%.*}}) : $@Sendable @async @callee_guaranteed (@guaranteed SendableKlass) -> ()
|
|
|
|
// CHECK: [[GLOBAL_CONCURRENT_FUNC:%.*]] = function_ref @$s21attr_execution_silgen33globalConcurrentFuncSendableKlassyyAA0gH0CYaF : $@convention(thin) @async (@guaranteed SendableKlass) -> ()
|
|
// CHECK: [[TTFI:%.*]] = thin_to_thick_function [[GLOBAL_CONCURRENT_FUNC]] to $@async @callee_guaranteed (@guaranteed SendableKlass) -> ()
|
|
// FIVE: [[V2:%.*]] = move_value [lexical] [var_decl] [[TTFI]]
|
|
// SIX: [[CVT:%.*]] = convert_function [[TTFI]] to $@Sendable @async @callee_guaranteed (@guaranteed SendableKlass) -> ()
|
|
// SIX: [[V2:%.*]] = move_value [lexical] [var_decl] [[CVT]]
|
|
// CHECK: [[V2_B:%.*]] = begin_borrow [[V2]]
|
|
// CHECK: [[V2_B_C:%.*]] = copy_value [[V2_B]]
|
|
// CHECK: [[V2_B_C_B:%.*]] = begin_borrow [[V2_B_C]]
|
|
// CHECK: apply [[V2_B_C_B]]({{%.*}})
|
|
|
|
// FIVE: [[X_C:%.*]] = copy_value [[X]]
|
|
// FIVE: [[V3:%.*]] = move_value [lexical] [var_decl] [[X_C]]
|
|
// FIVE: [[V3_B:%.*]] = begin_borrow [[V3]]
|
|
// FIVE: [[V3_B_C:%.*]] = copy_value [[V3_B]]
|
|
// FIVE: [[V3_B_C_B:%.*]] = begin_borrow [[V3_B_C]]
|
|
// FIVE: apply [[V3_B_C_B]]({{%.*}})
|
|
|
|
// FIVE: [[Y_C:%.*]] = copy_value [[Y]]
|
|
// FIVE: [[THUNK:%.*]] = function_ref @$sBA21attr_execution_silgen13SendableKlassCIegHgILg_ACIegHg_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()) -> ()
|
|
// FIVE: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[Y_C]])
|
|
// FIVE: [[V4:%.*]] = move_value [lexical] [var_decl] [[PA]]
|
|
// FIVE: [[V4_B:%.*]] = begin_borrow [[V4]]
|
|
// FIVE: [[V4_B_C:%.*]] = copy_value [[V4_B]]
|
|
// FIVE: [[V4_B_C_B:%.*]] = begin_borrow [[V4_B_C]]
|
|
// FIVE: apply [[V4_B_C_B]]({{%.*}})
|
|
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen23globalActorConversions2yyyAA13SendableKlassCYac_yADYaYCctYaF'
|
|
|
|
// FIVE-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sBA21attr_execution_silgen13SendableKlassCIegHgILg_ACIegHg_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()) -> () {
|
|
// FIVE: bb0([[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : @guaranteed
|
|
// FIVE: [[ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
|
|
// FIVE: [[E:%.*]] = init_existential_ref [[ACTOR]] : $MainActor : $MainActor, $any Actor
|
|
// FIVE: [[E_OPT:%.*]] = enum $Optional<any Actor>, #Optional.some!enumelt, [[E]]
|
|
// FIVE: hop_to_executor [[E_OPT]]
|
|
// FIVE: [[E_OPT_B:%.*]] = begin_borrow [[E_OPT]]
|
|
// FIVE: [[E_OPT_B_CAST:%.*]] = unchecked_value_cast [[E_OPT_B]] to $Builtin.ImplicitActor
|
|
// FIVE: apply [[FUNC]]([[E_OPT_B_CAST]], [[ARG]])
|
|
// FIVE: } // end sil function '$sBA21attr_execution_silgen13SendableKlassCIegHgILg_ACIegHg_TRScMTU'
|
|
|
|
// SIX-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sBA21attr_execution_silgen13SendableKlassCIetHgILg_ACIeghHg_TRScMTU : $@convention(thin) @Sendable @async (@guaranteed SendableKlass, @convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()) -> () {
|
|
// SIX: bb0([[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()):
|
|
// SIX: [[ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
|
|
// SIX: [[E:%.*]] = init_existential_ref [[ACTOR]] : $MainActor : $MainActor, $any Actor
|
|
// SIX: [[E_OPT:%.*]] = enum $Optional<any Actor>, #Optional.some!enumelt, [[E]]
|
|
// SIX: hop_to_executor [[E_OPT]]
|
|
// SIX: [[E_OPT_B:%.*]] = begin_borrow [[E_OPT]]
|
|
// SIX: [[E_OPT_B_CAST:%.*]] = unchecked_value_cast [[E_OPT_B]] to $Builtin.ImplicitActor
|
|
// SIX: apply [[FUNC]]([[E_OPT_B_CAST]], [[ARG]])
|
|
// SIX: } // end sil function '$sBA21attr_execution_silgen13SendableKlassCIetHgILg_ACIeghHg_TRScMTU'
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sBA21attr_execution_silgen13SendableKlassCIegHgILg_ACIegHg_TR : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> ()) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : @guaranteed
|
|
// CHECK: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: [[ACTOR_CAST:%.*]] = unchecked_value_cast [[ACTOR]] to $Builtin.ImplicitActor
|
|
// CHECK: apply [[FUNC]]([[ACTOR_CAST]], [[ARG]])
|
|
// CHECK: } // end sil function '$sBA21attr_execution_silgen13SendableKlassCIegHgILg_ACIegHg_TR'
|
|
func globalActorConversions2(_ x: @escaping @concurrent (SendableKlass) async -> (),
|
|
_ y: nonisolated(nonsending) @escaping (SendableKlass) async -> ()) async {
|
|
let v1: @MainActor (SendableKlass) async -> Void = globalCallerFuncSendableKlass
|
|
await v1(SendableKlass())
|
|
let v2: @MainActor (SendableKlass) async -> Void = globalConcurrentFuncSendableKlass
|
|
await v2(SendableKlass())
|
|
#if SWIFT_FIVE
|
|
let v3: @MainActor (SendableKlass) async -> Void = x
|
|
await v3(SendableKlass())
|
|
let v4: @MainActor (SendableKlass) async -> Void = y
|
|
await v4(SendableKlass())
|
|
#endif
|
|
let v5: @concurrent (SendableKlass) async -> Void = y
|
|
await v5(SendableKlass())
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s21attr_execution_silgen23globalActorConversions3yyAA13SendableKlassCADYac_A2DYaYCctYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@guaranteed SendableKlass) -> @owned SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass) -> () {
|
|
// CHECK: bb0([[X:%.*]] : @guaranteed $@async @callee_guaranteed (@guaranteed SendableKlass) -> @owned SendableKlass, [[Y:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass):
|
|
// CHECK: [[GLOBAL_CALLER_FUNC:%.*]] = function_ref @$s21attr_execution_silgen29globalCallerFuncSendableKlassyAA0gH0CADYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass
|
|
// FIVE: [[TTFI:%.*]] = thin_to_thick_function [[GLOBAL_CALLER_FUNC]] to $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass
|
|
// FIVE: [[THUNK:%.*]] = function_ref @$sBA21attr_execution_silgen13SendableKlassCACIegHgILgo_A2CIegHgo_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass) -> @owned SendableKlass
|
|
// FIVE: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[TTFI]])
|
|
// SIX: [[THUNK:%.*]] = function_ref @$sBA21attr_execution_silgen13SendableKlassCACIetHgILgo_A2CIeghHgo_TRScMTU : $@convention(thin) @Sendable @async (@guaranteed SendableKlass, @convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass) -> @owned SendableKlass
|
|
// SIX: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[GLOBAL_CALLER_FUNC]])
|
|
// CHECK: [[V1:%.*]] = move_value [lexical] [var_decl] [[PA]]
|
|
// CHECK: [[V1_B:%.*]] = begin_borrow [[V1]]
|
|
// CHECK: [[V1_B_C:%.*]] = copy_value [[V1_B]]
|
|
// CHECK: [[V1_B_C_B:%.*]] = begin_borrow [[V1_B_C]]
|
|
// CHECK: apply [[V1_B_C_B]]({{%.*}})
|
|
|
|
// CHECK: [[GLOBAL_CONCURRENT_FUNC:%.*]] = function_ref @$s21attr_execution_silgen33globalConcurrentFuncSendableKlassyAA0gH0CADYaF : $@convention(thin) @async (@guaranteed SendableKlass) -> @owned SendableKlass
|
|
// CHECK: [[TTFI:%.*]] = thin_to_thick_function [[GLOBAL_CONCURRENT_FUNC]] to $@async @callee_guaranteed (@guaranteed SendableKlass) -> @owned SendableKlass
|
|
// FIVE: [[V2:%.*]] = move_value [lexical] [var_decl] [[TTFI]]
|
|
// SIX: [[CVT:%.*]] = convert_function [[TTFI]] to $@Sendable @async @callee_guaranteed (@guaranteed SendableKlass) -> @owned SendableKlass
|
|
// SIX: [[V2:%.*]] = move_value [lexical] [var_decl] [[CVT]]
|
|
// CHECK: [[V2_B:%.*]] = begin_borrow [[V2]]
|
|
// CHECK: [[V2_B_C:%.*]] = copy_value [[V2_B]]
|
|
// CHECK: [[V2_B_C_B:%.*]] = begin_borrow [[V2_B_C]]
|
|
// CHECK: apply [[V2_B_C_B]]({{%.*}})
|
|
|
|
// FIVE: [[X_C:%.*]] = copy_value [[X]]
|
|
// FIVE: [[V3:%.*]] = move_value [lexical] [var_decl] [[X_C]]
|
|
// FIVE: [[V3_B:%.*]] = begin_borrow [[V3]]
|
|
// FIVE: [[V3_B_C:%.*]] = copy_value [[V3_B]]
|
|
// FIVE: [[V3_B_C_B:%.*]] = begin_borrow [[V3_B_C]]
|
|
// FIVE: apply [[V3_B_C_B]]({{%.*}})
|
|
|
|
// FIVE: [[Y_C:%.*]] = copy_value [[Y]]
|
|
// FIVE: [[THUNK:%.*]] = function_ref @$sBA21attr_execution_silgen13SendableKlassCACIegHgILgo_A2CIegHgo_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass) -> @owned SendableKlass
|
|
// FIVE: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[Y_C]])
|
|
// FIVE: [[V4:%.*]] = move_value [lexical] [var_decl] [[PA]]
|
|
// FIVE: [[V4_B:%.*]] = begin_borrow [[V4]]
|
|
// FIVE: [[V4_B_C:%.*]] = copy_value [[V4_B]]
|
|
// FIVE: [[V4_B_C_B:%.*]] = begin_borrow [[V4_B_C]]
|
|
// FIVE: apply [[V4_B_C_B]]({{%.*}})
|
|
|
|
// CHECK: [[Y_C:%.*]] = copy_value [[Y]]
|
|
// CHECK: [[THUNK:%.*]] = function_ref @$sBA21attr_execution_silgen13SendableKlassCACIegHgILgo_A2CIegHgo_TR : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass) -> @owned SendableKlass
|
|
// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[Y_C]])
|
|
// CHECK: [[V5:%.*]] = move_value [lexical] [var_decl] [[PA]]
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen23globalActorConversions3yyAA13SendableKlassCADYac_A2DYaYCctYaF'
|
|
|
|
// FIVE-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sBA21attr_execution_silgen13SendableKlassCACIegHgILgo_A2CIegHgo_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass) -> @owned SendableKlass {
|
|
// FIVE: bb0([[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : @guaranteed
|
|
// FIVE: [[ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
|
|
// FIVE: [[E:%.*]] = init_existential_ref [[ACTOR]] : $MainActor : $MainActor, $any Actor
|
|
// FIVE: [[E_OPT:%.*]] = enum $Optional<any Actor>, #Optional.some!enumelt, [[E]]
|
|
// FIVE: hop_to_executor [[E_OPT]]
|
|
// FIVE: [[E_OPT_B:%.*]] = begin_borrow [[E_OPT]]
|
|
// FIVE: [[E_OPT_B_CAST:%.*]] = unchecked_value_cast [[E_OPT_B]] to $Builtin.ImplicitActor
|
|
// FIVE: apply [[FUNC]]([[E_OPT_B_CAST]], [[ARG]])
|
|
// FIVE: } // end sil function '$sBA21attr_execution_silgen13SendableKlassCACIegHgILgo_A2CIegHgo_TRScMTU'
|
|
|
|
// SIX-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sBA21attr_execution_silgen13SendableKlassCACIetHgILgo_A2CIeghHgo_TRScMTU : $@convention(thin) @Sendable @async (@guaranteed SendableKlass, @convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass) -> @owned SendableKlass {
|
|
// SIX: bb0([[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass):
|
|
// SIX: [[ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
|
|
// SIX: [[E:%.*]] = init_existential_ref [[ACTOR]] : $MainActor : $MainActor, $any Actor
|
|
// SIX: [[E_OPT:%.*]] = enum $Optional<any Actor>, #Optional.some!enumelt, [[E]]
|
|
// SIX: hop_to_executor [[E_OPT]]
|
|
// SIX: [[E_OPT_B:%.*]] = begin_borrow [[E_OPT]]
|
|
// SIX: [[E_OPT_B_CAST:%.*]] = unchecked_value_cast [[E_OPT_B]] to $Builtin.ImplicitActor
|
|
// SIX: apply [[FUNC]]([[E_OPT_B_CAST]], [[ARG]])
|
|
// SIX: } // end sil function '$sBA21attr_execution_silgen13SendableKlassCACIetHgILgo_A2CIeghHgo_TRScMTU'
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sBA21attr_execution_silgen13SendableKlassCACIegHgILgo_A2CIegHgo_TR : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass) -> @owned SendableKlass) -> @owned SendableKlass {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : @guarantee
|
|
// CHECK: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: } // end sil function '$sBA21attr_execution_silgen13SendableKlassCACIegHgILgo_A2CIegHgo_TR'
|
|
func globalActorConversions3(_ x: @escaping @concurrent (SendableKlass) async -> SendableKlass,
|
|
_ y: nonisolated(nonsending) @escaping (SendableKlass) async -> SendableKlass) async {
|
|
let v1: @MainActor (SendableKlass) async -> SendableKlass = globalCallerFuncSendableKlass
|
|
_ = await v1(SendableKlass())
|
|
let v2: @MainActor (SendableKlass) async -> SendableKlass = globalConcurrentFuncSendableKlass
|
|
_ = await v2(SendableKlass())
|
|
#if SWIFT_FIVE
|
|
let v3: @MainActor (SendableKlass) async -> SendableKlass = x
|
|
_ = await v3(SendableKlass())
|
|
let v4: @MainActor (SendableKlass) async -> SendableKlass = y
|
|
_ = await v4(SendableKlass())
|
|
#endif
|
|
let v5: @concurrent (SendableKlass) async -> SendableKlass = y
|
|
_ = await v5(SendableKlass())
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s21attr_execution_silgen26conversionsFromSyncToAsyncyyyAA16NonSendableKlassCYbc_yAA0jK0CYbScMYcctYaF : $@convention(thin) @async (@guaranteed @Sendable @callee_guaranteed (@guaranteed NonSendableKlass) -> (), @guaranteed @Sendable @callee_guaranteed (@guaranteed SendableKlass) -> ()) -> ()
|
|
// CHECK: bb0([[X:%.*]] : @guaranteed $@Sendable @callee_guaranteed (@guaranteed NonSendableKlass) -> (), [[Y:%.*]] : @guaranteed $@Sendable @callee_guaranteed (@guaranteed SendableKlass) -> ()):
|
|
|
|
// CHECK: [[X_C:%.*]] = copy_value [[X]]
|
|
// CHECK: [[THUNK:%.*]] = function_ref @$s21attr_execution_silgen16NonSendableKlassCIeghg_BAACIegHgILg_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed NonSendableKlass, @guaranteed @Sendable @callee_guaranteed (@guaranteed NonSendableKlass) -> ()) -> ()
|
|
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[X_C]])
|
|
|
|
// CHECK: [[Y_C:%.*]] = copy_value [[Y]]
|
|
// CHECK: [[THUNK:%.*]] = function_ref @$s21attr_execution_silgen13SendableKlassCIeghg_BAACIegHgILg_TRScMTU : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass, @guaranteed @Sendable @callee_guaranteed (@guaranteed SendableKlass) -> ()) -> ()
|
|
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[Y_C]])
|
|
|
|
// CHECK: [[Y_C:%.*]] = copy_value [[Y]]
|
|
// CHECK: [[THUNK:%.*]] = function_ref @$s21attr_execution_silgen13SendableKlassCIeghg_ACIegHg_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @Sendable @callee_guaranteed (@guaranteed SendableKlass) -> ()) -> ()
|
|
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[Y_C]])
|
|
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen26conversionsFromSyncToAsyncyyyAA16NonSendableKlassCYbc_yAA0jK0CYbScMYcctYaF'
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s21attr_execution_silgen16NonSendableKlassCIeghg_BAACIegHgILg_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed NonSendableKlass, @guaranteed @Sendable @callee_guaranteed (@guaranteed NonSendableKlass) -> ()) -> () {
|
|
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Builtin.ImplicitActor
|
|
// CHECK: apply {{%.*}}({{%.*}}) : $@Sendable @callee_guaranteed (@guaranteed NonSendableKlass) -> ()
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen16NonSendableKlassCIeghg_BAACIegHgILg_TR'
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s21attr_execution_silgen13SendableKlassCIeghg_BAACIegHgILg_TRScMTU : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed SendableKlass, @guaranteed @Sendable @callee_guaranteed (@guaranteed SendableKlass) -> ()) -> () {
|
|
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Builtin.ImplicitActor, [[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : @guaranteed $@Sendable @callee_guaranteed
|
|
// CHECK: [[MAIN_ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
|
|
// CHECK: [[MAIN_ACTOR_B:%.*]] = begin_borrow [[MAIN_ACTOR]]
|
|
// CHECK: hop_to_executor [[MAIN_ACTOR_B]]
|
|
// CHECK: apply [[FUNC]]([[ARG]])
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen13SendableKlassCIeghg_BAACIegHgILg_TRScMTU'
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s21attr_execution_silgen13SendableKlassCIeghg_ACIegHg_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @Sendable @callee_guaranteed (@guaranteed SendableKlass) -> ()) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : @guaranteed $@Sendable @callee_guaranteed (@guaranteed SendableKlass) -> ()):
|
|
// CHECK: [[MAIN_ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
|
|
// CHECK: [[MAIN_ACTOR_B:%.*]] = begin_borrow [[MAIN_ACTOR]]
|
|
// CHECK: hop_to_executor [[MAIN_ACTOR_B]]
|
|
// CHECK-NOT: hop_to_executor
|
|
// CHECK: apply [[FUNC]]([[ARG]])
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen13SendableKlassCIeghg_ACIegHg_TRScMTU'
|
|
|
|
func conversionsFromSyncToAsync(_ x: @escaping @Sendable (NonSendableKlass) -> Void,
|
|
_ y: @escaping @MainActor @Sendable (SendableKlass) -> Void) async {
|
|
let _: nonisolated(nonsending) (NonSendableKlass) async -> Void = x
|
|
let _: nonisolated(nonsending) (SendableKlass) async -> Void = y
|
|
let _: @concurrent (SendableKlass) async -> Void = y
|
|
}
|
|
|
|
func testThatClosuresAssumeIsolation(fn: inout nonisolated(nonsending) (Int) async -> Void) {
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaYCcfU_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> () {
|
|
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Builtin.ImplicitActor):
|
|
// CHECK: hop_to_executor [[EXECUTOR]]
|
|
let _: nonisolated(nonsending) () async -> Void = {
|
|
_ = 42
|
|
}
|
|
|
|
func testParam(_: nonisolated(nonsending) () async throws -> Void) {}
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaYCXEfU0_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> @error any Error {
|
|
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Builtin.ImplicitActor):
|
|
// CHECK: hop_to_executor [[EXECUTOR]]
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaYCXEfU0_'
|
|
testParam { _ = 42 }
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaXEfU1_ : $@convention(thin) @async () -> ()
|
|
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]]
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaXEfU1_'
|
|
testParam { @concurrent in _ = 42 }
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIgH_BAs5Error_pIegHgILzo_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed @noescape @async @callee_guaranteed () -> ()) -> @error any Error {
|
|
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Builtin.ImplicitActor, [[FUNC:%.*]] : @guaranteed $@noescape @async @callee_guaranteed () -> ()):
|
|
// CHECK: apply [[FUNC]]()
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: } // end sil function '$sIgH_BAs5Error_pIegHgILzo_TR'
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFySiYaYCcfU2_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, Int) -> () {
|
|
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Builtin.ImplicitActor, %1 : $Int):
|
|
// CHECK: hop_to_executor [[EXECUTOR]]
|
|
fn = { _ in }
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFySiYacfU3_ : $@convention(thin) @async (Int) -> ()
|
|
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]]
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFySiYacfU3_'
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sSiIegHy_BASiIegHgILy_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, Int, @guaranteed @async @callee_guaranteed (Int) -> ()) -> () {
|
|
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Builtin.ImplicitActor, [[ARG:%.*]] : $Int, [[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed (Int) -> ()):
|
|
// CHECK: apply [[FUNC]]([[ARG]])
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: } // end sil function '$sSiIegHy_BASiIegHgILy_TR'
|
|
fn = { @concurrent _ in }
|
|
}
|
|
|
|
@MainActor
|
|
func testNoIsolationTransfer() {
|
|
// CHECK: // Isolation: global_actor. type: MainActor
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen23testNoIsolationTransferyyF0D7ErasureL_yyyyYaYAcF : $@convention(thin) (@guaranteed @isolated(any) @async @callee_guaranteed () -> ()) -> ()
|
|
func testErasure(@_inheritActorContext _: @escaping @isolated(any) () async -> Void) {}
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen23testNoIsolationTransferyyFyyYacfU_ : $@convention(thin) @async (@guaranteed Optional<any Actor>) -> () {
|
|
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]]
|
|
testErasure { @concurrent in }
|
|
}
|
|
|
|
func testClosuresDontAssumeGlobalActorWithMarkedAsConcurrent() {
|
|
func test(_ fn: @MainActor () async -> Void) {}
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen55testClosuresDontAssumeGlobalActorWithMarkedAsConcurrentyyFyyYaYbXEfU_
|
|
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK-NEXT: hop_to_executor [[GENERIC_EXECUTOR]]
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen55testClosuresDontAssumeGlobalActorWithMarkedAsConcurrentyyFyyYaYbXEfU_'
|
|
test { @Sendable @concurrent in
|
|
}
|
|
}
|
|
|
|
nonisolated(nonsending)
|
|
public func takesCallerIsolatedThrowingFunction<T>(
|
|
_ operation: nonisolated(nonsending) () async throws -> T
|
|
) async rethrows -> T {
|
|
try await operation()
|
|
}
|
|
|
|
func observe() {}
|
|
|
|
// Test that we emit closures with nonisolated(nonsending) isolation without
|
|
// introducing an intermediate @concurrent closure function.
|
|
func testConvertToThrowing(isolation: isolated (any Actor)? = #isolation) async {
|
|
// CHECK-LABEL: sil hidden [ossa] @$s21attr_execution_silgen21testConvertToThrowing9isolationyScA_pSgYi_tYaF :
|
|
// CHECK: [[ACTOR_COPY:%.*]] = copy_value %0
|
|
// CHECK-NEXT: [[ACTOR_BORROW:%.*]] = begin_borrow [[ACTOR_COPY]]
|
|
// CHECK-NEXT: hop_to_executor [[ACTOR_BORROW]]
|
|
// CHECK: [[CLOSURE:%.*]] = function_ref @$s21attr_execution_silgen21testConvertToThrowing9isolationyScA_pSgYi_tYaFyyYaYCXEfU_ :
|
|
// CHECK-NEXT: [[CLOSURE_VALUE:%.*]] = thin_to_thick_function [[CLOSURE]] to
|
|
// CHECK-NEXT: [[ACTOR_BORROW_CAST:%.*]] = unchecked_value_cast [[ACTOR_BORROW]]
|
|
// CHECK-NEXT: // function_ref
|
|
// CHECK-NEXT: [[FN:%.*]] = function_ref
|
|
// CHECK-NEXT: try_apply [[FN]]<()>({{%.*}}, [[ACTOR_BORROW_CAST]], [[CLOSURE_VALUE]]) {{.*}}, normal bb1, error bb2
|
|
// CHECK: bb1(
|
|
// This hop is unnecessary because nonisolated(nonsending) should
|
|
// preserve isolation on return.
|
|
// CHECK-NEXT: hop_to_executor [[ACTOR_BORROW]]
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen21testConvertToThrowing9isolationyScA_pSgYi_tYaFyyYaYCXEfU_ : $@convention(thin) @async @substituted <τ_0_0> (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor) -> (@out τ_0_0, @error any Error) for <()>
|
|
// CHECK: bb0(
|
|
// CHECK-NEXT: debug_value
|
|
// This hop is unnecessary because nonisolated(nonsending) should
|
|
// ensure isolation before call.
|
|
// CHECK-NEXT: hop_to_executor %1
|
|
// CHECK-NEXT: // function_ref observe()
|
|
// CHECK-NEXT: [[FN:%.*]] = function_ref @$s21attr_execution_silgen7observeyyF :
|
|
// CHECK-NEXT: apply [[FN]]()
|
|
|
|
await takesCallerIsolatedThrowingFunction {
|
|
observe()
|
|
}
|
|
}
|
|
|
|
func testSendableClosureNonisolatedNonSendingInference() {
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen49testSendableClosureNonisolatedNonSendingInferenceyyFySiYaYbYCcfU_ : $@convention(thin) @Sendable @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, Int) -> ()
|
|
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Builtin.ImplicitActor, %1 : $Int):
|
|
// CHECK: hop_to_executor [[EXECUTOR]]
|
|
// CHECK: // end sil function '$s21attr_execution_silgen49testSendableClosureNonisolatedNonSendingInferenceyyFySiYaYbYCcfU_'
|
|
let _: nonisolated(nonsending) @Sendable (Int) async -> Void = { _ in }
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen49testSendableClosureNonisolatedNonSendingInferenceyyFyS2SYaKYCcYaYbYCcfU0_ : $@convention(thin) @Sendable @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed String) -> (@owned String, @error any Error)) -> @error any Error
|
|
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Builtin.ImplicitActor, %1 : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed String) -> (@owned String, @error any Error)):
|
|
// CHECK: hop_to_executor [[EXECUTOR]]
|
|
// CHECK: // end sil function '$s21attr_execution_silgen49testSendableClosureNonisolatedNonSendingInferenceyyFyS2SYaKYCcYaYbYCcfU0_'
|
|
let _: nonisolated(nonsending) @Sendable (
|
|
nonisolated(nonsending) @escaping (String) async throws -> String
|
|
) async throws -> Void = { _ in }
|
|
}
|
|
|
|
// CHECK-LABEL: sil hidden [ossa] @$s21attr_execution_silgen014testSendableToE35ConversionWithNonisilatedNonsendingyyF : $@convention(thin) () -> ()
|
|
// CHECK: [[TEST_REF:%.*]] = function_ref @$s21attr_execution_silgen014testSendableToE35ConversionWithNonisilatedNonsendingyyF0D0L_7closureyS2SYaKYCc_tYaYbKF : $@convention(thin) @Sendable @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @guaranteed String) -> (@owned String, @error any Error)) -> @error any Error
|
|
// CHECK: // end sil function '$s21attr_execution_silgen014testSendableToE35ConversionWithNonisilatedNonsendingyyF'
|
|
func testSendableToSendableConversionWithNonisilatedNonsending() {
|
|
@Sendable nonisolated(nonsending) func test(
|
|
closure: nonisolated(nonsending) @escaping (String) async throws -> String
|
|
) async throws {
|
|
}
|
|
|
|
let _: nonisolated(nonsending) @Sendable (
|
|
nonisolated(nonsending) @escaping (String) async throws -> String
|
|
) async throws -> Void = test
|
|
}
|
|
|
|
func testNonisolatedNonsendingClosureInGlobalActorContext() {
|
|
class NonSendable {
|
|
var state = ""
|
|
}
|
|
|
|
struct S {
|
|
static func compute(closure: nonisolated(nonsending) @Sendable @escaping (sending NonSendable) async -> Void) async {}
|
|
}
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen52testNonisolatedNonsendingClosureInGlobalActorContextyyF0D0L_yyYaF : $@convention(thin) @async () -> ()
|
|
// CHECK: [[CLOSURE:%.*]] = function_ref @$s21attr_execution_silgen52testNonisolatedNonsendingClosureInGlobalActorContextyyF0D0L_yyYaFyAaByyF11NonSendableL_CYuYaYbYCcfU_ : $@convention(thin) @Sendable @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @guaranteed NonSendable) -> ()
|
|
// CHECK: [[THICK_CLOSURE:%.*]] = thin_to_thick_function [[CLOSURE]] to $@Sendable @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @guaranteed NonSendable) -> ()
|
|
// CHECK: [[CLOSURE_THUNK:%.*]] = function_ref @$sBA21attr_execution_silgen52testNonisolatedNonsendingClosureInGlobalActorContextyyF11NonSendableL_CIeghHgILgT_BAADIeghHgILxT_TR : $@convention(thin) @Sendable @async (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @owned NonSendable, @guaranteed @Sendable @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @guaranteed NonSendable) -> ()) -> ()
|
|
// CHECK: [[THUNKED_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE_THUNK]]([[THICK_CLOSURE]])
|
|
// CHECK: [[COMPUTE:%.*]] = function_ref @$s21attr_execution_silgen52testNonisolatedNonsendingClosureInGlobalActorContextyyF1SL_V7compute7closureyyAaByyF11NonSendableL_CnYuYaYbYCc_tYaFZ : $@convention(method) @async (@guaranteed @Sendable @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @owned NonSendable) -> (), @thin S.Type) -> ()
|
|
// CHECK: apply [[COMPUTE]]([[THUNKED_CLOSURE]], {{.*}}) : $@convention(method) @async (@guaranteed @Sendable @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Builtin.ImplicitActor, @sil_sending @owned NonSendable) -> (), @thin S.Type) -> ()
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen52testNonisolatedNonsendingClosureInGlobalActorContextyyF0D0L_yyYaF'
|
|
@MainActor
|
|
func test() async {
|
|
// CHECK: // closure #1 in test #1 () in testNonisolatedNonsendingClosureInGlobalActorContext()
|
|
// CHECK: // Isolation: caller_isolation_inheriting
|
|
await S.compute { _ in
|
|
}
|
|
}
|
|
}
|