@@ -7786,18 +7786,6 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
77867786 return ctorCall;
77877787}
77887788
7789- // / Determine whether this closure should be treated as Sendable.
7790- static bool isSendableClosure (ConstraintSystem &cs,
7791- const AbstractClosureExpr *closure) {
7792- if (auto fnType = cs.getType (const_cast <AbstractClosureExpr *>(closure))
7793- ->getAs <FunctionType>()) {
7794- if (fnType->isSendable ())
7795- return true ;
7796- }
7797-
7798- return false ;
7799- }
7800-
78017789bool ExprRewriter::isDistributedThunk (ConcreteDeclRef ref, Expr *context) {
78027790 auto *FD = dyn_cast_or_null<AbstractFunctionDecl>(ref.getDecl ());
78037791 if (!(FD && FD->isInstanceMember () && FD->isDistributed ()))
@@ -7821,55 +7809,60 @@ bool ExprRewriter::isDistributedThunk(ConcreteDeclRef ref, Expr *context) {
78217809
78227810 // If this is a method reference on an potentially isolated
78237811 // actor then it cannot be a remote thunk.
7824- if (isPotentiallyIsolatedActor (actor, [&](ParamDecl *P) {
7825- return P->isIsolated () ||
7826- llvm::is_contained (solution.isolatedParams , P);
7827- }))
7828- return false ;
7829-
7830- if (actor->isKnownToBeLocal ())
7831- return false ;
7832-
7833- bool isInAsyncLetInitializer = target && target->isAsyncLetInitializer ();
7834-
7835- auto isActorInitOrDeInitContext = [&](const DeclContext *dc) {
7836- return ::isActorInitOrDeInitContext (
7837- dc, [&](const AbstractClosureExpr *closure) {
7838- return isSendableClosure (cs, closure);
7839- });
7840- };
7841-
7842- switch (ActorIsolationRestriction::forDeclaration (ref, dc)) {
7843- case ActorIsolationRestriction::CrossActorSelf: {
7844- // Not a thunk if it's used in actor init or de-init.
7845- if (!isInAsyncLetInitializer && isActorInitOrDeInitContext (dc))
7846- return false ;
7812+ bool isPotentiallyIsolated = isPotentiallyIsolatedActor (
7813+ actor,
7814+ [&](ParamDecl *P) {
7815+ return P->isIsolated () ||
7816+ llvm::is_contained (solution.isolatedParams , P);
7817+ });
7818+
7819+ // Adjust the declaration context to the innermost context that is neither
7820+ // a local function nor a closure, so that the actor reference is checked
7821+ auto referenceDC = dc;
7822+ while (true ) {
7823+ switch (referenceDC->getContextKind ()) {
7824+ case DeclContextKind::AbstractClosureExpr:
7825+ case DeclContextKind::Initializer:
7826+ case DeclContextKind::SerializedLocal:
7827+ referenceDC = referenceDC->getParent ();
7828+ continue ;
78477829
7848- // Here we know that the method could be used across actors
7849- // and the actor it's used on is non-isolated, which means
7850- // that it could be a thunk, so we have to be conservative
7851- // about it.
7852- return true ;
7853- }
7830+ case DeclContextKind::AbstractFunctionDecl:
7831+ case DeclContextKind::GenericTypeDecl:
7832+ case DeclContextKind::SubscriptDecl:
7833+ if (auto value = dyn_cast<ValueDecl>(referenceDC->getAsDecl ())) {
7834+ if (value->isLocalCapture ()) {
7835+ referenceDC = referenceDC->getParent ();
7836+ continue ;
7837+ }
7838+ }
7839+ break ;
78547840
7855- case ActorIsolationRestriction::ActorSelf: {
7856- // An instance member of an actor can be referenced from an actor's
7857- // designated initializer or deinitializer.
7858- if (actor->isActorSelf () && !isInAsyncLetInitializer) {
7859- if (auto *fn = isActorInitOrDeInitContext (dc)) {
7860- if (!(isa<ConstructorDecl>(fn) &&
7861- cast<ConstructorDecl>(fn)->isConvenienceInit ()))
7862- return false ;
7863- }
7841+ case DeclContextKind::EnumElementDecl:
7842+ case DeclContextKind::ExtensionDecl:
7843+ case DeclContextKind::FileUnit:
7844+ case DeclContextKind::Module:
7845+ case DeclContextKind::TopLevelCodeDecl:
7846+ break ;
78647847 }
78657848
7866- // Call on a non-isolated actor in async context requires
7867- // implicit thunk.
7868- return isInAsyncLetInitializer || cs.isAsynchronousContext (dc);
7849+ break ;
78697850 }
78707851
7871- default :
7852+ // Create a simple actor reference, assuming that we might be in a
7853+ // non-isolated context but knowing whether it's potentially isolated.
7854+ // We only care about the "distributed" flag.
7855+ ReferencedActor actorRef = ReferencedActor (
7856+ actor, isPotentiallyIsolated, ReferencedActor::NonIsolatedContext);
7857+ auto refResult = ActorReferenceResult::forReference (
7858+ ref, context->getLoc (), referenceDC, None, actorRef);
7859+ switch (refResult) {
7860+ case ActorReferenceResult::ExitsActorToNonisolated:
7861+ case ActorReferenceResult::SameConcurrencyDomain:
78727862 return false ;
7863+
7864+ case ActorReferenceResult::EntersActor:
7865+ return refResult.options .contains (ActorReferenceResult::Flags::Distributed);
78737866 }
78747867}
78757868
0 commit comments