Skip to content

Commit 355e02d

Browse files
committed
[AST] Route inverse marking detection through TypeDecl::hasInverseMarking
The first step on the path to dismangle `TypeDecl::getMarking()`.
1 parent ed8cc09 commit 355e02d

File tree

3 files changed

+25
-15
lines changed

3 files changed

+25
-15
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "swift/AST/IfConfigClause.h"
3333
#include "swift/AST/Import.h"
3434
#include "swift/AST/Initializer.h"
35+
#include "swift/AST/InverseMarking.h"
3536
#include "swift/AST/LayoutConstraint.h"
3637
#include "swift/AST/LifetimeAnnotation.h"
3738
#include "swift/AST/ReferenceCounting.h"
@@ -3234,6 +3235,8 @@ class TypeDecl : public ValueDecl {
32343235
/// Type if it `isEscapable` instead of using this.
32353236
CanBeInvertible::Result canBeEscapable() const;
32363237

3238+
InverseMarking::Mark hasInverseMarking(InvertibleProtocolKind target) const;
3239+
32373240
/// Determine how the given invertible protocol was written on this TypeDecl,
32383241
/// if at all.
32393242
InverseMarking getMarking(InvertibleProtocolKind ip) const;
@@ -5224,8 +5227,7 @@ class ProtocolDecl final : public NominalTypeDecl {
52245227

52255228
/// Determine whether this protocol has ~<target>` stated on
52265229
/// itself, one of its inherited types or `Self` requirements.
5227-
std::pair</*found=*/bool, /*where=*/SourceLoc>
5228-
hasInverseMarking(InvertibleProtocolKind target) const;
5230+
InverseMarking::Mark hasInverseMarking(InvertibleProtocolKind target) const;
52295231

52305232
/// Determine whether this protocol requires conformance to `IP`, without
52315233
/// querying a generic signature.

lib/AST/Decl.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4901,6 +4901,14 @@ GenericParameterReferenceInfo ValueDecl::findExistentialSelfReferences(
49014901
llvm::None);
49024902
}
49034903

4904+
InverseMarking::Mark
4905+
TypeDecl::hasInverseMarking(InvertibleProtocolKind target) const {
4906+
if (auto P = dyn_cast<ProtocolDecl>(this))
4907+
return P->hasInverseMarking(target);
4908+
4909+
return getMarking(target).getInverse();
4910+
}
4911+
49044912
InverseMarking TypeDecl::getMarking(InvertibleProtocolKind ip) const {
49054913
return evaluateOrDefault(
49064914
getASTContext().evaluator,
@@ -6614,13 +6622,13 @@ bool ProtocolDecl::inheritsFrom(const ProtocolDecl *super) const {
66146622
});
66156623
}
66166624

6617-
std::pair</*found=*/bool, /*where=*/SourceLoc>
6625+
InverseMarking::Mark
66186626
ProtocolDecl::hasInverseMarking(InvertibleProtocolKind target) const {
66196627
auto &ctx = getASTContext();
66206628

66216629
// Legacy support stops here.
66226630
if (!ctx.LangOpts.hasFeature(Feature::NoncopyableGenerics))
6623-
return std::make_pair(false, SourceLoc());
6631+
return InverseMarking::Mark();
66246632

66256633
auto inheritedTypes = getInherited();
66266634
for (unsigned i = 0; i < inheritedTypes.size(); ++i) {
@@ -6634,13 +6642,14 @@ ProtocolDecl::hasInverseMarking(InvertibleProtocolKind target) const {
66346642
if (auto *composition = type->getAs<ProtocolCompositionType>()) {
66356643
// Found ~<target> in the protocol inheritance clause.
66366644
if (composition->getInverses().contains(target))
6637-
return std::make_pair(true, repr ? repr->getLoc() : SourceLoc());
6645+
return InverseMarking::Mark(InverseMarking::Kind::Explicit,
6646+
repr ? repr->getLoc() : SourceLoc());
66386647
}
66396648
}
66406649

66416650
auto *whereClause = getTrailingWhereClause();
66426651
if (!whereClause)
6643-
return std::make_pair(false, SourceLoc());
6652+
return InverseMarking::Mark();
66446653

66456654
for (const auto &reqRepr : whereClause->getRequirements()) {
66466655
if (reqRepr.isInvalid() ||
@@ -6654,10 +6663,11 @@ ProtocolDecl::hasInverseMarking(InvertibleProtocolKind target) const {
66546663
continue;
66556664

66566665
if (constraintRepr->isInverseOf(target, getDeclContext()))
6657-
return std::make_pair(true, constraintRepr->getLoc());
6666+
return InverseMarking::Mark(InverseMarking::Kind::Explicit,
6667+
constraintRepr->getLoc());
66586668
}
66596669

6660-
return std::make_pair(false, SourceLoc());
6670+
return InverseMarking::Mark();
66616671
}
66626672

66636673
bool ProtocolDecl::requiresInvertible(InvertibleProtocolKind ip) const {
@@ -6689,7 +6699,7 @@ bool ProtocolDecl::requiresInvertible(InvertibleProtocolKind ip) const {
66896699
// Otherwise, check to see if there's an inverse on this protocol.
66906700

66916701
// The implicit requirement was suppressed on this protocol, keep looking.
6692-
if (proto->hasInverseMarking(ip).first)
6702+
if (proto->hasInverseMarking(ip))
66936703
return TypeWalker::Action::Continue;
66946704

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

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,15 +2064,13 @@ static void checkProtocolRefinementRequirements(ProtocolDecl *proto) {
20642064
if (EnabledNoncopyableGenerics) {
20652065
if (auto kp = otherProto->getKnownProtocolKind()) {
20662066
if (auto ip = getInvertibleProtocolKind(*kp)) {
2067-
bool hasInverse;
2068-
SourceLoc inverseLoc;
2069-
2070-
std::tie(hasInverse, inverseLoc) = proto->hasInverseMarking(*ip);
2071-
if (!hasInverse)
2067+
auto inverse = proto->hasInverseMarking(*ip);
2068+
if (!inverse)
20722069
continue; // no ~IP annotation
20732070

20742071
auto &Diags = proto->getASTContext().Diags;
2075-
Diags.diagnose(inverseLoc, diag::inverse_generic_but_also_conforms,
2072+
Diags.diagnose(inverse.getLoc(),
2073+
diag::inverse_generic_but_also_conforms,
20762074
proto->getSelfInterfaceType(), getProtocolName(*kp));
20772075
continue;
20782076
}

0 commit comments

Comments
 (0)