@@ -621,13 +621,13 @@ static Expr *constructDistributedUnownedSerialExecutor(ASTContext &ctx,
621621}
622622
623623static std::pair<BraceStmt *, bool >
624- deriveBodyDistributedActor_localUnownedExecutor (AbstractFunctionDecl *getter, void *) {
625- // var localUnownedExecutor : UnownedSerialExecutor? {
624+ deriveBodyDistributedActor_unownedExecutor (AbstractFunctionDecl *getter, void *) {
625+ // var unownedExecutor : UnownedSerialExecutor {
626626 // get {
627627 // guard __isLocalActor(self) else {
628- // return nil
628+ // return buildDefaultDistributedRemoteActorExecutor(self)
629629 // }
630- // return Optional( Builtin.buildDefaultActorExecutorRef(self) )
630+ // return Builtin.buildDefaultActorExecutorRef(self)
631631 // }
632632 // }
633633 ASTContext &ctx = getter->getASTContext ();
@@ -657,7 +657,7 @@ deriveBodyDistributedActor_localUnownedExecutor(AbstractFunctionDecl *getter, vo
657657 if (!initCall) return failure ();
658658
659659 // guard __isLocalActor(self) else {
660- // return nil
660+ // return buildDefaultDistributedRemoteActorExecutor(self)
661661 // }
662662 auto isLocalActorDecl = ctx.getIsLocalDistributedActor ();
663663 DeclRefExpr *isLocalActorExpr =
@@ -673,22 +673,71 @@ deriveBodyDistributedActor_localUnownedExecutor(AbstractFunctionDecl *getter, vo
673673 CallExpr *isLocalActorCall = CallExpr::createImplicit (ctx, isLocalActorExpr, argListForIsLocal);
674674 isLocalActorCall->setType (ctx.getBoolType ());
675675 isLocalActorCall->setThrows (false );
676- auto returnNilIfRemoteStmt = DerivedConformance::returnNilIfFalseGuardTypeChecked (
677- ctx, isLocalActorCall, /* optionalWrappedType=*/ initCall->getType ());
678676
677+ GuardStmt* guardElseRemoteReturnExec;
678+ {
679+ // Find the buildDefaultDistributedRemoteActorExecutor method
680+ auto buildRemoteExecutorDecl =
681+ ctx.getBuildDefaultDistributedRemoteActorUnownedExecutor ();
682+ assert (buildRemoteExecutorDecl && " cannot find buildDefaultDistributedRemoteActorExecutor" );
683+ auto substitutions = SubstitutionMap::get (
684+ buildRemoteExecutorDecl->getGenericSignature (),
685+ [&](SubstitutableType *dependentType) {
686+ if (auto gp = dyn_cast<GenericTypeParamType>(dependentType)) {
687+ if (gp->getDepth () == 0 && gp->getIndex () == 0 ) {
688+ return getter->getImplicitSelfDecl ()->getType ();
689+ }
690+ }
679691
680- // Finalize preparing the unowned executor for returning.
681- auto wrappedCall = new (ctx) InjectIntoOptionalExpr (initCall, initCall->getType ()->wrapInOptionalType ());
692+ return Type ();
693+ },
694+ LookUpConformanceInModule (getter->getParentModule ())
695+ );
696+ DeclRefExpr *buildRemoteExecutorExpr =
697+ new (ctx) DeclRefExpr (
698+ ConcreteDeclRef (buildRemoteExecutorDecl, substitutions),
699+ DeclNameLoc (),/* implicit=*/ true ,
700+ AccessSemantics::Ordinary);
701+ buildRemoteExecutorExpr->setType (
702+ buildRemoteExecutorDecl->getInterfaceType ()
703+ .subst (substitutions)
704+ );
705+
706+ Expr *selfForBuildRemoteExecutor = DerivedConformance::createSelfDeclRef (getter);
707+ selfForBuildRemoteExecutor->setType (selfType);
708+ auto *argListForBuildRemoteExecutor =
709+ ArgumentList::forImplicitCallTo (buildRemoteExecutorDecl->getParameters (),
710+ /* argExprs=*/ {selfForBuildRemoteExecutor}, ctx);
711+ CallExpr *buildRemoteExecutorCall = CallExpr::createImplicit (ctx, buildRemoteExecutorExpr,
712+ argListForBuildRemoteExecutor);
713+ buildRemoteExecutorCall->setType (ctx.getUnownedSerialExecutorType ());
714+ buildRemoteExecutorCall->setThrows (false );
715+
716+ SmallVector<ASTNode, 1 > statements = {
717+ new (ctx) ReturnStmt (SourceLoc (), buildRemoteExecutorCall)
718+ };
719+
720+ SmallVector<StmtConditionElement, 1 > conditions = {
721+ isLocalActorCall
722+ };
723+
724+ // Build and return the complete guard statement.
725+ guardElseRemoteReturnExec =
726+ new (ctx) GuardStmt (SourceLoc (), ctx.AllocateCopy (conditions),
727+ BraceStmt::create (ctx, SourceLoc (), statements, SourceLoc ()));
728+ }
682729
683- auto ret = new (ctx) ReturnStmt (SourceLoc (), wrappedCall, /* implicit*/ true );
730+ // Finalize preparing the unowned executor for returning.
731+ // auto wrappedCall = new (ctx) InjectIntoOptionalExpr(initCall, initCall->getType());
732+ auto returnDefaultExec = new (ctx) ReturnStmt (SourceLoc (), initCall, /* implicit=*/ true );
684733
685734 auto body = BraceStmt::create (
686- ctx, SourceLoc (), { returnNilIfRemoteStmt, ret }, SourceLoc (), /* implicit=*/ true );
735+ ctx, SourceLoc (), { guardElseRemoteReturnExec, returnDefaultExec }, SourceLoc (), /* implicit=*/ true );
687736 return { body, /* isTypeChecked=*/ true };
688737}
689738
690- // / Derive the declaration of DistributedActor's localUnownedExecutor property.
691- static ValueDecl *deriveDistributedActor_localUnownedExecutor (DerivedConformance &derived) {
739+ // / Derive the declaration of DistributedActor's unownedExecutor property.
740+ static ValueDecl *deriveDistributedActor_unownedExecutor (DerivedConformance &derived) {
692741 ASTContext &ctx = derived.Context ;
693742
694743 // Retrieve the types and declarations we'll need to form this operation.
@@ -699,11 +748,10 @@ static ValueDecl *deriveDistributedActor_localUnownedExecutor(DerivedConformance
699748 return nullptr ;
700749 }
701750 Type executorType = executorDecl->getDeclaredInterfaceType ();
702- Type optionalExecutorType = executorType->wrapInOptionalType ();
703751
704752 if (auto classDecl = dyn_cast<ClassDecl>(derived.Nominal )) {
705- if (auto existing = classDecl->getLocalUnownedExecutorProperty ()) {
706- if (existing->getInterfaceType ()->isEqual (optionalExecutorType )) {
753+ if (auto existing = classDecl->getUnownedExecutorProperty ()) {
754+ if (existing->getInterfaceType ()->isEqual (executorType )) {
707755 return const_cast <VarDecl *>(existing);
708756 } else {
709757 // bad type, should be diagnosed elsewhere
@@ -713,8 +761,8 @@ static ValueDecl *deriveDistributedActor_localUnownedExecutor(DerivedConformance
713761 }
714762
715763 auto propertyPair = derived.declareDerivedProperty (
716- DerivedConformance::SynthesizedIntroducer::Var, ctx.Id_localUnownedExecutor ,
717- optionalExecutorType, optionalExecutorType ,
764+ DerivedConformance::SynthesizedIntroducer::Var, ctx.Id_unownedExecutor ,
765+ executorType, executorType ,
718766 /* static*/ false , /* final*/ false );
719767 auto property = propertyPair.first ;
720768 property->setSynthesized (true );
@@ -738,8 +786,8 @@ static ValueDecl *deriveDistributedActor_localUnownedExecutor(DerivedConformance
738786 property, asAvailableAs, ctx);
739787
740788 auto getter =
741- derived.addGetterToReadOnlyDerivedProperty (property, optionalExecutorType );
742- getter->setBodySynthesizer (deriveBodyDistributedActor_localUnownedExecutor );
789+ derived.addGetterToReadOnlyDerivedProperty (property, executorType );
790+ getter->setBodySynthesizer (deriveBodyDistributedActor_unownedExecutor );
743791
744792 // IMPORTANT: MUST BE AFTER [id, actorSystem].
745793 if (auto id = derived.Nominal ->getDistributedActorIDProperty ()) {
@@ -782,24 +830,24 @@ static void assertRequiredSynthesizedPropertyOrder(DerivedConformance &derived,
782830 if (auto id = Nominal->getDistributedActorIDProperty ()) {
783831 if (auto system = Nominal->getDistributedActorSystemProperty ()) {
784832 if (auto classDecl = dyn_cast<ClassDecl>(derived.Nominal )) {
785- if (auto localUnownedExecutor = classDecl->getLocalUnownedExecutorProperty ()) {
786- int idIdx, actorSystemIdx, localUnownedExecutorIdx = 0 ;
833+ if (auto unownedExecutor = classDecl->getUnownedExecutorProperty ()) {
834+ int idIdx, actorSystemIdx, unownedExecutorIdx = 0 ;
787835 int idx = 0 ;
788836 for (auto member: Nominal->getMembers ()) {
789837 if (auto binding = dyn_cast<PatternBindingDecl>(member)) {
790838 if (binding->getSingleVar ()->getName () == Context.Id_id ) {
791839 idIdx = idx;
792840 } else if (binding->getSingleVar ()->getName () == Context.Id_actorSystem ) {
793841 actorSystemIdx = idx;
794- } else if (binding->getSingleVar ()->getName () == Context.Id_localUnownedExecutor ) {
795- localUnownedExecutorIdx = idx;
842+ } else if (binding->getSingleVar ()->getName () == Context.Id_unownedExecutor ) {
843+ unownedExecutorIdx = idx;
796844 }
797845 idx += 1 ;
798846 }
799847 }
800- if (idIdx + actorSystemIdx + localUnownedExecutorIdx >= 0 + 1 + 2 ) {
848+ if (idIdx + actorSystemIdx + unownedExecutorIdx >= 0 + 1 + 2 ) {
801849 // we have found all the necessary fields, let's assert their order
802- assert (idIdx < actorSystemIdx < localUnownedExecutorIdx && " order of fields MUST be exact." );
850+ assert (idIdx < actorSystemIdx < unownedExecutorIdx && " order of fields MUST be exact." );
803851 }
804852 }
805853 }
@@ -821,8 +869,8 @@ ValueDecl *DerivedConformance::deriveDistributedActor(ValueDecl *requirement) {
821869 derivedValue = deriveDistributedActor_id (*this );
822870 } else if (var->getName () == Context.Id_actorSystem ) {
823871 derivedValue = deriveDistributedActor_actorSystem (*this );
824- } else if (var->getName () == Context.Id_localUnownedExecutor ) {
825- derivedValue = deriveDistributedActor_localUnownedExecutor (*this );
872+ } else if (var->getName () == Context.Id_unownedExecutor ) {
873+ derivedValue = deriveDistributedActor_unownedExecutor (*this );
826874 }
827875
828876 assertRequiredSynthesizedPropertyOrder (*this , derivedValue);
0 commit comments