@@ -4642,7 +4642,7 @@ namespace {
4642
4642
}
4643
4643
4644
4644
// Attempt to resolve the global actor type of a closure.
4645
- Type resolveGlobalActorType (AbstractClosureExpr *ACE) {
4645
+ Type resolveGlobalActorType (AbstractClosureExpr *ACE) const {
4646
4646
// Check whether the closure's type has a global actor already.
4647
4647
if (Type closureType = getType (ACE)) {
4648
4648
if (auto closureFnType = closureType->getAs <FunctionType>()) {
@@ -4664,91 +4664,92 @@ namespace {
4664
4664
// /
4665
4665
// / This function assumes that enclosing closures have already had their
4666
4666
// / isolation checked.
4667
- ActorIsolation determineClosureIsolation (
4668
- AbstractClosureExpr *closure) {
4669
- bool preconcurrency = false ;
4667
+ ActorIsolation
4668
+ determineClosureIsolation (AbstractClosureExpr *closure) const ;
4669
+ };
4670
+ } // end anonymous namespace
4670
4671
4671
- if (auto explicitClosure = dyn_cast<ClosureExpr>(closure))
4672
- preconcurrency = explicitClosure->isIsolatedByPreconcurrency ();
4672
+ ActorIsolation ActorIsolationChecker::determineClosureIsolation (
4673
+ AbstractClosureExpr *closure) const {
4674
+ bool preconcurrency = false ;
4673
4675
4674
- // If the closure specifies a global actor, use it.
4675
- if (Type globalActor = resolveGlobalActorType (closure)) {
4676
- return ActorIsolation::forGlobalActor (globalActor)
4677
- .withPreconcurrency (preconcurrency);
4678
- }
4676
+ ActorIsolation isolation = [&] {
4677
+ if (auto explicitClosure = dyn_cast<ClosureExpr>(closure))
4678
+ preconcurrency = explicitClosure->isIsolatedByPreconcurrency ();
4679
4679
4680
- if (auto *explicitClosure = dyn_cast<ClosureExpr>(closure)) {
4681
- if (auto *attr =
4682
- explicitClosure->getAttrs ().getAttribute <NonisolatedAttr>();
4683
- attr && ctx.LangOpts .hasFeature (Feature::ClosureIsolation)) {
4684
- return ActorIsolation::forNonisolated (attr->isUnsafe ())
4685
- .withPreconcurrency (preconcurrency);
4686
- }
4680
+ // If the closure specifies a global actor, use it.
4681
+ if (Type globalActor = resolveGlobalActorType (closure)) {
4682
+ return ActorIsolation::forGlobalActor (globalActor);
4683
+ }
4684
+
4685
+ if (auto *explicitClosure = dyn_cast<ClosureExpr>(closure)) {
4686
+ if (auto *attr =
4687
+ explicitClosure->getAttrs ().getAttribute <NonisolatedAttr>();
4688
+ attr && ctx.LangOpts .hasFeature (Feature::ClosureIsolation)) {
4689
+ return ActorIsolation::forNonisolated (attr->isUnsafe ());
4687
4690
}
4691
+ }
4688
4692
4689
- // If a closure has an isolated parameter, it is isolated to that
4690
- // parameter.
4691
- for (auto param : *closure->getParameters ()) {
4692
- if (param->isIsolated ())
4693
- return ActorIsolation::forActorInstanceCapture (param)
4694
- .withPreconcurrency (preconcurrency);
4695
- }
4696
-
4697
- // If we have a closure that acts as an isolation inference boundary, then
4698
- // we return that it is non-isolated.
4699
- //
4700
- // NOTE: Since we already checked for global actor isolated things, we
4701
- // know that all Sendable closures must be nonisolated. That is why it is
4702
- // safe to rely on this path to handle Sendable closures.
4703
- if (isIsolationInferenceBoundaryClosure (
4704
- closure, /* canInheritActorContext*/ true ))
4705
- return ActorIsolation::forNonisolated (/* unsafe=*/ false )
4706
- .withPreconcurrency (preconcurrency);
4707
-
4708
- // A non-Sendable closure gets its isolation from its context.
4709
- auto parentIsolation = getActorIsolationOfContext (
4710
- closure->getParent (), getClosureActorIsolation);
4711
- preconcurrency |= parentIsolation.preconcurrency ();
4712
-
4713
- // We must have parent isolation determined to get here.
4714
- switch (parentIsolation) {
4715
- case ActorIsolation::CallerIsolationInheriting:
4716
- case ActorIsolation::Nonisolated:
4717
- case ActorIsolation::NonisolatedUnsafe:
4718
- case ActorIsolation::Unspecified:
4719
- return ActorIsolation::forNonisolated (parentIsolation ==
4720
- ActorIsolation::NonisolatedUnsafe)
4721
- .withPreconcurrency (preconcurrency);
4693
+ // If a closure has an isolated parameter, it is isolated to that
4694
+ // parameter.
4695
+ for (auto param : *closure->getParameters ()) {
4696
+ if (param->isIsolated ())
4697
+ return ActorIsolation::forActorInstanceCapture (param);
4698
+ }
4722
4699
4723
- case ActorIsolation::Erased:
4724
- llvm_unreachable (" context cannot have erased isolation" );
4700
+ // If we have a closure that acts as an isolation inference boundary, then
4701
+ // we return that it is non-isolated.
4702
+ //
4703
+ // NOTE: Since we already checked for global actor isolated things, we
4704
+ // know that all Sendable closures must be nonisolated. That is why it is
4705
+ // safe to rely on this path to handle Sendable closures.
4706
+ if (isIsolationInferenceBoundaryClosure (closure,
4707
+ /* canInheritActorContext=*/ true ))
4708
+ return ActorIsolation::forNonisolated (/* unsafe=*/ false );
4709
+
4710
+ // A non-Sendable closure gets its isolation from its context.
4711
+ auto parentIsolation = getActorIsolationOfContext (
4712
+ closure->getParent (), getClosureActorIsolation);
4713
+ preconcurrency |= parentIsolation.preconcurrency ();
4714
+
4715
+ // We must have parent isolation determined to get here.
4716
+ switch (parentIsolation) {
4717
+ case ActorIsolation::CallerIsolationInheriting:
4718
+ case ActorIsolation::Nonisolated:
4719
+ case ActorIsolation::NonisolatedUnsafe:
4720
+ case ActorIsolation::Unspecified:
4721
+ return ActorIsolation::forNonisolated (
4722
+ parentIsolation == ActorIsolation::NonisolatedUnsafe);
4725
4723
4726
- case ActorIsolation::GlobalActor: {
4727
- Type globalActor = closure->mapTypeIntoContext (
4728
- parentIsolation.getGlobalActor ()->mapTypeOutOfContext ());
4729
- return ActorIsolation::forGlobalActor (globalActor)
4730
- .withPreconcurrency (preconcurrency);
4731
- }
4724
+ case ActorIsolation::Erased:
4725
+ llvm_unreachable (" context cannot have erased isolation" );
4732
4726
4733
- case ActorIsolation::ActorInstance: {
4734
- if (checkIsolatedCapture) {
4735
- if (auto param = closure->getCaptureInfo ().getIsolatedParamCapture ())
4736
- return ActorIsolation::forActorInstanceCapture (param)
4737
- .withPreconcurrency (preconcurrency);
4738
- } else {
4739
- // If we don't have capture information during code completion, assume
4740
- // that the closure captures the `isolated` parameter from the parent
4741
- // context.
4742
- return parentIsolation;
4743
- }
4727
+ case ActorIsolation::GlobalActor: {
4728
+ Type globalActor = closure->mapTypeIntoContext (
4729
+ parentIsolation.getGlobalActor ()->mapTypeOutOfContext ());
4730
+ return ActorIsolation::forGlobalActor (globalActor);
4731
+ }
4744
4732
4745
- return ActorIsolation::forNonisolated (/* unsafe=*/ false )
4746
- .withPreconcurrency (preconcurrency);
4733
+ case ActorIsolation::ActorInstance: {
4734
+ if (checkIsolatedCapture) {
4735
+ if (auto param = closure->getCaptureInfo ().getIsolatedParamCapture ())
4736
+ return ActorIsolation::forActorInstanceCapture (param);
4737
+ } else {
4738
+ // If we don't have capture information during code completion, assume
4739
+ // that the closure captures the `isolated` parameter from the parent
4740
+ // context.
4741
+ return parentIsolation;
4747
4742
}
4743
+
4744
+ return ActorIsolation::forNonisolated (/* unsafe=*/ false );
4748
4745
}
4749
4746
}
4747
+ }();
4750
4748
4751
- };
4749
+ // Apply computed preconcurrency.
4750
+ isolation = isolation.withPreconcurrency (preconcurrency);
4751
+
4752
+ return isolation;
4752
4753
}
4753
4754
4754
4755
bool ActorIsolationChecker::mayExecuteConcurrentlyWith (
0 commit comments