mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[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:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user