diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 27a297e8b..5f9d53ecb 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs | |||
@@ -30,6 +30,7 @@ pub(crate) struct Expander { | |||
30 | hygiene: Hygiene, | 30 | hygiene: Hygiene, |
31 | ast_id_map: Arc<AstIdMap>, | 31 | ast_id_map: Arc<AstIdMap>, |
32 | module: ModuleId, | 32 | module: ModuleId, |
33 | recursive_limit: usize, | ||
33 | } | 34 | } |
34 | 35 | ||
35 | impl Expander { | 36 | impl Expander { |
@@ -41,7 +42,7 @@ impl Expander { | |||
41 | let crate_def_map = db.crate_def_map(module.krate); | 42 | let crate_def_map = db.crate_def_map(module.krate); |
42 | let hygiene = Hygiene::new(db.upcast(), current_file_id); | 43 | let hygiene = Hygiene::new(db.upcast(), current_file_id); |
43 | let ast_id_map = db.ast_id_map(current_file_id); | 44 | let ast_id_map = db.ast_id_map(current_file_id); |
44 | Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module } | 45 | Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module, recursive_limit: 0 } |
45 | } | 46 | } |
46 | 47 | ||
47 | pub(crate) fn enter_expand<T: ast::AstNode>( | 48 | pub(crate) fn enter_expand<T: ast::AstNode>( |
@@ -50,6 +51,10 @@ impl Expander { | |||
50 | local_scope: Option<&ItemScope>, | 51 | local_scope: Option<&ItemScope>, |
51 | macro_call: ast::MacroCall, | 52 | macro_call: ast::MacroCall, |
52 | ) -> Option<(Mark, T)> { | 53 | ) -> Option<(Mark, T)> { |
54 | if self.recursive_limit > 1024 { | ||
55 | return None; | ||
56 | } | ||
57 | |||
53 | let macro_call = InFile::new(self.current_file_id, ¯o_call); | 58 | let macro_call = InFile::new(self.current_file_id, ¯o_call); |
54 | 59 | ||
55 | if let Some(call_id) = macro_call.as_call_id(db, |path| { | 60 | if let Some(call_id) = macro_call.as_call_id(db, |path| { |
@@ -73,6 +78,7 @@ impl Expander { | |||
73 | self.hygiene = Hygiene::new(db.upcast(), file_id); | 78 | self.hygiene = Hygiene::new(db.upcast(), file_id); |
74 | self.current_file_id = file_id; | 79 | self.current_file_id = file_id; |
75 | self.ast_id_map = db.ast_id_map(file_id); | 80 | self.ast_id_map = db.ast_id_map(file_id); |
81 | self.recursive_limit += 1; | ||
76 | 82 | ||
77 | return Some((mark, expr)); | 83 | return Some((mark, expr)); |
78 | } | 84 | } |
@@ -88,6 +94,7 @@ impl Expander { | |||
88 | self.hygiene = Hygiene::new(db.upcast(), mark.file_id); | 94 | self.hygiene = Hygiene::new(db.upcast(), mark.file_id); |
89 | self.current_file_id = mark.file_id; | 95 | self.current_file_id = mark.file_id; |
90 | self.ast_id_map = mem::take(&mut mark.ast_id_map); | 96 | self.ast_id_map = mem::take(&mut mark.ast_id_map); |
97 | self.recursive_limit -= 1; | ||
91 | mark.bomb.defuse(); | 98 | mark.bomb.defuse(); |
92 | } | 99 | } |
93 | 100 | ||