diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 46 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 4 |
2 files changed, 38 insertions, 12 deletions
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index b0a3f1784..1aa9a9b7d 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs | |||
@@ -225,22 +225,48 @@ 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 | if let Some((mark, items)) = expander.enter_expand(db, m) { | 232 | res.extend(collect_impl_items_in_macro(db, &mut expander, m, id, limit)) |
230 | let items: InFile<ast::MacroItems> = expander.to_source(items); | ||
231 | expander.exit(db, mark); | ||
232 | res.extend(collect_impl_items( | ||
233 | db, | ||
234 | items.value.items().filter_map(|it| ImplItem::cast(it.syntax().clone())), | ||
235 | items.file_id, | ||
236 | id, | ||
237 | )); | ||
238 | } | ||
239 | } | 233 | } |
240 | 234 | ||
241 | res | 235 | res |
242 | } | 236 | } |
243 | 237 | ||
238 | fn collect_impl_items_in_macro( | ||
239 | db: &impl DefDatabase, | ||
240 | expander: &mut Expander, | ||
241 | m: ast::MacroCall, | ||
242 | id: ImplId, | ||
243 | limit: usize, | ||
244 | ) -> Vec<AssocItemId> { | ||
245 | if limit == 0 { | ||
246 | return Vec::new(); | ||
247 | } | ||
248 | |||
249 | if let Some((mark, items)) = expander.enter_expand(db, m) { | ||
250 | let items: InFile<ast::MacroItems> = expander.to_source(items); | ||
251 | let mut res = collect_impl_items( | ||
252 | db, | ||
253 | items.value.items().filter_map(|it| ImplItem::cast(it.syntax().clone())), | ||
254 | items.file_id, | ||
255 | id, | ||
256 | ); | ||
257 | // Recursive collect macros | ||
258 | // Note that ast::ModuleItem do not include ast::MacroCall | ||
259 | // We cannot use ModuleItemOwner::items here | ||
260 | for it in items.value.syntax().children().filter_map(ast::MacroCall::cast) { | ||
261 | res.extend(collect_impl_items_in_macro(db, expander, it, id, limit - 1)) | ||
262 | } | ||
263 | expander.exit(db, mark); | ||
264 | res | ||
265 | } else { | ||
266 | Vec::new() | ||
267 | } | ||
268 | } | ||
269 | |||
244 | fn collect_impl_items( | 270 | fn collect_impl_items( |
245 | db: &impl DefDatabase, | 271 | db: &impl DefDatabase, |
246 | impl_items: impl Iterator<Item = ImplItem>, | 272 | impl_items: impl Iterator<Item = ImplItem>, |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 8b641d8b5..45199fa11 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -399,14 +399,14 @@ where | |||
399 | let resolutions = enum_data | 399 | let resolutions = enum_data |
400 | .variants | 400 | .variants |
401 | .iter() | 401 | .iter() |
402 | .filter_map(|(local_id, variant_data)| { | 402 | .map(|(local_id, variant_data)| { |
403 | let name = variant_data.name.clone(); | 403 | let name = variant_data.name.clone(); |
404 | let variant = EnumVariantId { parent: e, local_id }; | 404 | let variant = EnumVariantId { parent: e, local_id }; |
405 | let res = Resolution { | 405 | let res = Resolution { |
406 | def: PerNs::both(variant.into(), variant.into()), | 406 | def: PerNs::both(variant.into(), variant.into()), |
407 | import: Some(import_id), | 407 | import: Some(import_id), |
408 | }; | 408 | }; |
409 | Some((name, res)) | 409 | (name, res) |
410 | }) | 410 | }) |
411 | .collect::<Vec<_>>(); | 411 | .collect::<Vec<_>>(); |
412 | self.update(module_id, Some(import_id), &resolutions); | 412 | self.update(module_id, Some(import_id), &resolutions); |