@@ -2641,10 +2641,7 @@ static void diagnoseOperatorAmbiguity(ConstraintSystem &cs,
26412641 ConstraintLocator *locator) {
26422642 auto &DE = cs.getASTContext ().Diags ;
26432643 auto *anchor = castToExpr (locator->getAnchor ());
2644-
2645- auto *applyExpr = dyn_cast_or_null<ApplyExpr>(cs.getParentExpr (anchor));
2646- if (!applyExpr)
2647- return ;
2644+ auto *applyExpr = cast<ApplyExpr>(cs.getParentExpr (anchor));
26482645
26492646 auto isNameOfStandardComparisonOperator = [](Identifier opName) -> bool {
26502647 return opName.is (" ==" ) || opName.is (" !=" ) || opName.is (" ===" ) ||
@@ -3028,9 +3025,23 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
30283025 DE.diagnose (getLoc (commonAnchor), diag::no_candidates_match_result_type,
30293026 baseName.userFacingName (), getContextualType (anchor));
30303027 } else if (name.isOperator ()) {
3031- diagnoseOperatorAmbiguity (*this , name.getBaseIdentifier (), solutions,
3032- commonCalleeLocator);
3033- return true ;
3028+ auto *anchor = castToExpr (commonCalleeLocator->getAnchor ());
3029+
3030+ // If operator is "applied" e.g. `1 + 2` there are tailored
3031+ // diagnostics in case of ambiguity, but if it's referenced
3032+ // e.g. `arr.sort(by: <)` it's better to produce generic error
3033+ // and a note per candidate.
3034+ if (auto *parentExpr = getParentExpr (anchor)) {
3035+ if (isa<ApplyExpr>(parentExpr)) {
3036+ diagnoseOperatorAmbiguity (*this , name.getBaseIdentifier (), solutions,
3037+ commonCalleeLocator);
3038+ return true ;
3039+ }
3040+ }
3041+
3042+ DE.diagnose (anchor->getLoc (), diag::no_overloads_match_exactly_in_call,
3043+ /* isApplication=*/ false , decl->getDescriptiveKind (),
3044+ name.isSpecial (), name.getBaseName ());
30343045 } else {
30353046 bool isApplication =
30363047 llvm::any_of (ArgumentInfos, [&](const auto &argInfo) {
0 commit comments