@@ -7851,18 +7851,6 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
78517851 return ctorCall;
78527852}
78537853
7854- // / Determine whether this closure should be treated as Sendable.
7855- static bool isSendableClosure (ConstraintSystem &cs,
7856- const AbstractClosureExpr *closure) {
7857- if (auto fnType = cs.getType (const_cast <AbstractClosureExpr *>(closure))
7858- ->getAs <FunctionType>()) {
7859- if (fnType->isSendable ())
7860- return true ;
7861- }
7862-
7863- return false ;
7864- }
7865-
78667854bool ExprRewriter::isDistributedThunk (ConcreteDeclRef ref, Expr *context) {
78677855 auto *FD = dyn_cast_or_null<AbstractFunctionDecl>(ref.getDecl ());
78687856 if (!(FD && FD->isInstanceMember () && FD->isDistributed ()))
@@ -7886,55 +7874,60 @@ bool ExprRewriter::isDistributedThunk(ConcreteDeclRef ref, Expr *context) {
78867874
78877875 // If this is a method reference on an potentially isolated
78887876 // actor then it cannot be a remote thunk.
7889- if (isPotentiallyIsolatedActor (actor, [&](ParamDecl *P) {
7890- return P->isIsolated () ||
7891- llvm::is_contained (solution.isolatedParams , P);
7892- }))
7893- return false ;
7894-
7895- if (actor->isKnownToBeLocal ())
7896- return false ;
7897-
7898- bool isInAsyncLetInitializer = target && target->isAsyncLetInitializer ();
7899-
7900- auto isActorInitOrDeInitContext = [&](const DeclContext *dc) {
7901- return ::isActorInitOrDeInitContext (
7902- dc, [&](const AbstractClosureExpr *closure) {
7903- return isSendableClosure (cs, closure);
7904- });
7905- };
7906-
7907- switch (ActorIsolationRestriction::forDeclaration (ref, dc)) {
7908- case ActorIsolationRestriction::CrossActorSelf: {
7909- // Not a thunk if it's used in actor init or de-init.
7910- if (!isInAsyncLetInitializer && isActorInitOrDeInitContext (dc))
7911- return false ;
7877+ bool isPotentiallyIsolated = isPotentiallyIsolatedActor (
7878+ actor,
7879+ [&](ParamDecl *P) {
7880+ return P->isIsolated () ||
7881+ llvm::is_contained (solution.isolatedParams , P);
7882+ });
7883+
7884+ // Adjust the declaration context to the innermost context that is neither
7885+ // a local function nor a closure, so that the actor reference is checked
7886+ auto referenceDC = dc;
7887+ while (true ) {
7888+ switch (referenceDC->getContextKind ()) {
7889+ case DeclContextKind::AbstractClosureExpr:
7890+ case DeclContextKind::Initializer:
7891+ case DeclContextKind::SerializedLocal:
7892+ referenceDC = referenceDC->getParent ();
7893+ continue ;
79127894
7913- // Here we know that the method could be used across actors
7914- // and the actor it's used on is non-isolated, which means
7915- // that it could be a thunk, so we have to be conservative
7916- // about it.
7917- return true ;
7918- }
7895+ case DeclContextKind::AbstractFunctionDecl:
7896+ case DeclContextKind::GenericTypeDecl:
7897+ case DeclContextKind::SubscriptDecl:
7898+ if (auto value = dyn_cast<ValueDecl>(referenceDC->getAsDecl ())) {
7899+ if (value->isLocalCapture ()) {
7900+ referenceDC = referenceDC->getParent ();
7901+ continue ;
7902+ }
7903+ }
7904+ break ;
79197905
7920- case ActorIsolationRestriction::ActorSelf: {
7921- // An instance member of an actor can be referenced from an actor's
7922- // designated initializer or deinitializer.
7923- if (actor->isActorSelf () && !isInAsyncLetInitializer) {
7924- if (auto *fn = isActorInitOrDeInitContext (dc)) {
7925- if (!(isa<ConstructorDecl>(fn) &&
7926- cast<ConstructorDecl>(fn)->isConvenienceInit ()))
7927- return false ;
7928- }
7906+ case DeclContextKind::EnumElementDecl:
7907+ case DeclContextKind::ExtensionDecl:
7908+ case DeclContextKind::FileUnit:
7909+ case DeclContextKind::Module:
7910+ case DeclContextKind::TopLevelCodeDecl:
7911+ break ;
79297912 }
79307913
7931- // Call on a non-isolated actor in async context requires
7932- // implicit thunk.
7933- return isInAsyncLetInitializer || cs.isAsynchronousContext (dc);
7914+ break ;
79347915 }
79357916
7936- default :
7917+ // Create a simple actor reference, assuming that we might be in a
7918+ // non-isolated context but knowing whether it's potentially isolated.
7919+ // We only care about the "distributed" flag.
7920+ ReferencedActor actorRef = ReferencedActor (
7921+ actor, isPotentiallyIsolated, ReferencedActor::NonIsolatedContext);
7922+ auto refResult = ActorReferenceResult::forReference (
7923+ ref, context->getLoc (), referenceDC, None, actorRef);
7924+ switch (refResult) {
7925+ case ActorReferenceResult::ExitsActorToNonisolated:
7926+ case ActorReferenceResult::SameConcurrencyDomain:
79377927 return false ;
7928+
7929+ case ActorReferenceResult::EntersActor:
7930+ return refResult.options .contains (ActorReferenceResult::Flags::Distributed);
79387931 }
79397932}
79407933
0 commit comments