Skip to content

Commit 82014d7

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 2018942 commit 82014d7

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
@@ -1457,10 +1457,10 @@ namespace {
14571457
}
14581458
}
14591459

1460-
// "Defer" blocks are treated as if they are in their enclosing context.
1461-
if (auto func = dyn_cast<FuncDecl>(dc)) {
1462-
if (func->isDeferBody())
1463-
continue;
1460+
if (auto func = dyn_cast<AbstractFunctionDecl>(dc)) {
1461+
// @Sendable functions are nonisolated.
1462+
if (func->isSendable())
1463+
return ReferencedActor(var, ReferencedActor::SendableFunction);
14641464
}
14651465

14661466
// Check isolation of the context itself. We do this separately
@@ -1469,9 +1469,14 @@ namespace {
14691469
switch (auto isolation = getActorIsolationOfContext(dc)) {
14701470
case ActorIsolation::Independent:
14711471
case ActorIsolation::Unspecified:
1472-
if (auto func = dyn_cast<AbstractFunctionDecl>(dc)) {
1473-
if (func->isSendable())
1474-
return ReferencedActor(var, ReferencedActor::SendableFunction);
1472+
// Local functions can capture an isolated parameter.
1473+
// FIXME: This really should be modeled by getActorIsolationOfContext.
1474+
if (isa<FuncDecl>(dc) && cast<FuncDecl>(dc)->isLocalCapture()) {
1475+
// FIXME: Local functions could presumably capture an isolated
1476+
// parameter that isn't 'self'.
1477+
if (isPotentiallyIsolated &&
1478+
(var->isSelfParameter() || var->isSelfParamCapture()))
1479+
continue;
14751480
}
14761481

14771482
return ReferencedActor(var, ReferencedActor::NonIsolatedContext);
@@ -1482,12 +1487,6 @@ namespace {
14821487
var, isolation.getGlobalActor());
14831488

14841489
case ActorIsolation::ActorInstance:
1485-
// FIXME: Local functions could presumably capture an isolated
1486-
// parameter that isn't'self'.
1487-
if (isPotentiallyIsolated &&
1488-
(var->isSelfParameter() || var->isSelfParamCapture()))
1489-
return ReferencedActor(var, ReferencedActor::Isolated);
1490-
14911490
break;
14921491
}
14931492
}

test/Concurrency/actor_isolation.swift

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

858858
return counter
859859
}
860+
861+
func localNext() -> Int {
862+
func doIt() {
863+
counter = counter + 1
864+
}
865+
doIt()
866+
867+
return counter
868+
}
860869
}

0 commit comments

Comments
 (0)