Skip to content

Commit 406b8bd

Browse files
authored
Merge pull request #76133 from slavapestov/sync-local-func-isolation
SIL: Synchronous local functions don't need to capture the isolation parameter
2 parents 543fd21 + f2fff10 commit 406b8bd

File tree

4 files changed

+40
-29
lines changed

4 files changed

+40
-29
lines changed

lib/SIL/IR/TypeLowering.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4485,26 +4485,6 @@ TypeConverter::getLoweredLocalCaptures(SILDeclRef fn) {
44854485
PrettyStackTraceAnyFunctionRef("lowering local captures", curFn);
44864486
collectCaptures(curFn.getCaptureInfo());
44874487

4488-
if (auto *afd = curFn.getAbstractFunctionDecl()) {
4489-
// If a local function inherits isolation from the enclosing context,
4490-
// make sure we capture the isolated parameter, if we haven't already.
4491-
if (afd->isLocalCapture()) {
4492-
auto actorIsolation = getActorIsolation(afd);
4493-
if (actorIsolation.getKind() == ActorIsolation::ActorInstance) {
4494-
if (auto *var = actorIsolation.getActorInstance()) {
4495-
assert(isa<ParamDecl>(var));
4496-
recordCapture(CapturedValue(var, 0, afd->getLoc()));
4497-
if (var->getInterfaceType()->hasTypeParameter()) {
4498-
// If the isolated parameter is of a generic (actor)
4499-
// type, we need to treat as if the local function is
4500-
// generic.
4501-
capturesGenericParams = true;
4502-
}
4503-
}
4504-
}
4505-
}
4506-
}
4507-
45084488
// A function's captures also include its default arguments, because
45094489
// when we reference a function we don't track which default arguments
45104490
// are referenced too.

lib/SILOptimizer/Utils/SILIsolationInfo.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -892,10 +892,9 @@ SILIsolationInfo SILIsolationInfo::get(SILArgument *arg) {
892892
}
893893

894894
// Otherwise, if we do not have an isolated argument and are not in an
895-
// alloactor, then we might be isolated via global isolation.
895+
// allocator, then we might be isolated via global isolation.
896896
if (auto functionIsolation = fArg->getFunction()->getActorIsolation()) {
897897
if (functionIsolation.isActorIsolated()) {
898-
assert(functionIsolation.isGlobalActor());
899898
if (functionIsolation.isGlobalActor()) {
900899
return SILIsolationInfo::getGlobalActorIsolated(
901900
fArg, functionIsolation.getGlobalActor());

lib/Sema/TypeCheckCaptures.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,9 @@ class FindCapturedVars : public ASTWalker {
234234

235235
// Visit the type of the capture, if it isn't a class reference, since
236236
// we'd need the metadata to do so.
237-
if (VD->hasInterfaceType()
238-
&& (!ObjC
237+
if (!ObjC
239238
|| !isa<VarDecl>(VD)
240-
|| !cast<VarDecl>(VD)->getTypeInContext()->hasRetainablePointerRepresentation()))
239+
|| !cast<VarDecl>(VD)->getTypeInContext()->hasRetainablePointerRepresentation())
241240
checkType(VD->getInterfaceType(), VD->getLoc());
242241
}
243242

@@ -752,6 +751,18 @@ CaptureInfo CaptureInfoRequest::evaluate(Evaluator &evaluator,
752751
finder.checkType(type, AFD->getLoc());
753752
}
754753

754+
if (AFD->isLocalCapture() && AFD->hasAsync()) {
755+
// If a local function inherits isolation from the enclosing context,
756+
// make sure we capture the isolated parameter, if we haven't already.
757+
auto actorIsolation = getActorIsolation(AFD);
758+
if (actorIsolation.getKind() == ActorIsolation::ActorInstance) {
759+
if (auto *var = actorIsolation.getActorInstance()) {
760+
assert(isa<ParamDecl>(var));
761+
finder.addCapture(CapturedValue(var, 0, AFD->getLoc()));
762+
}
763+
}
764+
}
765+
755766
// Extensions of generic ObjC functions can't use generic parameters from
756767
// their context.
757768
if (finder.hasGenericParamCaptures()) {

test/SILGen/local_function_isolation.swift

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,32 @@ func test() async {}
5959
// local/nested function.
6060
actor GenericActor<K> {
6161
var i: Int = 0
62-
private func outerFunc() {
63-
func accessSelf() -> Int {
64-
// CHECK-LABEL: sil private [ossa] @$s24local_function_isolation12GenericActorC9outerFunc33_7B9E2B75110B8600A136A469D51CAF2BLLyyF10accessSelfL_SiylF : $@convention(thin) <K> (@sil_isolated @guaranteed GenericActor<K>) -> Int {
62+
func outerFunc() async {
63+
func accessSelf() async -> Int {
64+
// CHECK-LABEL: sil private [ossa] @$s24local_function_isolation12GenericActorC9outerFuncyyYaF10accessSelfL_SiyYalF : $@convention(thin) @async <K> (@sil_isolated @guaranteed GenericActor<K>) -> Int {
6565
return 0
6666
}
67-
print(accessSelf())
67+
await print(accessSelf())
6868
}
6969
}
70+
71+
// Make sure defer doesn't capture anything.
72+
actor DeferInsideInitActor {
73+
init(foo: ()) async throws {
74+
// CHECK-LABEL: sil private [ossa] @$s24local_function_isolation20DeferInsideInitActorC3fooACyt_tYaKcfc6$deferL_yyF : $@convention(thin) () -> () {
75+
defer {}
76+
try self.init()
77+
}
78+
}
79+
80+
actor NestedAsyncInSyncActor {
81+
public func outer() async {
82+
// CHECK-LABEL: sil private [ossa] @$s24local_function_isolation22NestedAsyncInSyncActorC5outeryyYaF6middleL_yyF : $@convention(thin) (@sil_isolated @guaranteed NestedAsyncInSyncActor) -> () {
83+
func middle() {
84+
// CHECK-LABEL: sil private [ossa] @$s24local_function_isolation22NestedAsyncInSyncActorC5outeryyYaF6middleL_yyF5innerL_yyYaF : $@convention(thin) @async (@sil_isolated @guaranteed NestedAsyncInSyncActor) -> () {
85+
func inner() async {}
86+
_ = inner
87+
}
88+
_ = middle
89+
}
90+
}

0 commit comments

Comments
 (0)