Skip to content

Commit a282aaa

Browse files
committed
[CSClosure] Rename closure solution application and switch to AnyFunctionRef
Closure solution application has been renamed to `SyntacticElementSolutionApplication` and can now handle both closure and function bodies.
1 parent e801342 commit a282aaa

File tree

1 file changed

+44
-40
lines changed

1 file changed

+44
-40
lines changed

lib/Sema/CSClosure.cpp

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,12 +1124,12 @@ ConstraintSystem::simplifySyntacticElementConstraint(
11241124
namespace {
11251125

11261126
/// Statement visitor that applies constraints for a given closure body.
1127-
class ClosureConstraintApplication
1128-
: public StmtVisitor<ClosureConstraintApplication, ASTNode> {
1129-
friend StmtVisitor<ClosureConstraintApplication, ASTNode>;
1127+
class SyntacticElementSolutionApplication
1128+
: public StmtVisitor<SyntacticElementSolutionApplication, ASTNode> {
1129+
friend StmtVisitor<SyntacticElementSolutionApplication, ASTNode>;
11301130

11311131
Solution &solution;
1132-
ClosureExpr *closure;
1132+
AnyFunctionRef context;
11331133
Type resultType;
11341134
RewriteTargetFn rewriteTarget;
11351135
bool isSingleExpression;
@@ -1141,19 +1141,19 @@ class ClosureConstraintApplication
11411141
/// Whether an error was encountered while generating constraints.
11421142
bool hadError = false;
11431143

1144-
ClosureConstraintApplication(
1145-
Solution &solution, ClosureExpr *closure, Type resultType,
1146-
RewriteTargetFn rewriteTarget)
1147-
: solution(solution), closure(closure), resultType(resultType),
1148-
rewriteTarget(rewriteTarget),
1149-
isSingleExpression(closure->hasSingleExpressionBody()) { }
1144+
SyntacticElementSolutionApplication(Solution &solution,
1145+
AnyFunctionRef context, Type resultType,
1146+
RewriteTargetFn rewriteTarget)
1147+
: solution(solution), context(context), resultType(resultType),
1148+
rewriteTarget(rewriteTarget),
1149+
isSingleExpression(context.hasSingleExpressionBody()) {}
11501150

11511151
private:
11521152
/// Rewrite an expression without any particularly special context.
11531153
Expr *rewriteExpr(Expr *expr) {
1154-
auto result = rewriteTarget(
1155-
SolutionApplicationTarget(expr, closure, CTP_Unused, Type(),
1156-
/*isDiscarded=*/false));
1154+
auto result = rewriteTarget(SolutionApplicationTarget(
1155+
expr, context.getAsDeclContext(), CTP_Unused, Type(),
1156+
/*isDiscarded=*/false));
11571157
if (result)
11581158
return result->getAsExpr();
11591159

@@ -1193,30 +1193,32 @@ class ClosureConstraintApplication
11931193
}
11941194

11951195
ASTNode visitBreakStmt(BreakStmt *breakStmt) {
1196+
auto *DC = context.getAsDeclContext();
11961197
if (auto target = findBreakOrContinueStmtTarget(
1197-
closure->getASTContext(), closure->getParentSourceFile(),
1198-
breakStmt->getLoc(), breakStmt->getTargetName(),
1199-
breakStmt->getTargetLoc(),
1200-
/*isContinue=*/false, closure)) {
1198+
DC->getASTContext(), DC->getParentSourceFile(), breakStmt->getLoc(),
1199+
breakStmt->getTargetName(), breakStmt->getTargetLoc(),
1200+
/*isContinue=*/false, context.getAsDeclContext())) {
12011201
breakStmt->setTarget(target);
12021202
}
12031203

12041204
return breakStmt;
12051205
}
12061206

12071207
ASTNode visitContinueStmt(ContinueStmt *continueStmt) {
1208+
auto *DC = context.getAsDeclContext();
12081209
if (auto target = findBreakOrContinueStmtTarget(
1209-
closure->getASTContext(), closure->getParentSourceFile(),
1210+
DC->getASTContext(), DC->getParentSourceFile(),
12101211
continueStmt->getLoc(), continueStmt->getTargetName(),
1211-
continueStmt->getTargetLoc(), /*isContinue=*/true, closure)) {
1212+
continueStmt->getTargetLoc(), /*isContinue=*/true,
1213+
context.getAsDeclContext())) {
12121214
continueStmt->setTarget(target);
12131215
}
12141216

12151217
return continueStmt;
12161218
}
12171219

12181220
ASTNode visitFallthroughStmt(FallthroughStmt *fallthroughStmt) {
1219-
if (checkFallthroughStmt(closure, fallthroughStmt))
1221+
if (checkFallthroughStmt(context.getAsDeclContext(), fallthroughStmt))
12201222
hadError = true;
12211223
return fallthroughStmt;
12221224
}
@@ -1225,16 +1227,16 @@ class ClosureConstraintApplication
12251227
TypeChecker::typeCheckDecl(deferStmt->getTempDecl());
12261228

12271229
Expr *theCall = deferStmt->getCallExpr();
1228-
TypeChecker::typeCheckExpression(theCall, closure);
1230+
TypeChecker::typeCheckExpression(theCall, context.getAsDeclContext());
12291231
deferStmt->setCallExpr(theCall);
12301232

12311233
return deferStmt;
12321234
}
12331235

12341236
ASTNode visitIfStmt(IfStmt *ifStmt) {
12351237
// Rewrite the condition.
1236-
if (auto condition = rewriteTarget(
1237-
SolutionApplicationTarget(ifStmt->getCond(), closure)))
1238+
if (auto condition = rewriteTarget(SolutionApplicationTarget(
1239+
ifStmt->getCond(), context.getAsDeclContext())))
12381240
ifStmt->setCond(*condition->getAsStmtCondition());
12391241
else
12401242
hadError = true;
@@ -1249,8 +1251,8 @@ class ClosureConstraintApplication
12491251
}
12501252

12511253
ASTNode visitGuardStmt(GuardStmt *guardStmt) {
1252-
if (auto condition = rewriteTarget(
1253-
SolutionApplicationTarget(guardStmt->getCond(), closure)))
1254+
if (auto condition = rewriteTarget(SolutionApplicationTarget(
1255+
guardStmt->getCond(), context.getAsDeclContext())))
12541256
guardStmt->setCond(*condition->getAsStmtCondition());
12551257
else
12561258
hadError = true;
@@ -1261,8 +1263,8 @@ class ClosureConstraintApplication
12611263
}
12621264

12631265
ASTNode visitWhileStmt(WhileStmt *whileStmt) {
1264-
if (auto condition = rewriteTarget(
1265-
SolutionApplicationTarget(whileStmt->getCond(), closure)))
1266+
if (auto condition = rewriteTarget(SolutionApplicationTarget(
1267+
whileStmt->getCond(), context.getAsDeclContext())))
12661268
whileStmt->setCond(*condition->getAsStmtCondition());
12671269
else
12681270
hadError = true;
@@ -1336,7 +1338,8 @@ class ClosureConstraintApplication
13361338

13371339
// Check to see if the sequence expr is throwing (in async context),
13381340
// if so require the stmt to have a `try`.
1339-
hadError |= diagnoseUnhandledThrowsInAsyncContext(closure, forEachStmt);
1341+
hadError |= diagnoseUnhandledThrowsInAsyncContext(
1342+
context.getAsDeclContext(), forEachStmt);
13401343

13411344
return forEachStmt;
13421345
}
@@ -1371,8 +1374,8 @@ class ClosureConstraintApplication
13711374
}
13721375
}
13731376

