Skip to content

Commit e1e0194

Browse files
committed
[Mangling] Mangle protocol symbolic references in any-generic-type production.
We were strangely excluding protocols from being symbolically referenced in the any-generic-type production, which meant that we could not resolve (e.g.) associated type references to private protocols at runtime. Allow protocol symbolic references in this position, and cope with it in the demangler. Fixes the rest of rdar://problem/44977236. (cherry picked from commit dafaabe)
1 parent 5dcf4f2 commit e1e0194

File tree

5 files changed

+24
-3
lines changed

5 files changed

+24
-3
lines changed

lib/AST/ASTMangler.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,8 +1569,7 @@ void ASTMangler::appendAnyGenericType(const GenericTypeDecl *decl) {
15691569
// Try to mangle a symbolic reference for a nominal type.
15701570
if (AllowSymbolicReferences) {
15711571
auto nominal = key->getAnyNominal();
1572-
if (nominal && !isa<ProtocolDecl>(nominal)
1573-
&& (!CanSymbolicReference || CanSymbolicReference(nominal))) {
1572+
if (nominal && (!CanSymbolicReference || CanSymbolicReference(nominal))) {
15741573
appendSymbolicReference(nominal);
15751574
// Substitutions can refer back to the symbolic reference.
15761575
addSubstitution(key.getPointer());

lib/Demangling/Demangler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,6 +1681,10 @@ NodePointer Demangler::popAssocTypeName() {
16811681
if (Proto && !isProtocolNode(Proto))
16821682
return nullptr;
16831683

1684+
// If we haven't seen a protocol, check for a symbolic reference.
1685+
if (!Proto)
1686+
Proto = popNode(Node::Kind::ProtocolSymbolicReference);
1687+
16841688
NodePointer Id = popNode(Node::Kind::Identifier);
16851689
NodePointer AssocTy = changeKind(Id, Node::Kind::DependentAssociatedTypeRef);
16861690
addChild(AssocTy, Proto);

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,8 @@ swift::_contextDescriptorMatchesMangling(const ContextDescriptor *context,
475475
if (node->getKind() == Demangle::Node::Kind::Protocol) {
476476
auto proto = llvm::cast<ProtocolDescriptor>(context);
477477
auto nameNode = node->getChild(1);
478+
if (nameNode->getKind() != Demangle::Node::Kind::Identifier)
479+
return false;
478480
if (nameNode->getText() == proto->Name.get()) {
479481
node = node->getChild(0);
480482
break;

test/IRGen/protocol_resilience_descriptors.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
// Associated type default + flags
2525
// CHECK-DEFINITION-SAME: [[INT]] add
26-
// CHECK-DEFINITION-SAME: @"default assoc type _____y2T118resilient_protocol29ProtocolWithAssocTypeDefaultsPQzG 18resilient_protocol7WrapperV"
26+
// CHECK-DEFINITION-SAME: @"default assoc type _____y2T1_____QzG 18resilient_protocol7WrapperV AA29ProtocolWithAssocTypeDefaultsP"
2727
// CHECK-DEFINITION-SAME: [[INT]] 1
2828

2929
// Protocol requirements base descriptor

test/Runtime/associated_type_demangle_private.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,20 @@ AssociatedTypeDemangleTests.test("private types") {
2929
expectEqual(Foo.Inner.Innermost.self, getP_A(Foo.Inner.self))
3030
}
3131

32+
private protocol P2 {
33+
associatedtype A
34+
}
35+
36+
struct Bar: P2 {
37+
typealias A = Int
38+
}
39+
40+
class C1<T> { }
41+
42+
private class C2<T: P2>: C1<T.A> { }
43+
44+
AssociatedTypeDemangleTests.test("private protocols") {
45+
expectEqual("C2<Bar>", String(describing: C2<Bar>.self))
46+
}
47+
3248
runAllTests()

0 commit comments

Comments
 (0)