@@ -2610,12 +2610,13 @@ void ASTMangler::appendSymbolicReference(SymbolicReferent referent) {
2610
2610
static void reconcileInverses (
2611
2611
SmallVector<InverseRequirement, 2 > &inverses,
2612
2612
GenericSignature sig,
2613
- std::optional<unsigned > inversesAlreadyMangledDepth) {
2613
+ std::optional<unsigned > inversesAlreadyMangledDepth,
2614
+ std::optional<unsigned > suppressedInnermostDepth) {
2614
2615
CanGenericSignature baseSig;
2615
2616
if (sig)
2616
2617
baseSig = sig.getCanonicalSignature ();
2617
2618
2618
- if (baseSig || inversesAlreadyMangledDepth)
2619
+ if (baseSig || inversesAlreadyMangledDepth || suppressedInnermostDepth )
2619
2620
llvm::erase_if (inverses, [&](InverseRequirement const & inv) -> bool {
2620
2621
// Drop inverses that aren't applicable in the nested / child signature,
2621
2622
// because of an added requirement.
@@ -2630,6 +2631,10 @@ static void reconcileInverses(
2630
2631
if (gp->getDepth () <= limit)
2631
2632
return true ;
2632
2633
2634
+ if (suppressedInnermostDepth &&
2635
+ gp->getDepth () == *suppressedInnermostDepth)
2636
+ return true ;
2637
+
2633
2638
return false ;
2634
2639
});
2635
2640
@@ -3353,7 +3358,8 @@ void ASTMangler::gatherGenericSignatureParts(GenericSignature sig,
3353
3358
// Process inverses relative to the base entity's signature.
3354
3359
if (AllowInverses) {
3355
3360
// Simplify and canonicalize inverses.
3356
- reconcileInverses (inverseReqs, base.getSignature (), base.getDepth ());
3361
+ reconcileInverses (inverseReqs, base.getSignature (), base.getDepth (),
3362
+ base.getSuppressedInnermostInversesDepth ());
3357
3363
} else {
3358
3364
inverseReqs.clear ();
3359
3365
}
@@ -4654,6 +4660,31 @@ void ASTMangler::appendConstrainedExistential(Type base, GenericSignature sig,
4654
4660
return appendOperator (" XP" );
4655
4661
}
4656
4662
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
+
4657
4688
ASTMangler::BaseEntitySignature::BaseEntitySignature (const Decl *decl)
4658
4689
: sig(nullptr ), innermostTypeDecl(true ), extension(false ),
4659
4690
mangledDepth(std::nullopt) {
@@ -4668,12 +4699,22 @@ ASTMangler::BaseEntitySignature::BaseEntitySignature(const Decl *decl)
4668
4699
case DeclKind::Enum:
4669
4700
case DeclKind::Struct:
4670
4701
case DeclKind::Class:
4702
+ case DeclKind::EnumElement:
4671
4703
sig = decl->getInnermostDeclContext ()->getGenericSignatureOfContext ();
4672
4704
4673
4705
// Protocol members never mangle inverse constraints on `Self`.
4674
4706
if (isa<ProtocolDecl>(decl->getDeclContext ()))
4675
4707
setDepth (0 );
4676
4708
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
+
4677
4718
break ;
4678
4719
4679
4720
case DeclKind::TypeAlias: // FIXME: is this right? typealiases have a generic signature!
@@ -4686,7 +4727,6 @@ ASTMangler::BaseEntitySignature::BaseEntitySignature(const Decl *decl)
4686
4727
case DeclKind::Module:
4687
4728
case DeclKind::Param:
4688
4729
case DeclKind::Macro:
4689
- case DeclKind::EnumElement:
4690
4730
case DeclKind::Extension:
4691
4731
case DeclKind::TopLevelCode:
4692
4732
case DeclKind::Import:
0 commit comments