@@ -698,27 +698,6 @@ static bool isAsyncCall(
698
698
// / features.
699
699
static bool shouldDiagnoseExistingDataRaces (const DeclContext *dc);
700
700
701
- // / Determine whether this closure should be treated as Sendable.
702
- // /
703
- // / \param forActorIsolation Whether this check is for the purposes of
704
- // / determining whether the closure must be non-isolated.
705
- static bool isSendableClosure (
706
- const AbstractClosureExpr *closure, bool forActorIsolation) {
707
- if (auto explicitClosure = dyn_cast<ClosureExpr>(closure)) {
708
- if (forActorIsolation && explicitClosure->inheritsActorContext ()) {
709
- return false ;
710
- }
711
- }
712
-
713
- if (auto type = closure->getType ()) {
714
- if (auto fnType = type->getAs <AnyFunctionType>())
715
- if (fnType->isSendable ())
716
- return true ;
717
- }
718
-
719
- return false ;
720
- }
721
-
722
701
// / Returns true if this closure acts as an inference boundary in the AST. An
723
702
// / inference boundary is an expression in the AST where we newly infer
724
703
// / isolation different from our parent decl context.
@@ -733,30 +712,23 @@ static bool isSendableClosure(
733
712
// / function. That @MainActor closure would act as an Isolation Inference
734
713
// / Boundary.
735
714
// /
736
- // / \arg forActorIsolation we currently have two slightly varying semantics
737
- // / here. If this is set, then we assuming that we are being called recursively
738
- // / while walking up a decl context path to determine the actor isolation of a
739
- // / closure. In such a case, we do not want to be a boundary if we should
740
- // / inheritActorContext. In other contexts though, we want to determine if the
741
- // / closure is part of an init or deinit. In such a case, we are walking up the
742
- // / decl context chain and we want to stop if we see a sending parameter since
743
- // / in such a case, the sending closure parameter is known to not be part of the
744
- // / init or deinit.
715
+ // / \param canInheritActorContext Whether or not the closure is allowed to
716
+ // / inherit the isolation of the enclosing context. If this is \c true ,
717
+ // / the closure is not considered an isolation inference boundary if the
718
+ // / \c @_inheritActorContext attribute is applied to the closure. This
719
+ // / attribute is inferred from a parameter declaration for closure arguments,
720
+ // / and it's set on the closure in CSApply.
745
721
static bool
746
722
isIsolationInferenceBoundaryClosure (const AbstractClosureExpr *closure,
747
- bool forActorIsolation ) {
723
+ bool canInheritActorContext ) {
748
724
if (auto *ce = dyn_cast<ClosureExpr>(closure)) {
749
- if (!forActorIsolation) {
750
- // For example, one would along this path see if for flow sensitive
751
- // isolation the closure is part of an init or deinit.
752
- if (ce->isPassedToSendingParameter ())
753
- return true ;
754
- } else {
755
- // This is for actor isolation. If we have inheritActorContext though, we
756
- // do not want to do anything since we are part of our parent's isolation.
757
- if (!ce->inheritsActorContext () && ce->isPassedToSendingParameter ())
758
- return true ;
759
- }
725
+ // If the closure can inherit the isolation of the enclosing context,
726
+ // it is not an actor isolation inference boundary.
727
+ if (canInheritActorContext && ce->inheritsActorContext ())
728
+ return false ;
729
+
730
+ if (ce->isPassedToSendingParameter ())
731
+ return true ;
760
732
}
761
733
762
734
// An autoclosure for an async let acts as a boundary. It is non-Sendable
@@ -766,7 +738,7 @@ isIsolationInferenceBoundaryClosure(const AbstractClosureExpr *closure,
766
738
return true ;
767
739
}
768
740
769
- return isSendableClosure ( closure, forActorIsolation );
741
+ return closure-> isSendable ( );
770
742
}
771
743
772
744
// / Add Fix-It text for the given nominal type to adopt Sendable.
@@ -1693,7 +1665,7 @@ swift::isActorInitOrDeInitContext(const DeclContext *dc) {
1693
1665
// Stop looking if we hit an isolation inference boundary.
1694
1666
if (auto *closure = dyn_cast<AbstractClosureExpr>(dc)) {
1695
1667
if (isIsolationInferenceBoundaryClosure (closure,
1696
- false /* is for actor isolation */ ))
1668
+ /* canInheritActorContext */ false ))
1697
1669
return nullptr ;
1698
1670
1699
1671
// Otherwise, look through our closure at the closure's parent decl
@@ -2704,7 +2676,7 @@ namespace {
2704
2676
// because they cannot leave the isolation domain they're created
2705
2677
// in anyway.
2706
2678
if (isIsolationInferenceBoundaryClosure (
2707
- closure, /* can inherit actor context */ false ))
2679
+ closure, /* canInheritActorContext */ false ))
2708
2680
return false ;
2709
2681
2710
2682
if (closure->getActorIsolation ().isActorIsolated ())
@@ -3238,7 +3210,7 @@ namespace {
3238
3210
case ActorIsolation::Unspecified:
3239
3211
case ActorIsolation::Nonisolated:
3240
3212
case ActorIsolation::NonisolatedUnsafe:
3241
- if (isSendableClosure ( closure, /* forActorIsolation= */ true )) {
3213
+ if (closure-> isSendable ( )) {
3242
3214
return ReferencedActor (var, isPotentiallyIsolated, ReferencedActor::SendableClosure);
3243
3215
}
3244
3216
@@ -4516,7 +4488,7 @@ namespace {
4516
4488
// know that all Sendable closures must be nonisolated. That is why it is
4517
4489
// safe to rely on this path to handle Sendable closures.
4518
4490
if (isIsolationInferenceBoundaryClosure (
4519
- closure, true /* is for closure isolation */ ))
4491
+ closure, /* canInheritActorContext */ true ))
4520
4492
return ActorIsolation::forNonisolated (/* unsafe=*/ false )
4521
4493
.withPreconcurrency (preconcurrency);
4522
4494
@@ -4607,7 +4579,7 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
4607
4579
while (useContext != defContext) {
4608
4580
// If we find a concurrent closure... it can be run concurrently.
4609
4581
if (auto closure = dyn_cast<AbstractClosureExpr>(useContext)) {
4610
- if (isSendableClosure ( closure, /* forActorIsolation= */ false ))
4582
+ if (closure-> isSendable ( ))
4611
4583
return true ;
4612
4584
4613
4585
if (isolatedStateMayEscape)
0 commit comments