[SE-0111] Drop argument labels on references to function values.

When referencing a function in the type checker, drop argument labels
when we don't need them to type-check an immediate call to that
function. This provides the semantic behavior of SE-0111, e.g.,
references to functions as values produce unlabeled function types,
without the representational change of actually dropping argument
labels from the type system.

At the moment, this only works for bare references to functions. It
still needs to be pushed through more of the type checker and more AST
nodes to work in the general case.

Keep this work behind the frontend flag
-suppress-argument-labels-in-types for now.
This commit is contained in:
Doug Gregor
2016-07-28 11:10:53 -07:00
parent 8c7e75afa0
commit a9536906ff
23 changed files with 539 additions and 124 deletions

View File

@@ -997,10 +997,12 @@ namespace {
/// \brief Add constraints for a reference to a named member of the given
/// base type, and return the type of such a reference.
Type addMemberRefConstraints(Expr *expr, Expr *base, DeclName name) {
Type addMemberRefConstraints(Expr *expr, Expr *base, DeclName name,
FunctionRefKind functionRefKind) {
// The base must have a member of the given name, such that accessing
// that member through the base returns a value convertible to the type
// of this expression.
// FIXME: use functionRefKind
auto baseTy = base->getType();
auto tv = CS.createTypeVariable(
CS.getConstraintLocator(expr, ConstraintLocator::Member),
@@ -1012,7 +1014,8 @@ namespace {
/// \brief Add constraints for a reference to a specific member of the given
/// base type, and return the type of such a reference.
Type addMemberRefConstraints(Expr *expr, Expr *base, ValueDecl *decl) {
Type addMemberRefConstraints(Expr *expr, Expr *base, ValueDecl *decl,
FunctionRefKind functionRefKind) {
// If we're referring to an invalid declaration, fail.
if (!decl)
return nullptr;
@@ -1025,7 +1028,8 @@ namespace {
CS.getConstraintLocator(expr, ConstraintLocator::Member);
auto tv = CS.createTypeVariable(memberLocator, TVO_CanBindToLValue);
OverloadChoice choice(base->getType(), decl, /*isSpecialized=*/false, CS);
OverloadChoice choice(base->getType(), decl, /*isSpecialized=*/false,
functionRefKind);
auto locator = CS.getConstraintLocator(expr, ConstraintLocator::Member);
CS.addBindOverloadConstraint(tv, choice, locator);
return tv;
@@ -1115,7 +1119,7 @@ namespace {
// UnresolvedSubscriptExpr from SubscriptExpr.
if (decl) {
OverloadChoice choice(base->getType(), decl, /*isSpecialized=*/false,
CS);
FunctionRefKind::SingleApply);
CS.addBindOverloadConstraint(fnTy, choice, subscriptMemberLocator);
} else {
CS.addValueMemberConstraint(baseTy, Context.Id_subscript,
@@ -1314,7 +1318,8 @@ namespace {
auto tv = CS.createTypeVariable(locator, TVO_CanBindToLValue);
CS.resolveOverload(locator, tv,
OverloadChoice(Type(), E->getDecl(),
E->isSpecialized(), CS));
E->isSpecialized(),
E->getFunctionRefKind()));
if (E->getDecl()->getType() &&
!E->getDecl()->getType()->getAs<TypeVariableType>()) {
@@ -1379,7 +1384,7 @@ namespace {
choices.push_back(OverloadChoice(Type(), decls[i],
expr->isSpecialized(),
CS));
/*FIXME:*/FunctionRefKind::DoubleApply));
}
// If there are no valid overloads, give up.
@@ -1401,12 +1406,14 @@ namespace {
Type visitMemberRefExpr(MemberRefExpr *expr) {
return addMemberRefConstraints(expr, expr->getBase(),
expr->getMember().getDecl());
expr->getMember().getDecl(),
/*FIXME:*/FunctionRefKind::DoubleApply);
}
Type visitDynamicMemberRefExpr(DynamicMemberRefExpr *expr) {
return addMemberRefConstraints(expr, expr->getBase(),
expr->getMember().getDecl());
expr->getMember().getDecl(),
/*FIXME:*/FunctionRefKind::DoubleApply);
}
virtual Type visitUnresolvedMemberExpr(UnresolvedMemberExpr *expr) {
@@ -1495,7 +1502,8 @@ namespace {
return methodTy;
}
return addMemberRefConstraints(expr, expr->getBase(), expr->getName());
return addMemberRefConstraints(expr, expr->getBase(), expr->getName(),
/*FIXME:*/FunctionRefKind::DoubleApply);
}
Type visitUnresolvedSpecializeExpr(UnresolvedSpecializeExpr *expr) {
@@ -1842,7 +1850,8 @@ namespace {
ASTContext &context = CS.getASTContext();
Identifier name
= context.getIdentifier(llvm::utostr(expr->getFieldNumber()));
return addMemberRefConstraints(expr, expr->getBase(), name);
return addMemberRefConstraints(expr, expr->getBase(), name,
FunctionRefKind::Unapplied);
}
/// Give each parameter in a ClosureExpr a fresh type variable if parameter