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.rs55
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()
}