From 28b5334580e5814d102b006e310ca0d1f03cdd72 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 16 Dec 2020 23:42:03 +0100 Subject: 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. --- crates/hir_def/src/item_tree.rs | 8 -------- crates/hir_def/src/item_tree/lower.rs | 24 ++--------------------- crates/hir_def/src/nameres/collector.rs | 34 +++++++++++++++++++++++++-------- 3 files changed, 28 insertions(+), 38 deletions(-) (limited to 'crates/hir_def/src') diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 8cd0b18cc..b8e09e3af 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -646,12 +646,6 @@ pub struct MacroCall { pub struct MacroRules { /// The name of the declared macro. pub name: Name, - /// Has `#[macro_export]`. - pub is_export: bool, - /// Has `#[macro_export(local_inner_macros)]`. - pub is_local_inner: bool, - /// Has `#[rustc_builtin_macro]`. - pub is_builtin: bool, pub ast_id: FileAstId, } @@ -660,8 +654,6 @@ pub struct MacroRules { pub struct MacroDef { pub name: Name, pub visibility: RawVisibilityId, - /// Has `#[rustc_builtin_macro]`. - pub is_builtin: bool, pub ast_id: FileAstId, } diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index dd3409762..7de385ee8 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -539,39 +539,19 @@ impl Ctx { fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option> { let name = m.name().map(|it| it.as_name())?; - let attrs = Attrs::new(m, &self.hygiene); - let ast_id = self.source_ast_id_map.ast_id(m); - // FIXME: cfg_attr - let export_attr = attrs.by_key("macro_export"); - - let is_export = export_attr.exists(); - let is_local_inner = if is_export { - export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it { - tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { - ident.text.contains("local_inner_macros") - } - _ => false, - }) - } else { - false - }; - - let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); - let res = MacroRules { name, is_export, is_builtin, is_local_inner, ast_id }; + let res = MacroRules { name, ast_id }; Some(id(self.data().macro_rules.alloc(res))) } fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option> { let name = m.name().map(|it| it.as_name())?; - let attrs = Attrs::new(m, &self.hygiene); let ast_id = self.source_ast_id_map.ast_id(m); let visibility = self.lower_visibility(m); - let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); - let res = MacroDef { name, is_builtin, ast_id, visibility }; + let res = MacroDef { name, ast_id, visibility }; Some(id(self.data().macro_defs.alloc(res))) } diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 785895277..1936348fb 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -26,7 +26,8 @@ use crate::{ db::DefDatabase, item_scope::{ImportType, PerNsGlobImports}, item_tree::{ - self, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, StructDefKind, + self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, + StructDefKind, }, nameres::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, @@ -967,14 +968,15 @@ impl ModCollector<'_, '_> { }) } ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), - ModItem::MacroRules(mac) => self.collect_macro_rules(&self.item_tree[mac]), + ModItem::MacroRules(id) => self.collect_macro_rules(id), ModItem::MacroDef(id) => { let mac = &self.item_tree[id]; let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it // to define builtin macros, so we support at least that part. - if mac.is_builtin { + let attrs = self.item_tree.attrs(ModItem::from(id).into()); + if attrs.by_key("rustc_builtin_macro").exists() { let krate = self.def_collector.def_map.krate; let macro_id = find_builtin_macro(&mac.name, krate, ast_id) .or_else(|| find_builtin_derive(&mac.name, krate, ast_id)); @@ -1300,18 +1302,34 @@ impl ModCollector<'_, '_> { self.def_collector.resolve_proc_macro(¯o_name); } - fn collect_macro_rules(&mut self, mac: &MacroRules) { + fn collect_macro_rules(&mut self, id: FileItemTreeId) { + let mac = &self.item_tree[id]; + let attrs = self.item_tree.attrs(ModItem::from(id).into()); let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); + let export_attr = attrs.by_key("macro_export"); + + let is_export = export_attr.exists(); + let is_local_inner = if is_export { + export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it { + tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { + ident.text.contains("local_inner_macros") + } + _ => false, + }) + } else { + false + }; + // Case 1: builtin macros - if mac.is_builtin { + if attrs.by_key("rustc_builtin_macro").exists() { let krate = self.def_collector.def_map.krate; if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { self.def_collector.define_macro( self.module_id, mac.name.clone(), macro_id, - mac.is_export, + is_export, ); return; } @@ -1322,9 +1340,9 @@ impl ModCollector<'_, '_> { ast_id: Some(ast_id), krate: self.def_collector.def_map.krate, kind: MacroDefKind::Declarative, - local_inner: mac.is_local_inner, + local_inner: is_local_inner, }; - self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, mac.is_export); + self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, is_export); } fn collect_macro_call(&mut self, mac: &MacroCall) { -- cgit v1.2.3