[CS] Resolve callees for implicit callAsFunction

Add a case to getCalleeLocator to return the
appropriate locator for a call to an implicit
callAsFunction member reference.

Resolves SR-11386 & SR-11778.
This commit is contained in:
Hamish Knight
2019-11-21 14:17:29 -08:00
parent 778e130f31
commit bf0e9c727d
5 changed files with 66 additions and 1 deletions

View File

@@ -478,10 +478,18 @@ ConstraintSystem::getCalleeLocator(ConstraintLocator *locator,
if (lookThroughApply) {
if (auto *applyExpr = dyn_cast<ApplyExpr>(anchor)) {
auto *fnExpr = applyExpr->getFn();
// FIXME: We should probably assert that we don't get a type variable
// here to make sure we only retrieve callee locators for resolved calls,
// ensuring that callee locators don't change after binding a type.
// Unfortunately CSDiag currently calls into getCalleeLocator, so all bets
// are off. Once we remove that legacy diagnostic logic, we should be able
// to assert here.
auto fnTy = getFixedTypeRecursive(getType(fnExpr), /*wantRValue*/ true);
// For an apply of a metatype, we have a short-form constructor. Unlike
// other locators to callees, these are anchored on the apply expression
// rather than the function expr.
auto fnTy = getFixedTypeRecursive(getType(fnExpr), /*wantRValue*/ true);
if (fnTy->is<AnyMetatypeType>()) {
auto *fnLocator =
getConstraintLocator(applyExpr, ConstraintLocator::ApplyFunction);
@@ -489,6 +497,10 @@ ConstraintSystem::getCalleeLocator(ConstraintLocator *locator,
ConstraintLocator::ConstructorMember);
}
// Handle an apply of a nominal type which supports callAsFunction.
if (fnTy->isCallableNominalType(DC))
return getConstraintLocator(anchor, ConstraintLocator::ApplyFunction);
// Otherwise fall through and look for locators anchored on the function
// expr. For CallExprs, this can look through things like parens and
// optional chaining.