@@ -61,17 +61,18 @@ using namespace swift;
61
61
#define DEBUG_TYPE " TypeCheckStmt"
62
62
63
63
namespace {
64
- // / After forming autoclosures, we must re-parent any closure expressions
65
- // / nested inside the autoclosure, because the autoclosure introduces a new
66
- // / DeclContext.
67
- class ContextualizeClosuresAndMacros : public ASTWalker {
64
+ // / After forming autoclosures and lazy initializer getters, we must update
65
+ // / the DeclContexts for any AST nodes that store the DeclContext they're
66
+ // / within. This includes e.g closures and decls, as well as some other
67
+ // / expressions, statements, and patterns.
68
+ class ContextualizationWalker : public ASTWalker {
68
69
DeclContext *ParentDC;
69
70
70
- ContextualizeClosuresAndMacros (DeclContext *parent) : ParentDC(parent) {}
71
+ ContextualizationWalker (DeclContext *parent) : ParentDC(parent) {}
71
72
72
73
public:
73
74
static void contextualize (ASTNode node, DeclContext *DC) {
74
- node.walk (ContextualizeClosuresAndMacros (DC));
75
+ node.walk (ContextualizationWalker (DC));
75
76
}
76
77
77
78
MacroWalking getMacroWalkingBehavior () const override {
@@ -85,34 +86,7 @@ namespace {
85
86
}
86
87
87
88
PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
88
- if (auto CE = dyn_cast<AutoClosureExpr>(E)) {
89
- CE->setParent (ParentDC);
90
-
91
- // Recurse into the autoclosure body with the new ParentDC.
92
- auto oldParentDC = ParentDC;
93
- ParentDC = CE;
94
- CE->getBody ()->walk (*this );
95
- ParentDC = oldParentDC;
96
-
97
- TypeChecker::computeCaptures (CE);
98
- return Action::SkipNode (E);
99
- }
100
-
101
- if (auto CapE = dyn_cast<CaptureListExpr>(E)) {
102
- // Capture lists need to be reparented to enclosing autoclosures
103
- // and/or initializers of property wrapper backing properties
104
- // (because they subsume initializers associated with wrapped
105
- // properties).
106
- if (isa<AutoClosureExpr>(ParentDC) ||
107
- isPropertyWrapperBackingPropertyInitContext (ParentDC)) {
108
- for (auto &Cap : CapE->getCaptureList ()) {
109
- Cap.PBD ->setDeclContext (ParentDC);
110
- Cap.getVar ()->setDeclContext (ParentDC);
111
- }
112
- }
113
- }
114
-
115
- if (auto CE = dyn_cast<ClosureExpr>(E)) {
89
+ if (auto *CE = dyn_cast<AbstractClosureExpr>(E)) {
116
90
CE->setParent (ParentDC);
117
91
contextualize (CE->getBody (), CE);
118
92
@@ -121,12 +95,13 @@ namespace {
121
95
}
122
96
123
97
// Caller-side default arguments need their @autoclosures checked.
124
- if (auto *DAE = dyn_cast<DefaultArgumentExpr>(E))
98
+ if (auto *DAE = dyn_cast<DefaultArgumentExpr>(E)) {
125
99
if (DAE->isCallerSide () &&
126
100
(DAE->getParamDecl ()->isAutoClosure () ||
127
101
(DAE->getParamDecl ()->getDefaultArgumentKind () ==
128
102
DefaultArgumentKind::ExpressionMacro)))
129
103
DAE->getCallerSideDefaultExpr ()->walk (*this );
104
+ }
130
105
131
106
// Macro expansion expressions require a DeclContext as well.
132
107
if (auto macroExpansion = dyn_cast<MacroExpansionExpr>(E)) {
@@ -136,26 +111,59 @@ namespace {
136
111
return Action::Continue (E);
137
112
}
138
113
139
- // / We don't want to recurse into most local declarations.
140
- PreWalkAction walkToDeclPre (Decl *D) override {
141
- // But we do want to walk into the initializers of local
142
- // variables.
143
- return Action::VisitNodeIf (isa<PatternBindingDecl>(D));
114
+ PreWalkResult<Pattern *> walkToPatternPre (Pattern *P) override {
115
+ // A couple of patterns store DeclContexts.
116
+ if (auto *EP = dyn_cast<ExprPattern>(P))
117
+ EP->setDeclContext (ParentDC);
118
+ if (auto *EP = dyn_cast<EnumElementPattern>(P))
119
+ EP->setDeclContext (ParentDC);
120
+
121
+ return Action::Continue (P);
144
122
}
145
123
146
- private:
147
- static bool isPropertyWrapperBackingPropertyInitContext (DeclContext *DC) {
148
- auto *init = dyn_cast<PatternBindingInitializer>(DC);
149
- if (!init)
150
- return false ;
124
+ PreWalkResult<Stmt *> walkToStmtPre (Stmt *S) override {
125
+ // The ASTWalker doesn't walk the case body variables, contextualize them
126
+ // ourselves.
127
+ if (auto *CS = dyn_cast<CaseStmt>(S)) {
128
+ for (auto *CaseVar : CS->getCaseBodyVariablesOrEmptyArray ())
129
+ CaseVar->setDeclContext (ParentDC);
130
+ }
131
+ // A few statements store DeclContexts, update them.
132
+ if (auto *BS = dyn_cast<BreakStmt>(S))
133
+ BS->setDeclContext (ParentDC);
134
+ if (auto *CS = dyn_cast<ContinueStmt>(S))
135
+ CS->setDeclContext (ParentDC);
136
+ if (auto *FS = dyn_cast<FallthroughStmt>(S))
137
+ FS->setDeclContext (ParentDC);
138
+
139
+ return Action::Continue (S);
140
+ }
151
141
152
- if (auto *PB = init->getBinding ()) {
153
- auto *var = PB->getSingleVar ();
154
- return var && var->getOriginalWrappedProperty (
155
- PropertyWrapperSynthesizedPropertyKind::Backing);
142
+ PreWalkAction walkToDeclPre (Decl *D) override {
143
+ // We may encounter some decls parented outside of a local context, e.g
144
+ // VarDecls in TopLevelCodeDecls are parented to the file. In such cases,
145
+ // assume the DeclContext they already have is correct, autoclosures
146
+ // and lazy var inits cannot be defined in such contexts anyway.
147
+ if (!D->getDeclContext ()->isLocalContext ())
148
+ return Action::SkipNode ();
149
+
150
+ D->setDeclContext (ParentDC);
151
+
152
+ // Auxiliary decls need to have their contexts adjusted too.
153
+ if (auto *VD = dyn_cast<VarDecl>(D)) {
154
+ VD->visitAuxiliaryDecls ([&](VarDecl *D) {
155
+ D->setDeclContext (ParentDC);
156
+ });
156
157
}
157
158
158
- return false ;
159
+ // We don't currently support peer macro declarations in local contexts,
160
+ // however we don't reject them either; so just to be safe, adjust their
161
+ // context too.
162
+ D->visitAuxiliaryDecls ([&](Decl *D) {
163
+ D->setDeclContext (ParentDC);
164
+ });
165
+
166
+ return Action::VisitNodeIf (isa<PatternBindingDecl>(D));
159
167
}
160
168
};
161
169
@@ -208,12 +216,12 @@ namespace {
208
216
} // end anonymous namespace
209
217
210
218
void TypeChecker::contextualizeExpr (Expr *E, DeclContext *DC) {
211
- ContextualizeClosuresAndMacros ::contextualize (E, DC);
219
+ ContextualizationWalker ::contextualize (E, DC);
212
220
}
213
221
214
222
void TypeChecker::contextualizeTopLevelCode (TopLevelCodeDecl *TLCD) {
215
223
if (auto *body = TLCD->getBody ())
216
- ContextualizeClosuresAndMacros ::contextualize (body, TLCD);
224
+ ContextualizationWalker ::contextualize (body, TLCD);
217
225
}
218
226
219
227
namespace {
@@ -1036,7 +1044,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
1036
1044
// / Type-check an entire function body.
1037
1045
bool typeCheckBody (BraceStmt *&S) {
1038
1046
bool HadError = typeCheckStmt (S);
1039
- ContextualizeClosuresAndMacros ::contextualize (S, DC);
1047
+ ContextualizationWalker ::contextualize (S, DC);
1040
1048
return HadError;
1041
1049
}
1042
1050
@@ -2918,7 +2926,7 @@ TypeCheckFunctionBodyRequest::evaluate(Evaluator &eval,
2918
2926
body = *optBody;
2919
2927
alreadyTypeChecked = true ;
2920
2928
2921
- ContextualizeClosuresAndMacros ::contextualize (body, AFD);
2929
+ ContextualizationWalker ::contextualize (body, AFD);
2922
2930
}
2923
2931
}
2924
2932
}
0 commit comments