@@ -2003,11 +2003,15 @@ namespace {
2003
2003
// / an expression or function.
2004
2004
llvm::SmallDenseMap<const DeclContext *, ActorIsolation> requiredIsolation;
2005
2005
2006
- using IsolationPair = std::pair<ReferencedActor::Kind, ActorIsolation>;
2006
+ using ActorRefKindPair = std::pair<ReferencedActor::Kind, ActorIsolation>;
2007
+
2008
+ using IsolationPair = std::pair<ActorIsolation, ActorIsolation>;
2007
2009
2008
2010
using DiagnosticList = std::vector<IsolationError>;
2009
2011
2010
- llvm::DenseMap<IsolationPair, DiagnosticList> isoErrors;
2012
+ llvm::DenseMap<ActorRefKindPair, DiagnosticList> refErrors;
2013
+
2014
+ llvm::DenseMap<IsolationPair, DiagnosticList> applyErrors;
2011
2015
2012
2016
// / Keeps track of the capture context of variables that have been
2013
2017
// / explicitly captured in closures.
@@ -2065,8 +2069,8 @@ namespace {
2065
2069
bool diagnoseIsolationErrors () {
2066
2070
bool diagnosedError = false ;
2067
2071
2068
- for (auto list : isoErrors ) {
2069
- IsolationPair key = list.getFirst ();
2072
+ for (auto list : refErrors ) {
2073
+ ActorRefKindPair key = list.getFirst ();
2070
2074
DiagnosticList errors = list.getSecond ();
2071
2075
ActorIsolation isolation = key.second ;
2072
2076
@@ -2087,6 +2091,30 @@ namespace {
2087
2091
.limitBehavior (behavior);
2088
2092
}
2089
2093
}
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
+
2090
2118
return diagnosedError;
2091
2119
}
2092
2120
@@ -2422,8 +2450,6 @@ namespace {
2422
2450
requiredIsolationLoc = expr->getLoc ();
2423
2451
2424
2452
expr->walk (*this );
2425
- // print all diagnostics here :)
2426
- // diagnoseIsolationErrors(getDeclContext(), isoErrors);
2427
2453
requiredIsolationLoc = SourceLoc ();
2428
2454
return requiredIsolation[getDeclContext ()];
2429
2455
}
@@ -3225,28 +3251,49 @@ namespace {
3225
3251
// If we need to mark the call as implicitly asynchronous, make sure
3226
3252
// we're in an asynchronous context.
3227
3253
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
+ }
3238
3273
} 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 ())
3242
3288
.warnUntilSwiftVersionIf (getContextIsolation ().preconcurrency (), 6 );
3243
- }
3289
+ }
3244
3290
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
+ }
3250
3297
3251
3298
return true ;
3252
3299
}
@@ -3622,14 +3669,14 @@ namespace {
3622
3669
refKind + 1 , refGlobalActor,
3623
3670
result.isolation ));
3624
3671
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 ()){
3627
3674
iter->second .push_back (isoMismatch);
3628
3675
} else {
3629
3676
DiagnosticList list;
3630
3677
list.push_back (isoMismatch);
3631
3678
auto keyPair = std::make_pair (refKind,result.isolation );
3632
- isoErrors .insert (std::make_pair (keyPair, list));
3679
+ refErrors .insert (std::make_pair (keyPair, list));
3633
3680
}
3634
3681
} else {
3635
3682
ctx.Diags .diagnose (
0 commit comments