@@ -2641,10 +2641,7 @@ static void diagnoseOperatorAmbiguity(ConstraintSystem &cs,
2641
2641
ConstraintLocator *locator) {
2642
2642
auto &DE = cs.getASTContext ().Diags ;
2643
2643
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));
2648
2645
2649
2646
auto isNameOfStandardComparisonOperator = [](Identifier opName) -> bool {
2650
2647
return opName.is (" ==" ) || opName.is (" !=" ) || opName.is (" ===" ) ||
@@ -3028,9 +3025,23 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
3028
3025
DE.diagnose (getLoc (commonAnchor), diag::no_candidates_match_result_type,
3029
3026
baseName.userFacingName (), getContextualType (anchor));
3030
3027
} 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 ());
3034
3045
} else {
3035
3046
bool isApplication =
3036
3047
llvm::any_of (ArgumentInfos, [&](const auto &argInfo) {
0 commit comments