@@ -5533,6 +5533,82 @@ static void addAttributesForActorIsolation(ValueDecl *value,
5533
5533
}
5534
5534
}
5535
5535
5536
+ // / Determine the default isolation and isolation source for this declaration,
5537
+ // / which may still be overridden by other inference rules.
5538
+ static std::tuple<InferredActorIsolation, ValueDecl *,
5539
+ std::optional<ActorIsolation>>
5540
+ computeDefaultInferredActorIsolation (ValueDecl *value) {
5541
+ auto &ctx = value->getASTContext ();
5542
+
5543
+ // If we are supposed to infer main actor isolation by default for entities
5544
+ // within our module, make our default isolation main actor.
5545
+ if (ctx.LangOpts .hasFeature (Feature::UnspecifiedMeansMainActorIsolated) &&
5546
+ value->getModuleContext () == ctx.MainModule ) {
5547
+
5548
+ // Default global actor isolation does not apply to any declarations
5549
+ // within actors and distributed actors.
5550
+ bool inActorContext = false ;
5551
+ auto *dc = value->getInnermostDeclContext ();
5552
+ while (dc && !inActorContext) {
5553
+ if (auto *nominal = dc->getSelfNominalTypeDecl ()) {
5554
+ inActorContext = nominal->isAnyActor ();
5555
+ }
5556
+ dc = dc->getParent ();
5557
+ }
5558
+
5559
+ if (!inActorContext) {
5560
+ // FIXME: deinit should be implicitly MainActor too.
5561
+ if (isa<TypeDecl>(value) || isa<ExtensionDecl>(value) ||
5562
+ isa<AbstractStorageDecl>(value) || isa<FuncDecl>(value) ||
5563
+ isa<ConstructorDecl>(value)) {
5564
+ return {{ActorIsolation::forMainActor (ctx), {}}, nullptr , {}};
5565
+ }
5566
+ }
5567
+ }
5568
+
5569
+ // If we have an async function... by default we inherit isolation.
5570
+ if (ctx.LangOpts .hasFeature (
5571
+ Feature::NonIsolatedAsyncInheritsIsolationFromContext)) {
5572
+ if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
5573
+ func && func->hasAsync () &&
5574
+ func->getModuleContext () == ctx.MainModule ) {
5575
+ return {{ActorIsolation::forNonisolated (false /* is unsafe*/ ), {}},
5576
+ nullptr ,
5577
+ {}};
5578
+ }
5579
+ }
5580
+
5581
+ if (auto func = dyn_cast<AbstractFunctionDecl>(value)) {
5582
+ // A @Sendable function is assumed to be actor-independent.
5583
+ if (func->isSendable ()) {
5584
+ return {
5585
+ {ActorIsolation::forConcurrent (/* unsafe=*/ false ), {}}, nullptr , {}};
5586
+ }
5587
+ }
5588
+
5589
+ // When no other isolation applies, an actor's non-async init is independent
5590
+ if (auto nominal = value->getDeclContext ()->getSelfNominalTypeDecl ())
5591
+ if (nominal->isAnyActor ())
5592
+ if (auto ctor = dyn_cast<ConstructorDecl>(value))
5593
+ if (!ctor->hasAsync ())
5594
+ return {{ActorIsolation::forConcurrent (/* unsafe=*/ false ), {}},
5595
+ nullptr ,
5596
+ {}};
5597
+
5598
+ // Look for and remember the overridden declaration's isolation.
5599
+ if (auto *overriddenValue = value->getOverriddenDeclOrSuperDeinit ()) {
5600
+ // Use the overridden decl's iso as the default isolation for this decl.
5601
+ auto isolation = getOverriddenIsolationFor (value);
5602
+ return {{isolation,
5603
+ IsolationSource (overriddenValue, IsolationSource::Override)},
5604
+ overriddenValue,
5605
+ isolation};
5606
+ }
5607
+
5608
+ // We did not find anything special, return unspecified.
5609
+ return {{ActorIsolation::forUnspecified (), {}}, nullptr , {}};
5610
+ }
5611
+
5536
5612
InferredActorIsolation ActorIsolationRequest::evaluate (
5537
5613
Evaluator &evaluator, ValueDecl *value) const {
5538
5614
// If this declaration has actor-isolated "self", it's isolated to that
@@ -5576,7 +5652,7 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5576
5652
value->getAttrs ().add (preconcurrency);
5577
5653
}
5578
5654
5579
- if (FuncDecl *fd = dyn_cast<FuncDecl>(value)) {
5655
+ if (auto *fd = dyn_cast<FuncDecl>(value)) {
5580
5656
// Main.main() and Main.$main are implicitly MainActor-protected.
5581
5657
// Any other isolation is an error.
5582
5658
std::optional<ActorIsolation> mainIsolation =
@@ -5609,74 +5685,11 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5609
5685
IsolationSource (/* source*/ nullptr , IsolationSource::Explicit)};
5610
5686
}
5611
5687
5612
- // Determine the default isolation for this declaration, which may still be
5613
- // overridden by other inference rules.
5614
- ActorIsolation defaultIsolation = ActorIsolation::forUnspecified ();
5615
- IsolationSource defaultIsolationSource;
5616
-
5617
- // If we are supposed to infer main actor isolation by default for entities
5618
- // within our module, make our default isolation main actor.
5619
- if (ctx.LangOpts .hasFeature (Feature::UnspecifiedMeansMainActorIsolated) &&
5620
- value->getModuleContext () == ctx.MainModule ) {
5621
-
5622
- // Default global actor isolation does not apply to any declarations
5623
- // within actors and distributed actors.
5624
- bool inActorContext = false ;
5625
- auto *dc = value->getInnermostDeclContext ();
5626
- while (dc && !inActorContext) {
5627
- if (auto *nominal = dc->getSelfNominalTypeDecl ()) {
5628
- inActorContext = nominal->isAnyActor ();
5629
- }
5630
- dc = dc->getParent ();
5631
- }
5632
-
5633
- if (!inActorContext) {
5634
- // FIXME: deinit should be implicitly MainActor too.
5635
- if (isa<TypeDecl>(value) || isa<ExtensionDecl>(value) ||
5636
- isa<AbstractStorageDecl>(value) || isa<FuncDecl>(value) ||
5637
- isa<ConstructorDecl>(value)) {
5638
- defaultIsolation = ActorIsolation::forMainActor (ctx);
5639
- }
5640
- }
5641
- }
5642
-
5643
- // If we have an async function... by default we inherit isolation.
5644
- if (ctx.LangOpts .hasFeature (
5645
- Feature::NonIsolatedAsyncInheritsIsolationFromContext)) {
5646
- if (auto *func = dyn_cast<AbstractFunctionDecl>(value);
5647
- func && func->hasAsync () &&
5648
- func->getModuleContext () == ctx.MainModule ) {
5649
- defaultIsolation = ActorIsolation::forNonisolated (false /* is unsafe*/ );
5650
- }
5651
- }
5652
-
5653
- if (auto func = dyn_cast<AbstractFunctionDecl>(value)) {
5654
- // A @Sendable function is assumed to be actor-independent.
5655
- if (func->isSendable ()) {
5656
- defaultIsolation = ActorIsolation::forConcurrent (/* unsafe=*/ false );
5657
- }
5658
- }
5659
-
5660
- // When no other isolation applies, an actor's non-async init is independent
5661
- if (auto nominal = value->getDeclContext ()->getSelfNominalTypeDecl ())
5662
- if (nominal->isAnyActor ())
5663
- if (auto ctor = dyn_cast<ConstructorDecl>(value))
5664
- if (!ctor->hasAsync ())
5665
- defaultIsolation = ActorIsolation::forConcurrent (/* unsafe=*/ false );
5666
-
5667
- // Look for and remember the overridden declaration's isolation.
5668
- std::optional<ActorIsolation> overriddenIso;
5669
- ValueDecl *overriddenValue = value->getOverriddenDeclOrSuperDeinit ();
5670
- if (overriddenValue) {
5671
- // use the overridden decl's iso as the default isolation for this decl.
5672
- defaultIsolation = getOverriddenIsolationFor (value);
5673
- defaultIsolationSource =
5674
- IsolationSource (overriddenValue, IsolationSource::Override);
5675
- overriddenIso = defaultIsolation;
5676
- }
5677
-
5678
- // NOTE: After this point, the default has been set. Only touch the default
5679
- // isolation above this point since code below assumes it is now constant.
5688
+ InferredActorIsolation defaultIsolation;
5689
+ ValueDecl *overriddenValue;
5690
+ std::optional<ActorIsolation> overriddenIsolation;
5691
+ std::tie (defaultIsolation, overriddenValue, overriddenIsolation) =
5692
+ computeDefaultInferredActorIsolation (value);
5680
5693
5681
5694
// Function used when returning an inferred isolation.
5682
5695
auto inferredIsolation = [&](ActorIsolation inferred,
@@ -5687,16 +5700,17 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5687
5700
// if the inferred isolation is not valid, then carry-over the overridden
5688
5701
// declaration's isolation as this decl's inferred isolation.
5689
5702
switch (validOverrideIsolation (value, inferred, overriddenValue,
5690
- *overriddenIso )) {
5703
+ *overriddenIsolation )) {
5691
5704
case OverrideIsolationResult::Allowed:
5692
5705
case OverrideIsolationResult::Sendable:
5693
5706
break ;
5694
5707
5695
5708
case OverrideIsolationResult::Disallowed:
5696
- if (overriddenValue->hasClangNode () && overriddenIso->isUnspecified ()) {
5697
- inferred = overriddenIso->withPreconcurrency (true );
5709
+ if (overriddenValue->hasClangNode () &&
5710
+ overriddenIsolation->isUnspecified ()) {
5711
+ inferred = overriddenIsolation->withPreconcurrency (true );
5698
5712
} else {
5699
- inferred = *overriddenIso ;
5713
+ inferred = *overriddenIsolation ;
5700
5714
}
5701
5715
break ;
5702
5716
}
@@ -5955,7 +5969,7 @@ InferredActorIsolation ActorIsolationRequest::evaluate(
5955
5969
}
5956
5970
5957
5971
// Default isolation for this member.
5958
- return { defaultIsolation, defaultIsolationSource} ;
5972
+ return defaultIsolation;
5959
5973
}
5960
5974
5961
5975
bool HasIsolatedSelfRequest::evaluate (
0 commit comments