Merge pull request #81338 from gottesmm/pr-e2235199764eea9659e08932699c74d60cf387b7

[concurrency] Ensure that we treat closures that are nonisolated(nonsending) via their ActorIsolation as nonisolated(nonsending).
This commit is contained in:
Michael Gottesman
2025-05-06 18:47:58 -07:00
committed by GitHub
5 changed files with 419 additions and 78 deletions

View File

@@ -2633,6 +2633,9 @@ static CanSILFunctionType getSILFunctionType(
} else if (decl->getAttrs().hasAttribute<ConcurrentAttr>()) {
actorIsolation = ActorIsolation::forNonisolated(false /*unsafe*/);
}
} else if (auto *closure = constant->getAbstractClosureExpr()) {
if (auto isolation = closure->getActorIsolation())
actorIsolation = isolation;
}
if (!actorIsolation) {

View File

@@ -765,6 +765,13 @@ static ActorIsolation getActorIsolationForFunction(SILFunction &fn) {
return ActorIsolation::forNonisolated(false);
}
// If we have a closure expr, check if our type is
// nonisolated(nonsending). In that case, we use that instead.
if (auto *closureExpr = constant.getAbstractClosureExpr()) {
if (auto actorIsolation = closureExpr->getActorIsolation())
return actorIsolation;
}
// If we have actor isolation for our constant, put the isolation onto the
// function. If the isolation is unspecified, we do not return it.
if (auto isolation =

View File

@@ -1346,8 +1346,32 @@ namespace {
new (ctx) AutoClosureExpr(/*set body later*/ nullptr, thunkTy, dc);
thunk->setParameterList(thunkParamList);
thunk->setThunkKind(AutoClosureExpr::Kind::SingleCurryThunk);
// TODO: We should do this in the ActorIsolation checker but for now it is
// too risky. This is a narrow fix for 6.2.
//
// The problem that this is working around is given an autoclosure that
// returns an autoclosure that partially applies over an instance method,
// we do not visit the inner autoclosure in the ActorIsolation checker
// meaning that we do not properly call setActorIsolation on the
// AbstractClosureExpr that we produce here.
switch (thunkTy->getIsolation().getKind()) {
case FunctionTypeIsolation::Kind::NonIsolated:
case FunctionTypeIsolation::Kind::Parameter:
case FunctionTypeIsolation::Kind::Erased:
break;
case FunctionTypeIsolation::Kind::GlobalActor:
thunk->setActorIsolation(ActorIsolation::forGlobalActor(
thunkTy->getIsolation().getGlobalActorType()));
break;
case FunctionTypeIsolation::Kind::NonIsolatedCaller:
thunk->setActorIsolation(
ActorIsolation::forCallerIsolationInheriting());
break;
}
cs.cacheType(thunk);
// If the `self` type is existential, it must be opened.
OpaqueValueExpr *baseOpened = nullptr;
Expr *origBaseExpr = baseExpr;

View File

@@ -123,6 +123,16 @@ typedef void (^NonsendableCompletionHandler)(NSString * _Nullable, NSString * _N
__attribute__((swift_async_error(zero_argument, 3)));
- (void)getIceCreamFlavorWithCompletionHandler:
(void (^)(Flavor flavor, NSError *__nullable error))completionHandler;
@property(class, strong, readonly) SlowServer *standardServer;
- (void)getValueWithKey:(NSString *)valueIdentifier
completion:(void (^)(NSString *__nullable value,
NSError *__nullable error))completionHandler;
- (void)getMainActorValueWithKey:(NSString *)valueIdentifier
completion:
(void (^)(NSString *__nullable value,
NSError *__nullable error))completionHandler
MAIN_ACTOR;
@end
@protocol RefrigeratorDelegate<NSObject>

View File

@@ -1,6 +1,10 @@
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -Xllvm -sil-print-types -emit-silgen -I %S/Inputs/custom-modules -target %target-swift-5.1-abi-triple %s -verify | %FileCheck --implicit-check-not=hop_to_executor --check-prefix=CHECK --check-prefix=CHECK-%target-cpu %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -Xllvm -sil-print-types -emit-silgen -I %S/Inputs/custom-modules -target %target-swift-5.1-abi-triple %s -verify | %FileCheck --implicit-check-not=hop_to_executor --check-prefix=CHECK --check-prefix=CHECK-%target-cpu --check-prefix CHECK-C %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-upcoming-feature NonisolatedNonsendingByDefault -Xllvm -sil-print-types -emit-silgen -I %S/Inputs/custom-modules -target %target-swift-5.1-abi-triple %s -verify | %FileCheck --implicit-check-not=hop_to_executor --check-prefix=CHECK --check-prefix=CHECK-%target-cpu --check-prefix CHECK-NN %s
// REQUIRES: concurrency
// REQUIRES: objc_interop
// REQUIRES: swift_feature_NonisolatedNonsendingByDefault
import Foundation
import ObjCConcurrency
@@ -15,42 +19,46 @@ import ObjCConcurrency
// CHECK-LABEL: sil {{.*}}@{{.*}}15testSlowServing
func testSlowServing(p: SlowServing) async throws {
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK-NN: bb0([[HOP_TARGET:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[HOP_TARGET:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[HOP_TARGET]] :
// CHECK: objc_method {{.*}} $@convention(objc_method) <τ_0_0 where τ_0_0 : SlowServing> (@convention(block) (Int) -> (), τ_0_0) -> ()
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK: hop_to_executor [[HOP_TARGET]] :
let _: Int = await p.requestInt()
// CHECK: objc_method {{.*}} $@convention(objc_method) <τ_0_0 where τ_0_0 : SlowServing> (@convention(block) (NSString) -> (), τ_0_0) -> ()
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK: hop_to_executor [[HOP_TARGET]] :
let _: String = await p.requestString()
// CHECK: objc_method {{.*}} $@convention(objc_method) <τ_0_0 where τ_0_0 : SlowServing> (@convention(block) (Int, NSString) -> (), τ_0_0) -> ()
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK: hop_to_executor [[HOP_TARGET]] :
let _: (Int, String) = await p.requestIntAndString()
// CHECK: objc_method {{.*}} $@convention(objc_method) <τ_0_0 where τ_0_0 : SlowServing> (@convention(block) (Int, Optional<NSString>, Optional<NSError>) -> (), τ_0_0) -> ()
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK: hop_to_executor [[HOP_TARGET]] :
// CHECK: hop_to_executor [[HOP_TARGET]] :
// CHECK-NEXT: builtin "willThrow"
let _: (Int, String) = try await p.tryRequestIntAndString()
}
// CHECK-LABEL: sil {{.*}}@{{.*}}20testSlowServingAgain
func testSlowServingAgain(p: SlowServing) async throws {
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK-NN: bb0([[HOP_TARGET:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[HOP_TARGET:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[HOP_TARGET]] :
// CHECK: objc_method {{.*}} $@convention(objc_method) <τ_0_0 where τ_0_0 : SlowServing> (@convention(block) (Optional<NSString>, Optional<NSError>) -> (), τ_0_0) -> ()
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK: hop_to_executor [[HOP_TARGET]] :
// CHECK: hop_to_executor [[HOP_TARGET]] :
// CHECK-NEXT: builtin "willThrow"
let _: String = try await p.tryRequestString()
}
class SlowSwiftServer: NSObject, SlowServing {
// CHECK-LABEL: sil {{.*}} @$s21objc_async_from_swift15SlowSwiftServerC10requestIntSiyYaF
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK-NN: bb0([[HOP_TARGET:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[HOP_TARGET:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[HOP_TARGET]] :
// CHECK: } // end sil function '$s21objc_async_from_swift15SlowSwiftServerC10requestIntSiyYaF{{.*}}'
// CHECK-LABEL: sil private {{.*}} @${{.*}}10requestInt{{.*}}To :
// CHECK: [[BLOCK_COPY:%.*]] = copy_block %0
// CHECK: [[SELF:%.*]] = copy_value %1
@@ -66,11 +74,13 @@ class SlowSwiftServer: NSObject, SlowServing {
func requestInt() async -> Int { return 0 }
func requestString() async -> String { return "" }
// CHECK-LABEL: sil {{.*}} @$s21objc_async_from_swift15SlowSwiftServerC13requestStringSSyYaF
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK-NN: bb0([[HOP_TARGET:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[HOP_TARGET:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[HOP_TARGET]] :
// CHECK-LABEL: sil {{.*}} @$s21objc_async_from_swift15SlowSwiftServerC16tryRequestStringSSyYaKF
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK-NN: bb0([[HOP_TARGET:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[HOP_TARGET:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[HOP_TARGET]] :
// CHECK-LABEL: sil shared {{.*}} @${{.*}}16tryRequestString{{.*}}U_To :
// CHECK: [[BLOCK_COPY:%.*]] = copy_block %0
// CHECK: try_apply{{.*}}@async{{.*}}, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]]
@@ -85,13 +95,15 @@ class SlowSwiftServer: NSObject, SlowServing {
func tryRequestString() async throws -> String { return "" }
// CHECK-LABEL: sil {{.*}} @$s21objc_async_from_swift15SlowSwiftServerC19requestIntAndStringSi_SStyYaF
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK-NN: bb0([[HOP_TARGET:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[HOP_TARGET:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[HOP_TARGET]] :
func requestIntAndString() async -> (Int, String) { return (0, "") }
// CHECK-LABEL: sil {{.*}} @$s21objc_async_from_swift15SlowSwiftServerC22tryRequestIntAndStringSi_SStyYaKF
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]] :
// CHECK-NN: bb0([[HOP_TARGET:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[HOP_TARGET:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK: hop_to_executor [[HOP_TARGET]] :
func tryRequestIntAndString() async throws -> (Int, String) { return (0, "") }
}
@@ -108,19 +120,30 @@ extension SlowServer: NativelySlowServing {}
class SlowServerlet: SlowServer {
// Native Function
//
// CHECK-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> Int
// CHECK-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>
// CHECK: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: // end sil function '$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaF'
// CHECK-C-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> Int
// CHECK-C-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>
// CHECK-C: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-C: hop_to_executor [[ACTOR]]
// CHECK-C: // end sil function '$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaF'
// CHECK-NN-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String, @guaranteed SlowServerlet) -> Int {
// CHECK-NN: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: } // end sil function '$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaF'
// TODO: We are labeling this as having caller_isolation_inheriting when NN
// is enabled... but we do not have an actor parameter. This is incorrect.
//
// @objc thunk closure
//
// CHECK-LABEL: sil shared [thunk] [ossa] @$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaFyyYacfU_To : $@convention(thin) @Sendable @async (NSString, Optional<@convention(block) @Sendable (Int) -> ()>, SlowServerlet) -> () {
// CHECK-NN: [[NONE:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
// CHECK: [[STR_ARG:%.*]] = begin_borrow {{.*}} : $String
// CHECK: [[SELF:%.*]] = begin_borrow {{.*}} : $SlowServerlet
// CHECK: [[FUNC:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> Int
// CHECK: apply [[FUNC]]([[STR_ARG]], [[SELF]])
// CHECK-C: [[FUNC:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> Int
// CHECK-C: apply [[FUNC]]([[STR_ARG]], [[SELF]])
// CHECK-NN: [[FUNC:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String, @guaranteed SlowServerlet) -> Int
// CHECK-NN: apply [[FUNC]]([[NONE]], [[STR_ARG]], [[SELF]])
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC011doSomethingE8NullablyySiSSYaFyyYacfU_To'
override func doSomethingSlowNullably(_: String) async -> Int {
return 0
@@ -128,18 +151,26 @@ class SlowServerlet: SlowServer {
// Native function.
//
// CHECK-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> @owned String
// CHECK-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>
// CHECK: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-NEXT: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaF'
// CHECK-C-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> @owned String
// CHECK-C-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>
// CHECK-C: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-C-NEXT: hop_to_executor [[ACTOR]]
// CHECK-C: } // end sil function '$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaF'
// CHECK-NN-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String, @guaranteed SlowServerlet) -> @owned String {
// CHECK-NN: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: } // end sil function '$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaF'
// @objc closure thunk
// CHECK-LABEL: sil shared [thunk] [ossa] @$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaFyyYacfU_To : $@convention(thin) @Sendable @async (NSString, Optional<@convention(block) @Sendable (NSString) -> ()>, SlowServerlet) -> () {
// CHECK-NN: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
// CHECK: [[STR_ARG:%.*]] = begin_borrow {{.*}} : $String
// CHECK: [[SELF:%.*]] = begin_borrow {{.*}} : $SlowServerlet
// CHECK: [[FUNC:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> @owned String
// CHECK: apply [[FUNC]]([[STR_ARG]], [[SELF]])
// CHECK-C: [[FUNC:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> @owned String
// CHECK-C: apply [[FUNC]]([[STR_ARG]], [[SELF]])
// CHECK-NN: [[FUNC:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String, @guaranteed SlowServerlet) -> @owned String
// CHECK-NN: apply [[FUNC]]([[ACTOR]], [[STR_ARG]], [[SELF]])
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC18findAnswerNullablyyS2SYaFyyYacfU_To'
override func findAnswerNullably(_ x: String) async -> String {
return x
@@ -147,19 +178,27 @@ class SlowServerlet: SlowServer {
// Native
//
// CHECK-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-NEXT: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKF'
// CHECK-C-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-C-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-C-NEXT: hop_to_executor [[ACTOR]]
// CHECK-C: } // end sil function '$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKF'
// CHECK-NN-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String, @guaranteed SlowServerlet) -> (@owned String, @error any Error) {
// CHECK-NN: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: } // end sil function '$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKF'
// @objc thunk closure
//
// CHECK-LABEL: sil shared [thunk] [ossa] @$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKFyyYacfU_To : $@convention(thin) @Sendable @async (NSString, Optional<@convention(block) @Sendable (Optional<NSString>, Optional<NSError>) -> ()>, SlowServerlet) -> () {
// CHECK-NN: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
// CHECK: [[STR_ARG:%.*]] = begin_borrow {{.*}} : $String
// CHECK: [[SELF:%.*]] = begin_borrow {{.*}} : $SlowServerlet
// CHECK: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK: apply [[NATIVE]]([[STR_ARG]], [[SELF]])
// CHECK-C: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKF : $@convention(method) @async (@guaranteed String, @guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-C: apply [[NATIVE]]([[STR_ARG]], [[SELF]])
// CHECK-NN: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String, @guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-NN: apply [[NATIVE]]([[ACTOR]], [[STR_ARG]], [[SELF]])
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC28doSomethingDangerousNullablyyS2SYaKFyyYacfU_To'
override func doSomethingDangerousNullably(_ x: String) async throws -> String {
return x
@@ -167,17 +206,25 @@ class SlowServerlet: SlowServer {
// Native
//
// CHECK-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-NEXT: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKF'
// CHECK-C-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-C-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-C-NEXT: hop_to_executor [[ACTOR]]
// CHECK-C: } // end sil function '$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKF'
// CHECK-NN-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SlowServerlet) -> (@owned String, @error any Error) {
// CHECK-NN: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: } // end sil function '$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKF'
// @objc closure thunk
// CHECK-LABEL: sil shared [thunk] [ossa] @$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKFyyYacfU_To : $@convention(thin) @Sendable @async (Optional<@convention(block) @Sendable (Optional<NSString>, Optional<NSError>) -> ()>, SlowServerlet) -> () {
// CHECK-NN: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
// CHECK: [[SELF:%.*]] = begin_borrow {{.*}} : $SlowServerlet
// CHECK: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK: apply [[NATIVE]]([[SELF]])
// CHECK-C: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-C: try_apply [[NATIVE]]([[SELF]])
// CHECK-NN: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-NN: try_apply [[NATIVE]]([[ACTOR]], [[SELF]])
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC30doSomethingUnspecifiedNullablySSyYaKFyyYacfU_To'
override func doSomethingUnspecifiedNullably() async throws -> String {
fatalError()
@@ -185,20 +232,31 @@ class SlowServerlet: SlowServer {
// Native
//
// CHECK-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC17doSomethingFlaggySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-NEXT: hop_to_executor [[ACTOR]]
// CHECK-C-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC17doSomethingFlaggySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-C-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-C-NEXT: hop_to_executor [[ACTOR]]
// CHECK-C: } // end sil function '$s21objc_async_from_swift13SlowServerletC17doSomethingFlaggySSyYaKF'
// CHECK-NN-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC17doSomethingFlaggySSyYaKF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SlowServerlet) -> (@owned String, @error any Error) {
// CHECK-NN: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: } // end sil function '$s21objc_async_from_swift13SlowServerletC17doSomethingFlaggySSyYaKF'
// @objc thunk closure
// CHECK-LABEL: sil shared [thunk] [ossa] @$s21objc_async_from_swift13SlowServerletC17doSomethingFlaggySSyYaKFyyYacfU_To : $@convention(thin) @Sendable @async (@convention(block) @Sendable ({{.*}}, Optional<NSString>, Optional<NSError>) -> (), SlowServerlet) -> () {
// CHECK: [[SELF:%.*]] = begin_borrow {{.*}} : $SlowServerlet
// CHECK: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC17doSomethingFlaggySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK: try_apply [[NATIVE]]([[SELF]]) : {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
// CHECK-NN: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
// CHECK: [[SELF:%.*]] = begin_borrow {{.*}} : $SlowServerlet
// CHECK-C: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC17doSomethingFlaggySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-C: try_apply [[NATIVE]]([[SELF]]) : {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
// CHECK-NN: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC17doSomethingFlaggySSyYaKF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-NN: try_apply [[NATIVE]]([[ACTOR]], [[SELF]]) : {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
//
// CHECK: [[NORMAL_BB]]({{.*}}):
// CHECK: integer_literal {{.*}}0
// CHECK: integer_literal {{.*}}0
//
// CHECK: [[ERROR_BB]]({{.*}}):
// CHECK: integer_literal {{.*}}1
// CHECK: integer_literal {{.*}}1
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC17doSomethingFlaggySSyYaKFyyYacfU_To'
override func doSomethingFlaggy() async throws -> String {
return ""
@@ -206,39 +264,59 @@ class SlowServerlet: SlowServer {
// Native
//
// CHECK-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC21doSomethingZeroFlaggySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-NEXT: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC21doSomethingZeroFlaggySSyYaKF'
// CHECK-C-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC21doSomethingZeroFlaggySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-C-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-C-NEXT: hop_to_executor [[ACTOR]]
// CHECK-C: } // end sil function '$s21objc_async_from_swift13SlowServerletC21doSomethingZeroFlaggySSyYaKF'
//
// CHECK-NN-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC21doSomethingZeroFlaggySSyYaKF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SlowServerlet) -> (@owned String, @error any Error) {
// CHECK-NN: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: } // end sil function '$s21objc_async_from_swift13SlowServerletC21doSomethingZeroFlaggySSyYaKF'
//
// @objc thunk closure
// CHECK-LABEL: sil shared [thunk] [ossa] @$s21objc_async_from_swift13SlowServerletC21doSomethingZeroFlaggySSyYaKFyyYacfU_To : $@convention(thin) @Sendable @async (@convention(block) @Sendable (Optional<NSString>, {{.*}}, Optional<NSError>) -> (), SlowServerlet) -> () {
// CHECK: [[SELF:%.*]] = begin_borrow {{.*}} : $SlowServerlet
// CHECK: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC21doSomethingZeroFlaggySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK: try_apply [[NATIVE]]([[SELF]]) : {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
// CHECK-NN: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
// CHECK: [[SELF:%.*]] = begin_borrow {{.*}} : $SlowServerlet
// CHECK-C: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC21doSomethingZeroFlaggySSyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-C: try_apply [[NATIVE]]([[SELF]]) : {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
// CHECK-NN: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC21doSomethingZeroFlaggySSyYaKF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SlowServerlet) -> (@owned String, @error any Error)
// CHECK-NN: try_apply [[NATIVE]]([[ACTOR]], [[SELF]]) : {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
//
// CHECK: [[NORMAL_BB]]({{.*}}):
// CHECK: integer_literal {{.*}}1
// CHECK: integer_literal {{.*}}1
//
// CHECK: [[ERROR_BB]]({{.*}}):
// CHECK: integer_literal {{.*}}0
// CHECK: integer_literal {{.*}}0
override func doSomethingZeroFlaggy() async throws -> String {
return ""
}
// Native
//
// CHECK-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @owned String, @error any Error)
// CHECK-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-NEXT: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKF'
// CHECK-C-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @owned String, @error any Error)
// CHECK-C-NOT: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-C: [[ACTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-C-NEXT: hop_to_executor [[ACTOR]]
// CHECK-C: } // end sil function '$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKF'
//
// CHECK-NN-LABEL: sil hidden [ossa] @$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SlowServerlet) -> (@owned String, @owned String, @error any Error) {
// CHECK-NN: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: } // end sil function '$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKF'
//
// CHECK-LABEL: sil shared [thunk] [ossa] @$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKFyyYacfU_To : $@convention(thin) @Sendable @async (@convention(block) @Sendable ({{.*}}, Optional<NSString>, Optional<NSError>, Optional<NSString>) -> (), SlowServerlet) -> () {
// CHECK: [[SELF:%.*]] = begin_borrow {{.*}} : $SlowServerlet
// CHECK: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @owned String, @error any Error)
// CHECK: try_apply [[NATIVE]]([[SELF]]) : {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
// CHECK-NN: [[ACTOR:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
// CHECK: [[SELF:%.*]] = begin_borrow {{.*}} : $SlowServerlet
// CHECK-C: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKF : $@convention(method) @async (@guaranteed SlowServerlet) -> (@owned String, @owned String, @error any Error)
// CHECK-C: try_apply [[NATIVE]]([[SELF]]) : {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
// CHECK-NN: [[NATIVE:%.*]] = function_ref @$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SlowServerlet) -> (@owned String, @owned String, @error any Error)
// CHECK-NN: try_apply [[NATIVE]]([[ACTOR]], [[SELF]]) : {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
//
// CHECK: [[NORMAL_BB]]({{.*}}):
// CHECK: integer_literal {{.*}}1
//
// CHECK: [[ERROR_BB]]({{.*}}):
// CHECK: integer_literal {{.*}}0
// CHECK: } // end sil function '$s21objc_async_from_swift13SlowServerletC28doSomethingMultiResultFlaggySS_SStyYaKFyyYacfU_To'
@@ -294,3 +372,222 @@ actor Dril: NSObject {
return true
}
}
// Check that we do not crash here and emit the autoclosures correctly
func testAutoclosureInStaticMethod() {
final class TestKlass {
// Default argument for method.
//
// CHECK-LABEL: sil private [ossa] @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_ : $@convention(thin) () -> @owned @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error) {
//
// Get standard.
// CHECK: [[METATYPE:%.*]] = metatype $@objc_metatype SlowServer.Type
// CHECK: [[GET_STANDARD_FUNC:%.*]] = objc_method %1 : $@objc_metatype SlowServer.Type, #SlowServer.standard!getter.foreign : (SlowServer.Type) -> () -> SlowServer, $@convention(objc_method) (@objc_metatype SlowServer.Type) -> @autoreleased SlowServer
// CHECK: [[STANDARD:%.*]] = apply [[GET_STANDARD_FUNC]]([[METATYPE]])
//
// Then grab value.
// CHECK: [[GET_VALUE:%.*]] = function_ref @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKYCcSo10SlowServerCcfu_ : $@convention(thin) (@guaranteed SlowServer) -> @owned @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String) -> (@owned String, @error any Error)
// CHECK: [[RESULT:%.*]] = apply [[GET_VALUE]]([[STANDARD]])
//
// Then we need to thunk to eliminate the implicit leading parameter. We use
// the thunk that passes in .none so this acts as a concurrent function.
//
// CHECK: [[THUNK_FN:%.*]] = function_ref @$sScA_pSgS2Ss5Error_pIegHggozo_S2SsAB_pIegHgozo_TR : $@convention(thin) @async (@guaranteed String, @guaranteed @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String) -> (@owned String, @error any Error)) -> (@owned String, @error any Error)
// CHECK: [[THUNKED:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]([[RESULT]])
// CHECK: return [[THUNKED]]
// CHECK: } // end sil function '$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_'
// This is the first implicit closure. We close over self here.
//
// CHECK-LABEL: sil private [ossa] @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKYCcSo10SlowServerCcfu_ : $@convention(thin) (@guaranteed SlowServer) -> @owned @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String) -> (@owned String, @error any Error) {
// CHECK: bb0([[SELF:%.*]] :
//
// Close over self and return it.
// CHECK: [[SECOND_CLOSURE:%.*]] = function_ref @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKYCcSo10SlowServerCcfu_S2SYaKYCcfu0_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String, @guaranteed SlowServer) -> (@owned String, @error any Error)
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
// CHECK: [[CLOSE_OVER_SELF:%.*]] = partial_apply [callee_guaranteed] [[SECOND_CLOSURE]]([[SELF_COPY]])
// CHECK: return [[CLOSE_OVER_SELF]]
// CHECK: } // end sil function '$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKYCcSo10SlowServerCcfu_'
// The second closure. In this function we actually perform the objective-c call.
// CHECK-LABEL: sil private [ossa] @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKYCcSo10SlowServerCcfu_S2SYaKYCcfu0_ : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String, @guaranteed SlowServer) -> (@owned String, @error any Error) {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[ARG:%.*]] : @guaranteed $String, [[CAPTURE:%.*]] : @closureCapture @guaranteed $SlowServer):
//
// Hop to the actor
// CHECK: hop_to_executor [[ACTOR]]
//
// Declare result
// CHECK: [[RESULT:%.*]] = alloc_stack $String
//
// Bridge string arg.
// CHECK: [[ARG_C:%.*]] = copy_value [[ARG]]
// CHECK: [[BRIDGE_FN:%.*]] = function_ref @$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF : $@convention(method) (@guaranteed String) -> @owned NSString
// CHECK: [[ARG_C_B:%.*]] = begin_borrow [[ARG_C]]
// CHECK: [[NS_STRING:%.*]] = apply [[BRIDGE_FN]]([[ARG_C_B]])
//
// ObjC Method
// CHECK: [[OBJC_METHOD:%.*]] = objc_method [[CAPTURE]]
//
// Prepare the continuation.
// CHECK: [[RAW_UNSAFE_CONT:%.*]] = get_async_continuation_addr [throws] String, [[RESULT]]
// CHECK: [[UNSAFE_CONT:%.*]] = struct $UnsafeContinuation<String, any Error> ([[RAW_UNSAFE_CONT]] :
// CHECK: [[BLOCK_STORAGE:%.*]] = alloc_stack $@block_storage Any
// CHECK: [[PROJ_BLOCK_STORAGE:%.*]] = project_block_storage [[BLOCK_STORAGE]]
// CHECK: [[INIT_PROJ_BLOCK_STORAGE:%.*]] = init_existential_addr [[PROJ_BLOCK_STORAGE]]
// CHECK: store [[UNSAFE_CONT]] to [trivial] [[INIT_PROJ_BLOCK_STORAGE]]
// CHECK: merge_isolation_region [[BLOCK_STORAGE]] : $*@block_storage Any, [[RESULT]]
// CHECK: [[OBJC_COMPLETION_HANDLER_IMPL:%.*]] = function_ref @$sSo8NSStringCSgSo7NSErrorCSgIeyBhyy_SSTz_ : $@convention(c) @Sendable (@inout_aliasable @block_storage Any, Optional<NSString>, Optional<NSError>) -> ()
// CHECK: [[BLOCK:%.*]] = init_block_storage_header [[BLOCK_STORAGE]] : $*@block_storage Any, invoke [[OBJC_COMPLETION_HANDLER_IMPL]]
// CHECK: merge_isolation_region [[CAPTURE]] : $SlowServer, [[BLOCK_STORAGE]]
// CHECK: apply [[OBJC_METHOD]]([[NS_STRING]], [[BLOCK]], [[CAPTURE]])
// CHECK: await_async_continuation [[RAW_UNSAFE_CONT]] : $Builtin.RawUnsafeContinuation, resume [[RESUME_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
//
// CHECK: [[RESUME_BB]]:
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: [[LOADED_RESULT:%.*]] = load [take] [[RESULT]]
// CHECK: return [[LOADED_RESULT]]
//
// CHECK: [[ERROR_BB]]([[ERROR:%.*]] :
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: throw [[ERROR]]
// CHECK: } // end sil function '$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKYCcSo10SlowServerCcfu_S2SYaKYCcfu0_'
// Actual static method
//
// We do not actually care about FileChecking this... we just need to
// FileCheck the hop_to_executor to show to FileCheck that we expect these
// hop_to_executor lines to occur in the function since we reject
// non-explicitly specified hop_to_executor lines.
//
// CHECK-C-LABEL: sil private [ossa] @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZ : $@convention(method) @async (@guaranteed String, @guaranteed @noescape @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error), @thick TestKlass.Type) -> @owned Optional<String> {
// CHECK-C: bb0([[STRING:%.*]] : @guaranteed $String, [[COMPLETION:%.*]] : @guaranteed $@noescape @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error), [[METATYPE:%.*]] : $@thick TestKlass.Type)
// CHECK-C: [[EXEC_NONE:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-C: hop_to_executor [[EXEC_NONE]]
// CHECK-C: hop_to_executor [[EXEC_NONE]]
// CHECK-C: hop_to_executor [[EXEC_NONE]]
// CHECK-C: } // end sil function '$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZ'
//
// CHECK-NN-LABEL: sil private [ossa] @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZ : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String, @guaranteed @noescape @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error), @thick TestKlass.Type) -> @owned Optional<String> {
// CHECK-NN: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[STRING:%.*]] : @guaranteed $String, [[COMPLETION:%.*]] : @guaranteed $@noescape @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error), [[METATYPE:%.*]] : $@thick TestKlass.Type)
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: } // end sil function '$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C8getValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZ'
static func getValue(id: String,
valueForKey: (_ identifier: String) async throws -> String = SlowServer.standard.value(withKey:)) async -> String? {
let result: String
do {
result = try await valueForKey(id)
} catch {
return nil
}
return result
}
// Default argument for method.
//
// CHECK-LABEL: sil private [ossa] @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_ : $@convention(thin) () -> @owned @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error) {
//
// Get standard.
// CHECK: [[METATYPE:%.*]] = metatype $@objc_metatype SlowServer.Type
// CHECK: [[GET_STANDARD_FUNC:%.*]] = objc_method %1 : $@objc_metatype SlowServer.Type, #SlowServer.standard!getter.foreign : (SlowServer.Type) -> () -> SlowServer, $@convention(objc_method) (@objc_metatype SlowServer.Type) -> @autoreleased SlowServer
// CHECK: [[STANDARD:%.*]] = apply [[GET_STANDARD_FUNC]]([[METATYPE]])
//
// Then grab value.
// CHECK: [[GET_VALUE:%.*]] = function_ref @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKScMYccSo10SlowServerCcfu_ : $@convention(thin) (@guaranteed SlowServer) -> @owned @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error)
// CHECK: [[RESULT:%.*]] = apply [[GET_VALUE]]([[STANDARD]])
//
// CHECK: return [[RESULT]]
// CHECK: } // end sil function '$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_'
// This is the first implicit closure. We close over self here.
//
// CHECK-LABEL: sil private [ossa] @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKScMYccSo10SlowServerCcfu_ : $@convention(thin) (@guaranteed SlowServer) -> @owned @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error) {
// CHECK: bb0([[SELF:%.*]] :
//
// Close over self and return it.
// CHECK: [[SECOND_CLOSURE:%.*]] = function_ref @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKScMYccSo10SlowServerCcfu_S2SYaKScMYccfu0_ : $@convention(thin) @async (@guaranteed String, @guaranteed SlowServer) -> (@owned String, @error any Error)
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
// CHECK: [[CLOSE_OVER_SELF:%.*]] = partial_apply [callee_guaranteed] [[SECOND_CLOSURE]]([[SELF_COPY]])
// CHECK: return [[CLOSE_OVER_SELF]]
// CHECK: } // end sil function '$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKScMYccSo10SlowServerCcfu_'
// The second closure. In this function we actually perform the objective-c call.
//
// It is main actor isolated.
//
// CHECK-LABEL: sil private [ossa] @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKScMYccSo10SlowServerCcfu_S2SYaKScMYccfu0_ : $@convention(thin) @async (@guaranteed String, @guaranteed SlowServer) -> (@owned String, @error any Error) {
// CHECK: bb0([[ARG:%.*]] : @guaranteed $String, [[CAPTURE:%.*]] : @closureCapture @guaranteed $SlowServer):
//
// CHECK: [[ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
//
// Hop to the actor
// CHECK: [[ACTOR_B:%.*]] = begin_borrow [[ACTOR]]
// CHECK: hop_to_executor [[ACTOR_B]]
//
// Declare result
// CHECK: [[RESULT:%.*]] = alloc_stack $String
//
// Bridge string arg.
// CHECK: [[ARG_C:%.*]] = copy_value [[ARG]]
// CHECK: [[BRIDGE_FN:%.*]] = function_ref @$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF : $@convention(method) (@guaranteed String) -> @owned NSString
// CHECK: [[ARG_C_B:%.*]] = begin_borrow [[ARG_C]]
// CHECK: [[NS_STRING:%.*]] = apply [[BRIDGE_FN]]([[ARG_C_B]])
//
// ObjC Method
// CHECK: [[OBJC_METHOD:%.*]] = objc_method [[CAPTURE]]
//
// Prepare the continuation.
// CHECK: [[RAW_UNSAFE_CONT:%.*]] = get_async_continuation_addr [throws] String, [[RESULT]]
// CHECK: [[UNSAFE_CONT:%.*]] = struct $UnsafeContinuation<String, any Error> ([[RAW_UNSAFE_CONT]] :
// CHECK: [[BLOCK_STORAGE:%.*]] = alloc_stack $@block_storage Any
// CHECK: [[PROJ_BLOCK_STORAGE:%.*]] = project_block_storage [[BLOCK_STORAGE]]
// CHECK: [[INIT_PROJ_BLOCK_STORAGE:%.*]] = init_existential_addr [[PROJ_BLOCK_STORAGE]]
// CHECK: store [[UNSAFE_CONT]] to [trivial] [[INIT_PROJ_BLOCK_STORAGE]]
// CHECK: merge_isolation_region [[BLOCK_STORAGE]] : $*@block_storage Any, [[RESULT]]
// CHECK: [[OBJC_COMPLETION_HANDLER_IMPL:%.*]] = function_ref @$sSo8NSStringCSgSo7NSErrorCSgIeyBhyy_SSTz_ : $@convention(c) @Sendable (@inout_aliasable @block_storage Any, Optional<NSString>, Optional<NSError>) -> ()
// CHECK: [[BLOCK:%.*]] = init_block_storage_header [[BLOCK_STORAGE]] : $*@block_storage Any, invoke [[OBJC_COMPLETION_HANDLER_IMPL]]
// CHECK: merge_isolation_region [[CAPTURE]] : $SlowServer, [[BLOCK_STORAGE]]
// CHECK: apply [[OBJC_METHOD]]([[NS_STRING]], [[BLOCK]], [[CAPTURE]])
// CHECK: await_async_continuation [[RAW_UNSAFE_CONT]] : $Builtin.RawUnsafeContinuation, resume [[RESUME_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
//
// CHECK: [[RESUME_BB]]:
// CHECK: hop_to_executor [[ACTOR_B]]
// CHECK: [[LOADED_RESULT:%.*]] = load [take] [[RESULT]]
// CHECK: return [[LOADED_RESULT]]
//
// CHECK: [[ERROR_BB]]([[ERROR:%.*]] :
// CHECK: hop_to_executor [[ACTOR_B]]
// CHECK: throw [[ERROR]]
// CHECK: } // end sil function '$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZfA0_S2SYaKScMYccSo10SlowServerCcfu_S2SYaKScMYccfu0_'
// Actual static method
//
// This is not main actor isolated
//
// CHECK-C-LABEL: sil private [ossa] @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZ : $@convention(method) @async (@guaranteed String, @guaranteed @noescape @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error), @thick TestKlass.Type) -> @owned Optional<String> {
// CHECK-C: bb0([[STRING:%.*]] : @guaranteed $String, [[COMPLETION:%.*]] : @guaranteed $@noescape @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error), [[METATYPE:%.*]] : $@thick TestKlass.Type)
// CHECK-C: [[EXEC_NONE:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
// CHECK-C: hop_to_executor [[EXEC_NONE]]
// CHECK-C: hop_to_executor [[EXEC_NONE]]
// CHECK-C: hop_to_executor [[EXEC_NONE]]
// CHECK-C: } // end sil function '$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZ'
//
// CHECK-NN-LABEL: sil private [ossa] @$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZ : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed String, @guaranteed @noescape @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error), @thick TestKlass.Type) -> @owned Optional<String> {
// CHECK-NN: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[STRING:%.*]] : @guaranteed $String, [[COMPLETION:%.*]] : @guaranteed $@noescape @async @callee_guaranteed (@guaranteed String) -> (@owned String, @error any Error), [[METATYPE:%.*]] : $@thick TestKlass.Type)
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: hop_to_executor [[ACTOR]]
// CHECK-NN: } // end sil function '$s21objc_async_from_swift29testAutoclosureInStaticMethodyyF9TestKlassL_C17getMainActorValue2id11valueForKeySSSgSS_S2SYaKXEtYaFZ'
static func getMainActorValue(id: String,
valueForKey: (_ identifier: String) async throws -> String = SlowServer.standard.mainActorValue(withKey:)) async -> String? {
let result: String
do {
result = try await valueForKey(id)
} catch {
return nil
}
return result
}
}
}