Skip to content

Commit 27cf336

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 (cherry picked from commit 39a013f)
1 parent d3145b2 commit 27cf336

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
@@ -2395,6 +2395,25 @@ std::optional<ActorIsolation>
23952395
swift::getSILFunctionTypeActorIsolation(CanAnyFunctionType substFnInterfaceType,
23962396
std::optional<SILDeclRef> origConstant,
23972397
std::optional<SILDeclRef> constant) {
2398+
// If we have origConstant then we are creating a protocol method thunk. In
2399+
// such a case, we want to use the origConstant's actor isolation.
2400+
if (origConstant && constant &&
2401+
*origConstant != *constant) {
2402+
if (auto *decl = origConstant->getAbstractFunctionDecl()) {
2403+
if (auto *nonisolatedAttr =
2404+
decl->getAttrs().getAttribute<NonisolatedAttr>()) {
2405+
if (nonisolatedAttr->isNonSending())
2406+
return ActorIsolation::forCallerIsolationInheriting();
2407+
}
2408+
2409+
if (decl->getAttrs().hasAttribute<ConcurrentAttr>()) {
2410+
return ActorIsolation::forNonisolated(false /*unsafe*/);
2411+
}
2412+
}
2413+
2414+
return getActorIsolationOfContext(origConstant->getInnermostDeclContext());
2415+
}
2416+
23982417
if (constant) {
23992418
// TODO: It should to be possible to `getActorIsolation` if
24002419
// 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)