Skip to content

Commit e032d91

Browse files
committed
Runtime: Update _swift_buildDemanglingForMetadata() for subclass existentials
1 parent 06c3c99 commit e032d91

File tree

2 files changed

+37
-7
lines changed

2 files changed

+37
-7
lines changed

stdlib/public/runtime/Demangle.cpp

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,15 +149,42 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
149149
}
150150
case MetadataKind::Existential: {
151151
auto exis = static_cast<const ExistentialTypeMetadata *>(type);
152-
NodePointer proto_list = Dem.createNode(Node::Kind::ProtocolList);
153-
NodePointer type_list = Dem.createNode(Node::Kind::TypeList);
154-
155-
proto_list->addChild(type_list, Dem);
152+
NodePointer proto_list;
156153

157154
std::vector<const ProtocolDescriptor *> protocols;
158155
protocols.reserve(exis->Protocols.NumProtocols);
159156
for (unsigned i = 0, e = exis->Protocols.NumProtocols; i < e; ++i)
160157
protocols.push_back(exis->Protocols[i]);
158+
159+
if (exis->getSuperclassConstraint()) {
160+
// If there is a superclass constraint, we mangle it specially.
161+
proto_list = Dem.createNode(Node::Kind::ProtocolListWithClass);
162+
} else if (exis->isClassBounded()) {
163+
// Check if the class constraint is implied by any of our
164+
// protocols.
165+
bool requiresClassImplicit = false;
166+
167+
for (auto *protocol : protocols) {
168+
if (protocol->Flags.getClassConstraint()
169+
== ProtocolClassConstraint::Class)
170+
requiresClassImplicit = true;
171+
}
172+
173+
// If it was implied, we don't do anything special.
174+
if (requiresClassImplicit)
175+
proto_list = Dem.createNode(Node::Kind::ProtocolList);
176+
// If the existential type has an explicit AnyObject constraint,
177+
// we must mangle it as such.
178+
else
179+
proto_list = Dem.createNode(Node::Kind::ProtocolListWithAnyObject);
180+
} else {
181+
// Just a simple composition of protocols.
182+
proto_list = Dem.createNode(Node::Kind::ProtocolList);
183+
}
184+
185+
NodePointer type_list = Dem.createNode(Node::Kind::TypeList);
186+
187+
proto_list->addChild(type_list, Dem);
161188

162189
// Sort the protocols by their mangled names.
163190
// The ordering in the existential type metadata is by metadata pointer,
@@ -198,7 +225,12 @@ swift::_swift_buildDemanglingForMetadata(const Metadata *type,
198225
assert(protocolNode->getChild(0)->getKind() == Node::Kind::Protocol);
199226
type_list->addChild(protocolNode, Dem);
200227
}
201-
228+
229+
if (auto *superclass = exis->getSuperclassConstraint()) {
230+
auto superclassNode = _swift_buildDemanglingForMetadata(superclass, Dem);
231+
proto_list->addChild(superclassNode, Dem);
232+
}
233+
202234
return proto_list;
203235
}
204236
case MetadataKind::ExistentialMetatype: {

test/Interpreter/subclass_existentials.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,12 +163,10 @@ SubclassExistentialsTestSuite.test("Metadata instantiation") {
163163

164164
// FIXME: Not implemented yet
165165

166-
/*
167166
SubclassExistentialsTestSuite.test("Metadata to string") {
168167
expectEqual("Base<Int> & P", String(describing: ((Base<Int>) & P).self))
169168
expectEqual("Base<Int> & P & Q", String(describing: ((Base<Int>) & P & Q).self))
170169
}
171-
*/
172170

173171
SubclassExistentialsTestSuite.test("Call instance methods") {
174172
do {

0 commit comments

Comments
 (0)