@@ -790,7 +790,7 @@ static bool isDistributedActorCtor(SILFunction &F) {
790790// / Injects a hop_to_executor instruction after the specified insertion point.
791791static void injectHopToExecutorAfter (SILLocation loc,
792792 SILBasicBlock::iterator insertPt,
793- SILValue actor, bool needsBorrow = true ) {
793+ DIMemoryObjectInfo &TheMemory ) {
794794
795795 LLVM_DEBUG (llvm::dbgs () << " hop-injector: requested insertion after "
796796 << *insertPt);
@@ -805,20 +805,30 @@ static void injectHopToExecutorAfter(SILLocation loc,
805805 auto injectAfter = [&](SILInstruction *insertPt) -> void {
806806 LLVM_DEBUG (llvm::dbgs () << " hop-injector: injecting after " << *insertPt);
807807 SILBuilderWithScope::insertAfter (insertPt, [&](SILBuilder &b) {
808- if (needsBorrow)
809- actor = b.createBeginBorrow (loc, actor);
808+
809+ const bool delegating = !TheMemory.isNonDelegatingInit ();
810+ SILValue val = TheMemory.getUninitializedValue ();
811+
812+ // delegating inits always have an alloc we need to load it from.
813+ if (delegating)
814+ val = b.createLoad (loc.asAutoGenerated (), val,
815+ LoadOwnershipQualifier::Copy);
816+
817+ SILValue actor = b.createBeginBorrow (loc.asAutoGenerated (), val);
810818
811819 b.createHopToExecutor (loc.asAutoGenerated (), actor, /* mandatory=*/ false );
812820
813821 // Distributed actors also need to notify their transport immediately
814822 // after performing the hop.
815- if (isDistributedActorCtor (b.getFunction ())) {
823+ if (!delegating && isDistributedActorCtor (b.getFunction ())) {
816824 auto transport = findFirstDistributedActorSystemArg (b.getFunction ());
817825 emitActorReadyCall (b, loc.asAutoGenerated (), actor, transport);
818826 }
819827
820- if (needsBorrow)
821- b.createEndBorrow (loc, actor);
828+ b.createEndBorrow (loc.asAutoGenerated (), actor);
829+
830+ if (delegating)
831+ b.createDestroyValue (loc.asAutoGenerated (), val);
822832 });
823833 };
824834
@@ -892,7 +902,7 @@ void LifetimeChecker::injectActorHopForBlock(
892902 // Make sure we found the initializing use of TheMemory.
893903 assert (bbi != bbe && " this block is not initializing?" );
894904
895- injectHopToExecutorAfter (loc, bbi, TheMemory. getUninitializedValue () );
905+ injectHopToExecutorAfter (loc, bbi, TheMemory);
896906}
897907
898908static bool isFailableInitReturnUseOfEnum (EnumInst *EI);
@@ -929,8 +939,8 @@ void LifetimeChecker::injectActorHops() {
929939 // We insert this directly after the mark_uninitialized instruction, so
930940 // that it happens as early as `self` is available.`
931941 if (TheMemory.getNumElements () == 0 ) {
932- auto *selfDef = TheMemory.getUninitializedValue ();
933- return injectHopToExecutorAfter (ctor, selfDef->getIterator (), selfDef );
942+ auto *selfDef = TheMemory.getUninitializedValue (); // FIXME: this might be wrong for convenience inits (rdar://87485045)
943+ return injectHopToExecutorAfter (ctor, selfDef->getIterator (), TheMemory );
934944 }
935945
936946 // Returns true iff a block returns normally from the initializer,
0 commit comments