Skip to content

Commit 840b7ea

Browse files
committed
Enter actor isolation for a distributed witness via the distributed thunk
We cannot hop to a distributed actor directly, so call through the distributed thunk instead.
1 parent 25a7988 commit 840b7ea

File tree

2 files changed

+41
-19
lines changed

2 files changed

+41
-19
lines changed

lib/SILGen/SILGenPoly.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4440,6 +4440,34 @@ void SILGenFunction::emitProtocolWitness(
44404440
SmallVector<ManagedValue, 8> origParams;
44414441
collectThunkParams(loc, origParams);
44424442

4443+
// If we are supposed to enter the actor, do so now.
4444+
if (enterIsolation) {
4445+
if (enterIsolation->isDistributedActor()) {
4446+
// For a distributed actor, call through the distributed thunk.
4447+
witness = witness.asDistributed();
4448+
} else {
4449+
// For a non-distributed actor, hop to the actor.
4450+
Optional<ManagedValue> actorSelf;
4451+
4452+
// For an instance actor, get the actor 'self'.
4453+
if (*enterIsolation == ActorIsolation::ActorInstance) {
4454+
auto actorSelfVal = origParams.back();
4455+
4456+
if (actorSelfVal.getType().isAddress()) {
4457+
auto &actorSelfTL = getTypeLowering(actorSelfVal.getType());
4458+
if (!actorSelfTL.isAddressOnly()) {
4459+
actorSelfVal = emitManagedLoad(
4460+
*this, loc, actorSelfVal, actorSelfTL);
4461+
}
4462+
}
4463+
4464+
actorSelf = actorSelfVal;
4465+
}
4466+
4467+
emitHopToTargetActor(loc, enterIsolation, actorSelf);
4468+
}
4469+
}
4470+
44434471
// Get the type of the witness.
44444472
auto witnessInfo = getConstantInfo(getTypeExpansionContext(), witness);
44454473
CanAnyFunctionType witnessSubstTy = witnessInfo.LoweredType;
@@ -4481,25 +4509,6 @@ void SILGenFunction::emitProtocolWitness(
44814509
witnessUnsubstTy->getSelfParameter());
44824510
}
44834511

4484-
// If we are supposed to hop to the actor, do so now.
4485-
if (enterIsolation) {
4486-
Optional<ManagedValue> actorSelf;
4487-
if (*enterIsolation == ActorIsolation::ActorInstance) {
4488-
auto actorSelfVal = origParams.back();
4489-
4490-
if (actorSelfVal.getType().isAddress()) {
4491-
auto &actorSelfTL = getTypeLowering(actorSelfVal.getType());
4492-
if (!actorSelfTL.isAddressOnly()) {
4493-
actorSelfVal = emitManagedLoad(*this, loc, actorSelfVal, actorSelfTL);
4494-
}
4495-
}
4496-
4497-
actorSelf = actorSelfVal;
4498-
}
4499-
4500-
emitHopToTargetActor(loc, enterIsolation, actorSelf);
4501-
}
4502-
45034512
// For static C++ methods and constructors, we need to drop the (metatype)
45044513
// "self" param. The "native" SIL representation will look like this:
45054514
// @convention(method) (@thin Foo.Type) -> () but the "actual" SIL function

test/SILGen/distributed_thunk.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,16 @@ extension DA {
1717

1818
distributed func f() { }
1919
}
20+
21+
protocol ServerProto {
22+
func doSomething() async throws
23+
}
24+
25+
extension DA: ServerProto {
26+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s17distributed_thunk2DACAA11ServerProtoA2aDP11doSomethingyyYaKFTW : $@convention(witness_method: ServerProto) @async (@in_guaranteed DA) -> @error Error
27+
// CHECK-NOT: hop_to_executor
28+
// CHECK-NOT: return
29+
// CHECK: function_ref @$s17distributed_thunk2DAC11doSomethingyyFTE
30+
// CHECK: return
31+
distributed func doSomething() { }
32+
}

0 commit comments

Comments
 (0)