@@ -2543,7 +2543,8 @@ namespace {
2543
2543
// / Determine whether code in the given use context might execute
2544
2544
// / concurrently with code in the definition context.
2545
2545
bool mayExecuteConcurrentlyWith (
2546
- const DeclContext *useContext, const DeclContext *defContext);
2546
+ const DeclContext *useContext, const DeclContext *defContext,
2547
+ bool includeSending = false );
2547
2548
2548
2549
// / If the subexpression is a reference to a mutable local variable from a
2549
2550
// / different context, record its parent. We'll query this as part of
@@ -3051,12 +3052,9 @@ namespace {
3051
3052
}
3052
3053
}
3053
3054
3054
- // FIXME: When passing to a sending parameter, should this be handled
3055
- // by region isolation? Or should it always be handled by region
3056
- // isolation?
3057
3055
if (mayExecuteConcurrentlyWith (
3058
- localFunc.getAsDeclContext (), getDeclContext ()) ||
3059
- (explicitClosure && explicitClosure-> isPassedToSendingParameter () )) {
3056
+ localFunc.getAsDeclContext (), getDeclContext (),
3057
+ /* includeSending */ true )) {
3060
3058
auto innermostGenericDC = localFunc.getAsDeclContext ();
3061
3059
while (innermostGenericDC && !innermostGenericDC->isGenericContext ())
3062
3060
innermostGenericDC = innermostGenericDC->getParent ();
@@ -4816,13 +4814,12 @@ ActorIsolation ActorIsolationChecker::determineClosureIsolation(
4816
4814
}
4817
4815
4818
4816
bool ActorIsolationChecker::mayExecuteConcurrentlyWith (
4819
- const DeclContext *useContext, const DeclContext *defContext) {
4817
+ const DeclContext *useContext, const DeclContext *defContext,
4818
+ bool includeSending) {
4820
4819
// Fast path for when the use and definition contexts are the same.
4821
4820
if (useContext == defContext)
4822
4821
return false ;
4823
4822
4824
- bool isolatedStateMayEscape = false ;
4825
-
4826
4823
auto useIsolation = getActorIsolationOfContext (
4827
4824
const_cast <DeclContext *>(useContext), getClosureActorIsolation);
4828
4825
if (useIsolation.isActorIsolated ()) {
@@ -4840,16 +4837,6 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
4840
4837
if (ctx.LangOpts .hasFeature (Feature::GlobalActorIsolatedTypesUsability) &&
4841
4838
regionIsolationEnabled && useIsolation.isGlobalActor ())
4842
4839
return false ;
4843
-
4844
- // If the local function is not Sendable, its isolation differs
4845
- // from that of the context, and both contexts are actor isolated,
4846
- // then capturing non-Sendable values allows the closure to stash
4847
- // those values into actor-isolated state. The original context
4848
- // may also stash those values into isolated state, enabling concurrent
4849
- // access later on.
4850
- isolatedStateMayEscape =
4851
- (!regionIsolationEnabled &&
4852
- useIsolation.isActorIsolated () && defIsolation.isActorIsolated ());
4853
4840
}
4854
4841
4855
4842
// Walk the context chain from the use to the definition.
@@ -4859,18 +4846,17 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
4859
4846
if (closure->isSendable ())
4860
4847
return true ;
4861
4848
4862
- if (isolatedStateMayEscape)
4863
- return true ;
4849
+ if (auto *explicitClosure = dyn_cast<ClosureExpr>(closure)) {
4850
+ if (includeSending && explicitClosure->isPassedToSendingParameter ())
4851
+ return true ;
4852
+ }
4864
4853
}
4865
4854
4866
4855
if (auto func = dyn_cast<FuncDecl>(useContext)) {
4867
4856
if (func->isLocalCapture ()) {
4868
4857
// If the function is @Sendable... it can be run concurrently.
4869
4858
if (func->isSendable ())
4870
4859
return true ;
4871
-
4872
- if (isolatedStateMayEscape)
4873
- return true ;
4874
4860
}
4875
4861
}
4876
4862
0 commit comments