1374-
TypeChecker::checkSwitchExhaustiveness(switchStmt, closure,
1375-
limitExhaustivityChecks);
1377+
TypeChecker::checkSwitchExhaustiveness(
1378+
switchStmt, context.getAsDeclContext(), limitExhaustivityChecks);
13761379

13771380
return switchStmt;
13781381
}
@@ -1392,7 +1395,8 @@ class ClosureConstraintApplication
13921395
ASTNode visitCaseStmt(CaseStmt *caseStmt) {
13931396
// Translate the patterns and guard expressions for each case label item.
13941397
for (auto &caseItem : caseStmt->getMutableCaseLabelItems()) {
1395-
SolutionApplicationTarget caseTarget(&caseItem, closure);
1398+
SolutionApplicationTarget caseTarget(&caseItem,
1399+
context.getAsDeclContext());
13961400
if (!rewriteTarget(caseTarget)) {
13971401
hadError = true;
13981402
}
@@ -1420,7 +1424,7 @@ class ClosureConstraintApplication
14201424
if (!braceStmt->empty()) {
14211425
if (auto stmt = braceStmt->getLastElement().dyn_cast<Stmt *>()) {
14221426
if (auto deferStmt = dyn_cast<DeferStmt>(stmt)) {
1423-
auto &diags = closure->getASTContext().Diags;
1427+
auto &diags = cs.getASTContext().Diags;
14241428
diags
14251429
.diagnose(deferStmt->getStartLoc(), diag::defer_stmt_at_block_end)
14261430
.fixItReplace(deferStmt->getStartLoc(), "do");
@@ -1462,7 +1466,8 @@ class ClosureConstraintApplication
14621466
// of the body if there is none. This wasn't needed before SE-0326
14631467
// because result type was (incorrectly) inferred as `Void` due to
14641468
// the body being skipped.
1465-
if (!closure->hasSingleExpressionBody() &&
1469+
auto *closure = context.getAbstractClosureExpr();
1470+
if (closure && !closure->hasSingleExpressionBody() &&
14661471
closure->getBody() == braceStmt) {
14671472
if (resultType->getOptionalObjectType() &&
14681473
resultType->lookThroughAllOptionalTypes()->isVoid() &&
@@ -1475,8 +1480,8 @@ class ClosureConstraintApplication
14751480
}
14761481

14771482
ASTNode addImplicitVoidReturn(BraceStmt *braceStmt) {
1478-
auto &ctx = closure->getASTContext();
14791483
auto &cs = solution.getConstraintSystem();
1484+
auto &ctx = cs.getASTContext();
14801485

14811486
auto *resultExpr = getVoidExpr(ctx);
14821487
cs.cacheExprTypes(resultExpr);
@@ -1488,8 +1493,8 @@ class ClosureConstraintApplication
14881493
// to it, to make sure that optional injection happens required
14891494
// number of times.
14901495
{
1491-
SolutionApplicationTarget target(resultExpr, closure, CTP_ReturnStmt,
1492-
resultType,
1496+
SolutionApplicationTarget target(resultExpr, context.getAsDeclContext(),
1497+
CTP_ReturnStmt, resultType,
14931498
/*isDiscarded=*/false);
14941499
cs.setSolutionApplicationTarget(returnStmt, target);
14951500

@@ -1554,7 +1559,7 @@ class ClosureConstraintApplication
15541559
}
15551560

15561561
SolutionApplicationTarget resultTarget(
1557-
resultExpr, closure,
1562+
resultExpr, context.getAsDeclContext(),
15581563
mode == convertToResult ? CTP_ReturnStmt : CTP_Unused,
15591564
mode == convertToResult ? resultType : Type(),
15601565
/*isDiscarded=*/false);
@@ -1601,7 +1606,7 @@ class ClosureConstraintApplication
16011606
public:
16021607
/// Apply solution to the closure and return updated body.
16031608
ASTNode apply() {
1604-
auto body = visit(closure->getBody());
1609+
auto body = visit(context.getBody());
16051610

16061611
// Since local functions can capture variables that are declared
16071612
// after them, let's type-check them after all of the pattern
@@ -1612,7 +1617,6 @@ class ClosureConstraintApplication
16121617
return body;
16131618
}
16141619
};
1615-
16161620
}
16171621

16181622
SolutionApplicationToFunctionResult ConstraintSystem::applySolution(
@@ -1705,7 +1709,7 @@ bool ConstraintSystem::applySolutionToBody(Solution &solution,
17051709
llvm::SaveAndRestore<DeclContext *> savedDC(currentDC, closure);
17061710

17071711
auto closureType = cs.getType(closure)->castTo<FunctionType>();
1708-
ClosureConstraintApplication application(
1712+
SyntacticElementSolutionApplication application(
17091713
solution, closure, closureType->getResult(), rewriteTarget);
17101714
auto body = application.apply();
17111715

0 commit comments

Comments
 (0)