Skip to content

Commit 435aa65

Browse files
committed
[Distributed] Synthesize thunks for distributed computed properties
1 parent 5a5b7c0 commit 435aa65

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
@@ -5355,6 +5355,10 @@ class VarDecl : public AbstractStorageDecl {
53555355
/// Does this have a 'distributed' modifier?
53565356
bool isDistributed() const;
53575357

5358+
/// Return a distributed thunk if this computed property is marked as
5359+
/// 'distributed' and and nullptr otherwise.
5360+
FuncDecl *getDistributedThunk() const;
5361+
53585362
/// Is this var known to be a "local" distributed actor,
53595363
/// if so the implicit throwing ans some isolation checks can be skipped.
53605364
bool isKnownToBeLocal() const;

include/swift/AST/TypeCheckRequests.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,17 +1237,20 @@ class GetDistributedRemoteCallArgumentInitFunctionRequest :
12371237
///
12381238
/// The thunk is responsible for invoking 'remoteCall' when invoked on a remote
12391239
/// 'distributed actor'.
1240-
class GetDistributedThunkRequest :
1241-
public SimpleRequest<GetDistributedThunkRequest,
1242-
FuncDecl *(AbstractFunctionDecl *),
1243-
RequestFlags::Cached> {
1240+
class GetDistributedThunkRequest
1241+
: public SimpleRequest<
1242+
GetDistributedThunkRequest,
1243+
FuncDecl *(llvm::PointerUnion<VarDecl *, AbstractFunctionDecl *>),
1244+
RequestFlags::Cached> {
1245+
using Originator = llvm::PointerUnion<VarDecl *, AbstractFunctionDecl *>;
1246+
12441247
public:
12451248
using SimpleRequest::SimpleRequest;
12461249

12471250
private:
12481251
friend SimpleRequest;
12491252

1250-
FuncDecl *evaluate(Evaluator &evaluator, AbstractFunctionDecl *distributedFunc) const;
1253+
FuncDecl *evaluate(Evaluator &evaluator, Originator originator) const;
12511254

12521255
public:
12531256
// Caching

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ SWIFT_REQUEST(TypeChecker, GetDistributedTargetInvocationResultHandlerOnReturnFu
127127
AbstractFunctionDecl *(NominalTypeDecl *),
128128
Cached, NoLocationInfo)
129129
SWIFT_REQUEST(TypeChecker, GetDistributedThunkRequest,
130-
FuncDecl *(AbstractFunctionDecl *),
130+
FuncDecl *(llvm::PointerUnion<VarDecl *, AbstractFunctionDecl *>),
131131
Cached, NoLocationInfo)
132132
SWIFT_REQUEST(TypeChecker, GetDistributedActorIDPropertyRequest,
133133
VarDecl *(NominalTypeDecl *),

lib/AST/DistributedDecl.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,20 @@ AbstractFunctionDecl *ASTContext::getRemoteCallOnDistributedActorSystem(
13331333
/********************** Distributed Actor Properties **************************/
13341334
/******************************************************************************/
13351335

1336+
FuncDecl *VarDecl::getDistributedThunk() const {
1337+
if (!isDistributed())
1338+
return nullptr;
1339+
1340+
// Only get-only 'distributed' computed properties are considered valid.
1341+
if (isStatic() || isLet() || hasStorageOrWrapsStorage() ||
1342+
getWriteImpl() != swift::WriteImplKind::Immutable)
1343+
return nullptr;
1344+
1345+
auto mutableThis = const_cast<VarDecl *>(this);
1346+
return evaluateOrDefault(getASTContext().evaluator,
1347+
GetDistributedThunkRequest{mutableThis}, nullptr);
1348+
}
1349+
13361350
FuncDecl*
13371351
AbstractFunctionDecl::getDistributedThunk() const {
13381352
if (!isDistributed())

lib/Sema/CodeSynthesisDistributedActor.cpp

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

684-
DeclName thunkName = func->getName();
684+
DeclName thunkName;
685+
686+
// Since accessors don't have names, let's generate one based on
687+
// the computed property.
688+
if (auto *accessor = dyn_cast<AccessorDecl>(func)) {
689+
auto *var = accessor->getStorage();
690+
thunkName = DeclName(C, var->getBaseName(),
691+
/*argumentNames=*/ArrayRef<Identifier>());
692+
} else {
693+
// Let's use the name of a 'distributed func'
694+
thunkName = func->getName();
695+
}
685696

686697
// --- Prepare generic parameters
687698
GenericParamList *genericParamList = nullptr;
@@ -811,10 +822,21 @@ addDistributedActorCodableConformance(
811822
/*********************** SYNTHESIS ENTRY POINTS *******************************/
812823
/******************************************************************************/
813824

814-
FuncDecl *GetDistributedThunkRequest::evaluate(
815-
Evaluator &evaluator, AbstractFunctionDecl *distributedTarget) const {
816-
if (!distributedTarget->isDistributed())
817-
return nullptr;
825+
FuncDecl *GetDistributedThunkRequest::evaluate(Evaluator &evaluator,
826+
Originator originator) const {
827+
AbstractFunctionDecl *distributedTarget = nullptr;
828+
if (auto *var = originator.dyn_cast<VarDecl *>()) {
829+
if (!var->isDistributed())
830+
return nullptr;
831+
832+
distributedTarget = var->getAccessor(AccessorKind::Get);
833+
} else {
834+
distributedTarget = originator.get<AbstractFunctionDecl *>();
835+
if (!distributedTarget->isDistributed())
836+
return nullptr;
837+
}
838+
839+
assert(distributedTarget);
818840

819841
auto &C = distributedTarget->getASTContext();
820842
auto DC = distributedTarget->getDeclContext();

lib/Sema/TypeCheckDistributed.cpp

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

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

488493
auto &C = func->getASTContext();
489494
auto DC = func->getDeclContext();
@@ -654,6 +659,18 @@ void TypeChecker::checkDistributedActor(SourceFile *SF, NominalTypeDecl *nominal
654659
(void)nominal->getDefaultInitializer();
655660

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

0 commit comments

Comments
 (0)