@@ -554,12 +554,14 @@ ActorIsolationRestriction ActorIsolationRestriction::forDeclaration(
554554 return forActorSelf (isolation.getActor (),
555555 isAccessibleAcrossActors || isa<ConstructorDecl>(decl));
556556
557+ case ActorIsolation::GlobalActorUnsafe:
557558 case ActorIsolation::GlobalActor: {
558559 Type actorType = isolation.getGlobalActor ();
559560 if (auto subs = declRef.getSubstitutions ())
560561 actorType = actorType.subst (subs);
561562
562- return forGlobalActor (actorType, isAccessibleAcrossActors);
563+ return forGlobalActor (actorType, isAccessibleAcrossActors,
564+ isolation == ActorIsolation::GlobalActorUnsafe);
563565 }
564566
565567 case ActorIsolation::Independent:
@@ -1293,7 +1295,14 @@ namespace {
12931295 case ActorIsolationRestriction::Unrestricted:
12941296 case ActorIsolationRestriction::Unsafe:
12951297 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+
12971306 case ActorIsolationRestriction::GlobalActor: {
12981307 ctx.Diags .diagnose (argLoc, diag::actor_isolated_inout_state,
12991308 decl->getDescriptiveKind (), decl->getName (),
@@ -1361,8 +1370,10 @@ namespace {
13611370 return isolation;
13621371
13631372 case ActorIsolation::GlobalActor:
1373+ case ActorIsolation::GlobalActorUnsafe:
13641374 return ActorIsolation::forGlobalActor (
1365- constDC->mapTypeIntoContext (isolation.getGlobalActor ()));
1375+ constDC->mapTypeIntoContext (isolation.getGlobalActor ()),
1376+ isolation == ActorIsolation::GlobalActorUnsafe);
13661377 }
13671378 };
13681379
@@ -1467,7 +1478,8 @@ namespace {
14671478 // Check whether we are within the same isolation context, in which
14681479 // case there is nothing further to check,
14691480 auto contextIsolation = getInnermostIsolatedContext (declContext);
1470- if (contextIsolation == ActorIsolation::forGlobalActor (globalActor)) {
1481+ if (contextIsolation.isGlobalActor () &&
1482+ contextIsolation.getGlobalActor ()->isEqual (globalActor)) {
14711483 return false ;
14721484 }
14731485
@@ -1490,7 +1502,8 @@ namespace {
14901502 noteIsolatedActorMember (value);
14911503 return true ;
14921504
1493- case ActorIsolation::GlobalActor: {
1505+ case ActorIsolation::GlobalActor:
1506+ case ActorIsolation::GlobalActorUnsafe: {
14941507 // Check if this decl reference is the callee of the enclosing Apply,
14951508 // making it OK as an implicitly async call.
14961509 if (inspectForImplicitlyAsync ())
@@ -1675,11 +1688,16 @@ namespace {
16751688 case ActorIsolationRestriction::ActorSelf:
16761689 llvm_unreachable (" non-member reference into an actor" );
16771690
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+
16791698 case ActorIsolationRestriction::GlobalActor:
16801699 return checkGlobalActorReference (
1681- valueRef, loc, isolation.getGlobalActor (),
1682- isolation == ActorIsolationRestriction::CrossGlobalActor);
1700+ valueRef, loc, isolation.getGlobalActor (), isolation.isCrossActor );
16831701
16841702 case ActorIsolationRestriction::Unsafe:
16851703 return diagnoseReferenceToUnsafeGlobal (value, loc);
@@ -1829,6 +1847,7 @@ namespace {
18291847 }
18301848
18311849 case ActorIsolation::GlobalActor:
1850+ case ActorIsolation::GlobalActorUnsafe:
18321851 // Check for implicit async.
18331852 if (auto result = checkImplicitlyAsync ())
18341853 return *result;
@@ -1846,11 +1865,17 @@ namespace {
18461865 llvm_unreachable (" Unhandled actor isolation" );
18471866 }
18481867
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+
18501875 case ActorIsolationRestriction::GlobalActor:
18511876 return checkGlobalActorReference (
18521877 memberRef, memberLoc, isolation.getGlobalActor (),
1853- isolation == ActorIsolationRestriction::CrossGlobalActor );
1878+ isolation. isCrossActor );
18541879
18551880 case ActorIsolationRestriction::Unsafe:
18561881 // This case is hit when passing actor state inout to functions in some
@@ -1880,7 +1905,8 @@ namespace {
18801905 case ActorIsolation::Unspecified:
18811906 return ClosureActorIsolation::forIndependent ();
18821907
1883- case ActorIsolation::GlobalActor: {
1908+ case ActorIsolation::GlobalActor:
1909+ case ActorIsolation::GlobalActorUnsafe: {
18841910 Type globalActorType = closure->mapTypeIntoContext (
18851911 parentIsolation.getGlobalActor ()->mapTypeOutOfContext ());
18861912 return ClosureActorIsolation::forGlobalActor (globalActorType);
@@ -2036,14 +2062,8 @@ static Optional<ActorIsolation> getIsolationFromAttributes(
20362062 diag::global_actor_non_unsafe_init, globalActorType);
20372063 }
20382064
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-
20452065 return ActorIsolation::forGlobalActor (
2046- globalActorType->mapTypeOutOfContext ());
2066+ globalActorType->mapTypeOutOfContext (), isUnsafe );
20472067 }
20482068
20492069 llvm_unreachable (" Forgot about an attribute?" );
@@ -2113,7 +2133,8 @@ static Optional<ActorIsolation> getIsolationFromWitnessedRequirements(
21132133 case ActorIsolation::Unspecified:
21142134 return true ;
21152135
2116- case ActorIsolation::GlobalActor: {
2136+ case ActorIsolation::GlobalActor:
2137+ case ActorIsolation::GlobalActorUnsafe: {
21172138 // Substitute into the global actor type.
21182139 auto conformance = std::get<0 >(isolated);
21192140 auto requirementSubs = SubstitutionMap::getProtocolSubstitutions (
@@ -2124,7 +2145,8 @@ static Optional<ActorIsolation> getIsolationFromWitnessedRequirements(
21242145 return true ;
21252146
21262147 // 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);
21282150 return false ;
21292151 }
21302152 }
@@ -2188,6 +2210,10 @@ ActorIsolation ActorIsolationRequest::evaluate(
21882210 ActorIndependentKind::Safe, /* IsImplicit=*/ true ));
21892211 break ;
21902212
2213+ case ActorIsolation::GlobalActorUnsafe:
2214+ // Don't infer unsafe global actor isolation.
2215+ return ActorIsolation::forUnspecified ();
2216+
21912217 case ActorIsolation::GlobalActor: {
21922218 auto typeExpr = TypeExpr::createImplicit (inferred.getGlobalActor (), ctx);
21932219 auto attr = CustomAttr::create (
@@ -2315,15 +2341,65 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
23152341 // If the overridden declaration is @actorIndependent(unsafe) and the
23162342 // overriding declaration has been placed in a global actor, allow it.
23172343 if (overriddenIsolation.getKind () == ActorIsolation::IndependentUnsafe &&
2318- isolation.getKind () == ActorIsolation::GlobalActor )
2344+ isolation.isGlobalActor () )
23192345 return ;
23202346
23212347 // If the overridden declaration is from Objective-C with no actor annotation,
23222348 // and the overriding declaration has been placed in a global actor, allow it.
23232349 if (overridden->hasClangNode () && !overriddenIsolation &&
2324- isolation.getKind () == ActorIsolation::GlobalActor )
2350+ isolation.isGlobalActor () )
23252351 return ;
23262352
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+
23272403 // Isolation mismatch. Diagnose it.
23282404 value->diagnose (
23292405 diag::actor_isolation_override_mismatch, isolation,
0 commit comments