Skip to content

Commit 6746ba5

Browse files
committed
Record attribute calls on assoc items in TraitData and ImplData
1 parent 6cf0cad commit 6746ba5

File tree

5 files changed

+79
-27
lines changed

5 files changed

+79
-27
lines changed

crates/hir/src/semantics/source_to_def.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,7 @@ impl SourceToDefCtx<'_, '_> {
316316
}
317317

318318
pub(super) fn macro_to_def(&mut self, src: InFile<ast::Macro>) -> Option<MacroDefId> {
319-
let makro =
320-
self.dyn_map(src.as_ref()).and_then(|it| it[keys::MACRO_CALL].get(&src).copied());
319+
let makro = self.dyn_map(src.as_ref()).and_then(|it| it[keys::MACRO].get(&src).copied());
321320
if let res @ Some(_) = makro {
322321
return res;
323322
}

crates/hir_def/src/child_by_source.rs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,31 @@ pub trait ChildBySource {
3030
impl ChildBySource for TraitId {
3131
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
3232
let data = db.trait_data(*self);
33-
// FIXME attribute macros
34-
for &(_, item) in data.items.iter() {
33+
34+
data.attribute_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each(
35+
|(ast_id, call_id)| {
36+
let item = ast_id.with_value(ast_id.to_node(db.upcast()));
37+
res[keys::ATTR_MACRO_CALL].insert(item, call_id);
38+
},
39+
);
40+
data.items.iter().for_each(|&(_, item)| {
3541
child_by_source_assoc_items(db, res, file_id, item);
36-
}
42+
});
3743
}
3844
}
3945

4046
impl ChildBySource for ImplId {
4147
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
4248
let data = db.impl_data(*self);
43-
// FIXME attribute macros
44-
for &item in data.items.iter() {
49+
data.attribute_calls().filter(|(ast_id, _)| ast_id.file_id == file_id).for_each(
50+
|(ast_id, call_id)| {
51+
let item = ast_id.with_value(ast_id.to_node(db.upcast()));
52+
res[keys::ATTR_MACRO_CALL].insert(item, call_id);
53+
},
54+
);
55+
data.items.iter().for_each(|&item| {
4556
child_by_source_assoc_items(db, res, file_id, item);
46-
}
57+
});
4758
}
4859
}
4960

