Skip to content

Commit 2d5dd75

Browse files
committed
[concurrency] Make sure that TypeLowering inserts the extra actor parameter for @execution(caller) parameters.
Previously, we handled cases where we had an actual SILDeclRef constant (e.x.: an actual function ref), but we did not handle cases where we did not have a constant but instead just had a FunctionTypeIsolation. We now handle that correctly.
1 parent a94727d commit 2d5dd75

File tree

3 files changed

+58
-4
lines changed

3 files changed

+58
-4
lines changed

include/swift/AST/ActorIsolation.h

+4
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ class ActorIsolation {
233233

234234
bool isDistributedActor() const;
235235

236+
bool isCallerIsolationInheriting() const {
237+
return getKind() == CallerIsolationInheriting;
238+
}
239+
236240
Type getGlobalActor() const {
237241
assert(isGlobalActor());
238242

lib/SIL/IR/SILFunctionType.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -1662,8 +1662,7 @@ class DestructureInputs {
16621662

16631663
// If we are an async function that is unspecified or nonisolated, insert an
16641664
// isolated parameter if AsyncCallerExecution is enabled.
1665-
if (IsolationInfo &&
1666-
IsolationInfo->getKind() == ActorIsolation::CallerIsolationInheriting &&
1665+
if (IsolationInfo && IsolationInfo->isCallerIsolationInheriting() &&
16671666
extInfoBuilder.isAsync()) {
16681667
auto actorProtocol = TC.Context.getProtocol(KnownProtocolKind::Actor);
16691668
auto actorType =
@@ -2584,6 +2583,13 @@ static CanSILFunctionType getSILFunctionType(
25842583
actorIsolation =
25852584
getActorIsolationOfContext(constant->getInnermostDeclContext());
25862585
}
2586+
} else if (substFnInterfaceType->hasExtInfo() &&
2587+
substFnInterfaceType->getExtInfo()
2588+
.getIsolation()
2589+
.isNonIsolatedCaller()) {
2590+
// If our function type is a nonisolated caller and we can not infer from
2591+
// our constant, we must be caller isolation inheriting.
2592+
actorIsolation = ActorIsolation::forCallerIsolationInheriting();
25872593
}
25882594
DestructureInputs destructurer(expansionContext, TC, conventions,
25892595
foreignInfo, actorIsolation, inputs,

test/SILGen/execution_attr.swift

+46-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %target-swift-emit-silgen %s -enable-experimental-feature ExecutionAttribute | %FileCheck %s
2-
// RUN: %target-swift-emit-silgen %s -enable-experimental-feature ExecutionAttribute -enable-experimental-feature AsyncCallerExecution | %FileCheck %s
1+
// RUN: %target-swift-emit-silgen %s -enable-experimental-feature ExecutionAttribute | %FileCheck -check-prefix CHECK -check-prefix DISABLED %s
2+
// RUN: %target-swift-emit-silgen %s -enable-experimental-feature ExecutionAttribute -enable-experimental-feature AsyncCallerExecution | %FileCheck -check-prefix CHECK -check-prefix ENABLED %s
33

44
// REQUIRES: concurrency
55
// REQUIRES: asserts
@@ -20,3 +20,47 @@ func executionCaller() async {}
2020
// CHECK: sil hidden [ossa] @$s14execution_attr0A10ConcurrentyyYaF : $@convention(thin) @async () -> () {
2121
@execution(concurrent)
2222
func executionConcurrent() async {}
23+
24+
// DISABLED: sil hidden [ossa] @$s14execution_attr0A15CallerParameteryyyyYaYCXEYaF : $@convention(thin) @async (@guaranteed @noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> () {
25+
// ENABLED: sil hidden [ossa] @$s14execution_attr0A15CallerParameteryyyyYaYCXEYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed @noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> ()) -> () {
26+
// CHECK: } // end sil function '$s14execution_attr0A15CallerParameteryyyyYaYCXEYaF'
27+
func executionCallerParameter(_ x: @execution(caller) () async -> ()) async {
28+
await x()
29+
}
30+
31+
// DISABLED-LABEL: sil hidden [ossa] @$s14execution_attr0A19ConcurrentParameteryyyyYaXEYaF : $@convention(thin) @async (@guaranteed @noescape @async @callee_guaranteed () -> ()) -> () {
32+
// ENABLED-LABEL: sil hidden [ossa] @$s14execution_attr0A19ConcurrentParameteryyyyYaXEYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed @noescape @async @callee_guaranteed () -> ()) -> () {
33+
func executionConcurrentParameter(_ x: @execution(concurrent) () async -> ()) async {
34+
await x()
35+
}
36+
37+
struct S {
38+
let field: @execution(caller) () async -> ()
39+
}
40+
41+
// DISABLED: sil hidden [ossa] @$s14execution_attr0A11CallerFieldyyAA1SVYaF : $@convention(thin) @async (@guaranteed S) -> () {
42+
// DISABLED: bb0([[ARG:%.*]] : @guaranteed $S):
43+
// DISABLED: [[FIELD:%.*]] = struct_extract [[ARG]]
44+
// DISABLED: [[FIELD_COPY:%.*]] = copy_value [[FIELD]]
45+
// DISABLED: [[ACTOR_NONE:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
46+
// DISABLED: [[BORROWED_FIELD:%.*]] = begin_borrow [[FIELD_COPY]]
47+
// DISABLED: apply [[BORROWED_FIELD]]([[ACTOR_NONE]])
48+
// DISABLED: } // end sil function '$s14execution_attr0A11CallerFieldyyAA1SVYaF'
49+
50+
// ENABLED: sil hidden [ossa] @$s14execution_attr0A11CallerFieldyyAA1SVYaF : $@convention(thin) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @guaranteed S) -> () {
51+
// ENABLED: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[ARG:%.*]] : @guaranteed $S):
52+
// ENABLED: [[FIELD:%.*]] = struct_extract [[ARG]]
53+
// ENABLED: [[FIELD_COPY:%.*]] = copy_value [[FIELD]]
54+
// ENABLED: [[BORROWED_FIELD:%.*]] = begin_borrow [[FIELD_COPY]]
55+
// ENABLED: apply [[BORROWED_FIELD]]([[ACTOR]])
56+
// ENABLED: } // end sil function '$s14execution_attr0A11CallerFieldyyAA1SVYaF'
57+
func executionCallerField(_ s: S) async {
58+
await s.field()
59+
}
60+
61+
extension S {
62+
// CHECK-LABEL: // S.executionCallerFieldMethod(_:)
63+
// CHECK: // Isolation: unspecified
64+
// CHECK: sil hidden [ossa] @$s14execution_attr1SV0A17CallerFieldMethodyyyyYaYCXEF : $@convention(method) (@guaranteed @noescape @async @callee_guaranteed (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>) -> (), @guaranteed S) -> () {
65+
func executionCallerFieldMethod(_ x: @execution(caller) () async -> ()) {}
66+
}

0 commit comments

Comments
 (0)