@@ -742,6 +742,10 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
742
742
743
743
SILType selfTy = getLoweredLoadableType (selfDecl->getType ());
744
744
ManagedValue selfArg = B.createInputFunctionArgument (selfTy, selfDecl);
745
+
746
+ // is this a designated initializer for a distributed actor?
747
+ const bool isDesignatedDistActorInit =
748
+ selfClassDecl->isDistributedActor () && !isDelegating;
745
749
746
750
// Make sure we've hopped to the right global actor, if any.
747
751
if (ctor->hasAsync () && !selfClassDecl->isActor ()) {
@@ -780,7 +784,7 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
780
784
}
781
785
782
786
// Distributed actor initializers implicitly initialize their transport and id
783
- if (selfClassDecl-> isDistributedActor () && !isDelegating ) {
787
+ if (isDesignatedDistActorInit ) {
784
788
initializeDistributedActorImplicitStorageInit (ctor, selfArg);
785
789
}
786
790
@@ -814,6 +818,13 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
814
818
failureExitBB = createBasicBlock ();
815
819
failureExitArg = failureExitBB->createPhiArgument (
816
820
resultLowering.getLoweredType (), OwnershipKind::Owned);
821
+
822
+ // For an async distributed actor init, we must `resignIdentity` before
823
+ // the clean-ups are triggered in this failure block.
824
+ if (isDesignatedDistActorInit && ctor->hasAsync ()) {
825
+ // TODO: refactor emitDistributedActor_resignAddress so we can call it
826
+ // within this initializer.
827
+ }
817
828
818
829
Cleanups.emitCleanupsForReturn (ctor, IsForUnwind);
819
830
SILValue nilResult =
@@ -865,6 +876,18 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
865
876
B.clearInsertionPoint ();
866
877
}
867
878
}
879
+
880
+ // For distributed actors, their synchronous initializers invoke "actor ready"
881
+ // at the very end, just before returning on a successful initialization.
882
+ // There is no need for injecting `resignIdentity` calls in such inits,
883
+ // because we can never call `actorReady` prematurely.
884
+ if (isDesignatedDistActorInit && !ctor->hasAsync ()) {
885
+ RegularLocation loc (ctor);
886
+ loc.markAutoGenerated ();
887
+
888
+ SILGenSavedInsertionPoint savedIP (*this , ReturnDest.getBlock ());
889
+ emitDistributedActorReady (loc, ctor, selfArg);
890
+ }
868
891
869
892
CleanupStateRestorationScope SelfCleanupSave (Cleanups);
870
893
@@ -931,12 +954,6 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
931
954
// Unpop our selfArg cleanup, so we can forward.
932
955
std::move (SelfCleanupSave).pop ();
933
956
934
- // TODO(distributed): rdar://81783599 if this is a distributed actor, jump to the distributedReady block?
935
- // // For distributed actors, emit "actor ready" since we successfully initialized
936
- // if (selfClassDecl->isDistributedActor() && !isDelegating) {
937
- // emitDistributedActorReady(ctor, selfArg);
938
- // }
939
-
940
957
// Finish off the epilog by returning. If this is a failable ctor, then we
941
958
// actually jump to the failure epilog to keep the invariant that there is
942
959
// only one SIL return instruction per SIL function.
0 commit comments