@@ -5457,70 +5457,6 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5457
5457
};
5458
5458
}
5459
5459
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
-
5524
5460
auto isolationFromAttr = getIsolationFromAttributes (value);
5525
5461
if (isolationFromAttr && isolationFromAttr->preconcurrency () &&
5526
5462
!value->getAttrs ().hasAttribute <PreconcurrencyAttr>()) {
@@ -5557,10 +5493,8 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5557
5493
checkClassGlobalActorIsolation (classDecl, *isolationFromAttr);
5558
5494
}
5559
5495
5560
- return {
5561
- checkGlobalIsolation (*isolationFromAttr),
5562
- IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)
5563
- };
5496
+ return {*isolationFromAttr,
5497
+ IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)};
5564
5498
}
5565
5499
5566
5500
// Determine the default isolation for this declaration, which may still be
@@ -5596,83 +5530,77 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5596
5530
// Function used when returning an inferred isolation.
5597
5531
auto inferredIsolation = [&](ActorIsolation inferred,
5598
5532
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 ;
5611
5543
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;
5620
5549
}
5550
+ break ;
5621
5551
}
5552
+ }
5622
5553
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 ())
5636
5562
return ActorIsolation::forUnspecified ().withPreconcurrency (
5637
5563
inferred.preconcurrency ());
5638
- }
5564
+ }
5639
5565
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
+ }
5643
5570
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 ;
5646
5574
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" );
5660
5577
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);
5662
5588
}
5663
5589
5664
- case ActorIsolation::ActorInstance:
5665
- case ActorIsolation::Unspecified:
5666
- if (onlyGlobal)
5667
- return ActorIsolation::forUnspecified ().withPreconcurrency (
5668
- inferred.preconcurrency ());
5590
+ break ;
5591
+ }
5669
5592
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
+ }
5673
5602
5674
- return inferred;
5675
- }());
5603
+ return inferred;
5676
5604
};
5677
5605
5678
5606
// If this is a local function, inherit the actor isolation from its
@@ -5874,10 +5802,7 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5874
5802
}
5875
5803
5876
5804
// Default isolation for this member.
5877
- return {
5878
- checkGlobalIsolation (defaultIsolation),
5879
- defaultIsolationSource
5880
- };
5805
+ return {defaultIsolation, defaultIsolationSource};
5881
5806
}
5882
5807
5883
5808
bool HasIsolatedSelfRequest::evaluate (
@@ -6075,6 +6000,63 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
6075
6000
overridden->diagnose (diag::overridden_here);
6076
6001
}
6077
6002
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
+
6078
6060
bool swift::contextRequiresStrictConcurrencyChecking (
6079
6061
const DeclContext *dc,
6080
6062
llvm::function_ref<Type(const AbstractClosureExpr *)> getType,
0 commit comments