@@ -698,27 +698,6 @@ static bool isAsyncCall(
698698// / features.
699699static bool shouldDiagnoseExistingDataRaces (const DeclContext *dc);
700700
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-
722701// / Returns true if this closure acts as an inference boundary in the AST. An
723702// / inference boundary is an expression in the AST where we newly infer
724703// / isolation different from our parent decl context.
@@ -733,30 +712,23 @@ static bool isSendableClosure(
733712// / function. That @MainActor closure would act as an Isolation Inference
734713// / Boundary.
735714// /
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.
745721static bool
746722isIsolationInferenceBoundaryClosure (const AbstractClosureExpr *closure,
747- bool forActorIsolation ) {
723+ bool canInheritActorContext ) {
748724 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 ;
760732 }
761733
762734 // An autoclosure for an async let acts as a boundary. It is non-Sendable
@@ -766,7 +738,7 @@ isIsolationInferenceBoundaryClosure(const AbstractClosureExpr *closure,
766738 return true ;
767739 }
768740
769- return isSendableClosure ( closure, forActorIsolation );
741+ return closure-> isSendable ( );
770742}
771743
772744// / Add Fix-It text for the given nominal type to adopt Sendable.
@@ -1693,7 +1665,7 @@ swift::isActorInitOrDeInitContext(const DeclContext *dc) {
16931665 // Stop looking if we hit an isolation inference boundary.
16941666 if (auto *closure = dyn_cast<AbstractClosureExpr>(dc)) {
16951667 if (isIsolationInferenceBoundaryClosure (closure,
1696- false /* is for actor isolation */ ))
1668+ /* canInheritActorContext */ false ))
16971669 return nullptr ;
16981670
16991671 // Otherwise, look through our closure at the closure's parent decl
@@ -2703,7 +2675,8 @@ namespace {
27032675 // function type, but this is okay for non-Sendable closures
27042676 // because they cannot leave the isolation domain they're created
27052677 // in anyway.
2706- if (closure->isSendable ())
2678+ if (isIsolationInferenceBoundaryClosure (
2679+ closure, /* canInheritActorContext*/ false ))
27072680 return false ;
27082681
27092682 if (closure->getActorIsolation ().isActorIsolated ())
@@ -3237,7 +3210,7 @@ namespace {
32373210 case ActorIsolation::Unspecified:
32383211 case ActorIsolation::Nonisolated:
32393212 case ActorIsolation::NonisolatedUnsafe:
3240- if (isSendableClosure ( closure, /* forActorIsolation= */ true )) {
3213+ if (closure-> isSendable ( )) {
32413214 return ReferencedActor (var, isPotentiallyIsolated, ReferencedActor::SendableClosure);
32423215 }
32433216
@@ -4515,7 +4488,7 @@ namespace {
45154488 // know that all Sendable closures must be nonisolated. That is why it is
45164489 // safe to rely on this path to handle Sendable closures.
45174490 if (isIsolationInferenceBoundaryClosure (
4518- closure, true /* is for closure isolation */ ))
4491+ closure, /* canInheritActorContext */ true ))
45194492 return ActorIsolation::forNonisolated (/* unsafe=*/ false )
45204493 .withPreconcurrency (preconcurrency);
45214494
@@ -4606,7 +4579,7 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
46064579 while (useContext != defContext) {
46074580 // If we find a concurrent closure... it can be run concurrently.
46084581 if (auto closure = dyn_cast<AbstractClosureExpr>(useContext)) {
4609- if (isSendableClosure ( closure, /* forActorIsolation= */ false ))
4582+ if (closure-> isSendable ( ))
46104583 return true ;
46114584
46124585 if (isolatedStateMayEscape)
@@ -6063,7 +6036,7 @@ DefaultInitializerIsolation::evaluate(Evaluator &evaluator,
60636036 auto i = pbd->getPatternEntryIndexForVarDecl (var);
60646037
60656038 dc = cast<Initializer>(pbd->getInitContext (i));
6066- initExpr = pbd->getCheckedAndContextualizedInit (i);
6039+ initExpr = pbd->getContextualizedInit (i);
60676040 enclosingIsolation = getActorIsolation (var);
60686041 } else if (auto *param = dyn_cast<ParamDecl>(var)) {
60696042 // If this parameter corresponds to a stored property for a
0 commit comments