From 38bc4d030348bd938ffc1cc8fbacb3ce72b713d3 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Thu, 30 Jun 2022 14:05:38 -0700 Subject: [PATCH 1/2] Generalize the Mangling of Constrained Existential Types Upgrade the old mangling from a list of argument types to a list of requiremnets. For now, only same-type requirements may actually be mangled since those are all that are available to the surface language. Reconstruction of existential types now consists of demangling (a list of) base protocol(s), decoding the constraints, and converting the same-type constraints back into a list of arguments. rdar://96088707 --- docs/ABI/Mangling.rst | 3 +- include/swift/AST/ASTDemangler.h | 3 +- include/swift/AST/ASTMangler.h | 19 +- include/swift/Demangling/DemangleNodes.def | 4 +- include/swift/Demangling/Demangler.h | 2 + include/swift/Demangling/TypeDecoder.h | 25 ++- include/swift/Reflection/TypeRef.h | 37 ++-- include/swift/Reflection/TypeRefBuilder.h | 7 +- include/swift/Reflection/TypeRefs.def | 2 +- lib/AST/ASTDemangler.cpp | 34 +++- lib/AST/ASTMangler.cpp | 108 ++++++++--- lib/Demangling/Demangler.cpp | 43 +++-- lib/Demangling/NodePrinter.cpp | 19 +- lib/Demangling/OldRemangler.cpp | 13 +- lib/Demangling/Remangler.cpp | 41 +++- lib/IRGen/GenExistential.cpp | 23 ++- lib/IRGen/IRGenMangler.cpp | 16 +- stdlib/public/Reflection/TypeLowering.cpp | 8 +- stdlib/public/Reflection/TypeRef.cpp | 181 +++++++++++------- stdlib/public/runtime/MetadataLookup.cpp | 81 ++++---- test/Demangle/Inputs/manglings.txt | 5 +- test/IRGen/existential_shape_metadata.swift | 30 +-- test/SILGen/parameterized_existentials.swift | 14 +- .../cast_folding_parameterized_protocol.swift | 4 +- unittests/runtime/SpecifierDSL.h | 47 +++-- 25 files changed, 496 insertions(+), 273 deletions(-) diff --git a/docs/ABI/Mangling.rst b/docs/ABI/Mangling.rst index eb7123c4e7d4d..6a8a2efd0367b 100644 --- a/docs/ABI/Mangling.rst +++ b/docs/ABI/Mangling.rst @@ -637,7 +637,7 @@ Types type ::= protocol-list 'p' // existential type type ::= protocol-list superclass 'Xc' // existential type with superclass type ::= protocol-list 'Xl' // existential type with AnyObject - type ::= protocol-list 'y' (type* '_')* type* retroactive-conformance* 'XP' // parameterized protocol type + type ::= protocol-list requirement* '_' 'XP' // constrained existential type type ::= type-list 't' // tuple type ::= type generic-signature 'u' // generic type type ::= 'x' // generic param, depth=0, idx=0 @@ -878,6 +878,7 @@ now codified into the ABI; the index 0 is therefore reserved. GENERIC-PARAM-INDEX ::= 'z' // depth = 0, idx = 0 GENERIC-PARAM-INDEX ::= INDEX // depth = 0, idx = N+1 GENERIC-PARAM-INDEX ::= 'd' INDEX INDEX // depth = M+1, idx = N + GENERIC-PARAM-INDEX ::= 's' // depth = 0, idx = 0; Constrained existential 'Self' type LAYOUT-CONSTRAINT ::= 'N' // NativeRefCountedObject LAYOUT-CONSTRAINT ::= 'R' // RefCountedObject diff --git a/include/swift/AST/ASTDemangler.h b/include/swift/AST/ASTDemangler.h index f00299d896dd9..486d65f720b04 100644 --- a/include/swift/AST/ASTDemangler.h +++ b/include/swift/AST/ASTDemangler.h @@ -119,7 +119,8 @@ class ASTBuilder { Type createProtocolTypeFromDecl(ProtocolDecl *protocol); - Type createParameterizedProtocolType(Type base, ArrayRef args); + Type createConstrainedExistentialType(Type base, + ArrayRef constraints); Type createExistentialMetatypeType(Type instance, Optional repr=None); diff --git a/include/swift/AST/ASTMangler.h b/include/swift/AST/ASTMangler.h index e52660ffdeba4..809c398e40492 100644 --- a/include/swift/AST/ASTMangler.h +++ b/include/swift/AST/ASTMangler.h @@ -343,7 +343,8 @@ class ASTMangler : public Mangler { bool &isAssocTypeAtDepth); void appendOpWithGenericParamIndex(StringRef, - const GenericTypeParamType *paramTy); + const GenericTypeParamType *paramTy, + bool baseIsProtocolSelf = false); /// Mangles a sugared type iff we are mangling for the debugger. template void appendSugaredType(Type type, @@ -444,8 +445,17 @@ class ASTMangler : public Mangler { bool appendGenericSignature(GenericSignature sig, GenericSignature contextSig = nullptr); - void appendRequirement(const Requirement &reqt, - GenericSignature sig); + /// Append a requirement to the mangling. + /// + /// \param reqt The requirement to mangle + /// \param sig The generic signature. + /// \param lhsBaseIsProtocolSelf If \c true, mangle the base of the left-hand + /// side of the constraint with a special protocol 'Self' sentinel node. This + /// supports distinguishing requirements rooted at 'Self' in constrained + /// existentials from ambient generic parameters that would otherwise be + /// at e.g. (0, 0) as well. + void appendRequirement(const Requirement &reqt, GenericSignature sig, + bool lhsBaseIsProtocolSelf = false); void appendGenericSignatureParts(GenericSignature sig, ArrayRef> params, @@ -521,6 +531,9 @@ class ASTMangler : public Mangler { Demangle::AutoDiffFunctionKind kind, const AutoDiffConfig &config); void appendIndexSubset(IndexSubset *indexSubset); + + void appendConstrainedExistential(Type base, GenericSignature sig, + const ValueDecl *forDecl); }; } // end namespace Mangle diff --git a/include/swift/Demangling/DemangleNodes.def b/include/swift/Demangling/DemangleNodes.def index 4368e118bf0f6..07834df141b38 100644 --- a/include/swift/Demangling/DemangleNodes.def +++ b/include/swift/Demangling/DemangleNodes.def @@ -98,6 +98,9 @@ NODE(FunctionSignatureSpecializationReturn) NODE(FunctionSignatureSpecializationParamKind) NODE(FunctionSignatureSpecializationParamPayload) NODE(FunctionType) +NODE(ConstrainedExistential) +NODE(ConstrainedExistentialRequirementList) +NODE(ConstrainedExistentialSelf) NODE(GenericPartialSpecialization) NODE(GenericPartialSpecializationNotReAbstracted) NODE(GenericProtocolWitnessTable) @@ -170,7 +173,6 @@ NODE(EscapingObjCBlock) CONTEXT_NODE(OtherNominalType) CONTEXT_NODE(OwningAddressor) CONTEXT_NODE(OwningMutableAddressor) -NODE(ParameterizedProtocol) NODE(PartialApplyForwarder) NODE(PartialApplyObjCForwarder) NODE(PostfixOperator) diff --git a/include/swift/Demangling/Demangler.h b/include/swift/Demangling/Demangler.h index 5a66eb2d27ca2..6ead2032e762e 100644 --- a/include/swift/Demangling/Demangler.h +++ b/include/swift/Demangling/Demangler.h @@ -580,6 +580,8 @@ class Demangler : public NodeFactory { NodePointer demangleIndexSubset(); NodePointer demangleDifferentiableFunctionType(); + NodePointer demangleConstrainedExistentialRequirementList(); + bool demangleBoundGenerics(Vector &TypeListList, NodePointer &RetroactiveConformances); diff --git a/include/swift/Demangling/TypeDecoder.h b/include/swift/Demangling/TypeDecoder.h index d8ef4b940e5f3..76463521bb874 100644 --- a/include/swift/Demangling/TypeDecoder.h +++ b/include/swift/Demangling/TypeDecoder.h @@ -713,7 +713,7 @@ class TypeDecoder { forRequirement); } - case NodeKind::ParameterizedProtocol: { + case NodeKind::ConstrainedExistential: { if (Node->getNumChildren() < 2) return MAKE_NODE_TYPE_ERROR(Node, "fewer children (%zu) than required (2)", @@ -723,23 +723,20 @@ class TypeDecoder { if (protocolType.isError()) return protocolType; - llvm::SmallVector args; + llvm::SmallVector requirements; - const auto &genericArgs = Node->getChild(1); - if (genericArgs->getKind() != NodeKind::TypeList) - return MAKE_NODE_TYPE_ERROR0(genericArgs, "is not TypeList"); + auto *reqts = Node->getChild(1); + if (reqts->getKind() != NodeKind::ConstrainedExistentialRequirementList) + return MAKE_NODE_TYPE_ERROR0(reqts, "is not requirement list"); - for (auto genericArg : *genericArgs) { - auto paramType = decodeMangledType(genericArg, depth + 1, - /*forRequirement=*/false); - if (paramType.isError()) - return paramType; - args.push_back(paramType.getType()); - } + decodeRequirement(reqts, requirements, Builder); - return Builder.createParameterizedProtocolType(protocolType.getType(), - args); + return Builder.createConstrainedExistentialType(protocolType.getType(), + requirements); } + case NodeKind::ConstrainedExistentialSelf: + return Builder.createGenericTypeParameterType(/*depth*/ 0, /*index*/ 0); case NodeKind::Protocol: case NodeKind::ProtocolSymbolicReference: { diff --git a/include/swift/Reflection/TypeRef.h b/include/swift/Reflection/TypeRef.h index 3227b91ac80ae..9e20f97525648 100644 --- a/include/swift/Reflection/TypeRef.h +++ b/include/swift/Reflection/TypeRef.h @@ -563,39 +563,48 @@ class ProtocolCompositionTypeRef final : public TypeRef { } }; -class ParameterizedProtocolTypeRef final : public TypeRef { +class ConstrainedExistentialTypeRef final : public TypeRef { const ProtocolCompositionTypeRef *Base; - std::vector Args; + std::vector Requirements; static TypeRefID Profile(const ProtocolCompositionTypeRef *Protocol, - std::vector Args) { + std::vector Requirements) { TypeRefID ID; ID.addPointer(Protocol); - for (auto Arg : Args) { - ID.addPointer(Arg); + for (auto reqt : Requirements) { + ID.addPointer(reqt.getFirstType()); + if (reqt.getKind() != RequirementKind::Layout) + ID.addPointer(reqt.getSecondType()); + else + ID.addInteger( + unsigned(0)); // FIXME: Layout constraints aren't implemented yet + ID.addInteger(unsigned(reqt.getKind())); } return ID; } public: - ParameterizedProtocolTypeRef(const ProtocolCompositionTypeRef *Protocol, - std::vector Args) - : TypeRef(TypeRefKind::ParameterizedProtocol), Base(Protocol), - Args(Args) {} + ConstrainedExistentialTypeRef(const ProtocolCompositionTypeRef *Protocol, + std::vector Requirements) + : TypeRef(TypeRefKind::ConstrainedExistential), Base(Protocol), + Requirements(Requirements) {} template - static const ParameterizedProtocolTypeRef * + static const ConstrainedExistentialTypeRef * create(Allocator &A, const ProtocolCompositionTypeRef *Protocol, - std::vector Args) { - FIND_OR_CREATE_TYPEREF(A, ParameterizedProtocolTypeRef, Protocol, Args); + std::vector Requirements) { + FIND_OR_CREATE_TYPEREF(A, ConstrainedExistentialTypeRef, Protocol, + Requirements); } const ProtocolCompositionTypeRef *getBase() const { return Base; } - const std::vector &getArgs() const { return Args; } + const std::vector &getRequirements() const { + return Requirements; + } static bool classof(const TypeRef *TR) { - return TR->getKind() == TypeRefKind::ParameterizedProtocol; + return TR->getKind() == TypeRefKind::ConstrainedExistential; } }; diff --git a/include/swift/Reflection/TypeRefBuilder.h b/include/swift/Reflection/TypeRefBuilder.h index fec045fa94e5f..7c77ef8d14d67 100644 --- a/include/swift/Reflection/TypeRefBuilder.h +++ b/include/swift/Reflection/TypeRefBuilder.h @@ -650,13 +650,12 @@ class TypeRefBuilder { isClassBound); } - const ParameterizedProtocolTypeRef * - createParameterizedProtocolType(const TypeRef *base, - llvm::ArrayRef args) { + const ConstrainedExistentialTypeRef *createConstrainedExistentialType( + const TypeRef *base, llvm::ArrayRef constraints) { auto *baseProto = llvm::dyn_cast(base); if (!baseProto) return nullptr; - return ParameterizedProtocolTypeRef::create(*this, baseProto, args); + return ConstrainedExistentialTypeRef::create(*this, baseProto, constraints); } const ExistentialMetatypeTypeRef *createExistentialMetatypeType( diff --git a/include/swift/Reflection/TypeRefs.def b/include/swift/Reflection/TypeRefs.def index 61baf077fd505..e95845700b539 100644 --- a/include/swift/Reflection/TypeRefs.def +++ b/include/swift/Reflection/TypeRefs.def @@ -22,7 +22,7 @@ TYPEREF(BoundGeneric, TypeRef) TYPEREF(Tuple, TypeRef) TYPEREF(Function, TypeRef) TYPEREF(ProtocolComposition, TypeRef) -TYPEREF(ParameterizedProtocol, TypeRef) +TYPEREF(ConstrainedExistential, TypeRef) TYPEREF(Metatype, TypeRef) TYPEREF(ExistentialMetatype, TypeRef) TYPEREF(GenericTypeParameter, TypeRef) diff --git a/lib/AST/ASTDemangler.cpp b/lib/AST/ASTDemangler.cpp index 7bef8968705cf..547019bb82065 100644 --- a/lib/AST/ASTDemangler.cpp +++ b/lib/AST/ASTDemangler.cpp @@ -625,12 +625,38 @@ Type ASTBuilder::createExistentialMetatypeType(Type instance, getMetatypeRepresentation(*repr)); } -Type ASTBuilder::createParameterizedProtocolType(Type base, - ArrayRef args) { +Type ASTBuilder::createConstrainedExistentialType( + Type base, ArrayRef constraints) { + // FIXME: Generalize to other kinds of bases. if (!base->getAs()) return Type(); - return ParameterizedProtocolType::get(base->getASTContext(), - base->castTo(), args); + auto baseTy = base->castTo(); + auto baseDecl = baseTy->getDecl(); + llvm::SmallDenseMap cmap; + for (const auto &req : constraints) { + switch (req.getKind()) { + case RequirementKind::Conformance: + case RequirementKind::Superclass: + case RequirementKind::Layout: + continue; + + case RequirementKind::SameType: + if (auto *DMT = req.getFirstType()->getAs()) + if (baseDecl->getAssociatedType(DMT->getName())) + cmap[DMT->getName()] = req.getSecondType(); + } + } + llvm::SmallVector args; + for (auto *assocTy : baseDecl->getPrimaryAssociatedTypes()) { + auto argTy = cmap.find(assocTy->getName()); + if (argTy == cmap.end()) { + return Type(); + } + args.push_back(argTy->getSecond()); + } + auto constrainedBase = + ParameterizedProtocolType::get(base->getASTContext(), baseTy, args); + return ExistentialType::get(constrainedBase); } Type ASTBuilder::createMetatypeType(Type instance, diff --git a/lib/AST/ASTMangler.cpp b/lib/AST/ASTMangler.cpp index 355acab44b31e..2655fb2ddf962 100644 --- a/lib/AST/ASTMangler.cpp +++ b/lib/AST/ASTMangler.cpp @@ -1233,7 +1233,12 @@ void ASTMangler::appendType(Type type, GenericSignature sig, case TypeKind::ExistentialMetatype: { ExistentialMetatypeType *EMT = cast(tybase); - appendType(EMT->getInstanceType(), sig, forDecl); + if (EMT->getInstanceType()->isExistentialType() && + EMT->hasParameterizedExistential()) + appendConstrainedExistential(EMT->getInstanceType(), sig, forDecl); + else + appendType(EMT->getInstanceType(), sig, forDecl); + if (EMT->hasRepresentation()) { appendOperator("Xm", getMetatypeRepresentationOp(EMT->getRepresentation())); @@ -1283,17 +1288,16 @@ void ASTMangler::appendType(Type type, GenericSignature sig, return appendExistentialLayout(layout, sig, forDecl); } - case TypeKind::ParameterizedProtocol: { - auto layout = type->getExistentialLayout(); - appendExistentialLayout(layout, sig, forDecl); - bool isFirstArgList = true; - appendBoundGenericArgs(type, sig, isFirstArgList, forDecl); - return appendOperator("XP"); - } + case TypeKind::ParameterizedProtocol: + llvm_unreachable("Handled by generalized existential mangling!"); case TypeKind::Existential: { - auto constraint = cast(tybase)->getConstraintType(); - return appendType(constraint, sig, forDecl); + auto *ET = cast(tybase); + if (tybase->hasParameterizedExistential()) { + return appendConstrainedExistential(ET->getConstraintType(), sig, + forDecl); + } + return appendType(ET->getConstraintType(), sig, forDecl); } case TypeKind::UnboundGeneric: @@ -1488,8 +1492,9 @@ GenericTypeParamType *ASTMangler::appendAssocType(DependentMemberType *DepTy, return nullptr; } -void ASTMangler::appendOpWithGenericParamIndex(StringRef Op, - const GenericTypeParamType *paramTy) { +void ASTMangler::appendOpWithGenericParamIndex( + StringRef Op, const GenericTypeParamType *paramTy, + bool baseIsProtocolSelf) { llvm::SmallVector OpBuf(Op.begin(), Op.end()); if (paramTy->getDepth() > 0) { OpBuf.push_back('d'); @@ -1498,7 +1503,11 @@ void ASTMangler::appendOpWithGenericParamIndex(StringRef Op, Index(paramTy->getIndex())); } if (paramTy->getIndex() == 0) { - OpBuf.push_back('z'); + if (baseIsProtocolSelf) { + OpBuf.push_back('s'); + } else { + OpBuf.push_back('z'); + } return appendOperator(StringRef(OpBuf.data(), OpBuf.size())); } appendOperator(Op, Index(paramTy->getIndex() - 1)); @@ -1598,9 +1607,6 @@ void ASTMangler::appendBoundGenericArgs(Type type, GenericSignature sig, if (Type parent = nominalType->getParent()) appendBoundGenericArgs(parent->getDesugaredType(), sig, isFirstArgList, forDecl); - } else if (auto *ppt = dyn_cast(typePtr)) { - assert(!ppt->getBaseType()->getParent()); - genericArgs = ppt->getArgs(); } else { auto boundType = cast(typePtr); genericArgs = boundType->getGenericArgs(); @@ -2795,7 +2801,8 @@ bool ASTMangler::appendGenericSignature(GenericSignature sig, } void ASTMangler::appendRequirement(const Requirement &reqt, - GenericSignature sig) { + GenericSignature sig, + bool lhsBaseIsProtocolSelf) { Type FirstTy = reqt.getFirstType()->getCanonicalType(); @@ -2818,7 +2825,6 @@ void ASTMangler::appendRequirement(const Requirement &reqt, } if (auto *DT = FirstTy->getAs()) { - bool isAssocTypeAtDepth = false; if (tryMangleTypeSubstitution(DT, sig)) { switch (reqt.getKind()) { case RequirementKind::Conformance: @@ -2834,6 +2840,7 @@ void ASTMangler::appendRequirement(const Requirement &reqt, } llvm_unreachable("bad requirement type"); } + bool isAssocTypeAtDepth = false; GenericTypeParamType *gpBase = appendAssocType(DT, sig, isAssocTypeAtDepth); addTypeSubstitution(DT, sig); @@ -2841,17 +2848,18 @@ void ASTMangler::appendRequirement(const Requirement &reqt, switch (reqt.getKind()) { case RequirementKind::Conformance: return appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "RP" : "Rp", - gpBase); + gpBase, lhsBaseIsProtocolSelf); case RequirementKind::Layout: - appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "RM" : "Rm", gpBase); + appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "RM" : "Rm", gpBase, + lhsBaseIsProtocolSelf); appendOpParamForLayoutConstraint(reqt.getLayoutConstraint()); return; case RequirementKind::Superclass: return appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "RC" : "Rc", - gpBase); + gpBase, lhsBaseIsProtocolSelf); case RequirementKind::SameType: return appendOpWithGenericParamIndex(isAssocTypeAtDepth ? "RT" : "Rt", - gpBase); + gpBase, lhsBaseIsProtocolSelf); } llvm_unreachable("bad requirement type"); } @@ -3514,3 +3522,59 @@ std::string ASTMangler::mangleDistributedThunk(const AbstractFunctionDecl *thunk return mangleEntity(thunk, SymbolKind::DistributedThunk); } + +static void gatherExistentialRequirements(SmallVectorImpl &reqs, + ParameterizedProtocolType *PPT) { + auto protoTy = PPT->getBaseType(); + PPT->getRequirements(protoTy->getDecl()->getSelfInterfaceType(), reqs); +} + +void ASTMangler::appendConstrainedExistential(Type base, GenericSignature sig, + const ValueDecl *forDecl) { + auto layout = base->getExistentialLayout(); + appendExistentialLayout(layout, sig, forDecl); + SmallVector requirements; + assert(!base->is() && + "plain protocol type constraint has no generalization structure"); + if (auto *PCT = base->getAs()) { + for (auto memberTy : PCT->getMembers()) { + if (auto *PPT = memberTy->getAs()) + gatherExistentialRequirements(requirements, PPT); + } + } else { + auto *PPT = base->castTo(); + gatherExistentialRequirements(requirements, PPT); + } + + assert(!requirements.empty() && "Unconstrained existential?"); + // Sort the requirements to canonicalize their order. + llvm::array_pod_sort( + requirements.begin(), requirements.end(), + [](const Requirement *lhs, const Requirement *rhs) -> int { + return lhs->compare(*rhs); + }); + + bool firstRequirement = true; + for (const auto &reqt : requirements) { + switch (reqt.getKind()) { + case RequirementKind::Layout: + case RequirementKind::Conformance: + case RequirementKind::Superclass: + // The surface language cannot express these requirements yet, so + // we have no mangling for them. + assert(false && "Unexpected requirement in constrained existential!"); + continue; + + case RequirementKind::SameType: { + break; + } + } + + appendRequirement(reqt, sig, /*baseIsProtocolSelf*/ true); + if (firstRequirement) { + appendOperator("_"); + firstRequirement = false; + } + } + return appendOperator("XP"); +} diff --git a/lib/Demangling/Demangler.cpp b/lib/Demangling/Demangler.cpp index d3e700677c523..ba80045429784 100644 --- a/lib/Demangling/Demangler.cpp +++ b/lib/Demangling/Demangler.cpp @@ -1818,12 +1818,6 @@ NodePointer Demangler::demangleBoundGenericArgs(NodePointer Nominal, case Node::Kind::Constructor: // Well, not really a nominal type. return createWithChildren(Node::Kind::BoundGenericFunction, Nominal, args); - case Node::Kind::Type: - if (!Nominal->hasChildren()) - return nullptr; - if (Nominal->getFirstChild()->getKind() != Node::Kind::ProtocolList) - return nullptr; - return createWithChildren(Node::Kind::ParameterizedProtocol, Nominal, args); default: return nullptr; } @@ -2367,6 +2361,9 @@ NodePointer Demangler::demangleGenericParamIndex() { if (nextIf('z')) { return getDependentGenericParamType(0, 0); } + if (nextIf('s')) { + return createNode(Node::Kind::ConstrainedExistentialSelf); + } return getDependentGenericParamType(0, demangleIndex() + 1); } @@ -3268,20 +3265,10 @@ NodePointer Demangler::demangleSpecialType() { MTR, Type)); } case 'P': { - NodePointer RetroactiveConformances; - Vector TypeListList(*this, 4); - - if (!demangleBoundGenerics(TypeListList, RetroactiveConformances)) - return nullptr; - - NodePointer Type = popNode(Node::Kind::Type); - if (!Type) - return nullptr; - - NodePointer BoundNode = demangleBoundGenericArgs(Type, TypeListList, 0); - NodePointer NTy = createType(BoundNode); - addSubstitution(NTy); - return NTy; + NodePointer Reqs = demangleConstrainedExistentialRequirementList(); + NodePointer Base = popNode(Node::Kind::Type); + return createType( + createWithChildren(Node::Kind::ConstrainedExistential, Base, Reqs)); } case 'p': return createType(createWithChild(Node::Kind::ExistentialMetatype, @@ -3573,6 +3560,22 @@ NodePointer Demangler::demangleProtocolListType() { return createType(ProtoList); } +NodePointer Demangler::demangleConstrainedExistentialRequirementList() { + NodePointer ReqList = + createNode(Node::Kind::ConstrainedExistentialRequirementList); + bool firstElem = false; + do { + firstElem = (popNode(Node::Kind::FirstElementMarker) != nullptr); + NodePointer Req = popNode(isRequirement); + if (!Req) + return nullptr; + ReqList->addChild(Req, *this); + } while (!firstElem); + + ReqList->reverseChildren(); + return ReqList; +} + NodePointer Demangler::demangleGenericSignature(bool hasParamCounts) { NodePointer Sig = createNode(Node::Kind::DependentGenericSignature); if (hasParamCounts) { diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index 61967d96066ab..19d9c40702148 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -306,7 +306,9 @@ class NodePrinter { case Node::Kind::MetatypeRepresentation: case Node::Kind::Module: case Node::Kind::Tuple: - case Node::Kind::ParameterizedProtocol: + case Node::Kind::ConstrainedExistential: + case Node::Kind::ConstrainedExistentialRequirementList: + case Node::Kind::ConstrainedExistentialSelf: case Node::Kind::Protocol: case Node::Kind::ProtocolSymbolicReference: case Node::Kind::ReturnType: @@ -2273,8 +2275,16 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, } return nullptr; } - case Node::Kind::ParameterizedProtocol: { - printBoundGeneric(Node, depth); + case Node::Kind::ConstrainedExistential: { + Printer << "any "; + print(Node->getChild(0), depth + 1); + Printer << "<"; + print(Node->getChild(1), depth + 1); + Printer << ">"; + return nullptr; + } + case Node::Kind::ConstrainedExistentialRequirementList: { + printChildren(Node, depth, ", "); return nullptr; } case Node::Kind::ExistentialMetatype: { @@ -2291,6 +2301,9 @@ NodePointer NodePrinter::print(NodePointer Node, unsigned depth, Printer << ".Type"; return nullptr; } + case Node::Kind::ConstrainedExistentialSelf: + Printer << "Self"; + return nullptr; case Node::Kind::MetatypeRepresentation: { Printer << Node->getText(); return nullptr; diff --git a/lib/Demangling/OldRemangler.cpp b/lib/Demangling/OldRemangler.cpp index e85897af15924..357447ef8269e 100644 --- a/lib/Demangling/OldRemangler.cpp +++ b/lib/Demangling/OldRemangler.cpp @@ -2714,8 +2714,17 @@ ManglingError Remangler::mangleObjCAsyncCompletionHandlerImpl(Node *node, unsigned depth) { return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } -ManglingError Remangler::mangleParameterizedProtocol(Node *node, - unsigned int depth) { +ManglingError Remangler::mangleConstrainedExistential(Node *node, + unsigned int depth) { + return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); +} +ManglingError +Remangler::mangleConstrainedExistentialRequirementList(Node *node, + unsigned int depth) { + return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); +} +ManglingError Remangler::mangleConstrainedExistentialSelf(Node *node, + unsigned int depth) { return MANGLING_ERROR(ManglingError::UnsupportedNodeKind, node); } ManglingError Remangler::mangleUniquable(Node *node, unsigned int depth) { diff --git a/lib/Demangling/Remangler.cpp b/lib/Demangling/Remangler.cpp index 41a070d3cad7d..6ad74e3166062 100644 --- a/lib/Demangling/Remangler.cpp +++ b/lib/Demangling/Remangler.cpp @@ -416,6 +416,11 @@ bool Remangler::mangleStandardSubstitution(Node *node) { void Remangler::mangleDependentGenericParamIndex(Node *node, const char *nonZeroPrefix, char zeroOp) { + if (node->getKind() == Node::Kind::ConstrainedExistentialSelf) { + Buffer << 's'; + return; + } + auto paramDepth = node->getChild(0)->getIndex(); auto index = node->getChild(1)->getIndex(); @@ -449,7 +454,8 @@ Remangler::mangleConstrainedType(Node *node, unsigned depth) { node = getChildOfType(node->getFirstChild()); } - if (node->getKind() != Node::Kind::DependentGenericParamType) { + if (node->getKind() != Node::Kind::DependentGenericParamType && + node->getKind() != Node::Kind::ConstrainedExistentialSelf) { RETURN_IF_ERROR(mangle(node, depth + 1)); if (!Chain.size()) return std::pair{-1, nullptr}; @@ -601,7 +607,7 @@ ManglingError Remangler::mangleGenericArgs(Node *node, char &Separator, break; } - case Node::Kind::ParameterizedProtocol: { + case Node::Kind::ConstrainedExistential: { Buffer << Separator; Separator = '_'; RETURN_IF_ERROR(mangleChildNodes(node->getChild(1), depth + 1)); @@ -1225,15 +1231,32 @@ ManglingError Remangler::mangleErrorType(Node *node, unsigned depth) { return ManglingError::Success; } -ManglingError Remangler::mangleParameterizedProtocol(Node *node, - unsigned int depth) { - RETURN_IF_ERROR(mangleType(node->getChild(0), depth + 1)); - char separator = 'y'; - RETURN_IF_ERROR(mangleGenericArgs(node, separator, depth + 1)); +ManglingError Remangler::mangleConstrainedExistential(Node *node, + unsigned int depth) { + RETURN_IF_ERROR(mangleChildNode(node, 0, depth + 1)); + RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); Buffer << "XP"; return ManglingError::Success; } +ManglingError +Remangler::mangleConstrainedExistentialRequirementList(Node *node, + unsigned int depth) { + assert(node->getNumChildren() > 0); + bool FirstElem = true; + for (size_t Idx = 0, Num = node->getNumChildren(); Idx < Num; ++Idx) { + RETURN_IF_ERROR(mangleChildNode(node, Idx, depth + 1)); + mangleListSeparator(FirstElem); + } + return ManglingError::Success; +} + +ManglingError Remangler::mangleConstrainedExistentialSelf(Node *node, + unsigned int depth) { + Buffer << "s"; + return ManglingError::Success; +} + ManglingError Remangler::mangleExistentialMetatype(Node *node, unsigned depth) { if (node->getFirstChild()->getKind() == Node::Kind::MetatypeRepresentation) { RETURN_IF_ERROR(mangleChildNode(node, 1, depth + 1)); @@ -3522,7 +3545,7 @@ bool Demangle::isSpecialized(Node *node) { case Node::Kind::BoundGenericTypeAlias: case Node::Kind::BoundGenericProtocol: case Node::Kind::BoundGenericFunction: - case Node::Kind::ParameterizedProtocol: + case Node::Kind::ConstrainedExistential: return true; case Node::Kind::Structure: @@ -3625,7 +3648,7 @@ ManglingErrorOr Demangle::getUnspecialized(Node *node, return nominalType; } - case Node::Kind::ParameterizedProtocol: { + case Node::Kind::ConstrainedExistential: { NodePointer unboundType = node->getChild(0); DEMANGLER_ASSERT(unboundType->getKind() == Node::Kind::Type, unboundType); return unboundType; diff --git a/lib/IRGen/GenExistential.cpp b/lib/IRGen/GenExistential.cpp index 58ac7286658f1..ddd29592d4da3 100644 --- a/lib/IRGen/GenExistential.cpp +++ b/lib/IRGen/GenExistential.cpp @@ -1440,16 +1440,23 @@ static const TypeInfo *createExistentialTypeInfo(IRGenModule &IGM, CanType T) { return createErrorExistentialTypeInfo(IGM, layout); } - // Note: Protocol composition types are not nominal, but we name them anyway. - if (auto existential = T->getAs()) { - T = existential->getConstraintType()->getCanonicalType(); - } llvm::StructType *type; - if (isa(T) || isa(T)) + if (T->hasParameterizedExistential()) { type = IGM.createNominalType(T); - else - type = IGM.createNominalType(cast(T.getPointer())); - + } else { + // Note: Protocol composition types are not nominal, but we name them + // anyway. + if (auto existential = T->getAs()) { + T = existential->getConstraintType()->getCanonicalType(); + } + + if (isa(T)) + type = IGM.createNominalType(T); + else + type = + IGM.createNominalType(cast(T.getPointer())); + } + assert(type->isOpaque() && "creating existential type in concrete struct"); // In an opaque metadata, the first two fields are the fixed buffer diff --git a/lib/IRGen/IRGenMangler.cpp b/lib/IRGen/IRGenMangler.cpp index 4a16b969d5137..d3dd63a54b9d0 100644 --- a/lib/IRGen/IRGenMangler.cpp +++ b/lib/IRGen/IRGenMangler.cpp @@ -230,13 +230,17 @@ std::string IRGenMangler::mangleTypeForLLVMTypeName(CanType Ty) { // To make LLVM IR more readable we always add a 'T' prefix so that type names // don't start with a digit and don't need to be quoted. Buffer << 'T'; - if (auto existential = Ty->getAs()) - Ty = existential->getConstraintType()->getCanonicalType(); - if (auto P = dyn_cast(Ty)) { - appendProtocolName(P->getDecl(), /*allowStandardSubstitution=*/false); - appendOperator("P"); - } else { + if (Ty->is() && Ty->hasParameterizedExistential()) { appendType(Ty, nullptr); + } else { + if (auto existential = Ty->getAs()) + Ty = existential->getConstraintType()->getCanonicalType(); + if (auto P = dyn_cast(Ty)) { + appendProtocolName(P->getDecl(), /*allowStandardSubstitution=*/false); + appendOperator("P"); + } else { + appendType(Ty, nullptr); + } } return finalize(); } diff --git a/stdlib/public/Reflection/TypeLowering.cpp b/stdlib/public/Reflection/TypeLowering.cpp index 742a398300c39..8dd80ef049ba2 100644 --- a/stdlib/public/Reflection/TypeLowering.cpp +++ b/stdlib/public/Reflection/TypeLowering.cpp @@ -1758,7 +1758,7 @@ class HasFixedSize } bool - visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { + visitConstrainedExistentialTypeRef(const ConstrainedExistentialTypeRef *CET) { return true; } @@ -1879,7 +1879,7 @@ class HasSingletonMetatype } MetatypeRepresentation - visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { + visitConstrainedExistentialTypeRef(const ConstrainedExistentialTypeRef *CET) { return MetatypeRepresentation::Thin; } @@ -2330,8 +2330,8 @@ class LowerType } const TypeInfo * - visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { - return visitProtocolCompositionTypeRef(PPT->getBase()); + visitConstrainedExistentialTypeRef(const ConstrainedExistentialTypeRef *CET) { + return visitProtocolCompositionTypeRef(CET->getBase()); } const TypeInfo *visitMetatypeTypeRef(const MetatypeTypeRef *M) { diff --git a/stdlib/public/Reflection/TypeRef.cpp b/stdlib/public/Reflection/TypeRef.cpp index b95f3ff8e7d3c..74611dfca8909 100644 --- a/stdlib/public/Reflection/TypeRef.cpp +++ b/stdlib/public/Reflection/TypeRef.cpp @@ -238,11 +238,11 @@ class PrintTypeRef : public TypeRefVisitor { } void - visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { - printHeader("parameterized_protocol"); - printRec(PPT->getBase()); - for (auto param : PPT->getArgs()) - printRec(param); + visitConstrainedExistentialTypeRef(const ConstrainedExistentialTypeRef *CET) { + printHeader("constrained_existential_type"); + printRec(CET->getBase()); + for (auto req : CET->getRequirements()) + visitTypeRefRequirement(req); stream << ")"; } @@ -311,6 +311,27 @@ class PrintTypeRef : public TypeRefVisitor { stream << ")"; } + void visitTypeRefRequirement(const TypeRefRequirement &req) { + printHeader("requirement "); + switch (req.getKind()) { + case RequirementKind::Conformance: + case RequirementKind::Superclass: + printRec(req.getFirstType()); + stream << " : "; + printRec(req.getSecondType()); + break; + case RequirementKind::SameType: + printRec(req.getFirstType()); + stream << " == "; + printRec(req.getSecondType()); + break; + case RequirementKind::Layout: + stream << "layout requirement"; + break; + } + stream << ")"; + } + void visitSILBoxTypeWithLayoutTypeRef(const SILBoxTypeWithLayoutTypeRef *SB) { printHeader("sil_box_with_layout\n"); Indent += 2; @@ -333,24 +354,7 @@ class PrintTypeRef : public TypeRefVisitor { } Indent -= 2; for (auto &req : SB->getRequirements()) { - printHeader("requirement "); - switch (req.getKind()) { - case RequirementKind::Conformance: - case RequirementKind::Superclass: - printRec(req.getFirstType()); - stream << " : "; - printRec(req.getSecondType()); - break; - case RequirementKind::SameType: - printRec(req.getFirstType()); - stream << " == "; - printRec(req.getSecondType()); - break; - case RequirementKind::Layout: - stream << "layout requirement"; - break; - } - stream << ")"; + visitTypeRefRequirement(req); } stream << ")"; stream << ")"; @@ -431,8 +435,8 @@ struct TypeRefIsConcrete } bool - visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { - return visit(PPT->getBase()); + visitConstrainedExistentialTypeRef(const ConstrainedExistentialTypeRef *CET) { + return visit(CET->getBase()); } bool visitMetatypeTypeRef(const MetatypeTypeRef *M) { @@ -777,13 +781,14 @@ class DemanglingForTypeRef } Demangle::NodePointer - visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { - auto node = Dem.createNode(Node::Kind::ParameterizedProtocol); - node->addChild(visit(PPT->getBase()), Dem); - auto genericArgsList = Dem.createNode(Node::Kind::TypeList); - for (auto param : PPT->getArgs()) - genericArgsList->addChild(visit(param), Dem); - node->addChild(genericArgsList, Dem); + visitConstrainedExistentialTypeRef(const ConstrainedExistentialTypeRef *CET) { + auto node = Dem.createNode(Node::Kind::ConstrainedExistential); + node->addChild(visit(CET->getBase()), Dem); + auto constraintList = + Dem.createNode(Node::Kind::ConstrainedExistentialRequirementList); + for (auto req : CET->getRequirements()) + constraintList->addChild(visitTypeRefRequirement(req), Dem); + node->addChild(constraintList, Dem); return node; } @@ -858,6 +863,37 @@ class DemanglingForTypeRef return node; } + Demangle::NodePointer visitTypeRefRequirement(const TypeRefRequirement &req) { + switch (req.getKind()) { + case RequirementKind::Conformance: + case RequirementKind::Superclass: + case RequirementKind::SameType: { + Node::Kind kind; + switch (req.getKind()) { + case RequirementKind::Conformance: + kind = Node::Kind::DependentGenericConformanceRequirement; + break; + case RequirementKind::Superclass: + // A DependentGenericSuperclasseRequirement kind seems to be missing. + kind = Node::Kind::DependentGenericConformanceRequirement; + break; + case RequirementKind::SameType: + kind = Node::Kind::DependentGenericSameTypeRequirement; + break; + default: + llvm_unreachable("Unhandled requirement kind"); + } + auto r = Dem.createNode(kind); + r->addChild(visit(req.getFirstType()), Dem); + r->addChild(visit(req.getSecondType()), Dem); + return r; + } + case RequirementKind::Layout: + // Not implemented. + return nullptr; + } + } + Demangle::NodePointer visitSILBoxTypeWithLayoutTypeRef(const SILBoxTypeWithLayoutTypeRef *SB) { auto node = Dem.createNode(Node::Kind::SILBoxTypeWithLayout); @@ -888,35 +924,10 @@ class DemanglingForTypeRef ++index; } for (auto &req : SB->getRequirements()) { - switch (req.getKind()) { - case RequirementKind::Conformance: - case RequirementKind::Superclass: - case RequirementKind::SameType: { - Node::Kind kind; - switch (req.getKind()) { - case RequirementKind::Conformance: - kind = Node::Kind::DependentGenericConformanceRequirement; - break; - case RequirementKind::Superclass: - // A DependentGenericSuperclasseRequirement kind seems to be missing. - kind = Node::Kind::DependentGenericConformanceRequirement; - break; - case RequirementKind::SameType: - kind = Node::Kind::DependentGenericSameTypeRequirement; - break; - default: - llvm_unreachable("unreachable"); - } - auto r = Dem.createNode(kind); - r->addChild(visit(req.getFirstType()), Dem); - r->addChild(visit(req.getSecondType()), Dem); - signature->addChild(r, Dem); - break; - } - case RequirementKind::Layout: - // Not implemented. - break; - } + auto *r = visitTypeRefRequirement(req); + if (!r) + continue; + signature->addChild(r, Dem); } node->addChild(signature, Dem); auto list = Dem.createNode(Node::Kind::TypeList); @@ -1102,12 +1113,9 @@ class ThickenMetatype } const TypeRef * - visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { - std::vector ThickArgs; - for (auto Param : PPT->getArgs()) - ThickArgs.push_back(visit(Param)); - return ParameterizedProtocolTypeRef::create(Builder, PPT->getBase(), - ThickArgs); + visitConstrainedExistentialTypeRef(const ConstrainedExistentialTypeRef *CET) { + return ConstrainedExistentialTypeRef::create(Builder, CET->getBase(), + CET->getRequirements()); } const TypeRef *visitMetatypeTypeRef(const MetatypeTypeRef *M) { @@ -1257,13 +1265,40 @@ class TypeRefSubstitution return EM; } + llvm::Optional + visitTypeRefRequirement(const TypeRefRequirement &req) { + auto newFirst = visit(req.getFirstType()); + if (!newFirst) + return None; + + switch (req.getKind()) { + case RequirementKind::Conformance: + case RequirementKind::Superclass: + case RequirementKind::SameType: { + auto newSecond = visit(req.getFirstType()); + if (!newSecond) + return None; + return TypeRefRequirement(req.getKind(), newFirst, newSecond); + } + case RequirementKind::Layout: + return TypeRefRequirement(req.getKind(), newFirst, + req.getLayoutConstraint()); + } + + llvm_unreachable("Unhandled RequirementKind in switch."); + } + const TypeRef * - visitParameterizedProtocolTypeRef(const ParameterizedProtocolTypeRef *PPT) { - std::vector substArg; - for (auto Param : PPT->getArgs()) - substArg.push_back(visit(Param)); - return ParameterizedProtocolTypeRef::create(Builder, PPT->getBase(), - substArg); + visitConstrainedExistentialTypeRef(const ConstrainedExistentialTypeRef *CET) { + std::vector constraints; + for (auto Req : CET->getRequirements()) { + auto substReq = visitTypeRefRequirement(Req); + if (!substReq) + continue; + constraints.emplace_back(*substReq); + } + return ConstrainedExistentialTypeRef::create(Builder, CET->getBase(), + constraints); } const TypeRef * diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index e766cfbce15c2..072cf5a8e6a72 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -1312,6 +1312,29 @@ class DecodedMetadataBuilder { /// Ownership information related to the metadata we are trying to lookup. TypeReferenceOwnership ReferenceOwnership; +public: + struct BuiltLayoutConstraint { + bool operator==(BuiltLayoutConstraint rhs) const { return true; } + operator bool() const { return true; } + }; + using BuiltLayoutConstraint = BuiltLayoutConstraint; +#if LLVM_PTR_SIZE == 4 + /// Unfortunately the alignment of TypeRef is too large to squeeze in 3 extra + /// bits on (some?) 32-bit systems. + class BigBuiltTypeIntPair { + BuiltType Ptr; + RequirementKind Int; + + public: + BigBuiltTypeIntPair(BuiltType ptr, RequirementKind i) : Ptr(ptr), Int(i) {} + RequirementKind getInt() const { return Int; } + BuiltType getPointer() const { return Ptr; } + uint64_t getOpaqueValue() const { + return (uint64_t)Ptr | ((uint64_t)Int << 32); + } + }; +#endif + public: DecodedMetadataBuilder(Demangler &demangler, SubstGenericParameterFn substGenericParameter, @@ -1327,6 +1350,23 @@ class DecodedMetadataBuilder { using BuiltSubstitution = std::pair; using BuiltSubstitutionMap = llvm::ArrayRef; using BuiltGenericTypeParam = const Metadata *; + struct Requirement : public RequirementBase, + +#endif + BuiltLayoutConstraint> { + Requirement(RequirementKind kind, BuiltType first, BuiltType second) + : RequirementBase(kind, first, second) {} + Requirement(RequirementKind kind, BuiltType first, + BuiltLayoutConstraint second) + : RequirementBase(kind, first, second) {} + }; + using BuiltRequirement = Requirement; BuiltType decodeMangledType(NodePointer node, bool forRequirement = true) { @@ -1522,8 +1562,8 @@ class DecodedMetadataBuilder { } TypeLookupErrorOr - createParameterizedProtocolType(BuiltType base, - llvm::ArrayRef args) const { + createConstrainedExistentialType(BuiltType base, + llvm::ArrayRef rs) const { // FIXME: Runtime plumbing. return BuiltType(); } @@ -1650,11 +1690,6 @@ class DecodedMetadataBuilder { } using BuiltSILBoxField = llvm::PointerIntPair; - struct BuiltLayoutConstraint { - bool operator==(BuiltLayoutConstraint rhs) const { return true; } - operator bool() const { return true; } - }; - using BuiltLayoutConstraint = BuiltLayoutConstraint; BuiltLayoutConstraint getLayoutConstraint(LayoutConstraintKind kind) { return {}; } @@ -1664,38 +1699,6 @@ class DecodedMetadataBuilder { return {}; } -#if LLVM_PTR_SIZE == 4 - /// Unfortunately the alignment of TypeRef is too large to squeeze in 3 extra - /// bits on (some?) 32-bit systems. - class BigBuiltTypeIntPair { - BuiltType Ptr; - RequirementKind Int; - public: - BigBuiltTypeIntPair(BuiltType ptr, RequirementKind i) : Ptr(ptr), Int(i) {} - RequirementKind getInt() const { return Int; } - BuiltType getPointer() const { return Ptr; } - uint64_t getOpaqueValue() const { - return (uint64_t)Ptr | ((uint64_t)Int << 32); - } - }; -#endif - - struct Requirement : public RequirementBase, - -#endif - BuiltLayoutConstraint> { - Requirement(RequirementKind kind, BuiltType first, BuiltType second) - : RequirementBase(kind, first, second) {} - Requirement(RequirementKind kind, BuiltType first, - BuiltLayoutConstraint second) - : RequirementBase(kind, first, second) {} - }; - using BuiltRequirement = Requirement; - TypeLookupErrorOr createSILBoxTypeWithLayout( llvm::ArrayRef Fields, llvm::ArrayRef Substitutions, diff --git a/test/Demangle/Inputs/manglings.txt b/test/Demangle/Inputs/manglings.txt index a235814704c39..63f6534e5b1cd 100644 --- a/test/Demangle/Inputs/manglings.txt +++ b/test/Demangle/Inputs/manglings.txt @@ -427,9 +427,8 @@ $s1A3bar1aySSYt_tF ---> A.bar(a: _const Swift.String) -> () $s1t1fyyFSiAA3StrVcs7KeyPathCyADSiGcfu_SiADcfu0_33_556644b740b1b333fecb81e55a7cce98ADSiTf3npk_n ---> function signature specialization ]> of implicit closure #2 (t.Str) -> Swift.Int in implicit closure #1 (Swift.KeyPath) -> (t.Str) -> Swift.Int in t.f() -> () $s21back_deploy_attribute0A12DeployedFuncyyFTwb ---> back deployment thunk for back_deploy_attribute.backDeployedFunc() -> () $s21back_deploy_attribute0A12DeployedFuncyyFTwB ---> back deployment fallback for back_deploy_attribute.backDeployedFunc() -> () -$s4test3FooVAAyyAA1P_pyxqd__XPlF ---> test.Foo.test(test.P) -> () -$s4test3FooVAAyyAA1P_pyxXPF ---> test.Foo.test(test.P) -> () +$s4test3fooyyAA1P_px1TRts_XPlF ---> test.foo(any test.P) -> () +$s4test3fooyyAA1P_pSS1TAaCPRts_Si1UAERtsXPF ---> test.foo(any test.P) -> () $s4test3FooVAAyyAA1P_pF ---> test.Foo.test(test.P) -> () -$s4test3FooVAAyyAA1P_pyqd__XPAaDRd__lF ---> test.Foo.test(test.P) -> () $sxxxIxzCXxxxesy -> $sxxxIxzCXxxxesy $Sxxx_x_xxIxzCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC$x -> $Sxxx_x_xxIxzCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC$x diff --git a/test/IRGen/existential_shape_metadata.swift b/test/IRGen/existential_shape_metadata.swift index 694bc8d679761..3f2935814c53d 100644 --- a/test/IRGen/existential_shape_metadata.swift +++ b/test/IRGen/existential_shape_metadata.swift @@ -1,16 +1,16 @@ // RUN: %target-swift-frontend -emit-ir %s -swift-version 5 -disable-availability-checking | %IRGenFileCheck %s -// CHECK-LABEL: @"$sl26existential_shape_metadata2Q0_pyxXPXGMq" = linkonce_odr hidden constant +// CHECK-LABEL: @"$sl26existential_shape_metadata2Q0_px1TRts_XPXGMq" = linkonce_odr hidden constant // CHECK-SAME: { i32 {{.*}}sub ([[INT]] ptrtoint (i8** @{{[0-9]+}} to [[INT]]) // CHECK-SAME: i32 6400, -// CHECK-SAME: i32 {{.*}} @"flat unique 26existential_shape_metadata2Q0_pyxXP" +// CHECK-SAME: i32 {{.*}} @"flat unique 26existential_shape_metadata2Q0_px1TAaBPRts_XP" // CHECK-SAME: i16 2, i16 2, i16 3, i16 0, // CHECK-SAME: i16 1, i16 0, i16 1, i16 0, i32 1, -// CHECK-LABEL: @"$sl26existential_shape_metadata2R033_881A0B6978EB4286E7CFF1E27030ACACLL_pyxXPXG" = internal constant +// CHECK-LABEL: @"$sl26existential_shape_metadata2R033_881A0B6978EB4286E7CFF1E27030ACACLL_px1TRts_XPXG" = internal constant // CHECK-SAME: { i32 6400, // This could use a symbolic reference because this doesn't have to be uniqued. -// CHECK-SAME: i32 {{.*}} @"flat unique 26existential_shape_metadata2R033_881A0B6978EB4286E7CFF1E27030ACACLL_pyxXP" +// CHECK-SAME: i32 {{.*}} @"flat unique 26existential_shape_metadata2R033_881A0B6978EB4286E7CFF1E27030ACACLL_px1TAabCLLPRts_XP" // CHECK-SAME: i16 2, i16 2, i16 3, i16 0, // CHECK-SAME: i16 1, i16 0, i16 1, i16 0, i32 1, @@ -37,24 +37,24 @@ private struct C {} // CHECK-LABEL: define{{.*}} @"$s26existential_shape_metadata12testConcrete public func testConcrete() -> Any.Type { - // CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s26existential_shape_metadata2Q0_pySiXPMa"([[INT]] 0) + // CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s26existential_shape_metadata2Q0_pSi1TAaBPRts_XPMa"([[INT]] 0) // CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 // CHECK: ret %swift.type* [[METADATA]] return (any Q0).self } -// CHECK-LABEL: define{{.*}} linkonce_odr hidden swiftcc %swift.metadata_response @"$s26existential_shape_metadata2Q0_pySiXPMa"( +// CHECK-LABEL: define{{.*}} linkonce_odr hidden swiftcc %swift.metadata_response @"$s26existential_shape_metadata2Q0_pSi1TAaBPRts_XPMa"( // CHECK: [[ENTRY:.*]]: // CHECK: [[ARGS:%.*]] = alloca [1 x i8*], align - // CHECK: [[LOAD:%.*]] = load %swift.type*, %swift.type** @"$s26existential_shape_metadata2Q0_pySiXPML", align + // CHECK: [[LOAD:%.*]] = load %swift.type*, %swift.type** @"$s26existential_shape_metadata2Q0_pSi1TAaBPRts_XPML", align // CHECK: [[NULL:%.*]] = icmp eq %swift.type* [[LOAD]], null // CHECK: br i1 [[NULL]], label %[[CACHE_IS_NULL:.*]], label %[[CONT:.*]] // CHECK: [[CACHE_IS_NULL]]: // CHECK: [[T0:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[ARGS]], i32 0, i32 0 // CHECK: store i8* bitcast (%swift.type* @"$sSiN" to i8*), i8** [[T0]], align // CHECK: [[T0:%.*]] = bitcast [1 x i8*]* [[ARGS]] to i8** - // CHECK: [[CALL:%.*]] = call %swift.type* @swift_getExtendedExistentialTypeMetadata({{.*}}@"$sl26existential_shape_metadata2Q0_pyxXPXGMq{{(\.ptrauth)?}}" to i8*), i8** [[T0]]) - // CHECK: store atomic %swift.type* [[CALL]], %swift.type** @"$s26existential_shape_metadata2Q0_pySiXPML" release, align + // CHECK: [[CALL:%.*]] = call %swift.type* @swift_getExtendedExistentialTypeMetadata({{.*}}@"$sl26existential_shape_metadata2Q0_px1TRts_XPXGMq{{(\.ptrauth)?}}" to i8*), i8** [[T0]]) + // CHECK: store atomic %swift.type* [[CALL]], %swift.type** @"$s26existential_shape_metadata2Q0_pSi1TAaBPRts_XPML" release, align // CHECK: br label %[[CONT]] // CHECK: [[CONT]]: // CHECK: [[METADATA:%.*]] = phi %swift.type* [ [[LOAD]], %[[ENTRY]] ], [ [[CALL]], %[[CACHE_IS_NULL]] ] @@ -70,7 +70,7 @@ public func testDependent(t: T.Type) -> Any.Type { // CHECK: [[T1:%.*]] = bitcast %swift.type* %T to i8* // CHECK: store i8* [[T1]], i8** [[T0]], align // CHECK: [[T0:%.*]] = bitcast [1 x i8*]* [[ARGS]] to i8** - // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_getExtendedExistentialTypeMetadata({{.*}}@"$sl26existential_shape_metadata2Q0_pyxXPXGMq{{(\.ptrauth)?}}" to i8*), i8** [[T0]]) + // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_getExtendedExistentialTypeMetadata({{.*}}@"$sl26existential_shape_metadata2Q0_px1TRts_XPXGMq{{(\.ptrauth)?}}" to i8*), i8** [[T0]]) // CHECK: ret %swift.type* [[METADATA]] return (any Q0).self } @@ -85,7 +85,7 @@ public func testComplexApplication(t: T.Type) -> Any.Type { // CHECK: [[T1:%.*]] = bitcast %swift.type* [[B_T]] to i8* // CHECK: store i8* [[T1]], i8** [[T0]], align // CHECK: [[T0:%.*]] = bitcast [1 x i8*]* [[ARGS]] to i8** - // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_getExtendedExistentialTypeMetadata({{.*}}@"$sl26existential_shape_metadata2Q0_pyxXPXGMq{{(\.ptrauth)?}}" to i8*), i8** [[T0]]) + // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_getExtendedExistentialTypeMetadata({{.*}}@"$sl26existential_shape_metadata2Q0_px1TRts_XPXGMq{{(\.ptrauth)?}}" to i8*), i8** [[T0]]) // CHECK: ret %swift.type* [[METADATA]] return (any Q0>).self } @@ -99,7 +99,7 @@ public func test_private(t: T.Type) -> Any.Type { // CHECK: store i8* [[T1]], i8** [[T0]], align // CHECK: [[T0:%.*]] = bitcast [1 x i8*]* [[ARGS]] to i8** // FIXME: this should be unique? - // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_getExtendedExistentialTypeMetadata_unique({{.*}}@"$sl26existential_shape_metadata2R033_881A0B6978EB4286E7CFF1E27030ACACLL_pyxXPXG{{(\.ptrauth)?}}" to i8*), i8** [[T0]]) + // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_getExtendedExistentialTypeMetadata_unique({{.*}}@"$sl26existential_shape_metadata2R033_881A0B6978EB4286E7CFF1E27030ACACLL_px1TRts_XPXG{{(\.ptrauth)?}}" to i8*), i8** [[T0]]) // CHECK: ret %swift.type* [[METADATA]] return (any R0).self } @@ -108,7 +108,7 @@ public func test_private(t: T.Type) -> Any.Type { // change anything: the shape is still public. // CHECK-LABEL: define{{.*}} @"$s26existential_shape_metadata23test_privateApplication public func test_privateApplication(t: T.Type) -> Any.Type { - // CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s26existential_shape_metadata2Q0_pyAA1C33_881A0B6978EB4286E7CFF1E27030ACACLLVXPMa"([[INT]] 0) + // CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s26existential_shape_metadata2Q0_pAA1C33_881A0B6978EB4286E7CFF1E27030ACACLLV1TAaBPRts_XPMa"([[INT]] 0) // CHECK: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 // CHECK: ret %swift.type* [[METADATA]] return (any Q0).self @@ -116,9 +116,9 @@ public func test_privateApplication(t: T.Type) -> Any.Type { // FIXME: this accessor should have internal linkage, but we compute // formal linkage wrong for types -// CHECK-LABEL: define{{.*}} linkonce_odr hidden swiftcc %swift.metadata_response @"$s26existential_shape_metadata2Q0_pyAA1C33_881A0B6978EB4286E7CFF1E27030ACACLLVXPMa"( +// CHECK-LABEL: define{{.*}} linkonce_odr hidden swiftcc %swift.metadata_response @"$s26existential_shape_metadata2Q0_pAA1C33_881A0B6978EB4286E7CFF1E27030ACACLLV1TAaBPRts_XPMa"( // CHECK: [[ARGS:%.*]] = alloca [1 x i8*], align // CHECK: [[T0:%.*]] = getelementptr inbounds [1 x i8*], [1 x i8*]* [[ARGS]], i32 0, i32 0 // CHECK: store i8* {{.*}}"$s26existential_shape_metadata1C33_881A0B6978EB4286E7CFF1E27030ACACLLVMf"{{.*}}, i8** [[T0]], align // CHECK: [[T0:%.*]] = bitcast [1 x i8*]* [[ARGS]] to i8** - // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_getExtendedExistentialTypeMetadata({{.*}}@"$sl26existential_shape_metadata2Q0_pyxXPXGMq{{(\.ptrauth)?}}" to i8*), i8** [[T0]]) + // CHECK: [[METADATA:%.*]] = call %swift.type* @swift_getExtendedExistentialTypeMetadata({{.*}}@"$sl26existential_shape_metadata2Q0_px1TRts_XPXGMq{{(\.ptrauth)?}}" to i8*), i8** [[T0]]) diff --git a/test/SILGen/parameterized_existentials.swift b/test/SILGen/parameterized_existentials.swift index 4f40475c49646..252ced960083b 100644 --- a/test/SILGen/parameterized_existentials.swift +++ b/test/SILGen/parameterized_existentials.swift @@ -24,7 +24,7 @@ struct S: Q { struct R { var force: () -> any P - // CHECK-LABEL: sil hidden [ossa] @$s13parameterized1RV5forceACyxq_q0_GAA1P_pyxq_q0_XPyc_tcfC : $@convention(method) (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> () -> @out P<τ_0_0, τ_0_1, τ_0_2> for , @thin R.Type) -> @owned R { + // CHECK-LABEL: sil hidden [ossa] @$s13parameterized1RV5forceACyxq_q0_GAA1P_px1TRts_q_1URtsq0_1VRtsXPyc_tcfC : $@convention(method) (@owned @callee_guaranteed @substituted <τ_0_0, τ_0_1, τ_0_2> () -> @out P<τ_0_0, τ_0_1, τ_0_2> for , @thin R.Type) -> @owned R { } // CHECK-LABEL: sil hidden [ossa] @$s13parameterized6upcastyAA1P_pAA1SVF : $@convention(thin) (S) -> @out P { @@ -75,26 +75,26 @@ func reuse(_ k: () -> any P) {} func upcastResult() { // CHECK: [[RES_FN:%.*]] = function_ref @$s13parameterized12upcastResultyyFAA1SVyXEfU_ : $@convention(thin) () -> S // CHECK: [[THICK_RES_FN:%.*]] = thin_to_thick_function [[RES_FN]] : $@convention(thin) () -> S to $@noescape @callee_guaranteed () -> S - // CHECK: [[S_TO_P_RES_THUNK_FN:%.*]] = function_ref @$s13parameterized1SVIgd_AA1P_pySiSSSfXPIegr_TR : $@convention(thin) (@noescape @callee_guaranteed () -> S) -> @out P + // CHECK: [[S_TO_P_RES_THUNK_FN:%.*]] = function_ref @$s13parameterized1SVIgd_AA1P_pSi1TAaDPRts_SS1UAFRtsSf1VAFRtsXPIegr_TR : $@convention(thin) (@noescape @callee_guaranteed () -> S) -> @out P // CHECK: [[PARTIAL_RES_THUNK_FN:%.*]] = partial_apply [callee_guaranteed] [[S_TO_P_RES_THUNK_FN]]([[THICK_RES_FN]]) : $@convention(thin) (@noescape @callee_guaranteed () -> S) -> @out P // CHECK: [[NOESCAPE_RES_THUNK_FN:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_RES_THUNK_FN]] : $@callee_guaranteed () -> @out P to $@noescape @callee_guaranteed () -> @out P - // CHECK: [[REUSE_FN:%.*]] = function_ref @$s13parameterized5reuseyyAA1P_pySiSSSfXPyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> @out P) -> () + // CHECK: [[REUSE_FN:%.*]] = function_ref @$s13parameterized5reuseyyAA1P_pSi1TAaCPRts_SS1UAERtsSf1VAERtsXPyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> @out P) -> () // CHECK: {{%.*}} = apply [[REUSE_FN]]([[NOESCAPE_RES_THUNK_FN]]) : $@convention(thin) (@noescape @callee_guaranteed () -> @out P) -> () reuse({ () -> S in S() }) - // CHECK: [[RES_Q_FN:%.*]] = function_ref @$s13parameterized12upcastResultyyFAA1Q_pySiSSSfXPyXEfU0_ : $@convention(thin) () -> @out Q + // CHECK: [[RES_Q_FN:%.*]] = function_ref @$s13parameterized12upcastResultyyFAA1Q_pSi1XAaCPRts_SS1YAERtsSf1ZAERtsXPyXEfU0_ : $@convention(thin) () -> @out Q // CHECK: [[THICK_NOESCAPE_RES_Q_FN:%.*]] = thin_to_thick_function [[RES_Q_FN]] : $@convention(thin) () -> @out Q to $@noescape @callee_guaranteed () -> @out Q - // CHECK: [[P_TO_Q_RES_THUNK_FN:%.*]] = function_ref @$s13parameterized1Q_pySiSSSfXPIgr_AA1P_pySiSSSfXPIegr_TR : $@convention(thin) (@noescape @callee_guaranteed () -> @out Q) -> @out P + // CHECK: [[P_TO_Q_RES_THUNK_FN:%.*]] = function_ref @$s13parameterized1Q_pSi1XAaBPRts_SS1YADRtsSf1ZADRtsXPIgr_AA1P_pSi1TAaJPRts_SS1UALRtsSf1VALRtsXPIegr_TR : $@convention(thin) (@noescape @callee_guaranteed () -> @out Q) -> @out P // CHECK: [[PARTIAL_P_TO_Q_RES_THUNK_FN:%.*]] = partial_apply [callee_guaranteed] [[P_TO_Q_RES_THUNK_FN]]([[THICK_NOESCAPE_RES_Q_FN]]) : $@convention(thin) (@noescape @callee_guaranteed () -> @out Q) -> @out P // CHECK: [[NOESCAPE_PARTIAL_P_TO_Q_RES_THUNK_FN:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PARTIAL_P_TO_Q_RES_THUNK_FN]] : $@callee_guaranteed () -> @out P to $@noescape @callee_guaranteed () -> @out P - // CHECK: [[REUSE_FN:%.*]] = function_ref @$s13parameterized5reuseyyAA1P_pySiSSSfXPyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> @out P) -> () + // CHECK: [[REUSE_FN:%.*]] = function_ref @$s13parameterized5reuseyyAA1P_pSi1TAaCPRts_SS1UAERtsSf1VAERtsXPyXEF : $@convention(thin) (@noescape @callee_guaranteed () -> @out P) -> () // CHECK: {{%.*}} = apply [[REUSE_FN]]([[NOESCAPE_PARTIAL_P_TO_Q_RES_THUNK_FN]]) : $@convention(thin) (@noescape @callee_guaranteed () -> @out P) -> () reuse({ () -> any Q in S() }) } -// CHECK-LABEL: sil hidden [ossa] @$s13parameterized5forceAA1P_pyxq_q0_XPyr1_lF : $@convention(thin) () -> @out P { +// CHECK-LABEL: sil hidden [ossa] @$s13parameterized5forceAA1P_px1TRts_q_1URtsq0_1VRtsXPyr1_lF : $@convention(thin) () -> @out P { func force() -> any P { return R(force: { force() }).force() } diff --git a/test/SILOptimizer/cast_folding_parameterized_protocol.swift b/test/SILOptimizer/cast_folding_parameterized_protocol.swift index aab2fa9b18497..48637841ceef5 100644 --- a/test/SILOptimizer/cast_folding_parameterized_protocol.swift +++ b/test/SILOptimizer/cast_folding_parameterized_protocol.swift @@ -49,7 +49,7 @@ public func concrete_to_existential(_ x: X, _ yt: Y, _ yi: Y) { use(yi as! any Q) } -// CHECK-LABEL: sil @$s35cast_folding_parameterized_protocol23existential_to_concreteyyxm_AA1P_pyxXPtlF : $@convention(thin) (@thick T.Type, @in_guaranteed P) -> () +// CHECK-LABEL: sil @$s35cast_folding_parameterized_protocol23existential_to_concreteyyxm_AA1P_px1TRts_XPtlF : $@convention(thin) (@thick T.Type, @in_guaranteed P) -> () public func existential_to_concrete(_: T.Type, _ p: any P) { // CHECK: unconditional_checked_cast_addr P in {{%.*}} : $*P to X in {{%.*}} : $*X _ = p as! X @@ -61,7 +61,7 @@ public func existential_to_concrete(_: T.Type, _ p: any P) { _ = p as! Y } -// CHECK-LABEL: sil @$s35cast_folding_parameterized_protocol015existential_to_E0yyAA1P_pyxXP_AA1Q_ptlF : $@convention(thin) (@in_guaranteed P, @in_guaranteed Q) -> () +// CHECK-LABEL: sil @$s35cast_folding_parameterized_protocol015existential_to_E0yyAA1P_px1TRts_XP_AA1Q_ptlF : $@convention(thin) (@in_guaranteed P, @in_guaranteed Q) -> () public func existential_to_existential(_ p: any P, _ q: any Q) { // CHECK: unconditional_checked_cast_addr P in {{%.*}} : $*P to Q in {{%.*}} : $*Q _ = p as! any Q diff --git a/unittests/runtime/SpecifierDSL.h b/unittests/runtime/SpecifierDSL.h index 5ed328c3b3c13..f87c40891257d 100644 --- a/unittests/runtime/SpecifierDSL.h +++ b/unittests/runtime/SpecifierDSL.h @@ -58,18 +58,17 @@ struct MemberTypeSpecifier { struct ProtocolTypeSpecifier { ProtocolSpecifier protocol; }; -struct ParameterizedProtocolTypeSpecifier { +struct ConstrainedExistentialTypeSpecifier { ProtocolSpecifier base; std::vector> args; }; struct ProtocolCompositionTypeSpecifier { std::vector components; }; -struct TypeSpecifier : TaggedUnion { +struct TypeSpecifier + : TaggedUnion { using TaggedUnion::TaggedUnion; }; @@ -137,8 +136,7 @@ inline TypeSpecifier parameterizedProtocol(ProtocolSpecifier &&base, Specs &&...specs) { std::vector> args; addParameterizedProtocolArguments(args, std::forward(specs)...); - return ParameterizedProtocolTypeSpecifier{std::move(base), - std::move(args)}; + return ConstrainedExistentialTypeSpecifier{std::move(base), std::move(args)}; } /// A class which "demangles" various DSL specifiers into demangle @@ -212,8 +210,8 @@ class Demangler { {node(Kind::TypeList, components)}); } - NodePointer demangleParameterizedProtocolType( - const ParameterizedProtocolTypeSpecifier &spec) { + NodePointer demangleConstrainedExistentialType( + const ConstrainedExistentialTypeSpecifier &spec) { // Demangle the base protocol and then wrap it up like the tree expects, // which for some reason is this. auto base = demangleProtocol(spec.base); @@ -222,14 +220,29 @@ class Demangler { {node(Kind::Type, {base})})}); - std::vector argVector; + std::vector reqVector; + bool firstReq = false; for (auto &arg: spec.args) { - // TODO: also include the associated type names - argVector.push_back(demangleType(arg.second)); + auto depType = + node(Kind::Type, + {node(Kind::DependentMemberType, + {node(Kind::Type, + {factory.createNode(Kind::ConstrainedExistentialSelf), + node(Kind::DependentAssociatedTypeRef, + {factory.createNode(Kind::Identifier, arg.first), + node(Kind::Type, + {demangleProtocol(spec.base)})})})})}); + auto constraintType = demangleType(arg.second); + reqVector.push_back(node(Kind::DependentGenericSameTypeRequirement, + {depType, constraintType})); + if (firstReq) { + reqVector.push_back(node(Kind::FirstElementMarker, {})); + firstReq = false; + } } - auto args = node(Kind::TypeList, argVector); - return node(Kind::ParameterizedProtocol, - {base, args}); + NodePointer constraints = + node(Node::Kind::ConstrainedExistentialRequirementList, reqVector); + return node(Kind::ConstrainedExistential, {base, constraints}); } NodePointer demangleTypeImpl(const TypeSpecifier &spec) { @@ -240,7 +253,7 @@ class Demangler { CASE(MemberType) CASE(ProtocolType) CASE(ProtocolCompositionType) - CASE(ParameterizedProtocolType) + CASE(ConstrainedExistentialType) #undef CASE swift_unreachable("unknown type specifier"); } From f30bf85aece1aaf4a523a078c8dd15322d8beaec Mon Sep 17 00:00:00 2001 From: John McCall Date: Fri, 1 Jul 2022 11:20:56 -0400 Subject: [PATCH 2/2] Fix the build on 32-bit targets. --- stdlib/public/runtime/MetadataLookup.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stdlib/public/runtime/MetadataLookup.cpp b/stdlib/public/runtime/MetadataLookup.cpp index 072cf5a8e6a72..ee2b3c4c4816f 100644 --- a/stdlib/public/runtime/MetadataLookup.cpp +++ b/stdlib/public/runtime/MetadataLookup.cpp @@ -1313,6 +1313,8 @@ class DecodedMetadataBuilder { TypeReferenceOwnership ReferenceOwnership; public: + using BuiltType = const Metadata *; + struct BuiltLayoutConstraint { bool operator==(BuiltLayoutConstraint rhs) const { return true; } operator bool() const { return true; } @@ -1343,7 +1345,6 @@ class DecodedMetadataBuilder { substGenericParameter(substGenericParameter), substWitnessTable(substWitnessTable) { } - using BuiltType = const Metadata *; using BuiltTypeDecl = const ContextDescriptor *; using BuiltProtocolDecl = ProtocolDescriptorRef; using BuiltGenericSignature = const Metadata *;