mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Set the type of ParenExpr to ParenType
This eliminates a hack I just added in coerceCallArguments().
This commit is contained in:
@@ -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()) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user