Skip to content

Commit 4804616

Browse files
committed
Fix an edge case in ExistentialSpecializer
ExistentialSpecializer could be building the function type from a witness_method. We cannot attach a witnessProtocolConformance to the newly specialized thin function.
1 parent 9bde41a commit 4804616

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

lib/SILOptimizer/FunctionSignatureTransforms/ExistentialTransform.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,15 +376,14 @@ ExistentialTransform::createExistentialSpecializedFunctionType() {
376376
/// Finally the ExtInfo.
377377
auto ExtInfo = FTy->getExtInfo();
378378
ExtInfo = ExtInfo.withRepresentation(SILFunctionTypeRepresentation::Thin);
379-
auto witnessMethodConformance = FTy->getWitnessMethodConformanceOrInvalid();
380379

381380
/// Return the new signature.
382381
return SILFunctionType::get(
383382
NewGenericSig, ExtInfo, FTy->getCoroutineKind(),
384383
FTy->getCalleeConvention(), InterfaceParams, FTy->getYields(),
385384
FTy->getResults(), InterfaceErrorResult,
386385
SubstitutionMap(), SubstitutionMap(),
387-
Ctx, witnessMethodConformance);
386+
Ctx);
388387
}
389388

390389
/// Create the Thunk Body with always_inline attribute.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %target-swift-frontend -O -Xllvm -sil-disable-pass=GenericSpecializer -Xllvm -sil-disable-pass=EarlyInliner -Xllvm -sil-disable-pass=PerfInliner -Xllvm -sil-disable-pass=LateInliner -emit-sil -sil-verify-all %s | %FileCheck %s
2+
3+
// Test for ExistentialSpecializer when an existential type is passed to a witness_method func representation
4+
protocol P {
5+
@inline(never)
6+
func myfuncP(_ q:Q) -> Int
7+
}
8+
9+
protocol Q {
10+
@inline(never)
11+
func myfuncQ() -> Int
12+
}
13+
14+
class C : P {
15+
var id = 10
16+
@inline(never)
17+
func myfuncP(_ q:Q) -> Int {
18+
return id
19+
}
20+
}
21+
22+
class D : Q {
23+
var id = 20
24+
@inline(never)
25+
func myfuncQ() -> Int {
26+
return id
27+
}
28+
}
29+
30+
// CHECK-LABEL: @$s30existential_spl_witness_method1CCAA1PA2aDP7myfuncPySiAA1Q_pFTW : $@convention(witness_method: P) (@in_guaranteed Q, @in_guaranteed C) -> Int {
31+
// CHECK: [[FR1:%.*]] = function_ref @$s30existential_spl_witness_method1CCAA1PA2aDP7myfuncPySiAA1Q_pFTWTf4en_n : $@convention(thin) <τ_0_0 where τ_0_0 : Q> (@in_guaranteed τ_0_0, @in_guaranteed C) -> Int
32+
// CHECK: apply [[FR1]]
33+
// CHECK-LABEL: } // end sil function '$s30existential_spl_witness_method1CCAA1PA2aDP7myfuncPySiAA1Q_pFTW'
34+
35+
// CHECK-LABEL : @$s30existential_spl_witness_method3bazyyAA1P_p_AA1Q_ptFTf4ee_n : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : Q> (@in_guaranteed τ_0_0, @in_guaranteed τ_0_1) -> () {
36+
// CHECK: [[FR2:%.*]] = function_ref @$s30existential_spl_witness_method1CCAA1PA2aDP7myfuncPySiAA1Q_pFTW : $@convention(witness_method: P) (@in_guaranteed Q, @in_guaranteed C) -> Int
37+
// CHECK: apply [[FR2]]
38+
// CHECK-LABEL: } // end sil function '$s30existential_spl_witness_method3bazyyAA1P_p_AA1Q_ptFTf4ee_n'
39+
@inline(never)
40+
func baz(_ p : P, _ q : Q) {
41+
p.myfuncP(q)
42+
}
43+
44+
baz(C(), D());
45+

0 commit comments

Comments
 (0)