diff options
Diffstat (limited to 'crates/hir_def/src/body.rs')
-rw-r--r-- | crates/hir_def/src/body.rs | 72 |
1 files changed, 16 insertions, 56 deletions
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index 44ae13643..8a9b936ea 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs | |||
@@ -19,7 +19,7 @@ use hir_expand::{ | |||
19 | use la_arena::{Arena, ArenaMap}; | 19 | use la_arena::{Arena, ArenaMap}; |
20 | use profile::Count; | 20 | use profile::Count; |
21 | use rustc_hash::FxHashMap; | 21 | use rustc_hash::FxHashMap; |
22 | use syntax::{ast, AstNode, AstPtr, SyntaxNode}; | 22 | use syntax::{ast, AstNode, AstPtr}; |
23 | 23 | ||
24 | pub use lower::LowerCtx; | 24 | pub use lower::LowerCtx; |
25 | 25 | ||
@@ -98,14 +98,11 @@ impl Expander { | |||
98 | } | 98 | } |
99 | } | 99 | } |
100 | 100 | ||
101 | fn enter_expand_intern( | 101 | pub(crate) fn enter_expand<T: ast::AstNode>( |
102 | &mut self, | 102 | &mut self, |
103 | db: &dyn DefDatabase, | 103 | db: &dyn DefDatabase, |
104 | macro_call: ast::MacroCall, | 104 | macro_call: ast::MacroCall, |
105 | ) -> Result< | 105 | ) -> Result<ExpandResult<Option<(Mark, T)>>, UnresolvedMacro> { |
106 | ExpandResult<Option<(SyntaxNode, impl FnMut(&dyn DefDatabase) -> Mark + '_)>>, | ||
107 | UnresolvedMacro, | ||
108 | > { | ||
109 | if self.recursion_limit + 1 > EXPANSION_RECURSION_LIMIT { | 106 | if self.recursion_limit + 1 > EXPANSION_RECURSION_LIMIT { |
110 | cov_mark::hit!(your_stack_belongs_to_me); | 107 | cov_mark::hit!(your_stack_belongs_to_me); |
111 | return Ok(ExpandResult::str_err( | 108 | return Ok(ExpandResult::str_err( |
@@ -150,55 +147,6 @@ impl Expander { | |||
150 | } | 147 | } |
151 | }; | 148 | }; |
152 | 149 | ||
153 | let this = self; | ||
154 | |||
155 | let advance_state = move |db: &dyn DefDatabase| { | ||
156 | this.recursion_limit += 1; | ||
157 | let mark = Mark { | ||
158 | file_id: this.current_file_id, | ||
159 | ast_id_map: mem::take(&mut this.ast_id_map), | ||
160 | bomb: DropBomb::new("expansion mark dropped"), | ||
161 | }; | ||
162 | this.cfg_expander.hygiene = Hygiene::new(db.upcast(), file_id); | ||
163 | this.current_file_id = file_id; | ||
164 | this.ast_id_map = db.ast_id_map(file_id); | ||
165 | mark | ||
166 | }; | ||
167 | |||
168 | Ok(ExpandResult { value: Some((raw_node, advance_state)), err }) | ||
169 | } | ||
170 | |||
171 | pub(crate) fn enter_expand_raw( | ||
172 | &mut self, | ||
173 | db: &dyn DefDatabase, | ||
174 | macro_call: ast::MacroCall, | ||
175 | ) -> Result<ExpandResult<Option<(Mark, SyntaxNode)>>, UnresolvedMacro> { | ||
176 | let (raw_node, mut advance_state, err) = match self.enter_expand_intern(db, macro_call)? { | ||
177 | ExpandResult { value: Some((raw_node, advance_state)), err } => { | ||
178 | (raw_node, advance_state, err) | ||
179 | } | ||
180 | ExpandResult { value: None, err } => return Ok(ExpandResult { value: None, err }), | ||
181 | }; | ||
182 | |||
183 | log::debug!("macro expansion {:#?}", raw_node); | ||
184 | |||
185 | let mark = advance_state(db); | ||
186 | |||
187 | Ok(ExpandResult { value: Some((mark, raw_node)), err }) | ||
188 | } | ||
189 | |||
190 | pub(crate) fn enter_expand<T: ast::AstNode>( | ||
191 | &mut self, | ||
192 | db: &dyn DefDatabase, | ||
193 | macro_call: ast::MacroCall, | ||
194 | ) -> Result<ExpandResult<Option<(Mark, T)>>, UnresolvedMacro> { | ||
195 | let (raw_node, mut advance_state, err) = match self.enter_expand_intern(db, macro_call)? { | ||
196 | ExpandResult { value: Some((raw_node, advance_state)), err } => { | ||
197 | (raw_node, advance_state, err) | ||
198 | } | ||
199 | ExpandResult { value: None, err } => return Ok(ExpandResult { value: None, err }), | ||
200 | }; | ||
201 | |||
202 | let node = match T::cast(raw_node) { | 150 | let node = match T::cast(raw_node) { |
203 | Some(it) => it, | 151 | Some(it) => it, |
204 | None => { | 152 | None => { |
@@ -209,7 +157,15 @@ impl Expander { | |||
209 | 157 | ||
210 | log::debug!("macro expansion {:#?}", node.syntax()); | 158 | log::debug!("macro expansion {:#?}", node.syntax()); |
211 | 159 | ||
212 | let mark = advance_state(db); | 160 | self.recursion_limit += 1; |
161 | let mark = Mark { | ||
162 | file_id: self.current_file_id, | ||
163 | ast_id_map: mem::take(&mut self.ast_id_map), | ||
164 | bomb: DropBomb::new("expansion mark dropped"), | ||
165 | }; | ||
166 | self.cfg_expander.hygiene = Hygiene::new(db.upcast(), file_id); | ||
167 | self.current_file_id = file_id; | ||
168 | self.ast_id_map = db.ast_id_map(file_id); | ||
213 | 169 | ||
214 | Ok(ExpandResult { value: Some((mark, node)), err }) | 170 | Ok(ExpandResult { value: Some((mark, node)), err }) |
215 | } | 171 | } |
@@ -234,6 +190,10 @@ impl Expander { | |||
234 | &self.cfg_expander.cfg_options | 190 | &self.cfg_expander.cfg_options |
235 | } | 191 | } |
236 | 192 | ||
193 | pub(crate) fn current_file_id(&self) -> HirFileId { | ||
194 | self.current_file_id | ||
195 | } | ||
196 | |||
237 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { | 197 | fn parse_path(&mut self, path: ast::Path) -> Option<Path> { |
238 | let ctx = LowerCtx::with_hygiene(&self.cfg_expander.hygiene); | 198 | let ctx = LowerCtx::with_hygiene(&self.cfg_expander.hygiene); |
239 | Path::from_src(path, &ctx) | 199 | Path::from_src(path, &ctx) |