Skip to content

Commit 3319bc0

Browse files
committed
[Distributed] Be able to synthesize actorSystem prop from request
1 parent a6941e6 commit 3319bc0

File tree

2 files changed

+67
-12
lines changed

2 files changed

+67
-12
lines changed

lib/Sema/CodeSynthesisDistributedActor.cpp

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,9 @@ lookupDistributedActorProperty(NominalTypeDecl *decl, DeclName name) {
8383
// what already has a witness.
8484
static VarDecl *addImplicitDistributedActorIDProperty(
8585
ClassDecl *nominal) {
86-
if (!nominal || !nominal->isDistributedActor())
86+
if (!nominal)
87+
return nullptr;
88+
if (!nominal->isDistributedActor())
8789
return nullptr;
8890

8991
auto &C = nominal->getASTContext();
@@ -131,6 +133,55 @@ static VarDecl *addImplicitDistributedActorIDProperty(
131133
return propDecl;
132134
}
133135

136+
static VarDecl *addImplicitDistributedActorActorSystemProperty(
137+
ClassDecl *nominal) {
138+
if (!nominal)
139+
return nullptr;
140+
if (!nominal->isDistributedActor())
141+
return nullptr;
142+
143+
auto &C = nominal->getASTContext();
144+
145+
// ==== Synthesize and add 'id' property to the actor decl
146+
Type propertyType = getDistributedActorSystemType(nominal);
147+
148+
auto *propDecl = new (C)
149+
VarDecl(/*IsStatic*/false, VarDecl::Introducer::Let,
150+
SourceLoc(), C.Id_actorSystem, nominal);
151+
propDecl->setImplicit();
152+
propDecl->setSynthesized();
153+
propDecl->copyFormalAccessFrom(nominal, /*sourceIsParentContext*/ true);
154+
propDecl->setInterfaceType(propertyType);
155+
156+
Pattern *propPat = NamedPattern::createImplicit(C, propDecl);
157+
propPat->setType(propertyType);
158+
159+
propPat = TypedPattern::createImplicit(C, propPat, propertyType);
160+
propPat->setType(propertyType);
161+
162+
PatternBindingDecl *pbDecl = PatternBindingDecl::createImplicit(
163+
C, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
164+
nominal);
165+
166+
// mark as nonisolated, allowing access to it from everywhere
167+
propDecl->getAttrs().add(
168+
new (C) NonisolatedAttr(/*IsImplicit=*/true));
169+
// mark as @_compilerInitialized, since we synthesize the initializing
170+
// assignment during SILGen.
171+
propDecl->getAttrs().add(
172+
new (C) CompilerInitializedAttr(/*IsImplicit=*/true));
173+
174+
auto idProperty = nominal->getDistributedActorIDProperty();
175+
// IMPORTANT: The `id` MUST be the first field of any distributed actor.
176+
// So we find the property and add the system AFTER it using the hint.
177+
//
178+
// If the `id` was not synthesized yet, we'll end up inserting at head,
179+
// but the id synthesis will force itself to be FIRST anyway, so it works out.
180+
nominal->addMember(propDecl, /*hint=*/idProperty);
181+
nominal->addMember(pbDecl, /*hint=*/idProperty);
182+
return propDecl;
183+
}
184+
134185
/******************************************************************************/
135186
/*********************** DISTRIBUTED THUNK SYNTHESIS **************************/
136187
/******************************************************************************/
@@ -223,6 +274,7 @@ deriveBodyDistributed_thunk(AbstractFunctionDecl *thunk, void *context) {
223274
SmallVector<ASTNode, 8> remoteBranchStmts;
224275
// --- self.actorSystem
225276
auto systemProperty = nominal->getDistributedActorSystemProperty();
277+
assert(systemProperty && "Unable to find 'actorSystem' property");
226278
auto systemRefExpr =
227279
UnresolvedDotExpr::createImplicit(
228280
C, new (C) DeclRefExpr(selfDecl, dloc, implicit), // TODO: make createImplicit
@@ -824,18 +876,21 @@ VarDecl *GetDistributedActorSystemPropertyRequest::evaluate(
824876
return nullptr;
825877
}
826878

827-
for (auto system : nominal->lookupDirect(C.Id_actorSystem)) {
828-
if (auto var = dyn_cast<VarDecl>(system)) {
829-
auto conformance = module->conformsToProtocol(
830-
var->getInterfaceType(), DAS);
831-
if (conformance.isInvalid())
832-
continue;
879+
auto classDecl = dyn_cast<ClassDecl>(nominal);
880+
if (!classDecl)
881+
return nullptr;
833882

834-
return var;
835-
}
883+
// We may be triggered after synthesis was handled via `DerivedConformances`,
884+
// in which case we should locate the existing property, rather than add
885+
// another one. Generally derived conformances are triggered early and are right
886+
// but for some reason sometimes we get a request before synthesis was triggered
887+
// there... so this is to workaround that issue, and ensure we're always
888+
// synthesising correctly, regardless of entry-point.
889+
if (auto existingProp = lookupDistributedActorProperty(classDecl, C.Id_actorSystem)) {
890+
return existingProp;
836891
}
837892

838-
return nullptr;
893+
return addImplicitDistributedActorActorSystemProperty(classDecl);
839894
}
840895

841896
NormalProtocolConformance *GetDistributedActorImplicitCodableRequest::evaluate(

lib/Sema/DerivedConformances.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,11 +338,11 @@ ValueDecl *DerivedConformance::getDerivableRequirement(NominalTypeDecl *nominal,
338338
return getRequirement(KnownProtocolKind::Actor);
339339

340340
// DistributedActor.id
341-
if(name.isSimpleName(ctx.Id_id))
341+
if (name.isSimpleName(ctx.Id_id))
342342
return getRequirement(KnownProtocolKind::DistributedActor);
343343

344344
// DistributedActor.actorSystem
345-
if(name.isSimpleName(ctx.Id_actorSystem))
345+
if (name.isSimpleName(ctx.Id_actorSystem))
346346
return getRequirement(KnownProtocolKind::DistributedActor);
347347

348348
return nullptr;

0 commit comments

Comments
 (0)