Skip to content

Commit 90d8816

Browse files
committed
[Distributed] Move property synthesis to DerivedConformanceDistributedActor
1 parent 0a0926b commit 90d8816

8 files changed

+147
-95
lines changed

lib/Sema/CodeSynthesisDistributedActor.cpp

Lines changed: 1 addition & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -93,95 +93,6 @@ static void addFactoryResolveFunction(ClassDecl *decl) {
9393
decl->addMember(factoryDecl);
9494
}
9595

96-
/******************************************************************************/
97-
/******************************** PROPERTIES **********************************/
98-
/******************************************************************************/
99-
100-
// TODO: deduplicate with 'declareDerivedProperty' from DerivedConformance...
101-
std::pair<VarDecl *, PatternBindingDecl *>
102-
createStoredProperty(ClassDecl *classDecl, ASTContext &ctx,
103-
VarDecl::Introducer introducer, Identifier name,
104-
Type propertyInterfaceType, Type propertyContextType,
105-
bool isStatic, bool isFinal) {
106-
auto parentDC = classDecl;
107-
108-
VarDecl *propDecl = new (ctx)
109-
VarDecl(/*IsStatic*/ isStatic, introducer,
110-
SourceLoc(), name, parentDC);
111-
propDecl->setImplicit();
112-
propDecl->setSynthesized();
113-
propDecl->copyFormalAccessFrom(classDecl, /*sourceIsParentContext*/ true);
114-
propDecl->setInterfaceType(propertyInterfaceType);
115-
116-
Pattern *propPat = NamedPattern::createImplicit(ctx, propDecl);
117-
propPat->setType(propertyContextType);
118-
119-
propPat = TypedPattern::createImplicit(ctx, propPat, propertyContextType);
120-
propPat->setType(propertyContextType);
121-
122-
auto *pbDecl = PatternBindingDecl::createImplicit(
123-
ctx, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
124-
parentDC);
125-
return {propDecl, pbDecl};
126-
}
127-
128-
/// Adds the following, fairly special, properties to each distributed actor:
129-
/// - actorTransport
130-
/// - id
131-
// TODO(distributed): move this synthesis to DerivedConformance style
132-
static void addImplicitDistributedActorStoredProperties(ClassDecl *decl) {
133-
assert(decl->isDistributedActor());
134-
135-
auto &C = decl->getASTContext();
136-
137-
// ```
138-
// @_distributedActorIndependent
139-
// let id: AnyActorIdentity
140-
// ```
141-
{
142-
auto propertyType = C.getAnyActorIdentityDecl()->getDeclaredInterfaceType();
143-
144-
VarDecl *propDecl;
145-
PatternBindingDecl *pbDecl;
146-
std::tie(propDecl, pbDecl) = createStoredProperty(
147-
decl, C,
148-
VarDecl::Introducer::Let, C.Id_id,
149-
propertyType, propertyType,
150-
/*isStatic=*/false, /*isFinal=*/true);
151-
152-
// mark as @_distributedActorIndependent, allowing access to it from everywhere
153-
propDecl->getAttrs().add(
154-
new (C) DistributedActorIndependentAttr(/*IsImplicit=*/true));
155-
156-
decl->addMember(propDecl);
157-
decl->addMember(pbDecl);
158-
}
159-
160-
// ```
161-
// @_distributedActorIndependent
162-
// let actorTransport: ActorTransport
163-
// ```
164-
// (no need for @actorIndependent because it is an immutable let)
165-
{
166-
auto propertyType = C.getActorTransportDecl()->getDeclaredInterfaceType();
167-
168-
VarDecl *propDecl;
169-
PatternBindingDecl *pbDecl;
170-
std::tie(propDecl, pbDecl) = createStoredProperty(
171-
decl, C,
172-
VarDecl::Introducer::Let, C.Id_actorTransport,
173-
propertyType, propertyType,
174-
/*isStatic=*/false, /*isFinal=*/true);
175-
176-
// mark as @_distributedActorIndependent, allowing access to it from everywhere
177-
propDecl->getAttrs().add(
178-
new (C) DistributedActorIndependentAttr(/*IsImplicit=*/true));
179-
180-
decl->addMember(propDecl);
181-
decl->addMember(pbDecl);
182-
}
183-
}
184-
18596
/******************************************************************************/
18697
/*************************** _REMOTE_ FUNCTIONS *******************************/
18798
/******************************************************************************/
@@ -355,6 +266,6 @@ void swift::addImplicitDistributedActorMembersToClass(ClassDecl *decl) {
355266
return;
356267

357268
addFactoryResolveFunction(decl);
358-
addImplicitDistributedActorStoredProperties(decl);
269+
// addImplicitDistributedActorStoredProperties(decl);
359270
addImplicitRemoteActorFunctions(decl);
360271
}

