Skip to content

Commit 826f17e

Browse files
committed
Decouple detection of «Self ==» constraints from SelfReferenceKind
1 parent 3bc381b commit 826f17e

File tree

3 files changed

+33
-52
lines changed

3 files changed

+33
-52
lines changed

include/swift/AST/Decl.h

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3747,56 +3747,48 @@ class ClassDecl final : public NominalTypeDecl {
37473747
struct SelfReferenceKind {
37483748
bool result;
37493749
bool parameter;
3750-
bool requirement;
37513750
bool other;
37523751

37533752
/// The type does not refer to 'Self' at all.
37543753
static SelfReferenceKind None() {
3755-
return SelfReferenceKind(false, false, false, false);
3754+
return SelfReferenceKind(false, false, false);
37563755
}
37573756

37583757
/// The type refers to 'Self', but only as the type of a property or
37593758
/// the result type of a method/subscript.
37603759
static SelfReferenceKind Result() {
3761-
return SelfReferenceKind(true, false, false, false);
3760+
return SelfReferenceKind(true, false, false);
37623761
}
37633762

37643763
/// The type refers to 'Self', but only as the parameter type
37653764
/// of a method/subscript.
37663765
static SelfReferenceKind Parameter() {
3767-
return SelfReferenceKind(false, true, false, false);
3768-
}
3769-
3770-
/// The type refers to 'Self' within a same-type requiement.
3771-
static SelfReferenceKind Requirement() {
3772-
return SelfReferenceKind(false, false, true, false);
3766+
return SelfReferenceKind(false, true, false);
37733767
}
37743768

37753769
/// The type refers to 'Self' in a position that is invariant.
37763770
static SelfReferenceKind Other() {
3777-
return SelfReferenceKind(false, false, false, true);
3771+
return SelfReferenceKind(false, false, true);
37783772
}
37793773

37803774
SelfReferenceKind flip() const {
3781-
return SelfReferenceKind(parameter, result, requirement, other);
3775+
return SelfReferenceKind(parameter, result, other);
37823776
}
37833777

37843778
SelfReferenceKind operator|=(SelfReferenceKind kind) {
37853779
result |= kind.result;
3786-
requirement |= kind.requirement;
37873780
parameter |= kind.parameter;
37883781
other |= kind.other;
37893782
return *this;
37903783
}
37913784

37923785
operator bool() const {
3793-
return result || parameter || requirement || other;
3786+
return result || parameter || other;
37943787
}
37953788

37963789
private:
3797-
SelfReferenceKind(bool result, bool parameter, bool requirement, bool other)
3798-
: result(result), parameter(parameter), requirement(requirement),
3799-
other(other) { }
3790+
SelfReferenceKind(bool result, bool parameter, bool other)
3791+
: result(result), parameter(parameter), other(other) { }
38003792
};
38013793

38023794
/// The set of known protocols for which derived conformances are supported.

lib/AST/Decl.cpp

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4778,25 +4778,6 @@ findProtocolSelfReferences(const ProtocolDecl *proto, Type type,
47784778
return SelfReferenceKind::None();
47794779
}
47804780

4781-
/// Find Self references in a generic signature's same-type requirements.
4782-
static SelfReferenceKind
4783-
findProtocolSelfReferences(const ProtocolDecl *protocol,
4784-
GenericSignature genericSig){
4785-
if (!genericSig) return SelfReferenceKind::None();
4786-
4787-
auto selfTy = protocol->getSelfInterfaceType();
4788-
for (const auto &req : genericSig->getRequirements()) {
4789-
if (req.getKind() != RequirementKind::SameType)
4790-
continue;
4791-
4792-
if (req.getFirstType()->isEqual(selfTy) ||
4793-
req.getSecondType()->isEqual(selfTy))
4794-
return SelfReferenceKind::Requirement();
4795-
}
4796-
4797-
return SelfReferenceKind::None();
4798-
}
4799-
48004781
/// Find Self references within the given requirement.
48014782
SelfReferenceKind
48024783
ProtocolDecl::findProtocolSelfReferences(const ValueDecl *value,
@@ -4836,27 +4817,11 @@ ProtocolDecl::findProtocolSelfReferences(const ValueDecl *value,
48364817
return SelfReferenceKind::Other();
48374818
}
48384819

4839-
// Check the requirements of a generic function.
4840-
if (func->isGeneric()) {
4841-
if (auto result =
4842-
::findProtocolSelfReferences(this, func->getGenericSignature()))
4843-
return result;
4844-
}
4845-
48464820
return ::findProtocolSelfReferences(this, type,
48474821
skipAssocTypes);
48484822
} else {
48494823
assert(isa<AbstractStorageDecl>(value));
48504824

4851-
if (auto *const subscript = dyn_cast<SubscriptDecl>(value)) {
4852-
// Check the requirements of a generic subscript.
4853-
if (subscript->isGeneric()) {
4854-
if (auto result = ::findProtocolSelfReferences(
4855-
this, subscript->getGenericSignature()))
4856-
return result;
4857-
}
4858-
}
4859-
48604825
return ::findProtocolSelfReferences(this, type,
48614826
skipAssocTypes);
48624827
}

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3359,6 +3359,30 @@ diagnoseMissingWitnesses(MissingWitnessDiagnosisKind Kind) {
33593359
}
33603360
}
33613361

3362+
/// Whether the given protocol requirement has a "Self ==" constraint.
3363+
static bool hasSelfSameTypeConstraint(const ValueDecl *req) {
3364+
const auto *proto = cast<ProtocolDecl>(req->getDeclContext());
3365+
const auto *genCtx = req->getAsGenericContext();
3366+
if (!genCtx)
3367+
return false;
3368+
3369+
const auto genericSig = genCtx->getGenericSignature();
3370+
if (!genericSig)
3371+
return false;
3372+
3373+
const auto selfTy = proto->getSelfInterfaceType();
3374+
for (const auto &constr : genericSig->getRequirements()) {
3375+
if (constr.getKind() != RequirementKind::SameType)
3376+
continue;
3377+
3378+
if (constr.getFirstType()->isEqual(selfTy) ||
3379+
constr.getSecondType()->isEqual(selfTy))
3380+
return true;
3381+
}
3382+
3383+
return false;
3384+
}
3385+
33623386
/// Determine the given witness has a same-type constraint constraining the
33633387
/// given 'Self' type, and return the requirement that does.
33643388
///
@@ -3509,7 +3533,7 @@ void ConformanceChecker::checkNonFinalClassWitness(ValueDecl *requirement,
35093533
});
35103534
}
35113535
}
3512-
} else if (selfKind.requirement) {
3536+
} else if (hasSelfSameTypeConstraint(requirement)) {
35133537
if (auto targetPair = getAdopteeSelfSameTypeConstraint(classDecl,
35143538
witness)) {
35153539
// A "Self ==" constraint works incorrectly with subclasses. Complain.

0 commit comments

Comments
 (0)