[Constraint solver] Synchronize argument label setting/retrievable.

The walker that was setting argument labels was looking through ! and ?
postfix expressions, but the lookup code itself was not, leading to missed
opportunities for filtering based on argument labels. Generalize the
transformation that maps from the function expression down to the locator
for which we will retrieve argument labels.
This commit is contained in:
Doug Gregor
2019-03-01 21:45:39 -08:00
parent 233cf6ffa6
commit 603d5d6f20
4 changed files with 53 additions and 23 deletions

View File

@@ -139,6 +139,25 @@ bool constraints::areConservativelyCompatibleArgumentLabels(
decl, hasCurriedSelf, labels, hasTrailingClosure);
}
Expr *constraints::getArgumentLabelTargetExpr(Expr *fn) {
// Dig out the function, looking through, parentheses, ?, and !.
do {
fn = fn->getSemanticsProvidingExpr();
if (auto force = dyn_cast<ForceValueExpr>(fn)) {
fn = force->getSubExpr();
continue;
}
if (auto bind = dyn_cast<BindOptionalExpr>(fn)) {
fn = bind->getSubExpr();
continue;
}
return fn;
} while (true);
}
bool constraints::
areConservativelyCompatibleArgumentLabels(ValueDecl *decl,
bool hasCurriedSelf,
@@ -3289,13 +3308,6 @@ getArgumentLabels(ConstraintSystem &cs, ConstraintLocatorBuilder locator) {
}
if (parts.back().getKind() == ConstraintLocator::ConstructorMember) {
// FIXME: Workaround for strange anchor on ConstructorMember locators.
if (auto optionalWrapper = dyn_cast<BindOptionalExpr>(anchor))
anchor = optionalWrapper->getSubExpr();
else if (auto forceWrapper = dyn_cast<ForceValueExpr>(anchor))
anchor = forceWrapper->getSubExpr();
parts.pop_back();
continue;
}
@@ -3306,6 +3318,7 @@ getArgumentLabels(ConstraintSystem &cs, ConstraintLocatorBuilder locator) {
if (!parts.empty())
return None;
anchor = getArgumentLabelTargetExpr(anchor);
auto known = cs.ArgumentLabels.find(cs.getConstraintLocator(anchor));
if (known == cs.ArgumentLabels.end())
return None;