@@ -1124,12 +1124,12 @@ ConstraintSystem::simplifySyntacticElementConstraint(
1124
1124
namespace {
1125
1125
1126
1126
// / 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>;
1130
1130
1131
1131
Solution &solution;
1132
- ClosureExpr *closure ;
1132
+ AnyFunctionRef context ;
1133
1133
Type resultType;
1134
1134
RewriteTargetFn rewriteTarget;
1135
1135
bool isSingleExpression;
@@ -1141,19 +1141,19 @@ class ClosureConstraintApplication
1141
1141
// / Whether an error was encountered while generating constraints.
1142
1142
bool hadError = false ;
1143
1143
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()) {}
1150
1150
1151
1151
private:
1152
1152
// / Rewrite an expression without any particularly special context.
1153
1153
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 ));
1157
1157
if (result)
1158
1158
return result->getAsExpr ();
1159
1159
@@ -1193,30 +1193,32 @@ class ClosureConstraintApplication
1193
1193
}
1194
1194
1195
1195
ASTNode visitBreakStmt (BreakStmt *breakStmt) {
1196
+ auto *DC = context.getAsDeclContext ();
1196
1197
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 ())) {
1201
1201
breakStmt->setTarget (target);
1202
1202
}
1203
1203
1204
1204
return breakStmt;
1205
1205
}
1206
1206
1207
1207
ASTNode visitContinueStmt (ContinueStmt *continueStmt) {
1208
+ auto *DC = context.getAsDeclContext ();
1208
1209
if (auto target = findBreakOrContinueStmtTarget (
1209
- closure ->getASTContext (), closure ->getParentSourceFile (),
1210
+ DC ->getASTContext (), DC ->getParentSourceFile (),
1210
1211
continueStmt->getLoc (), continueStmt->getTargetName (),
1211
- continueStmt->getTargetLoc (), /* isContinue=*/ true , closure)) {
1212
+ continueStmt->getTargetLoc (), /* isContinue=*/ true ,
1213
+ context.getAsDeclContext ())) {
1212
1214
continueStmt->setTarget (target);
1213
1215
}
1214
1216
1215
1217
return continueStmt;
1216
1218
}
1217
1219
1218
1220
ASTNode visitFallthroughStmt (FallthroughStmt *fallthroughStmt) {
1219
- if (checkFallthroughStmt (closure , fallthroughStmt))
1221
+ if (checkFallthroughStmt (context. getAsDeclContext () , fallthroughStmt))
1220
1222
hadError = true ;
1221
1223
return fallthroughStmt;
1222
1224
}
@@ -1225,16 +1227,16 @@ class ClosureConstraintApplication
1225
1227
TypeChecker::typeCheckDecl (deferStmt->getTempDecl ());
1226
1228
1227
1229
Expr *theCall = deferStmt->getCallExpr ();
1228
- TypeChecker::typeCheckExpression (theCall, closure );
1230
+ TypeChecker::typeCheckExpression (theCall, context. getAsDeclContext () );
1229
1231
deferStmt->setCallExpr (theCall);
1230
1232
1231
1233
return deferStmt;
1232
1234
}
1233
1235
1234
1236
ASTNode visitIfStmt (IfStmt *ifStmt) {
1235
1237
// Rewrite the condition.
1236
- if (auto condition = rewriteTarget (
1237
- SolutionApplicationTarget ( ifStmt->getCond (), closure )))
1238
+ if (auto condition = rewriteTarget (SolutionApplicationTarget (
1239
+ ifStmt->getCond (), context. getAsDeclContext () )))
1238
1240
ifStmt->setCond (*condition->getAsStmtCondition ());
1239
1241
else
1240
1242
hadError = true ;
@@ -1249,8 +1251,8 @@ class ClosureConstraintApplication
1249
1251
}
1250
1252
1251
1253
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 () )))
1254
1256
guardStmt->setCond (*condition->getAsStmtCondition ());
1255
1257
else
1256
1258
hadError = true ;
@@ -1261,8 +1263,8 @@ class ClosureConstraintApplication
1261
1263
}
1262
1264
1263
1265
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 () )))
1266
1268
whileStmt->setCond (*condition->getAsStmtCondition ());
1267
1269
else
1268
1270
hadError = true ;
@@ -1336,7 +1338,8 @@ class ClosureConstraintApplication
1336
1338
1337
1339
// Check to see if the sequence expr is throwing (in async context),
1338
1340
// if so require the stmt to have a `try`.
1339
- hadError |= diagnoseUnhandledThrowsInAsyncContext (closure, forEachStmt);
1341
+ hadError |= diagnoseUnhandledThrowsInAsyncContext (
1342
+ context.getAsDeclContext (), forEachStmt);
1340
1343
1341
1344
return forEachStmt;
1342
1345
}
@@ -1371,8 +1374,8 @@ class ClosureConstraintApplication
1371
1374
}
1372
1375
}
1373
1376
1374
- TypeChecker::checkSwitchExhaustiveness (switchStmt, closure,
1375
- limitExhaustivityChecks);
1377
+ TypeChecker::checkSwitchExhaustiveness (
1378
+ switchStmt, context. getAsDeclContext (), limitExhaustivityChecks);
1376
1379
1377
1380
return switchStmt;
1378
1381
}
@@ -1392,7 +1395,8 @@ class ClosureConstraintApplication
1392
1395
ASTNode visitCaseStmt (CaseStmt *caseStmt) {
1393
1396
// Translate the patterns and guard expressions for each case label item.
1394
1397
for (auto &caseItem : caseStmt->getMutableCaseLabelItems ()) {
1395
- SolutionApplicationTarget caseTarget (&caseItem, closure);
1398
+ SolutionApplicationTarget caseTarget (&caseItem,
1399
+ context.getAsDeclContext ());
1396
1400
if (!rewriteTarget (caseTarget)) {
1397
1401
hadError = true ;
1398
1402
}
@@ -1420,7 +1424,7 @@ class ClosureConstraintApplication
1420
1424
if (!braceStmt->empty ()) {
1421
1425
if (auto stmt = braceStmt->getLastElement ().dyn_cast <Stmt *>()) {
1422
1426
if (auto deferStmt = dyn_cast<DeferStmt>(stmt)) {
1423
- auto &diags = closure-> getASTContext ().Diags ;
1427
+ auto &diags = cs. getASTContext ().Diags ;
1424
1428
diags
1425
1429
.diagnose (deferStmt->getStartLoc (), diag::defer_stmt_at_block_end)
1426
1430
.fixItReplace (deferStmt->getStartLoc (), " do" );
@@ -1462,7 +1466,8 @@ class ClosureConstraintApplication
1462
1466
// of the body if there is none. This wasn't needed before SE-0326
1463
1467
// because result type was (incorrectly) inferred as `Void` due to
1464
1468
// the body being skipped.
1465
- if (!closure->hasSingleExpressionBody () &&
1469
+ auto *closure = context.getAbstractClosureExpr ();
1470
+ if (closure && !closure->hasSingleExpressionBody () &&
1466
1471
closure->getBody () == braceStmt) {
1467
1472
if (resultType->getOptionalObjectType () &&
1468
1473
resultType->lookThroughAllOptionalTypes ()->isVoid () &&
@@ -1475,8 +1480,8 @@ class ClosureConstraintApplication
1475
1480
}
1476
1481
1477
1482
ASTNode addImplicitVoidReturn (BraceStmt *braceStmt) {
1478
- auto &ctx = closure->getASTContext ();
1479
1483
auto &cs = solution.getConstraintSystem ();
1484
+ auto &ctx = cs.getASTContext ();
1480
1485
1481
1486
auto *resultExpr = getVoidExpr (ctx);
1482
1487
cs.cacheExprTypes (resultExpr);
@@ -1488,8 +1493,8 @@ class ClosureConstraintApplication
1488
1493
// to it, to make sure that optional injection happens required
1489
1494
// number of times.
1490
1495
{
1491
- SolutionApplicationTarget target (resultExpr, closure, CTP_ReturnStmt ,
1492
- resultType,
1496
+ SolutionApplicationTarget target (resultExpr, context. getAsDeclContext () ,
1497
+ CTP_ReturnStmt, resultType,
1493
1498
/* isDiscarded=*/ false );
1494
1499
cs.setSolutionApplicationTarget (returnStmt, target);
1495
1500
@@ -1554,7 +1559,7 @@ class ClosureConstraintApplication
1554
1559
}
1555
1560
1556
1561
SolutionApplicationTarget resultTarget (
1557
- resultExpr, closure ,
1562
+ resultExpr, context. getAsDeclContext () ,
1558
1563
mode == convertToResult ? CTP_ReturnStmt : CTP_Unused,
1559
1564
mode == convertToResult ? resultType : Type (),
1560
1565
/* isDiscarded=*/ false );
@@ -1601,7 +1606,7 @@ class ClosureConstraintApplication
1601
1606
public:
1602
1607
// / Apply solution to the closure and return updated body.
1603
1608
ASTNode apply () {
1604
- auto body = visit (closure-> getBody ());
1609
+ auto body = visit (context. getBody ());
1605
1610
1606
1611
// Since local functions can capture variables that are declared
1607
1612
// after them, let's type-check them after all of the pattern
@@ -1612,7 +1617,6 @@ class ClosureConstraintApplication
1612
1617
return body;
1613
1618
}
1614
1619
};
1615
-
1616
1620
}
1617
1621
1618
1622
SolutionApplicationToFunctionResult ConstraintSystem::applySolution (
@@ -1705,7 +1709,7 @@ bool ConstraintSystem::applySolutionToBody(Solution &solution,
1705
1709
llvm::SaveAndRestore<DeclContext *> savedDC (currentDC, closure);
1706
1710
1707
1711
auto closureType = cs.getType (closure)->castTo <FunctionType>();
1708
- ClosureConstraintApplication application (
1712
+ SyntacticElementSolutionApplication application (
1709
1713
solution, closure, closureType->getResult (), rewriteTarget);
1710
1714
auto body = application.apply ();
1711
1715
0 commit comments