lib/Sema/DerivedConformanceDistributedActor.cpp

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,101 @@ bool DerivedConformance::canDeriveDistributedActor(
3030
}
3131
// ==== ------------------------------------------------------------------------
3232

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};
59+
}
60+
61+
static ValueDecl *deriveDistributedActor_id(DerivedConformance &derived) {
62+
assert(derived.Nominal->isDistributedActor());
63+
auto decl = dyn_cast<ClassDecl>(derived.Nominal);
64+
auto &C = derived.Context;
65+
66+
// ```
67+
// @_distributedActorIndependent
68+
// let id: AnyActorIdentity
69+
// ```
70+
auto propertyType = C.getAnyActorIdentityDecl()->getDeclaredInterfaceType();
71+
72+
VarDecl *propDecl;
73+
PatternBindingDecl *pbDecl;
74+
std::tie(propDecl, pbDecl) = createStoredProperty(
75+
decl, C,
76+
VarDecl::Introducer::Let, C.Id_id,
77+
propertyType, propertyType,
78+
/*isStatic=*/false, /*isFinal=*/true);
79+
80+
// mark as @_distributedActorIndependent, allowing access to it from everywhere
81+
propDecl->getAttrs().add(
82+
new (C) DistributedActorIndependentAttr(/*IsImplicit=*/true));
83+
84+
derived.addMembersToConformanceContext({ propDecl, pbDecl });
85+
return propDecl;
86+
}
87+
88+
static ValueDecl *deriveDistributedActor_actorTransport(
89+
DerivedConformance &derived) {
90+
assert(derived.Nominal->isDistributedActor());
91+
auto decl = dyn_cast<ClassDecl>(derived.Nominal);
92+
auto &C = derived.Context;
93+
94+
// ```
95+
// @_distributedActorIndependent
96+
// let actorTransport: ActorTransport
97+
// ```
98+
// (no need for @actorIndependent because it is an immutable let)
99+
auto propertyType = C.getActorTransportDecl()->getDeclaredInterfaceType();
100+
101+
VarDecl *propDecl;
102+
PatternBindingDecl *pbDecl;
103+
std::tie(propDecl, pbDecl) = createStoredProperty(
104+
decl, C,
105+
VarDecl::Introducer::Let, C.Id_actorTransport,
106+
propertyType, propertyType,
107+
/*isStatic=*/false, /*isFinal=*/true);
108+
109+
// mark as @_distributedActorIndependent, allowing access to it from everywhere
110+
propDecl->getAttrs().add(
111+
new (C) DistributedActorIndependentAttr(/*IsImplicit=*/true));
112+
113+
derived.addMembersToConformanceContext({ propDecl, pbDecl });
114+
return propDecl;
115+
}
116+
117+
118+
// ==== ------------------------------------------------------------------------
119+
33120
ValueDecl *DerivedConformance::deriveDistributedActor(ValueDecl *requirement) {
121+
if (auto var = dyn_cast<VarDecl>(requirement)) {
122+
if (var->getName() == Context.Id_id)
123+
return deriveDistributedActor_id(*this);
124+
125+
if (var->getName() == Context.Id_actorTransport)
126+
return deriveDistributedActor_actorTransport(*this);
127+
}
128+
34129
return nullptr;
35130
}

lib/Sema/DerivedConformances.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,14 @@ ValueDecl *DerivedConformance::getDerivableRequirement(NominalTypeDecl *nominal,
312312
if (name.isSimpleName(ctx.Id_unownedExecutor))
313313
return getRequirement(KnownProtocolKind::Actor);
314314

315+
// DistributedActor.id
316+
if(name.isSimpleName(ctx.Id_id))
317+
return getRequirement(KnownProtocolKind::DistributedActor);
318+
319+
// DistributedActor.actorTransport
320+
if(name.isSimpleName(ctx.Id_actorTransport))
321+
return getRequirement(KnownProtocolKind::DistributedActor);
322+
315323
return nullptr;
316324
}
317325

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2930,6 +2930,11 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
29302930

