Merge pull request #21396 from slavapestov/enum-curry-thunk-regression-5.0
SILGen: Fix partial application of enum case with one-element labeled tuple [5.0]
diff --git a/lib/SILGen/RValue.cpp b/lib/SILGen/RValue.cpp
index b38b284..98ed559 100644
--- a/lib/SILGen/RValue.cpp
+++ b/lib/SILGen/RValue.cpp
@@ -318,13 +318,8 @@
KIND == ImplodeKind::Copy, "Not handled by init");
bool isInit = (KIND == ImplodeKind::Forward);
- // First, unwrap one-element tuples, since we cannot lower them.
- auto tupleType = dyn_cast<TupleType>(type);
- if (tupleType && tupleType->getNumElements() == 1)
- type = tupleType.getElementType(0);
-
// If the element has non-tuple type, just serve it up to the initialization.
- tupleType = dyn_cast<TupleType>(type);
+ auto tupleType = dyn_cast<TupleType>(type);
if (!tupleType) {
// We take the first value.
ManagedValue result = values[0];
diff --git a/test/SILGen/enum_curry_thunks.swift b/test/SILGen/enum_curry_thunks.swift
new file mode 100644
index 0000000..f897085
--- /dev/null
+++ b/test/SILGen/enum_curry_thunks.swift
@@ -0,0 +1,51 @@
+// RUN: %target-swift-emit-silgen -parse-as-library %s | %FileCheck %s
+
+enum PartialApplyEnumPayload<T, U> {
+ case Left(T)
+ case Both(T, U)
+
+ case LeftWithLabel(left: T)
+ case BothWithLabel(left: T, right: U)
+
+ case TupleWithLabel(both: (T, U))
+
+ // Note: SILGen can emit these thunks correctly, but we disabled
+ // the feature since calling the constructor directly (without a
+ // thunk) doesn't work yet.
+ /* case Variadic(_: Int...)
+ case VariadicWithLabel(indices: Int...)
+ case VariadicTuple(_: (Int, Int)...)
+ case VariadicWithOther(String, _: Int...) */
+
+ case Autoclosure(@autoclosure () -> ())
+}
+
+struct S {}
+struct C {}
+
+func partialApplyEnumCases(_ x: S, y: C) {
+ _ = PartialApplyEnumPayload<S, C>.Left
+ _ = PartialApplyEnumPayload<S, C>.Both
+ _ = PartialApplyEnumPayload<S, C>.LeftWithLabel
+ _ = PartialApplyEnumPayload<S, C>.TupleWithLabel
+ /* _ = PartialApplyEnumPayload<S, C>.Variadic
+ _ = PartialApplyEnumPayload<S, C>.VariadicWithLabel
+ _ = PartialApplyEnumPayload<S, C>.VariadicTuple
+ _ = PartialApplyEnumPayload<S, C>.VariadicWithOther */
+ _ = PartialApplyEnumPayload<S, C>.Autoclosure
+}
+
+// CHECK-LABEL: sil shared [transparent] [thunk] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4LeftyACyxq_GxcAEmr0_lFTc : $@convention(thin) <T, U> (@thin PartialApplyEnumPayload<T, U>.Type) -> @owned @callee_guaranteed (@in_guaranteed T) -> @out PartialApplyEnumPayload<T, U> {
+// CHECK-LABEL: sil shared [transparent] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4LeftyACyxq_GxcAEmr0_lF : $@convention(method) <T, U> (@in T, @thin PartialApplyEnumPayload<T, U>.Type) -> @out PartialApplyEnumPayload<T, U> {
+
+// CHECK-LABEL: sil shared [transparent] [thunk] @$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> {
+// CHECK-LABEL: sil shared [transparent] @$s17enum_curry_thunks23PartialApplyEnumPayloadO4BothyACyxq_Gx_q_tcAEmr0_lF : $@convention(method) <T, U> (@in T, @in U, @thin PartialApplyEnumPayload<T, U>.Type) -> @out PartialApplyEnumPayload<T, U> {
+
+// CHECK-LABEL: sil shared [transparent] [thunk] @$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> {
+// CHECK-LABEL: sil shared [transparent] @$s17enum_curry_thunks23PartialApplyEnumPayloadO13LeftWithLabelyACyxq_Gx_tcAEmr0_lF : $@convention(method) <T, U> (@in T, @thin PartialApplyEnumPayload<T, U>.Type) -> @out PartialApplyEnumPayload<T, U> {
+
+// CHECK-LABEL: sil shared [transparent] [thunk] @$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> {
+// CHECK-LABEL: sil shared [transparent] @$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> {
+
+// CHECK-LABEL: sil shared [transparent] [thunk] @$s17enum_curry_thunks23PartialApplyEnumPayloadO11AutoclosureyACyxq_GyyXAcAEmr0_lFTc : $@convention(thin) <T, U> (@thin PartialApplyEnumPayload<T, U>.Type) -> @owned @callee_guaranteed (@guaranteed @callee_guaranteed () -> ()) -> @out PartialApplyEnumPayload<T, U> {
+// CHECK-LABEL: sil shared [transparent] @$s17enum_curry_thunks23PartialApplyEnumPayloadO11AutoclosureyACyxq_GyyXAcAEmr0_lF : $@convention(method) <T, U> (@owned @callee_guaranteed () -> (), @thin PartialApplyEnumPayload<T, U>.Type) -> @out PartialApplyEnumPayload<T, U> {
diff --git a/test/SILGen/functions.swift b/test/SILGen/functions.swift
index ead4e21..8a8feb6 100644
--- a/test/SILGen/functions.swift
+++ b/test/SILGen/functions.swift
@@ -522,35 +522,3 @@
// CHECK: // closure #1 () -> () in closure #1 () -> () in functions.testNoescape2() -> ()
// CHECK-NEXT: sil private @$s9functions13testNoescape2yyFyyXEfU_yycfU_ : $@convention(thin) (@guaranteed { var Int }) -> () {
-
-enum PartialApplyEnumPayload<T, U> {
- case Left(T)
- case Right(U)
-}
-
-struct S {}
-struct C {}
-
-func partialApplyEnumCases(_ x: S, y: C) {
- let left = PartialApplyEnumPayload<S, C>.Left
- let left2 = left(S())
-
- let right = PartialApplyEnumPayload<S, C>.Right
- let right2 = right(C())
-}
-
-// CHECK-LABEL: sil shared [transparent] [thunk] @$s9functions23PartialApplyEnumPayloadO4Left{{[_0-9a-zA-Z]*}}F
-// CHECK: [[UNCURRIED:%.*]] = function_ref @$s9functions23PartialApplyEnumPayloadO4Left{{[_0-9a-zA-Z]*}}F
-// CHECK: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[UNCURRIED]]<T, U>(%0)
-// 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>
-// CHECK: [[THUNKED_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CANONICAL_THUNK]]<T, U>([[CLOSURE]])
-// CHECK: return [[THUNKED_CLOSURE]]
-// CHECK: } // end sil function '$s9functions23PartialApplyEnumPayloadO4Left{{[_0-9a-zA-Z]*}}F'
-
-// CHECK-LABEL: sil shared [transparent] [thunk] @$s9functions23PartialApplyEnumPayloadO5Right{{[_0-9a-zA-Z]*}}F
-// CHECK: [[UNCURRIED:%.*]] = function_ref @$s9functions23PartialApplyEnumPayloadO5Right{{[_0-9a-zA-Z]*}}F
-// CHECK: [[CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[UNCURRIED]]<T, U>(%0)
-// 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>
-// CHECK: [[THUNKED_CLOSURE:%.*]] = partial_apply [callee_guaranteed] [[CANONICAL_THUNK]]<T, U>([[CLOSURE]])
-// CHECK: return [[THUNKED_CLOSURE]]
-// CHECK: } // end sil function '$s9functions23PartialApplyEnumPayloadO5Right{{[_0-9a-zA-Z]*}}F'