aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r--crates/hir_def/src/db.rs7
-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/lang_item.rs77
-rw-r--r--crates/hir_def/src/nameres/collector.rs34
5 files changed, 58 insertions, 92 deletions
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs
index 7f250da33..d1a459066 100644
--- a/crates/hir_def/src/db.rs
+++ b/crates/hir_def/src/db.rs
@@ -16,8 +16,8 @@ use crate::{
16 lang_item::{LangItemTarget, LangItems}, 16 lang_item::{LangItemTarget, LangItems},
17 nameres::CrateDefMap, 17 nameres::CrateDefMap,
18 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, 18 AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
19 GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, 19 GenericDefId, ImplId, ImplLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc,
20 TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, 20 TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
21}; 21};
22 22
23#[salsa::query_group(InternDatabaseStorage)] 23#[salsa::query_group(InternDatabaseStorage)]
@@ -95,9 +95,6 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
95 #[salsa::invoke(Attrs::attrs_query)] 95 #[salsa::invoke(Attrs::attrs_query)]
96 fn attrs(&self, def: AttrDefId) -> Attrs; 96 fn attrs(&self, def: AttrDefId) -> Attrs;
97 97
98 #[salsa::invoke(LangItems::module_lang_items_query)]
99 fn module_lang_items(&self, module: ModuleId) -> Option<Arc<LangItems>>;
100
101 #[salsa::invoke(LangItems::crate_lang_items_query)] 98 #[salsa::invoke(LangItems::crate_lang_items_query)]
102 fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>; 99 fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>;
103 100
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/lang_item.rs b/crates/hir_def/src/lang_item.rs
index 063eadccb..30188b740 100644
--- a/crates/hir_def/src/lang_item.rs
+++ b/crates/hir_def/src/lang_item.rs
@@ -8,8 +8,8 @@ use rustc_hash::FxHashMap;
8use syntax::SmolStr; 8use syntax::SmolStr;
9 9
10use crate::{ 10use crate::{
11 db::DefDatabase, AdtId, AttrDefId, CrateId, EnumId, FunctionId, ImplId, ModuleDefId, ModuleId, 11 db::DefDatabase, AdtId, AttrDefId, CrateId, EnumId, FunctionId, ImplId, ModuleDefId, StaticId,
12 StaticId, StructId, TraitId, 12 StructId, TraitId,
13}; 13};
14 14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -84,27 +84,34 @@ impl LangItems {
84 84
85 let crate_def_map = db.crate_def_map(krate); 85 let crate_def_map = db.crate_def_map(krate);
86 86
87 crate_def_map 87 for (_, module_data) in crate_def_map.modules.iter() {
88 .modules 88 for impl_def in module_data.scope.impls() {
89 .iter() 89 lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId)
90 .filter_map(|(local_id, _)| db.module_lang_items(ModuleId { krate, local_id })) 90 }
91 .for_each(|it| lang_items.items.extend(it.items.iter().map(|(k, v)| (k.clone(), *v))));
92
93 Arc::new(lang_items)
94 }
95 91
96 pub(crate) fn module_lang_items_query( 92 for def in module_data.scope.declarations() {
97 db: &dyn DefDatabase, 93 match def {
98 module: ModuleId, 94 ModuleDefId::TraitId(trait_) => {
99 ) -> Option<Arc<LangItems>> { 95 lang_items.collect_lang_item(db, trait_, LangItemTarget::TraitId)
100 let _p = profile::span("module_lang_items_query"); 96 }
101 let mut lang_items = LangItems::default(); 97 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
102 lang_items.collect_lang_items(db, module); 98 lang_items.collect_lang_item(db, e, LangItemTarget::EnumId)
103 if lang_items.items.is_empty() { 99 }
104 None 100 ModuleDefId::AdtId(AdtId::StructId(s)) => {
105 } else { 101 lang_items.collect_lang_item(db, s, LangItemTarget::StructId)
106 Some(Arc::new(lang_items)) 102 }
103 ModuleDefId::FunctionId(f) => {
104 lang_items.collect_lang_item(db, f, LangItemTarget::FunctionId)
105 }
106 ModuleDefId::StaticId(s) => {
107 lang_items.collect_lang_item(db, s, LangItemTarget::StaticId)
108 }
109 _ => {}
110 }
111 }
107 } 112 }
113
114 Arc::new(lang_items)
108 } 115 }
109 116
110 /// Salsa query. Look for a lang item, starting from the specified crate and recursively 117 /// Salsa query. Look for a lang item, starting from the specified crate and recursively
@@ -126,34 +133,6 @@ impl LangItems {
126 .find_map(|dep| db.lang_item(dep.crate_id, item.clone())) 133 .find_map(|dep| db.lang_item(dep.crate_id, item.clone()))
127 } 134 }
128 135
129 fn collect_lang_items(&mut self, db: &dyn DefDatabase, module: ModuleId) {
130 // Look for impl targets
131 let def_map = db.crate_def_map(module.krate);
132 let module_data = &def_map[module.local_id];
133 for impl_def in module_data.scope.impls() {
134 self.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId)
135 }
136
137 for def in module_data.scope.declarations() {
138 match def {
139 ModuleDefId::TraitId(trait_) => {
140 self.collect_lang_item(db, trait_, LangItemTarget::TraitId)
141 }
142 ModuleDefId::AdtId(AdtId::EnumId(e)) => {
143 self.collect_lang_item(db, e, LangItemTarget::EnumId)
144 }
145 ModuleDefId::AdtId(AdtId::StructId(s)) => {
146 self.collect_lang_item(db, s, LangItemTarget::StructId)
147 }
148 ModuleDefId::FunctionId(f) => {
149 self.collect_lang_item(db, f, LangItemTarget::FunctionId)
150 }
151 ModuleDefId::StaticId(s) => self.collect_lang_item(db, s, LangItemTarget::StaticId),
152 _ => {}
153 }
154 }
155 }
156
157 fn collect_lang_item<T>( 136 fn collect_lang_item<T>(
158 &mut self, 137 &mut self,
159 db: &dyn DefDatabase, 138 db: &dyn DefDatabase,
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) {