Repository: apple/swift
File: lib/Sema/CSDiagnostics.cpp (C++)

Code before:
        locator->isLastElement<LocatorPathElt::ApplyArgument>() ||
        locator->isLastElement<LocatorPathElt::ClosureResult>() ||
        locator->isLastElement<LocatorPathElt::ClosureBody>()))
    return false;

  // If this is a misplaced `missing argument` situation, it would be
  // diagnosed by invalid conversion fix.
  if (isMisplacedMissingArgument(getSolution(), locator))
    return false;

  auto anchor = getAnchor();

  if (auto *closure = getAsExpr<ClosureExpr>(anchor))
    return diagnoseClosure(closure);

  // This is a situation where function type is passed as an argument
  // to a function type parameter and their argument arity is different.
  //
  // ```
  // func foo(_: (Int) -> Void) {}
  // func bar() {}
  //
  // foo(bar) // `() -> Void` vs. `(Int) -> Void`
  // ```
  if (locator->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
    auto info_ptr = getFunctionArgApplyInfo(locator);
    if (!info_ptr)
      return false;

    auto info = *info_ptr;

    auto *argExpr = info.getArgExpr();
    emitDiagnosticAt(argExpr->getLoc(), diag::cannot_convert_argument_value,
                     info.getArgType(), info.getParamType());
    // TODO: It would be great so somehow point out which arguments are missing.
    return true;
  }

  // Function type has fewer arguments than expected by context:
  //
  // ```
  // func foo() {}
  // let _: (Int) -> Void = foo
  // ```
  if (locator->isLastElement<LocatorPathElt::ContextualType>()) {
    emitDiagnostic(diag::cannot_convert_initializer_value, getType(anchor),
                   resolveType(getContextualType(getAnchor())));
    // TODO: It would be great so somehow point out which arguments are missing.
    return true;
  }


Review comment (suggestion):
I’d expect the fix here would be to adjust `getFunctionArgApplyInfo` to produce a result for key path application instead of null,  because locator points at the argument position.

Code after:
        locator->isLastElement<LocatorPathElt::ApplyArgument>() ||
        locator->isLastElement<LocatorPathElt::ClosureResult>() ||
        locator->isLastElement<LocatorPathElt::ClosureBody>()))
    return false;

  // If this is a misplaced `missing argument` situation, it would be
  // diagnosed by invalid conversion fix.
  if (isMisplacedMissingArgument(getSolution(), locator))
    return false;

  auto anchor = getAnchor();

  if (auto *closure = getAsExpr<ClosureExpr>(anchor))
    return diagnoseClosure(closure);

  // This is a situation where function type is passed as an argument
  // to a function type parameter and their argument arity is different.
  //
  // ```
  // func foo(_: (Int) -> Void) {}
  // func bar() {}
  //
  // foo(bar) // `() -> Void` vs. `(Int) -> Void`
  // ```
  if (locator->isLastElement<LocatorPathElt::ApplyArgToParam>()) {
    auto info = *(getFunctionArgApplyInfo(locator));

    auto *argExpr = info.getArgExpr();
    emitDiagnosticAt(argExpr->getLoc(), diag::cannot_convert_argument_value,
                     info.getArgType(), info.getParamType());
    // TODO: It would be great so somehow point out which arguments are missing.
    return true;
  }

  // Function type has fewer arguments than expected by context:
  //
  // ```
  // func foo() {}
  // let _: (Int) -> Void = foo
  // ```
  if (locator->isLastElement<LocatorPathElt::ContextualType>()) {
    emitDiagnostic(diag::cannot_convert_initializer_value, getType(anchor),
                   resolveType(getContextualType(getAnchor())));
    // TODO: It would be great so somehow point out which arguments are missing.
    return true;
  }

  if (diagnoseMissingResultBuilderElement())
    return true;

  if (diagnoseInvalidTupleDestructuring())