@@ -3062,6 +3062,130 @@ diagnoseAmbiguityWithEphemeralPointers(ConstraintSystem &cs,
3062
3062
return cs.diagnoseAmbiguity (solutions);
3063
3063
}
3064
3064
3065
+ static bool diagnoseAmbiguity (
3066
+ ConstraintSystem &cs,
3067
+ ArrayRef<std::pair<const Solution *, const ConstraintFix *>> aggregateFix,
3068
+ SolutionDiff &solutionDiff, ArrayRef<Solution> solutions) {
3069
+ auto anchor = aggregateFix.front ().second ->getAnchor ();
3070
+
3071
+ // Assignment failures are all about the source expression, because
3072
+ // they treat destination as a contextual type.
3073
+ if (auto *assignExpr = getAsExpr<AssignExpr>(anchor))
3074
+ anchor = assignExpr->getSrc ();
3075
+
3076
+ if (auto *callExpr = getAsExpr<CallExpr>(anchor)) {
3077
+ if (!isa<TypeExpr>(callExpr->getDirectCallee ()))
3078
+ anchor = callExpr->getDirectCallee ();
3079
+ } else if (auto *applyExpr = getAsExpr<ApplyExpr>(anchor)) {
3080
+ anchor = applyExpr->getFn ();
3081
+ }
3082
+
3083
+ auto ambiguity =
3084
+ llvm::find_if (solutionDiff.overloads ,
3085
+ [&anchor](const SolutionDiff::OverloadDiff &diff) -> bool {
3086
+ return diff.locator ->getAnchor () == anchor;
3087
+ });
3088
+
3089
+ if (ambiguity == solutionDiff.overloads .end ()) {
3090
+ auto &fix = aggregateFix.front ();
3091
+ return aggregateFix.size () == 1
3092
+ ? fix.second ->diagnose (*fix.first , /* asNote=*/ false )
3093
+ : fix.second ->diagnoseForAmbiguity (aggregateFix);
3094
+ }
3095
+
3096
+ auto &DE = cs.getASTContext ().Diags ;
3097
+
3098
+ auto *decl = ambiguity->choices .front ().getDeclOrNull ();
3099
+ if (!decl)
3100
+ return false ;
3101
+
3102
+ auto *commonCalleeLocator = ambiguity->locator ;
3103
+
3104
+ bool diagnosed = true ;
3105
+ {
3106
+ DiagnosticTransaction transaction (DE);
3107
+
3108
+ auto commonAnchor = commonCalleeLocator->getAnchor ();
3109
+ if (auto *callExpr = getAsExpr<CallExpr>(commonAnchor))
3110
+ commonAnchor = callExpr->getDirectCallee ();
3111
+
3112
+ const auto name = decl->getName ();
3113
+
3114
+ // Emit an error message for the ambiguity.
3115
+ if (name.isOperator ()) {
3116
+ auto *anchor = castToExpr (commonCalleeLocator->getAnchor ());
3117
+
3118
+ // If operator is "applied" e.g. `1 + 2` there are tailored
3119
+ // diagnostics in case of ambiguity, but if it's referenced
3120
+ // e.g. `arr.sort(by: <)` it's better to produce generic error
3121
+ // and a note per candidate.
3122
+ if (auto *parentExpr = cs.getParentExpr (anchor)) {
3123
+ if (isa<ApplyExpr>(parentExpr)) {
3124
+ diagnoseOperatorAmbiguity (cs, name.getBaseIdentifier (), solutions,
3125
+ commonCalleeLocator);
3126
+ return true ;
3127
+ }
3128
+ }
3129
+
3130
+ DE.diagnose (anchor->getLoc (), diag::no_overloads_match_exactly_in_call,
3131
+ /* isApplication=*/ false , decl->getDescriptiveKind (),
3132
+ name.isSpecial (), name.getBaseName ());
3133
+ } else {
3134
+ bool isApplication =
3135
+ llvm::any_of (cs.ArgumentInfos , [&](const auto &argInfo) {
3136
+ return argInfo.first ->getAnchor () == commonAnchor;
3137
+ });
3138
+
3139
+ DE.diagnose (getLoc (commonAnchor),
3140
+ diag::no_overloads_match_exactly_in_call, isApplication,
3141
+ decl->getDescriptiveKind (), name.isSpecial (),
3142
+ name.getBaseName ());
3143
+ }
3144
+
3145
+ // Produce candidate notes
3146
+ SmallPtrSet<ValueDecl *, 4 > distinctChoices;
3147
+ llvm::SmallSet<CanType, 4 > candidateTypes;
3148
+ for (const auto &solution : solutions) {
3149
+ auto overload = solution.getOverloadChoice (commonCalleeLocator);
3150
+ auto *decl = overload.choice .getDecl ();
3151
+ auto type = solution.simplifyType (overload.openedType );
3152
+ // Skip if we've already produced a note for this overload
3153
+ if (!distinctChoices.insert (decl).second )
3154
+ continue ;
3155
+
3156
+ if (solution.Fixes .size () == 1 ) {
3157
+ diagnosed &=
3158
+ solution.Fixes .front ()->diagnose (solution, /* asNote*/ true );
3159
+ } else if (llvm::all_of (solution.Fixes , [&](ConstraintFix *fix) {
3160
+ return fix->getLocator ()
3161
+ ->findLast <LocatorPathElt::ApplyArgument>()
3162
+ .hasValue ();
3163
+ })) {
3164
+ // All fixes have to do with arguments, so let's show the parameter
3165
+ // lists.
3166
+ auto *fn = type->getAs <AnyFunctionType>();
3167
+ assert (fn);
3168
+ DE.diagnose (decl->getLoc (), diag::candidate_partial_match,
3169
+ fn->getParamListAsString (fn->getParams ()));
3170
+ } else {
3171
+ // Emit a general "found candidate" note
3172
+ if (decl->getLoc ().isInvalid ()) {
3173
+ if (candidateTypes.insert (type->getCanonicalType ()).second )
3174
+ DE.diagnose (getLoc (commonAnchor), diag::found_candidate_type, type);
3175
+ } else {
3176
+ DE.diagnose (decl->getLoc (), diag::found_candidate);
3177
+ }
3178
+ }
3179
+ }
3180
+
3181
+ // If not all of the fixes produced a note, we can't diagnose this.
3182
+ if (!diagnosed)
3183
+ transaction.abort ();
3184
+ }
3185
+
3186
+ return diagnosed;
3187
+ }
3188
+
3065
3189
bool ConstraintSystem::diagnoseAmbiguityWithFixes (
3066
3190
SmallVectorImpl<Solution> &solutions) {
3067
3191
if (solutions.empty ())
0 commit comments