Skip to content

Commit 28b5334

Browse files
Avoid querying attributes in item tree lowering
ItemTree is per-file, so there is no unique crate associated with it. This means that it cannot know the active CfgOptions and thus couldn't handle `cfg_attr`. Prepare it for `cfg_attr`s by avoiding accessing attributes.
1 parent 067067a commit 28b5334

File tree

3 files changed

+28
-38
lines changed

3 files changed

+28
-38
lines changed

crates/hir_def/src/item_tree.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -646,12 +646,6 @@ pub struct MacroCall {
646646
pub struct MacroRules {
647647
/// The name of the declared macro.
648648
pub name: Name,
649-
/// Has `#[macro_export]`.
650-
pub is_export: bool,
651-
/// Has `#[macro_export(local_inner_macros)]`.
652-
pub is_local_inner: bool,
653-
/// Has `#[rustc_builtin_macro]`.
654-
pub is_builtin: bool,
655649
pub ast_id: FileAstId<ast::MacroRules>,
656650
}
657651

@@ -660,8 +654,6 @@ pub struct MacroRules {
660654
pub struct MacroDef {
661655
pub name: Name,
662656
pub visibility: RawVisibilityId,
663-
/// Has `#[rustc_builtin_macro]`.
664-
pub is_builtin: bool,
665657
pub ast_id: FileAstId<ast::MacroDef>,
666658
}
667659

crates/hir_def/src/item_tree/lower.rs

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -539,39 +539,19 @@ impl Ctx {
539539

540540
fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> {
541541
let name = m.name().map(|it| it.as_name())?;
542-
let attrs = Attrs::new(m, &self.hygiene);
543-
544542
let ast_id = self.source_ast_id_map.ast_id(m);
545543

546-
// FIXME: cfg_attr
547-
let export_attr = attrs.by_key("macro_export");
548-
549-
let is_export = export_attr.exists();
550-
let is_local_inner = if is_export {
551-
export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it {
552-
tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
553-
ident.text.contains("local_inner_macros")
554-
}
555-
_ => false,
556-
})
557-
} else {
558-
false
559-
};
560-
561-
let is_builtin = attrs.by_key("rustc_builtin_macro").exists();
562-
let res = MacroRules { name, is_export, is_builtin, is_local_inner, ast_id };
544+
let res = MacroRules { name, ast_id };
563545
Some(id(self.data().macro_rules.alloc(res)))
564546
}
565547

566548
fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<MacroDef>> {
567549
let name = m.name().map(|it| it.as_name())?;
568-
let attrs = Attrs::new(m, &self.hygiene);
569550

570551
let ast_id = self.source_ast_id_map.ast_id(m);
571552
let visibility = self.lower_visibility(m);
572553

573-
let is_builtin = attrs.by_key("rustc_builtin_macro").exists();
574-
let res = MacroDef { name, is_builtin, ast_id, visibility };
554+
let res = MacroDef { name, ast_id, visibility };
575555
Some(id(self.data().macro_defs.alloc(res)))
576556
}
577557

crates/hir_def/src/nameres/collector.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ use crate::{
2626
db::DefDatabase,
2727
item_scope::{ImportType, PerNsGlobImports},
2828
item_tree::{
29-
self, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, StructDefKind,
29+
self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind,
30+
StructDefKind,
3031
},
3132
nameres::{
3233
diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
@@ -967,14 +968,15 @@ impl ModCollector<'_, '_> {
967968
})
968969
}
969970
ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]),
970-
ModItem::MacroRules(mac) => self.collect_macro_rules(&self.item_tree[mac]),
971+
ModItem::MacroRules(id) => self.collect_macro_rules(id),
971972
ModItem::MacroDef(id) => {
972973
let mac = &self.item_tree[id];
973974
let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
974975

975976
// "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it
976977
// to define builtin macros, so we support at least that part.
977-
if mac.is_builtin {
978+
let attrs = self.item_tree.attrs(ModItem::from(id).into());
979+
if attrs.by_key("rustc_builtin_macro").exists() {
978980
let krate = self.def_collector.def_map.krate;
979981
let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
980982
.or_else(|| find_builtin_derive(&mac.name, krate, ast_id));
@@ -1300,18 +1302,34 @@ impl ModCollector<'_, '_> {
13001302
self.def_collector.resolve_proc_macro(&macro_name);
13011303
}
13021304

1303-
fn collect_macro_rules(&mut self, mac: &MacroRules) {
1305+
fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
1306+
let mac = &self.item_tree[id];
1307+
let attrs = self.item_tree.attrs(ModItem::from(id).into());
13041308
let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
13051309

1310+
let export_attr = attrs.by_key("macro_export");
1311+
1312+
let is_export = export_attr.exists();
1313+
let is_local_inner = if is_export {
1314+
export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it {
1315+
tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
1316+
ident.text.contains("local_inner_macros")
1317+
}
1318+
_ => false,
1319+
})
1320+
} else {
1321+
false
1322+
};
1323+
13061324
// Case 1: builtin macros
1307-
if mac.is_builtin {
1325+
if attrs.by_key("rustc_builtin_macro").exists() {
13081326
let krate = self.def_collector.def_map.krate;
13091327
if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) {
13101328
self.def_collector.define_macro(
13111329
self.module_id,
13121330
mac.name.clone(),
13131331
macro_id,
1314-
mac.is_export,
1332+
is_export,
13151333
);
13161334
return;
13171335
}
@@ -1322,9 +1340,9 @@ impl ModCollector<'_, '_> {
13221340
ast_id: Some(ast_id),
13231341
krate: self.def_collector.def_map.krate,
13241342
kind: MacroDefKind::Declarative,
1325-
local_inner: mac.is_local_inner,
1343+
local_inner: is_local_inner,
13261344
};
1327-
self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, mac.is_export);
1345+
self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, is_export);
13281346
}
13291347

13301348
fn collect_macro_call(&mut self, mac: &MacroCall) {

0 commit comments

Comments
 (0)