Skip to content

Commit 2e4fad3

Browse files
committed
[concurrency] Make captured self in a closure show up as an @sil_isolated parameter in the closure's function signature.
This ensures that when region isolation is enabled, we can begin properly modeling when a closure should not be allowed to be isolated. In the next commit, I am going to loosen this and we should be able to pass in actors outside of methods without the closure being afflicted with "actor derived-ness".
1 parent 2a78ce8 commit 2e4fad3

File tree

2 files changed

+44
-16
lines changed

2 files changed

+44
-16
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1917,6 +1917,7 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
19171917
// signature from the AST for that.
19181918
auto origGenericSig = function.getAnyFunctionRef()->getGenericSignature();
19191919
auto loweredCaptures = TC.getLoweredLocalCaptures(function);
1920+
auto *isolatedParam = loweredCaptures.getIsolatedParamCapture();
19201921

19211922
for (auto capture : loweredCaptures.getCaptures()) {
19221923
if (capture.isDynamicSelfMetadata()) {
@@ -1955,13 +1956,17 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
19551956
continue;
19561957
}
19571958

1958-
auto *VD = capture.getDecl();
1959-
auto type = VD->getInterfaceType();
1959+
auto *varDecl = capture.getDecl();
1960+
auto type = varDecl->getInterfaceType();
19601961
auto canType = type->getReducedType(origGenericSig);
19611962

1963+
auto options = SILParameterInfo::Options();
1964+
if (isolatedParam == varDecl)
1965+
options |= SILParameterInfo::Isolated;
1966+
19621967
// If we're capturing a parameter pack, wrap it in a tuple.
19631968
if (isa<PackExpansionType>(canType)) {
1964-
assert(!cast<ParamDecl>(VD)->supportsMutation() &&
1969+
assert(!cast<ParamDecl>(varDecl)->supportsMutation() &&
19651970
"Cannot capture a pack as an lvalue");
19661971

19671972
SmallVector<TupleTypeElt, 1> elts;
@@ -1983,7 +1988,7 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
19831988
} else {
19841989
convention = ParameterConvention::Direct_Guaranteed;
19851990
}
1986-
SILParameterInfo param(loweredTy.getASTType(), convention);
1991+
SILParameterInfo param(loweredTy.getASTType(), convention, options);
19871992
inputs.push_back(param);
19881993
break;
19891994
}
@@ -1995,10 +2000,10 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
19952000
.getLoweredType();
19962001
// Lvalues are captured as a box that owns the captured value.
19972002
auto boxTy = TC.getInterfaceBoxTypeForCapture(
1998-
VD, minimalLoweredTy.getASTType(),
2003+
varDecl, minimalLoweredTy.getASTType(),
19992004
/*mutable*/ true);
20002005
auto convention = ParameterConvention::Direct_Guaranteed;
2001-
auto param = SILParameterInfo(boxTy, convention);
2006+
auto param = SILParameterInfo(boxTy, convention, options);
20022007
inputs.push_back(param);
20032008
break;
20042009
}
@@ -2009,30 +2014,30 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
20092014
TypeExpansionContext::minimal())
20102015
.getLoweredType();
20112016
// Lvalues are captured as a box that owns the captured value.
2012-
auto boxTy =
2013-
TC.getInterfaceBoxTypeForCapture(VD, minimalLoweredTy.getASTType(),
2014-
/*mutable*/ false);
2017+
auto boxTy = TC.getInterfaceBoxTypeForCapture(
2018+
varDecl, minimalLoweredTy.getASTType(),
2019+
/*mutable*/ false);
20152020
auto convention = ParameterConvention::Direct_Guaranteed;
2016-
auto param = SILParameterInfo(boxTy, convention);
2021+
auto param = SILParameterInfo(boxTy, convention, options);
20172022
inputs.push_back(param);
20182023
break;
20192024
}
20202025
case CaptureKind::StorageAddress: {
20212026
// Non-escaping lvalues are captured as the address of the value.
20222027
SILType ty = loweredTy.getAddressType();
2023-
auto param =
2024-
SILParameterInfo(ty.getASTType(),
2025-
ParameterConvention::Indirect_InoutAliasable);
2028+
auto param = SILParameterInfo(
2029+
ty.getASTType(), ParameterConvention::Indirect_InoutAliasable,
2030+
options);
20262031
inputs.push_back(param);
20272032
break;
20282033
}
20292034
case CaptureKind::Immutable: {
20302035
// 'let' constants that are address-only are captured as the address of
20312036
// the value and will be consumed by the closure.
20322037
SILType ty = loweredTy.getAddressType();
2033-
auto param =
2034-
SILParameterInfo(ty.getASTType(),
2035-
ParameterConvention::Indirect_In_Guaranteed);
2038+
auto param = SILParameterInfo(ty.getASTType(),
2039+
ParameterConvention::Indirect_In_Guaranteed,
2040+
options);
20362041
inputs.push_back(param);
20372042
break;
20382043
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %target-swift-frontend -emit-silgen %s -module-name test -swift-version 5 | %FileCheck %s
2+
3+
// REQUIRES: concurrency
4+
5+
class NonSendableKlass {}
6+
7+
func useValue<T>(_ t: T) {}
8+
9+
@MainActor func transferToMain<T>(_ t: T) async {}
10+
11+
actor MyActor {
12+
var ns = NonSendableKlass()
13+
14+
// CHECK-LABEL: sil hidden [ossa] @$s4test7MyActorC19passSelfIntoClosureyyYaF : $@convention(method) @async (@sil_isolated @guaranteed MyActor) -> () {
15+
// CHECK: bb0([[ARG:%.*]] : @guaranteed $
16+
// CHECK: [[COPY:%.*]] = copy_value [[ARG]]
17+
// CHECK: [[PAI:%.*]] = partial_apply [callee_guaranteed] {{.*}}([[COPY]]) : $@convention(thin) (@sil_isolated @guaranteed MyActor) -> ()
18+
// CHECK: } // end sil function '$s4test7MyActorC19passSelfIntoClosureyyYaF'
19+
func passSelfIntoClosure() async {
20+
let closure = { useValue(self.ns) }
21+
await transferToMain(closure)
22+
}
23+
}

0 commit comments

Comments
 (0)