@@ -869,9 +869,8 @@ namespace {
869
869
}
870
870
871
871
private:
872
- // / If the expression is a reference to `self`, return the context of
873
- // / the 'self' parameter.
874
- static DeclContext *getSelfReferenceContext (Expr *expr) {
872
+ // / If the expression is a reference to `self`, the `self` declaration.
873
+ static VarDecl *getReferencedSelf (Expr *expr) {
875
874
// Look through identity expressions and implicit conversions.
876
875
Expr *prior;
877
876
do {
@@ -885,24 +884,13 @@ namespace {
885
884
886
885
// 'super' references always act on self.
887
886
if (auto super = dyn_cast<SuperRefExpr>(expr))
888
- return super->getSelf ()-> getDeclContext () ;
887
+ return super->getSelf ();
889
888
890
889
// Declaration references to 'self'.
891
890
if (auto declRef = dyn_cast<DeclRefExpr>(expr)) {
892
891
if (auto var = dyn_cast<VarDecl>(declRef->getDecl ())) {
893
- if (var->isSelfParameter ())
894
- return var->getDeclContext ();
895
-
896
- // If this is a 'self' capture in a capture list, recurse through
897
- // the capture list entry's initializer to find the original 'self'.
898
- if (var->isSelfParamCapture ()) {
899
- for (auto capture : var->getParentCaptureList ()->getCaptureList ()) {
900
- if (capture.Var == var) {
901
- expr = capture.Init ->getInit (0 );
902
- return getSelfReferenceContext (expr);
903
- }
904
- }
905
- }
892
+ if (var->isSelfParameter () || var->isSelfParamCapture ())
893
+ return var;
906
894
}
907
895
}
908
896
@@ -1268,6 +1256,44 @@ namespace {
1268
1256
llvm_unreachable (" unhandled actor isolation kind!" );
1269
1257
}
1270
1258
1259
+ // / Determine the reason for the given declaration context to be
1260
+ // / actor-independent.
1261
+ static Diag<DescriptiveDeclKind, DeclName>
1262
+ findActorIndependentReason (DeclContext *dc) {
1263
+ if (auto autoclosure = dyn_cast<AutoClosureExpr>(dc)) {
1264
+ switch (autoclosure->getThunkKind ()) {
1265
+ case AutoClosureExpr::Kind::AsyncLet:
1266
+ return diag::actor_isolated_from_async_let;
1267
+
1268
+ case AutoClosureExpr::Kind::DoubleCurryThunk:
1269
+ case AutoClosureExpr::Kind::SingleCurryThunk:
1270
+ return findActorIndependentReason (dc->getParent ());
1271
+
1272
+ case AutoClosureExpr::Kind::None:
1273
+ break ;
1274
+ }
1275
+ }
1276
+
1277
+ if (auto closure = dyn_cast<AbstractClosureExpr>(dc)) {
1278
+ if (isConcurrentClosure (closure)) {
1279
+ return diag::actor_isolated_from_concurrent_closure;
1280
+ }
1281
+
1282
+ if (isEscapingClosure (closure)) {
1283
+ return diag::actor_isolated_from_escaping_closure;
1284
+ }
1285
+
1286
+ return findActorIndependentReason (dc->getParent ());
1287
+ }
1288
+
1289
+ if (auto func = dyn_cast<AbstractFunctionDecl>(dc)) {
1290
+ if (func->isConcurrent ())
1291
+ return diag::actor_isolated_from_concurrent_function;
1292
+ }
1293
+
1294
+ return diag::actor_isolated_self_independent_context;
1295
+ }
1296
+
1271
1297
// / Check a reference with the given base expression to the given member.
1272
1298
// / Returns true iff the member reference refers to actor-isolated state
1273
1299
// / in an invalid or unsafe way such that a diagnostic was emitted.
@@ -1286,8 +1312,8 @@ namespace {
1286
1312
1287
1313
case ActorIsolationRestriction::ActorSelf: {
1288
1314
// Must reference actor-isolated state on 'self'.
1289
- auto *selfDC = getSelfReferenceContext (base);
1290
- if (!selfDC ) {
1315
+ auto *selfVar = getReferencedSelf (base);
1316
+ if (!selfVar ) {
1291
1317
// actor-isolated non-self calls are implicitly async and thus OK.
1292
1318
if (maybeImplicitAsync && isa<AbstractFunctionDecl>(member)) {
1293
1319
markNearestCallAsImplicitlyAsync ();
@@ -1303,8 +1329,9 @@ namespace {
1303
1329
return true ;
1304
1330
}
1305
1331
1306
- // Check whether the context of 'self' is actor-isolated.
1307
- switch (auto contextIsolation = getActorIsolationOfContext (selfDC)) {
1332
+ // Check whether the current context is differently-isolated.
1333
+ auto curDC = const_cast <DeclContext *>(getDeclContext ());
1334
+ switch (auto contextIsolation = getActorIsolationOfContext (curDC)) {
1308
1335
case ActorIsolation::ActorInstance:
1309
1336
// An escaping partial application of something that is part of
1310
1337
// the actor's isolated state is never permitted.
@@ -1323,15 +1350,15 @@ namespace {
1323
1350
// Okay
1324
1351
break ;
1325
1352
1326
- case ActorIsolation::Independent:
1353
+ case ActorIsolation::Independent: {
1327
1354
// The 'self' is for an actor-independent member, which means
1328
1355
// we cannot refer to actor-isolated state.
1329
- ctx.Diags .diagnose (
1330
- memberLoc, diag::actor_isolated_self_independent_context,
1331
- member->getDescriptiveKind (),
1332
- member->getName ());
1356
+ auto diag = findActorIndependentReason (curDC);
1357
+ ctx.Diags .diagnose (memberLoc, diag, member->getDescriptiveKind (),
1358
+ member->getName ());
1333
1359
noteIsolatedActorMember (member);
1334
1360
return true ;
1361
+ }
1335
1362
1336
1363
case ActorIsolation::GlobalActor:
1337
1364
// The 'self' is for a member that's part of a global actor, which
@@ -1347,7 +1374,8 @@ namespace {
1347
1374
1348
1375
// Check whether we are in a context that will not execute concurrently
1349
1376
// with the context of 'self'.
1350
- if (mayExecuteConcurrentlyWith (getDeclContext (), selfDC)) {
1377
+ if (mayExecuteConcurrentlyWith (
1378
+ getDeclContext (), selfVar->getDeclContext ())) {
1351
1379
ctx.Diags .diagnose (
1352
1380
memberLoc, diag::actor_isolated_concurrent_access,
1353
1381
member->getDescriptiveKind (), member->getName ());
0 commit comments