Skip to content

Commit 0c9ab00

Browse files
committed
[Mangling] Disambiguate protocol-conformance-ref better
Fix to 510b64f. The mangling operator "HP" has to distinguish between "protocol" and "protocol module", not between the presence or absence of protocol-conformance-ref. New grammar: protocol-conformance-ref ::= protocol protocol-conformance-ref ::= protocol module 'HP' rdar://problem/46735592, again
1 parent f85bb3e commit 0c9ab00

File tree

5 files changed

+23
-13
lines changed

5 files changed

+23
-13
lines changed

docs/ABI/Mangling.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,8 @@ Property behaviors are implemented using private protocol conformances.
633633
::
634634

635635
concrete-protocol-conformance ::= type protocol-conformance-ref any-protocol-conformance-list 'HC'
636-
protocol-conformance-ref ::= protocol module? 'HP'
636+
protocol-conformance-ref ::= protocol
637+
protocol-conformance-ref ::= protocol module 'HP'
637638

638639
any-protocol-conformance ::= concrete-protocol-conformance
639640
any-protocol-conformance ::= dependent-protocol-conformance

lib/AST/ASTMangler.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2280,10 +2280,10 @@ void ASTMangler::appendProtocolConformanceRef(
22802280
// For retroactive conformances, add a reference to the module in which the
22812281
// conformance resides. For @objc protocols, there is no point: conformances
22822282
// are global anyway.
2283-
if (isRetroactiveConformance(conformance))
2283+
if (isRetroactiveConformance(conformance)) {
22842284
appendModule(conformance->getDeclContext()->getParentModule());
2285-
2286-
appendOperator("HP");
2285+
appendOperator("HP");
2286+
}
22872287
}
22882288

22892289
/// Retrieve the index of the conformance requirement indicated by the

lib/Demangling/Demangler.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,18 +1299,17 @@ NodePointer Demangler::demangleProtocolConformanceRef() {
12991299
NodePointer module = popModule();
13001300
NodePointer proto = popProtocol();
13011301
auto protocolConformanceRef =
1302-
createWithChild(Node::Kind::ProtocolConformanceRef, proto);
1303-
1304-
// The module is optional, present only for retroactive conformances. Add it
1305-
// as the second child.
1306-
if (protocolConformanceRef && module)
1307-
protocolConformanceRef->addChild(module, *this);
1302+
createWithChildren(Node::Kind::ProtocolConformanceRef, proto, module);
13081303
return protocolConformanceRef;
13091304
}
13101305

13111306
NodePointer Demangler::demangleConcreteProtocolConformance() {
13121307
NodePointer conditionalConformanceList = popAnyProtocolConformanceList();
13131308
NodePointer conformanceRef = popNode(Node::Kind::ProtocolConformanceRef);
1309+
if (!conformanceRef) {
1310+
NodePointer proto = popProtocol();
1311+
conformanceRef = createWithChild(Node::Kind::ProtocolConformanceRef, proto);
1312+
}
13141313
NodePointer type = popNode(Node::Kind::Type);
13151314
return createWithChildren(Node::Kind::ConcreteProtocolConformance,
13161315
type, conformanceRef, conditionalConformanceList);

lib/Demangling/Remangler.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,9 +1657,10 @@ void Remangler::mangleProtocolConformance(Node *node) {
16571657

16581658
void Remangler::mangleProtocolConformanceRef(Node *node) {
16591659
manglePureProtocol(node->getChild(0));
1660-
if (node->getNumChildren() > 1)
1660+
if (node->getNumChildren() > 1) {
16611661
mangleChildNode(node, 1);
1662-
Buffer << "HP";
1662+
Buffer << "HP";
1663+
}
16631664
}
16641665

16651666
void Remangler::mangleConcreteProtocolConformance(Node *node) {

test/SILGen/mangling_retroactive.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,14 @@ extension Z: Equatable where T: Hashable, V: Equatable {
3838
struct RequiresEquatable<T: Equatable> { }
3939

4040
// Conditional requirement involves retroactive conformances.
41-
// CHECK: sil hidden [ossa] @$s20mangling_retroactive5test2yyAA17RequiresEquatableVyAA1ZVy12RetroactiveB1XVSiAG1YVAI0F1A1PAAHPyHCg_AkL1QAAHPyHCg1_GAOSQHPAISHAAHPyHC_AKSQAAHPyHCHCg_GF
41+
// CHECK: sil hidden [ossa] @$s20mangling_retroactive5test2yyAA17RequiresEquatableVyAA1ZVy12RetroactiveB1XVSiAG1YVAI0F1A1PAAHPyHCg_AkL1QAAHPyHCg1_GAOSQAISHAAHPyHC_AKSQAAHPyHCHCg_GF
4242
func test2(_: RequiresEquatable<Z<X, Int, Y>>) { }
43+
44+
struct UnconditionallyP<T: Q>: P {}
45+
struct RequiresP<T: P> {}
46+
47+
// RequiresP uses a non-retroactive conformance for its generic param
48+
// UnconditionallyP, even though UnconditionallyP's generic param uses a
49+
// retroactive conformance to conform to Q.
50+
func rdar46735592(_: RequiresP<UnconditionallyP<Y>>) { }
51+
// CHECK: sil hidden [ossa] @$s20mangling_retroactive12rdar46735592yyAA9RequiresPVyAA16UnconditionallyPVy12RetroactiveB1YVAI0F1A1QAAHPyHCg_GAlJ1PyHCg_GF

0 commit comments

Comments
 (0)