Skip to content

Commit 1f33a0c

Browse files
committed
[Distributed] move where we invoke dist synthesis; detect transport param
1 parent e1dcd77 commit 1f33a0c

18 files changed

+230
-184
lines changed

include/swift/AST/Decl.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -3367,7 +3367,11 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
33673367
/// for types that are not global actors.
33683368
VarDecl *getGlobalActorInstance() const;
33693369

3370-
bool hasDistributedActorLocalInitializer() const;
3370+
/// Check if the declaration has an user-defined initializer.
3371+
/// If so, we may want to e.g. not generate a default initializer etc.
3372+
///
3373+
/// \returns true if the decl has an user-defined designated initializer.
3374+
bool hasUserDefinedDesignatedInit() const;
33713375

33723376
/// Whether this type is a global actor, which can be used as an
33733377
/// attribute to decorate declarations for inclusion in the actor-isolated

include/swift/AST/DiagnosticsSema.def

+8
Original file line numberDiff line numberDiff line change
@@ -4581,6 +4581,14 @@ ERROR(distributed_actor_func_static,none,
45814581
ERROR(distributed_actor_func_not_in_distributed_actor,none,
45824582
"'distributed' function can only be declared within 'distributed actor'",
45834583
())
4584+
ERROR(distributed_actor_designated_ctor_must_have_one_transport_param,none,
4585+
"designated distributed actor initializer %0 must accept exactly one"
4586+
"ActorTransport parameter, found %1",
4587+
(DeclName, int))
4588+
ERROR(distributed_actor_designated_ctor_missing_transport_param,none,
4589+
"designated distributed actor initializer %0 is missing required "
4590+
"ActorTransport parameter",
4591+
(DeclName))
45844592
ERROR(distributed_actor_independent_property_must_be_let,none,
45854593
"_distributedActorIndependent can be applied to properties, however they must be 'let'",
45864594
())

include/swift/AST/TypeCheckRequests.h

+1
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,7 @@ enum class ImplicitMemberAction : uint8_t {
20652065
ResolveDecodable,
20662066
ResolveDistributedActor,
20672067
ResolveDistributedActorIdentity,
2068+
ResolveDistributedActorTransport,
20682069
};
20692070

20702071
class ResolveImplicitMemberRequest

lib/AST/Decl.cpp

+8-3
Original file line numberDiff line numberDiff line change
@@ -4208,10 +4208,15 @@ ConstructorDecl *NominalTypeDecl::getDefaultInitializer() const {
42084208
SynthesizeDefaultInitRequest{mutableThis}, nullptr);
42094209
}
42104210

