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