@@ -554,12 +554,14 @@ ActorIsolationRestriction ActorIsolationRestriction::forDeclaration(
554
554
return forActorSelf (isolation.getActor (),
555
555
isAccessibleAcrossActors || isa<ConstructorDecl>(decl));
556
556
557
+ case ActorIsolation::GlobalActorUnsafe:
557
558
case ActorIsolation::GlobalActor: {
558
559
Type actorType = isolation.getGlobalActor ();
559
560
if (auto subs = declRef.getSubstitutions ())
560
561
actorType = actorType.subst (subs);
561
562
562
- return forGlobalActor (actorType, isAccessibleAcrossActors);
563
+ return forGlobalActor (actorType, isAccessibleAcrossActors,
564
+ isolation == ActorIsolation::GlobalActorUnsafe);
563
565
}
564
566
565
567
case ActorIsolation::Independent:
@@ -1293,7 +1295,14 @@ namespace {
1293
1295
case ActorIsolationRestriction::Unrestricted:
1294
1296
case ActorIsolationRestriction::Unsafe:
1295
1297
break ;
1296
- case ActorIsolationRestriction::CrossGlobalActor:
1298
+ case ActorIsolationRestriction::GlobalActorUnsafe:
1299
+ // If we're not supposed to diagnose existing data races here,
1300
+ // we're done.
1301
+ if (!shouldDiagnoseExistingDataRaces (getDeclContext ()))
1302
+ break ;
1303
+
1304
+ LLVM_FALLTHROUGH;
1305
+
1297
1306
case ActorIsolationRestriction::GlobalActor: {
1298
1307
ctx.Diags .diagnose (argLoc, diag::actor_isolated_inout_state,
1299
1308
decl->getDescriptiveKind (), decl->getName (),
@@ -1361,8 +1370,10 @@ namespace {
1361
1370
return isolation;
1362
1371
1363
1372
case ActorIsolation::GlobalActor:
1373
+ case ActorIsolation::GlobalActorUnsafe:
1364
1374
return ActorIsolation::forGlobalActor (
1365
- constDC->mapTypeIntoContext (isolation.getGlobalActor ()));
1375
+ constDC->mapTypeIntoContext (isolation.getGlobalActor ()),
1376
+ isolation == ActorIsolation::GlobalActorUnsafe);
1366
1377
}
1367
1378
};
1368
1379
@@ -1467,7 +1478,8 @@ namespace {
1467
1478
// Check whether we are within the same isolation context, in which
1468
1479
// case there is nothing further to check,
1469
1480
auto contextIsolation = getInnermostIsolatedContext (declContext);
1470
- if (contextIsolation == ActorIsolation::forGlobalActor (globalActor)) {
1481
+ if (contextIsolation.isGlobalActor () &&
1482
+ contextIsolation.getGlobalActor ()->isEqual (globalActor)) {
1471
1483
return false ;
1472
1484
}
1473
1485
@@ -1490,7 +1502,8 @@ namespace {
1490
1502
noteIsolatedActorMember (value);
1491
1503
return true ;
1492
1504
1493
- case ActorIsolation::GlobalActor: {
1505
+ case ActorIsolation::GlobalActor:
1506
+ case ActorIsolation::GlobalActorUnsafe: {
1494
1507
// Check if this decl reference is the callee of the enclosing Apply,
1495
1508
// making it OK as an implicitly async call.
1496
1509
if (inspectForImplicitlyAsync ())
@@ -1675,11 +1688,16 @@ namespace {
1675
1688
case ActorIsolationRestriction::ActorSelf:
1676
1689
llvm_unreachable (" non-member reference into an actor" );
1677
1690
1678
- case ActorIsolationRestriction::CrossGlobalActor:
1691
+ case ActorIsolationRestriction::GlobalActorUnsafe:
1692
+ // Only complain if we're in code that's adopted concurrency features.
1693
+ if (!shouldDiagnoseExistingDataRaces (getDeclContext ()))
1694
+ return false ;
1695
+
1696
+ LLVM_FALLTHROUGH;
1697
+
1679
1698
case ActorIsolationRestriction::GlobalActor:
1680
1699
return checkGlobalActorReference (
1681
- valueRef, loc, isolation.getGlobalActor (),
1682
- isolation == ActorIsolationRestriction::CrossGlobalActor);
1700
+ valueRef, loc, isolation.getGlobalActor (), isolation.isCrossActor );
1683
1701
1684
1702
case ActorIsolationRestriction::Unsafe:
1685
1703
return diagnoseReferenceToUnsafeGlobal (value, loc);
@@ -1829,6 +1847,7 @@ namespace {
1829
1847
}
1830
1848
1831
1849
case ActorIsolation::GlobalActor:
1850
+ case ActorIsolation::GlobalActorUnsafe:
1832
1851
// Check for implicit async.
1833
1852
if (auto result = checkImplicitlyAsync ())
1834
1853
return *result;
@@ -1846,11 +1865,17 @@ namespace {
1846
1865
llvm_unreachable (" Unhandled actor isolation" );
1847
1866
}
1848
1867
1849
- case ActorIsolationRestriction::CrossGlobalActor:
1868
+ case ActorIsolationRestriction::GlobalActorUnsafe:
1869
+ // Only complain if we're in code that's adopted concurrency features.
1870
+ if (!shouldDiagnoseExistingDataRaces (getDeclContext ()))
1871
+ return false ;
1872
+
1873
+ LLVM_FALLTHROUGH;
1874
+
1850
1875
case ActorIsolationRestriction::GlobalActor:
1851
1876
return checkGlobalActorReference (
1852
1877
memberRef, memberLoc, isolation.getGlobalActor (),
1853
- isolation == ActorIsolationRestriction::CrossGlobalActor );
1878
+ isolation. isCrossActor );
1854
1879
1855
1880
case ActorIsolationRestriction::Unsafe:
1856
1881
// This case is hit when passing actor state inout to functions in some
@@ -1880,7 +1905,8 @@ namespace {
1880
1905
case ActorIsolation::Unspecified:
1881
1906
return ClosureActorIsolation::forIndependent ();
1882
1907
1883
- case ActorIsolation::GlobalActor: {
1908
+ case ActorIsolation::GlobalActor:
1909
+ case ActorIsolation::GlobalActorUnsafe: {
1884
1910
Type globalActorType = closure->mapTypeIntoContext (
1885
1911
parentIsolation.getGlobalActor ()->mapTypeOutOfContext ());
1886
1912
return ClosureActorIsolation::forGlobalActor (globalActorType);
@@ -2036,14 +2062,8 @@ static Optional<ActorIsolation> getIsolationFromAttributes(
2036
2062
diag::global_actor_non_unsafe_init, globalActorType);
2037
2063
}
2038
2064
2039
- // TODO: Model as unsafe from the actor-isolation perspective, which
2040
- // disables all checking. We probably want to model this as a separate kind
2041
- // of actor isolation to emit warnings.
2042
- if (isUnsafe)
2043
- return ActorIsolation::forIndependent (ActorIndependentKind::Unsafe);
2044
-
2045
2065
return ActorIsolation::forGlobalActor (
2046
- globalActorType->mapTypeOutOfContext ());
2066
+ globalActorType->mapTypeOutOfContext (), isUnsafe );
2047
2067
}
2048
2068
2049
2069
llvm_unreachable (" Forgot about an attribute?" );
@@ -2113,7 +2133,8 @@ static Optional<ActorIsolation> getIsolationFromWitnessedRequirements(
2113
2133
case ActorIsolation::Unspecified:
2114
2134
return true ;
2115
2135
2116
- case ActorIsolation::GlobalActor: {
2136
+ case ActorIsolation::GlobalActor:
2137
+ case ActorIsolation::GlobalActorUnsafe: {
2117
2138
// Substitute into the global actor type.
2118
2139
auto conformance = std::get<0 >(isolated);
2119
2140
auto requirementSubs = SubstitutionMap::getProtocolSubstitutions (
@@ -2124,7 +2145,8 @@ static Optional<ActorIsolation> getIsolationFromWitnessedRequirements(
2124
2145
return true ;
2125
2146
2126
2147
// Update the global actor type, now that we've done this substitution.
2127
- std::get<1 >(isolated) = ActorIsolation::forGlobalActor (globalActor);
2148
+ std::get<1 >(isolated) = ActorIsolation::forGlobalActor (
2149
+ globalActor, isolation == ActorIsolation::GlobalActorUnsafe);
2128
2150
return false ;
2129
2151
}
2130
2152
}
@@ -2188,6 +2210,10 @@ ActorIsolation ActorIsolationRequest::evaluate(
2188
2210
ActorIndependentKind::Safe, /* IsImplicit=*/ true ));
2189
2211
break ;
2190
2212
2213
+ case ActorIsolation::GlobalActorUnsafe:
2214
+ // Don't infer unsafe global actor isolation.
2215
+ return ActorIsolation::forUnspecified ();
2216
+
2191
2217
case ActorIsolation::GlobalActor: {
2192
2218
auto typeExpr = TypeExpr::createImplicit (inferred.getGlobalActor (), ctx);
2193
2219
auto attr = CustomAttr::create (
@@ -2315,15 +2341,65 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
2315
2341
// If the overridden declaration is @actorIndependent(unsafe) and the
2316
2342
// overriding declaration has been placed in a global actor, allow it.
2317
2343
if (overriddenIsolation.getKind () == ActorIsolation::IndependentUnsafe &&
2318
- isolation.getKind () == ActorIsolation::GlobalActor )
2344
+ isolation.isGlobalActor () )
2319
2345
return ;
2320
2346
2321
2347
// If the overridden declaration is from Objective-C with no actor annotation,
2322
2348
// and the overriding declaration has been placed in a global actor, allow it.
2323
2349
if (overridden->hasClangNode () && !overriddenIsolation &&
2324
- isolation.getKind () == ActorIsolation::GlobalActor )
2350
+ isolation.isGlobalActor () )
2325
2351
return ;
2326
2352
2353
+ // If the overridden declaration uses an unsafe global actor, we can do
2354
+ // anything except be actor-isolated or have a different global actor.
2355
+ if (overriddenIsolation == ActorIsolation::GlobalActorUnsafe) {
2356
+ switch (isolation) {
2357
+ case ActorIsolation::Independent:
2358
+ case ActorIsolation::IndependentUnsafe:
2359
+ case ActorIsolation::Unspecified:
2360
+ return ;
2361
+
2362
+ case ActorIsolation::ActorInstance:
2363
+ // Diagnose below.
2364
+ break ;
2365
+
2366
+ case ActorIsolation::GlobalActor:
2367
+ case ActorIsolation::GlobalActorUnsafe:
2368
+ // The global actors don't match; diagnose it.
2369
+ if (overriddenIsolation.getGlobalActor ()->isEqual (
2370
+ isolation.getGlobalActor ()))
2371
+ return ;
2372
+
2373
+ // Diagnose below.
2374
+ break ;
2375
+ }
2376
+ }
2377
+
2378
+ // If the overriding declaration uses an unsafe global actor, we can do
2379
+ // anything that doesn't actively conflict with the overridden isolation.
2380
+ if (isolation == ActorIsolation::GlobalActorUnsafe) {
2381
+ switch (overriddenIsolation) {
2382
+ case ActorIsolation::Unspecified:
2383
+ return ;
2384
+
2385
+ case ActorIsolation::ActorInstance:
2386
+ case ActorIsolation::Independent:
2387
+ case ActorIsolation::IndependentUnsafe:
2388
+ // Diagnose below.
2389
+ break ;
2390
+
2391
+ case ActorIsolation::GlobalActor:
2392
+ case ActorIsolation::GlobalActorUnsafe:
2393
+ // The global actors don't match; diagnose it.
2394
+ if (overriddenIsolation.getGlobalActor ()->isEqual (
2395
+ isolation.getGlobalActor ()))
2396
+ return ;
2397
+
2398
+ // Diagnose below.
2399
+ break ;
2400
+ }
2401
+ }
2402
+
2327
2403
// Isolation mismatch. Diagnose it.
2328
2404
value->diagnose (
2329
2405
diag::actor_isolation_override_mismatch, isolation,
0 commit comments