diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2020-12-16 23:42:03 +0100 |
|---|---|---|
| committer | Jonas Schievink <jonasschievink@gmail.com> | 2020-12-16 23:42:03 +0100 |
| commit | 28b5334580e5814d102b006e310ca0d1f03cdd72 (patch) | |
| tree | da9ac7abc2f426dbe2783aa7a2a29e57d17cddf8 | |
| parent | 067067a6c11bb5afda98f5af14bfdec4744e7812 (diff) | |
| download | rust-28b5334580e5814d102b006e310ca0d1f03cdd72.tar.gz rust-28b5334580e5814d102b006e310ca0d1f03cdd72.zip | |
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.
| -rw-r--r-- | crates/hir_def/src/item_tree.rs | 8 | ||||
| -rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 24 | ||||
| -rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 34 |
3 files changed, 28 insertions, 38 deletions
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 8cd0b18ccda..b8e09e3af31 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<ast::MacroRules>, } @@ -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<ast::MacroDef>, } diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index dd3409762e3..7de385ee83e 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<FileItemTreeId<MacroRules>> { 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<FileItemTreeId<MacroDef>> { 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 785895277fa..1936348fb43 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<MacroRules>) { + 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) { |
