Skip to content

Commit 9258b4e

Browse files
xedinktoso
authored andcommitted
[Distributed] Synthesize thunks for distributed computed properties
1 parent 0d4afc8 commit 9258b4e

File tree

6 files changed

+72
-12
lines changed

6 files changed

+72
-12
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5345,6 +5345,10 @@ class VarDecl : public AbstractStorageDecl {
53455345
/// Does this have a 'distributed' modifier?
53465346
bool isDistributed() const;
53475347

5348+
/// Return a distributed thunk if this computed property is marked as
5349+
/// 'distributed' and and nullptr otherwise.
5350+
FuncDecl *getDistributedThunk() const;
5351+
53485352
/// Is this var known to be a "local" distributed actor,
53495353
/// if so the implicit throwing ans some isolation checks can be skipped.
53505354
bool isKnownToBeLocal() const;

include/swift/AST/TypeCheckRequests.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,17 +1279,20 @@ class GetDistributedRemoteCallArgumentInitFunctionRequest :
12791279
///
12801280
/// The thunk is responsible for invoking 'remoteCall' when invoked on a remote
12811281
/// 'distributed actor'.
1282-
class GetDistributedThunkRequest :
1283-
public SimpleRequest<GetDistributedThunkRequest,
1284-
FuncDecl *(AbstractFunctionDecl *),
1285-
RequestFlags::Cached> {
1282+
class GetDistributedThunkRequest
1283+
: public SimpleRequest<
1284+
GetDistributedThunkRequest,
1285+
FuncDecl *(llvm::PointerUnion<VarDecl *, AbstractFunctionDecl *>),
1286+
RequestFlags::Cached> {
1287+
using Originator = llvm::PointerUnion<VarDecl *, AbstractFunctionDecl *>;
1288+
12861289
public:
12871290
using SimpleRequest::SimpleRequest;
12881291

12891292
private:
12901293
friend SimpleRequest;
12911294

1292-
FuncDecl *evaluate(Evaluator &evaluator, AbstractFunctionDecl *distributedFunc) const;
1295+
FuncDecl *evaluate(Evaluator &evaluator, Originator originator) const;
12931296

12941297
public:
12951298
// Caching

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ SWIFT_REQUEST(TypeChecker, GetDistributedTargetInvocationResultHandlerOnReturnFu
137137
AbstractFunctionDecl *(NominalTypeDecl *),
138138
Cached, NoLocationInfo)
139139
SWIFT_REQUEST(TypeChecker, GetDistributedThunkRequest,
140-
FuncDecl *(AbstractFunctionDecl *),
140+
FuncDecl *(llvm::PointerUnion<VarDecl *, AbstractFunctionDecl *>),
141141
Cached, NoLocationInfo)
142142
SWIFT_REQUEST(TypeChecker, GetDistributedActorIDPropertyRequest,
143143
VarDecl *(NominalTypeDecl *),

lib/AST/DistributedDecl.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,20 @@ AbstractFunctionDecl *ASTContext::getRemoteCallOnDistributedActorSystem(
13731373
/********************** Distributed Actor Properties **************************/
13741374
/******************************************************************************/
13751375

1376+
FuncDecl *VarDecl::getDistributedThunk() const {
1377+
if (!isDistributed())
1378+
return nullptr;
1379+
1380+
// Only get-only 'distributed' computed properties are considered valid.
1381+
if (isStatic() || isLet() || hasStorageOrWrapsStorage() ||
1382+
getWriteImpl() != swift::WriteImplKind::Immutable)
1383+
return nullptr;
1384+
1385+
auto mutableThis = const_cast<VarDecl *>(this);
1386+
return evaluateOrDefault(getASTContext().evaluator,
1387+
GetDistributedThunkRequest{mutableThis}, nullptr);
1388+
}
1389+
13761390
FuncDecl*
13771391
AbstractFunctionDecl::getDistributedThunk() const {
13781392
if (!isDistributed())

lib/Sema/CodeSynthesisDistributedActor.cpp

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,18 @@ static FuncDecl *createDistributedThunkFunction(FuncDecl *func) {
646646
assert(systemTy &&
647647
"Thunk synthesis must have concrete actor system type available");
648648

649-
DeclName thunkName = func->getName();
649+
DeclName thunkName;
650+
651+
// Since accessors don't have names, let's generate one based on
652+
// the computed property.
653+
if (auto *accessor = dyn_cast<AccessorDecl>(func)) {
654+
auto *var = accessor->getStorage();
655+
thunkName = DeclName(C, var->getBaseName(),
656+
/*argumentNames=*/ArrayRef<Identifier>());
657+
} else {
658+
// Let's use the name of a 'distributed func'
659+
thunkName = func->getName();
660+
}
650661

651662
// --- Prepare generic parameters
652663
GenericParamList *genericParamList = nullptr;
@@ -776,10 +787,21 @@ addDistributedActorCodableConformance(
776787
/*********************** SYNTHESIS ENTRY POINTS *******************************/
777788
/******************************************************************************/
778789

779-
FuncDecl *GetDistributedThunkRequest::evaluate(
780-
Evaluator &evaluator, AbstractFunctionDecl *distributedTarget) const {
781-
if (!distributedTarget->isDistributed())
782-
return nullptr;
790+
FuncDecl *GetDistributedThunkRequest::evaluate(Evaluator &evaluator,
791+
Originator originator) const {
792+
AbstractFunctionDecl *distributedTarget = nullptr;
793+
if (auto *var = originator.dyn_cast<VarDecl *>()) {
794+
if (!var->isDistributed())
795+
return nullptr;
796+
797+
distributedTarget = var->getAccessor(AccessorKind::Get);
798+
} else {
799+
distributedTarget = originator.get<AbstractFunctionDecl *>();
800+
if (!distributedTarget->isDistributed())
801+
return nullptr;
802+
}
803+
804+
assert(distributedTarget);
783805

784806
auto &C = distributedTarget->getASTContext();
785807
auto DC = distributedTarget->getDeclContext();

lib/Sema/TypeCheckDistributed.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,12 @@ bool swift::checkDistributedFunction(AbstractFunctionDecl *func) {
482482

483483
bool CheckDistributedFunctionRequest::evaluate(
484484
Evaluator &evaluator, AbstractFunctionDecl *func) const {
485-
assert(func->isDistributed());
485+
if (auto *accessor = dyn_cast<AccessorDecl>(func)) {
486+
auto *var = cast<VarDecl>(accessor->getStorage());
487+
assert(var->isDistributed() && accessor->isGetter());
488+
} else {
489+
assert(func->isDistributed());
490+
}
486491

487492
auto &C = func->getASTContext();
488493
auto DC = func->getDeclContext();
@@ -653,6 +658,18 @@ void TypeChecker::checkDistributedActor(SourceFile *SF, NominalTypeDecl *nominal
653658
(void)nominal->getDefaultInitializer();
654659

655660
for (auto member : nominal->getMembers()) {
661+
// A distributed computed property needs to have a thunk for
662+
// its getter accessor.
663+
if (auto *var = dyn_cast<VarDecl>(member)) {
664+
if (!var->isDistributed())
665+
continue;
666+
667+
if (auto thunk = var->getDistributedThunk())
668+
SF->DelayedFunctions.push_back(thunk);
669+
670+
continue;
671+
}
672+
656673
// --- Ensure all thunks
657674
if (auto func = dyn_cast<AbstractFunctionDecl>(member)) {
658675
if (!func->isDistributed())

0 commit comments

Comments
 (0)