Skip to content

Commit 70131a3

Browse files
committed
[Runtime] Fix printing keypaths with LocalDeclName subscript types.
We assumed a bit too much about the structure of a single-argument subscript demangle tree and assumed that the argument identifier node was always in the same place. If it wasn't, we'd try to get text from the wrong node and get a bogus StringRef. Verify the node kind before trying to extract text, and handle LocalDeclName nodes as well as Identifier nodes. rdar://129886558
1 parent d07e8ce commit 70131a3

File tree

2 files changed

+27
-6
lines changed

2 files changed

+27
-6
lines changed

lib/Demangling/NodePrinter.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3626,6 +3626,17 @@ std::string Demangle::keyPathSourceString(const char *MangledName,
36263626
return argumentTypeNames[i];
36273627
return std::string("<unknown>");
36283628
};
3629+
auto getArgumentNodeName = [](NodePointer node) {
3630+
if (node->getKind() == Node::Kind::Identifier) {
3631+
return std::string(node->getText());
3632+
}
3633+
if (node->getKind() == Node::Kind::LocalDeclName) {
3634+
auto text = node->getChild(1)->getText();
3635+
auto index = node->getChild(0)->getIndex() + 1;
3636+
return std::string(text) + " #" + std::to_string(index);
3637+
}
3638+
return std::string("<unknown>");
3639+
};
36293640
// Multiple arguments case
36303641
NodePointer argList = matchSequenceOfKinds(
36313642
child, {
@@ -3644,11 +3655,8 @@ std::string Demangle::keyPathSourceString(const char *MangledName,
36443655
if (argumentType->getKind() == Node::Kind::TupleElement) {
36453656
argumentType =
36463657
argumentType->getChild(0)->getChild(0)->getChild(1);
3647-
if (argumentType->getKind() == Node::Kind::Identifier) {
3648-
argumentTypeNames.push_back(
3649-
std::string(argumentType->getText()));
3650-
continue;
3651-
}
3658+
argumentTypeNames.push_back(getArgumentNodeName(argumentType));
3659+
continue;
36523660
}
36533661
argumentTypeNames.push_back("<Unknown>");
36543662
}
@@ -3663,7 +3671,7 @@ std::string Demangle::keyPathSourceString(const char *MangledName,
36633671
});
36643672
if (argList != nullptr) {
36653673
argumentTypeNames.push_back(
3666-
std::string(argList->getChild(0)->getChild(1)->getText()));
3674+
getArgumentNodeName(argList->getChild(0)->getChild(1)));
36673675
}
36683676
}
36693677
child = child->getChild(1);

test/Interpreter/keypath.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,16 @@ do {
149149
// CHECK: 5
150150
print(Test(obj: "Hello").utf8.count)
151151
}
152+
153+
do {
154+
struct S1: Hashable {}
155+
struct S2 {
156+
subscript(param: S1) -> String { "Subscript with private type" }
157+
}
158+
159+
let kp = \S2[S1()]
160+
// CHECK: Subscript with private type
161+
print(S2()[keyPath: kp])
162+
// CHECK: \S2.subscript(_: S1 #{{[0-9]+}})
163+
print(kp)
164+
}

0 commit comments

Comments
 (0)