Skip to content

Commit 39a013f

Browse files
committed
[silgen] Place the correct isolation on protocol witness thunks.
We were using the isolation from the witness not from the requirement which we are supposed to do. The witness thunk thunks the isolation from the requirement to the witness so from an ABI perspective it should have the interface implied by the requirement's isolation since that is what callers of the witness method will expect. rdar://151394209
1 parent ff1cbea commit 39a013f

File tree

2 files changed

+27
-14
lines changed

2 files changed

+27
-14
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,6 +2390,25 @@ std::optional<ActorIsolation>
23902390
swift::getSILFunctionTypeActorIsolation(CanAnyFunctionType substFnInterfaceType,
23912391
std::optional<SILDeclRef> origConstant,
23922392
std::optional<SILDeclRef> constant) {
2393+
// If we have origConstant then we are creating a protocol method thunk. In
2394+
// such a case, we want to use the origConstant's actor isolation.
2395+
if (origConstant && constant &&
2396+
*origConstant != *constant) {
2397+
if (auto *decl = origConstant->getAbstractFunctionDecl()) {
2398+
if (auto *nonisolatedAttr =
2399+
decl->getAttrs().getAttribute<NonisolatedAttr>()) {
2400+
if (nonisolatedAttr->isNonSending())
2401+
return ActorIsolation::forCallerIsolationInheriting();
2402+
}
2403+
2404+
if (decl->getAttrs().hasAttribute<ConcurrentAttr>()) {
2405+
return ActorIsolation::forNonisolated(false /*unsafe*/);
2406+
}
2407+
}
2408+
2409+
return getActorIsolationOfContext(origConstant->getInnermostDeclContext());
2410+
}
2411+
23932412
if (constant) {
23942413
// TODO: It should to be possible to `getActorIsolation` if
23952414
// reference is to a decl instead of trying to get isolation

test/Concurrency/attr_execution/protocols_silgen.swift

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,17 @@ struct AllCaller : P {
4848
// CHECK: } // end sil function '$s21attr_execution_silgen9AllCallerVAA1PA2aDP10callerTestyyYaFTW'
4949
nonisolated(nonsending) func callerTest() async {}
5050

51-
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s21attr_execution_silgen9AllCallerVAA1PA2aDP14concurrentTestyyYaFTW : $@convention(witness_method: P) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @in_guaranteed AllCaller) -> () {
52-
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[SELF:%.*]] : $*AllCaller):
51+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s21attr_execution_silgen9AllCallerVAA1PA2aDP14concurrentTestyyYaFTW : $@convention(witness_method: P) @async (@in_guaranteed AllCaller) -> () {
52+
// CHECK: bb0([[SELF:%.*]] : $*AllCaller):
5353
// CHECK: [[LOAD:%.*]] = load [trivial] [[SELF]]
5454
// CHECK: [[FUNC:%.*]] = function_ref @$s21attr_execution_silgen9AllCallerV14concurrentTestyyYaF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, AllCaller) -> ()
5555
// CHECK: [[NIL:%.*]] = enum $Optional<any Actor>, #Optional.none!enumelt
5656
// CHECK: apply [[FUNC]]([[NIL]], [[LOAD]])
5757
// CHECK: } // end sil function '$s21attr_execution_silgen9AllCallerVAA1PA2aDP14concurrentTestyyYaFTW'
5858
nonisolated(nonsending) func concurrentTest() async {}
5959

60-
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s21attr_execution_silgen9AllCallerVAA1PA2aDP13mainActorTestyyYaFTW : $@convention(witness_method: P) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @in_guaranteed AllCaller) -> () {
61-
// CHECK: bb0({{%.*}} : @guaranteed $Optional<any Actor>, [[SELF:%.*]] : $*AllCaller):
60+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s21attr_execution_silgen9AllCallerVAA1PA2aDP13mainActorTestyyYaFTW : $@convention(witness_method: P) @async (@in_guaranteed AllCaller) -> () {
61+
// CHECK: bb0([[SELF:%.*]] : $*AllCaller):
6262
// CHECK: [[LOAD:%.*]] = load [trivial] [[SELF]]
6363
// CHECK: [[FUNC:%.*]] = function_ref @$s21attr_execution_silgen9AllCallerV13mainActorTestyyYaF : $@convention(method) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, AllCaller) -> ()
6464
// CHECK: [[MAIN_ACTOR:%.*]] = apply {{%.*}}({{%.*}}) : $@convention(method) (@thick MainActor.Type) -> @owned MainActor
@@ -70,11 +70,8 @@ struct AllCaller : P {
7070
}
7171

7272
struct AllConcurrent : P {
73-
// TODO: This seems wrong. We need to have our thunk have the implicit
74-
// isolated parameter from an ABI perspective.
75-
//
76-
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s21attr_execution_silgen13AllConcurrentVAA1PA2aDP10callerTestyyYaFTW : $@convention(witness_method: P) @async (@in_guaranteed AllConcurrent) -> () {
77-
// CHECK: bb0([[SELF:%.*]] :
73+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s21attr_execution_silgen13AllConcurrentVAA1PA2aDP10callerTestyyYaFTW : $@convention(witness_method: P) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @in_guaranteed AllConcurrent) -> () {
74+
// CHECK: bb0([[ACTOR]] : @guaranteed $Optional<any Actor>, [[SELF:%.*]] :
7875
// CHECK: [[LOAD:%.*]] = load [trivial] [[SELF]]
7976
// CHECK: [[FUNC:%.*]] = function_ref @$s21attr_execution_silgen13AllConcurrentV10callerTestyyYaF : $@convention(method) @async (AllConcurrent) -> ()
8077
// CHECK: apply [[FUNC]]([[LOAD]])
@@ -99,11 +96,8 @@ struct AllConcurrent : P {
9996
}
10097

10198
struct AllMainActor : P {
102-
// TODO: This is incorrect from an ABI perspective. The witness needs to have
103-
// the implicit isolated parameter.
104-
//
105-
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s21attr_execution_silgen12AllMainActorVAA1PA2aDP10callerTestyyYaFTW : $@convention(witness_method: P) @async (@in_guaranteed AllMainActor) -> () {
106-
// CHECK: bb0([[SELF:%.*]] :
99+
// CHECK-LABEL: sil private [transparent] [thunk] [ossa] @$s21attr_execution_silgen12AllMainActorVAA1PA2aDP10callerTestyyYaFTW : $@convention(witness_method: P) @async (@sil_isolated @sil_implicit_leading_param @guaranteed Optional<any Actor>, @in_guaranteed AllMainActor) -> () {
100+
// CHECK: bb0([[ACTOR:%.*]] : @guaranteed $Optional<any Actor>, [[SELF:%.*]] :
107101
// CHECK: [[LOAD:%.*]] = load [trivial] [[SELF]]
108102
// CHECK: [[FUNC:%.*]] = function_ref @$s21attr_execution_silgen12AllMainActorV10callerTestyyYaF : $@convention(method) @async (AllMainActor) -> ()
109103
// CHECK: apply [[FUNC]]([[LOAD]])

0 commit comments

Comments
 (0)