24
24
#include " swift/AST/NameLookupRequests.h"
25
25
#include " swift/AST/Pattern.h"
26
26
#include " swift/AST/SourceFile.h"
27
+ #include " swift/AST/Stmt.h"
27
28
#include " swift/AST/TypeCheckRequests.h"
28
29
#include " swift/Basic/Defer.h"
29
30
#include " swift/Basic/SourceManager.h"
@@ -50,6 +51,37 @@ static Expr *isImplicitPromotionToOptional(Expr *E) {
50
51
return nullptr ;
51
52
}
52
53
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
+
53
85
// / Diagnose syntactic restrictions of expressions.
54
86
// /
55
87
// / - Module values may only occur as part of qualification.
@@ -72,7 +104,7 @@ static Expr *isImplicitPromotionToOptional(Expr *E) {
72
104
// /
73
105
static void diagSyntacticUseRestrictions (const Expr *E, const DeclContext *DC,
74
106
bool isExprStmt) {
75
- class DiagnoseWalker : public ASTWalker {
107
+ class DiagnoseWalker : public BaseDiagnosticWalker {
76
108
SmallPtrSet<Expr*, 4 > AlreadyDiagnosedMetatypes;
77
109
SmallPtrSet<DeclRefExpr*, 4 > AlreadyDiagnosedBitCasts;
78
110
@@ -89,18 +121,8 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
89
121
return { false , P };
90
122
}
91
123
92
- bool walkToDeclPre (Decl *D) override {
93
- if (auto *closure = dyn_cast<ClosureExpr>(D->getDeclContext ()))
94
- return !closure->isSeparatelyTypeChecked ();
95
- return false ;
96
- }
97
-
98
124
bool walkToTypeReprPre (TypeRepr *T) override { return true ; }
99
125
100
- bool shouldWalkIntoSeparatelyCheckedClosure (ClosureExpr *expr) override {
101
- return false ;
102
- }
103
-
104
126
bool shouldWalkCaptureInitializerExpressions () override { return true ; }
105
127
106
128
bool shouldWalkIntoTapExpression () override { return false ; }
@@ -1449,7 +1471,7 @@ static void diagRecursivePropertyAccess(const Expr *E, const DeclContext *DC) {
1449
1471
// / confusion, so we force an explicit self.
1450
1472
static void diagnoseImplicitSelfUseInClosure (const Expr *E,
1451
1473
const DeclContext *DC) {
1452
- class DiagnoseWalker : public ASTWalker {
1474
+ class DiagnoseWalker : public BaseDiagnosticWalker {
1453
1475
ASTContext &Ctx;
1454
1476
SmallVector<AbstractClosureExpr *, 4 > Closures;
1455
1477
public:
@@ -1530,18 +1552,6 @@ static void diagnoseImplicitSelfUseInClosure(const Expr *E,
1530
1552
return true ;
1531
1553
}
1532
1554
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
-
1545
1555
bool shouldWalkCaptureInitializerExpressions () override { return true ; }
1546
1556
1547
1557
bool shouldWalkIntoTapExpression () override { return false ; }
0 commit comments