Merge pull request #21156 from slavapestov/single-tuple-argument-again-5.0

Runtime: Fix metatype to mangling of function with single tuple-typed argument [5.0]
diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp
index 940d926..fd2f0e2 100644
--- a/lib/AST/ASTMangler.cpp
+++ b/lib/AST/ASTMangler.cpp
@@ -1767,9 +1767,8 @@
     const auto &param = params.front();
     auto type = param.getPlainType();
 
-    // If this is just a single parenthesized type,
-    // to save space in the mangled name, let's encode
-    // it as a single type dropping sugar.
+    // If the sole unlabeled parameter has a non-tuple type, encode
+    // the parameter list as a single type.
     if (!param.hasLabel() && !param.isVariadic() &&
         !isa<TupleType>(type.getPointer())) {
       appendTypeListElement(Identifier(), type, param.getParameterFlags());
diff --git a/stdlib/public/runtime/Demangle.cpp b/stdlib/public/runtime/Demangle.cpp
index 6fc743a..7b14ea3 100644
--- a/stdlib/public/runtime/Demangle.cpp
+++ b/stdlib/public/runtime/Demangle.cpp
@@ -495,14 +495,21 @@
     NodePointer totalInput = nullptr;
     switch (inputs.size()) {
     case 1: {
-      auto &singleParam = inputs.front();
+      auto singleParam = inputs.front();
+
+      // If the sole unlabeled parameter has a non-tuple type, encode
+      // the parameter list as a single type.
       if (!singleParam.second) {
-        totalInput = singleParam.first;
-        break;
+        auto singleType = singleParam.first;
+        if (singleType->getKind() == Node::Kind::Type)
+          singleType = singleType->getFirstChild();
+        if (singleType->getKind() != Node::Kind::Tuple) {
+          totalInput = singleParam.first;
+          break;
+        }
       }
 
-      // If single parameter has a variadic marker it
-      // requires a tuple wrapper.
+      // Otherwise it requires a tuple wrapper.
       LLVM_FALLTHROUGH;
     }
 
diff --git a/test/RemoteAST/structural_types.swift b/test/RemoteAST/structural_types.swift
index dad61d1..858f211 100644
--- a/test/RemoteAST/structural_types.swift
+++ b/test/RemoteAST/structural_types.swift
@@ -37,6 +37,14 @@
 printType(Fn8.self)
 // CHECK: found type: (String, Int, Double, Float) -> ()
 
+typealias Fn9 = ((Int, Float)) -> ()
+printType(Fn9.self)
+// CHECK: found type: ((Int, Float)) -> ()
+
+typealias Fn10 = (Int...) -> ()
+printType(Fn10.self)
+// CHECK: found type: (Int...) -> ()
+
 typealias Tuple1 = (Int, Float, Int)
 printType(Tuple1.self)
 // CHECK: found type: (Int, Float, Int)
diff --git a/test/stdlib/TypeName.swift b/test/stdlib/TypeName.swift
index 75cf1bb..debd0d6 100644
--- a/test/stdlib/TypeName.swift
+++ b/test/stdlib/TypeName.swift
@@ -59,11 +59,17 @@
   typealias F = () -> ()
   typealias F2 = () -> () -> ()
   typealias F3 = (() -> ()) -> ()
+  typealias F4 = (Int, Float) -> ()
+  typealias F5 = ((Int, Float)) -> ()
+  typealias F6 = (Int...) -> ()
 
   expectEqual("() -> ()", _typeName(F.self))
   expectEqual("() -> () -> ()", _typeName(F2.self))
   expectEqual("(() -> ()) -> ()", _typeName(F3.self))
   expectEqual("() -> ()", _typeName((() -> ()).self))
+  expectEqual("(Swift.Int, Swift.Float) -> ()", _typeName(F4.self))
+  expectEqual("((Swift.Int, Swift.Float)) -> ()", _typeName(F5.self))
+  expectEqual("(Swift.Int...) -> ()", _typeName(F6.self))
 
   expectEqual("(main.P) -> main.P2 & main.P3",
     _typeName(((P) -> P2 & P3).self))