Skip to content

Commit 55e9f37

Browse files
committed
[Concurrency] Clean up code that determines whether a closure is an actor
isolation inference boundary.
1 parent 7de7eaf commit 55e9f37

File tree

1 file changed

+20
-48
lines changed

1 file changed

+20
-48
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 20 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -698,27 +698,6 @@ static bool isAsyncCall(
698698
/// features.
699699
static 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.
745721
static bool
746722
isIsolationInferenceBoundaryClosure(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
@@ -2704,7 +2676,7 @@ namespace {
27042676
// because they cannot leave the isolation domain they're created
27052677
// in anyway.
27062678
if (isIsolationInferenceBoundaryClosure(
2707-
closure, /*can inherit actor context*/false))
2679+
closure, /*canInheritActorContext*/false))
27082680
return false;
27092681

27102682
if (closure->getActorIsolation().isActorIsolated())
@@ -3238,7 +3210,7 @@ namespace {
32383210
case ActorIsolation::Unspecified:
32393211
case ActorIsolation::Nonisolated:
32403212
case ActorIsolation::NonisolatedUnsafe:
3241-
if (isSendableClosure(closure, /*forActorIsolation=*/true)) {
3213+
if (closure->isSendable()) {
32423214
return ReferencedActor(var, isPotentiallyIsolated, ReferencedActor::SendableClosure);
32433215
}
32443216

@@ -4516,7 +4488,7 @@ namespace {
45164488
// know that all Sendable closures must be nonisolated. That is why it is
45174489
// safe to rely on this path to handle Sendable closures.
45184490
if (isIsolationInferenceBoundaryClosure(
4519-
closure, true /*is for closure isolation*/))
4491+
closure, /*canInheritActorContext*/true))
45204492
return ActorIsolation::forNonisolated(/*unsafe=*/false)
45214493
.withPreconcurrency(preconcurrency);
45224494

@@ -4607,7 +4579,7 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
46074579
while (useContext != defContext) {
46084580
// If we find a concurrent closure... it can be run concurrently.
46094581
if (auto closure = dyn_cast<AbstractClosureExpr>(useContext)) {
4610-
if (isSendableClosure(closure, /*forActorIsolation=*/false))
4582+
if (closure->isSendable())
46114583
return true;
46124584

46134585
if (isolatedStateMayEscape)

0 commit comments

Comments
 (0)