@@ -6614,6 +6614,47 @@ bool ProtocolDecl::inheritsFrom(const ProtocolDecl *super) const {
6614
6614
});
6615
6615
}
6616
6616
6617
+ static bool hasInverseMarking (ProtocolDecl *P, InvertibleProtocolKind target) {
6618
+ auto &ctx = P->getASTContext ();
6619
+
6620
+ // Legacy support stops here.
6621
+ if (!ctx.LangOpts .hasFeature (Feature::NoncopyableGenerics))
6622
+ return false ;
6623
+
6624
+ auto inheritedTypes = P->getInherited ();
6625
+ for (unsigned i = 0 ; i < inheritedTypes.size (); ++i) {
6626
+ auto type = inheritedTypes.getResolvedType (i, TypeResolutionStage::Structural);
6627
+ if (!type)
6628
+ continue ;
6629
+
6630
+ if (auto *composition = type->getAs <ProtocolCompositionType>()) {
6631
+ // Found ~<target> in the protocol inheritance clause.
6632
+ if (composition->getInverses ().contains (target))
6633
+ return true ;
6634
+ }
6635
+ }
6636
+
6637
+ auto *whereClause = P->getTrailingWhereClause ();
6638
+ if (!whereClause)
6639
+ return false ;
6640
+
6641
+ return llvm::any_of (
6642
+ whereClause->getRequirements (), [&](const RequirementRepr &reqRepr) {
6643
+ if (reqRepr.isInvalid () ||
6644
+ reqRepr.getKind () != RequirementReprKind::TypeConstraint)
6645
+ return false ;
6646
+
6647
+ auto *subjectRepr = dyn_cast<IdentTypeRepr>(reqRepr.getSubjectRepr ());
6648
+ auto *constraintRepr = reqRepr.getConstraintRepr ();
6649
+
6650
+ if (!subjectRepr ||
6651
+ !subjectRepr->getNameRef ().isSimpleName (ctx.Id_Self ))
6652
+ return false ;
6653
+
6654
+ return constraintRepr->isInverseOf (target, P->getDeclContext ());
6655
+ });
6656
+ }
6657
+
6617
6658
bool ProtocolDecl::requiresInvertible (InvertibleProtocolKind ip) const {
6618
6659
// Protocols don't inherit from themselves.
6619
6660
if (auto thisIP = getInvertibleProtocolKind ()) {
@@ -6641,16 +6682,12 @@ bool ProtocolDecl::requiresInvertible(InvertibleProtocolKind ip) const {
6641
6682
return TypeWalker::Action::Continue;
6642
6683
6643
6684
// Otherwise, check to see if there's an inverse on this protocol.
6644
- switch (proto->getMarking (ip).getInverse ().getKind ()) {
6645
- case InverseMarking::Kind::None:
6646
- return TypeWalker::Action::Stop; // No inverse, so implicitly inherited.
6647
-
6648
- case InverseMarking::Kind::LegacyExplicit:
6649
- case InverseMarking::Kind::Explicit:
6650
- case InverseMarking::Kind::Inferred:
6651
- // The implicit requirement was suppressed on this protocol, keep looking.
6685
+
6686
+ // The implicit requirement was suppressed on this protocol, keep looking.
6687
+ if (hasInverseMarking (proto, ip))
6652
6688
return TypeWalker::Action::Continue;
6653
- }
6689
+
6690
+ return TypeWalker::Action::Stop; // No inverse, so implicitly inherited.
6654
6691
});
6655
6692
}
6656
6693
0 commit comments