@@ -255,7 +255,6 @@ createDistributedActor_init_local(ClassDecl *classDecl,
255255// / \param initDecl The function decl whose body to synthesize.
256256static std::pair<BraceStmt *, bool >
257257createDistributedActor_init_resolve_body (AbstractFunctionDecl *initDecl, void *) {
258-
259258 auto *funcDC = cast<DeclContext>(initDecl);
260259 auto &C = funcDC->getASTContext ();
261260
@@ -289,8 +288,8 @@ createDistributedActor_init_resolve_body(AbstractFunctionDecl *initDecl, void *)
289288 statements.push_back (assignAddressExpr);
290289 // end-of-FIXME: this must be checking with the transport instead
291290
292- auto *body = BraceStmt::create (C, SourceLoc (), statements, SourceLoc (),
293- /* implicit=*/ true );
291+ BraceStmt *body = BraceStmt::create (C, SourceLoc (), statements, SourceLoc (),
292+ /* implicit=*/ true );
294293
295294 return { body, /* isTypeChecked=*/ false };
296295}
@@ -306,7 +305,6 @@ static ConstructorDecl *
306305createDistributedActor_init_resolve (ClassDecl *classDecl,
307306 ASTContext &ctx) {
308307 auto &C = ctx;
309-
310308 auto conformanceDC = classDecl;
311309
312310 // Expected type: (Self) -> (ActorAddress, ActorTransport) -> (Self)
@@ -465,6 +463,81 @@ static void addImplicitDistributedActorConstructors(ClassDecl *decl) {
465463 }
466464}
467465
466+ /* *****************************************************************************/
467+ /* ******************************* DEINIT **************************************/
468+ /* *****************************************************************************/
469+
470+ // / A distributed actor's deinit MUST call `transport.resignAddress` before it
471+ // / is deallocated.
472+ static void addImplicitResignAddress (ClassDecl *decl) {
473+ auto &C = decl->getASTContext ();
474+
475+ DestructorDecl *existingDeinit = decl->getDestructor ();
476+ assert (existingDeinit);
477+
478+ // DestructorDecl *deinitDecl = existingDeinit != nullptr ? existingDeinit :
479+ // new (C) DestructorDecl(SourceLoc(), decl);
480+ DestructorDecl *deinitDecl = new (C) DestructorDecl (SourceLoc (), decl);
481+
482+ BraceStmt *body = deinitDecl->getBody ();
483+
484+ // == Copy all existing statements to the new deinit
485+ SmallVector<ASTNode, 2 > statements; // TODO: how to init at body statements count size?
486+ for (auto stmt : body->getElements ())
487+ statements.push_back (stmt); // TODO: copy?
488+
489+ // TODO: INJECT THIS AS FIRST THING IN A DEFER {}
490+
491+ // == Inject the lifecycle 'resignAddress' interaction
492+ // ==== self
493+ auto *selfRef = DerivedConformance::createSelfDeclRef (deinitDecl);
494+
495+ // ==== `self.actorTransport`
496+ auto *varTransportExpr = UnresolvedDotExpr::createImplicit (C, selfRef,
497+ C.Id_actorTransport );
498+
499+ // ==== `self.actorAddress`
500+ auto *varAddressExpr = UnresolvedDotExpr::createImplicit (C, selfRef,
501+ C.Id_actorAddress );
502+ // auto addressRef = new (C) DeclRefExpr(varAddressExpr, DeclNameLoc(),
503+ // /*implicit*/ true);
504+ // auto addressRef = new (C) DeclRefExpr(ConcreteDeclRef(varAddressExpr), DeclNameLoc(),
505+ // /*implicit=*/true);
506+ // addressRef->setType(varAddressExpr->getType());
507+
508+ // ==== `self.transport.resignAddress(self.actorAddress)`
509+ auto loc = deinitDecl->getLoc ();
510+ // auto resignAddressRef = new (C) DeclRefExpr(varTransportExpr, DeclNameLoc(),
511+ // /*implicit=*/true);
512+ // resignAddressRef->setThrows(false);
513+ auto resignFuncDecls = C.getActorTransportDecl ()->lookupDirect (C.Id_resignAddress );
514+ assert (resignFuncDecls.size () == 1 );
515+ AbstractFunctionDecl *resignFuncDecl = dyn_cast<AbstractFunctionDecl>(resignFuncDecls.front ());
516+ auto resignFuncRef = new (C) DeclRefExpr (resignFuncDecl, DeclNameLoc (), /* implicit=*/ true );
517+
518+ auto *addressParam = new (C) ParamDecl (
519+ SourceLoc (), SourceLoc (), Identifier (),
520+ SourceLoc (), C.Id_address , decl);
521+ addressParam->setInterfaceType (C.getActorAddressDecl ()->getInterfaceType ());
522+ addressParam->setSpecifier (ParamSpecifier::Default);
523+ addressParam->setImplicit ();
524+ auto *paramList = ParameterList::createWithoutLoc (addressParam);
525+
526+ auto *resignFuncRefRef = UnresolvedDotExpr::createImplicit (
527+ C, varTransportExpr, C.Id_resignAddress , paramList);
528+
529+ Expr *resignAddressCall = CallExpr::createImplicit (C, resignFuncRefRef,
530+ { varAddressExpr },
531+ { Identifier () });
532+ statements.push_back (resignAddressCall);
533+
534+ BraceStmt *newBody = BraceStmt::create (C, SourceLoc (), statements, SourceLoc (),
535+ /* implicit=*/ true );
536+
537+ newBody->dump ();
538+ deinitDecl->setBody (newBody, AbstractFunctionDecl::BodyKind::TypeChecked); // FIXME: no idea if Parsed is right, we are NOT type checked I guess?
539+ }
540+
468541/* *****************************************************************************/
469542/* ******************************* PROPERTIES **********************************/
470543/* *****************************************************************************/
@@ -577,7 +650,7 @@ synthesizeRemoteFuncStubBody(AbstractFunctionDecl *func, void *context) {
577650 auto uintInit = ctx.getIntBuiltinInitDecl (uintDecl);
578651
579652 auto missingTransportDecl = ctx.getMissingDistributedActorTransport ();
580- assert (missingTransportDecl);
653+ assert (missingTransportDecl && " Could not locate '_missingDistributedActorTransport' function " );
581654
582655 // Create a call to _Distributed._missingDistributedActorTransport
583656 auto loc = func->getLoc ();
@@ -733,4 +806,5 @@ void swift::addImplicitDistributedActorMembersToClass(ClassDecl *decl) {
733806 addImplicitDistributedActorConstructors (decl);
734807 addImplicitDistributedActorStoredProperties (decl);
735808 addImplicitRemoteActorFunctions (decl);
809+ // addImplicitResignAddress(decl);
736810}
0 commit comments