Skip to content

Commit 4921e77

Browse files
committed
[AST] Move hasInverseMarking into ProtocolDecl and produce a loc of found inverse
1 parent a81ec0a commit 4921e77

File tree

2 files changed

+31
-21
lines changed

2 files changed

+31
-21
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5216,6 +5216,11 @@ class ProtocolDecl final : public NominalTypeDecl {
52165216
/// protocol.
52175217
bool inheritsFrom(const ProtocolDecl *Super) const;
52185218

5219+
/// Determine whether this protocol has ~<target>` stated on
5220+
/// itself, one of its inherited types or `Self` requirements.
5221+
std::pair</*found=*/bool, /*where=*/SourceLoc>
5222+
hasInverseMarking(InvertibleProtocolKind target) const;
5223+
52195224
/// Determine whether this protocol requires conformance to `IP`, without
52205225
/// querying a generic signature.
52215226
bool requiresInvertible(InvertibleProtocolKind ip) const;

lib/AST/Decl.cpp

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6613,45 +6613,50 @@ bool ProtocolDecl::inheritsFrom(const ProtocolDecl *super) const {
66136613
});
66146614
}
66156615

6616-
static bool hasInverseMarking(ProtocolDecl *P, InvertibleProtocolKind target) {
6617-
auto &ctx = P->getASTContext();
6616+
std::pair</*found=*/bool, /*where=*/SourceLoc>
6617+
ProtocolDecl::hasInverseMarking(InvertibleProtocolKind target) const {
6618+
auto &ctx = getASTContext();
66186619

66196620
// Legacy support stops here.
66206621
if (!ctx.LangOpts.hasFeature(Feature::NoncopyableGenerics))
6621-
return false;
6622+
return std::make_pair(false, SourceLoc());
66226623

6623-
auto inheritedTypes = P->getInherited();
6624+
auto inheritedTypes = getInherited();
66246625
for (unsigned i = 0; i < inheritedTypes.size(); ++i) {
6625-
auto type = inheritedTypes.getResolvedType(i, TypeResolutionStage::Structural);
6626+
auto type =
6627+
inheritedTypes.getResolvedType(i, TypeResolutionStage::Structural);
66266628
if (!type)
66276629
continue;
66286630

6631+
auto *repr = inheritedTypes.getTypeRepr(i);
6632+
66296633
if (auto *composition = type->getAs<ProtocolCompositionType>()) {
66306634
// Found ~<target> in the protocol inheritance clause.
66316635
if (composition->getInverses().contains(target))
6632-
return true;
6636+
return std::make_pair(true, repr ? repr->getLoc() : SourceLoc());
66336637
}
66346638
}
66356639

6636-
auto *whereClause = P->getTrailingWhereClause();
6640+
auto *whereClause = getTrailingWhereClause();
66376641
if (!whereClause)
6638-
return false;
6642+
return std::make_pair(false, SourceLoc());
66396643

6640-
return llvm::any_of(
6641-
whereClause->getRequirements(), [&](const RequirementRepr &reqRepr) {
6642-
if (reqRepr.isInvalid() ||
6643-
reqRepr.getKind() != RequirementReprKind::TypeConstraint)
6644-
return false;
6644+
for (const auto &reqRepr : whereClause->getRequirements()) {
6645+
if (reqRepr.isInvalid() ||
6646+
reqRepr.getKind() != RequirementReprKind::TypeConstraint)
6647+
continue;
66456648

6646-
auto *subjectRepr = dyn_cast<IdentTypeRepr>(reqRepr.getSubjectRepr());
6647-
auto *constraintRepr = reqRepr.getConstraintRepr();
6649+
auto *subjectRepr = dyn_cast<IdentTypeRepr>(reqRepr.getSubjectRepr());
6650+
auto *constraintRepr = reqRepr.getConstraintRepr();
66486651

6649-
if (!subjectRepr ||
6650-
!subjectRepr->getNameRef().isSimpleName(ctx.Id_Self))
6651-
return false;
6652+
if (!subjectRepr || !subjectRepr->getNameRef().isSimpleName(ctx.Id_Self))
6653+
continue;
66526654

6653-
return constraintRepr->isInverseOf(target, P->getDeclContext());
6654-
});
6655+
if (constraintRepr->isInverseOf(target, getDeclContext()))
6656+
return std::make_pair(true, constraintRepr->getLoc());
6657+
}
6658+
6659+
return std::make_pair(false, SourceLoc());
66556660
}
66566661

66576662
bool ProtocolDecl::requiresInvertible(InvertibleProtocolKind ip) const {
@@ -6678,7 +6683,7 @@ bool ProtocolDecl::requiresInvertible(InvertibleProtocolKind ip) const {
66786683
// Otherwise, check to see if there's an inverse on this protocol.
66796684

66806685
// The implicit requirement was suppressed on this protocol, keep looking.
6681-
if (hasInverseMarking(proto, ip))
6686+
if (proto->hasInverseMarking(ip).first)
66826687
return TypeWalker::Action::Continue;
66836688

66846689
return TypeWalker::Action::Stop; // No inverse, so implicitly inherited.

0 commit comments

Comments
 (0)