diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def index df41580cf465c..51b9042d5337c 100644 --- a/include/swift/Demangling/DemangleNodes.def +++ b/include/swift/Demangling/DemangleNodes.def @@ -75,6 +75,7 @@ NODE(DependentPseudogenericSignature) NODE(DependentProtocolConformanceRoot) NODE(DependentProtocolConformanceInherited) NODE(DependentProtocolConformanceAssociated) +NODE(DependentProtocolConformanceOpaque) CONTEXT_NODE(Destructor) CONTEXT_NODE(DidSet) NODE(Directness) diff --git a/include/swift/Demangling/Demangler.h b/include/swift/Demangling/Demangler.h index f634e5a86181b..6165f48aae1af 100644 --- a/include/swift/Demangling/Demangler.h +++ b/include/swift/Demangling/Demangler.h @@ -596,6 +596,7 @@ class Demangler : public NodeFactory { NodePointer demangleDependentProtocolConformanceInherited(); NodePointer popDependentAssociatedConformance(); NodePointer demangleDependentProtocolConformanceAssociated(); + NodePointer demangleDependentProtocolConformanceOpaque(); NodePointer demangleThunkOrSpecialization(); NodePointer demangleGenericSpecialization(Node::Kind SpecKind, NodePointer droppedArguments); diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp index df66c2672ffdc..b261d56f22e48 100644 --- a/lib/Demangling/Demangler.cpp +++ b/lib/Demangling/Demangler.cpp @@ -1042,6 +1042,7 @@ NodePointer Demangler::demangleOperator() { case 'C': return demangleConcreteProtocolConformance(); case 'D': return demangleDependentProtocolConformanceRoot(); case 'I': return demangleDependentProtocolConformanceInherited(); + case 'O': return demangleDependentProtocolConformanceOpaque(); case 'P': return createWithChild( Node::Kind::ProtocolConformanceRefInTypeModule, popProtocol()); @@ -1961,6 +1962,7 @@ NodePointer Demangler::popAnyProtocolConformance() { case Node::Kind::DependentProtocolConformanceRoot: case Node::Kind::DependentProtocolConformanceInherited: case Node::Kind::DependentProtocolConformanceAssociated: + case Node::Kind::DependentProtocolConformanceOpaque: return true; default: @@ -2060,6 +2062,13 @@ NodePointer Demangler::demangleDependentConformanceIndex() { return createNode(Node::Kind::Index, unsigned(index) - 2); } +NodePointer Demangler::demangleDependentProtocolConformanceOpaque() { + NodePointer type = popNode(Node::Kind::Type); + NodePointer conformance = popDependentProtocolConformance(); + return createWithChildren(Node::Kind::DependentProtocolConformanceOpaque, + conformance, type); +} + NodePointer Demangler::demangleRetroactiveConformance() { NodePointer index = demangleIndexAsNode(); NodePointer conformance = popAnyProtocolConformance(); diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index f2799cd799507..fedd33622f9ae 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -615,6 +615,7 @@ class NodePrinter { case Node::Kind::DependentProtocolConformanceAssociated: case Node::Kind::DependentProtocolConformanceInherited: case Node::Kind::DependentProtocolConformanceRoot: + case Node::Kind::DependentProtocolConformanceOpaque: case Node::Kind::ProtocolConformanceRefInTypeModule: case Node::Kind::ProtocolConformanceRefInProtocolModule: case Node::Kind::ProtocolConformanceRefInOtherModule: @@ -3285,6 +3286,12 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, Printer << " to "; print(Node->getChild(1), depth + 1); return nullptr; + case Node::Kind::DependentProtocolConformanceOpaque: + Printer << "opaque result conformance "; + print(Node->getChild(0), depth + 1); + Printer << " of "; + print(Node->getChild(1), depth + 1); + return nullptr; case Node::Kind::ProtocolConformanceRefInTypeModule: Printer << "protocol conformance ref (type's module) "; printChildren(Node, depth); diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp index 3a26e908465f4..6013ee0ba39e9 100644 --- a/lib/Demangling/OldRemangler.cpp +++ b/lib/Demangling/OldRemangler.cpp @@ -555,6 +555,13 @@ Remangler::mangleDependentProtocolConformanceAssociated(Node *node, return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } +ManglingError +Remangler::mangleDependentProtocolConformanceOpaque(Node *node, + unsigned depth) { + // Dependent conformances aren't in the old mangling + return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); +} + ManglingError Remangler::mangleProtocolConformance(Node *node, unsigned depth) { // type, protocol name, context DEMANGLER_ASSERT(node->getNumChildren() == 3, node); diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp index 4a29fd664911b..687357facd5c4 100644 --- a/lib/Demangling/Remangler.cpp +++ b/lib/Demangling/Remangler.cpp @@ -2777,6 +2777,16 @@ ManglingError Remangler::mangleDependentConformanceIndex(Node *node, return ManglingError::Success; } +ManglingError Remangler::mangleDependentProtocolConformanceOpaque(Node *node, + unsigned depth) { + DEMANGLER_ASSERT(node->getKind() == Node::Kind::DependentProtocolConformanceOpaque, + node); + mangleAnyProtocolConformance(node->getChild(0), depth + 1); + mangleType(node->getChild(1), depth + 1); + Buffer << "HO"; + return ManglingError::Success; +} + ManglingError Remangler::mangleAnyProtocolConformance(Node *node, unsigned depth) { switch (node->getKind()) { @@ -2790,6 +2800,8 @@ ManglingError Remangler::mangleAnyProtocolConformance(Node *node, return mangleDependentProtocolConformanceInherited(node, depth + 1); case Node::Kind::DependentProtocolConformanceAssociated: return mangleDependentProtocolConformanceAssociated(node, depth + 1); + case Node::Kind::DependentProtocolConformanceOpaque: + return mangleDependentProtocolConformanceOpaque(node, depth + 1); default: // Should this really succeed?! return ManglingError::Success; diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt index 540bf28a22e00..17d9e400a0c95 100644 --- a/test/Demangle/Inputs/manglings.txt +++ b/test/Demangle/Inputs/manglings.txt @@ -497,3 +497,4 @@ _$s15raw_identifiers0020pathfoo_yuEHaaCiJskayyF ---> raw_identifiers.`path://foo _$s15raw_identifiers10FontWeightO009_100_FpEpdyyFZ ---> static raw_identifiers.FontWeight.`100`() -> () $s7Library1BC1iSivxTwd ---> default override of Library.B.i.modify2 : Swift.Int $s7Library1BC1iSivxTwdTwc ---> coro function pointer to default override of Library.B.i.modify2 : Swift.Int +$s3use1xAA3OfPVy3lib1GVyAA1fQryFQOyQo_GAjE1PAAxAeKHD1_AIHO_HCg_Gvp ---> use.x : use.OfP some>>.0>> diff --git a/test/SILGen/Inputs/opaque_result_type_retroactive_other.swift b/test/SILGen/Inputs/opaque_result_type_retroactive_other.swift new file mode 100644 index 0000000000000..5faa511ea5a30 --- /dev/null +++ b/test/SILGen/Inputs/opaque_result_type_retroactive_other.swift @@ -0,0 +1,9 @@ +public struct G { + public init(_: T) {} +} + +public protocol P { + associatedtype A: P + + func a() -> A +} diff --git a/test/SILGen/opaque_result_type_retroactive.swift b/test/SILGen/opaque_result_type_retroactive.swift new file mode 100644 index 0000000000000..eaaabcb7ec57c --- /dev/null +++ b/test/SILGen/opaque_result_type_retroactive.swift @@ -0,0 +1,31 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend -emit-module %S/Inputs/opaque_result_type_retroactive_other.swift -emit-module -emit-module-path %t/opaque_result_type_retroactive_other.swiftmodule +// RUN: %target-swift-emit-silgen %s -I %t | %FileCheck %s + +import opaque_result_type_retroactive_other + +extension G: @retroactive P where T: P { + public func a() -> T { + fatalError() + } +} + +public struct S: P { + public func a() -> S { + return self + } +} + +public func f() -> some P { + return S() +} + +public struct OfP { + public init(_: T) {} +} + +// CHECK-LABEL: sil_global @$s30opaque_result_type_retroactive1xAA3OfPVy0a1_b1_c1_D6_other1GVyAA1fQryFQOyQo_GAjE1PAAxAeKHD1_AIHO_HCg_Gvp +public var x = OfP(G(f())) + +// CHECK-LABEL: sil_global @$s30opaque_result_type_retroactive1yAA3OfPVy0a1_b1_c1_D6_other1GVyAA1fQryFQOyQo_1AAE1PPQxGAnekAxAeKHD1_AJQzAeKHA1_AMHO_HCg_Gvp +public var y = OfP(G(f().a()))