Skip to content

Commit fc41370

Browse files
authored
Merge pull request #18752 from xedin/add-get-req-dc-to-failure
[Diagnostics] Extract requirement declaration context retrieval into …
2 parents ef06972 + 0f411b1 commit fc41370

File tree

2 files changed

+34
-18
lines changed

2 files changed

+34
-18
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17-
#include "ConstraintSystem.h"
1817
#include "CSDiagnostics.h"
18+
#include "ConstraintSystem.h"
1919
#include "MiscDiagnostics.h"
2020
#include "swift/AST/Expr.h"
21+
#include "swift/AST/GenericSignature.h"
2122
#include "swift/AST/Types.h"
2223
#include "llvm/ADT/ArrayRef.h"
2324

@@ -67,7 +68,7 @@ Type RequirementFailure::getOwnerType() const {
6768
return getType(getAnchor())->getInOutObjectType()->getMetatypeInstanceType();
6869
}
6970

70-
const Requirement &RequirementFailure::getRequirement() {
71+
const Requirement &RequirementFailure::getRequirement() const {
7172
auto *genericCtx = AffectedDecl->getAsGenericContext();
7273
return genericCtx->getGenericRequirements()[getRequirementIndex()];
7374
}
@@ -100,6 +101,27 @@ ValueDecl *RequirementFailure::getDeclRef() const {
100101
return ownerType->getAnyGeneric();
101102
}
102103

104+
const DeclContext *RequirementFailure::getRequirementDC() const {
105+
const auto &req = getRequirement();
106+
auto *DC = AffectedDecl->getDeclContext();
107+
108+
do {
109+
auto *D = DC->getInnermostDeclarationDeclContext();
110+
if (!D)
111+
break;
112+
113+
if (auto *GC = D->getAsGenericContext()) {
114+
auto *sig = GC->getGenericSignature();
115+
if (sig && sig->isRequirementSatisfied(req))
116+
return DC;
117+
}
118+
119+
DC = DC->getParent();
120+
} while (DC);
121+
122+
return AffectedDecl->getAsGenericContext();
123+
}
124+
103125
bool MissingConformanceFailure::diagnose() {
104126
auto *anchor = getAnchor();
105127
auto ownerType = getOwnerType();
@@ -175,21 +197,10 @@ bool MissingConformanceFailure::diagnose() {
175197
} else {
176198
const auto &req = getRequirement();
177199
auto *genericCtx = AffectedDecl->getAsGenericContext();
200+
const auto *reqDC = getRequirementDC();
178201

179-
std::function<const DeclContext *(Type)> getAffectedCtx =
180-
[&](Type type) -> const DeclContext * {
181-
if (auto *DMT = type->getAs<DependentMemberType>())
182-
return getAffectedCtx(DMT->getBase());
183-
184-
if (auto *GPT = type->getAs<GenericTypeParamType>())
185-
return GPT->getDecl()->getDeclContext();
186-
187-
return genericCtx;
188-
};
189-
190-
const auto *affected = getAffectedCtx(req.getFirstType());
191-
if (affected != genericCtx) {
192-
auto *NTD = affected->getAsNominalTypeOrNominalTypeExtensionContext();
202+
if (reqDC != genericCtx) {
203+
auto *NTD = reqDC->getAsNominalTypeOrNominalTypeExtensionContext();
193204
emitDiagnostic(anchor->getLoc(), diag::type_does_not_conform_in_decl_ref,
194205
AffectedDecl->getDescriptiveKind(),
195206
AffectedDecl->getFullName(), NTD->getDeclaredType(), type,
@@ -200,7 +211,7 @@ bool MissingConformanceFailure::diagnose() {
200211
AffectedDecl->getFullName(), type, protocolType);
201212
}
202213

203-
emitDiagnostic(affected->getAsDeclOrDeclExtensionContext(),
214+
emitDiagnostic(reqDC->getAsDeclOrDeclExtensionContext(),
204215
diag::where_type_does_not_conform_type, req.getFirstType(),
205216
type);
206217
}

lib/Sema/CSDiagnostics.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,12 @@ class RequirementFailure : public FailureDiagnostic {
134134
Type getOwnerType() const;
135135

136136
/// Generic requirement associated with the failure.
137-
const Requirement &getRequirement();
137+
const Requirement &getRequirement() const;
138+
139+
protected:
140+
/// Retrieve declaration contextual where current
141+
/// requirement has been introduced.
142+
const DeclContext *getRequirementDC() const;
138143

139144
private:
140145
/// Retrieve declaration associated with failing generic requirement.

0 commit comments

Comments
 (0)