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