Skip to content

Commit 0106bde

Browse files
committed
Hop to the generic executor in non-actor-isolated async functions.
Async functions are now expected to set ExpectedExecutor in their prologue (and, generally, immediately hop to it). I updated the prologue code for a bunch of function emission, most of which was uninteresting. Top-level code was not returning to the main executor, which is now fixed; fortunately, we weren't assuming that we were on the main executor yet. We had some code that only kicked in when an ExpectedExecutor wasn't set which made us capture the current executor before a hop and then return to it later. This code has been removed; there's no situation in which save-and-return is the semantically correct thing to do given the possibility of hop optimization. I suspect it could also have led to crashes if the current executor is being kept alive only because it's currently running code. If we ever add async functions that are supposed to inherit their caller's executor, we should have the caller pass the right executor down to it. This is the first half of SE-0338; the second, sendability enforcement, is much more complicated, and Doug has volunteered to do it. Fixes rdar://79284465, as well as some tests that were XFAILed on Windows.
1 parent 5a2df1c commit 0106bde

17 files changed

+256
-140
lines changed

lib/SILGen/SILGenBridging.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1588,7 +1588,7 @@ void SILGenFunction::emitNativeToForeignThunk(SILDeclRef thunk) {
15881588
// A hop is only needed in the thunk if it is global-actor isolated.
15891589
// Native, instance-isolated async methods will hop in the prologue.
15901590
if (isolation && isolation->isGlobalActor()) {
1591-
emitHopToTargetActor(loc, *isolation, None);
1591+
emitPrologGlobalActorHop(loc, isolation->getGlobalActor());
15921592
}
15931593
}
15941594

