@@ -2610,12 +2610,13 @@ void ASTMangler::appendSymbolicReference(SymbolicReferent referent) {
26102610static void reconcileInverses (
26112611 SmallVector<InverseRequirement, 2 > &inverses,
26122612 GenericSignature sig,
2613- std::optional<unsigned > inversesAlreadyMangledDepth) {
2613+ std::optional<unsigned > inversesAlreadyMangledDepth,
2614+ std::optional<unsigned > suppressedInnermostDepth) {
26142615 CanGenericSignature baseSig;
26152616 if (sig)
26162617 baseSig = sig.getCanonicalSignature ();
26172618
2618- if (baseSig || inversesAlreadyMangledDepth)
2619+ if (baseSig || inversesAlreadyMangledDepth || suppressedInnermostDepth )
26192620 llvm::erase_if (inverses, [&](InverseRequirement const & inv) -> bool {
26202621 // Drop inverses that aren't applicable in the nested / child signature,
26212622 // because of an added requirement.
@@ -2630,6 +2631,10 @@ static void reconcileInverses(
26302631 if (gp->getDepth () <= limit)
26312632 return true ;
26322633
2634+ if (suppressedInnermostDepth &&
2635+ gp->getDepth () == *suppressedInnermostDepth)
2636+ return true ;
2637+
26332638 return false ;
26342639 });
26352640
@@ -3353,7 +3358,8 @@ void ASTMangler::gatherGenericSignatureParts(GenericSignature sig,
33533358 // Process inverses relative to the base entity's signature.
33543359 if (AllowInverses) {
33553360 // Simplify and canonicalize inverses.
3356- reconcileInverses (inverseReqs, base.getSignature (), base.getDepth ());
3361+ reconcileInverses (inverseReqs, base.getSignature (), base.getDepth (),
3362+ base.getSuppressedInnermostInversesDepth ());
33573363 } else {
33583364 inverseReqs.clear ();
33593365 }
@@ -4654,6 +4660,31 @@ void ASTMangler::appendConstrainedExistential(Type base, GenericSignature sig,
46544660 return appendOperator (" XP" );
46554661}
46564662
4663+ // / Determine whether this declaration can only occur within the primary
4664+ // / type definition.
4665+ static bool canOnlyOccurInPrimaryTypeDefinition (const Decl *decl) {
4666+ // Enum elements always occur within the primary definition.
4667+ if (isa<EnumElementDecl>(decl))
4668+ return true ;
4669+
4670+ return false ;
4671+ }
4672+
4673+ // / When the immediate enclosing context of this declaration is
4674+ // / a generic type (with its own generic parameters), return the depth of
4675+ // / the innermost generic parameters.
4676+ static std::optional<unsigned > getEnclosingTypeGenericDepth (const Decl *decl) {
4677+ auto typeDecl = dyn_cast<GenericTypeDecl>(decl->getDeclContext ());
4678+ if (!typeDecl)
4679+ return std::nullopt ;
4680+
4681+ auto genericParams = typeDecl->getGenericParams ();
4682+ if (!genericParams)
4683+ return std::nullopt ;
4684+
4685+ return genericParams->getParams ().back ()->getDepth ();
4686+ }
4687+
46574688ASTMangler::BaseEntitySignature::BaseEntitySignature (const Decl *decl)
46584689 : sig(nullptr ), innermostTypeDecl(true ), extension(false ),
46594690 mangledDepth(std::nullopt ) {
@@ -4668,12 +4699,22 @@ ASTMangler::BaseEntitySignature::BaseEntitySignature(const Decl *decl)
46684699 case DeclKind::Enum:
46694700 case DeclKind::Struct:
46704701 case DeclKind::Class:
4702+ case DeclKind::EnumElement:
46714703 sig = decl->getInnermostDeclContext ()->getGenericSignatureOfContext ();
46724704
46734705 // Protocol members never mangle inverse constraints on `Self`.
46744706 if (isa<ProtocolDecl>(decl->getDeclContext ()))
46754707 setDepth (0 );
46764708
4709+ // Declarations that can only occur in the primary type definition should
4710+ // not mangle inverses for the generic parameters of that type definition.
4711+ // This allows types to introduce conditional conformances to invertible
4712+ // protocols without breaking ABI.
4713+ if (canOnlyOccurInPrimaryTypeDefinition (decl)) {
4714+ if (auto depth = getEnclosingTypeGenericDepth (decl))
4715+ suppressedInnermostDepth = depth;
4716+ }
4717+
46774718 break ;
46784719
46794720 case DeclKind::TypeAlias: // FIXME: is this right? typealiases have a generic signature!
@@ -4686,7 +4727,6 @@ ASTMangler::BaseEntitySignature::BaseEntitySignature(const Decl *decl)
46864727 case DeclKind::Module:
46874728 case DeclKind::Param:
46884729 case DeclKind::Macro:
4689- case DeclKind::EnumElement:
46904730 case DeclKind::Extension:
46914731 case DeclKind::TopLevelCode:
46924732 case DeclKind::Import:
0 commit comments