[CS] Consolidate logic forming locators to callees

This commit adds `ConstraintSystem::getCalleeLocator`, which forms a
locator that describes the callee of a given expression. This function
is then used to replace various places where this logic is duplicated.

This commit also changes the conditions under which a ConstructorMember
callee locator is formed. Previously it was formed for a CallExpr with a
TypeExpr function expr. However, now such a locator is formed if the
function expr is of AnyMetatypeType. This allows it to be more lenient
with invalid code, as well as work with DotSelfExpr.

Resolves SR-10694.
This commit is contained in:
Hamish Knight
2019-05-15 20:31:53 +01:00
committed by Hamish Knight
parent 30be693913
commit 894a1e50bf
6 changed files with 75 additions and 89 deletions

View File

@@ -411,6 +411,44 @@ ConstraintLocator *ConstraintSystem::getConstraintLocator(
return getConstraintLocator(anchor, path, builder.getSummaryFlags());
}
ConstraintLocator *ConstraintSystem::getCalleeLocator(Expr *expr) {
if (auto *applyExpr = dyn_cast<ApplyExpr>(expr)) {
auto *fnExpr = applyExpr->getFn();
// 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.
if (simplifyType(getType(fnExpr))->is<AnyMetatypeType>()) {
auto *fnLocator =
getConstraintLocator(applyExpr, ConstraintLocator::ApplyFunction);
return getConstraintLocator(fnLocator,
ConstraintLocator::ConstructorMember);
}
// Otherwise fall through and look for locators anchored on the fn expr.
expr = fnExpr;
}
auto *locator = getConstraintLocator(expr);
if (auto *ude = dyn_cast<UnresolvedDotExpr>(expr)) {
if (TC.getSelfForInitDelegationInConstructor(DC, ude)) {
return getConstraintLocator(locator,
ConstraintLocator::ConstructorMember);
} else {
return getConstraintLocator(locator, ConstraintLocator::Member);
}
}
if (isa<UnresolvedMemberExpr>(expr))
return getConstraintLocator(locator, ConstraintLocator::UnresolvedMember);
if (isa<SubscriptExpr>(expr))
return getConstraintLocator(locator, ConstraintLocator::SubscriptMember);
if (isa<MemberRefExpr>(expr))
return getConstraintLocator(locator, ConstraintLocator::Member);
return locator;
}
Type ConstraintSystem::openUnboundGenericType(UnboundGenericType *unbound,
ConstraintLocatorBuilder locator,
OpenedTypeMap &replacements) {