lib/SILGen/SILGenConstructor.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -672,13 +672,17 @@ static void emitDefaultActorInitialization(
672672
void SILGenFunction::emitConstructorPrologActorHop(
673673
SILLocation loc,
674674
Optional<ActorIsolation> maybeIso) {
675-
if (!maybeIso)
676-
return;
677-
678-
if (auto executor = emitExecutor(loc, *maybeIso, None)) {
679-
ExpectedExecutor = *executor;
680-
B.createHopToExecutor(loc.asAutoGenerated(), *executor, /*mandatory*/ false);
675+
loc = loc.asAutoGenerated();
676+
if (maybeIso) {
677+
if (auto executor = emitExecutor(loc, *maybeIso, None)) {
678+
ExpectedExecutor = *executor;
679+
}
681680
}
681+
682+
if (!ExpectedExecutor)
683+
ExpectedExecutor = emitGenericExecutor(loc);
684+
685+
B.createHopToExecutor(loc, ExpectedExecutor, /*mandatory*/ false);
682686
}
683687

684688
// MARK: class constructor

lib/SILGen/SILGenFunction.cpp

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -922,36 +922,7 @@ void SILGenFunction::emitAsyncMainThreadStart(SILDeclRef entryPoint) {
922922
JobType, {}, {task});
923923
jobResult = wrapCallArgs(jobResult, swiftJobRunFuncDecl, 0);
924924

925-
// Get main executor
926-
FuncDecl *getMainExecutorFuncDecl = SGM.getGetMainExecutor();
927-
if (!getMainExecutorFuncDecl) {
928-
// If it doesn't exist due to an SDK-compiler mismatch, we can conjure one
929-
// up instead of crashing:
930-
// @available(SwiftStdlib 5.1, *)
931-
// @_silgen_name("swift_task_getMainExecutor")
932-
// internal func _getMainExecutor() -> Builtin.Executor
933-
934-
ParameterList *emptyParams = ParameterList::createEmpty(getASTContext());
935-
getMainExecutorFuncDecl = FuncDecl::createImplicit(
936-
getASTContext(), StaticSpellingKind::None,
937-
DeclName(
938-
getASTContext(),
939-
DeclBaseName(getASTContext().getIdentifier("_getMainExecutor")),
940-
/*Arguments*/ emptyParams),
941-
{}, /*async*/ false, /*throws*/ false, {}, emptyParams,
942-
getASTContext().TheExecutorType,
943-
entryPoint.getDecl()->getModuleContext());
944-
getMainExecutorFuncDecl->getAttrs().add(
945-
new (getASTContext())
946-
SILGenNameAttr("swift_task_getMainExecutor", /*implicit*/ true));
947-
}
948-
949-
SILFunction *getMainExeutorSILFunc = SGM.getFunction(
950-
SILDeclRef(getMainExecutorFuncDecl, SILDeclRef::Kind::Func),
951-
NotForDefinition);
952-
SILValue getMainExeutorFunc =
953-
B.createFunctionRefFor(moduleLoc, getMainExeutorSILFunc);
954-
SILValue mainExecutor = B.createApply(moduleLoc, getMainExeutorFunc, {}, {});
925+
SILValue mainExecutor = emitMainExecutor(moduleLoc);
955926
mainExecutor = wrapCallArgs(mainExecutor, swiftJobRunFuncDecl, 1);
956927

957928
// Run first part synchronously

lib/SILGen/SILGenFunction.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -874,11 +874,22 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
874874
void emitConstructorPrologActorHop(SILLocation loc,
875875
Optional<ActorIsolation> actorIso);
876876

877+
/// Set the given global actor as the isolation for this function
878+
/// (generally a thunk) and hop to it.
879+
void emitPrologGlobalActorHop(SILLocation loc, Type globalActor);
880+
877881
/// Emit the executor for the given actor isolation.
878882
Optional<SILValue> emitExecutor(SILLocation loc,
879883
ActorIsolation isolation,
880884
Optional<ManagedValue> maybeSelf);
881885

886+
/// Emit the executor value that corresponds to the generic (concurrent)
887+
/// executor.
888+
SILValue emitGenericExecutor(SILLocation loc);
889+
890+
/// Emit the executor value that corresponds to the main actor.
891+
SILValue emitMainExecutor(SILLocation loc);
892+
882893
/// Emit a precondition check to ensure that the function is executing in
883894
/// the expected isolation context.
884895
void emitPreconditionCheckExpectedExecutor(

lib/SILGen/SILGenPoly.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2944,11 +2944,10 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
29442944

29452945
// If the input is synchronous and global-actor-qualified, and the
29462946
// output is asynchronous, hop to the executor expected by the input.
2947-
ExecutorBreadcrumb prevExecutor;
2947+
// Treat this thunk as if it were isolated to that global actor.
29482948
if (outputSubstType->isAsync() && !inputSubstType->isAsync()) {
29492949
if (Type globalActor = inputSubstType->getGlobalActor()) {
2950-
prevExecutor = SGF.emitHopToTargetActor(
2951-
loc, ActorIsolation::forGlobalActor(globalActor, false), None);
2950+
SGF.emitPrologGlobalActorHop(loc, globalActor);
29522951
}
29532952
}
29542953

@@ -2995,9 +2994,6 @@ static void buildThunkBody(SILGenFunction &SGF, SILLocation loc,
29952994
// Reabstract the result.
29962995
SILValue outerResult = resultPlanner.execute(innerResult);
29972996

2998-
// If we hopped to the target's executor, then we need to hop back.
2999-
prevExecutor.emit(SGF, loc);
3000-
30012997
scope.pop();
30022998
SGF.B.createReturn(loc, outerResult);
30032999
}

lib/SILGen/SILGenProlog.cpp

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
552552
return false;
553553
};
554554

555-
// Initialize ExpectedExecutor if the function is an actor-isolated
555+
// Initialize ExpectedExecutor if the function is an async
556556
// function or closure.
557557
bool wantDataRaceChecks = getOptions().EnableActorDataRaceChecks &&
558558
!F.isAsync() &&
@@ -642,6 +642,13 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
642642
}
643643
}
644644
}
645+
646+
// In async functions, the generic executor is our expected executor
647+
// if we don't have any sort of isolation.
648+
if (!ExpectedExecutor && F.isAsync()) {
649+
ExpectedExecutor = emitGenericExecutor(
650+
RegularLocation::getAutoGeneratedLocation(F.getLocation()));
651+
}
645652

646653
// Jump to the expected executor.
647654
if (ExpectedExecutor) {
@@ -661,6 +668,54 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
661668
}
662669
}
663670

