@@ -61,17 +61,18 @@ using namespace swift;
6161#define DEBUG_TYPE " TypeCheckStmt"
6262
6363namespace {
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 {
6869 DeclContext *ParentDC;
6970
70- ContextualizeClosuresAndMacros (DeclContext *parent) : ParentDC(parent) {}
71+ ContextualizationWalker (DeclContext *parent) : ParentDC(parent) {}
7172
7273 public:
7374 static void contextualize (ASTNode node, DeclContext *DC) {
74- node.walk (ContextualizeClosuresAndMacros (DC));
75+ node.walk (ContextualizationWalker (DC));
7576 }
7677
7778 MacroWalking getMacroWalkingBehavior () const override {
@@ -85,34 +86,7 @@ namespace {
8586 }
8687
8788 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)) {
11690 CE->setParent (ParentDC);
11791 contextualize (CE->getBody (), CE);
11892
@@ -121,12 +95,13 @@ namespace {
12195 }
12296
12397 // Caller-side default arguments need their @autoclosures checked.
124- if (auto *DAE = dyn_cast<DefaultArgumentExpr>(E))
98+ if (auto *DAE = dyn_cast<DefaultArgumentExpr>(E)) {
12599 if (DAE->isCallerSide () &&
126100 (DAE->getParamDecl ()->isAutoClosure () ||
127101 (DAE->getParamDecl ()->getDefaultArgumentKind () ==
128102 DefaultArgumentKind::ExpressionMacro)))
129103 DAE->getCallerSideDefaultExpr ()->walk (*this );
104+ }
130105
131106 // Macro expansion expressions require a DeclContext as well.
132107 if (auto macroExpansion = dyn_cast<MacroExpansionExpr>(E)) {
@@ -136,26 +111,59 @@ namespace {
136111 return Action::Continue (E);
137112 }
138113
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);
144122 }
145123
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+ }
151141
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+ });
156157 }
157158
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));
159167 }
160168 };
161169
@@ -208,12 +216,12 @@ namespace {
208216} // end anonymous namespace
209217
210218void TypeChecker::contextualizeExpr (Expr *E, DeclContext *DC) {
211- ContextualizeClosuresAndMacros ::contextualize (E, DC);
219+ ContextualizationWalker ::contextualize (E, DC);
212220}
213221
214222void TypeChecker::contextualizeTopLevelCode (TopLevelCodeDecl *TLCD) {
215223 if (auto *body = TLCD->getBody ())
216- ContextualizeClosuresAndMacros ::contextualize (body, TLCD);
224+ ContextualizationWalker ::contextualize (body, TLCD);
217225}
218226
219227namespace {
@@ -1036,7 +1044,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
10361044 // / Type-check an entire function body.
10371045 bool typeCheckBody (BraceStmt *&S) {
10381046 bool HadError = typeCheckStmt (S);
1039- ContextualizeClosuresAndMacros ::contextualize (S, DC);
1047+ ContextualizationWalker ::contextualize (S, DC);
10401048 return HadError;
10411049 }
10421050
@@ -2918,7 +2926,7 @@ TypeCheckFunctionBodyRequest::evaluate(Evaluator &eval,
29182926 body = *optBody;
29192927 alreadyTypeChecked = true ;
29202928
2921- ContextualizeClosuresAndMacros ::contextualize (body, AFD);
2929+ ContextualizationWalker ::contextualize (body, AFD);
29222930 }
29232931 }
29242932 }
0 commit comments