Skip to content

Commit 2b04447

Browse files
authored
[CSDiagnostics] Store FunctionArgApplyInfo on ArgumentMismatch… (swiftlang#27537)
[CSDiagnostics] Store FunctionArgApplyInfo on ArgumentMismatchFailure
2 parents e7c0172 + 6e3671d commit 2b04447

File tree

13 files changed

+221
-137
lines changed

13 files changed

+221
-137
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ ERROR(cannot_convert_argument_value,none,
381381
(Type,Type))
382382

383383
NOTE(candidate_has_invalid_argument_at_position,none,
384-
"candidate expects value of type %0 at position #%1",
384+
"candidate expects value of type %0 for parameter #%1",
385385
(Type, unsigned))
386386

387387
ERROR(cannot_convert_array_to_variadic,none,

lib/Sema/CSDiagnostics.cpp

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -221,20 +221,28 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
221221
if (!argExpr)
222222
return None;
223223

224-
ValueDecl *callee = nullptr;
224+
Optional<OverloadChoice> choice;
225225
Type rawFnType;
226226
if (auto overload = getChoiceFor(argLocator)) {
227227
// If we have resolved an overload for the callee, then use that to get the
228228
// function type and callee.
229-
callee = overload->choice.getDeclOrNull();
229+
choice = overload->choice;
230230
rawFnType = overload->openedType;
231231
} 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+
}
238246
}
239247

240248
// Try to resolve the function type by loading lvalues and looking through
@@ -249,6 +257,7 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
249257
// Resolve the interface type for the function. Note that this may not be a
250258
// function type, for example it could be a generic parameter.
251259
Type fnInterfaceType;
260+
auto *callee = choice ? choice->getDeclOrNull() : nullptr;
252261
if (callee && callee->hasInterfaceType()) {
253262
// If we have a callee with an interface type, we can use it. This is
254263
// preferable to resolveInterfaceType, as this will allow us to get a
@@ -261,7 +270,7 @@ FailureDiagnostic::getFunctionArgApplyInfo(ConstraintLocator *locator) const {
261270
fnInterfaceType = callee->getInterfaceType();
262271

263272
// Strip off the curried self parameter if necessary.
264-
if (callee->hasCurriedSelf())
273+
if (hasAppliedSelf(cs, *choice))
265274
fnInterfaceType = fnInterfaceType->castTo<AnyFunctionType>()->getResult();
266275

267276
if (auto *fn = fnInterfaceType->getAs<AnyFunctionType>()) {
@@ -5033,13 +5042,9 @@ bool ArgumentMismatchFailure::diagnoseAsError() {
50335042
}
50345043

50355044
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());
50435048
return true;
50445049
}
50455050

@@ -5066,11 +5071,10 @@ bool ArgumentMismatchFailure::diagnoseUseOfReferenceEqualityOperator() const {
50665071
// one would cover both arguments.
50675072
if (getAnchor() == rhs && rhsType->is<FunctionType>()) {
50685073
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))})))
50745078
return true;
50755079
}
50765080

@@ -5228,14 +5232,12 @@ bool ArgumentMismatchFailure::diagnoseMisplacedMissingArgument() const {
52285232
if (!MissingArgumentsFailure::isMisplacedMissingArgument(cs, locator))
52295233
return false;
52305234

5231-
auto info = *getFunctionArgApplyInfo(locator);
5232-
52335235
auto *argType = cs.createTypeVariable(
52345236
cs.getConstraintLocator(locator, LocatorPathElt::SynthesizedArgument(1)),
52355237
/*flags=*/0);
52365238

52375239
// Assign new type variable to a type of a parameter.
5238-
auto *fnType = info.getFnType();
5240+
auto *fnType = getFnType();
52395241
const auto &param = fnType->getParams()[0];
52405242
cs.assignFixedType(argType, param.getOldType());
52415243

0 commit comments

Comments
 (0)