@@ -62,61 +62,47 @@ using namespace swift;
6262#define DEBUG_TYPE " TypeCheckStmt"
6363
6464namespace {
65- // / After forming autoclosures, we must re-parent any closure expressions
66- // / nested inside the autoclosure, because the autoclosure introduces a new
67- // / DeclContext.
68- class ContextualizeClosuresAndMacros : public ASTWalker {
65+ // / After forming autoclosures and lazy initializer getters, we must update
66+ // / the DeclContexts for any AST nodes that store the DeclContext they're
67+ // / within. This includes e.g closures and decls, as well as some other
68+ // / expressions, statements, and patterns.
69+ class ContextualizationWalker : public ASTWalker {
6970 DeclContext *ParentDC;
71+
72+ ContextualizationWalker (DeclContext *parent) : ParentDC(parent) {}
73+
7074 public:
71- ContextualizeClosuresAndMacros (DeclContext *parent) : ParentDC(parent) {}
75+ static void contextualize (ASTNode node, DeclContext *DC) {
76+ node.walk (ContextualizationWalker (DC));
77+ }
7278
7379 MacroWalking getMacroWalkingBehavior () const override {
7480 return MacroWalking::ArgumentsAndExpansion;
7581 }
7682
77- PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
78- if (auto CE = dyn_cast<AutoClosureExpr>(E)) {
79- CE->setParent (ParentDC);
80-
81- // Recurse into the autoclosure body with the new ParentDC.
82- auto oldParentDC = ParentDC;
83- ParentDC = CE;
84- CE->getBody ()->walk (*this );
85- ParentDC = oldParentDC;
86-
87- TypeChecker::computeCaptures (CE);
88- return Action::SkipNode (E);
89- }
90-
91- if (auto CapE = dyn_cast<CaptureListExpr>(E)) {
92- // Capture lists need to be reparented to enclosing autoclosures
93- // and/or initializers of property wrapper backing properties
94- // (because they subsume initializers associated with wrapped
95- // properties).
96- if (isa<AutoClosureExpr>(ParentDC) ||
97- isPropertyWrapperBackingPropertyInitContext (ParentDC)) {
98- for (auto &Cap : CapE->getCaptureList ()) {
99- Cap.PBD ->setDeclContext (ParentDC);
100- Cap.getVar ()->setDeclContext (ParentDC);
101- }
102- }
103- }
83+ LazyInitializerWalking getLazyInitializerWalkingBehavior () override {
84+ // Don't walk lazy initializers, we contextualize the getter body
85+ // specially when synthesizing.
86+ return LazyInitializerWalking::None;
87+ }
10488
105- if (auto CE = dyn_cast<ClosureExpr>(E)) {
89+ PreWalkResult<Expr *> walkToExprPre (Expr *E) override {
90+ if (auto *CE = dyn_cast<AbstractClosureExpr>(E)) {
10691 CE->setParent (ParentDC);
107- CE->getBody ()-> walk ( ContextualizeClosuresAndMacros (CE) );
92+ contextualize ( CE->getBody (), CE );
10893
10994 TypeChecker::computeCaptures (CE);
11095 return Action::SkipNode (E);
11196 }
11297
11398 // Caller-side default arguments need their @autoclosures checked.
114- if (auto *DAE = dyn_cast<DefaultArgumentExpr>(E))
99+ if (auto *DAE = dyn_cast<DefaultArgumentExpr>(E)) {
115100 if (DAE->isCallerSide () &&
116101 (DAE->getParamDecl ()->isAutoClosure () ||
117102 (DAE->getParamDecl ()->getDefaultArgumentKind () ==
118103 DefaultArgumentKind::ExpressionMacro)))
119104 DAE->getCallerSideDefaultExpr ()->walk (*this );
105+ }
120106
121107 // Macro expansion expressions require a DeclContext as well.
122108 if (auto macroExpansion = dyn_cast<MacroExpansionExpr>(E)) {
@@ -126,26 +112,62 @@ namespace {
126112 return Action::Continue (E);
127113 }
128114
129- // / We don't want to recurse into most local declarations.
130- PreWalkAction walkToDeclPre (Decl *D) override {
131- // But we do want to walk into the initializers of local
132- // variables.
133- return Action::VisitNodeIf (isa<PatternBindingDecl>(D));
115+ PreWalkResult<Pattern *> walkToPatternPre (Pattern *P) override {
116+ // A couple of patterns store DeclContexts.
117+ if (auto *EP = dyn_cast<ExprPattern>(P))
118+ EP->setDeclContext (ParentDC);
119+ if (auto *EP = dyn_cast<EnumElementPattern>(P))
120+ EP->setDeclContext (ParentDC);
121+
122+ return Action::Continue (P);
134123 }
135124
136- private:
137- static bool isPropertyWrapperBackingPropertyInitContext (DeclContext *DC) {
138- auto *init = dyn_cast<PatternBindingInitializer>(DC);
139- if (!init)
140- return false ;
125+ PreWalkResult<Stmt *> walkToStmtPre (Stmt *S) override {
126+ // The ASTWalker doesn't walk the case body variables, contextualize them
127+ // ourselves.
128+ if (auto *CS = dyn_cast<CaseStmt>(S)) {
129+ for (auto *CaseVar : CS->getCaseBodyVariablesOrEmptyArray ())
130+ CaseVar->setDeclContext (ParentDC);
131+ }
132+ // A few statements store DeclContexts, update them.
133+ if (auto *BS = dyn_cast<BreakStmt>(S))
134+ BS->setDeclContext (ParentDC);
135+ if (auto *CS = dyn_cast<ContinueStmt>(S))
136+ CS->setDeclContext (ParentDC);
137+ if (auto *FS = dyn_cast<FallthroughStmt>(S))
138+ FS->setDeclContext (ParentDC);
141139
142- if (auto *PB = init->getBinding ()) {
143- auto *var = PB->getSingleVar ();
144- return var && var->getOriginalWrappedProperty (
145- PropertyWrapperSynthesizedPropertyKind::Backing);
140+ return Action::Continue (S);
141+ }
142+
143+ PreWalkAction walkToDeclPre (Decl *D) override {
144+ // We may encounter some decls parented outside of a local context, e.g
145+ // VarDecls in TopLevelCodeDecls are parented to the file. In such cases,
146+ // assume the DeclContext they already have is correct, autoclosures
147+ // and lazy var inits cannot be defined in such contexts anyway.
148+ if (!D->getDeclContext ()->isLocalContext ())
149+ return Action::SkipNode ();
150+
151+ D->setDeclContext (ParentDC);
152+
153+ // Auxiliary decls need to have their contexts adjusted too.
154+ if (auto *VD = dyn_cast<VarDecl>(D)) {
155+ VD->visitAuxiliaryDecls ([&](VarDecl *D) {
156+ D->setDeclContext (ParentDC);
157+ });
146158 }
147159
148- return false ;
160+ // We don't currently support peer macro declarations in local contexts,
161+ // however we don't reject them either; so just to be safe, adjust their
162+ // context too.
163+ D->visitAuxiliaryDecls ([&](Decl *D) {
164+ D->setDeclContext (ParentDC);
165+ });
166+
167+ // Only recurse into decls that aren't themselves DeclContexts. This
168+ // allows us to visit e.g initializers for PatternBindingDecls and
169+ // accessors for VarDecls.
170+ return Action::SkipNodeIf (isa<DeclContext>(D));
149171 }
150172 };
151173
@@ -197,21 +219,13 @@ namespace {
197219 };
198220} // end anonymous namespace
199221
200- void TypeChecker::contextualizeInitializer (Initializer *DC, Expr *E) {
201- ContextualizeClosuresAndMacros CC (DC);
202- E->walk (CC);
203- }
204-
205- void TypeChecker::contextualizeCallSideDefaultArgument (DeclContext *DC,
206- Expr *E) {
207- ContextualizeClosuresAndMacros CC (DC);
208- E->walk (CC);
222+ void TypeChecker::contextualizeExpr (Expr *E, DeclContext *DC) {
223+ ContextualizationWalker::contextualize (E, DC);
209224}
210225
211226void TypeChecker::contextualizeTopLevelCode (TopLevelCodeDecl *TLCD) {
212- ContextualizeClosuresAndMacros CC (TLCD);
213227 if (auto *body = TLCD->getBody ())
214- body-> walk (CC );
228+ ContextualizationWalker::contextualize (body, TLCD );
215229}
216230
217231namespace {
@@ -1034,7 +1048,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
10341048 // / Type-check an entire function body.
10351049 bool typeCheckBody (BraceStmt *&S) {
10361050 bool HadError = typeCheckStmt (S);
1037- S-> walk ( ContextualizeClosuresAndMacros (DC) );
1051+ ContextualizationWalker::contextualize (S, DC );
10381052 return HadError;
10391053 }
10401054
@@ -2916,7 +2930,7 @@ TypeCheckFunctionBodyRequest::evaluate(Evaluator &eval,
29162930 body = *optBody;
29172931 alreadyTypeChecked = true ;
29182932
2919- body-> walk ( ContextualizeClosuresAndMacros ( AFD) );
2933+ ContextualizationWalker::contextualize (body, AFD);
29202934 }
29212935 }
29222936 }
0 commit comments