@@ -5366,70 +5366,6 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
53665366 };
53675367 }
53685368
5369- // Diagnose global state that is not either immutable plus Sendable or
5370- // isolated to a global actor.
5371- auto checkGlobalIsolation = [var = dyn_cast<VarDecl>(value), &ctx](
5372- ActorIsolation isolation) {
5373- // Diagnose only declarations in the same module.
5374- //
5375- // TODO: This should be factored out from ActorIsolationRequest into
5376- // either ActorIsolationChecker or DeclChecker.
5377- if (var && var->getLoc (/* SerializedOK*/ false ) &&
5378- var->getASTContext ().LangOpts .hasFeature (Feature::GlobalConcurrency) &&
5379- !isolation.isGlobalActor () &&
5380- (isolation != ActorIsolation::NonisolatedUnsafe)) {
5381- auto *classDecl = var->getDeclContext ()->getSelfClassDecl ();
5382- const bool isActorType = classDecl && classDecl->isAnyActor ();
5383- if (var->isGlobalStorage () && !isActorType) {
5384- auto *diagVar = var;
5385- if (auto *originalVar = var->getOriginalWrappedProperty ()) {
5386- diagVar = originalVar;
5387- }
5388-
5389- bool diagnosed = false ;
5390- if (var->isLet ()) {
5391- auto type = var->getInterfaceType ();
5392- diagnosed = diagnoseIfAnyNonSendableTypes (
5393- type, SendableCheckContext (var->getDeclContext ()),
5394- /* inDerivedConformance=*/ Type (), /* typeLoc=*/ SourceLoc (),
5395- /* diagnoseLoc=*/ var->getLoc (),
5396- diag::shared_immutable_state_decl, diagVar);
5397- } else {
5398- diagVar->diagnose (diag::shared_mutable_state_decl, diagVar)
5399- .warnUntilSwiftVersion (6 );
5400- diagnosed = true ;
5401- }
5402-
5403- // If we diagnosed this global, tack on notes to suggest potential
5404- // courses of action.
5405- if (diagnosed) {
5406- if (!var->isLet ()) {
5407- auto diag = diagVar->diagnose (diag::shared_state_make_immutable,
5408- diagVar);
5409- SourceLoc fixItLoc = getFixItLocForVarToLet (diagVar);
5410- if (fixItLoc.isValid ()) {
5411- diag.fixItReplace (fixItLoc, " let" );
5412- }
5413- }
5414-
5415- auto mainActor = ctx.getMainActorType ();
5416- if (mainActor) {
5417- diagVar->diagnose (diag::add_globalactor_to_decl,
5418- mainActor->getWithoutParens ().getString (),
5419- diagVar, mainActor)
5420- .fixItInsert (diagVar->getAttributeInsertionLoc (false ),
5421- diag::insert_globalactor_attr, mainActor);
5422- }
5423- diagVar->diagnose (diag::shared_state_nonisolated_unsafe,
5424- diagVar)
5425- .fixItInsert (diagVar->getAttributeInsertionLoc (true ),
5426- " nonisolated(unsafe) " );
5427- }
5428- }
5429- }
5430- return isolation;
5431- };
5432-
54335369 auto isolationFromAttr = getIsolationFromAttributes (value);
54345370 if (isolationFromAttr && isolationFromAttr->preconcurrency () &&
54355371 !value->getAttrs ().hasAttribute <PreconcurrencyAttr>()) {
@@ -5466,10 +5402,8 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
54665402 checkClassGlobalActorIsolation (classDecl, *isolationFromAttr);
54675403 }
54685404
5469- return {
5470- checkGlobalIsolation (*isolationFromAttr),
5471- IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)
5472- };
5405+ return {*isolationFromAttr,
5406+ IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)};
54735407 }
54745408
54755409 // Determine the default isolation for this declaration, which may still be
@@ -5505,83 +5439,77 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
55055439 // Function used when returning an inferred isolation.
55065440 auto inferredIsolation = [&](ActorIsolation inferred,
55075441 bool onlyGlobal = false ) {
5508- // Invoke the body within checkGlobalIsolation to check the result.
5509- return checkGlobalIsolation ([&] {
5510- // check if the inferred isolation is valid in the context of
5511- // its overridden isolation.
5512- if (overriddenValue) {
5513- // if the inferred isolation is not valid, then carry-over the
5514- // overridden declaration's isolation as this decl's inferred isolation.
5515- switch (validOverrideIsolation (value, inferred, overriddenValue,
5516- *overriddenIso)) {
5517- case OverrideIsolationResult::Allowed:
5518- case OverrideIsolationResult::Sendable:
5519- break ;
5442+ // check if the inferred isolation is valid in the context of its overridden
5443+ // isolation.
5444+ if (overriddenValue) {
5445+ // if the inferred isolation is not valid, then carry-over the overridden
5446+ // declaration's isolation as this decl's inferred isolation.
5447+ switch (validOverrideIsolation (value, inferred, overriddenValue,
5448+ *overriddenIso)) {
5449+ case OverrideIsolationResult::Allowed:
5450+ case OverrideIsolationResult::Sendable:
5451+ break ;
55205452
5521- case OverrideIsolationResult::Disallowed:
5522- if (overriddenValue->hasClangNode () &&
5523- overriddenIso->isUnspecified ()) {
5524- inferred = overriddenIso->withPreconcurrency (true );
5525- } else {
5526- inferred = *overriddenIso;
5527- }
5528- break ;
5453+ case OverrideIsolationResult::Disallowed:
5454+ if (overriddenValue->hasClangNode () && overriddenIso->isUnspecified ()) {
5455+ inferred = overriddenIso->withPreconcurrency (true );
5456+ } else {
5457+ inferred = *overriddenIso;
55295458 }
5459+ break ;
55305460 }
5461+ }
55315462
5532- // Add an implicit attribute to capture the actor isolation that was
5533- // inferred, so that (e.g.) it will be printed and serialized.
5534- switch (inferred) {
5535- case ActorIsolation::Nonisolated:
5536- case ActorIsolation::NonisolatedUnsafe:
5537- // Stored properties cannot be non-isolated, so don't infer it.
5538- if (auto var = dyn_cast<VarDecl>(value)) {
5539- if (!var->isStatic () && var->hasStorage ())
5540- return ActorIsolation::forUnspecified ().withPreconcurrency (
5541- inferred.preconcurrency ());
5542- }
5543-
5544- if (onlyGlobal) {
5463+ // Add an implicit attribute to capture the actor isolation that was
5464+ // inferred, so that (e.g.) it will be printed and serialized.
5465+ switch (inferred) {
5466+ case ActorIsolation::Nonisolated:
5467+ case ActorIsolation::NonisolatedUnsafe:
5468+ // Stored properties cannot be non-isolated, so don't infer it.
5469+ if (auto var = dyn_cast<VarDecl>(value)) {
5470+ if (!var->isStatic () && var->hasStorage ())
55455471 return ActorIsolation::forUnspecified ().withPreconcurrency (
55465472 inferred.preconcurrency ());
5547- }
5473+ }
55485474
5549- value->getAttrs ().add (new (ctx) NonisolatedAttr (
5550- inferred == ActorIsolation::NonisolatedUnsafe, /* implicit=*/ true ));
5551- break ;
5475+ if (onlyGlobal) {
5476+ return ActorIsolation::forUnspecified ().withPreconcurrency (
5477+ inferred.preconcurrency ());
5478+ }
55525479
5553- case ActorIsolation::Erased:
5554- llvm_unreachable (" cannot infer erased isolation" );
5480+ value->getAttrs ().add (new (ctx) NonisolatedAttr (
5481+ inferred == ActorIsolation::NonisolatedUnsafe, /* implicit=*/ true ));
5482+ break ;
55555483
5556- case ActorIsolation::GlobalActor: {
5557- auto typeExpr =
5558- TypeExpr::createImplicit (inferred.getGlobalActor (), ctx);
5559- auto attr =
5560- CustomAttr::create (ctx, SourceLoc (), typeExpr, /* implicit=*/ true );
5561- value->getAttrs ().add (attr);
5562-
5563- if (inferred.preconcurrency () &&
5564- !value->getAttrs ().hasAttribute <PreconcurrencyAttr>()) {
5565- auto preconcurrency =
5566- new (ctx) PreconcurrencyAttr (/* isImplicit*/ true );
5567- value->getAttrs ().add (preconcurrency);
5568- }
5484+ case ActorIsolation::Erased:
5485+ llvm_unreachable (" cannot infer erased isolation" );
55695486
5570- break ;
5487+ case ActorIsolation::GlobalActor: {
5488+ auto typeExpr = TypeExpr::createImplicit (inferred.getGlobalActor (), ctx);
5489+ auto attr =
5490+ CustomAttr::create (ctx, SourceLoc (), typeExpr, /* implicit=*/ true );
5491+ value->getAttrs ().add (attr);
5492+
5493+ if (inferred.preconcurrency () &&
5494+ !value->getAttrs ().hasAttribute <PreconcurrencyAttr>()) {
5495+ auto preconcurrency = new (ctx) PreconcurrencyAttr (/* isImplicit*/ true );
5496+ value->getAttrs ().add (preconcurrency);
55715497 }
55725498
5573- case ActorIsolation::ActorInstance:
5574- case ActorIsolation::Unspecified:
5575- if (onlyGlobal)
5576- return ActorIsolation::forUnspecified ().withPreconcurrency (
5577- inferred.preconcurrency ());
5499+ break ;
5500+ }
55785501
5579- // Nothing to do.
5580- break ;
5581- }
5502+ case ActorIsolation::ActorInstance:
5503+ case ActorIsolation::Unspecified:
5504+ if (onlyGlobal)
5505+ return ActorIsolation::forUnspecified ().withPreconcurrency (
5506+ inferred.preconcurrency ());
5507+
5508+ // Nothing to do.
5509+ break ;
5510+ }
55825511
5583- return inferred;
5584- }());
5512+ return inferred;
55855513 };
55865514
55875515 // If this is a local function, inherit the actor isolation from its
@@ -5783,10 +5711,7 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
57835711 }
57845712
57855713 // Default isolation for this member.
5786- return {
5787- checkGlobalIsolation (defaultIsolation),
5788- defaultIsolationSource
5789- };
5714+ return {defaultIsolation, defaultIsolationSource};
57905715}
57915716
57925717bool HasIsolatedSelfRequest::evaluate (
@@ -5984,6 +5909,63 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
59845909 overridden->diagnose (diag::overridden_here);
59855910}
59865911
5912+ void swift::checkGlobalIsolation (VarDecl *var) {
5913+ const auto isolation = getActorIsolation (var);
5914+ if (var->getLoc () &&
5915+ var->getASTContext ().LangOpts .hasFeature (Feature::GlobalConcurrency) &&
5916+ !isolation.isGlobalActor () &&
5917+ (isolation != ActorIsolation::NonisolatedUnsafe)) {
5918+ auto *classDecl = var->getDeclContext ()->getSelfClassDecl ();
5919+ const bool isActorType = classDecl && classDecl->isAnyActor ();
5920+ if (var->isGlobalStorage () && !isActorType) {
5921+ auto *diagVar = var;
5922+ if (auto *originalVar = var->getOriginalWrappedProperty ()) {
5923+ diagVar = originalVar;
5924+ }
5925+
5926+ bool diagnosed = false ;
5927+ if (var->isLet ()) {
5928+ auto type = var->getInterfaceType ();
5929+ diagnosed = diagnoseIfAnyNonSendableTypes (
5930+ type, SendableCheckContext (var->getDeclContext ()),
5931+ /* inDerivedConformance=*/ Type (), /* typeLoc=*/ SourceLoc (),
5932+ /* diagnoseLoc=*/ var->getLoc (), diag::shared_immutable_state_decl,
5933+ diagVar);
5934+ } else {
5935+ diagVar->diagnose (diag::shared_mutable_state_decl, diagVar)
5936+ .warnUntilSwiftVersion (6 );
5937+ diagnosed = true ;
5938+ }
5939+
5940+ // If we diagnosed this global, tack on notes to suggest potential courses
5941+ // of action.
5942+ if (diagnosed) {
5943+ if (!var->isLet ()) {
5944+ auto diag =
5945+ diagVar->diagnose (diag::shared_state_make_immutable, diagVar);
5946+ SourceLoc fixItLoc = getFixItLocForVarToLet (diagVar);
5947+ if (fixItLoc.isValid ()) {
5948+ diag.fixItReplace (fixItLoc, " let" );
5949+ }
5950+ }
5951+
5952+ auto mainActor = var->getASTContext ().getMainActorType ();
5953+ if (mainActor) {
5954+ diagVar
5955+ ->diagnose (diag::add_globalactor_to_decl,
5956+ mainActor->getWithoutParens ().getString (), diagVar,
5957+ mainActor)
5958+ .fixItInsert (diagVar->getAttributeInsertionLoc (false ),
5959+ diag::insert_globalactor_attr, mainActor);
5960+ }
5961+ diagVar->diagnose (diag::shared_state_nonisolated_unsafe, diagVar)
5962+ .fixItInsert (diagVar->getAttributeInsertionLoc (true ),
5963+ " nonisolated(unsafe) " );
5964+ }
5965+ }
5966+ }
5967+ }
5968+
59875969bool swift::contextRequiresStrictConcurrencyChecking (
59885970 const DeclContext *dc,
59895971 llvm::function_ref<Type(const AbstractClosureExpr *)> getType,
0 commit comments