aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-12-16 22:42:03 +0000
committerJonas Schievink <[email protected]>2020-12-16 22:42:03 +0000
commit28b5334580e5814d102b006e310ca0d1f03cdd72 (patch)
treeda9ac7abc2f426dbe2783aa7a2a29e57d17cddf8 /crates/hir_def/src
parent067067a6c11bb5afda98f5af14bfdec4744e7812 (diff)
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.
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r--crates/hir_def/src/item_tree.rs8
-rw-r--r--crates/hir_def/src/item_tree/lower.rs24
-rw-r--r--crates/hir_def/src/nameres/collector.rs34
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 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 {
646pub struct MacroRules { 646pub struct MacroRules {
647 /// The name of the declared macro. 647 /// The name of the declared macro.
648 pub name: Name, 648 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,
655 pub ast_id: FileAstId<ast::MacroRules>, 649 pub ast_id: FileAstId<ast::MacroRules>,
656} 650}
657 651
@@ -660,8 +654,6 @@ pub struct MacroRules {
660pub struct MacroDef { 654pub struct MacroDef {
661 pub name: Name, 655 pub name: Name,
662 pub visibility: RawVisibilityId, 656 pub visibility: RawVisibilityId,
663 /// Has `#[rustc_builtin_macro]`.
664 pub is_builtin: bool,
665 pub ast_id: FileAstId<ast::MacroDef>, 657 pub ast_id: FileAstId<ast::MacroDef>,
666} 658}
667 659
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 {
539 539
540 fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> { 540 fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> {
541 let name = m.name().map(|it| it.as_name())?; 541 let name = m.name().map(|it| it.as_name())?;
542 let attrs = Attrs::new(m, &self.hygiene);
543
544 let ast_id = self.source_ast_id_map.ast_id(m); 542 let ast_id = self.source_ast_id_map.ast_id(m);
545 543
546 // FIXME: cfg_attr 544 let res = MacroRules { name, ast_id };
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 };
563 Some(id(self.data().macro_rules.alloc(res))) 545 Some(id(self.data().macro_rules.alloc(res)))
564 } 546 }
565 547
566 fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<MacroDef>> { 548 fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<MacroDef>> {
567 let name = m.name().map(|it| it.as_name())?; 549 let name = m.name().map(|it| it.as_name())?;
568 let attrs = Attrs::new(m, &self.hygiene);
569 550
570 let ast_id = self.source_ast_id_map.ast_id(m); 551 let ast_id = self.source_ast_id_map.ast_id(m);
571 let visibility = self.lower_visibility(m); 552 let visibility = self.lower_visibility(m);
572 553
573 let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); 554 let res = MacroDef { name, ast_id, visibility };
574 let res = MacroDef { name, is_builtin, ast_id, visibility };
575 Some(id(self.data().macro_defs.alloc(res))) 555 Some(id(self.data().macro_defs.alloc(res)))
576 } 556 }
577 557
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::{
26 db::DefDatabase, 26 db::DefDatabase,
27 item_scope::{ImportType, PerNsGlobImports}, 27 item_scope::{ImportType, PerNsGlobImports},
28 item_tree::{ 28 item_tree::{
29 self, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, StructDefKind, 29 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind,
30 StructDefKind,
30 }, 31 },
31 nameres::{ 32 nameres::{
32 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 33 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
@@ -967,14 +968,15 @@ impl ModCollector<'_, '_> {
967 }) 968 })
968 } 969 }
969 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), 970 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),
971 ModItem::MacroDef(id) => { 972 ModItem::MacroDef(id) => {
972 let mac = &self.item_tree[id]; 973 let mac = &self.item_tree[id];
973 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); 974 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
974 975
975 // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it 976 // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it
976 // to define builtin macros, so we support at least that part. 977 // 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() {
978 let krate = self.def_collector.def_map.krate; 980 let krate = self.def_collector.def_map.krate;
979 let macro_id = find_builtin_macro(&mac.name, krate, ast_id) 981 let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
980 .or_else(|| find_builtin_derive(&mac.name, krate, ast_id)); 982 .or_else(|| find_builtin_derive(&mac.name, krate, ast_id));
@@ -1300,18 +1302,34 @@ impl ModCollector<'_, '_> {
1300 self.def_collector.resolve_proc_macro(&macro_name); 1302 self.def_collector.resolve_proc_macro(&macro_name);
1301 } 1303 }
1302 1304
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());
1304 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); 1308 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1305 1309
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
1306 // Case 1: builtin macros 1324 // Case 1: builtin macros
1307 if mac.is_builtin { 1325 if attrs.by_key("rustc_builtin_macro").exists() {
1308 let krate = self.def_collector.def_map.krate; 1326 let krate = self.def_collector.def_map.krate;
1309 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { 1327 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) {
1310 self.def_collector.define_macro( 1328 self.def_collector.define_macro(
1311 self.module_id, 1329 self.module_id,
1312 mac.name.clone(), 1330 mac.name.clone(),
1313 macro_id, 1331 macro_id,
1314 mac.is_export, 1332 is_export,
1315 ); 1333 );
1316 return; 1334 return;
1317 } 1335 }
@@ -1322,9 +1340,9 @@ impl ModCollector<'_, '_> {
1322 ast_id: Some(ast_id), 1340 ast_id: Some(ast_id),
1323 krate: self.def_collector.def_map.krate, 1341 krate: self.def_collector.def_map.krate,
1324 kind: MacroDefKind::Declarative, 1342 kind: MacroDefKind::Declarative,
1325 local_inner: mac.is_local_inner, 1343 local_inner: is_local_inner,
1326 }; 1344 };
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);
1328 } 1346 }
1329 1347
1330 fn collect_macro_call(&mut self, mac: &MacroCall) { 1348 fn collect_macro_call(&mut self, mac: &MacroCall) {