@@ -1315,6 +1315,9 @@ ReferencedActor ReferencedActor::forGlobalActor(VarDecl *actor,
1315
1315
return ReferencedActor (actor, isPotentiallyIsolated, kind, globalActor);
1316
1316
}
1317
1317
1318
+ static ActorIsolation getActorIsolationForReference (
1319
+ ValueDecl *decl, const DeclContext *fromDC);
1320
+
1318
1321
bool ReferencedActor::isKnownToBeLocal () const {
1319
1322
switch (kind) {
1320
1323
case GlobalActor:
@@ -2311,54 +2314,36 @@ namespace {
2311
2314
return false ;
2312
2315
2313
2316
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 ;
2329
2323
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 ();
2347
2331
ctx.Diags .diagnose (call->getLoc (),
2348
2332
diag::actor_isolated_mutating_func,
2349
2333
fnDecl->getName (), decl->getDescriptiveKind (),
2350
2334
decl->getName ());
2351
2335
result = true ;
2336
+ return ;
2352
2337
}
2353
- } else {
2354
- ctx.Diags .diagnose (argLoc, diag::actor_isolated_inout_state,
2355
- decl->getDescriptiveKind (), decl->getName (),
2356
- call->isImplicitlyAsync ().hasValue ());
2357
- result = true ;
2358
2338
}
2359
- break ;
2360
- }
2361
2339
}
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 ;
2362
2347
};
2363
2348
auto expressionWalker = [baseArg = arg->getSubExpr (),
2364
2349
checkDiagnostic](Expr *expr) -> Expr * {
0 commit comments