Sema: Set the type of ParenExpr to ParenType

This eliminates a hack I just added in coerceCallArguments().
This commit is contained in:
Slava Pestov
2018-09-10 22:49:57 -07:00
parent 3d7b7bd907
commit 3dfd8e3993
4 changed files with 30 additions and 40 deletions

View File

@@ -1699,7 +1699,6 @@ public:
Out << "\n";
abort();
}
Type InputExprTy = E->getArg()->getType();
Type ResultExprTy = E->getType();
if (!ResultExprTy->isEqual(FT->getResult())) {
Out << "result of ApplyExpr does not match result type of callee:";
@@ -1709,31 +1708,20 @@ public:
Out << "\n";
abort();
}
if (!InputExprTy->isEqual(FT->getInput())) {
TupleType *TT = FT->getInput()->getAs<TupleType>();
if (isa<SelfApplyExpr>(E)) {
Type InputExprObjectTy;
if (InputExprTy->hasReferenceSemantics() ||
InputExprTy->is<AnyMetatypeType>())
InputExprObjectTy = InputExprTy;
else
InputExprObjectTy = checkLValue(InputExprTy, "object argument");
Type FunctionInputObjectTy = checkLValue(FT->getInput(),
"'self' parameter");
checkSameOrSubType(InputExprObjectTy, FunctionInputObjectTy,
"object argument and 'self' parameter");
} else if (!TT || TT->getNumElements() != 1 ||
!TT->getElement(0).getType()->isEqual(InputExprTy)) {
Out << "Argument type does not match parameter type in ApplyExpr:"
"\nArgument type: ";
E->getArg()->getType().print(Out);
Out << "\nParameter type: ";
FT->printParams(Out);
Out << "\n";
E->dump(Out);
abort();
}
SmallVector<AnyFunctionType::Param, 8> Args;
Type InputExprTy = E->getArg()->getType();
AnyFunctionType::decomposeInput(InputExprTy, Args);
auto Params = FT->getParams();
if (!AnyFunctionType::equalParams(Args, Params)) {
Out << "Argument type does not match parameter type in ApplyExpr:"
"\nArgument type: ";
InputExprTy.print(Out);
Out << "\nParameter types: ";
FT->printParams(Out);
Out << "\n";
E->dump(Out);
abort();
}
if (!E->isThrowsSet()) {

View File

@@ -5679,6 +5679,8 @@ Expr *ExprRewriter::coerceCallArguments(
param.getParameterFlags()));
}
Type argTupleType = TupleType::get(fromTupleExprFields, tc.Context);
// Compute a new 'arg', from the bits we have. We have three cases: the
// scalar case, the paren case, and the tuple literal case.
if (!argTuple && !argParen) {
@@ -5695,7 +5697,7 @@ Expr *ExprRewriter::coerceCallArguments(
fromTupleExpr[0],
argParen->getRParenLoc(),
argParen->hasTrailingClosure(),
cs.getType(fromTupleExpr[0])));
argTupleType));
if (argParenImplicit) {
argParen->setImplicit();
}
@@ -5703,7 +5705,7 @@ Expr *ExprRewriter::coerceCallArguments(
} else {
// coerceToType may have updated the element type of the ParenExpr in
// place. If so, propagate the type out to the ParenExpr as well.
cs.setType(argParen, cs.getType(fromTupleExpr[0]));
cs.setType(argParen, argTupleType);
}
} else {
assert(argTuple);
@@ -5733,14 +5735,6 @@ Expr *ExprRewriter::coerceCallArguments(
}
}
// If we only have one argument and one parameter, we're done.
if (argTuple == nullptr &&
params.size() == 1 &&
params[0].getLabel().empty() &&
!params[0].isVariadic()) {
return arg;
}
// If we don't have to shuffle anything, we're done.
args.clear();
AnyFunctionType::decomposeInput(cs.getType(arg), args);
@@ -7127,15 +7121,18 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
auto escapable = new (tc.Context)
OpaqueValueExpr(apply->getFn()->getLoc(), Type());
cs.setType(escapable, FunctionType::composeInput(
tc.Context, escapableParams, false));
cs.setType(escapable, escapableParams[0].getType());
auto getType = [&](const Expr *E) -> Type {
return cs.getType(E);
};
auto callSubExpr = CallExpr::createImplicit(tc.Context, body, {escapable}, {}, getType);
auto callSubExpr = CallExpr::createImplicit(tc.Context, body,
{escapable}, {}, getType);
cs.cacheSubExprTypes(callSubExpr);
cs.setType(callSubExpr->getArg(),
AnyFunctionType::composeInput(tc.Context,
escapableParams, false));
cs.setType(callSubExpr, resultType);
auto replacement = new (tc.Context)

View File

@@ -271,7 +271,7 @@ void REPLChecker::generatePrintOfExpression(StringRef NameStr, Expr *E) {
TC.typeCheckClosureBody(CE);
auto *TheCall = CallExpr::createImplicit(Context, CE, { E }, { });
TheCall->getArg()->setType(ParenType::get(Context, E->getType()));
TheCall->getArg()->setType(AnyFunctionType::composeInput(Context, args, false));
TheCall->setType(Context.TheEmptyTupleType);
// Inject the call into the top level stream by wrapping it with a TLCD.

View File

@@ -31,3 +31,8 @@ func testVariations(
return takesFn($0)
}
}
func testBlock(f: @convention(block) () -> ()) {
let escape: (@escaping @convention(block) () -> ()) -> () = { _ in }
let _: () = withoutActuallyEscaping(f, do: escape)
}