@@ -2559,7 +2559,8 @@ namespace {
2559
2559
// / Determine whether code in the given use context might execute
2560
2560
// / concurrently with code in the definition context.
2561
2561
bool mayExecuteConcurrentlyWith (
2562
- const DeclContext *useContext, const DeclContext *defContext);
2562
+ const DeclContext *useContext, const DeclContext *defContext,
2563
+ bool includeSending = false );
2563
2564
2564
2565
// / If the subexpression is a reference to a mutable local variable from a
2565
2566
// / different context, record its parent. We'll query this as part of
@@ -3067,12 +3068,9 @@ namespace {
3067
3068
}
3068
3069
}
3069
3070
3070
- // FIXME: When passing to a sending parameter, should this be handled
3071
- // by region isolation? Or should it always be handled by region
3072
- // isolation?
3073
3071
if (mayExecuteConcurrentlyWith (
3074
- localFunc.getAsDeclContext (), getDeclContext ()) ||
3075
- (explicitClosure && explicitClosure-> isPassedToSendingParameter () )) {
3072
+ localFunc.getAsDeclContext (), getDeclContext (),
3073
+ /* includeSending */ true )) {
3076
3074
auto innermostGenericDC = localFunc.getAsDeclContext ();
3077
3075
while (innermostGenericDC && !innermostGenericDC->isGenericContext ())
3078
3076
innermostGenericDC = innermostGenericDC->getParent ();
@@ -4834,13 +4832,12 @@ ActorIsolation ActorIsolationChecker::determineClosureIsolation(
4834
4832
}
4835
4833
4836
4834
bool ActorIsolationChecker::mayExecuteConcurrentlyWith (
4837
- const DeclContext *useContext, const DeclContext *defContext) {
4835
+ const DeclContext *useContext, const DeclContext *defContext,
4836
+ bool includeSending) {
4838
4837
// Fast path for when the use and definition contexts are the same.
4839
4838
if (useContext == defContext)
4840
4839
return false ;
4841
4840
4842
- bool isolatedStateMayEscape = false ;
4843
-
4844
4841
auto useIsolation = getActorIsolationOfContext (
4845
4842
const_cast <DeclContext *>(useContext), getClosureActorIsolation);
4846
4843
if (useIsolation.isActorIsolated ()) {
@@ -4858,16 +4855,6 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
4858
4855
if (ctx.LangOpts .hasFeature (Feature::GlobalActorIsolatedTypesUsability) &&
4859
4856
regionIsolationEnabled && useIsolation.isGlobalActor ())
4860
4857
return false ;
4861
-
4862
- // If the local function is not Sendable, its isolation differs
4863
- // from that of the context, and both contexts are actor isolated,
4864
- // then capturing non-Sendable values allows the closure to stash
4865
- // those values into actor isolated state. The original context
4866
- // may also stash those values into isolated state, enabling concurrent
4867
- // access later on.
4868
- isolatedStateMayEscape =
4869
- (!regionIsolationEnabled &&
4870
- useIsolation.isActorIsolated () && defIsolation.isActorIsolated ());
4871
4858
}
4872
4859
4873
4860
// Walk the context chain from the use to the definition.
@@ -4877,18 +4864,17 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
4877
4864
if (closure->isSendable ())
4878
4865
return true ;
4879
4866
4880
- if (isolatedStateMayEscape)
4881
- return true ;
4867
+ if (auto *explicitClosure = dyn_cast<ClosureExpr>(closure)) {
4868
+ if (includeSending && explicitClosure->isPassedToSendingParameter ())
4869
+ return true ;
4870
+ }
4882
4871
}
4883
4872
4884
4873
if (auto func = dyn_cast<FuncDecl>(useContext)) {
4885
4874
if (func->isLocalCapture ()) {
4886
4875
// If the function is @Sendable... it can be run concurrently.
4887
4876
if (func->isSendable ())
4888
4877
return true ;
4889
-
4890
- if (isolatedStateMayEscape)
4891
- return true ;
4892
4878
}
4893
4879
}
4894
4880
0 commit comments