@@ -133,18 +133,56 @@ static void emitDistributedIfRemoteBranch(SILGenFunction &SGF, SILLocation Loc,
133133// ==== ------------------------------------------------------------------------
134134// MARK: local instance initialization
135135
136+ static SILArgument *findFirstDistributedActorSystemArg (SILFunction &F) {
137+ auto *module = F.getModule ().getSwiftModule ();
138+ auto &C = F.getASTContext ();
139+
140+ auto *transportProto = C.getProtocol (KnownProtocolKind::DistributedActorSystem);
141+ Type transportTy = transportProto->getDeclaredInterfaceType ();
142+
143+ for (auto arg : F.getArguments ()) {
144+ // TODO(distributed): also be able to locate a generic transport
145+ Type argTy = arg->getType ().getASTType ();
146+ auto argDecl = arg->getDecl ();
147+
148+ auto conformsToTransport =
149+ module ->lookupConformance (argDecl->getInterfaceType (), transportProto);
150+
151+ // Is it a protocol that conforms to DistributedActorSystem?
152+ if (argTy->isEqual (transportTy) || conformsToTransport) {
153+ return arg;
154+ }
155+
156+ // Is it some specific DistributedActorSystem?
157+ auto result = module ->lookupConformance (argTy, transportProto);
158+ if (!result.isInvalid ()) {
159+ return arg;
160+ }
161+ }
162+
163+ #ifndef NDEBUG
164+ llvm_unreachable (" Missing required DistributedActorSystem argument!" );
165+ #endif
166+
167+ return nullptr ;
168+ }
169+
136170// / For the initialization of a local distributed actor instance, emits code to
137171// / initialize the instance's stored property corresponding to the system.
138172static void emitActorSystemInit (SILGenFunction &SGF,
139173 ConstructorDecl *ctor,
140174 SILLocation loc,
141175 ManagedValue actorSelf) {
176+ assert (ctor->isImplicit () && " unexpected explicit dist actor init" );
177+ assert (ctor->isDesignatedInit ());
178+
142179 auto *dc = ctor->getDeclContext ();
143180 auto classDecl = dc->getSelfClassDecl ();
144181 auto &C = ctor->getASTContext ();
145182
146- // Sema has already guaranteed that there is exactly one DistributedActorSystem
147- // argument to the constructor, so we grab the first one from the params.
183+ // By construction, automatically generated distributed actor ctors have
184+ // exactly one ActorSystem-conforming argument to the constructor,
185+ // so we grab the first one from the params.
148186 SILValue systemArg = findFirstDistributedActorSystemArg (SGF.F );
149187 VarDecl *var = lookupProperty (classDecl, C.Id_actorSystem );
150188 assert (var);
@@ -160,6 +198,9 @@ static void emitActorSystemInit(SILGenFunction &SGF,
160198// / \endverbatim
161199static void emitIDInit (SILGenFunction &SGF, ConstructorDecl *ctor,
162200 SILLocation loc, ManagedValue borrowedSelfArg) {
201+ assert (ctor->isImplicit () && " unexpected explicit dist actor init" );
202+ assert (ctor->isDesignatedInit ());
203+
163204 auto &C = ctor->getASTContext ();
164205 auto &B = SGF.B ;
165206 auto &F = SGF.F ;
@@ -173,7 +214,8 @@ static void emitIDInit(SILGenFunction &SGF, ConstructorDecl *ctor,
173214 auto selfMetatype = SGF.getLoweredType (MetatypeType::get (selfTy));
174215 SILValue selfMetatypeValue = B.createMetatype (loc, selfMetatype);
175216
176- SILValue actorSystem = findFirstDistributedActorSystemArg (F);
217+ // since we're doing this only for the implicitly defined ctors, grab from arg
218+ SILValue actorSystem = findFirstDistributedActorSystemArg (SGF.F );
177219
178220 // --- create a temporary storage for the result of the call
179221 // it will be deallocated automatically as we exit this scope
@@ -230,12 +272,19 @@ void SILGenFunction::emitDistributedActorImplicitPropertyInits(
230272 loc.markAutoGenerated ();
231273
232274 selfArg = selfArg.borrow (*this , loc);
233- emitActorSystemInit (*this , ctor, loc, selfArg);
234- emitIDInit (*this , ctor, loc, selfArg);
235275
236276 // register a clean-up to resign the identity upon abnormal exit
277+ // we do this regardless of initializer kind, since it's easy to do in SILGen.
237278 auto *actorDecl = cast<ClassDecl>(ctor->getParent ()->getAsDecl ());
238279 Cleanups.pushCleanup <ResignIdentity>(actorDecl, selfArg.getValue ());
280+
281+ // Users must initialize the actorSystem property explicitly in their ctors
282+ if (!ctor->isImplicit ())
283+ return ;
284+
285+ // implicit ctors initialize these from the ActorSystem parameter.
286+ emitActorSystemInit (*this , ctor, loc, selfArg);
287+ emitIDInit (*this , ctor, loc, selfArg);
239288}
240289
241290void SILGenFunction::emitDistributedActorReady (
@@ -244,12 +293,27 @@ void SILGenFunction::emitDistributedActorReady(
244293 // Only designated initializers get the lifecycle handling injected
245294 assert (ctor->isDesignatedInit ());
246295
247- SILValue transport = findFirstDistributedActorSystemArg (F);
296+ auto &C = ctor->getASTContext ();
297+ auto *dc = ctor->getDeclContext ();
298+ auto classDecl = dc->getSelfClassDecl ();
248299
249300 FullExpr scope (Cleanups, CleanupLocation (loc));
250301 auto borrowedSelf = actorSelf.borrow (*this , loc);
251302
252- emitActorReadyCall (B, loc, borrowedSelf.getValue (), transport);
303+ // --- load the actor system from the actor instance
304+ ManagedValue actorSystem;
305+ SGFContext sgfCxt; // TODO: is this right?
306+ {
307+ VarDecl *property = lookupProperty (classDecl, C.Id_actorSystem );
308+ Type formalType = F.mapTypeIntoContext (property->getInterfaceType ());
309+ SILType loweredType = getLoweredType (formalType).getAddressType ();
310+ SILValue actorSystemRef = emitActorPropertyReference (
311+ *this , loc, borrowedSelf.getValue (), property);
312+ actorSystem = emitLoad (loc, actorSystemRef,
313+ getTypeLowering (loweredType), sgfCxt, IsNotTake);
314+ }
315+
316+ emitActorReadyCall (B, loc, borrowedSelf.getValue (), actorSystem.getValue ());
253317}
254318
255319// ==== ------------------------------------------------------------------------
0 commit comments