Skip to content

Commit eefbb15

Browse files
committed
[Diagnostics] Implement diagnostic-as-note for requirement failures
1 parent 81afed9 commit eefbb15

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1539,6 +1539,10 @@ NOTE(where_requirement_failure_both_subst,none,
15391539
"where %0 = %1, %2 = %3", (Type, Type, Type, Type))
15401540
NOTE(requirement_implied_by_conditional_conformance,none,
15411541
"requirement from conditional conformance of %0 to %1", (Type, Type))
1542+
NOTE(candidate_types_conformance_requirement,none,
1543+
"candidate requires that %0 conform to %1 "
1544+
"(requirement specified as %2 == %3%4)",
1545+
(Type, Type, Type, Type, StringRef))
15421546
NOTE(candidate_types_equal_requirement,none,
15431547
"candidate requires that the types %0 and %1 be equivalent "
15441548
"(requirement specified as %2 == %3%4)",

lib/Sema/CSDiagnostics.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,13 +117,20 @@ const DeclContext *RequirementFailure::getRequirementDC() const {
117117
}
118118

119119
bool RequirementFailure::diagnose(bool asNote) {
120-
if (!canDiagnoseFailure() || asNote)
120+
if (!canDiagnoseFailure())
121121
return false;
122122

123123
auto *anchor = getAnchor();
124124
const auto *reqDC = getRequirementDC();
125125
auto *genericCtx = AffectedDecl->getAsGenericContext();
126126

127+
if (asNote) {
128+
const auto &req = getRequirement();
129+
emitDiagnostic(reqDC->getAsDecl(), getDiagnosticAsNote(), getLHS(),
130+
getRHS(), req.getFirstType(), req.getSecondType(), "");
131+
return true;
132+
}
133+
127134
if (reqDC != genericCtx) {
128135
auto *NTD = reqDC->getSelfNominalTypeDecl();
129136
emitDiagnostic(anchor->getLoc(), getDiagnosticInRereference(),
@@ -160,9 +167,12 @@ void RequirementFailure::emitRequirementNote(const Decl *anchor) const {
160167
}
161168

162169
bool MissingConformanceFailure::diagnose(bool asNote) {
163-
if (!canDiagnoseFailure() || asNote)
170+
if (!canDiagnoseFailure())
164171
return false;
165172

173+
if (asNote)
174+
return RequirementFailure::diagnose(asNote);
175+
166176
auto *anchor = getAnchor();
167177
auto ownerType = getOwnerType();
168178
auto nonConformingType = getLHS();

lib/Sema/CSDiagnostics.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class RequirementFailure : public FailureDiagnostic {
133133
using PathEltKind = ConstraintLocator::PathElementKind;
134134
using DiagOnDecl = Diag<DescriptiveDeclKind, DeclName, Type, Type>;
135135
using DiagInReference = Diag<DescriptiveDeclKind, DeclName, Type, Type, Type>;
136+
using DiagAsNote = Diag<Type, Type, Type, Type, StringRef>;
136137

137138
const ValueDecl *AffectedDecl;
138139
/// If possible, find application expression associated
@@ -182,6 +183,7 @@ class RequirementFailure : public FailureDiagnostic {
182183

183184
virtual DiagOnDecl getDiagnosticOnDecl() const = 0;
184185
virtual DiagInReference getDiagnosticInRereference() const = 0;
186+
virtual DiagAsNote getDiagnosticAsNote() const = 0;
185187

186188
/// Determine whether it would be possible to diagnose
187189
/// current requirement failure.
@@ -242,6 +244,10 @@ class MissingConformanceFailure final : public RequirementFailure {
242244
DiagInReference getDiagnosticInRereference() const override {
243245
return diag::type_does_not_conform_in_decl_ref;
244246
}
247+
248+
DiagAsNote getDiagnosticAsNote() const override {
249+
return diag::candidate_types_conformance_requirement;
250+
}
245251
};
246252

247253
/// Diagnose failures related to same-type generic requirements, e.g.
@@ -278,6 +284,10 @@ class SameTypeRequirementFailure final : public RequirementFailure {
278284
DiagInReference getDiagnosticInRereference() const override {
279285
return diag::types_not_equal_in_decl_ref;
280286
}
287+
288+
DiagAsNote getDiagnosticAsNote() const override {
289+
return diag::candidate_types_equal_requirement;
290+
}
281291
};
282292

283293
/// Diagnose failures related to superclass generic requirements, e.g.
@@ -312,6 +322,10 @@ class SuperclassRequirementFailure final : public RequirementFailure {
312322
DiagInReference getDiagnosticInRereference() const override {
313323
return diag::types_not_inherited_in_decl_ref;
314324
}
325+
326+
DiagAsNote getDiagnosticAsNote() const override {
327+
return diag::candidate_types_inheritance_requirement;
328+
}
315329
};
316330

317331
/// Diagnose errors associated with missing, extraneous

0 commit comments

Comments
 (0)