Skip to content

Commit b697b2c

Browse files
authored
Merge pull request #21394 from slavapestov/enum-curry-thunk-regression
SILGen: Fix partial application of enum case with one-element labeled tuple
2 parents 4b95ca8 + 396007d commit b697b2c

File tree

3 files changed

+52
-38
lines changed

3 files changed

+52
-38
lines changed

lib/SILGen/RValue.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,13 +318,8 @@ static void copyOrInitValuesInto(Initialization *init,
318318
KIND == ImplodeKind::Copy, "Not handled by init");
319319
bool isInit = (KIND == ImplodeKind::Forward);
320320

321-
// First, unwrap one-element tuples, since we cannot lower them.
322-
auto tupleType = dyn_cast<TupleType>(type);
323-
if (tupleType && tupleType->getNumElements() == 1)
324-
type = tupleType.getElementType(0);
325-
326321
// If the element has non-tuple type, just serve it up to the initialization.
327-
tupleType = dyn_cast<TupleType>(type);
322+
auto tupleType = dyn_cast<TupleType>(type);
328323
if (!tupleType) {
329324
// We take the first value.
330325
ManagedValue result = values[0];

test/SILGen/enum_curry_thunks.swift

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: %target-swift-emit-silgen -parse-as-library %s | %FileCheck %s
2+
3+
enum PartialApplyEnumPayload<T, U> {
4+
case Left(T)
5+
case Both(T, U)
6+
7+
case LeftWithLabel(left: T)
8+
case BothWithLabel(left: T, right: U)
9+
10+
case TupleWithLabel(both: (T, U))
11+
12+
// Note: SILGen can emit these thunks correctly, but we disabled
13+
// the feature since calling the constructor directly (without a
14+
// thunk) doesn't work yet.
15+
/* case Variadic(_: Int...)
16+
case VariadicWithLabel(indices: Int...)
17+
case VariadicTuple(_: (Int, Int)...)
18+
case VariadicWithOther(String, _: Int...) */
19+
20+
case Autoclosure(@autoclosure () -> ())
21+
}
22+
23+
struct S {}
24+
struct C {}
25+
26+
func partialApplyEnumCases(_ x: S, y: C) {
27+
_ = PartialApplyEnumPayload<S, C>.Left
28+
_ = PartialApplyEnumPayload<S, C>.Both
29+
_ = PartialApplyEnumPayload<S, C>.LeftWithLabel
30+
_ = PartialApplyEnumPayload<S, C>.TupleWithLabel
31+
/* _ = PartialApplyEnumPayload<S, C>.Variadic
32+
_ = PartialApplyEnumPayload<S, C>.VariadicWithLabel
33+
_ = PartialApplyEnumPayload<S, C>.VariadicTuple
34+
_ = PartialApplyEnumPayload<S, C>.VariadicWithOther */
35+
_ = PartialApplyEnumPayload<S, C>.Autoclosure
36+
}
37+
38+
// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4LeftyACyxq_GxcAEmr0_lFTc : $@convention(thin) <T, U> (@thin PartialApplyEnumPayload<T, U>.Type) -> @owned @callee_guaranteed (@in_guaranteed T) -> @out PartialApplyEnumPayload<T, U> {
39+
// CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4LeftyACyxq_GxcAEmr0_lF : $@convention(method) <T, U> (@in T, @thin PartialApplyEnumPayload<T, U>.Type) -> @out PartialApplyEnumPayload<T, U> {
40+
41+
// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4BothyACyxq_Gx_q_tcAEmr0_lFTc : $@convention(thin) <T, U> (@thin PartialApplyEnumPayload<T, U>.Type) -> @owned @callee_guaranteed (@in_guaranteed T, @in_guaranteed U) -> @out PartialApplyEnumPayload<T, U> {
42+
// CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4BothyACyxq_Gx_q_tcAEmr0_lF : $@convention(method) <T, U> (@in T, @in U, @thin PartialApplyEnumPayload<T, U>.Type) -> @out PartialApplyEnumPayload<T, U> {
43+
44+
// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO13LeftWithLabelyACyxq_Gx_tcAEmr0_lFTc : $@convention(thin) <T, U> (@thin PartialApplyEnumPayload<T, U>.Type) -> @owned @callee_guaranteed (@in_guaranteed T) -> @out PartialApplyEnumPayload<T, U> {
45+
// CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO13LeftWithLabelyACyxq_Gx_tcAEmr0_lF : $@convention(method) <T, U> (@in T, @thin PartialApplyEnumPayload<T, U>.Type) -> @out PartialApplyEnumPayload<T, U> {
46+
47+
// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO14TupleWithLabelyACyxq_Gx_q_t_tcAEmr0_lFTc : $@convention(thin) <T, U> (@thin PartialApplyEnumPayload<T, U>.Type) -> @owned @callee_guaranteed (@in_guaranteed T, @in_guaranteed U) -> @out PartialApplyEnumPayload<T, U> {
48+
// CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO14TupleWithLabelyACyxq_Gx_q_t_tcAEmr0_lF : $@convention(method) <T, U> (@in T, @in U, @thin PartialApplyEnumPayload<T, U>.Type) -> @out PartialApplyEnumPayload<T, U> {
49+
50+
// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO11AutoclosureyACyxq_GyyXAcAEmr0_lFTc : $@convention(thin) <T, U> (@thin PartialApplyEnumPayload<T, U>.Type) -> @owned @callee_guaranteed (@guaranteed @callee_guaranteed () -> ()) -> @out PartialApplyEnumPayload<T, U> {
51+
// CHECK-LABEL: sil shared [transparent] [ossa] @$s17enum_curry_thunks23PartialApplyEnumPayloadO11AutoclosureyACyxq_GyyXAcAEmr0_lF : $@convention(method) <T, U> (@owned @callee_guaranteed () -> (), @thin PartialApplyEnumPayload<T, U>.Type) -> @out PartialApplyEnumPayload<T, U> {

test/SILGen/functions.swift

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -522,35 +522,3 @@ func testNoescape2() {
522522

523523
// CHECK: // closure #1 () -> () in closure #1 () -> () in functions.testNoescape2() -> ()
524524
// CHECK-NEXT: sil private [ossa] @$s9functions13testNoescape2yyFyyXEfU_yycfU_ : $@convention(thin) (@guaranteed { var Int }) -> () {
525-
526-
enum PartialApplyEnumPayload<T, U> {
527-
case Left(T)
528-
case Right(U)
529-
}
530-
531-
struct S {}
532-
struct C {}
533-
534-
func partialApplyEnumCases(_ x: S, y: C) {
535-
let left = PartialApplyEnumPayload<S, C>.Left
536-
let left2 = left(S())
537-
538-
let right = PartialApplyEnumPayload<S, C>.Right
539-
let right2 = right(C())
540-
}
541-
542-
// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s9functions23PartialApplyEnumPayloadO4Left{{[_0-9a-zA-Z]*}}F
543-
// CHECK: [[UNCURRIED:%.*]] = function_ref @$s9functions23PartialApplyEnumPayloadO4Left{{[_0-9a-zA-Z]*}}F
544-
// CHECK: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[UNCURRIED]]<T, U>(%0)
545-
// CHECK: [[CANONICAL_THUNK:%.*]] = function_ref @$sx9functions23PartialApplyEnumPayloadOyxq_GIegir_xADIegnr_r0_lTR : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ_0_0, @guaranteed @callee_guaranteed (@in τ_0_0) -> @out PartialApplyEnumPayload<τ_0_0, τ_0_1>) -> @out PartialApplyEnumPayload<τ_0_0, τ_0_1>
546-
// CHECK: [[THUNKED_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CANONICAL_THUNK]]<T, U>([[CLOSURE]])
547-
// CHECK: return [[THUNKED_CLOSURE]]
548-
// CHECK: } // end sil function '$s9functions23PartialApplyEnumPayloadO4Left{{[_0-9a-zA-Z]*}}F'
549-
550-
// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$s9functions23PartialApplyEnumPayloadO5Right{{[_0-9a-zA-Z]*}}F
551-
// CHECK: [[UNCURRIED:%.*]] = function_ref @$s9functions23PartialApplyEnumPayloadO5Right{{[_0-9a-zA-Z]*}}F
552-
// CHECK: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[UNCURRIED]]<T, U>(%0)
553-
// CHECK: [[CANONICAL_THUNK:%.*]] = function_ref @$sq_9functions23PartialApplyEnumPayloadOyxq_GIegir_q_ADIegnr_r0_lTR : $@convention(thin) <τ_0_0, τ_0_1> (@in_guaranteed τ_0_1, @guaranteed @callee_guaranteed (@in τ_0_1) -> @out PartialApplyEnumPayload<τ_0_0, τ_0_1>) -> @out PartialApplyEnumPayload<τ_0_0, τ_0_1>
554-
// CHECK: [[THUNKED_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CANONICAL_THUNK]]<T, U>([[CLOSURE]])
555-
// CHECK: return [[THUNKED_CLOSURE]]
556-
// CHECK: } // end sil function '$s9functions23PartialApplyEnumPayloadO5Right{{[_0-9a-zA-Z]*}}F'

0 commit comments

Comments
 (0)