Skip to content

Commit 3cebfdd

Browse files
committed
[Distributed] Add a way to determine if particular reference is to distributed thunk
Make it possible for type-checker to determine whether the given reference in the given context represents a call to a remote distributed actor.
1 parent 920669d commit 3cebfdd

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2651,6 +2651,11 @@ namespace {
26512651
}
26522652
}
26532653
}
2654+
2655+
/// Determine whether the given reference is to a method on
2656+
/// a remote distributed actor in the given context.
2657+
bool isDistributedThunk(ConcreteDeclRef ref, Expr *context,
2658+
bool isInAsyncLetInitializer);
26542659
};
26552660
}
26562661

@@ -2683,6 +2688,58 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
26832688
return false;
26842689
}
26852690

2691+
bool ActorIsolationChecker::isDistributedThunk(ConcreteDeclRef ref,
2692+
Expr *context,
2693+
bool isInAsyncLetInitializer) {
2694+
auto *FD = dyn_cast_or_null<AbstractFunctionDecl>(ref.getDecl());
2695+
if (!(FD && FD->isInstanceMember() && FD->isDistributed()))
2696+
return false;
2697+
2698+
if (!isa<SelfApplyExpr>(context))
2699+
return false;
2700+
2701+
auto actor = getIsolatedActor(cast<SelfApplyExpr>(context)->getBase());
2702+
2703+
// If this is a method reference on an isolated or potentially isolated
2704+
// actor then it cannot be a remote thunk.
2705+
if (actor.isIsolated() || actor.isPotentiallyIsolated)
2706+
return false;
2707+
2708+
auto *dc = getDeclContext();
2709+
2710+
switch (ActorIsolationRestriction::forDeclaration(ref, dc)) {
2711+
case ActorIsolationRestriction::CrossActorSelf: {
2712+
// Not a thunk if it's used in actor init or de-init.
2713+
if (!isInAsyncLetInitializer && isActorInitOrDeInitContext(dc))
2714+
return false;
2715+
2716+
// Here we know that the method could be used across actors
2717+
// and the actor it's used on is non-isolated, which means
2718+
// that it could be a thunk, so we have to be conservative
2719+
// about it.
2720+
return true;
2721+
}
2722+
2723+
case ActorIsolationRestriction::ActorSelf: {
2724+
// An instance member of an actor can be referenced from an actor's
2725+
// designated initializer or deinitializer.
2726+
if (actor.isActorSelf() && !isInAsyncLetInitializer) {
2727+
if (auto fn = isActorInitOrDeInitContext(dc)) {
2728+
if (!isConvenienceInit(fn))
2729+
return false;
2730+
}
2731+
}
2732+
2733+
// Call on a non-isolated actor in async context requires
2734+
// implicit thunk.
2735+
return isInAsyncLetInitializer || isInAsynchronousContext();
2736+
}
2737+
2738+
default:
2739+
return false;
2740+
}
2741+
}
2742+
26862743
void swift::checkTopLevelActorIsolation(TopLevelCodeDecl *decl) {
26872744
ActorIsolationChecker checker(decl);
26882745
decl->getBody()->walk(checker);
@@ -4285,3 +4342,11 @@ bool swift::isAsynchronousContext(const DeclContext *dc) {
42854342

42864343
return false;
42874344
}
4345+
4346+
bool swift::constraints::isDistributedThunk(ConcreteDeclRef ref,
4347+
Expr *context,
4348+
DeclContext *dc,
4349+
bool isInAsyncLetInitializer) {
4350+
ActorIsolationChecker checker(dc);
4351+
return checker.isDistributedThunk(ref, context, isInAsyncLetInitializer);
4352+
}

lib/Sema/TypeCheckConcurrency.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,14 @@ bool checkSendableConformance(
333333
/// function or a closure declaration marked as `async`.
334334
bool isAsynchronousContext(const DeclContext *dc);
335335

336+
namespace constraints {
337+
/// Determine whether the given reference is to a method on
338+
/// a remote distributed actor in the given context.
339+
bool isDistributedThunk(ConcreteDeclRef ref, Expr *context,
340+
DeclContext *dc,
341+
bool isInAsyncLetInitializer);
342+
} // end namespace constraints
343+
336344
} // end namespace swift
337345

338346
#endif /* SWIFT_SEMA_TYPECHECKCONCURRENCY_H */

0 commit comments

Comments
 (0)