671+
SILValue SILGenFunction::emitMainExecutor(SILLocation loc) {
672+
// Get main executor
673+
FuncDecl *getMainExecutorFuncDecl = SGM.getGetMainExecutor();
674+
if (!getMainExecutorFuncDecl) {
675+
// If it doesn't exist due to an SDK-compiler mismatch, we can conjure one
676+
// up instead of crashing:
677+
// @available(SwiftStdlib 5.1, *)
678+
// @_silgen_name("swift_task_getMainExecutor")
679+
// internal func _getMainExecutor() -> Builtin.Executor
680+
auto &ctx = getASTContext();
681+
682+
ParameterList *emptyParams = ParameterList::createEmpty(ctx);
683+
getMainExecutorFuncDecl = FuncDecl::createImplicit(
684+
ctx, StaticSpellingKind::None,
685+
DeclName(
686+
ctx,
687+
DeclBaseName(ctx.getIdentifier("_getMainExecutor")),
688+
/*Arguments*/ emptyParams),
689+
{}, /*async*/ false, /*throws*/ false, {}, emptyParams,
690+
ctx.TheExecutorType,
691+
getModule().getSwiftModule());
692+
getMainExecutorFuncDecl->getAttrs().add(
693+
new (ctx)
694+
SILGenNameAttr("swift_task_getMainExecutor", /*implicit*/ true));
695+
}
696+
697+
auto fn = SGM.getFunction(
698+
SILDeclRef(getMainExecutorFuncDecl, SILDeclRef::Kind::Func),
699+
NotForDefinition);
700+
SILValue fnRef = B.createFunctionRefFor(loc, fn);
701+
return B.createApply(loc, fnRef, {}, {});
702+
}
703+
704+
SILValue SILGenFunction::emitGenericExecutor(SILLocation loc) {
705+
// The generic executor is encoded as the nil value of
706+
// Optional<Builtin.SerialExecutor>.
707+
auto ty = SILType::getOptionalType(
708+
SILType::getPrimitiveObjectType(
709+
getASTContext().TheExecutorType));
710+
return B.createOptionalNone(loc, ty);
711+
}
712+
713+
void SILGenFunction::emitPrologGlobalActorHop(SILLocation loc,
714+
Type globalActor) {
715+
ExpectedExecutor = emitLoadGlobalActorExecutor(globalActor);
716+
B.createHopToExecutor(loc, ExpectedExecutor, /*mandatory*/ false);
717+
}
718+
664719
SILValue SILGenFunction::emitLoadGlobalActorExecutor(Type globalActor) {
665720
CanType actorType = CanType(globalActor);
666721
NominalTypeDecl *nominal = actorType->getNominalOrBoundGenericNominal();
@@ -800,19 +855,8 @@ void ExecutorBreadcrumb::emit(SILGenFunction &SGF, SILLocation loc) {
800855
}
801856

802857
SILValue SILGenFunction::emitGetCurrentExecutor(SILLocation loc) {
803-
// If this is an actor method, then the actor is the only executor we should
804-
// be running on (if we aren't setting up for a cross-actor call).
805-
if (ExpectedExecutor)
806-
return ExpectedExecutor;
807-
808-
// Otherwise, we'll have to ask the current task what executor it's running
809-
// on.
810-
auto &ctx = getASTContext();
811-
return B.createBuiltin(
812-
loc,
813-
ctx.getIdentifier(getBuiltinName(BuiltinValueKind::GetCurrentExecutor)),
814-
getLoweredType(OptionalType::get(ctx.TheExecutorType)),
815-
SubstitutionMap(), { });
858+
assert(ExpectedExecutor && "prolog failed to set up expected executor?");
859+
return ExpectedExecutor;
816860
}
817861

818862
static void emitIndirectResultParameters(SILGenFunction &SGF,

test/Concurrency/Runtime/class_resilience.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
// REQUIRES: concurrency_runtime
1616
// UNSUPPORTED: back_deployment_runtime
1717

18-
// XFAIL: windows
19-
// XFAIL: openbsd
20-
2118
import StdlibUnittest
2219
import resilient_class
2320

test/Concurrency/Runtime/protocol_resilience.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@
1515
// REQUIRES: concurrency_runtime
1616
// UNSUPPORTED: back_deployment_runtime
1717

18-
// XFAIL: windows
19-
// UNSUPPORTED: linux
20-
// UNSUPPORTED: openbsd
21-
2218
import StdlibUnittest
2319
import resilient_protocol
2420

test/Concurrency/cross_module_let_sil.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import OtherActors
77

88
// CHECK-LABEL: sil hidden [ossa] @$s4test6check1ySi11OtherActors0C11ModuleActorCYaF : $@convention(thin) @async (@guaranteed OtherModuleActor) -> Int {
99
// CHECK: bb0([[SELF:%[0-9]+]] : @guaranteed $OtherModuleActor):
10+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
11+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
1012
// CHECK: [[REF:%[0-9]+]] = ref_element_addr [[SELF]] : $OtherModuleActor, #OtherModuleActor.a
11-
// CHECK: [[OLD:%[0-9]+]] = builtin "getCurrentExecutor"() : $Optional<Builtin.Executor>
1213
// CHECK: hop_to_executor [[SELF]] : $OtherModuleActor
1314
// CHECK-NEXT: load [trivial] [[REF]]
14-
// CHECK-NEXT: hop_to_executor [[OLD]] : $Optional<Builtin.Executor>
15+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
1516
// CHECK: } // end sil function '$s4test6check1ySi11OtherActors0C11ModuleActorCYaF'
1617
func check1(_ actor: OtherModuleActor) async -> Int {
1718
return await actor.a
@@ -21,20 +22,25 @@ func check2(_ actor: isolated OtherModuleActor) -> Int {
2122
return actor.a
2223
}
2324

25+
// CHECK-LABEL: sil hidden [ossa] @$s4test6check3ySi11OtherActors0C11ModuleActorCYaF : $@convention(thin) @async (@guaranteed OtherModuleActor) -> Int {
26+
// CHECK: bb0([[SELF:%[0-9]+]] : @guaranteed $OtherModuleActor):
27+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
28+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
2429
func check3(_ actor: OtherModuleActor) async -> Int {
2530
return actor.b
2631
}
2732

2833
// CHECK-LABEL: sil hidden [ossa] @$s4test6check4y11OtherActors17SomeSendableClassCSgAC0C11ModuleActorCSgYaF : $@convention(thin) @async (@guaranteed Optional<OtherModuleActor>) -> @owned Optional<SomeSendableClass> {
2934
// CHECK: bb0({{%[0-9]+}} : @guaranteed $Optional<OtherModuleActor>):
35+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
36+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
3037
// CHECK: switch_enum {{%[0-9]+}} : $Optional<OtherModuleActor>, case #Optional.some!enumelt: [[SOME:bb[0-9]+]], case #Optional.none!enumelt: {{bb[0-9]+}}
3138

3239
// CHECK: [[SOME]]({{%[0-9]+}} : @owned $OtherModuleActor):
3340
// CHECK: [[REF:%[0-9]+]] = ref_element_addr {{%[0-9]+}} : $OtherModuleActor, #OtherModuleActor.d
34-
// CHECK: [[OLD:%[0-9]+]] = builtin "getCurrentExecutor"() : $Optional<Builtin.Executor>
3541
// CHECK: hop_to_executor {{%[0-9]+}} : $OtherModuleActor
3642
// CHECK-NEXT: load [copy] [[REF]]
37-
// CHECK: hop_to_executor [[OLD]] : $Optional<Builtin.Executor>
43+
// CHECK: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
3844
// CHECK: } // end sil function '$s4test6check4y11OtherActors17SomeSendableClassCSgAC0C11ModuleActorCSgYaF'
3945
func check4(_ actor: OtherModuleActor?) async -> SomeSendableClass? {
4046
return await actor?.d

test/Concurrency/throwing.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
// REQUIRES: concurrency_runtime
77
// UNSUPPORTED: back_deployment_runtime
88

9-
// SR-15252
10-
// XFAIL: OS=windows-msvc
11-
129
import _Concurrency
1310
import StdlibUnittest
1411

test/DebugInfo/async-lifetime-extension.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// Test that lifetime extension preserves a dbg.declare for "n" in the resume
77
// funclet.
88

9-
// CHECK-LABEL: define {{.*}} void @"$s1a4fiboyS2iYaFTQ0_"
9+
// CHECK-LABEL: define {{.*}} void @"$s1a4fiboyS2iYaFTY0_"
1010
// CHECK-NEXT: entryresume.0:
1111
// CHECK-NEXT: call void @llvm.dbg.declare(metadata {{.*}}%0, metadata ![[R:[0-9]+]], {{.*}}!DIExpression(DW_OP
1212
// CHECK-NEXT: call void @llvm.dbg.declare(metadata {{.*}}%0, metadata ![[N:[0-9]+]], {{.*}}!DIExpression(DW_OP

test/SILGen/async_initializer.swift

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,27 +127,33 @@ enum Birb {
127127
}
128128

129129
// CHECK-LABEL: sil hidden [ossa] @$s12initializers7makeCatyyYaF : $@convention(thin) @async () -> () {
130+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
131+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
130132
// CHECK: hop_to_executor {{%[0-9]+}} : $MainActor
131133
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thick Cat.Type) -> @owned Cat
132-
// CHECK-NEXT: hop_to_executor {{%[0-9]+}} : $Optional<Builtin.Executor>
134+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
133135
// CHECK: } // end sil function '$s12initializers7makeCatyyYaF'
134136
func makeCat() async {
135137
_ = await Cat(name: "Socks")
136138
}
137139

138140
// CHECK-LABEL: sil hidden [ossa] @$s12initializers7makeDogyyYaF : $@convention(thin) @async () -> () {
141+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
142+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
139143
// CHECK: hop_to_executor {{%[0-9]+}} : $MainActor
140144
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thin Dog.Type) -> Dog
141-
// CHECK-NEXT: hop_to_executor {{%[0-9]+}} : $Optional<Builtin.Executor>
145+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
142146
// CHECK: } // end sil function '$s12initializers7makeDogyyYaF'
143147
func makeDog() async {
144148
_ = await Dog(name: "Lassie")
145149
}
146150

147151
// CHECK-LABEL: sil hidden [ossa] @$s12initializers8makeBirbyyYaF : $@convention(thin) @async () -> () {
152+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
153+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
148154
// CHECK: hop_to_executor {{%[0-9]+}} : $MainActor
149155
// CHECK-NEXT: {{%[0-9]+}} = apply {{%[0-9]+}}({{%[0-9]+}}, {{%[0-9]+}}) : $@convention(method) (@owned String, @thin Birb.Type) -> Birb
150-
// CHECK-NEXT: hop_to_executor {{%[0-9]+}} : $Optional<Builtin.Executor>
156+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
151157
// CHECK: } // end sil function '$s12initializers8makeBirbyyYaF'
152158
func makeBirb() async {
153159
_ = await Birb(name: "Chirpy")
@@ -177,21 +183,47 @@ func makeActor() async -> SomeActor {
177183
return await SomeActor()
178184
}
179185

180-
// None of the below calls are expected to have a hop before or after the call.
181-
186+
// CHECK-LABEL: sil hidden [ossa] @$s12initializers20makeActorFromGenericAA04SomeC0CyYaF : $@convention(thin) @async () -> @owned SomeActor {
187+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
188+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
189+
// CHECK: apply
190+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
182191
func makeActorFromGeneric() async -> SomeActor {
183192
return await SomeActor()
184193
}
185194

195+
// CHECK-LABEL: sil hidden [ossa] @$s12initializers26callActorMethodFromGeneric1ayAA04SomeC0C_tYaF : $@convention(thin) @async (@guaranteed SomeActor) -> () {
196+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
197+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
198+
// CHECK: apply
199+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
186200
func callActorMethodFromGeneric(a: SomeActor) async {
187201
await a.someMethod()
188202
}
189203

204+
// CHECK-LABEL: sil hidden {{.*}} @$s12initializers15makeActorInTaskyyYaF : $@convention(thin) @async () -> () {
205+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
206+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
207+
// CHECK: apply
208+
// CHECK-LABEL: sil private [ossa] @$s12initializers15makeActorInTaskyyYaFAA04SomeC0CyYaYbcfU_ : $@convention(thin) @Sendable @async @substituted <τ_0_0> () -> @out τ_0_0 for <SomeActor> {
209+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
210+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
211+
// CHECK: apply
212+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
190213
@available(SwiftStdlib 5.1, *)
191214
func makeActorInTask() async {
192215
Task.detached { await SomeActor() }
193216
}
194217

218+
// CHECK-LABEL: sil hidden {{.*}} @$s12initializers21callActorMethodInTask1ayAA04SomeC0C_tYaF : $@convention(thin) @async (@guaranteed SomeActor) -> () {
219+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
220+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
221+
// CHECK: apply
222+
// CHECK-LABEL: sil private [ossa] @$s12initializers21callActorMethodInTask1ayAA04SomeC0C_tYaFyyYaYbcfU_ : $@convention(thin) @Sendable @async @substituted <τ_0_0> (@guaranteed SomeActor) -> @out τ_0_0 for <()> {
223+
// CHECK: [[GENERIC_EXEC:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none
224+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
225+
// CHECK: apply
226+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXEC]] : $Optional<Builtin.Executor>
195227
@available(SwiftStdlib 5.1, *)
196228
func callActorMethodInTask(a: SomeActor) async {
197229
Task.detached { await a.someMethod() }

0 commit comments

Comments
 (0)