@@ -638,26 +638,63 @@ class DemanglingForTypeRef
638638
639639 // / Produce the node to install as a nominal's context when swapping in the
640640 // / richer parent stored on the TypeRef.
641- // /
642- // / Extensions are special because they're the only node that can appear
643- // / instead of the parent (and contain it). For an Extension, the richer
644- // / parent replaces the extended-type slot, preserving the module and any
645- // / generic signature. For every other context kind, the richer parent
646- // / replaces the context wholesale.
647- // /
648- // / Returns nullptr if originalContext is a malformed Extension.
649641 Demangle::NodePointer
650642 substituteParentIntoContext (Demangle::NodePointer originalContext,
651643 Demangle::NodePointer parentNode) {
652- if (originalContext->getKind () != Node::Kind::Extension)
644+ switch (originalContext->getKind ()) {
645+ case Node::Kind::Extension: {
646+ // For a type nested in an extension vs a type nested in a parent type
647+ // directly, the mangling trees looks like this:
648+ //
649+ // Class Class
650+ // Extension Structure
651+ // Module: ModExt vs. Module: ModBase
652+ // Structure Identifier: Outer
653+ // Module: ModBase Identifier: Inner
654+ // Identifier: Outer
655+ // Identifier: Inner
656+ //
657+ if (originalContext->getNumChildren () < 2 ||
658+ originalContext->getNumChildren () > 3 ) {
659+ assert (false && " Extension node should have 2 or 3 children." );
660+ return nullptr ;
661+ }
662+ originalContext->replaceChild (1 , parentNode);
663+ return originalContext;
664+ }
665+ case Node::Kind::Protocol: {
666+ // Nominal members of a protocol are mangled with a BoundGenericProtocol
667+ // wrapping the protocol, where the generic argument slot holds the
668+ // relevant Self type (see the matching comment in TypeDecoder's
669+ // BoundGenericProtocol case). For example, accessing the typealias A from
670+ // protocol P through a conforming type S produces:
671+ //
672+ // protocol P { typealias A = ... }
673+ // struct S : P {}
674+ // let x: S.A = ...
675+ //
676+ // BoundGenericProtocol
677+ // |
678+ // --> Protocol: P
679+ // |
680+ // --> TypeList:
681+ // |
682+ // --> Structure: S
683+ auto bgp = Dem.createNode (Node::Kind::BoundGenericProtocol);
684+ auto typeProto = Dem.createNode (Node::Kind::Type);
685+ typeProto->addChild (originalContext, Dem);
686+ bgp->addChild (typeProto, Dem);
687+
688+ auto typeList = Dem.createNode (Node::Kind::TypeList);
689+ auto typeSelf = Dem.createNode (Node::Kind::Type);
690+ typeSelf->addChild (parentNode, Dem);
691+ typeList->addChild (typeSelf, Dem);
692+ bgp->addChild (typeList, Dem);
693+ return bgp;
694+ }
695+ default :
653696 return parentNode;
654- if (originalContext->getNumChildren () < 2 ||
655- originalContext->getNumChildren () > 3 ) {
656- assert (false && " Extension node should have 2 or 3 children." );
657- return nullptr ;
658697 }
659- originalContext->replaceChild (1 , parentNode);
660- return originalContext;
661698 }
662699
663700public:
0 commit comments