[Diagnostics] Diagnose mismatches related to use of === and !== via a tailored fix

This commit is contained in:
Pavel Yaskevich
2020-02-13 13:43:38 -08:00
parent 0a8de8bda8
commit 802e141be9

View File

@@ -2113,11 +2113,25 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
// witness tables.
if (!type1->isClassExistentialType() && !type1->mayHaveSuperclass()) {
if (shouldAttemptFixes()) {
auto *fix = AllowNonClassTypeToConvertToAnyObject::create(
*this, type1, getConstraintLocator(locator));
llvm::SmallVector<LocatorPathElt, 4> path;
if (auto *anchor = locator.getLocatorParts(path)) {
return recordFix(fix) ? getTypeMatchFailure(locator)
: getTypeMatchSuccess();
// Let's drop `optional` or `generic argument` bits from
// locator because that helps to diagnose reference equality
// operaators ("===" and "!==") since there is always a
// `value-to-optional` or `optional-to-optional` conversion
// associated with them (expected argument is `AnyObject?`).
if (!path.empty() &&
(path.back().is<LocatorPathElt::OptionalPayload>() ||
path.back().is<LocatorPathElt::GenericArgument>()))
path.pop_back();
auto *fix = AllowNonClassTypeToConvertToAnyObject::create(
*this, type1, getConstraintLocator(anchor, path));
return recordFix(fix) ? getTypeMatchFailure(locator)
: getTypeMatchSuccess();
}
}
return getTypeMatchFailure(locator);
@@ -3102,15 +3116,6 @@ bool ConstraintSystem::repairFailures(
repairViaBridgingCast(*this, lhs, rhs, conversionsOrFixes, locator))
break;
// If this is an argument to `===` or `!==` there are tailored
// diagnostics available for it as part of argument-to-parameter
// conversion fix, so let's not try any restrictions or other fixes.
if (isArgumentOfReferenceEqualityOperator(loc)) {
conversionsOrFixes.push_back(
AllowArgumentMismatch::create(*this, lhs, rhs, loc));
break;
}
// Argument is a r-value but parameter expects an l-value e.g.
//
// func foo(_ x: inout Int) {}