Skip to content

Commit c868bdd

Browse files
committed
[Distributed] resolve synthesis via DerivedConformanceDistributedActor <3
1 parent 1669fb4 commit c868bdd

File tree

6 files changed

+90
-95
lines changed

6 files changed

+90
-95
lines changed

lib/Sema/CodeSynthesisDistributedActor.cpp

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -30,69 +30,6 @@
3030
#include "DerivedConformances.h"
3131
using namespace swift;
3232

33-
/******************************************************************************/
34-
/******************************* RESOLVE FUNCTION *****************************/
35-
/******************************************************************************/
36-
37-
/// Synthesizes the
38-
///
39-
/// \verbatim
40-
/// static resolve(_ address: ActorAddress,
41-
/// using transport: ActorTransport) throws -> Self {
42-
/// <filled in by SILGenDistributed>
43-
/// }
44-
/// \endverbatim
45-
///
46-
/// factory function in the AST, with an empty body. Its body is
47-
/// expected to be filled-in during SILGen.
48-
// TODO(distributed): move this synthesis to DerivedConformance style
49-
static void addFactoryResolveFunction(ClassDecl *decl) {
50-
assert(decl->isDistributedActor());
51-
auto &C = decl->getASTContext();
52-
53-
auto mkParam = [&](Identifier argName, Identifier paramName, Type ty) -> ParamDecl* {
54-
auto *param = new (C) ParamDecl(SourceLoc(),
55-
SourceLoc(), argName,
56-
SourceLoc(), paramName, decl);
57-
param->setImplicit();
58-
param->setSpecifier(ParamSpecifier::Default);
59-
param->setInterfaceType(ty);
60-
return param;
61-
};
62-
63-
auto addressType = C.getAnyActorIdentityDecl()->getDeclaredInterfaceType();
64-
auto transportType = C.getActorTransportDecl()->getDeclaredInterfaceType();
65-
66-
// (_ identity: AnyActorIdentity, using transport: ActorTransport)
67-
auto *params = ParameterList::create(
68-
C,
69-
/*LParenLoc=*/SourceLoc(),
70-
/*params=*/{ mkParam(Identifier(), C.Id_identity, addressType),
71-
mkParam(C.Id_using, C.Id_transport, transportType)
72-
},
73-
/*RParenLoc=*/SourceLoc()
74-
);
75-
76-
// Func name: resolve(_:using:)
77-
DeclName name(C, C.Id_resolve, params);
78-
79-
// Expected type: (Self) -> (AnyActorIdentity, ActorTransport) throws -> (Self)
80-
auto *factoryDecl =
81-
FuncDecl::createImplicit(C, StaticSpellingKind::KeywordStatic,
82-
name, SourceLoc(),
83-
/*async=*/false,
84-
/*throws=*/true,
85-
/*genericParams=*/nullptr,
86-
params,
87-
/*returnType*/decl->getDeclaredInterfaceType(),
88-
decl);
89-
90-
factoryDecl->setDistributedActorFactory(); // TODO(distributed): should we mark this specifically as the resolve factory?
91-
factoryDecl->copyFormalAccessFrom(decl, /*sourceIsParentContext=*/true);
92-
93-
decl->addMember(factoryDecl);
94-
}
95-
9633
/******************************************************************************/
9734
/*************************** _REMOTE_ FUNCTIONS *******************************/
9835
/******************************************************************************/
@@ -265,6 +202,5 @@ void swift::addImplicitDistributedActorMembersToClass(ClassDecl *decl) {
265202
if (!swift::ensureDistributedModuleLoaded(decl))
266203
return;
267204

268-
addFactoryResolveFunction(decl);
269205
addImplicitRemoteActorFunctions(decl);
270206
}

lib/Sema/DerivedConformanceDistributedActor.cpp

Lines changed: 75 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -28,36 +28,78 @@ bool DerivedConformance::canDeriveDistributedActor(
2828
auto classDecl = dyn_cast<ClassDecl>(nominal);
2929
return classDecl && classDecl->isDistributedActor() && dc == nominal;
3030
}
31+
3132
// ==== ------------------------------------------------------------------------
3233

