Skip to content

Commit 67d8d9a

Browse files
committed
Local functions can capture "self" as isolated.
This is a short-term fix to address a regression in actor-isolation checking. A longer-term fix involves changing the way in which we model actor isolation so that local functions can be stated to be isolated to a particular capture, much like closures. This subsumes my short-sighted fix for "defer". Fixes rdar://79564012.
1 parent 544c796 commit 67d8d9a

File tree

2 files changed

+21
-13
lines changed

2 files changed

+21
-13
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,10 +1313,10 @@ namespace {
13131313
}
13141314
}
13151315

1316-
// "Defer" blocks are treated as if they are in their enclosing context.
1317-
if (auto func = dyn_cast<FuncDecl>(dc)) {
1318-
if (func->isDeferBody())
1319-
continue;
1316+
if (auto func = dyn_cast<AbstractFunctionDecl>(dc)) {
1317+
// @Sendable functions are nonisolated.
1318+
if (func->isSendable())
1319+
return ReferencedActor(var, ReferencedActor::SendableFunction);
13201320
}
13211321

13221322
// Check isolation of the context itself. We do this separately
@@ -1325,9 +1325,14 @@ namespace {
13251325
switch (auto isolation = getActorIsolationOfContext(dc)) {
13261326
case ActorIsolation::Independent:
13271327
case ActorIsolation::Unspecified:
1328-
if (auto func = dyn_cast<AbstractFunctionDecl>(dc)) {
1329-
if (func->isSendable())
1330-
return ReferencedActor(var, ReferencedActor::SendableFunction);
1328+
// Local functions can capture an isolated parameter.
1329+
// FIXME: This really should be modeled by getActorIsolationOfContext.
1330+
if (isa<FuncDecl>(dc) && cast<FuncDecl>(dc)->isLocalCapture()) {
1331+
// FIXME: Local functions could presumably capture an isolated
1332+
// parameter that isn't 'self'.
1333+
if (isPotentiallyIsolated &&
1334+
(var->isSelfParameter() || var->isSelfParamCapture()))
1335+
continue;
13311336
}
13321337

13331338
return ReferencedActor(var, ReferencedActor::NonIsolatedContext);
@@ -1339,12 +1344,6 @@ namespace {
13391344

13401345
case ActorIsolation::ActorInstance:
13411346
case ActorIsolation::DistributedActorInstance:
1342-
// FIXME: Local functions could presumably capture an isolated
1343-
// parameter that isn't'self'.
1344-
if (isPotentiallyIsolated &&
1345-
(var->isSelfParameter() || var->isSelfParamCapture()))
1346-
return ReferencedActor(var, ReferencedActor::Isolated);
1347-
13481347
break;
13491348
}
13501349
}

test/Concurrency/actor_isolation.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,4 +846,13 @@ actor Counter {
846846

847847
return counter
848848
}
849+
850+
func localNext() -> Int {
851+
func doIt() {
852+
counter = counter + 1
853+
}
854+
doIt()
855+
856+
return counter
857+
}
849858
}

0 commit comments

Comments
 (0)