@@ -1041,9 +1041,9 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
10411041 // / DC - This is the current DeclContext.
10421042 DeclContext *DC;
10431043
1044- // / Skip type checking any elements inside 'BraceStmt', also this is
1045- // / propagated to ConstraintSystem .
1046- bool LeaveBraceStmtBodyUnchecked = false ;
1044+ // / The BraceStmts that should be type-checked. This should always be `All`,
1045+ // / unless we're lazy type-checking for e.g completion .
1046+ BraceStmtChecking BraceChecking = BraceStmtChecking::All ;
10471047
10481048 ASTContext &getASTContext () const { return Ctx; };
10491049
@@ -1502,7 +1502,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
15021502 // FIXME: This is a hack to avoid cycles through NamingPatternRequest when
15031503 // doing lazy type-checking, we ought to fix the request to be granular in
15041504 // the type-checking work it kicks.
1505- bool skipWhere = LeaveBraceStmtBodyUnchecked &&
1505+ bool skipWhere = (BraceChecking != BraceStmtChecking::All) &&
15061506 Ctx.SourceMgr .hasIDEInspectionTargetBuffer ();
15071507
15081508 TypeChecker::typeCheckForEachPreamble (DC, S, skipWhere);
@@ -1737,11 +1737,19 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
17371737 auto sourceFile = DC->getParentSourceFile ();
17381738 checkLabeledStmtShadowing (getASTContext (), sourceFile, S);
17391739
1740- // Type-check the 'do' body. Type failures in here will generally
1741- // not cause type failures in the 'catch' clauses.
1742- Stmt *newBody = S->getBody ();
1743- typeCheckStmt (newBody);
1744- S->setBody (newBody);
1740+ {
1741+ // If we have do-catch body checking enabled, make sure we visit the
1742+ // BraceStmt.
1743+ std::optional<llvm::SaveAndRestore<BraceStmtChecking>> braceChecking;
1744+ if (BraceChecking == BraceStmtChecking::OnlyDoCatchBody)
1745+ braceChecking.emplace (BraceChecking, BraceStmtChecking::All);
1746+
1747+ // Type-check the 'do' body. Type failures in here will generally
1748+ // not cause type failures in the 'catch' clauses.
1749+ Stmt *newBody = S->getBody ();
1750+ typeCheckStmt (newBody);
1751+ S->setBody (newBody);
1752+ }
17451753
17461754 // Do-catch statements always limit exhaustivity checks.
17471755 bool limitExhaustivityChecks = true ;
@@ -2191,7 +2199,7 @@ void StmtChecker::typeCheckASTNode(ASTNode &node) {
21912199}
21922200
21932201Stmt *StmtChecker::visitBraceStmt (BraceStmt *BS) {
2194- if (LeaveBraceStmtBodyUnchecked )
2202+ if (BraceChecking != BraceStmtChecking::All )
21952203 return BS;
21962204
21972205 // Diagnose defer statement being last one in block (only if
@@ -2217,12 +2225,12 @@ Stmt *StmtChecker::visitBraceStmt(BraceStmt *BS) {
22172225}
22182226
22192227void TypeChecker::typeCheckASTNode (ASTNode &node, DeclContext *DC,
2220- bool LeaveBodyUnchecked ) {
2228+ BraceStmtChecking braceChecking ) {
22212229 StmtChecker stmtChecker (DC);
22222230 // FIXME: 'ActiveLabeledStmts', etc. in StmtChecker are not
22232231 // populated. Since they don't affect "type checking", it's doesn't cause
22242232 // any issue for now. But it should be populated nonetheless.
2225- stmtChecker.LeaveBraceStmtBodyUnchecked = LeaveBodyUnchecked ;
2233+ stmtChecker.BraceChecking = braceChecking ;
22262234 stmtChecker.typeCheckASTNode (node);
22272235}
22282236
@@ -2768,7 +2776,7 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(
27682776 }
27692777 }
27702778
2771- TypeChecker::typeCheckASTNode (finder.getRef (), DC, /* LeaveBodyUnchecked= */ false );
2779+ TypeChecker::typeCheckASTNode (finder.getRef (), DC);
27722780 return false ;
27732781}
27742782
0 commit comments