diff options
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 6a65633ae..1aa9a9b7d 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs | |||
@@ -225,8 +225,11 @@ fn collect_impl_items_in_macros( | |||
225 | let mut expander = Expander::new(db, impl_block.file_id, module_id); | 225 | let mut expander = Expander::new(db, impl_block.file_id, module_id); |
226 | let mut res = Vec::new(); | 226 | let mut res = Vec::new(); |
227 | 227 | ||
228 | // We set a limit to protect against infinite recursion | ||
229 | let limit = 100; | ||
230 | |||
228 | for m in impl_block.value.syntax().children().filter_map(ast::MacroCall::cast) { | 231 | for m in impl_block.value.syntax().children().filter_map(ast::MacroCall::cast) { |
229 | res.extend(collect_impl_items_in_macro(db, &mut expander, m, id)) | 232 | res.extend(collect_impl_items_in_macro(db, &mut expander, m, id, limit)) |
230 | } | 233 | } |
231 | 234 | ||
232 | res | 235 | res |
@@ -237,7 +240,12 @@ fn collect_impl_items_in_macro( | |||
237 | expander: &mut Expander, | 240 | expander: &mut Expander, |
238 | m: ast::MacroCall, | 241 | m: ast::MacroCall, |
239 | id: ImplId, | 242 | id: ImplId, |
243 | limit: usize, | ||
240 | ) -> Vec<AssocItemId> { | 244 | ) -> Vec<AssocItemId> { |
245 | if limit == 0 { | ||
246 | return Vec::new(); | ||
247 | } | ||
248 | |||
241 | if let Some((mark, items)) = expander.enter_expand(db, m) { | 249 | if let Some((mark, items)) = expander.enter_expand(db, m) { |
242 | let items: InFile<ast::MacroItems> = expander.to_source(items); | 250 | let items: InFile<ast::MacroItems> = expander.to_source(items); |
243 | let mut res = collect_impl_items( | 251 | let mut res = collect_impl_items( |
@@ -250,7 +258,7 @@ fn collect_impl_items_in_macro( | |||
250 | // Note that ast::ModuleItem do not include ast::MacroCall | 258 | // Note that ast::ModuleItem do not include ast::MacroCall |
251 | // We cannot use ModuleItemOwner::items here | 259 | // We cannot use ModuleItemOwner::items here |
252 | for it in items.value.syntax().children().filter_map(ast::MacroCall::cast) { | 260 | for it in items.value.syntax().children().filter_map(ast::MacroCall::cast) { |
253 | res.extend(collect_impl_items_in_macro(db, expander, it, id)) | 261 | res.extend(collect_impl_items_in_macro(db, expander, it, id, limit - 1)) |
254 | } | 262 | } |
255 | expander.exit(db, mark); | 263 | expander.exit(db, mark); |
256 | res | 264 | res |