Skip to content

Commit 8c108bc

Browse files
committed
Runtime: Fix demangling of function with single tuple-typed argument
While declaration mangling now does the right thing for parameter lists, the function type mangling unfortunately still models the parameter list as a single tuple node. Change the runtime's behavior to match the AST mangler, which wraps a single tuple-typed parameter in a tuple node, so that we can produce different mangling trees for function types taking multiple arguments versus a single tuple argument.
1 parent c14e1a3 commit 8c108bc

File tree

3 files changed

+20
-8
lines changed

3 files changed

+20
-8
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1767,9 +1767,8 @@ void ASTMangler::appendFunctionInputType(
17671767
const auto &param = params.front();
17681768
auto type = param.getPlainType();
17691769

1770-
// If this is just a single parenthesized type,
1771-
// to save space in the mangled name, let's encode
1772-
// it as a single type dropping sugar.
1770+
// If the sole unlabeled parameter has a non-tuple type, encode
1771+
// the parameter list as a single type.
17731772
if (!param.hasLabel() && !param.isVariadic() &&
17741773
!isa<TupleType>(type.getPointer())) {
17751774
appendTypeListElement(Identifier(), type, param.getParameterFlags());

stdlib/public/runtime/Demangle.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -495,14 +495,21 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
495495
NodePointer totalInput = nullptr;
496496
switch (inputs.size()) {
497497
case 1: {
498-
auto &singleParam = inputs.front();
498+
auto singleParam = inputs.front();
499+
500+
// If the sole unlabeled parameter has a non-tuple type, encode
501+
// the parameter list as a single type.
499502
if (!singleParam.second) {
500-
totalInput = singleParam.first;
501-
break;
503+
auto singleType = singleParam.first;
504+
if (singleType->getKind() == Node::Kind::Type)
505+
singleType = singleType->getFirstChild();
506+
if (singleType->getKind() != Node::Kind::Tuple) {
507+
totalInput = singleParam.first;
508+
break;
509+
}
502510
}
503511

504-
// If single parameter has a variadic marker it
505-
// requires a tuple wrapper.
512+
// Otherwise it requires a tuple wrapper.
506513
LLVM_FALLTHROUGH;
507514
}
508515

test/stdlib/TypeName.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,17 @@ TypeNameTests.test("Prints") {
5959
typealias F = () -> ()
6060
typealias F2 = () -> () -> ()
6161
typealias F3 = (() -> ()) -> ()
62+
typealias F4 = (Int, Float) -> ()
63+
typealias F5 = ((Int, Float)) -> ()
64+
typealias F6 = (Int...) -> ()
6265

6366
expectEqual("() -> ()", _typeName(F.self))
6467
expectEqual("() -> () -> ()", _typeName(F2.self))
6568
expectEqual("(() -> ()) -> ()", _typeName(F3.self))
6669
expectEqual("() -> ()", _typeName((() -> ()).self))
70+
expectEqual("(Swift.Int, Swift.Float) -> ()", _typeName(F4.self))
71+
expectEqual("((Swift.Int, Swift.Float)) -> ()", _typeName(F5.self))
72+
expectEqual("(Swift.Int...) -> ()", _typeName(F6.self))
6773

6874
expectEqual("(main.P) -> main.P2 & main.P3",
6975
_typeName(((P) -> P2 & P3).self))

0 commit comments

Comments
 (0)