[concurrency] Emit nonisolated(nonsending) async throw initializers correctly.

Specifically, we were not inserting the implicit isolated parameter and were not
setting up the actor prologue. To keep this specific to nonisolated(nonsending)
code, I only setup the actor prologue if we know that we have something that is
nonisolated(nonsending).

I also ported some async initializer tests to run with/without
nonisolated(nonsending) just to increase code coverage.

rdar://156919493
This commit is contained in:
Michael Gottesman
2025-07-29 12:27:15 -07:00
parent 9194fa0ab7
commit 3871d22257
6 changed files with 373 additions and 74 deletions

View File

@@ -1463,6 +1463,10 @@ public:
return actorIsolation;
}
bool isNonisolatedNonsending() const {
return actorIsolation && actorIsolation->isCallerIsolationInheriting();
}
/// Return the source file that this SILFunction belongs to if it exists.
SourceFile *getSourceFile() const;

View File

@@ -5857,8 +5857,7 @@ ApplyOptions CallEmission::emitArgumentsForNormalApply(
// Now, actually handle the implicit parameters.
if (auto isolated = substFnType->maybeGetIsolatedParameter();
isolated && isolated->hasOption(SILParameterInfo::ImplicitLeading)) {
auto executor =
ManagedValue::forBorrowedObjectRValue(SGF.ExpectedExecutor.getEager());
auto executor = SGF.emitExpectedExecutor(callSite->Loc);
args.push_back({});
// NOTE: Even though this calls emitActorInstanceIsolation, this also
// handles glboal actor isolated cases.

View File

@@ -947,6 +947,15 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) {
args.push_back(arg);
}
if (F.isNonisolatedNonsending()) {
auto paramTy = F.mapTypeIntoContext(
SILType::getOpaqueIsolationType(F.getASTContext()));
auto inContextParamTy = F.getLoweredType(paramTy.getASTType())
.getCategoryType(paramTy.getCategory());
SILArgument *arg = F.begin()->createFunctionArgument(inContextParamTy);
args.push_back(arg);
}
bindParametersForForwarding(ctor->getParameters(), args);
if (ctor->requiresUnavailableDeclABICompatibilityStubs())
@@ -1002,6 +1011,12 @@ void SILGenFunction::emitClassConstructorAllocator(ConstructorDecl *ctor) {
}
args.push_back(selfValue);
// For now, just do this if we have a nonisolated(nonsending) function so we
// do not change the semantics of non-nonisolated(nonsending) functions.
if (F.isNonisolatedNonsending()) {
emitExpectedExecutorProlog();
}
// Call the initializer. Always use the Swift entry point, which will be a
// bridging thunk if we're calling ObjC.
auto initConstant = SILDeclRef(ctor, SILDeclRef::Kind::Initializer);

View File

@@ -742,10 +742,17 @@ public:
assert(Value != invalid() && Value != unnecessary());
return Value != lazy();
}
/// WARNING: Please do not call this unless you are completely sure that one
/// will always have an eager executor (i.e.: you are not emitting for an
/// initializer and more cases). To be safe please use
/// SILGenFunction::emitExpectedExecutor instead which handles the lazy case
/// correctly.
SILValue getEager() const {
assert(isEager());
return Value;
}
void set(SILValue value) {
assert(Value == invalid());
assert(value != nullptr);

View File

@@ -0,0 +1,176 @@
// RUN: %target-swift-frontend -enable-experimental-concurrency -target %target-swift-5.1-abi-triple -emit-silgen -o - -strict-concurrency=complete -enable-upcoming-feature NonisolatedNonsendingByDefault %s | %FileCheck --implicit-check-not=hop_to_executor %s
// REQUIRES: concurrency
// REQUIRES: swift_feature_NonisolatedNonsendingByDefault
// This file contains tests specifically for async initializers that do not
// include type checker errors so we can test the SIL part of the pipeline. Put type checker errors into
// async_initializer.swift.
// CHECK-LABEL: sil hidden [ossa] @$s11initializer1fyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>):
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s11initializer1fyyYaF'
func f() async {}
func g() {}
class Fruit {
// Fruit.__allocating_init()
// Isolation: caller_isolation_inheriting
// CHECK-LABEL: sil hidden [exact_self_class] [ossa] @$s11initializer5FruitCACyYacfC : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @thick Fruit.Type) -> @owned Fruit {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s11initializer5FruitCACyYacfC'
// Fruit.init()
// Isolation: caller_isolation_inheriting
// CHECK-LABEL: sil hidden [ossa] @$s11initializer5FruitCACyYacfc : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @owned Fruit) -> @owned Fruit {
// CHECK: bb0([[ARG:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: hop_to_executor [[ARG]]
// CHECK: } // end sil function '$s11initializer5FruitCACyYacfc'
init() async {}
// CHECK-LABEL: sil hidden [exact_self_class] [ossa] @$s11initializer5FruitC4nameACSS_tcfC : $@convention(method) (@owned String, @thick Fruit.Type) -> @owned Fruit {
// CHECK: } // end sil function '$s11initializer5FruitC4nameACSS_tcfC'
// CHECK-LABEL: sil hidden [ossa] @$s11initializer5FruitC4nameACSS_tcfc : $@convention(method) (@owned String, @owned Fruit) -> @owned Fruit {
// CHECK: } // end sil function '$s11initializer5FruitC4nameACSS_tcfc'
init(name: String) {}
}
class Banana: Fruit {
// TODO: Make this not async. We currently miscompile if this is sync.
//
// class Fruit {
// required init() async {}
// init(name: String) {}
// }
//
// class Banana: Fruit {
// override required init() {
// super.init(name: "banana")
// }
// }
//
// func test(_ x: Fruit.Type) async {
// await print(x.init())
// }
//
// await test(Banana.self)
// Banana.__allocating_init()
// Isolation: caller_isolation_inheriting
// CHECK-LABEL: sil hidden [exact_self_class] [ossa] @$s11initializer6BananaCACyYacfC : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @thick Banana.Type) -> @owned Banana {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s11initializer6BananaCACyYacfC'
// Banana.init()
// Isolation: caller_isolation_inheriting
// CHECK-LABEL: sil hidden [ossa] @$s11initializer6BananaCACyYacfc : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @owned Banana) -> @owned Banana {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s11initializer6BananaCACyYacfc'
override init() async {
super.init(name: "banana")
}
}
class MyType {
// MyType.__allocating_init(_:)
// Isolation: caller_isolation_inheriting
//
// CHECK-LABEL: sil hidden [exact_self_class] [ossa] @$s11initializer6MyTypeCyACyyYaYCXEYacfC : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed @noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> (), @thick MyType.Type) -> @owned MyType {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[ARG:%.*]] : @guaranteed $@noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: [[FUNC:%.*]] = function_ref @$s11initializer6MyTypeCyACyyYaYCXEYacfc : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed @noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> (), @owned MyType) -> @owned MyType
// CHECK: apply [[FUNC]]([[ACTOR]], [[ARG]], {{%.*}}) :
// CHECK: } // end sil function '$s11initializer6MyTypeCyACyyYaYCXEYacfC'
// MyType.init(_:)
// Isolation: caller_isolation_inheriting
// CHECK-LABEL: sil hidden [ossa] @$s11initializer6MyTypeCyACyyYaYCXEYacfc : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed @noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> (), @owned MyType) -> @owned MyType {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[ARG:%.*]] : @guaranteed $@noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> (), [[SELF:%.*]] : @owned $MyType):
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: [[ARG_C:%.*]] = copy_value [[ARG]]
// CHECK: [[ARG_B:%.*]] = begin_borrow [[ARG_C]]
// CHECK: apply [[ARG_B]]([[ACTOR]])
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s11initializer6MyTypeCyACyyYaYCXEYacfc'
init(_ f: () async -> Void) reasync {
await f()
}
}
// CHECK-LABEL: sil hidden [ossa] @$s11initializer4beepyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>):
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: [[FUNC:%.*]] = function_ref @$s11initializer6MyTypeCyACyyYaYCXEYacfC : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed @noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> (), @thick MyType.Type) -> @owned MyType
// CHECK: apply [[FUNC]]([[ACTOR]], {{%.*}}, {{%.*}})
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s11initializer4beepyyYaF'
func beep() async {
let _ = await MyType(f)
let _ = MyType(g)
}
// thunk for @escaping @callee_guaranteed () -> ()
// CHECK-LABEL: sil shared [transparent] [serialized] [reabstraction_thunk] [ossa] @$sIeg_ScA_pSgIegHgIL_TR : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed @callee_guaranteed () -> ()) -> () {
// CHECK: hop_to_executor
// CHECK: } // end sil function '$sIeg_ScA_pSgIegHgIL_TR'
actor A {
// CHECK-LABEL: sil hidden [ossa] @$s11initializer1ACACyYacfc : $@convention(method) @async (@sil_isolated @owned A) -> @owned A {
// CHECK: hop_to_executor
// CHECK: hop_to_executor
// CHECK: } // end sil function '$s11initializer1ACACyYacfc'
init() async {
await f()
}
init() {
}
}
protocol AsyncDefaultConstructable {
init() async
}
struct Location {
var x : Int
var y : Int
// CHECK-LABEL: sil hidden [ossa] @$s11initializer8LocationVACyYacfC : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @thin Location.Type) -> Location {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s11initializer8LocationVACyYacfC'
init() async {
self.x = 0
self.y = 0
}
}
extension Location: AsyncDefaultConstructable {}
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s11initializer8LocationVAA25AsyncDefaultConstructableA2aDPxyYacfCTW : $@convention(witness_method: AsyncDefaultConstructable) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @thick Location.Type) -> @out Location {
// CHECK: bb0([[INDIRECT_RESULT:%.*]] : $*Location, [[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: [[FUNC:%.*]] = function_ref @$s11initializer8LocationVACyYacfC : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @thin Location.Type) -> Location
// CHECK: apply [[FUNC]]([[ACTOR]],
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s11initializer8LocationVAA25AsyncDefaultConstructableA2aDPxyYacfCTW'
// CHECK-LABEL: sil hidden [exact_self_class] [ossa] @$s11initializer12ExplicitTestCACyYaKcfC : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @thick ExplicitTest.Type) -> (@owned ExplicitTest, @error any Error) {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: [[FUNC:%.*]] = function_ref @$s11initializer12ExplicitTestCACyYaKcfc : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @owned ExplicitTest) -> (@owned ExplicitTest, @error any Error)
// CHECK: try_apply [[FUNC]]([[ACTOR]], {{%.*}})
// CHECK: } // end sil function '$s11initializer12ExplicitTestCACyYaKcfC'
// CHECK-LABEL: sil hidden [ossa] @$s11initializer12ExplicitTestCACyYaKcfc : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @owned ExplicitTest) -> (@owned ExplicitTest, @error any Error) {
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// CHECK: hop_to_executor [[ACTOR]]
// CHECK: } // end sil function '$s11initializer12ExplicitTestCACyYaKcfc'
class ExplicitTest {
nonisolated(nonsending) init() async throws {
}
}

View File

@@ -1,5 +1,8 @@
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-silgen %s -module-name initializers -swift-version 5 -target %target-swift-5.1-abi-triple | %FileCheck %s --enable-var-scope --implicit-check-not=hop_to_executor
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-silgen %s -module-name initializers -swift-version 5 -target %target-swift-5.1-abi-triple | %FileCheck -check-prefix=CHECK -check-prefix=NI %s --enable-var-scope --implicit-check-not=hop_to_executor
// RUN: %target-swift-frontend -Xllvm -sil-print-types -emit-silgen %s -module-name initializers -swift-version 5 -target %target-swift-5.1-abi-triple -enable-upcoming-feature NonisolatedNonsendingByDefault | %FileCheck %s -check-prefix=CHECK -check-prefix=NI-NS --enable-var-scope --implicit-check-not=hop_to_executor
// REQUIRES: concurrency
// REQUIRES: swift_feature_NonisolatedNonsendingByDefault
// CHECK: protocol Person {
// CHECK-NEXT: init() async
@@ -18,12 +21,12 @@
// CHECK: class EarthPerson : Person {
// CHECK-NEXT: required init() async
// CHECK-NEXT: required {{.*}}init() async
// CHECK-NEXT: init(name: String) async
// CHECK: @_inheritsConvenienceInitializers class NorthAmericaPerson : EarthPerson {
// CHECK-NEXT: required init() async
// CHECK-NEXT: override init(name: String) async
// CHECK-NEXT: required {{.*}}init() async
// CHECK-NEXT: override {{.*}}init(name: String) async
// CHECK: class Cat {
// CHECK-NEXT: @MainActor init()
@@ -46,12 +49,14 @@ protocol Person {
}
struct MyStruct {
// CHECK-DAG: sil hidden [ossa] @$s12initializers8MyStructVACyYacfC : $@convention(method) @async (@thin MyStruct.Type) -> MyStruct
// NI-DAG: sil hidden [ossa] @$s12initializers8MyStructVACyYacfC : $@convention(method) @async (@thin MyStruct.Type) -> MyStruct
// NI-NS-DAG: sil hidden [ossa] @$s12initializers8MyStructVACyYacfC : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @thin MyStruct.Type) -> MyStruct {
init() async {}
}
enum MyEnum {
// CHECK-DAG: sil hidden [ossa] @$s12initializers6MyEnumOACyYacfC : $@convention(method) @async (@thin MyEnum.Type) -> MyEnum
// NI-DAG: sil hidden [ossa] @$s12initializers6MyEnumOACyYacfC : $@convention(method) @async (@thin MyEnum.Type) -> MyEnum
// NI-NS-DAG: sil hidden [ossa] @$s12initializers6MyEnumOACyYacfC : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @thin MyEnum.Type) -> MyEnum {
init() async {}
}
@@ -59,35 +64,54 @@ actor MyActor {
// CHECK-DAG: sil hidden [ossa] @$s12initializers7MyActorCACyYacfc : $@convention(method) @async (@sil_isolated @owned MyActor) -> @owned MyActor
// CHECK: bb0(%0 : @owned $MyActor):
// In the prologue, hop to the generic executor.
// CHECK-NEXT: [[NIL_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[NIL_EXECUTOR]] :
// CHECK-NEXT: [[NIL_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[NIL_EXECUTOR]] :
// Later, when we return from an async call, hop to the
// correct flow-sensitive value.
// CHECK: [[FN:%.*]] = function_ref @$s12initializers8MyStructVACyYacfC :
// CHECK-NEXT: apply [[FN]]
// CHECK-NEXT: [[ISOLATION:%.*]] = builtin "flowSensitiveSelfIsolation"<MyActor>({{%.*}})
// CHECK-NEXT: hop_to_executor [[ISOLATION]]
// CHECK-NEXT: destroy_value [[ISOLATION]]
//
// NI: [[FN:%.*]] = function_ref @$s12initializers8MyStructVACyYacfC :
// NI-NEXT: apply [[FN]]
//
// NI-NS: [[ISOLATION_1:%.*]] = builtin "flowSensitiveSelfIsolation"<MyActor>({{%.*}})
// NI-NS-NEXT: // function_ref
// NI-NS-NEXT: [[FN:%.*]] = function_ref @$s12initializers8MyStructVACyYacfC :
// NI-NS-NEXT: apply [[FN]]([[ISOLATION_1]]
// NI-NS-NEXT: destroy_value [[ISOLATION_1]]
// CHECK-NEXT: [[ISOLATION_2:%.*]] = builtin "flowSensitiveSelfIsolation"<MyActor>({{%.*}})
// CHECK-NEXT: hop_to_executor [[ISOLATION_2]]
// CHECK: } // end sil function '$s12initializers7MyActorCACyYacfc'
init() async {
_ = await MyStruct()
}
}
class EarthPerson : Person {
// CHECK-DAG: sil hidden [ossa] @$s12initializers11EarthPersonCACyYacfc : $@convention(method) @async (@owned EarthPerson) -> @owned EarthPerson
// NI-NS-LABEL: sil hidden [exact_self_class] [ossa] @$s12initializers11EarthPersonCACyYacfC : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @thick EarthPerson.Type) -> @owned EarthPerson {
// NI-NS: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>,
// NI-NS: hop_to_executor [[ACTOR]]
// NI-NS: apply {{%.*}}([[ACTOR]], {{%.*}})
// NI-NS: } // end sil function '$s12initializers11EarthPersonCACyYacfC'
// NI-DAG: sil hidden [ossa] @$s12initializers11EarthPersonCACyYacfc : $@convention(method) @async (@owned EarthPerson) -> @owned EarthPerson
// NI-NS-DAG: sil hidden [ossa] @$s12initializers11EarthPersonCACyYacfc : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @owned EarthPerson) -> @owned EarthPerson {
required init() async {}
// CHECK-DAG: sil hidden [ossa] @$s12initializers11EarthPersonC4nameACSS_tYacfc : $@convention(method) @async (@owned String, @owned EarthPerson) -> @owned EarthPerson
// NI-DAG: sil hidden [ossa] @$s12initializers11EarthPersonC4nameACSS_tYacfc : $@convention(method) @async (@owned String, @owned EarthPerson) -> @owned EarthPerson
// NI-NS-DAG: sil hidden [ossa] @$s12initializers11EarthPersonC4nameACSS_tYacfc : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @owned String, @owned EarthPerson) -> @owned EarthPerson {
init(name: String) async {}
// CHECK-DAG: sil private [transparent] [thunk] [ossa] @$s12initializers11EarthPersonCAA0C0A2aDPxyYacfCTW : $@convention(witness_method: Person) @async (@thick EarthPerson.Type) -> @out EarthPerson
// NI-DAG: sil private [transparent] [thunk] [ossa] @$s12initializers11EarthPersonCAA0C0A2aDPxyYacfCTW : $@convention(
// NI-NS-DAG: sil private [transparent] [thunk] [ossa] @$s12initializers11EarthPersonCAA0C0A2aDPxyYacfCTW : $@convention(witness_method: Person) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @thick EarthPerson.Type) -> @out EarthPerson {
}
class NorthAmericaPerson : EarthPerson {
// CHECK-DAG: sil hidden [ossa] @$s12initializers18NorthAmericaPersonCACyYacfc : $@convention(method) @async (@owned NorthAmericaPerson) -> @owned NorthAmericaPerson
// NI-DAG: sil hidden [ossa] @$s12initializers18NorthAmericaPersonCACyYacfc : $@convention(method) @async (@owned NorthAmericaPerson) -> @owned NorthAmericaPerson
// NI-NS-DAG: sil hidden [ossa] @$s12initializers18NorthAmericaPersonCACyYacfc : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @owned NorthAmericaPerson) -> @owned NorthAmericaPerson {
required init() async { await super.init() }
// CHECK-DAG: sil hidden [ossa] @$s12initializers18NorthAmericaPersonC4nameACSS_tYacfc : $@convention(method) @async (@owned String, @owned NorthAmericaPerson) -> @owned NorthAmericaPerson
// NI-DAG: sil hidden [ossa] @$s12initializers18NorthAmericaPersonC4nameACSS_tYacfc : $@convention(method) @async (@owned String, @owned NorthAmericaPerson) -> @owned NorthAmericaPerson
// NI-NS-DAG: sil hidden [ossa] @$s12initializers18NorthAmericaPersonC4nameACSS_tYacfc : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @owned String, @owned NorthAmericaPerson) -> @owned NorthAmericaPerson {
override init(name: String) async { await super.init(name: name) }
}
@@ -100,8 +124,10 @@ func someAsyncFn() async {}
class Cat {
// CHECK-LABEL: sil hidden [ossa] @$s12initializers3CatCACyYacfc : $@convention(method) @async (@owned Cat) -> @owned Cat {
// CHECK: hop_to_executor {{%[0-9]+}} : $MainActor
// CHECK: {{%[0-9]+}} = function_ref @$s12initializers11someAsyncFnyyYaF : $@convention(thin) @async () -> ()
// CHECK: {{%[0-9]+}} = apply {{%[0-9]+}}() : $@convention(thin) @async () -> ()
// CHECK: {{%[0-9]+}} = function_ref @$s12initializers11someAsyncFnyyYaF :
// NI: {{%[0-9]+}} = apply {{%[0-9]+}}() : $@convention(thin) @async () -> ()
// NI-NS: {{%[0-9]+}} = apply {{%[0-9]+}}({{%.*}}) : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
// NI-NS-NEXT: destroy_value {{%.*}}
// CHECK-NEXT: hop_to_executor {{%[0-9]+}} : $MainActor
// CHECK: } // end sil function '$s12initializers3CatCACyYacfc'
@MainActor init() async {
@@ -114,8 +140,10 @@ class Cat {
struct Dog {
// CHECK-LABEL: sil hidden [ossa] @$s12initializers3DogVACyYacfC : $@convention(method) @async (@thin Dog.Type) -> Dog {
// CHECK: hop_to_executor {{%[0-9]+}} : $MainActor
// CHECK: {{%[0-9]+}} = function_ref @$s12initializers11someAsyncFnyyYaF : $@convention(thin) @async () -> ()
// CHECK: {{%[0-9]+}} = apply {{%[0-9]+}}() : $@convention(thin) @async () -> ()
// CHECK: {{%[0-9]+}} = function_ref @$s12initializers11someAsyncFnyyYaF
// NI: {{%[0-9]+}} = apply {{%[0-9]+}}() : $@convention(thin) @async () -> ()
// NI-NS: {{%[0-9]+}} = apply {{%[0-9]+}}({{%.*}}) : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()
// NI-NS-NEXT: destroy_value {{%.*}}
// CHECK-NEXT: hop_to_executor {{%[0-9]+}} : $MainActor
// CHECK: } // end sil function '$s12initializers3DogVACyYacfC'
@MainActor init() async {
@@ -128,9 +156,10 @@ struct Dog {
enum Birb {
// CHECK-LABEL: sil hidden [ossa] @$s12initializers4BirbOACyYacfC : $@convention(method) @async (@thin Birb.Type) -> Birb {
// CHECK: hop_to_executor {{%[0-9]+}} : $MainActor
// CHECK: {{%[0-9]+}} = function_ref @$s12initializers11someAsyncFnyyYaF : $@convention(thin) @async () -> ()
// CHECK: {{%[0-9]+}} = apply {{%[0-9]+}}() : $@convention(thin) @async () -> ()
// CHECK-NEXT: hop_to_executor {{%[0-9]+}} : $MainActor
// CHECK: {{%[0-9]+}} = function_ref @$s12initializers11someAsyncFnyyYaF :
// NI: {{%[0-9]+}} = apply {{%[0-9]+}}() : $@convention(thin) @async () -> ()
// NI-NS: {{%[0-9]+}} = apply {{%[0-9]+}}({{%.*}}) :
// CHECK: hop_to_executor {{%[0-9]+}} : $MainActor
// CHECK: } // end sil function '$s12initializers4BirbOACyYacfC'
@MainActor init() async {
await someAsyncFn()
@@ -139,38 +168,67 @@ enum Birb {
@MainActor init(name: String) {}
}
// CHECK-LABEL: sil hidden [ossa] @$s12initializers7makeCatyyYaF : $@convention(thin) @async () -> () {
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: hop_to_executor [[BORROWED_EXECUTOR:%[0-9]+]]
// CHECK: end_borrow [[BORROWED_EXECUTOR]]
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thick Cat.Type) -> @owned Cat
// CHECK: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: } // end sil function '$s12initializers7makeCatyyYaF'
// NI-LABEL: sil hidden [ossa] @$s12initializers7makeCatyyYaF : $@convention(thin) @async () -> () {
// NI: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: hop_to_executor [[BORROWED_EXECUTOR:%[0-9]+]]
// NI: end_borrow [[BORROWED_EXECUTOR]]
// NI-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thick Cat.Type) -> @owned Cat
// NI: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: } // end sil function '$s12initializers7makeCatyyYaF'
// NI-NS-LABEL: sil hidden [ossa] @$s12initializers7makeCatyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
// NI-NS: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>):
// NI-NS: hop_to_executor [[ACTOR]]
// NI-NS: [[INIT:%.*]] = function_ref @$s12initializers3CatC4nameACSS_tcfC : $@convention(method) (@owned String, @thick Cat.Type) -> @owned Cat
// NI-NS: [[MAIN_ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
// NI-NS: [[MAIN_ACTOR_B:%.*]] = begin_borrow [[MAIN_ACTOR]]
// NI-NS: hop_to_executor [[MAIN_ACTOR_B]]
// NI-NS: {{%[0-9]+}} = apply [[INIT]]({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thick Cat.Type) -> @owned Cat
// NI-NS: hop_to_executor [[ACTOR]]
// NI-NS: } // end sil function '$s12initializers7makeCatyyYaF'
func makeCat() async {
_ = await Cat(name: "Socks")
}
// CHECK-LABEL: sil hidden [ossa] @$s12initializers7makeDogyyYaF : $@convention(thin) @async () -> () {
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: hop_to_executor [[BORROWED_EXEC:%.*]] :
// CHECK-NEXT: end_borrow [[BORROWED_EXEC]]
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thin Dog.Type) -> Dog
// CHECK: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: } // end sil function '$s12initializers7makeDogyyYaF'
// NI-LABEL: sil hidden [ossa] @$s12initializers7makeDogyyYaF : $@convention(thin) @async () -> () {
// NI: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: hop_to_executor [[BORROWED_EXEC:%.*]] :
// NI-NEXT: end_borrow [[BORROWED_EXEC]]
// NI-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thin Dog.Type) -> Dog
// NI: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: } // end sil function '$s12initializers7makeDogyyYaF'
// NI-NS-LABEL: sil hidden [ossa] @$s12initializers7makeDogyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
// NI-NS: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>):
// NI-NS: hop_to_executor [[ACTOR]]
// NI-NS: hop_to_executor [[BORROWED_EXEC:%.*]] :
// NI-NS-NEXT: end_borrow [[BORROWED_EXEC]]
// NI-NS-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thin Dog.Type) -> Dog
// NI-NS: hop_to_executor [[ACTOR]]
// NI-NS: } // end sil function '$s12initializers7makeDogyyYaF'
func makeDog() async {
_ = await Dog(name: "Lassie")
}
// CHECK-LABEL: sil hidden [ossa] @$s12initializers8makeBirbyyYaF : $@convention(thin) @async () -> () {
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: hop_to_executor [[BORROWED_EXEC:%.*]] : $MainActor
// CHECK-NEXT: end_borrow [[BORROWED_EXEC]]
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thin Birb.Type) -> Birb
// CHECK: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: } // end sil function '$s12initializers8makeBirbyyYaF'
// NI-LABEL: sil hidden [ossa] @$s12initializers8makeBirbyyYaF : $@convention(thin) @async () -> () {
// NI: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: hop_to_executor [[BORROWED_EXEC:%.*]] : $MainActor
// NI-NEXT: end_borrow [[BORROWED_EXEC]]
// NI-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thin Birb.Type) -> Birb
// NI: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: } // end sil function '$s12initializers8makeBirbyyYaF'
// NI-NS-LABEL: sil hidden [ossa] @$s12initializers8makeBirbyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
// NI-NS: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>):
// NI-NS-NEXT: hop_to_executor [[ACTOR]]
// NI-NS: hop_to_executor [[BORROWED_EXEC:%.*]] : $MainActor
// NI-NS-NEXT: end_borrow [[BORROWED_EXEC]]
// NI-NS-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thin Birb.Type) -> Birb
// NI-NS: hop_to_executor [[ACTOR]]
// NI-NS: } // end sil function '$s12initializers8makeBirbyyYaF'
func makeBirb() async {
_ = await Birb(name: "Chirpy")
}
@@ -201,42 +259,82 @@ func makeActor() async -> SomeActor {
return await SomeActor()
}
// CHECK-LABEL: sil hidden [ossa] @$s12initializers20makeActorFromGenericAA04SomeC0CyYaF : $@convention(thin) @async () -> @owned SomeActor {
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: apply
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI-LABEL: sil hidden [ossa] @$s12initializers20makeActorFromGenericAA04SomeC0CyYaF : $@convention(thin) @async () -> @owned SomeActor {
// NI: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: apply
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: } // end sil function '$s12initializers20makeActorFromGenericAA04SomeC0CyYaF'
// NI-NS-LABEL: sil hidden [ossa] @$s12initializers20makeActorFromGenericAA04SomeC0CyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> @owned SomeActor {
// NI-NS: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>):
// NI-NS: hop_to_executor [[ACTOR]]
// NI-NS: apply {{%.*}}({{%.*}})
// NI-NS-NEXT: hop_to_executor [[ACTOR]]
// NI-NS: } // end sil function '$s12initializers20makeActorFromGenericAA04SomeC0CyYaF'
func makeActorFromGeneric() async -> SomeActor {
return await SomeActor()
}
// CHECK-LABEL: sil hidden [ossa] @$s12initializers26callActorMethodFromGeneric1ayAA04SomeC0C_tYaF : $@convention(thin) @async (@guaranteed SomeActor) -> () {
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: apply
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI-LABEL: sil hidden [ossa] @$s12initializers26callActorMethodFromGeneric1ayAA04SomeC0C_tYaF :
// NI: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: apply
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: } // end sil function '$s12initializers26callActorMethodFromGeneric1ayAA04SomeC0C_tYaF'
// NI-NS-LABEL: sil hidden [ossa] @$s12initializers26callActorMethodFromGeneric1ayAA04SomeC0C_tYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SomeActor) -> () {
// NI-NS: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[ARG:%.*]] : @guaranteed $SomeActor):
// NI-NS: hop_to_executor [[ACTOR]]
// NI-NS: [[FUNC:%.*]] = class_method [[ARG]]
// NI-NS: apply [[FUNC]]([[ARG]])
// NI-NS-NEXT: hop_to_executor [[ACTOR]]
// NI-NS: } // end sil function '$s12initializers26callActorMethodFromGeneric1ayAA04SomeC0C_tYaF'
func callActorMethodFromGeneric(a: SomeActor) async {
await a.someMethod()
}
// CHECK-LABEL: sil hidden {{.*}} @$s12initializers15makeActorInTaskyyYaF : $@convention(thin) @async () -> () {
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: apply
// CHECK-LABEL: sil private [ossa] @$s12initializers15makeActorInTaskyyYaFAA04SomeC0CyYacfU_ : $@convention(thin) @async @substituted <τ_0_0> (@guaranteed Optional<any Actor>) -> @out τ_0_0 for <SomeActor> {
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: apply
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI-LABEL: sil hidden {{.*}} @$s12initializers15makeActorInTaskyyYaF : $@convention(thin) @async () -> () {
// NI: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: apply
// NI: } // end sil function '$s12initializers15makeActorInTaskyyYaF'
// NI-NS-LABEL: sil hidden [available 10.15] [ossa] @$s12initializers15makeActorInTaskyyYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> () {
// NI-NS: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>):
// NI-NS: hop_to_executor [[ACTOR]]
// NI-NS: apply
// NI-NS: } // end sil function '$s12initializers15makeActorInTaskyyYaF'
// NI-LABEL: sil private [ossa] @$s12initializers15makeActorInTaskyyYaFAA04SomeC0CyYacfU_ : $@convention(thin) @async @substituted <τ_0_0> (@guaranteed Optional<any Actor>) -> @out τ_0_0 for <SomeActor> {
// NI: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: apply
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: } // end sil function '$s12initializers15makeActorInTaskyyYaFAA04SomeC0CyYacfU_'
// NI-NS-LABEL: sil private [ossa] @$s12initializers15makeActorInTaskyyYaFAA04SomeC0CyYacfU_ : $@convention(thin) @async @substituted <τ_0_0> (@guaranteed Optional<any Actor>) -> @out τ_0_0 for <SomeActor> {
// NI-NS: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// NI-NS-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI-NS: apply
// NI-NS-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI-NS: } // end sil function '$s12initializers15makeActorInTaskyyYaFAA04SomeC0CyYacfU_'
@available(SwiftStdlib 5.1, *)
func makeActorInTask() async {
Task.detached { await SomeActor() }
}
// CHECK-LABEL: sil hidden {{.*}} @$s12initializers21callActorMethodInTask1ayAA04SomeC0C_tYaF : $@convention(thin) @async (@guaranteed SomeActor) -> () {
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// CHECK: apply
// NI-LABEL: sil hidden {{.*}} @$s12initializers21callActorMethodInTask1ayAA04SomeC0C_tYaF : $@convention(thin) @async (@guaranteed SomeActor) -> () {
// NI: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// NI-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
// NI: apply
// NI: } // end sil function '$s12initializers21callActorMethodInTask1ayAA04SomeC0C_tYaF'
// NI-NS-LABEL: sil hidden [available 10.15] [ossa] @$s12initializers21callActorMethodInTask1ayAA04SomeC0C_tYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed SomeActor) -> () {
// NI-NS: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[ARG:%.*]] : @guaranteed $SomeActor):
// NI-NS: hop_to_executor [[ACTOR]]
// NI-NS: } // end sil function '$s12initializers21callActorMethodInTask1ayAA04SomeC0C_tYaF'
// CHECK-LABEL: sil private [ossa] @$s12initializers21callActorMethodInTask1ayAA04SomeC0C_tYaFyyYacfU_ : $@convention(thin) @async @substituted <τ_0_0> (@guaranteed Optional<any Actor>, @guaranteed SomeActor) -> @out τ_0_0 for <()> {
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>