Skip to content

Commit 3dfd8e3

Browse files
committed
Sema: Set the type of ParenExpr to ParenType
This eliminates a hack I just added in coerceCallArguments().
1 parent 3d7b7bd commit 3dfd8e3

File tree

4 files changed

+30
-40
lines changed

4 files changed

+30
-40
lines changed

lib/AST/ASTVerifier.cpp

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,7 +1699,6 @@ class Verifier : public ASTWalker {
16991699
Out << "\n";
17001700
abort();
17011701
}
1702-
Type InputExprTy = E->getArg()->getType();
17031702
Type ResultExprTy = E->getType();
17041703
if (!ResultExprTy->isEqual(FT->getResult())) {
17051704
Out << "result of ApplyExpr does not match result type of callee:";
@@ -1709,31 +1708,20 @@ class Verifier : public ASTWalker {
17091708
Out << "\n";
17101709
abort();
17111710
}
1712-
if (!InputExprTy->isEqual(FT->getInput())) {
1713-
TupleType *TT = FT->getInput()->getAs<TupleType>();
1714-
if (isa<SelfApplyExpr>(E)) {
1715-
Type InputExprObjectTy;
1716-
if (InputExprTy->hasReferenceSemantics() ||
1717-
InputExprTy->is<AnyMetatypeType>())
1718-
InputExprObjectTy = InputExprTy;
1719-
else
1720-
InputExprObjectTy = checkLValue(InputExprTy, "object argument");
1721-
Type FunctionInputObjectTy = checkLValue(FT->getInput(),
1722-
"'self' parameter");
1723-
1724-
checkSameOrSubType(InputExprObjectTy, FunctionInputObjectTy,
1725-
"object argument and 'self' parameter");
1726-
} else if (!TT || TT->getNumElements() != 1 ||
1727-
!TT->getElement(0).getType()->isEqual(InputExprTy)) {
1728-
Out << "Argument type does not match parameter type in ApplyExpr:"
1729-
"\nArgument type: ";
1730-
E->getArg()->getType().print(Out);
1731-
Out << "\nParameter type: ";
1732-
FT->printParams(Out);
1733-
Out << "\n";
1734-
E->dump(Out);
1735-
abort();
1736-
}
1711+
1712+
SmallVector<AnyFunctionType::Param, 8> Args;
1713+
Type InputExprTy = E->getArg()->getType();
1714+
AnyFunctionType::decomposeInput(InputExprTy, Args);
1715+
auto Params = FT->getParams();
1716+
if (!AnyFunctionType::equalParams(Args, Params)) {
1717+
Out << "Argument type does not match parameter type in ApplyExpr:"
1718+
"\nArgument type: ";
1719+
InputExprTy.print(Out);
1720+
Out << "\nParameter types: ";
1721+
FT->printParams(Out);
1722+
Out << "\n";
1723+
E->dump(Out);
1724+
abort();
17371725
}
17381726

17391727
if (!E->isThrowsSet()) {

lib/Sema/CSApply.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5679,6 +5679,8 @@ Expr *ExprRewriter::coerceCallArguments(
56795679
param.getParameterFlags()));
56805680
}
56815681

5682+
Type argTupleType = TupleType::get(fromTupleExprFields, tc.Context);
5683+
56825684
// Compute a new 'arg', from the bits we have. We have three cases: the
56835685
// scalar case, the paren case, and the tuple literal case.
56845686
if (!argTuple && !argParen) {
@@ -5695,15 +5697,15 @@ Expr *ExprRewriter::coerceCallArguments(
56955697
fromTupleExpr[0],
56965698
argParen->getRParenLoc(),
56975699
argParen->hasTrailingClosure(),
5698-
cs.getType(fromTupleExpr[0])));
5700+
argTupleType));
56995701
if (argParenImplicit) {
57005702
argParen->setImplicit();
57015703
}
57025704
arg = argParen;
57035705
} else {
57045706
// coerceToType may have updated the element type of the ParenExpr in
57055707
// place. If so, propagate the type out to the ParenExpr as well.
5706-
cs.setType(argParen, cs.getType(fromTupleExpr[0]));
5708+
cs.setType(argParen, argTupleType);
57075709
}
57085710
} else {
57095711
assert(argTuple);
@@ -5733,14 +5735,6 @@ Expr *ExprRewriter::coerceCallArguments(
57335735
}
57345736
}
57355737

5736-
// If we only have one argument and one parameter, we're done.
5737-
if (argTuple == nullptr &&
5738-
params.size() == 1 &&
5739-
params[0].getLabel().empty() &&
5740-
!params[0].isVariadic()) {
5741-
return arg;
5742-
}
5743-
57445738
// If we don't have to shuffle anything, we're done.
57455739
args.clear();
57465740
AnyFunctionType::decomposeInput(cs.getType(arg), args);
@@ -7127,15 +7121,18 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
71277121

71287122
auto escapable = new (tc.Context)
71297123
OpaqueValueExpr(apply->getFn()->getLoc(), Type());
7130-
cs.setType(escapable, FunctionType::composeInput(
7131-
tc.Context, escapableParams, false));
7124+
cs.setType(escapable, escapableParams[0].getType());
71327125

71337126
auto getType = [&](const Expr *E) -> Type {
71347127
return cs.getType(E);
71357128
};
71367129

7137-
auto callSubExpr = CallExpr::createImplicit(tc.Context, body, {escapable}, {}, getType);
7130+
auto callSubExpr = CallExpr::createImplicit(tc.Context, body,
7131+
{escapable}, {}, getType);
71387132
cs.cacheSubExprTypes(callSubExpr);
7133+
cs.setType(callSubExpr->getArg(),
7134+
AnyFunctionType::composeInput(tc.Context,
7135+
escapableParams, false));
71397136
cs.setType(callSubExpr, resultType);
71407137

71417138
auto replacement = new (tc.Context)

lib/Sema/TypeCheckREPL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ void REPLChecker::generatePrintOfExpression(StringRef NameStr, Expr *E) {
271271
TC.typeCheckClosureBody(CE);
272272

273273
auto *TheCall = CallExpr::createImplicit(Context, CE, { E }, { });
274-
TheCall->getArg()->setType(ParenType::get(Context, E->getType()));
274+
TheCall->getArg()->setType(AnyFunctionType::composeInput(Context, args, false));
275275
TheCall->setType(Context.TheEmptyTupleType);
276276

277277
// Inject the call into the top level stream by wrapping it with a TLCD.

test/Constraints/without_actually_escaping_no_errors.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,8 @@ func testVariations(
3131
return takesFn($0)
3232
}
3333
}
34+
35+
func testBlock(f: @convention(block) () -> ()) {
36+
let escape: (@escaping @convention(block) () -> ()) -> () = { _ in }
37+
let _: () = withoutActuallyEscaping(f, do: escape)
38+
}

0 commit comments

Comments
 (0)