29312931
TypeChecker::checkDeclAttributes(ED);
29322932

2933+
if (nominal->isDistributedActor()) {
2934+
auto decl = dyn_cast<ClassDecl>(nominal);
2935+
TypeChecker::checkDistributedActor(decl);
2936+
}
2937+
29332938
for (Decl *Member : ED->getMembers())
29342939
visit(Member);
29352940

lib/Sema/TypeCheckDistributed.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,11 @@ void swift::checkDistributedActorProperties(const ClassDecl *decl) {
154154

155155
for (auto member : decl->getMembers()) {
156156
if (auto prop = dyn_cast<VarDecl>(member)) {
157+
if (prop->isSynthesized())
158+
continue;
159+
157160
auto id = prop->getName();
158-
if (id == C.Id_actorTransport ||
159-
id == C.Id_id) {
161+
if (id == C.Id_actorTransport || id == C.Id_id) {
160162
prop->diagnose(diag::distributed_actor_user_defined_special_property,
161163
id);
162164
}
@@ -235,7 +237,5 @@ void TypeChecker::checkDistributedActor(ClassDecl *decl) {
235237
// --- Synthesize properties
236238
// TODO: those could technically move to DerivedConformance style
237239
swift::addImplicitDistributedActorMembersToClass(decl);
238-
239-
// ==== Functions
240240
}
241241

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6412,6 +6412,7 @@ ValueDecl *TypeChecker::deriveProtocolRequirement(DeclContext *DC,
64126412
return derived.deriveDifferentiable(Requirement);
64136413

64146414
case KnownDerivableProtocolKind::DistributedActor:
6415+
fprintf(stderr, "[%s:%d] (%s) DERIVE DistributedActor \n", __FILE__, __LINE__, __FUNCTION__);
64156416
return derived.deriveDistributedActor(Requirement);
64166417

64176418
case KnownDerivableProtocolKind::OptionSet:

test/Distributed/distributed_actor_basic.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,36 @@ import _Distributed
66

77
@available(SwiftStdlib 5.5, *)
88
distributed actor DA {
9+
}
10+
11+
@available(SwiftStdlib 5.5, *)
12+
distributed actor First {
13+
distributed func one(second: Second) async throws {
14+
try await second.two(first: self, second: second)
15+
}
16+
}
17+
18+
@available(SwiftStdlib 5.5, *)
19+
distributed actor Second {
20+
distributed func two(first: First, second: Second) async {
21+
try! await first.one(second: self)
22+
}
23+
}
24+
25+
// ==== ------------------------------------------------------------------------
26+
27+
@available(SwiftStdlib 5.5, *)
28+
extension First {
29+
@_dynamicReplacement (for :_remote_one(second:))
30+
nonisolated func _impl_one(second: Second) async throws {
31+
fatalError()
32+
}
33+
}
34+
35+
@available(SwiftStdlib 5.5, *)
36+
extension Second {
37+
@_dynamicReplacement (for :_remote_two(first:second:))
38+
nonisolated func _impl_two(first: First, second: Second) async throws {
39+
fatalError()
40+
}
941
}

test/SIL/Distributed/distributed_actor_default_deinit_sil.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ distributed actor SimpleEmptyDistributedActor {
3636

3737
// Finish up the destroying...
3838
// CHECK: bb3:
39-
// CHECK: destroy_addr [[ID_ADDR]] : $*AnyActorIdentity
4039
// CHECK: destroy_addr [[TRANSPORT_ADDR]] : $*ActorTransport
40+
// CHECK: destroy_addr [[ID_ADDR]] : $*AnyActorIdentity
4141
// CHECK: [[_:%[0-9]+]] = builtin "destroyDefaultActor"(%0 : $SimpleEmptyDistributedActor) : $()
4242
// CHECK: [[SELF:%[0-9]+]] = unchecked_ref_cast %0 : $SimpleEmptyDistributedActor to $Builtin.NativeObject
4343
// CHECK: return [[SELF]] : $Builtin.NativeObject

0 commit comments

Comments
 (0)