33-
// TODO: deduplicate with 'declareDerivedProperty' from DerivedConformance...
34-
std::pair<VarDecl *, PatternBindingDecl *>
35-
createStoredProperty(ClassDecl *classDecl, ASTContext &ctx,
36-
VarDecl::Introducer introducer, Identifier name,
37-
Type propertyInterfaceType, Type propertyContextType,
38-
bool isStatic, bool isFinal) {
39-
auto parentDC = classDecl;
40-
41-
VarDecl *propDecl = new (ctx)
42-
VarDecl(/*IsStatic*/ isStatic, introducer,
43-
SourceLoc(), name, parentDC);
44-
propDecl->setImplicit();
45-
propDecl->setSynthesized();
46-
propDecl->copyFormalAccessFrom(classDecl, /*sourceIsParentContext*/ true);
47-
propDecl->setInterfaceType(propertyInterfaceType);
48-
49-
Pattern *propPat = NamedPattern::createImplicit(ctx, propDecl);
50-
propPat->setType(propertyContextType);
51-
52-
propPat = TypedPattern::createImplicit(ctx, propPat, propertyContextType);
53-
propPat->setType(propertyContextType);
54-
55-
auto *pbDecl = PatternBindingDecl::createImplicit(
56-
ctx, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
57-
parentDC);
58-
return {propDecl, pbDecl};
34+
/******************************************************************************/
35+
/******************************* RESOLVE FUNCTION *****************************/
36+
/******************************************************************************/
37+
38+
/// Synthesizes the
39+
///
40+
/// \verbatim
41+
/// static resolve(_ address: ActorAddress,
42+
/// using transport: ActorTransport) throws -> Self {
43+
/// <filled in by SILGenDistributed>
44+
/// }
45+
/// \endverbatim
46+
///
47+
/// factory function in the AST, with an empty body. Its body is
48+
/// expected to be filled-in during SILGen.
49+
// TODO(distributed): move this synthesis to DerivedConformance style
50+
static FuncDecl *deriveDistributedActor_resolve(DerivedConformance &derived) {
51+
auto decl = dyn_cast<ClassDecl>(derived.Nominal);
52+
assert(decl->isDistributedActor());
53+
auto &C = decl->getASTContext();
54+
55+
auto mkParam = [&](Identifier argName, Identifier paramName, Type ty) -> ParamDecl* {
56+
auto *param = new (C) ParamDecl(SourceLoc(),
57+
SourceLoc(), argName,
58+
SourceLoc(), paramName, decl);
59+
param->setImplicit();
60+
param->setSpecifier(ParamSpecifier::Default);
61+
param->setInterfaceType(ty);
62+
return param;
63+
};
64+
65+
auto addressType = C.getAnyActorIdentityDecl()->getDeclaredInterfaceType();
66+
auto transportType = C.getActorTransportDecl()->getDeclaredInterfaceType();
67+
68+
// (_ identity: AnyActorIdentity, using transport: ActorTransport)
69+
auto *params = ParameterList::create(
70+
C,
71+
/*LParenLoc=*/SourceLoc(),
72+
/*params=*/{ mkParam(Identifier(), C.Id_identity, addressType),
73+
mkParam(C.Id_using, C.Id_transport, transportType)
74+
},
75+
/*RParenLoc=*/SourceLoc()
76+
);
77+
78+
// Func name: resolve(_:using:)
79+
DeclName name(C, C.Id_resolve, params);
80+
81+
// Expected type: (Self) -> (AnyActorIdentity, ActorTransport) throws -> (Self)
82+
auto *factoryDecl =
83+
FuncDecl::createImplicit(C, StaticSpellingKind::KeywordStatic,
84+
name, SourceLoc(),
85+
/*async=*/false,
86+
/*throws=*/true,
87+
/*genericParams=*/nullptr,
88+
params,
89+
/*returnType*/decl->getDeclaredInterfaceType(),
90+
decl);
91+
92+
factoryDecl->setDistributedActorFactory(); // TODO(distributed): should we mark this specifically as the resolve factory?
93+
factoryDecl->copyFormalAccessFrom(decl, /*sourceIsParentContext=*/true);
94+
95+
derived.addMembersToConformanceContext({factoryDecl});
96+
return factoryDecl;
5997
}
6098

99+
/******************************************************************************/
100+
/******************************* PROPERTIES ***********************************/
101+
/******************************************************************************/
102+
61103
static ValueDecl *deriveDistributedActor_id(DerivedConformance &derived) {
62104
assert(derived.Nominal->isDistributedActor());
63105
auto &C = derived.Context;
@@ -114,7 +156,6 @@ static ValueDecl *deriveDistributedActor_actorTransport(
114156
return propDecl;
115157
}
116158

117-
118159
// ==== ------------------------------------------------------------------------
119160

120161
ValueDecl *DerivedConformance::deriveDistributedActor(ValueDecl *requirement) {
@@ -126,5 +167,12 @@ ValueDecl *DerivedConformance::deriveDistributedActor(ValueDecl *requirement) {
126167
return deriveDistributedActor_actorTransport(*this);
127168
}
128169

170+
if (auto func = dyn_cast<FuncDecl>(requirement)) {
171+
// just a simple name check is enough here,
172+
// if we are invoked here we know for sure it is for the "right" function
173+
if (func->getName().getBaseName() == Context.Id_resolve)
174+
return deriveDistributedActor_resolve(*this);
175+
}
176+
129177
return nullptr;
130178
}

lib/Sema/DerivedConformances.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,17 @@ ValueDecl *DerivedConformance::getDerivableRequirement(NominalTypeDecl *nominal,
359359
return getRequirement(KnownProtocolKind::Hashable);
360360
}
361361

362+
// static DistributedActor.resolve(_:using:)
363+
if (name.isCompoundName() && name.getBaseName() == ctx.Id_resolve &&
364+
func->isStatic()) {
365+
auto argumentNames = name.getArgumentNames();
366+
if (argumentNames.size() == 2 &&
367+
argumentNames[0] == Identifier() &&
368+
argumentNames[1] == ctx.Id_using) {
369+
return getRequirement(KnownProtocolKind::DistributedActor);
370+
}
371+
}
372+
362373
return nullptr;
363374
}
364375

lib/Sema/TypeCheckDistributed.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,9 @@ void swift::checkDistributedActorConstructor(const ClassDecl *decl, ConstructorD
215215
// ==== ------------------------------------------------------------------------
216216

217217
void TypeChecker::checkDistributedActor(ClassDecl *decl) {
218+
if (!decl)
219+
return;
220+
218221
// ==== Ensure the _Distributed module is available,
219222
// without it there's no reason to check the decl in more detail anyway.
220223
if (!swift::ensureDistributedModuleLoaded(decl))

stdlib/public/Distributed/DistributedActor.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ public protocol AnyActor: Sendable, AnyObject {}
3434
/// distributed actor.
3535
@available(SwiftStdlib 5.5, *)
3636
public protocol DistributedActor:
37-
AnyActor,
38-
Identifiable, Hashable, Codable {
37+
AnyActor, Identifiable, Hashable, Codable {
3938
/// Resolves the passed in `identity` against the `transport`, returning
4039
/// either a local or remote actor reference.
4140
///

test/Distributed/Runtime/distributed_actor_deinit.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,9 @@ func test() {
135135
// a remote actor should not resign it's address, it was never "assigned" it
136136
print("before")
137137
_ = try! DA_userDefined2.resolve(.init(address), using: transport)
138-
print("done")
139138
// CHECK: before
140139
// CHECK-NEXT: resolve type:DA_userDefined2, address:AnyActorIdentity(ActorAddress(address: "xxx"))
141140
// CHECK-NEXT: Deinitializing
142-
// CHECK-NEXT: done
143141
}
144142

145143
@available(SwiftStdlib 5.5, *)

0 commit comments

Comments
 (0)