Skip to content

Commit 3257ff4

Browse files
committed
[AST] Move hasInverseMarking into ProtocolDecl and produce a loc of found inverse
1 parent 09ab12d commit 3257ff4

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
@@ -5222,6 +5222,11 @@ class ProtocolDecl final : public NominalTypeDecl {
52225222
/// protocol.
52235223
bool inheritsFrom(const ProtocolDecl *Super) const;
52245224

5225+
/// Determine whether this protocol has ~<target>` stated on
5226+
/// itself, one of its inherited types or `Self` requirements.
5227+
std::pair</*found=*/bool, /*where=*/SourceLoc>
5228+
hasInverseMarking(InvertibleProtocolKind target) const;
5229+
52255230
/// Determine whether this protocol requires conformance to `IP`, without
52265231
/// querying a generic signature.
52275232
bool requiresInvertible(InvertibleProtocolKind ip) const;

lib/AST/Decl.cpp

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

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

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

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

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

6637-
auto *whereClause = P->getTrailingWhereClause();
6641+
auto *whereClause = getTrailingWhereClause();
66386642
if (!whereClause)
6639-
return false;
6643+
return std::make_pair(false, SourceLoc());
66406644

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

6647-
auto *subjectRepr = dyn_cast<IdentTypeRepr>(reqRepr.getSubjectRepr());
6648-
auto *constraintRepr = reqRepr.getConstraintRepr();
6650+
auto *subjectRepr = dyn_cast<IdentTypeRepr>(reqRepr.getSubjectRepr());
6651+
auto *constraintRepr = reqRepr.getConstraintRepr();
66496652

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

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

66586663
bool ProtocolDecl::requiresInvertible(InvertibleProtocolKind ip) const {
@@ -6684,7 +6689,7 @@ bool ProtocolDecl::requiresInvertible(InvertibleProtocolKind ip) const {
66846689
// Otherwise, check to see if there's an inverse on this protocol.
66856690

66866691
// The implicit requirement was suppressed on this protocol, keep looking.
6687-
if (hasInverseMarking(proto, ip))
6692+
if (proto->hasInverseMarking(ip).first)
66886693
return TypeWalker::Action::Continue;
66896694

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

0 commit comments

Comments
 (0)