4211-
bool NominalTypeDecl::hasDistributedActorLocalInitializer() const {
4211+
bool NominalTypeDecl::hasUserDefinedDesignatedInit() const {
4212+
// Imported decls don't have a designated initializer defined by the user.
4213+
if (hasClangNode())
4214+
return false;
4215+
42124216
auto &ctx = getASTContext();
42134217
auto *mutableThis = const_cast<NominalTypeDecl *>(this);
4214-
return evaluateOrDefault(ctx.evaluator, HasDistributedActorLocalInitRequest{mutableThis},
4218+
return evaluateOrDefault(ctx.evaluator,
4219+
HasUserDefinedDesignatedInitRequest{mutableThis},
42154220
false);
42164221
}
42174222

@@ -4242,7 +4247,7 @@ void NominalTypeDecl::synthesizeSemanticMembersIfNeeded(DeclName member) {
42424247
if ((member.isSimpleName() || argumentNames.front() == Context.Id_from)) {
42434248
action.emplace(ImplicitMemberAction::ResolveDecodable);
42444249
} else if (argumentNames.front() == Context.Id_transport) {
4245-
action.emplace(ImplicitMemberAction::ResolveDistributedActor);
4250+
action.emplace(ImplicitMemberAction::ResolveDistributedActorTransport);
42464251
}
42474252
} else if (!baseName.isSpecial() &&
42484253
baseName.getIdentifier() == Context.Id_encode &&

lib/AST/TypeCheckRequests.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -1034,11 +1034,14 @@ void swift::simple_display(llvm::raw_ostream &out,
10341034
out << "resolve Decodable.init(from:)";
10351035
break;
10361036
case ImplicitMemberAction::ResolveDistributedActor:
1037-
out << "resolve DistributedActor[init(transport:), init(resolve:using:)]";
1037+
out << "resolve DistributedActor";
10381038
break;
10391039
case ImplicitMemberAction::ResolveDistributedActorIdentity:
10401040
out << "resolve DistributedActor.id";
10411041
break;
1042+
case ImplicitMemberAction::ResolveDistributedActorTransport:
1043+
out << "resolve DistributedActor.actorTransport";
1044+
break;
10421045
}
10431046
}
10441047

lib/SILGen/SILGenDistributed.cpp

+58-16
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,44 @@ using namespace Lowering;
3636
/****************** DISTRIBUTED ACTOR STORAGE INITIALIZATION ******************/
3737
/******************************************************************************/
3838

39+
/// Get the `ActorTransport` parameter of the constructor.
40+
/// Sema should have guaranteed that there is exactly one of them for any
41+
/// designated initializer of a distributed actor.
42+
static SILArgument*
43+
getActorTransportArgument(ASTContext& C, SILFunction& F, ConstructorDecl *ctor) {
44+
auto *DC = cast<DeclContext>(ctor);
45+
auto module = DC->getParentModule();
46+
47+
auto *transportProto =
48+
C.getProtocol(KnownProtocolKind::ActorTransport);
49+
Type transportTy = transportProto->getDeclaredInterfaceType();
50+
51+
for (auto arg : F.getArguments()) {
52+
// TODO(distributed): also be able to locate a generic transport
53+
Type argTy = arg->getType().getASTType();
54+
auto argDecl = arg->getDecl();
55+
argTy->dump();
56+
argDecl->dump();
57+
58+
auto conformsToTransport = module->lookupConformance(
59+
argDecl->getInterfaceType(), transportProto);
60+
61+
// Is it a protocol that conforms to ActorTransport?
62+
if (argTy->isEqual(transportTy) || conformsToTransport) {
63+
return arg;
64+
}
65+
66+
// Is it some specific ActorTransport?
67+
auto result = module->lookupConformance(argTy, transportProto);
68+
if (!result.isInvalid()) {
69+
return arg;
70+
}
71+
}
72+
73+
// did not find argument of ActorTransport type!
74+
llvm_unreachable("Missing required ActorTransport argument!");
75+
}
76+
3977

4078
static AbstractFunctionDecl*
4179
lookupAssignIdentityFunc(ASTContext& C) {
@@ -56,8 +94,11 @@ lookupAssignIdentityFunc(ASTContext& C) {
5694
/// // }
5795
/// \endverbatim
5896
static void
59-
emitDistributedActorTransportInit(SILGenFunction &SGF, ManagedValue borrowedSelfArg, VarDecl *selfDecl, ConstructorDecl *ctor,
60-
Pattern *pattern, VarDecl *var) {
97+
emitDistributedActorTransportInit(
98+
SILGenFunction &SGF,
99+
ManagedValue borrowedSelfArg, VarDecl *selfDecl,
100+
ConstructorDecl *ctor,
101+
Pattern *pattern, VarDecl *var) {
61102
auto &C = selfDecl->getASTContext();
62103
auto &B = SGF.B;
63104
auto &F = SGF.F;
@@ -71,7 +112,7 @@ emitDistributedActorTransportInit(SILGenFunction &SGF, ManagedValue borrowedSelf
71112
SGF.F.dump();
72113

73114
// ==== Prepare assignment: get the self.transport address
74-
SILValue transportArgValue = F.getArgument(0);
115+
SILValue transportArgValue = getActorTransportArgument(C, F, ctor);
75116
ManagedValue transportArgManaged = ManagedValue::forUnmanaged(transportArgValue);
76117
auto transportDecl = C.getActorTransportDecl();
77118

@@ -96,10 +137,11 @@ emitDistributedActorTransportInit(SILGenFunction &SGF, ManagedValue borrowedSelf
96137
/// // }
97138
/// \endverbatim
98139
static void
99-
emitDistributedActorIdentityInit(SILGenFunction &SGF,
100-
ManagedValue borrowedSelfArg,
101-
VarDecl *selfVarDecl, ConstructorDecl *ctor,
102-
Pattern *pattern, VarDecl *var) {
140+
emitDistributedActorIdentityInit(
141+
SILGenFunction &SGF,
142+
ManagedValue borrowedSelfArg, VarDecl *selfVarDecl,
143+
ConstructorDecl *ctor,
144+
Pattern *pattern, VarDecl *var) {
103145
auto &C = selfVarDecl->getASTContext();
104146
auto &B = SGF.B;
105147
auto &F = SGF.F;
@@ -120,8 +162,8 @@ emitDistributedActorIdentityInit(SILGenFunction &SGF,
120162
auto assignIdentityFnRef = SILDeclRef(assignIdentityFuncDecl);
121163

122164
// === Open the transport existential before call
123-
SILValue transportArgValue = F.getArgument(0);
124-
SILValue selfArgValue = F.getArgument(1);
165+
SILValue transportArgValue = getActorTransportArgument(C, F, ctor);
166+
SILValue selfArgValue = F.getSelfArgument();
125167
ProtocolDecl *distributedActorProto = C.getProtocol(KnownProtocolKind::DistributedActor);
126168
ProtocolDecl *transportProto = C.getProtocol(KnownProtocolKind::ActorTransport);
127169
assert(distributedActorProto);
@@ -137,8 +179,6 @@ emitDistributedActorIdentityInit(SILGenFunction &SGF,
137179
loc, transportArgValue, openedTransportSILType, OpenedExistentialAccess::Immutable);
138180

139181
// --- prepare `Self.self` metatype
140-
// TODO: how to get @dynamic_self, do we need it?
141-
// %14 = metatype $@thick @dynamic_self DA_DefaultDeinit.Type // type-defs: %1; user: %16
142182
auto *selfTyDecl = ctor->getParent()->getSelfNominalTypeDecl();
143183
// This would be bad: since not ok for generic
144184
// auto selfMetatype = SGF.getLoweredType(selfTyDecl->getInterfaceType());
@@ -162,11 +202,6 @@ emitDistributedActorIdentityInit(SILGenFunction &SGF,
162202
auto transportConfRef = ProtocolConformanceRef(transportProto);
163203
assert(!transportConfRef.isInvalid() && "Missing conformance to `ActorTransport`");
164204

165-
// fprintf(stderr, "[%s:%d] (%s) selfArg->getType()\n", __FILE__, __LINE__, __FUNCTION__);
166-
// selfArg.getType().dump();
167-
// fprintf(stderr, "[%s:%d] (%s) distributedActorProto\n", __FILE__, __LINE__, __FUNCTION__);
168-
// distributedActorProto->dump();
169-
170205
auto selfTy = F.mapTypeIntoContext(selfTyDecl->getDeclaredInterfaceType()); // TODO: thats just self var devl getType
171206

172207
auto distributedActorConfRef = module->lookupConformance(
@@ -236,6 +271,13 @@ void SILGenFunction::initializeDistributedActorImplicitStorageInit(
236271
auto classDecl = dc->getSelfClassDecl();
237272
auto &C = classDecl->getASTContext();
238273

274+
// Only designated initializers get the lifecycle handling injected
275+
if (!ctor->isDesignatedInit()) {
276+
fprintf(stderr, "[%s:%d] (%s) NOT DESIGNATED INIT SKIP\n", __FILE__, __LINE__, __FUNCTION__);
277+
278+
return;
279+
}
280+
239281
SILLocation prologueLoc = RegularLocation(ctor);
240282
prologueLoc.markAsPrologue(); // TODO: no idea if this is necessary or makes sense
241283

lib/Sema/CodeSynthesis.cpp

+7-3
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,8 @@ HasUserDefinedDesignatedInitRequest::evaluate(Evaluator &evaluator,
985985
return false;
986986
}
987987

988+
// TODO(distributed): duplicated of NominalTypeDecl::hasUserDefinedDesignatedInit,
989+
// remove this static version?
988990
static bool hasUserDefinedDesignatedInit(Evaluator &eval,
989991
NominalTypeDecl *decl) {
990992
// Imported decls don't have a designated initializer defined by the user.
@@ -1191,6 +1193,7 @@ static bool shouldAttemptInitializerSynthesis(const NominalTypeDecl *decl) {
11911193
}
11921194

11931195
void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
1196+
fprintf(stderr, "[%s:%d] (%s) ADD IMPLICIT\n", __FILE__, __LINE__, __FUNCTION__);
11941197
// If we already added implicit initializers, we're done.
11951198
if (decl->addedImplicitInitializers())
11961199
return;
@@ -1202,7 +1205,6 @@ void TypeChecker::addImplicitConstructors(NominalTypeDecl *decl) {
12021205

12031206
if (auto *classDecl = dyn_cast<ClassDecl>(decl)) {
12041207
addImplicitInheritedConstructorsToClass(classDecl);
1205-
addImplicitDistributedActorMembersToClass(classDecl); // FIXME(distributed): add always this is not just constructors
12061208
}
12071209

12081210
// Force the memberwise and default initializers if the type has them.
@@ -1286,18 +1288,20 @@ ResolveImplicitMemberRequest::evaluate(Evaluator &evaluator,
12861288
}
12871289
break;
12881290
case ImplicitMemberAction::ResolveDistributedActor:
1291+
case ImplicitMemberAction::ResolveDistributedActorTransport:
12891292
case ImplicitMemberAction::ResolveDistributedActorIdentity: {
12901293
// init(transport:) and init(resolve:using:) may be synthesized as part of
12911294
// derived conformance to the DistributedActor protocol.
12921295
// If the target should conform to the DistributedActor protocol, check the
12931296
// conformance here to attempt synthesis.
1294-
TypeChecker::addImplicitConstructors(target);
1297+
// FIXME(distributed): invoke the requirement adding explicitly here
1298+
TypeChecker::addImplicitConstructors(target);
12951299
auto *distributedActorProto =
12961300
Context.getProtocol(KnownProtocolKind::DistributedActor);
12971301
(void)evaluateTargetConformanceTo(distributedActorProto);
1298-
}
12991302
break;
13001303
}
1304+
}
13011305
return std::make_tuple<>();
13021306
}
13031307

0 commit comments

Comments
 (0)