@@ -221,20 +221,28 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
221
221
if (!argExpr)
222
222
return None;
223
223
224
- ValueDecl *callee = nullptr ;
224
+ Optional<OverloadChoice> choice ;
225
225
Type rawFnType;
226
226
if (auto overload = getChoiceFor (argLocator)) {
227
227
// If we have resolved an overload for the callee, then use that to get the
228
228
// function type and callee.
229
- callee = overload->choice . getDeclOrNull () ;
229
+ choice = overload->choice ;
230
230
rawFnType = overload->openedType ;
231
231
} else {
232
- // If we didn't resolve an overload for the callee, we must be dealing with
233
- // a call of an arbitrary function expr.
234
- auto *call = cast<CallExpr>(anchor);
235
- assert (!shouldHaveDirectCalleeOverload (call) &&
236
- " Should we have resolved a callee for this?" );
237
- rawFnType = cs.getType (call->getFn ());
232
+ // If we didn't resolve an overload for the callee, we should be dealing
233
+ // with a call of an arbitrary function expr.
234
+ if (auto *call = dyn_cast<CallExpr>(anchor)) {
235
+ assert (!shouldHaveDirectCalleeOverload (call) &&
236
+ " Should we have resolved a callee for this?" );
237
+ rawFnType = cs.getType (call->getFn ());
238
+ } else {
239
+ // FIXME: ArgumentMismatchFailure is currently used from CSDiag, meaning
240
+ // we can end up a BinaryExpr here with an unresolved callee. It should be
241
+ // possible to remove this once we've gotten rid of the old CSDiag logic
242
+ // and just assert that we have a CallExpr.
243
+ auto *apply = cast<ApplyExpr>(anchor);
244
+ rawFnType = cs.getType (apply->getFn ());
245
+ }
238
246
}
239
247
240
248
// Try to resolve the function type by loading lvalues and looking through
@@ -249,6 +257,7 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
249
257
// Resolve the interface type for the function. Note that this may not be a
250
258
// function type, for example it could be a generic parameter.
251
259
Type fnInterfaceType;
260
+ auto *callee = choice ? choice->getDeclOrNull () : nullptr ;
252
261
if (callee && callee->hasInterfaceType ()) {
253
262
// If we have a callee with an interface type, we can use it. This is
254
263
// preferable to resolveInterfaceType, as this will allow us to get a
@@ -261,7 +270,7 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
261
270
fnInterfaceType = callee->getInterfaceType ();
262
271
263
272
// Strip off the curried self parameter if necessary.
264
- if (callee-> hasCurriedSelf ( ))
273
+ if (hasAppliedSelf (cs, *choice ))
265
274
fnInterfaceType = fnInterfaceType->castTo <AnyFunctionType>()->getResult ();
266
275
267
276
if (auto *fn = fnInterfaceType->getAs <AnyFunctionType>()) {
@@ -5033,13 +5042,9 @@ bool ArgumentMismatchFailure::diagnoseAsError() {
5033
5042
}
5034
5043
5035
5044
bool ArgumentMismatchFailure::diagnoseAsNote () {
5036
- auto *locator = getLocator ();
5037
- auto argToParam = locator->findFirst <LocatorPathElt::ApplyArgToParam>();
5038
- assert (argToParam);
5039
-
5040
- if (auto *decl = getDecl ()) {
5041
- emitDiagnostic (decl, diag::candidate_has_invalid_argument_at_position,
5042
- getToType (), argToParam->getParamIdx ());
5045
+ if (auto *callee = getCallee ()) {
5046
+ emitDiagnostic (callee, diag::candidate_has_invalid_argument_at_position,
5047
+ getToType (), getParamPosition ());
5043
5048
return true ;
5044
5049
}
5045
5050
@@ -5066,11 +5071,10 @@ bool ArgumentMismatchFailure::diagnoseUseOfReferenceEqualityOperator() const {
5066
5071
// one would cover both arguments.
5067
5072
if (getAnchor () == rhs && rhsType->is <FunctionType>()) {
5068
5073
auto &cs = getConstraintSystem ();
5069
- auto info = getFunctionArgApplyInfo (locator);
5070
- if (info && cs.hasFixFor (cs.getConstraintLocator (
5071
- binaryOp, {ConstraintLocator::ApplyArgument,
5072
- LocatorPathElt::ApplyArgToParam (
5073
- 0 , 0 , info->getParameterFlagsAtIndex (0 ))})))
5074
+ if (cs.hasFixFor (cs.getConstraintLocator (
5075
+ binaryOp, {ConstraintLocator::ApplyArgument,
5076
+ LocatorPathElt::ApplyArgToParam (
5077
+ 0 , 0 , getParameterFlagsAtIndex (0 ))})))
5074
5078
return true ;
5075
5079
}
5076
5080
@@ -5228,14 +5232,12 @@ bool ArgumentMismatchFailure::diagnoseMisplacedMissingArgument() const {
5228
5232
if (!MissingArgumentsFailure::isMisplacedMissingArgument (cs, locator))
5229
5233
return false ;
5230
5234
5231
- auto info = *getFunctionArgApplyInfo (locator);
5232
-
5233
5235
auto *argType = cs.createTypeVariable (
5234
5236
cs.getConstraintLocator (locator, LocatorPathElt::SynthesizedArgument (1 )),
5235
5237
/* flags=*/ 0 );
5236
5238
5237
5239
// Assign new type variable to a type of a parameter.
5238
- auto *fnType = info. getFnType ();
5240
+ auto *fnType = getFnType ();
5239
5241
const auto ¶m = fnType->getParams ()[0 ];
5240
5242
cs.assignFixedType (argType, param.getOldType ());
5241
5243
0 commit comments