Skip to content

Commit 7b434c2

Browse files
committed
[rbi] Lookthrough an invocation of DistributedActor.asLocalActor when determining actor instances.
In this case, what is happening is that in SILGen, we insert implicit DistributedActor.asLocalActor calls to convert a distributed actor to its local any Actor typed form. The intention is that the actor parameter and result are considered the same... but there is nothing at the SIL level to enforce that. In this commit, I change ActorInstance (the utility that defines actor identity at a value level) to look through such a call. I implemented this by just recognizing the decl directly. We already do this in parts of SILGen, so I don't really see a problem with doing this. It also provides a nice benefit that we do not have to modify SILFunctionType to represent this or put a @_semantic attribute on the getter. NOTE: Generally, Sema prevents us from mixing together different actors. In this case, Sema does not help us since this call is inserted implicitly by the distributed actor implementation in SILGen. So this is not a problem in general. rdar://152436817 (cherry picked from commit 331626e)
1 parent 06f0913 commit 7b434c2

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

lib/SILOptimizer/Utils/SILIsolationInfo.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "swift/SILOptimizer/Utils/SILIsolationInfo.h"
1414

1515
#include "swift/AST/ASTWalker.h"
16+
#include "swift/AST/DistributedDecl.h"
1617
#include "swift/AST/Expr.h"
1718
#include "swift/SIL/AddressWalker.h"
1819
#include "swift/SIL/ApplySite.h"
@@ -1336,6 +1337,30 @@ SILValue ActorInstance::lookThroughInsts(SILValue value) {
13361337
}
13371338
}
13381339

1340+
// See if this is distributed asLocalActor. In such a case, we want to
1341+
// consider the result actor to be the same actor as the input isolated
1342+
// parameter.
1343+
if (auto fas = FullApplySite::isa(svi)) {
1344+
if (auto *functionRef = fas.getReferencedFunctionOrNull()) {
1345+
if (auto declRef = functionRef->getDeclRef()) {
1346+
if (auto *accessor =
1347+
dyn_cast_or_null<AccessorDecl>(declRef.getFuncDecl())) {
1348+
if (auto asLocalActorDecl =
1349+
getDistributedActorAsLocalActorComputedProperty(
1350+
functionRef->getDeclContext()->getParentModule())) {
1351+
if (auto asLocalActorGetter =
1352+
asLocalActorDecl->getAccessor(AccessorKind::Get);
1353+
asLocalActorGetter && asLocalActorGetter == accessor) {
1354+
value = lookThroughInsts(
1355+
fas.getIsolatedArgumentOperandOrNullPtr()->get());
1356+
continue;
1357+
}
1358+
}
1359+
}
1360+
}
1361+
}
1362+
}
1363+
13391364
break;
13401365
}
13411366

test/Distributed/distributed_actor_transfernonsendable.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ distributed actor MyDistributedActor {
6565
// expected-note @-1 {{'self'-isolated 'x' is captured by a main actor-isolated closure. main actor-isolated uses in closure may race against later nonisolated uses}}
6666
}
6767
}
68+
69+
70+
func doSomething() async { }
71+
72+
// Make sure that we consider asLocalActor's result to be the same actor as
73+
// its actor parameter.
74+
func testAsLocalActorForwards() async {
75+
await withTaskGroup { group in
76+
group.addTask {
77+
await self.doSomething()
78+
}
79+
}
80+
}
6881
}
6982

7083
/////////////////////////////////

0 commit comments

Comments
 (0)