Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir_def/src/data.rs')
| -rw-r--r-- | crates/hir_def/src/data.rs | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index 753084fb4b..f08be39128 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs @@ -2,7 +2,7 @@ use std::sync::Arc; -use hir_expand::{name::Name, AstId, ExpandResult, InFile}; +use hir_expand::{name::Name, AstId, ExpandResult, InFile, MacroCallId}; use syntax::ast; use crate::{ @@ -184,6 +184,7 @@ pub struct TraitData { /// method calls to this trait's methods when the receiver is an array and the crate edition is /// 2015 or 2018. pub skip_array_during_method_dispatch: bool, + pub attribute_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>, } impl TraitData { @@ -207,7 +208,7 @@ impl TraitData { .by_key("rustc_skip_array_during_method_dispatch") .exists(); - let items = collect_items( + let (attribute_calls, items) = collect_items( db, module_id, &mut expander, @@ -216,6 +217,8 @@ impl TraitData { container, 100, ); + let attribute_calls = + if attribute_calls.is_empty() { None } else { Some(Box::new(attribute_calls)) }; Arc::new(TraitData { name, @@ -224,6 +227,7 @@ impl TraitData { is_unsafe, visibility, skip_array_during_method_dispatch, + attribute_calls, }) } @@ -247,6 +251,10 @@ impl TraitData { _ => None, }) } + + pub fn attribute_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ { + self.attribute_calls.iter().flat_map(|it| it.iter()).copied() + } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -255,6 +263,7 @@ pub struct ImplData { pub self_ty: Interned<TypeRef>, pub items: Vec<AssocItemId>, pub is_negative: bool, + pub attribute_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>, } impl ImplData { @@ -271,7 +280,7 @@ impl ImplData { let container = ItemContainerId::ImplId(id); let mut expander = Expander::new(db, impl_loc.id.file_id(), module_id); - let items = collect_items( + let (attribute_calls, items) = collect_items( db, module_id, &mut expander, @@ -281,8 +290,14 @@ impl ImplData { 100, ); let items = items.into_iter().map(|(_, item)| item).collect(); + let attribute_calls = + if attribute_calls.is_empty() { None } else { Some(Box::new(attribute_calls)) }; + + Arc::new(ImplData { target_trait, self_ty, items, is_negative, attribute_calls }) + } - Arc::new(ImplData { target_trait, self_ty, items, is_negative }) + pub fn attribute_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ { + self.attribute_calls.iter().flat_map(|it| it.iter()).copied() } } @@ -341,9 +356,9 @@ fn collect_items( tree_id: item_tree::TreeId, container: ItemContainerId, limit: usize, -) -> Vec<(Name, AssocItemId)> { +) -> (Vec<(AstId<ast::Item>, MacroCallId)>, Vec<(Name, AssocItemId)>) { if limit == 0 { - return Vec::new(); + return Default::default(); } let item_tree = tree_id.item_tree(db); @@ -352,22 +367,25 @@ fn collect_items( let def_map = module.def_map(db); let mut items = Vec::new(); + let mut attribute_calls = Vec::new(); + 'items: for item in assoc_items { let attrs = item_tree.attrs(db, module.krate, ModItem::from(item).into()); if !attrs.is_cfg_enabled(cfg_options) { continue; } - for attr in &*attrs { - let ast_id = AstIdWithPath { - path: (*attr.path).clone(), - ast_id: AstId::new(expander.current_file_id(), item.ast_id(&item_tree).upcast()), - }; + let ast_id = AstId::new(expander.current_file_id(), item.ast_id(&item_tree).upcast()); + let ast_id_with_path = AstIdWithPath { path: (*attr.path).clone(), ast_id }; if let Ok(ResolvedAttr::Macro(call_id)) = - def_map.resolve_attr_macro(db, module.local_id, ast_id, attr) + def_map.resolve_attr_macro(db, module.local_id, ast_id_with_path, attr) { + attribute_calls.push((ast_id, call_id)); let res = expander.enter_expand_id(db, call_id); - items.extend(collect_macro_items(db, module, expander, container, limit, res)); + let (mac_attrs, mac_items) = + collect_macro_items(db, module, expander, container, limit, res); + items.extend(mac_items); + attribute_calls.extend(mac_attrs); continue 'items; } } @@ -401,13 +419,16 @@ fn collect_items( let res = expander.enter_expand(db, call); if let Ok(res) = res { - items.extend(collect_macro_items(db, module, expander, container, limit, res)); + let (mac_attrs, mac_items) = + collect_macro_items(db, module, expander, container, limit, res); + items.extend(mac_items); + attribute_calls.extend(mac_attrs); } } } } - items + (attribute_calls, items) } fn collect_macro_items( @@ -417,7 +438,7 @@ fn collect_macro_items( container: ItemContainerId, limit: usize, res: ExpandResult<Option<(Mark, ast::MacroItems)>>, -) -> Vec<(Name, AssocItemId)> { +) -> (Vec<(AstId<ast::Item>, MacroCallId)>, Vec<(Name, AssocItemId)>) { if let Some((mark, mac)) = res.value { let src: InFile<ast::MacroItems> = expander.to_source(mac); let tree_id = item_tree::TreeId::new(src.file_id, None); @@ -430,5 +451,5 @@ fn collect_macro_items( return items; } - Vec::new() + Default::default() } |