@@ -2003,11 +2003,15 @@ namespace {
20032003 // / an expression or function.
20042004 llvm::SmallDenseMap<const DeclContext *, ActorIsolation> requiredIsolation;
20052005
2006- using IsolationPair = std::pair<ReferencedActor::Kind, ActorIsolation>;
2006+ using ActorRefKindPair = std::pair<ReferencedActor::Kind, ActorIsolation>;
2007+
2008+ using IsolationPair = std::pair<ActorIsolation, ActorIsolation>;
20072009
20082010 using DiagnosticList = std::vector<IsolationError>;
20092011
2010- llvm::DenseMap<IsolationPair, DiagnosticList> isoErrors;
2012+ llvm::DenseMap<ActorRefKindPair, DiagnosticList> refErrors;
2013+
2014+ llvm::DenseMap<IsolationPair, DiagnosticList> applyErrors;
20112015
20122016 // / Keeps track of the capture context of variables that have been
20132017 // / explicitly captured in closures.
@@ -2065,8 +2069,8 @@ namespace {
20652069 bool diagnoseIsolationErrors () {
20662070 bool diagnosedError = false ;
20672071
2068- for (auto list : isoErrors ) {
2069- IsolationPair key = list.getFirst ();
2072+ for (auto list : refErrors ) {
2073+ ActorRefKindPair key = list.getFirst ();
20702074 DiagnosticList errors = list.getSecond ();
20712075 ActorIsolation isolation = key.second ;
20722076
@@ -2087,6 +2091,30 @@ namespace {
20872091 .limitBehavior (behavior);
20882092 }
20892093 }
2094+
2095+ for (auto list : applyErrors) {
2096+ IsolationPair key = list.getFirst ();
2097+ DiagnosticList errors = list.getSecond ();
2098+ ActorIsolation isolation = key.first ;
2099+
2100+ auto behavior = DiagnosticBehavior::Error;
2101+
2102+ // Add Fix-it for missing @SomeActor annotation
2103+ if (isolation.isGlobalActor ()) {
2104+ if (missingGlobalActorOnContext (
2105+ const_cast <DeclContext*>(getDeclContext ()), isolation.getGlobalActor ())) {
2106+ behavior= DiagnosticBehavior::Note;
2107+ }
2108+ }
2109+
2110+ for (IsolationError error : errors) {
2111+ // Diagnose actor_isolated_non_self_reference as note
2112+ // if we provide fix-it in missingGlobalActorOnContext
2113+ ctx.Diags .diagnose (error.loc , error.diag )
2114+ .limitBehavior (behavior);
2115+ }
2116+ }
2117+
20902118 return diagnosedError;
20912119 }
20922120
@@ -2422,8 +2450,6 @@ namespace {
24222450 requiredIsolationLoc = expr->getLoc ();
24232451
24242452 expr->walk (*this );
2425- // print all diagnostics here :)
2426- // diagnoseIsolationErrors(getDeclContext(), isoErrors);
24272453 requiredIsolationLoc = SourceLoc ();
24282454 return requiredIsolation[getDeclContext ()];
24292455 }
@@ -3225,28 +3251,49 @@ namespace {
32253251 // If we need to mark the call as implicitly asynchronous, make sure
32263252 // we're in an asynchronous context.
32273253 if (requiresAsync && !getDeclContext ()->isAsyncContext ()) {
3228- if (calleeDecl) {
3229- auto preconcurrency = getContextIsolation ().preconcurrency () ||
3230- calleeDecl->preconcurrency ();
3231- ctx.Diags .diagnose (
3232- apply->getLoc (), diag::actor_isolated_call_decl,
3233- *unsatisfiedIsolation,
3234- calleeDecl,
3235- getContextIsolation ())
3236- .warnUntilSwiftVersionIf (preconcurrency, 6 );
3237- calleeDecl->diagnose (diag::actor_isolated_sync_func, calleeDecl);
3254+
3255+ if (ctx.LangOpts .hasFeature (Feature::GroupActorErrors)) {
3256+ IsolationError isoMismatch =
3257+ IsolationError (
3258+ apply->getLoc (),
3259+ Diagnostic (diag::actor_isolated_call_decl,
3260+ *unsatisfiedIsolation,
3261+ calleeDecl,
3262+ getContextIsolation ()));
3263+
3264+ auto iter = applyErrors.find (std::make_pair (*unsatisfiedIsolation, getContextIsolation ()));
3265+ if (iter != applyErrors.end ()){
3266+ iter->second .push_back (isoMismatch);
3267+ } else {
3268+ DiagnosticList list;
3269+ list.push_back (isoMismatch);
3270+ auto keyPair = std::make_pair (*unsatisfiedIsolation, getContextIsolation ());
3271+ applyErrors.insert (std::make_pair (keyPair, list));
3272+ }
32383273 } else {
3239- ctx.Diags .diagnose (
3240- apply->getLoc (), diag::actor_isolated_call, *unsatisfiedIsolation,
3241- getContextIsolation ())
3274+ if (calleeDecl) {
3275+ auto preconcurrency = getContextIsolation ().preconcurrency () ||
3276+ calleeDecl->preconcurrency ();
3277+ ctx.Diags .diagnose (
3278+ apply->getLoc (), diag::actor_isolated_call_decl,
3279+ *unsatisfiedIsolation,
3280+ calleeDecl,
3281+ getContextIsolation ())
3282+ .warnUntilSwiftVersionIf (preconcurrency, 6 );
3283+ calleeDecl->diagnose (diag::actor_isolated_sync_func, calleeDecl);
3284+ } else {
3285+ ctx.Diags .diagnose (
3286+ apply->getLoc (), diag::actor_isolated_call, *unsatisfiedIsolation,
3287+ getContextIsolation ())
32423288 .warnUntilSwiftVersionIf (getContextIsolation ().preconcurrency (), 6 );
3243- }
3289+ }
32443290
3245- // if (unsatisfiedIsolation->isGlobalActor()) {
3246- // noteGlobalActorOnContext(
3247- // const_cast<DeclContext *>(getDeclContext()),
3248- // unsatisfiedIsolation->getGlobalActor());
3249- // }
3291+ if (unsatisfiedIsolation->isGlobalActor ()) {
3292+ missingGlobalActorOnContext (
3293+ const_cast <DeclContext *>(getDeclContext ()),
3294+ unsatisfiedIsolation->getGlobalActor ());
3295+ }
3296+ }
32503297
32513298 return true ;
32523299 }
@@ -3622,14 +3669,14 @@ namespace {
36223669 refKind + 1 , refGlobalActor,
36233670 result.isolation ));
36243671
3625- auto iter = isoErrors .find (std::make_pair (refKind,result.isolation ));
3626- if (iter != isoErrors .end ()){
3672+ auto iter = refErrors .find (std::make_pair (refKind,result.isolation ));
3673+ if (iter != refErrors .end ()){
36273674 iter->second .push_back (isoMismatch);
36283675 } else {
36293676 DiagnosticList list;
36303677 list.push_back (isoMismatch);
36313678 auto keyPair = std::make_pair (refKind,result.isolation );
3632- isoErrors .insert (std::make_pair (keyPair, list));
3679+ refErrors .insert (std::make_pair (keyPair, list));
36333680 }
36343681 } else {
36353682 ctx.Diags .diagnose (
0 commit comments