@@ -974,7 +974,6 @@ class PrintAST : public ASTVisitor<PrintAST> {
974974 SwapSelfAndDependentMemberType = 8 ,
975975 PrintInherited = 16 ,
976976 PrintInverseRequirements = 32 ,
977- IncludeOuterInverses = 64 ,
978977 };
979978
980979 // / The default generic signature flags for printing requirements.
@@ -1004,7 +1003,8 @@ class PrintAST : public ASTVisitor<PrintAST> {
10041003 void
10051004 printGenericSignature (GenericSignature genericSig,
10061005 unsigned flags,
1007- llvm::function_ref<bool (const Requirement &)> filter);
1006+ llvm::function_ref<bool (const Requirement &)> filter,
1007+ InverseFilter inverseFilter);
10081008 void printSingleDepthOfGenericSignature (
10091009 ArrayRef<GenericTypeParamType *> genericParams,
10101010 ArrayRef<Requirement> requirements,
@@ -1693,9 +1693,13 @@ static unsigned getDepthOfRequirement(const Requirement &req) {
16931693
16941694void PrintAST::printGenericSignature (GenericSignature genericSig,
16951695 unsigned flags) {
1696+ ASSERT (!((flags & InnermostOnly) && (flags & PrintInverseRequirements))
1697+ && " InnermostOnly + PrintInverseRequirements is not handled" );
1698+
16961699 printGenericSignature (genericSig, flags,
16971700 // print everything
1698- [&](const Requirement &) { return true ; });
1701+ [&](const Requirement &) { return true ; },
1702+ AllInverses ());
16991703}
17001704
17011705// Erase any requirements involving invertible protocols.
@@ -1710,16 +1714,35 @@ static void eraseInvertibleProtocolConformances(
17101714 });
17111715}
17121716
1717+ InversesAtDepth::InversesAtDepth (GenericContext *level) {
1718+ includedDepth = std::nullopt ;
1719+ // Does this generic context have its own generic parameters?
1720+ if (auto *list = level->getGenericParams ()) {
1721+ includedDepth = list->getParams ().back ()->getDepth (); // use this depth.
1722+ }
1723+ }
1724+ bool InversesAtDepth::operator ()(const InverseRequirement &inverse) const {
1725+ if (includedDepth) {
1726+ auto d = inverse.subject ->castTo <GenericTypeParamType>()->getDepth ();
1727+ return d == includedDepth.value ();
1728+ }
1729+ return false ;
1730+ }
1731+
17131732void PrintAST::printGenericSignature (
17141733 GenericSignature genericSig,
17151734 unsigned flags,
1716- llvm::function_ref<bool (const Requirement &)> filter) {
1735+ llvm::function_ref<bool (const Requirement &)> filter,
1736+ InverseFilter inverseFilter) {
17171737
17181738 SmallVector<Requirement, 2 > requirements;
17191739 SmallVector<InverseRequirement, 2 > inverses;
17201740
17211741 if (flags & PrintInverseRequirements) {
17221742 genericSig->getRequirementsWithInverses (requirements, inverses);
1743+ llvm::erase_if (inverses, [&](InverseRequirement inverse) -> bool {
1744+ return !inverseFilter (inverse);
1745+ });
17231746 } else {
17241747 requirements.append (genericSig.getRequirements ().begin (),
17251748 genericSig.getRequirements ().end ());
@@ -1728,17 +1751,6 @@ void PrintAST::printGenericSignature(
17281751 eraseInvertibleProtocolConformances (requirements);
17291752 }
17301753
1731- // Unless `IncludeOuterInverses` is enabled, limit inverses to the
1732- // innermost generic parameters.
1733- if (!(flags & IncludeOuterInverses) && !inverses.empty ()) {
1734- auto innerParams = genericSig.getInnermostGenericParams ();
1735- SmallPtrSet<TypeBase *, 4 > innerParamSet (innerParams.begin (),
1736- innerParams.end ());
1737- llvm::erase_if (inverses, [&](InverseRequirement inverse) -> bool {
1738- return !innerParamSet.contains (inverse.subject .getPointer ());
1739- });
1740- }
1741-
17421754 if (flags & InnermostOnly) {
17431755 auto genericParams = genericSig.getInnermostGenericParams ();
17441756
@@ -2772,8 +2784,9 @@ void PrintAST::printDeclGenericRequirements(GenericContext *decl) {
27722784 // In many cases, inverses should not be printed for outer generic parameters.
27732785 // Exceptions to that include extensions, as it's valid to write an inverse
27742786 // on the generic parameters they get from the extended nominal.
2775- if (isa<ExtensionDecl>(decl))
2776- flags |= IncludeOuterInverses;
2787+ InverseFilter inverseFilter = AllInverses ();
2788+ if (!isa<ExtensionDecl>(decl))
2789+ inverseFilter = InversesAtDepth (decl);
27772790
27782791 Printer.printStructurePre (PrintStructureKind::DeclGenericParameterClause);
27792792 printGenericSignature (genericSig,
@@ -2782,7 +2795,8 @@ void PrintAST::printDeclGenericRequirements(GenericContext *decl) {
27822795 if (parentSig)
27832796 return !parentSig->isRequirementSatisfied (req);
27842797 return true ;
2785- });
2798+ },
2799+ inverseFilter);
27862800 Printer.printStructurePost (PrintStructureKind::DeclGenericParameterClause);
27872801}
27882802
@@ -2916,20 +2930,6 @@ void PrintAST::printExtendedTypeName(TypeLoc ExtendedTypeLoc) {
29162930 printTypeLoc (TypeLoc (ExtendedTypeLoc.getTypeRepr (), Ty));
29172931}
29182932
2919- // / If an extension adds a conformance for an invertible protocol, then we
2920- // / should not print inverses for its generic signature, because no conditional
2921- // / requirements are inferred by default for such an extension.
2922- static bool isExtensionAddingInvertibleConformance (const ExtensionDecl *ext) {
2923- auto conformances = ext->getLocalConformances ();
2924- for (auto *conf : conformances) {
2925- if (conf->getProtocol ()->getInvertibleProtocolKind ()) {
2926- assert (conformances.size () == 1 && " expected solo conformance" );
2927- return true ;
2928- }
2929- }
2930- return false ;
2931- }
2932-
29332933void PrintAST::printSynthesizedExtension (Type ExtendedType,
29342934 ExtensionDecl *ExtDecl) {
29352935 if (Options.PrintCompatibilityFeatureChecks &&
@@ -3054,24 +3054,22 @@ void PrintAST::printExtension(ExtensionDecl *decl) {
30543054 assert (baseGenericSig &&
30553055 " an extension can't be generic if the base type isn't" );
30563056
3057- auto genSigFlags = defaultGenericRequirementFlags ()
3058- | IncludeOuterInverses;
3057+ auto genSigFlags = defaultGenericRequirementFlags ();
30593058
30603059 // Disable printing inverses if the extension is adding a conformance
30613060 // for an invertible protocol itself, as we do not infer any requirements
30623061 // in such an extension. We need to print the whole signature:
30633062 // extension S: Copyable where T: Copyable
3064- if (isExtensionAddingInvertibleConformance ( decl)) {
3063+ if (decl-> isAddingConformanceToInvertible ())
30653064 genSigFlags &= ~PrintInverseRequirements;
3066- genSigFlags &= ~IncludeOuterInverses;
3067- }
30683065
30693066 printGenericSignature (genericSig,
30703067 genSigFlags,
30713068 [baseGenericSig](const Requirement &req) -> bool {
30723069 // Only include constraints that are not satisfied by the base type.
30733070 return !baseGenericSig->isRequirementSatisfied (req);
3074- });
3071+ },
3072+ AllInverses ());
30753073 }
30763074 }
30773075 if (Options.TypeDefinitions ) {
0 commit comments