@@ -97,7 +108,7 @@ impl ChildBySource for ItemScope {
97108
// FIXME: Do we need to add proc-macros into a PROCMACRO dynmap here?
98109
Either::Right(_fn) => return,
99110
};
100-
res[keys::MACRO_CALL].insert(src, makro);
111+
res[keys::MACRO].insert(src, makro);
101112
}
102113
});
103114
self.unnamed_consts().for_each(|konst| {

crates/hir_def/src/data.rs

Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::sync::Arc;
44

5-
use hir_expand::{name::Name, AstId, ExpandResult, InFile};
5+
use hir_expand::{name::Name, AstId, ExpandResult, InFile, MacroCallId};
66
use syntax::ast;
77

88
use crate::{
@@ -184,6 +184,7 @@ pub struct TraitData {
184184
/// method calls to this trait's methods when the receiver is an array and the crate edition is
185185
/// 2015 or 2018.
186186
pub skip_array_during_method_dispatch: bool,
187+
pub attribute_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
187188
}
188189

189190
impl TraitData {
@@ -207,7 +208,7 @@ impl TraitData {
207208
.by_key("rustc_skip_array_during_method_dispatch")
208209
.exists();
209210

210-
let items = collect_items(
211+
let (attribute_calls, items) = collect_items(
211212
db,
212213
module_id,
213214
&mut expander,
@@ -216,6 +217,8 @@ impl TraitData {
216217
container,
217218
100,
218219
);
220+
let attribute_calls =
221+
if attribute_calls.is_empty() { None } else { Some(Box::new(attribute_calls)) };
219222

220223
Arc::new(TraitData {
221224
name,
@@ -224,6 +227,7 @@ impl TraitData {
224227
is_unsafe,
225228
visibility,
226229
skip_array_during_method_dispatch,
230+
attribute_calls,
227231
})
228232
}
229233

@@ -247,6 +251,10 @@ impl TraitData {
247251
_ => None,
248252
})
249253
}
254+
255+
pub fn attribute_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ {
256+
self.attribute_calls.iter().flat_map(|it| it.iter()).copied()
257+
}
250258
}
251259

252260
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -255,6 +263,7 @@ pub struct ImplData {
255263
pub self_ty: Interned<TypeRef>,
256264
pub items: Vec<AssocItemId>,
257265
pub is_negative: bool,
266+
pub attribute_calls: Option<Box<Vec<(AstId<ast::Item>, MacroCallId)>>>,
258267
}
259268

260269
impl ImplData {
@@ -271,7 +280,7 @@ impl ImplData {
271280
let container = ItemContainerId::ImplId(id);
272281
let mut expander = Expander::new(db, impl_loc.id.file_id(), module_id);
273282

274-
let items = collect_items(
283+
let (attribute_calls, items) = collect_items(
275284
db,
276285
module_id,
277286
&mut expander,
@@ -281,8 +290,14 @@ impl ImplData {
281290
100,
282291
);
283292
let items = items.into_iter().map(|(_, item)| item).collect();
293+
let attribute_calls =
294+
if attribute_calls.is_empty() { None } else { Some(Box::new(attribute_calls)) };
295+
296+
Arc::new(ImplData { target_trait, self_ty, items, is_negative, attribute_calls })
297+
}
284298

285-
Arc::new(ImplData { target_trait, self_ty, items, is_negative })
299+
pub fn attribute_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId)> + '_ {
300+
self.attribute_calls.iter().flat_map(|it| it.iter()).copied()
286301
}
287302
}
288303

@@ -341,9 +356,9 @@ fn collect_items(
341356
tree_id: item_tree::TreeId,
342357
container: ItemContainerId,
343358
limit: usize,
344-
) -> Vec<(Name, AssocItemId)> {
359+
) -> (Vec<(AstId<ast::Item>, MacroCallId)>, Vec<(Name, AssocItemId)>) {
345360
if limit == 0 {
346-
return Vec::new();
361+
return Default::default();
347362
}
348363

349364
let item_tree = tree_id.item_tree(db);
@@ -352,22 +367,25 @@ fn collect_items(
352367
let def_map = module.def_map(db);
353368

354369
let mut items = Vec::new();
370+
let mut attribute_calls = Vec::new();
371+
355372
'items: for item in assoc_items {
356373
let attrs = item_tree.attrs(db, module.krate, ModItem::from(item).into());
357374
if !attrs.is_cfg_enabled(cfg_options) {
358375
continue;
359376
}
360-
361377
for attr in &*attrs {
362-
let ast_id = AstIdWithPath {
363-
path: (*attr.path).clone(),
364-
ast_id: AstId::new(expander.current_file_id(), item.ast_id(&item_tree).upcast()),
365-
};
378+
let ast_id = AstId::new(expander.current_file_id(), item.ast_id(&item_tree).upcast());
379+
let ast_id_with_path = AstIdWithPath { path: (*attr.path).clone(), ast_id };
366380
if let Ok(ResolvedAttr::Macro(call_id)) =
367-
def_map.resolve_attr_macro(db, module.local_id, ast_id, attr)
381+
def_map.resolve_attr_macro(db, module.local_id, ast_id_with_path, attr)
368382
{
383+
attribute_calls.push((ast_id, call_id));
369384
let res = expander.enter_expand_id(db, call_id);
370-
items.extend(collect_macro_items(db, module, expander, container, limit, res));
385+
let (mac_attrs, mac_items) =
386+
collect_macro_items(db, module, expander, container, limit, res);
387+
items.extend(mac_items);
388+
attribute_calls.extend(mac_attrs);
371389
continue 'items;
372390
}
373391
}
@@ -401,13 +419,16 @@ fn collect_items(
401419
let res = expander.enter_expand(db, call);
402420

403421
if let Ok(res) = res {
404-
items.extend(collect_macro_items(db, module, expander, container, limit, res));
422+
let (mac_attrs, mac_items) =
423+
collect_macro_items(db, module, expander, container, limit, res);
424+
items.extend(mac_items);
425+
attribute_calls.extend(mac_attrs);
405426
}
406427
}
407428
}
408429
}
409430

410-
items
431+
(attribute_calls, items)
411432
}
412433

413434
fn collect_macro_items(
@@ -417,7 +438,7 @@ fn collect_macro_items(
417438
container: ItemContainerId,
418439
limit: usize,
419440
res: ExpandResult<Option<(Mark, ast::MacroItems)>>,
420-
) -> Vec<(Name, AssocItemId)> {
441+
) -> (Vec<(AstId<ast::Item>, MacroCallId)>, Vec<(Name, AssocItemId)>) {
421442
if let Some((mark, mac)) = res.value {
422443
let src: InFile<ast::MacroItems> = expander.to_source(mac);
423444
let tree_id = item_tree::TreeId::new(src.file_id, None);
@@ -430,5 +451,5 @@ fn collect_macro_items(
430451
return items;
431452
}
432453

433-
Vec::new()
454+
Default::default()
434455
}

crates/hir_def/src/keys.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new();
3232
pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new();
3333
pub const CONST_PARAM: Key<ast::ConstParam, ConstParamId> = Key::new();
3434

35-
pub const MACRO_CALL: Key<ast::Macro, MacroDefId> = Key::new();
35+
pub const MACRO: Key<ast::Macro, MacroDefId> = Key::new();
3636
pub const ATTR_MACRO_CALL: Key<ast::Item, MacroCallId> = Key::new();
3737
pub const DERIVE_MACRO_CALL: Key<ast::Attr, (AttrId, Box<[Option<MacroCallId>]>)> = Key::new();
3838

crates/ide/src/references.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,4 +1514,25 @@ fn func$0() {
15141514
"#]],
15151515
)
15161516
}
1517+
1518+
#[test]
1519+
fn attr_assoc_item() {
1520+
check(
1521+
r#"
1522+
//- proc_macros: identity
1523+
1524+
trait Trait {
1525+
#[proc_macros::identity]
1526+
fn func() {
1527+
Self::func$0();
1528+
}
1529+
}
1530+
"#,
1531+
expect![[r#"
1532+
func Function FileId(0) 48..87 51..55
1533+
1534+
FileId(0) 74..78
1535+
"#]],
1536+
)
1537+
}
15171538
}

0 commit comments

Comments
 (0)