2424#include " swift/AST/NameLookupRequests.h"
2525#include " swift/AST/Pattern.h"
2626#include " swift/AST/SourceFile.h"
27+ #include " swift/AST/Stmt.h"
2728#include " swift/AST/TypeCheckRequests.h"
2829#include " swift/Basic/Defer.h"
2930#include " swift/Basic/SourceManager.h"
@@ -50,6 +51,37 @@ static Expr *isImplicitPromotionToOptional(Expr *E) {
5051 return nullptr ;
5152}
5253
54+ bool BaseDiagnosticWalker::walkToDeclPre (Decl *D) {
55+ return isa<ClosureExpr>(D->getDeclContext ())
56+ ? shouldWalkIntoDeclInClosureContext (D)
57+ : false ;
58+ }
59+
60+ bool BaseDiagnosticWalker::shouldWalkIntoDeclInClosureContext (Decl *D) {
61+ auto *closure = dyn_cast<ClosureExpr>(D->getDeclContext ());
62+ assert (closure);
63+
64+ if (closure->isSeparatelyTypeChecked ())
65+ return false ;
66+
67+ auto &opts = D->getASTContext ().TypeCheckerOpts ;
68+
69+ // If multi-statement inference is enabled, let's not walk
70+ // into declarations contained in a multi-statement closure
71+ // because they'd be handled via `typeCheckDecl` that runs
72+ // syntactic diagnostics.
73+ if (opts.EnableMultiStatementClosureInference &&
74+ !closure->hasSingleExpressionBody ()) {
75+ // Since pattern bindings get their types through solution application,
76+ // `typeCheckDecl` doesn't touch initializers (because they are already
77+ // fully type-checked), so pattern bindings have to be allowed to be
78+ // walked to diagnose syntactic issues.
79+ return isa<PatternBindingDecl>(D);
80+ }
81+
82+ return true ;
83+ }
84+
5385// / Diagnose syntactic restrictions of expressions.
5486// /
5587// / - Module values may only occur as part of qualification.
@@ -72,7 +104,7 @@ static Expr *isImplicitPromotionToOptional(Expr *E) {
72104// /
73105static void diagSyntacticUseRestrictions (const Expr *E, const DeclContext *DC,
74106 bool isExprStmt) {
75- class DiagnoseWalker : public ASTWalker {
107+ class DiagnoseWalker : public BaseDiagnosticWalker {
76108 SmallPtrSet<Expr*, 4 > AlreadyDiagnosedMetatypes;
77109 SmallPtrSet<DeclRefExpr*, 4 > AlreadyDiagnosedBitCasts;
78110
@@ -89,18 +121,8 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
89121 return { false , P };
90122 }
91123
92- bool walkToDeclPre (Decl *D) override {
93- if (auto *closure = dyn_cast<ClosureExpr>(D->getDeclContext ()))
94- return !closure->isSeparatelyTypeChecked ();
95- return false ;
96- }
97-
98124 bool walkToTypeReprPre (TypeRepr *T) override { return true ; }
99125
100- bool shouldWalkIntoSeparatelyCheckedClosure (ClosureExpr *expr) override {
101- return false ;
102- }
103-
104126 bool shouldWalkCaptureInitializerExpressions () override { return true ; }
105127
106128 bool shouldWalkIntoTapExpression () override { return false ; }
@@ -1449,7 +1471,7 @@ static void diagRecursivePropertyAccess(const Expr *E, const DeclContext *DC) {
14491471// / confusion, so we force an explicit self.
14501472static void diagnoseImplicitSelfUseInClosure (const Expr *E,
14511473 const DeclContext *DC) {
1452- class DiagnoseWalker : public ASTWalker {
1474+ class DiagnoseWalker : public BaseDiagnosticWalker {
14531475 ASTContext &Ctx;
14541476 SmallVector<AbstractClosureExpr *, 4 > Closures;
14551477 public:
@@ -1530,18 +1552,6 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
15301552 return true ;
15311553 }
15321554
1533-
1534- // Don't walk into nested decls.
1535- bool walkToDeclPre (Decl *D) override {
1536- if (auto *closure = dyn_cast<ClosureExpr>(D->getDeclContext ()))
1537- return !closure->isSeparatelyTypeChecked ();
1538- return false ;
1539- }
1540-
1541- bool shouldWalkIntoSeparatelyCheckedClosure (ClosureExpr *expr) override {
1542- return false ;
1543- }
1544-
15451555 bool shouldWalkCaptureInitializerExpressions () override { return true ; }
15461556
15471557 bool shouldWalkIntoTapExpression () override { return false ; }
0 commit comments