[ConstraintSystem] Properly diagnose operator reference ambiguities

If operator is referenced instead of applied e.g. `arr.sort(by: <)`
ambiguities should be diagnosed as `no exact matches` with attached
notes describing a failure associated with each potential candidate.

Resolves: rdar://problem/62054241
This commit is contained in:
Pavel Yaskevich
2020-04-24 12:22:08 -07:00
parent d8bd62d774
commit bb414927a0
2 changed files with 29 additions and 7 deletions

View File

@@ -2641,10 +2641,7 @@ static void diagnoseOperatorAmbiguity(ConstraintSystem &cs,
ConstraintLocator *locator) {
auto &DE = cs.getASTContext().Diags;
auto *anchor = castToExpr(locator->getAnchor());
auto *applyExpr = dyn_cast_or_null<ApplyExpr>(cs.getParentExpr(anchor));
if (!applyExpr)
return;
auto *applyExpr = cast<ApplyExpr>(cs.getParentExpr(anchor));
auto isNameOfStandardComparisonOperator = [](Identifier opName) -> bool {
return opName.is("==") || opName.is("!=") || opName.is("===") ||
@@ -3028,9 +3025,23 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
DE.diagnose(getLoc(commonAnchor), diag::no_candidates_match_result_type,
baseName.userFacingName(), getContextualType(anchor));
} else if (name.isOperator()) {
diagnoseOperatorAmbiguity(*this, name.getBaseIdentifier(), solutions,
commonCalleeLocator);
return true;
auto *anchor = castToExpr(commonCalleeLocator->getAnchor());
// If operator is "applied" e.g. `1 + 2` there are tailored
// diagnostics in case of ambiguity, but if it's referenced
// e.g. `arr.sort(by: <)` it's better to produce generic error
// and a note per candidate.
if (auto *parentExpr = getParentExpr(anchor)) {
if (isa<ApplyExpr>(parentExpr)) {
diagnoseOperatorAmbiguity(*this, name.getBaseIdentifier(), solutions,
commonCalleeLocator);
return true;
}
}
DE.diagnose(anchor->getLoc(), diag::no_overloads_match_exactly_in_call,
/*isApplication=*/false, decl->getDescriptiveKind(),
name.isSpecial(), name.getBaseName());
} else {
bool isApplication =
llvm::any_of(ArgumentInfos, [&](const auto &argInfo) {