mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Specifically: 1. When we convert a function to nonisolated(nonsending), we need to make sure that in the thunk we hop upon return since nonisolated(nonsending) functions are assumed to preserve the caller's isolation. 2. When we convert a function from nonisolated(nonsending), we need to make sure that in the thunk we hop onto the actor that we are passing in as the isolated parameter of the nonisolated(nonsending) function. This ensures that the nonisolated(nonsending) function can assume that it is already on its isolated parameter's actor at function entry. rdar://155905383
591 lines
45 KiB
Swift
591 lines
45 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 Optional<any Actor>) -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()):
|
|
// CHECK: [[FUNC_COPY:%.*]] = copy_value [[FUNC]]
|
|
// CHECK: [[THUNK:%.*]] = function_ref @$sScA_pSgIegHgIL_IegH_TR : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> ()
|
|
// 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] @$sScA_pSgIegHgIL_IegH_TR : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()):
|
|
// CHECK: [[ENUM:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK: hop_to_executor [[ENUM]]
|
|
// CHECK: apply [[FUNC]]([[ENUM]])
|
|
// CHECK: } // end sil function '$sScA_pSgIegHgIL_IegH_TR'
|
|
|
|
// CHECK-LABEL: sil [ossa] @$s21attr_execution_silgen31testCallerToConcurrentMainActoryyyyYaYCcYaF : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()):
|
|
// CHECK: [[FUNC_COPY:%.*]] = copy_value [[FUNC]]
|
|
// CHECK: [[THUNK:%.*]] = function_ref @$sScA_pSgIegHgIL_IegH_TR : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> ()
|
|
// 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_ScA_pSgIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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_ScA_pSgIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed @async @callee_guaranteed () -> ()) -> () {
|
|
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed () -> ()):
|
|
// CHECK: apply [[FUNC]]
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: } // end sil function '$sIegH_ScA_pSgIegHgIL_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_ScA_pSgIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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 Optional<any Actor>) -> ()) -> () {
|
|
// CHECK: bb0([[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()):
|
|
// 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 Optional<any Actor>) -> ()) -> () {
|
|
// CHECK: bb0([[PARAM:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any 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:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK: [[Y2_B_C_B:%.*]] = begin_borrow [[Y2_B_C]]
|
|
// CHECK: apply [[Y2_B_C_B]]([[ACTOR]])
|
|
// 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 Optional<any Actor>) -> ()) -> () {
|
|
// CHECK: bb0([[PARAM:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()):
|
|
// CHECK: [[PARAM_COPY:%.*]] = copy_value [[PARAM]]
|
|
// CHECK: [[THUNK_1:%.*]] = function_ref @$sScA_pSgIegHgIL_IegH_TR : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> ()
|
|
// 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_ScA_pSgIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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_ScA_pSgIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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 @$sScA_pSgIegHgIL_IegH_TR : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> ()
|
|
// 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 Optional<any Actor>) -> ()) -> () {
|
|
// CHECK: bb0([[X:%.*]] : @guaranteed $@async @callee_guaranteed () -> (), [[Y:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()):
|
|
// CHECK: [[GLOBAL_CALLER_FUNC:%.*]] = function_ref @$s21attr_execution_silgen16globalCallerFuncyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
|
|
// FIVE: [[TTFI:%.*]] = thin_to_thick_function [[GLOBAL_CALLER_FUNC]] to $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
|
|
// FIVE: [[THUNK:%.*]] = function_ref @$sScA_pSgIegHgIL_IegH_TRScMTU : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> ()
|
|
// FIVE: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[TTFI]]) :
|
|
// SIX: [[THUNK:%.*]] = function_ref @$sScA_pSgIetHgIL_IeghH_TRScMTU : $@convention(thin) @Sendable @async (@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> ()
|
|
// 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 @$sScA_pSgIegHgIL_IegH_TRScMTU : $@convention(thin) @async (@guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> ()
|
|
// 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'
|
|
|
|
// 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>) -> ()) -> () {
|
|
// FIVE: bb0([[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: apply [[FUNC]]([[E_OPT]]) : $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
|
|
// FIVE: } // end sil function '$sScA_pSgIegHgIL_IegH_TRScMTU'
|
|
|
|
// 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>) -> ()) -> () {
|
|
// 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: apply [[FUNC]]([[E_OPT]]) : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
|
|
// SIX: } // end sil function '$sScA_pSgIetHgIL_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 Optional<any Actor>, @guaranteed SendableKlass) -> ()) -> () {
|
|
// CHECK: bb0([[X:%.*]] : @guaranteed $@async @callee_guaranteed (@guaranteed SendableKlass) -> (), [[Y:%.*]] : @guaranteed $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass) -> ()):
|
|
// CHECK: [[GLOBAL_CALLER_FUNC:%.*]] = function_ref @$s21attr_execution_silgen29globalCallerFuncSendableKlassyyAA0gH0CYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass) -> ()
|
|
// FIVE: [[TTFI:%.*]] = thin_to_thick_function [[GLOBAL_CALLER_FUNC]] to $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass) -> ()
|
|
// FIVE: [[THUNK:%.*]] = function_ref @$sScA_pSg21attr_execution_silgen13SendableKlassCIegHgILg_ADIegHg_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass) -> ()) -> ()
|
|
// FIVE: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[TTFI]]) :
|
|
// SIX: [[THUNK:%.*]] = function_ref @$sScA_pSg21attr_execution_silgen13SendableKlassCIetHgILg_ADIeghHg_TRScMTU : $@convention(thin) @Sendable @async (@guaranteed SendableKlass, @convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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 @$sScA_pSg21attr_execution_silgen13SendableKlassCIegHgILg_ADIegHg_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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] @$sScA_pSg21attr_execution_silgen13SendableKlassCIegHgILg_ADIegHg_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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: apply [[FUNC]]([[E_OPT]], [[ARG]])
|
|
// FIVE: } // end sil function '$sScA_pSg21attr_execution_silgen13SendableKlassCIegHgILg_ADIegHg_TRScMTU
|
|
|
|
// SIX-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sScA_pSg21attr_execution_silgen13SendableKlassCIetHgILg_ADIeghHg_TRScMTU : $@convention(thin) @Sendable @async (@guaranteed SendableKlass, @convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass) -> ()) -> () {
|
|
// SIX: bb0([[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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: apply [[FUNC]]([[E_OPT]], [[ARG]])
|
|
// SIX: // end sil function '$sScA_pSg21attr_execution_silgen13SendableKlassCIetHgILg_ADIeghHg_TRScMTU'
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sScA_pSg21attr_execution_silgen13SendableKlassCIegHgILg_ADIegHg_TR : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass) -> ()) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : @guaranteed
|
|
// CHECK: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: apply [[FUNC]]([[ACTOR]], [[ARG]])
|
|
// CHECK: } // end sil function '$sScA_pSg21attr_execution_silgen13SendableKlassCIegHgILg_ADIegHg_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 Optional<any Actor>, @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 Optional<any Actor>, @guaranteed SendableKlass) -> @owned SendableKlass):
|
|
// CHECK: [[GLOBAL_CALLER_FUNC:%.*]] = function_ref @$s21attr_execution_silgen29globalCallerFuncSendableKlassyAA0gH0CADYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass) -> @owned SendableKlass
|
|
// FIVE: [[TTFI:%.*]] = thin_to_thick_function [[GLOBAL_CALLER_FUNC]] to $@async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass) -> @owned SendableKlass
|
|
// FIVE: [[THUNK:%.*]] = function_ref @$sScA_pSg21attr_execution_silgen13SendableKlassCADIegHgILgo_A2DIegHgo_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass) -> @owned SendableKlass) -> @owned SendableKlass
|
|
// FIVE: [[PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK]]([[TTFI]])
|
|
// SIX: [[THUNK:%.*]] = function_ref @$sScA_pSg21attr_execution_silgen13SendableKlassCADIetHgILgo_A2DIeghHgo_TRScMTU : $@convention(thin) @Sendable @async (@guaranteed SendableKlass, @convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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 @$sScA_pSg21attr_execution_silgen13SendableKlassCADIegHgILgo_A2DIegHgo_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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 @$sScA_pSg21attr_execution_silgen13SendableKlassCADIegHgILgo_A2DIegHgo_TR : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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] @$sScA_pSg21attr_execution_silgen13SendableKlassCADIegHgILgo_A2DIegHgo_TRScMTU : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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: apply [[FUNC]]([[E_OPT]], [[ARG]])
|
|
// FIVE: } // end sil function '$sScA_pSg21attr_execution_silgen13SendableKlassCADIegHgILgo_A2DIegHgo_TRScMTU'
|
|
|
|
// SIX-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sScA_pSg21attr_execution_silgen13SendableKlassCADIetHgILgo_A2DIeghHgo_TRScMTU : $@convention(thin) @Sendable @async (@guaranteed SendableKlass, @convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass) -> @owned SendableKlass) -> @owned SendableKlass {
|
|
// SIX: bb0([[ARG:%.*]] : @guaranteed $SendableKlass, [[FUNC:%.*]] : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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: apply [[FUNC]]([[E_OPT]], [[ARG]])
|
|
// SIX: } // end sil function '$sScA_pSg21attr_execution_silgen13SendableKlassCADIetHgILgo_A2DIeghHgo_TRScMTU'
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sScA_pSg21attr_execution_silgen13SendableKlassCADIegHgILgo_A2DIegHgo_TR : $@convention(thin) @async (@guaranteed SendableKlass, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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 '$sScA_pSg21attr_execution_silgen13SendableKlassCADIegHgILgo_A2DIegHgo_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_ScA_pSgACIegHgILg_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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_ScA_pSgACIegHgILg_TRScMTU : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @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_ScA_pSgACIegHgILg_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed NonSendableKlass, @guaranteed @Sendable @callee_guaranteed (@guaranteed NonSendableKlass) -> ()) -> () {
|
|
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>
|
|
// CHECK: apply {{%.*}}({{%.*}}) : $@Sendable @callee_guaranteed (@guaranteed NonSendableKlass) -> ()
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen16NonSendableKlassCIeghg_ScA_pSgACIegHgILg_TR'
|
|
|
|
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$s21attr_execution_silgen13SendableKlassCIeghg_ScA_pSgACIegHgILg_TRScMTU : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SendableKlass, @guaranteed @Sendable @callee_guaranteed (@guaranteed SendableKlass) -> ()) -> () {
|
|
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[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_ScA_pSgACIegHgILg_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_tFyyYacfU_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
|
|
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>):
|
|
// 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_tFyyYaXEfU0_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
|
|
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>):
|
|
// CHECK: hop_to_executor [[EXECUTOR]]
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaXEfU0_'
|
|
|
|
// 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>) -> ()) -> () {
|
|
// FIVE: bb0([[FUNC:%.*]] : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()):
|
|
// FIVE: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
|
|
// FIVE: hop_to_executor [[ACTOR]]
|
|
// FIVE: apply [[FUNC]]([[ACTOR]])
|
|
// FIVE: } // end sil function '$sScA_pSgIetHgIL_IegH_TR'
|
|
|
|
// 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 {
|
|
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[FUNC:%.*]] : @guaranteed $@noescape @async @callee_guaranteed () -> ()):
|
|
// CHECK: apply [[FUNC]]()
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: } // end sil function '$sIgH_ScA_pSgs5Error_pIegHgILzo_TR'
|
|
testParam { 42 }
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFyyYaXEfU1_ : $@convention(thin) @async () -> ()
|
|
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
|
|
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]]
|
|
testParam { @concurrent in 42 }
|
|
|
|
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen31testThatClosuresAssumeIsolation2fnyySiYaYCcz_tFySiYacfU2_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, Int) -> () {
|
|
// CHECK: bb0([[EXECUTOR:%.*]] : @guaranteed $Optional<any Actor>, %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<Builtin.Executor>, #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_ScA_pSgSiIegHgILy_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, Int, @guaranteed @async @callee_guaranteed (Int) -> ()) -> () {
|
|
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[ARG:%.*]] : $Int, [[FUNC:%.*]] : @guaranteed $@async @callee_guaranteed (Int) -> ()):
|
|
// CHECK: apply [[FUNC]]([[ARG]])
|
|
// CHECK: hop_to_executor [[ACTOR]]
|
|
// CHECK: } // end sil function '$sSiIegHy_ScA_pSgSiIegHgILy_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<Builtin.Executor>, #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<Builtin.Executor>, #Optional.none!enumelt
|
|
// CHECK-NEXT: hop_to_executor [[GENERIC_EXECUTOR]]
|
|
// CHECK: } // end sil function '$s21attr_execution_silgen55testClosuresDontAssumeGlobalActorWithMarkedAsConcurrentyyFyyYaYbXEfU_'
|
|
test { @Sendable @concurrent in
|
|
}
|
|
}
|