@@ -2559,7 +2559,8 @@ namespace {
25592559 // / Determine whether code in the given use context might execute
25602560 // / concurrently with code in the definition context.
25612561 bool mayExecuteConcurrentlyWith (
2562- const DeclContext *useContext, const DeclContext *defContext);
2562+ const DeclContext *useContext, const DeclContext *defContext,
2563+ bool includeSending = false );
25632564
25642565 // / If the subexpression is a reference to a mutable local variable from a
25652566 // / different context, record its parent. We'll query this as part of
@@ -3067,12 +3068,9 @@ namespace {
30673068 }
30683069 }
30693070
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?
30733071 if (mayExecuteConcurrentlyWith (
3074- localFunc.getAsDeclContext (), getDeclContext ()) ||
3075- (explicitClosure && explicitClosure-> isPassedToSendingParameter () )) {
3072+ localFunc.getAsDeclContext (), getDeclContext (),
3073+ /* includeSending */ true )) {
30763074 auto innermostGenericDC = localFunc.getAsDeclContext ();
30773075 while (innermostGenericDC && !innermostGenericDC->isGenericContext ())
30783076 innermostGenericDC = innermostGenericDC->getParent ();
@@ -4834,13 +4832,12 @@ ActorIsolation ActorIsolationChecker::determineClosureIsolation(
48344832}
48354833
48364834bool ActorIsolationChecker::mayExecuteConcurrentlyWith (
4837- const DeclContext *useContext, const DeclContext *defContext) {
4835+ const DeclContext *useContext, const DeclContext *defContext,
4836+ bool includeSending) {
48384837 // Fast path for when the use and definition contexts are the same.
48394838 if (useContext == defContext)
48404839 return false ;
48414840
4842- bool isolatedStateMayEscape = false ;
4843-
48444841 auto useIsolation = getActorIsolationOfContext (
48454842 const_cast <DeclContext *>(useContext), getClosureActorIsolation);
48464843 if (useIsolation.isActorIsolated ()) {
@@ -4858,16 +4855,6 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
48584855 if (ctx.LangOpts .hasFeature (Feature::GlobalActorIsolatedTypesUsability) &&
48594856 regionIsolationEnabled && useIsolation.isGlobalActor ())
48604857 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 ());
48714858 }
48724859
48734860 // Walk the context chain from the use to the definition.
@@ -4877,18 +4864,17 @@ bool ActorIsolationChecker::mayExecuteConcurrentlyWith(
48774864 if (closure->isSendable ())
48784865 return true ;
48794866
4880- if (isolatedStateMayEscape)
4881- return true ;
4867+ if (auto *explicitClosure = dyn_cast<ClosureExpr>(closure)) {
4868+ if (includeSending && explicitClosure->isPassedToSendingParameter ())
4869+ return true ;
4870+ }
48824871 }
48834872
48844873 if (auto func = dyn_cast<FuncDecl>(useContext)) {
48854874 if (func->isLocalCapture ()) {
48864875 // If the function is @Sendable... it can be run concurrently.
48874876 if (func->isSendable ())
48884877 return true ;
4889-
4890- if (isolatedStateMayEscape)
4891- return true ;
48924878 }
48934879 }
48944880
0 commit comments