aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/body.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/body.rs')
-rw-r--r--crates/hir_def/src/body.rs74
1 files changed, 60 insertions, 14 deletions
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs
index 96b959967..44ae13643 100644
--- a/crates/hir_def/src/body.rs
+++ b/crates/hir_def/src/body.rs
@@ -19,9 +19,9 @@ use hir_expand::{
19use la_arena::{Arena, ArenaMap}; 19use la_arena::{Arena, ArenaMap};
20use profile::Count; 20use profile::Count;
21use rustc_hash::FxHashMap; 21use rustc_hash::FxHashMap;
22use syntax::{ast, AstNode, AstPtr}; 22use syntax::{ast, AstNode, AstPtr, SyntaxNode};
23 23
24pub(crate) use lower::LowerCtx; 24pub use lower::LowerCtx;
25 25
26use crate::{ 26use crate::{
27 attr::{Attrs, RawAttrs}, 27 attr::{Attrs, RawAttrs},
@@ -98,11 +98,14 @@ impl Expander {
98 } 98 }
99 } 99 }
100 100
101 pub(crate) fn enter_expand<T: ast::AstNode>( 101 fn enter_expand_intern(
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<ExpandResult<Option<(Mark, T)>>, UnresolvedMacro> { 105 ) -> Result<
106 ExpandResult<Option<(SyntaxNode, impl FnMut(&dyn DefDatabase) -> Mark + '_)>>,
107 UnresolvedMacro,
108 > {
106 if self.recursion_limit + 1 > EXPANSION_RECURSION_LIMIT { 109 if self.recursion_limit + 1 > EXPANSION_RECURSION_LIMIT {
107 cov_mark::hit!(your_stack_belongs_to_me); 110 cov_mark::hit!(your_stack_belongs_to_me);
108 return Ok(ExpandResult::str_err( 111 return Ok(ExpandResult::str_err(
@@ -147,6 +150,55 @@ impl Expander {
147 } 150 }
148 }; 151 };
149 152
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
150 let node = match T::cast(raw_node) { 202 let node = match T::cast(raw_node) {
151 Some(it) => it, 203 Some(it) => it,
152 None => { 204 None => {
@@ -157,15 +209,7 @@ impl Expander {
157 209
158 log::debug!("macro expansion {:#?}", node.syntax()); 210 log::debug!("macro expansion {:#?}", node.syntax());
159 211
160 self.recursion_limit += 1; 212 let mark = advance_state(db);
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);
169 213
170 Ok(ExpandResult { value: Some((mark, node)), err }) 214 Ok(ExpandResult { value: Some((mark, node)), err })
171 } 215 }
@@ -191,7 +235,8 @@ impl Expander {
191 } 235 }
192 236
193 fn parse_path(&mut self, path: ast::Path) -> Option<Path> { 237 fn parse_path(&mut self, path: ast::Path) -> Option<Path> {
194 Path::from_src(path, &self.cfg_expander.hygiene) 238 let ctx = LowerCtx::with_hygiene(&self.cfg_expander.hygiene);
239 Path::from_src(path, &ctx)
195 } 240 }
196 241
197 fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroDefId> { 242 fn resolve_path_as_macro(&self, db: &dyn DefDatabase, path: &ModPath) -> Option<MacroDefId> {
@@ -204,6 +249,7 @@ impl Expander {
204 } 249 }
205} 250}
206 251
252#[derive(Debug)]
207pub(crate) struct Mark { 253pub(crate) struct Mark {
208 file_id: HirFileId, 254 file_id: HirFileId,
209 ast_id_map: Arc<AstIdMap>, 255 ast_id_map: Arc<AstIdMap>,