@@ -1315,6 +1315,9 @@ ReferencedActor ReferencedActor::forGlobalActor(VarDecl *actor,
13151315 return ReferencedActor (actor, isPotentiallyIsolated, kind, globalActor);
13161316}
13171317
1318+ static ActorIsolation getActorIsolationForReference (
1319+ ValueDecl *decl, const DeclContext *fromDC);
1320+
13181321bool ReferencedActor::isKnownToBeLocal () const {
13191322 switch (kind) {
13201323 case GlobalActor:
@@ -2311,54 +2314,36 @@ namespace {
23112314 return false ;
23122315
23132316 bool result = false ;
2314- auto checkDiagnostic = [this , call, isPartialApply,
2315- &result](ValueDecl *decl, SourceLoc argLoc) {
2316- auto isolation = ActorIsolationRestriction::forDeclaration (
2317- decl, getDeclContext ());
2318- switch (isolation) {
2319- case ActorIsolationRestriction::Unrestricted:
2320- case ActorIsolationRestriction::Unsafe:
2321- break ;
2322- case ActorIsolationRestriction::GlobalActorUnsafe:
2323- // If we're not supposed to diagnose existing data races here,
2324- // we're done.
2325- if (!shouldDiagnoseExistingDataRaces (getDeclContext ()))
2326- break ;
2327-
2328- LLVM_FALLTHROUGH;
2317+ auto checkDiagnostic = [this , call, isPartialApply, &result](
2318+ ConcreteDeclRef declRef, SourceLoc argLoc) {
2319+ auto decl = declRef.getDecl ();
2320+ auto isolation = getActorIsolationForReference (decl, getDeclContext ());
2321+ if (!isolation.isActorIsolated ())
2322+ return ;
23292323
2330- case ActorIsolationRestriction::GlobalActor: {
2331- ctx.Diags .diagnose (argLoc, diag::actor_isolated_inout_state,
2332- decl->getDescriptiveKind (), decl->getName (),
2333- call->isImplicitlyAsync ().hasValue ());
2334- decl->diagnose (diag::kind_declared_here, decl->getDescriptiveKind ());
2335- result = true ;
2336- break ;
2337- }
2338- case ActorIsolationRestriction::CrossActorSelf:
2339- case ActorIsolationRestriction::ActorSelf: {
2340- if (isPartialApply) {
2341- // The partially applied InoutArg is a property of actor. This
2342- // can really only happen when the property is a struct with a
2343- // mutating async method.
2344- if (auto partialApply = dyn_cast<ApplyExpr>(call->getFn ())) {
2345- ValueDecl *fnDecl =
2346- cast<DeclRefExpr>(partialApply->getFn ())->getDecl ();
2324+ if (isPartialApply) {
2325+ // The partially applied InoutArg is a property of actor. This
2326+ // can really only happen when the property is a struct with a
2327+ // mutating async method.
2328+ if (auto partialApply = dyn_cast<ApplyExpr>(call->getFn ())) {
2329+ if (auto declRef = dyn_cast<DeclRefExpr>(partialApply->getFn ())) {
2330+ ValueDecl *fnDecl = declRef->getDecl ();
23472331 ctx.Diags .diagnose (call->getLoc (),
23482332 diag::actor_isolated_mutating_func,
23492333 fnDecl->getName (), decl->getDescriptiveKind (),
23502334 decl->getName ());
23512335 result = true ;
2336+ return ;
23522337 }
2353- } else {
2354- ctx.Diags .diagnose (argLoc, diag::actor_isolated_inout_state,
2355- decl->getDescriptiveKind (), decl->getName (),
2356- call->isImplicitlyAsync ().hasValue ());
2357- result = true ;
23582338 }
2359- break ;
2360- }
23612339 }
2340+
2341+ ctx.Diags .diagnose (argLoc, diag::actor_isolated_inout_state,
2342+ decl->getDescriptiveKind (), decl->getName (),
2343+ call->isImplicitlyAsync ().hasValue ());
2344+ decl->diagnose (diag::kind_declared_here, decl->getDescriptiveKind ());
2345+ result = true ;
2346+ return ;
23622347 };
23632348 auto expressionWalker = [baseArg = arg->getSubExpr (),
23642349 checkDiagnostic](Expr *expr) -> Expr * {
0 commit comments