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 ¶m = 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))