14
14
//
15
15
// ===----------------------------------------------------------------------===//
16
16
17
- #include " ConstraintSystem.h"
18
17
#include " CSDiagnostics.h"
18
+ #include " ConstraintSystem.h"
19
19
#include " MiscDiagnostics.h"
20
20
#include " swift/AST/Expr.h"
21
+ #include " swift/AST/GenericSignature.h"
21
22
#include " swift/AST/Types.h"
22
23
#include " llvm/ADT/ArrayRef.h"
23
24
@@ -67,7 +68,7 @@ Type RequirementFailure::getOwnerType() const {
67
68
return getType (getAnchor ())->getInOutObjectType ()->getMetatypeInstanceType ();
68
69
}
69
70
70
- const Requirement &RequirementFailure::getRequirement () {
71
+ const Requirement &RequirementFailure::getRequirement () const {
71
72
auto *genericCtx = AffectedDecl->getAsGenericContext ();
72
73
return genericCtx->getGenericRequirements ()[getRequirementIndex ()];
73
74
}
@@ -100,6 +101,27 @@ ValueDecl *RequirementFailure::getDeclRef() const {
100
101
return ownerType->getAnyGeneric ();
101
102
}
102
103
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
+
103
125
bool MissingConformanceFailure::diagnose () {
104
126
auto *anchor = getAnchor ();
105
127
auto ownerType = getOwnerType ();
@@ -175,21 +197,10 @@ bool MissingConformanceFailure::diagnose() {
175
197
} else {
176
198
const auto &req = getRequirement ();
177
199
auto *genericCtx = AffectedDecl->getAsGenericContext ();
200
+ const auto *reqDC = getRequirementDC ();
178
201
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 ();
193
204
emitDiagnostic (anchor->getLoc (), diag::type_does_not_conform_in_decl_ref,
194
205
AffectedDecl->getDescriptiveKind (),
195
206
AffectedDecl->getFullName (), NTD->getDeclaredType (), type,
@@ -200,7 +211,7 @@ bool MissingConformanceFailure::diagnose() {
200
211
AffectedDecl->getFullName (), type, protocolType);
201
212
}
202
213
203
- emitDiagnostic (affected ->getAsDeclOrDeclExtensionContext (),
214
+ emitDiagnostic (reqDC ->getAsDeclOrDeclExtensionContext (),
204
215
diag::where_type_does_not_conform_type, req.getFirstType (),
205
216
type);
206
217
}
0 commit comments