@@ -621,13 +621,13 @@ static Expr *constructDistributedUnownedSerialExecutor(ASTContext &ctx,
621
621
}
622
622
623
623
static std::pair<BraceStmt *, bool >
624
- deriveBodyDistributedActor_localUnownedExecutor (AbstractFunctionDecl *getter, void *) {
625
- // var localUnownedExecutor : UnownedSerialExecutor? {
624
+ deriveBodyDistributedActor_unownedExecutor (AbstractFunctionDecl *getter, void *) {
625
+ // var unownedExecutor : UnownedSerialExecutor {
626
626
// get {
627
627
// guard __isLocalActor(self) else {
628
- // return nil
628
+ // return buildDefaultDistributedRemoteActorExecutor(self)
629
629
// }
630
- // return Optional( Builtin.buildDefaultActorExecutorRef(self) )
630
+ // return Builtin.buildDefaultActorExecutorRef(self)
631
631
// }
632
632
// }
633
633
ASTContext &ctx = getter->getASTContext ();
@@ -657,7 +657,7 @@ deriveBodyDistributedActor_localUnownedExecutor(AbstractFunctionDecl *getter, vo
657
657
if (!initCall) return failure ();
658
658
659
659
// guard __isLocalActor(self) else {
660
- // return nil
660
+ // return buildDefaultDistributedRemoteActorExecutor(self)
661
661
// }
662
662
auto isLocalActorDecl = ctx.getIsLocalDistributedActor ();
663
663
DeclRefExpr *isLocalActorExpr =
@@ -673,22 +673,71 @@ deriveBodyDistributedActor_localUnownedExecutor(AbstractFunctionDecl *getter, vo
673
673
CallExpr *isLocalActorCall = CallExpr::createImplicit (ctx, isLocalActorExpr, argListForIsLocal);
674
674
isLocalActorCall->setType (ctx.getBoolType ());
675
675
isLocalActorCall->setThrows (false );
676
- auto returnNilIfRemoteStmt = DerivedConformance::returnNilIfFalseGuardTypeChecked (
677
- ctx, isLocalActorCall, /* optionalWrappedType=*/ initCall->getType ());
678
676
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
+ }
679
691
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
+ }
682
729
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 );
684
733
685
734
auto body = BraceStmt::create (
686
- ctx, SourceLoc (), { returnNilIfRemoteStmt, ret }, SourceLoc (), /* implicit=*/ true );
735
+ ctx, SourceLoc (), { guardElseRemoteReturnExec, returnDefaultExec }, SourceLoc (), /* implicit=*/ true );
687
736
return { body, /* isTypeChecked=*/ true };
688
737
}
689
738
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) {
692
741
ASTContext &ctx = derived.Context ;
693
742
694
743
// Retrieve the types and declarations we'll need to form this operation.
@@ -699,11 +748,10 @@ static ValueDecl *deriveDistributedActor_localUnownedExecutor(DerivedConformance
699
748
return nullptr ;
700
749
}
701
750
Type executorType = executorDecl->getDeclaredInterfaceType ();
702
- Type optionalExecutorType = executorType->wrapInOptionalType ();
703
751
704
752
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 )) {
707
755
return const_cast <VarDecl *>(existing);
708
756
} else {
709
757
// bad type, should be diagnosed elsewhere
@@ -713,8 +761,8 @@ static ValueDecl *deriveDistributedActor_localUnownedExecutor(DerivedConformance
713
761
}
714
762
715
763
auto propertyPair = derived.declareDerivedProperty (
716
- DerivedConformance::SynthesizedIntroducer::Var, ctx.Id_localUnownedExecutor ,
717
- optionalExecutorType, optionalExecutorType ,
764
+ DerivedConformance::SynthesizedIntroducer::Var, ctx.Id_unownedExecutor ,
765
+ executorType, executorType ,
718
766
/* static*/ false , /* final*/ false );
719
767
auto property = propertyPair.first ;
720
768
property->setSynthesized (true );
@@ -738,8 +786,8 @@ static ValueDecl *deriveDistributedActor_localUnownedExecutor(DerivedConformance
738
786
property, asAvailableAs, ctx);
739
787
740
788
auto getter =
741
- derived.addGetterToReadOnlyDerivedProperty (property, optionalExecutorType );
742
- getter->setBodySynthesizer (deriveBodyDistributedActor_localUnownedExecutor );
789
+ derived.addGetterToReadOnlyDerivedProperty (property, executorType );
790
+ getter->setBodySynthesizer (deriveBodyDistributedActor_unownedExecutor );
743
791
744
792
// IMPORTANT: MUST BE AFTER [id, actorSystem].
745
793
if (auto id = derived.Nominal ->getDistributedActorIDProperty ()) {
@@ -782,24 +830,24 @@ static void assertRequiredSynthesizedPropertyOrder(DerivedConformance &derived,
782
830
if (auto id = Nominal->getDistributedActorIDProperty ()) {
783
831
if (auto system = Nominal->getDistributedActorSystemProperty ()) {
784
832
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 ;
787
835
int idx = 0 ;
788
836
for (auto member: Nominal->getMembers ()) {
789
837
if (auto binding = dyn_cast<PatternBindingDecl>(member)) {
790
838
if (binding->getSingleVar ()->getName () == Context.Id_id ) {
791
839
idIdx = idx;
792
840
} else if (binding->getSingleVar ()->getName () == Context.Id_actorSystem ) {
793
841
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;
796
844
}
797
845
idx += 1 ;
798
846
}
799
847
}
800
- if (idIdx + actorSystemIdx + localUnownedExecutorIdx >= 0 + 1 + 2 ) {
848
+ if (idIdx + actorSystemIdx + unownedExecutorIdx >= 0 + 1 + 2 ) {
801
849
// 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." );
803
851
}
804
852
}
805
853
}
@@ -821,8 +869,8 @@ ValueDecl *DerivedConformance::deriveDistributedActor(ValueDecl *requirement) {
821
869
derivedValue = deriveDistributedActor_id (*this );
822
870
} else if (var->getName () == Context.Id_actorSystem ) {
823
871
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 );
826
874
}
827
875
828
876
assertRequiredSynthesizedPropertyOrder (*this , derivedValue);
0 commit comments