Skip to content

Commit 015129c

Browse files
committed
[Diagnostics] Allow requirement failure to diagnose operators
In absence of general argument conversion failures requirement errors associated with operators couldn't be diagnosed properly, now this restriction could be lifted.
1 parent 078c2b6 commit 015129c

File tree

3 files changed

+17
-25
lines changed

3 files changed

+17
-25
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -455,9 +455,6 @@ bool RequirementFailure::isStaticOrInstanceMember(const ValueDecl *decl) {
455455
}
456456

457457
bool RequirementFailure::diagnoseAsError() {
458-
if (!canDiagnoseFailure())
459-
return false;
460-
461458
auto *anchor = getRawAnchor();
462459
const auto *reqDC = getRequirementDC();
463460
auto *genericCtx = getGenericContext();
@@ -532,9 +529,6 @@ void RequirementFailure::emitRequirementNote(const Decl *anchor, Type lhs,
532529
}
533530

534531
bool MissingConformanceFailure::diagnoseAsError() {
535-
if (!canDiagnoseFailure())
536-
return false;
537-
538532
auto *anchor = getAnchor();
539533
auto ownerType = getOwnerType();
540534
auto nonConformingType = getLHS();

lib/Sema/CSDiagnostics.h

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -285,24 +285,6 @@ class RequirementFailure : public FailureDiagnostic {
285285
virtual DiagInReference getDiagnosticInRereference() const = 0;
286286
virtual DiagAsNote getDiagnosticAsNote() const = 0;
287287

288-
/// Determine whether it would be possible to diagnose
289-
/// current requirement failure.
290-
bool canDiagnoseFailure() const {
291-
// If this is a conditional requirement failure,
292-
// we have a lot more information compared to
293-
// type requirement case, because we know that
294-
// underlying conformance requirement matched.
295-
if (isConditional())
296-
return true;
297-
298-
// For static/initializer calls there is going to be
299-
// a separate fix, attached to the argument, which is
300-
// much easier to diagnose.
301-
// For operator calls we can't currently produce a good
302-
// diagnostic, so instead let's refer to expression diagnostics.
303-
return !(Apply && isOperator(Apply));
304-
}
305-
306288
static bool isOperator(const ApplyExpr *apply) {
307289
return isa<PrefixUnaryExpr>(apply) || isa<PostfixUnaryExpr>(apply) ||
308290
isa<BinaryExpr>(apply);

lib/Sema/CSSimplify.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1775,8 +1775,24 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
17751775
if (auto layoutConstraint = layout.getLayoutConstraint()) {
17761776
if (layoutConstraint->isClass()) {
17771777
if (kind == ConstraintKind::ConformsTo) {
1778-
if (!type1->satisfiesClassConstraint())
1778+
if (!type1->satisfiesClassConstraint()) {
1779+
if (shouldAttemptFixes()) {
1780+
if (auto last = locator.last()) {
1781+
// If solver is in diagnostic mode and this is a
1782+
// superclass requirement, let's consider conformance
1783+
// to `AnyObject` as solved since actual superclass
1784+
// requirement is going to fail too (because type can't
1785+
// satisfy it), and it's more interesting from diagnostics
1786+
// perspective.
1787+
auto req = last->getAs<LocatorPathElt::AnyRequirement>();
1788+
if (req &&
1789+
req->getRequirementKind() == RequirementKind::Superclass)
1790+
return getTypeMatchSuccess();
1791+
}
1792+
}
1793+
17791794
return getTypeMatchFailure(locator);
1795+
}
17801796
} else {
17811797
// Subtype relation to AnyObject also allows class-bound
17821798
// existentials that are not @objc and therefore carry

0 commit comments

Comments
 (0)