aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r--crates/ra_hir_def/src/data.rs46
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs4
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
238fn 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
244fn collect_impl_items( 270fn 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);