Skip to content

Commit c082cf6

Browse files
authored
Merge pull request swiftlang#35853 from jckarter/enum-case-witness-default-conventions-5.4
[5.4] SIL: Pick default ARC convention for enum case witness thunks based on the kind of the original decl.
2 parents 44e4285 + 1e2992f commit c082cf6

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2485,7 +2485,22 @@ static CanSILFunctionType getNativeSILFunctionType(
24852485
case SILFunctionType::Representation::Method:
24862486
case SILFunctionType::Representation::Closure:
24872487
case SILFunctionType::Representation::WitnessMethod: {
2488-
switch (constant ? constant->kind : SILDeclRef::Kind::Func) {
2488+
// FIXME: We should use origConstant unconditionally here, since in the
2489+
// case of protocol witness thunk type lowering, we want to lower the
2490+
// witness's calling convention according to the convention of the protocol
2491+
// requirement, even if the witness has a different kind. Previously we
2492+
// would base this on the witness `constant`, and this worked because
2493+
// witnesses had always been the same decl kind as the requirement, but
2494+
// enum cases as static witnesses broke this invariant.
2495+
//
2496+
// To minimize the change in behavior for Swift 5.4, we only consider
2497+
// origConstant when constant is an EnumElement, to avoid affecting other
2498+
// potential corner cases I'm not thinking of in the moment.
2499+
auto constantToTest = constant;
2500+
if (constant && constant->kind == SILDeclRef::Kind::EnumElement) {
2501+
constantToTest = origConstant;
2502+
}
2503+
switch (constantToTest ? constantToTest->kind : SILDeclRef::Kind::Func) {
24892504
case SILDeclRef::Kind::Initializer:
24902505
case SILDeclRef::Kind::EnumElement:
24912506
return getSILFunctionTypeForConventions(DefaultInitializerConventions());

test/SILGen/enum_witness_thunks.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
3+
class C {}
4+
5+
protocol P {
6+
static func c(_: C) -> Self
7+
}
8+
9+
enum E: P {
10+
case c(C)
11+
}
12+
13+
// CHECK-LABEL: sil {{.*}} @$s19enum_witness_thunks1EOAA1PA2aDP1cyxAA1CCFZTW : $@convention(witness_method: P) (@guaranteed C, @thick E.Type) -> @out E
14+
// CHECK: [[COPY:%.*]] = copy_value
15+
// CHECK: apply {{.*}}([[COPY]]

0 commit comments

Comments
 (0)