@@ -5366,70 +5366,6 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5366
5366
};
5367
5367
}
5368
5368
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
-
5433
5369
auto isolationFromAttr = getIsolationFromAttributes (value);
5434
5370
if (isolationFromAttr && isolationFromAttr->preconcurrency () &&
5435
5371
!value->getAttrs ().hasAttribute <PreconcurrencyAttr>()) {
@@ -5466,10 +5402,8 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5466
5402
checkClassGlobalActorIsolation (classDecl, *isolationFromAttr);
5467
5403
}
5468
5404
5469
- return {
5470
- checkGlobalIsolation (*isolationFromAttr),
5471
- IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)
5472
- };
5405
+ return {*isolationFromAttr,
5406
+ IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)};
5473
5407
}
5474
5408
5475
5409
// Determine the default isolation for this declaration, which may still be
@@ -5505,83 +5439,77 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5505
5439
// Function used when returning an inferred isolation.
5506
5440
auto inferredIsolation = [&](ActorIsolation inferred,
5507
5441
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 ;
5520
5452
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;
5529
5458
}
5459
+ break ;
5530
5460
}
5461
+ }
5531
5462
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 ())
5545
5471
return ActorIsolation::forUnspecified ().withPreconcurrency (
5546
5472
inferred.preconcurrency ());
5547
- }
5473
+ }
5548
5474
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
+ }
5552
5479
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 ;
5555
5483
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" );
5569
5486
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);
5571
5497
}
5572
5498
5573
- case ActorIsolation::ActorInstance:
5574
- case ActorIsolation::Unspecified:
5575
- if (onlyGlobal)
5576
- return ActorIsolation::forUnspecified ().withPreconcurrency (
5577
- inferred.preconcurrency ());
5499
+ break ;
5500
+ }
5578
5501
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
+ }
5582
5511
5583
- return inferred;
5584
- }());
5512
+ return inferred;
5585
5513
};
5586
5514
5587
5515
// If this is a local function, inherit the actor isolation from its
@@ -5783,10 +5711,7 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5783
5711
}
5784
5712
5785
5713
// Default isolation for this member.
5786
- return {
5787
- checkGlobalIsolation (defaultIsolation),
5788
- defaultIsolationSource
5789
- };
5714
+ return {defaultIsolation, defaultIsolationSource};
5790
5715
}
5791
5716
5792
5717
bool HasIsolatedSelfRequest::evaluate (
@@ -5984,6 +5909,63 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
5984
5909
overridden->diagnose (diag::overridden_here);
5985
5910
}
5986
5911
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
+
5987
5969
bool swift::contextRequiresStrictConcurrencyChecking (
5988
5970
const DeclContext *dc,
5989
5971
llvm::function_ref<Type(const AbstractClosureExpr *)> getType,
0 commit comments