@@ -5457,70 +5457,6 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
54575457 };
54585458 }
54595459
5460- // Diagnose global state that is not either immutable plus Sendable or
5461- // isolated to a global actor.
5462- auto checkGlobalIsolation = [var = dyn_cast<VarDecl>(value), &ctx](
5463- ActorIsolation isolation) {
5464- // Diagnose only declarations in the same module.
5465- //
5466- // TODO: This should be factored out from ActorIsolationRequest into
5467- // either ActorIsolationChecker or DeclChecker.
5468- if (var && var->getLoc (/* SerializedOK*/ false ) &&
5469- var->getASTContext ().LangOpts .hasFeature (Feature::GlobalConcurrency) &&
5470- !isolation.isGlobalActor () &&
5471- (isolation != ActorIsolation::NonisolatedUnsafe)) {
5472- auto *classDecl = var->getDeclContext ()->getSelfClassDecl ();
5473- const bool isActorType = classDecl && classDecl->isAnyActor ();
5474- if (var->isGlobalStorage () && !isActorType) {
5475- auto *diagVar = var;
5476- if (auto *originalVar = var->getOriginalWrappedProperty ()) {
5477- diagVar = originalVar;
5478- }
5479-
5480- bool diagnosed = false ;
5481- if (var->isLet ()) {
5482- auto type = var->getInterfaceType ();
5483- diagnosed = diagnoseIfAnyNonSendableTypes (
5484- type, SendableCheckContext (var->getDeclContext ()),
5485- /* inDerivedConformance=*/ Type (), /* typeLoc=*/ SourceLoc (),
5486- /* diagnoseLoc=*/ var->getLoc (),
5487- diag::shared_immutable_state_decl, diagVar);
5488- } else {
5489- diagVar->diagnose (diag::shared_mutable_state_decl, diagVar)
5490- .warnUntilSwiftVersion (6 );
5491- diagnosed = true ;
5492- }
5493-
5494- // If we diagnosed this global, tack on notes to suggest potential
5495- // courses of action.
5496- if (diagnosed) {
5497- if (!var->isLet ()) {
5498- auto diag = diagVar->diagnose (diag::shared_state_make_immutable,
5499- diagVar);
5500- SourceLoc fixItLoc = getFixItLocForVarToLet (diagVar);
5501- if (fixItLoc.isValid ()) {
5502- diag.fixItReplace (fixItLoc, " let" );
5503- }
5504- }
5505-
5506- auto mainActor = ctx.getMainActorType ();
5507- if (mainActor) {
5508- diagVar->diagnose (diag::add_globalactor_to_decl,
5509- mainActor->getWithoutParens ().getString (),
5510- diagVar, mainActor)
5511- .fixItInsert (diagVar->getAttributeInsertionLoc (false ),
5512- diag::insert_globalactor_attr, mainActor);
5513- }
5514- diagVar->diagnose (diag::shared_state_nonisolated_unsafe,
5515- diagVar)
5516- .fixItInsert (diagVar->getAttributeInsertionLoc (true ),
5517- " nonisolated(unsafe) " );
5518- }
5519- }
5520- }
5521- return isolation;
5522- };
5523-
55245460 auto isolationFromAttr = getIsolationFromAttributes (value);
55255461 if (isolationFromAttr && isolationFromAttr->preconcurrency () &&
55265462 !value->getAttrs ().hasAttribute <PreconcurrencyAttr>()) {
@@ -5557,10 +5493,8 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
55575493 checkClassGlobalActorIsolation (classDecl, *isolationFromAttr);
55585494 }
55595495
5560- return {
5561- checkGlobalIsolation (*isolationFromAttr),
5562- IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)
5563- };
5496+ return {*isolationFromAttr,
5497+ IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)};
55645498 }
55655499
55665500 // Determine the default isolation for this declaration, which may still be
@@ -5596,83 +5530,77 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
55965530 // Function used when returning an inferred isolation.
55975531 auto inferredIsolation = [&](ActorIsolation inferred,
55985532 bool onlyGlobal = false ) {
5599- // Invoke the body within checkGlobalIsolation to check the result.
5600- return checkGlobalIsolation ([&] {
5601- // check if the inferred isolation is valid in the context of
5602- // its overridden isolation.
5603- if (overriddenValue) {
5604- // if the inferred isolation is not valid, then carry-over the
5605- // overridden declaration's isolation as this decl's inferred isolation.
5606- switch (validOverrideIsolation (value, inferred, overriddenValue,
5607- *overriddenIso)) {
5608- case OverrideIsolationResult::Allowed:
5609- case OverrideIsolationResult::Sendable:
5610- break ;
5533+ // check if the inferred isolation is valid in the context of its overridden
5534+ // isolation.
5535+ if (overriddenValue) {
5536+ // if the inferred isolation is not valid, then carry-over the overridden
5537+ // declaration's isolation as this decl's inferred isolation.
5538+ switch (validOverrideIsolation (value, inferred, overriddenValue,
5539+ *overriddenIso)) {
5540+ case OverrideIsolationResult::Allowed:
5541+ case OverrideIsolationResult::Sendable:
5542+ break ;
56115543
5612- case OverrideIsolationResult::Disallowed:
5613- if (overriddenValue->hasClangNode () &&
5614- overriddenIso->isUnspecified ()) {
5615- inferred = overriddenIso->withPreconcurrency (true );
5616- } else {
5617- inferred = *overriddenIso;
5618- }
5619- break ;
5544+ case OverrideIsolationResult::Disallowed:
5545+ if (overriddenValue->hasClangNode () && overriddenIso->isUnspecified ()) {
5546+ inferred = overriddenIso->withPreconcurrency (true );
5547+ } else {
5548+ inferred = *overriddenIso;
56205549 }
5550+ break ;
56215551 }
5552+ }
56225553
5623- // Add an implicit attribute to capture the actor isolation that was
5624- // inferred, so that (e.g.) it will be printed and serialized.
5625- switch (inferred) {
5626- case ActorIsolation::Nonisolated:
5627- case ActorIsolation::NonisolatedUnsafe:
5628- // Stored properties cannot be non-isolated, so don't infer it.
5629- if (auto var = dyn_cast<VarDecl>(value)) {
5630- if (!var->isStatic () && var->hasStorage ())
5631- return ActorIsolation::forUnspecified ().withPreconcurrency (
5632- inferred.preconcurrency ());
5633- }
5634-
5635- if (onlyGlobal) {
5554+ // Add an implicit attribute to capture the actor isolation that was
5555+ // inferred, so that (e.g.) it will be printed and serialized.
5556+ switch (inferred) {
5557+ case ActorIsolation::Nonisolated:
5558+ case ActorIsolation::NonisolatedUnsafe:
5559+ // Stored properties cannot be non-isolated, so don't infer it.
5560+ if (auto var = dyn_cast<VarDecl>(value)) {
5561+ if (!var->isStatic () && var->hasStorage ())
56365562 return ActorIsolation::forUnspecified ().withPreconcurrency (
56375563 inferred.preconcurrency ());
5638- }
5564+ }
56395565
5640- value->getAttrs ().add (new (ctx) NonisolatedAttr (
5641- inferred == ActorIsolation::NonisolatedUnsafe, /* implicit=*/ true ));
5642- break ;
5566+ if (onlyGlobal) {
5567+ return ActorIsolation::forUnspecified ().withPreconcurrency (
5568+ inferred.preconcurrency ());
5569+ }
56435570
5644- case ActorIsolation::Erased:
5645- llvm_unreachable (" cannot infer erased isolation" );
5571+ value->getAttrs ().add (new (ctx) NonisolatedAttr (
5572+ inferred == ActorIsolation::NonisolatedUnsafe, /* implicit=*/ true ));
5573+ break ;
56465574
5647- case ActorIsolation::GlobalActor: {
5648- auto typeExpr =
5649- TypeExpr::createImplicit (inferred.getGlobalActor (), ctx);
5650- auto attr =
5651- CustomAttr::create (ctx, SourceLoc (), typeExpr, /* implicit=*/ true );
5652- value->getAttrs ().add (attr);
5653-
5654- if (inferred.preconcurrency () &&
5655- !value->getAttrs ().hasAttribute <PreconcurrencyAttr>()) {
5656- auto preconcurrency =
5657- new (ctx) PreconcurrencyAttr (/* isImplicit*/ true );
5658- value->getAttrs ().add (preconcurrency);
5659- }
5575+ case ActorIsolation::Erased:
5576+ llvm_unreachable (" cannot infer erased isolation" );
56605577
5661- break ;
5578+ case ActorIsolation::GlobalActor: {
5579+ auto typeExpr = TypeExpr::createImplicit (inferred.getGlobalActor (), ctx);
5580+ auto attr =
5581+ CustomAttr::create (ctx, SourceLoc (), typeExpr, /* implicit=*/ true );
5582+ value->getAttrs ().add (attr);
5583+
5584+ if (inferred.preconcurrency () &&
5585+ !value->getAttrs ().hasAttribute <PreconcurrencyAttr>()) {
5586+ auto preconcurrency = new (ctx) PreconcurrencyAttr (/* isImplicit*/ true );
5587+ value->getAttrs ().add (preconcurrency);
56625588 }
56635589
5664- case ActorIsolation::ActorInstance:
5665- case ActorIsolation::Unspecified:
5666- if (onlyGlobal)
5667- return ActorIsolation::forUnspecified ().withPreconcurrency (
5668- inferred.preconcurrency ());
5590+ break ;
5591+ }
56695592
5670- // Nothing to do.
5671- break ;
5672- }
5593+ case ActorIsolation::ActorInstance:
5594+ case ActorIsolation::Unspecified:
5595+ if (onlyGlobal)
5596+ return ActorIsolation::forUnspecified ().withPreconcurrency (
5597+ inferred.preconcurrency ());
5598+
5599+ // Nothing to do.
5600+ break ;
5601+ }
56735602
5674- return inferred;
5675- }());
5603+ return inferred;
56765604 };
56775605
56785606 // If this is a local function, inherit the actor isolation from its
@@ -5874,10 +5802,7 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
58745802 }
58755803
58765804 // Default isolation for this member.
5877- return {
5878- checkGlobalIsolation (defaultIsolation),
5879- defaultIsolationSource
5880- };
5805+ return {defaultIsolation, defaultIsolationSource};
58815806}
58825807
58835808bool HasIsolatedSelfRequest::evaluate (
@@ -6075,6 +6000,63 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
60756000 overridden->diagnose (diag::overridden_here);
60766001}
60776002
6003+ void swift::checkGlobalIsolation (VarDecl *var) {
6004+ const auto isolation = getActorIsolation (var);
6005+ if (var->getLoc () &&
6006+ var->getASTContext ().LangOpts .hasFeature (Feature::GlobalConcurrency) &&
6007+ !isolation.isGlobalActor () &&
6008+ (isolation != ActorIsolation::NonisolatedUnsafe)) {
6009+ auto *classDecl = var->getDeclContext ()->getSelfClassDecl ();
6010+ const bool isActorType = classDecl && classDecl->isAnyActor ();
6011+ if (var->isGlobalStorage () && !isActorType) {
6012+ auto *diagVar = var;
6013+ if (auto *originalVar = var->getOriginalWrappedProperty ()) {
6014+ diagVar = originalVar;
6015+ }
6016+
6017+ bool diagnosed = false ;
6018+ if (var->isLet ()) {
6019+ auto type = var->getInterfaceType ();
6020+ diagnosed = diagnoseIfAnyNonSendableTypes (
6021+ type, SendableCheckContext (var->getDeclContext ()),
6022+ /* inDerivedConformance=*/ Type (), /* typeLoc=*/ SourceLoc (),
6023+ /* diagnoseLoc=*/ var->getLoc (), diag::shared_immutable_state_decl,
6024+ diagVar);
6025+ } else {
6026+ diagVar->diagnose (diag::shared_mutable_state_decl, diagVar)
6027+ .warnUntilSwiftVersion (6 );
6028+ diagnosed = true ;
6029+ }
6030+
6031+ // If we diagnosed this global, tack on notes to suggest potential courses
6032+ // of action.
6033+ if (diagnosed) {
6034+ if (!var->isLet ()) {
6035+ auto diag =
6036+ diagVar->diagnose (diag::shared_state_make_immutable, diagVar);
6037+ SourceLoc fixItLoc = getFixItLocForVarToLet (diagVar);
6038+ if (fixItLoc.isValid ()) {
6039+ diag.fixItReplace (fixItLoc, " let" );
6040+ }
6041+ }
6042+
6043+ auto mainActor = var->getASTContext ().getMainActorType ();
6044+ if (mainActor) {
6045+ diagVar
6046+ ->diagnose (diag::add_globalactor_to_decl,
6047+ mainActor->getWithoutParens ().getString (), diagVar,
6048+ mainActor)
6049+ .fixItInsert (diagVar->getAttributeInsertionLoc (false ),
6050+ diag::insert_globalactor_attr, mainActor);
6051+ }
6052+ diagVar->diagnose (diag::shared_state_nonisolated_unsafe, diagVar)
6053+ .fixItInsert (diagVar->getAttributeInsertionLoc (true ),
6054+ " nonisolated(unsafe) " );
6055+ }
6056+ }
6057+ }
6058+ }
6059+
60786060bool swift::contextRequiresStrictConcurrencyChecking (
60796061 const DeclContext *dc,
60806062 llvm::function_ref<Type(const AbstractClosureExpr *)> getType,
0 commit comments