@@ -408,6 +408,8 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
408
408
S->walk (ContextualizeClosures (DC));
409
409
return HadError;
410
410
}
411
+
412
+ void typeCheckASTNode (ASTNode &node);
411
413
412
414
// ===--------------------------------------------------------------------===//
413
415
// Visit Methods.
@@ -1538,6 +1540,57 @@ void TypeChecker::checkIgnoredExpr(Expr *E) {
1538
1540
.highlight (valueE->getSourceRange ());
1539
1541
}
1540
1542
1543
+ void StmtChecker::typeCheckASTNode (ASTNode &node) {
1544
+ // Type check the expression
1545
+ if (auto *E = node.dyn_cast <Expr *>()) {
1546
+ auto &ctx = DC->getASTContext ();
1547
+
1548
+ TypeCheckExprOptions options = TypeCheckExprFlags::IsExprStmt;
1549
+ bool isDiscarded =
1550
+ (!ctx.LangOpts .Playground && !ctx.LangOpts .DebuggerSupport );
1551
+ if (isDiscarded)
1552
+ options |= TypeCheckExprFlags::IsDiscarded;
1553
+ if (TargetTypeCheckLoc.isValid ())
1554
+ options |= TypeCheckExprFlags::AllowUnresolvedTypeVariables;
1555
+
1556
+ auto resultTy =
1557
+ TypeChecker::typeCheckExpression (E, DC, Type (), CTP_Unused, options);
1558
+
1559
+ // If a closure expression is unused, the user might have intended to write
1560
+ // "do { ... }".
1561
+ auto *CE = dyn_cast<ClosureExpr>(E);
1562
+ if (CE || isa<CaptureListExpr>(E)) {
1563
+ ctx.Diags .diagnose (E->getLoc (), diag::expression_unused_closure);
1564
+
1565
+ if (CE && CE->hasAnonymousClosureVars () &&
1566
+ CE->getParameters ()->size () == 0 ) {
1567
+ ctx.Diags .diagnose (CE->getStartLoc (), diag::brace_stmt_suggest_do)
1568
+ .fixItInsert (CE->getStartLoc (), " do " );
1569
+ }
1570
+ } else if (isDiscarded && resultTy) {
1571
+ TypeChecker::checkIgnoredExpr (E);
1572
+ }
1573
+
1574
+ node = E;
1575
+ return ;
1576
+ }
1577
+
1578
+ // Type check the statement.
1579
+ if (auto *S = node.dyn_cast <Stmt *>()) {
1580
+ typeCheckStmt (S);
1581
+ node = S;
1582
+ return ;
1583
+ }
1584
+
1585
+ // Type check the declaration.
1586
+ if (auto *D = node.dyn_cast <Decl *>()) {
1587
+ TypeChecker::typeCheckDecl (D);
1588
+ return ;
1589
+ }
1590
+
1591
+ llvm_unreachable (" Type checking null ASTNode" );
1592
+ }
1593
+
1541
1594
Stmt *StmtChecker::visitBraceStmt (BraceStmt *BS) {
1542
1595
const SourceManager &SM = getASTContext ().SourceMgr ;
1543
1596
@@ -1569,52 +1622,7 @@ Stmt *StmtChecker::visitBraceStmt(BraceStmt *BS) {
1569
1622
continue ;
1570
1623
}
1571
1624
1572
- if (auto *SubExpr = elem.dyn_cast <Expr*>()) {
1573
- // Type check the expression.
1574
- TypeCheckExprOptions options = TypeCheckExprFlags::IsExprStmt;
1575
- bool isDiscarded = (!getASTContext ().LangOpts .Playground &&
1576
- !getASTContext ().LangOpts .DebuggerSupport );
1577
- if (isDiscarded)
1578
- options |= TypeCheckExprFlags::IsDiscarded;
1579
-
1580
- if (TargetTypeCheckLoc.isValid ()) {
1581
- assert (DiagnosticSuppression::isEnabled (getASTContext ().Diags ) &&
1582
- " Diagnosing and AllowUnresolvedTypeVariables don't seem to mix" );
1583
- options |= TypeCheckExprFlags::AllowUnresolvedTypeVariables;
1584
- }
1585
-
1586
- auto resultTy =
1587
- TypeChecker::typeCheckExpression (SubExpr, DC, Type (),
1588
- CTP_Unused, options);
1589
-
1590
- // If a closure expression is unused, the user might have intended
1591
- // to write "do { ... }".
1592
- auto *CE = dyn_cast<ClosureExpr>(SubExpr);
1593
- if (CE || isa<CaptureListExpr>(SubExpr)) {
1594
- getASTContext ().Diags .diagnose (SubExpr->getLoc (),
1595
- diag::expression_unused_closure);
1596
-
1597
- if (CE && CE->hasAnonymousClosureVars () &&
1598
- CE->getParameters ()->size () == 0 ) {
1599
- getASTContext ().Diags .diagnose (CE->getStartLoc (),
1600
- diag::brace_stmt_suggest_do)
1601
- .fixItInsert (CE->getStartLoc (), " do " );
1602
- }
1603
- } else if (isDiscarded && resultTy)
1604
- TypeChecker::checkIgnoredExpr (SubExpr);
1605
-
1606
- elem = SubExpr;
1607
- continue ;
1608
- }
1609
-
1610
- if (auto *SubStmt = elem.dyn_cast <Stmt*>()) {
1611
- typeCheckStmt (SubStmt);
1612
- elem = SubStmt;
1613
- continue ;
1614
- }
1615
-
1616
- Decl *SubDecl = elem.get <Decl *>();
1617
- TypeChecker::typeCheckDecl (SubDecl);
1625
+ typeCheckASTNode (elem);
1618
1626
}
1619
1627
1620
1628
return BS;
0 commit comments