@@ -558,6 +558,17 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
558558 !F.isAsync () &&
559559 !isInActorDestructor (FunctionDC);
560560
561+ // Local function to load the expected executor from a local actor
562+ auto loadExpectedExecutorForLocalVar = [&](VarDecl *var) {
563+ auto loc = RegularLocation::getAutoGeneratedLocation (F.getLocation ());
564+ Type actorType = var->getType ();
565+ RValue actorInstanceRV = emitRValueForDecl (
566+ loc, var, actorType, AccessSemantics::Ordinary);
567+ ManagedValue actorInstance =
568+ std::move (actorInstanceRV).getScalarValue ();
569+ ExpectedExecutor = emitLoadActorExecutor (loc, actorInstance);
570+ };
571+
561572 if (auto *funcDecl =
562573 dyn_cast_or_null<AbstractFunctionDecl>(FunctionDC->getAsDecl ())) {
563574 auto actorIsolation = getActorIsolation (funcDecl);
@@ -569,13 +580,7 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
569580 if (F.isAsync ()) {
570581 for (auto param : *funcDecl->getParameters ()) {
571582 if (param->isIsolated ()) {
572- auto loc = RegularLocation::getAutoGeneratedLocation (F.getLocation ());
573- Type actorType = param->getType ();
574- RValue actorInstanceRV = emitRValueForDecl (
575- loc, param, actorType, AccessSemantics::Ordinary);
576- ManagedValue actorInstance =
577- std::move (actorInstanceRV).getScalarValue ();
578- ExpectedExecutor = emitLoadActorExecutor (loc, actorInstance);
583+ loadExpectedExecutorForLocalVar (param);
579584 break ;
580585 }
581586 }
@@ -588,16 +593,21 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
588593 }
589594
590595 case ActorIsolation::ActorInstance: {
591- assert (selfParam && " no self parameter for ActorInstance isolation" );
592596 // Only produce an executor for actor-isolated functions that are async
593597 // or are local functions. The former require a hop, while the latter
594598 // are prone to dynamic data races in code that does not enforce Sendable
595599 // completely.
596600 if (F.isAsync () ||
597601 (wantDataRaceChecks && funcDecl->isLocalCapture ())) {
598- auto loc = RegularLocation::getAutoGeneratedLocation (F.getLocation ());
599- ManagedValue selfArg = ManagedValue::forUnmanaged (F.getSelfArgument ());
600- ExpectedExecutor = emitLoadActorExecutor (loc, selfArg);
602+ if (auto isolatedParam = funcDecl->getCaptureInfo ()
603+ .getIsolatedParamCapture ()) {
604+ loadExpectedExecutorForLocalVar (isolatedParam);
605+ } else {
606+ assert (selfParam && " no self parameter for ActorInstance isolation" );
607+ auto loc = RegularLocation::getAutoGeneratedLocation (F.getLocation ());
608+ ManagedValue selfArg = ManagedValue::forUnmanaged (F.getSelfArgument ());
609+ ExpectedExecutor = emitLoadActorExecutor (loc, selfArg);
610+ }
601611 }
602612 break ;
603613 }
@@ -619,14 +629,7 @@ void SILGenFunction::emitProlog(CaptureInfo captureInfo,
619629
620630 case ClosureActorIsolation::ActorInstance: {
621631 if (wantExecutor) {
622- auto loc = RegularLocation::getAutoGeneratedLocation (F.getLocation ());
623- auto actorDecl = actorIsolation.getActorInstance ();
624- Type actorType = actorDecl->getType ();
625- RValue actorInstanceRV = emitRValueForDecl (loc,
626- actorDecl, actorType, AccessSemantics::Ordinary);
627- ManagedValue actorInstance =
628- std::move (actorInstanceRV).getScalarValue ();
629- ExpectedExecutor = emitLoadActorExecutor (loc, actorInstance);
632+ loadExpectedExecutorForLocalVar (actorIsolation.getActorInstance ());
630633 }
631634 break ;
632635 }
0 commit comments