@@ -1261,6 +1261,9 @@ ReferencedActor ReferencedActor::forGlobalActor(VarDecl *actor,
12611261 return ReferencedActor (actor, isPotentiallyIsolated, kind, globalActor);
12621262}
12631263
1264+ static ActorIsolation getActorIsolationForReference (
1265+ ValueDecl *decl, const DeclContext *fromDC);
1266+
12641267bool ReferencedActor::isKnownToBeLocal () const {
12651268 switch (kind) {
12661269 case GlobalActor:
@@ -2250,54 +2253,36 @@ namespace {
22502253 return false ;
22512254
22522255 bool result = false ;
2253- auto checkDiagnostic = [this , call, isPartialApply,
2254- &result](ValueDecl *decl, SourceLoc argLoc) {
2255- auto isolation = ActorIsolationRestriction::forDeclaration (
2256- decl, getDeclContext ());
2257- switch (isolation) {
2258- case ActorIsolationRestriction::Unrestricted:
2259- case ActorIsolationRestriction::Unsafe:
2260- break ;
2261- case ActorIsolationRestriction::GlobalActorUnsafe:
2262- // If we're not supposed to diagnose existing data races here,
2263- // we're done.
2264- if (!shouldDiagnoseExistingDataRaces (getDeclContext ()))
2265- break ;
2266-
2267- LLVM_FALLTHROUGH;
2256+ auto checkDiagnostic = [this , call, isPartialApply, &result](
2257+ ConcreteDeclRef declRef, SourceLoc argLoc) {
2258+ auto decl = declRef.getDecl ();
2259+ auto isolation = getActorIsolationForReference (decl, getDeclContext ());
2260+ if (!isolation.isActorIsolated ())
2261+ return ;
22682262
2269- case ActorIsolationRestriction::GlobalActor: {
2270- ctx.Diags .diagnose (argLoc, diag::actor_isolated_inout_state,
2271- decl->getDescriptiveKind (), decl->getName (),
2272- call->isImplicitlyAsync ().hasValue ());
2273- decl->diagnose (diag::kind_declared_here, decl->getDescriptiveKind ());
2274- result = true ;
2275- break ;
2276- }
2277- case ActorIsolationRestriction::CrossActorSelf:
2278- case ActorIsolationRestriction::ActorSelf: {
2279- if (isPartialApply) {
2280- // The partially applied InoutArg is a property of actor. This
2281- // can really only happen when the property is a struct with a
2282- // mutating async method.
2283- if (auto partialApply = dyn_cast<ApplyExpr>(call->getFn ())) {
2284- ValueDecl *fnDecl =
2285- cast<DeclRefExpr>(partialApply->getFn ())->getDecl ();
2263+ if (isPartialApply) {
2264+ // The partially applied InoutArg is a property of actor. This
2265+ // can really only happen when the property is a struct with a
2266+ // mutating async method.
2267+ if (auto partialApply = dyn_cast<ApplyExpr>(call->getFn ())) {
2268+ if (auto declRef = dyn_cast<DeclRefExpr>(partialApply->getFn ())) {
2269+ ValueDecl *fnDecl = declRef->getDecl ();
22862270 ctx.Diags .diagnose (call->getLoc (),
22872271 diag::actor_isolated_mutating_func,
22882272 fnDecl->getName (), decl->getDescriptiveKind (),
22892273 decl->getName ());
22902274 result = true ;
2275+ return ;
22912276 }
2292- } else {
2293- ctx.Diags .diagnose (argLoc, diag::actor_isolated_inout_state,
2294- decl->getDescriptiveKind (), decl->getName (),
2295- call->isImplicitlyAsync ().hasValue ());
2296- result = true ;
22972277 }
2298- break ;
2299- }
23002278 }
2279+
2280+ ctx.Diags .diagnose (argLoc, diag::actor_isolated_inout_state,
2281+ decl->getDescriptiveKind (), decl->getName (),
2282+ call->isImplicitlyAsync ().hasValue ());
2283+ decl->diagnose (diag::kind_declared_here, decl->getDescriptiveKind ());
2284+ result = true ;
2285+ return ;
23012286 };
23022287 auto expressionWalker = [baseArg = arg->getSubExpr (),
23032288 checkDiagnostic](Expr *expr) -> Expr * {
0 commit comments