aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres/collector.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/nameres/collector.rs')
-rw-r--r--crates/hir_def/src/nameres/collector.rs121
1 files changed, 85 insertions, 36 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 85cc342c4..b114a6fe4 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,
@@ -220,17 +221,20 @@ impl DefCollector<'_> {
220 let item_tree = self.db.item_tree(file_id.into()); 221 let item_tree = self.db.item_tree(file_id.into());
221 let module_id = self.def_map.root; 222 let module_id = self.def_map.root;
222 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; 223 self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id };
223 let mut root_collector = ModCollector { 224 if item_tree
224 def_collector: &mut *self, 225 .top_level_attrs(self.db, self.def_map.krate)
225 macro_depth: 0, 226 .cfg()
226 module_id, 227 .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false))
227 file_id: file_id.into(),
228 item_tree: &item_tree,
229 mod_dir: ModDir::root(),
230 };
231 if item_tree.top_level_attrs().cfg().map_or(true, |cfg| root_collector.is_cfg_enabled(&cfg))
232 { 228 {
233 root_collector.collect(item_tree.top_level_items()); 229 ModCollector {
230 def_collector: &mut *self,
231 macro_depth: 0,
232 module_id,
233 file_id: file_id.into(),
234 item_tree: &item_tree,
235 mod_dir: ModDir::root(),
236 }
237 .collect(item_tree.top_level_items());
234 } 238 }
235 239
236 // main name resolution fixed-point loop. 240 // main name resolution fixed-point loop.
@@ -309,13 +313,13 @@ impl DefCollector<'_> {
309 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) { 313 let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) {
310 Some((_, expander)) => MacroDefId { 314 Some((_, expander)) => MacroDefId {
311 ast_id: None, 315 ast_id: None,
312 krate: Some(self.def_map.krate), 316 krate: self.def_map.krate,
313 kind: MacroDefKind::ProcMacro(*expander), 317 kind: MacroDefKind::ProcMacro(*expander),
314 local_inner: false, 318 local_inner: false,
315 }, 319 },
316 None => MacroDefId { 320 None => MacroDefId {
317 ast_id: None, 321 ast_id: None,
318 krate: Some(self.def_map.krate), 322 krate: self.def_map.krate,
319 kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)), 323 kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)),
320 local_inner: false, 324 local_inner: false,
321 }, 325 },
@@ -784,14 +788,6 @@ impl DefCollector<'_> {
784 directive: &DeriveDirective, 788 directive: &DeriveDirective,
785 path: &ModPath, 789 path: &ModPath,
786 ) -> Option<MacroDefId> { 790 ) -> Option<MacroDefId> {
787 if let Some(name) = path.as_ident() {
788 // FIXME this should actually be handled with the normal name
789 // resolution; the std lib defines built-in stubs for the derives,
790 // but these are new-style `macro`s, which we don't support yet
791 if let Some(def_id) = find_builtin_derive(name) {
792 return Some(def_id);
793 }
794 }
795 let resolved_res = self.def_map.resolve_path_fp_with_macro( 791 let resolved_res = self.def_map.resolve_path_fp_with_macro(
796 self.db, 792 self.db,
797 ResolveMode::Other, 793 ResolveMode::Other,
@@ -912,6 +908,8 @@ struct ModCollector<'a, 'b> {
912 908
913impl ModCollector<'_, '_> { 909impl ModCollector<'_, '_> {
914 fn collect(&mut self, items: &[ModItem]) { 910 fn collect(&mut self, items: &[ModItem]) {
911 let krate = self.def_collector.def_map.krate;
912
915 // Note: don't assert that inserted value is fresh: it's simply not true 913 // Note: don't assert that inserted value is fresh: it's simply not true
916 // for macros. 914 // for macros.
917 self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); 915 self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
@@ -928,7 +926,7 @@ impl ModCollector<'_, '_> {
928 // `#[macro_use] extern crate` is hoisted to imports macros before collecting 926 // `#[macro_use] extern crate` is hoisted to imports macros before collecting
929 // any other items. 927 // any other items.
930 for item in items { 928 for item in items {
931 let attrs = self.item_tree.attrs((*item).into()); 929 let attrs = self.item_tree.attrs(self.def_collector.db, krate, (*item).into());
932 if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) { 930 if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) {
933 if let ModItem::ExternCrate(id) = item { 931 if let ModItem::ExternCrate(id) = item {
934 let import = self.item_tree[*id].clone(); 932 let import = self.item_tree[*id].clone();
@@ -940,7 +938,7 @@ impl ModCollector<'_, '_> {
940 } 938 }
941 939
942 for &item in items { 940 for &item in items {
943 let attrs = self.item_tree.attrs(item.into()); 941 let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into());
944 if let Some(cfg) = attrs.cfg() { 942 if let Some(cfg) = attrs.cfg() {
945 if !self.is_cfg_enabled(&cfg) { 943 if !self.is_cfg_enabled(&cfg) {
946 self.emit_unconfigured_diagnostic(item, &cfg); 944 self.emit_unconfigured_diagnostic(item, &cfg);
@@ -953,7 +951,7 @@ impl ModCollector<'_, '_> {
953 951
954 let mut def = None; 952 let mut def = None;
955 match item { 953 match item {
956 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], attrs), 954 ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs),
957 ModItem::Import(import_id) => { 955 ModItem::Import(import_id) => {
958 self.def_collector.unresolved_imports.push(ImportDirective { 956 self.def_collector.unresolved_imports.push(ImportDirective {
959 module_id: self.module_id, 957 module_id: self.module_id,
@@ -975,7 +973,41 @@ impl ModCollector<'_, '_> {
975 }) 973 })
976 } 974 }
977 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), 975 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]),
978 ModItem::MacroRules(mac) => self.collect_macro_rules(&self.item_tree[mac]), 976 ModItem::MacroRules(id) => self.collect_macro_rules(id),
977 ModItem::MacroDef(id) => {
978 let mac = &self.item_tree[id];
979 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
980
981 // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it
982 // to define builtin macros, so we support at least that part.
983 let attrs = self.item_tree.attrs(
984 self.def_collector.db,
985 krate,
986 ModItem::from(id).into(),
987 );
988 if attrs.by_key("rustc_builtin_macro").exists() {
989 let krate = self.def_collector.def_map.krate;
990 let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
991 .or_else(|| find_builtin_derive(&mac.name, krate, ast_id));
992 if let Some(macro_id) = macro_id {
993 let vis = self
994 .def_collector
995 .def_map
996 .resolve_visibility(
997 self.def_collector.db,
998 self.module_id,
999 &self.item_tree[mac.visibility],
1000 )
1001 .unwrap_or(Visibility::Public);
1002 self.def_collector.update(
1003 self.module_id,
1004 &[(Some(mac.name.clone()), PerNs::macros(macro_id, vis))],
1005 vis,
1006 ImportType::Named,
1007 );
1008 }
1009 }
1010 }
979 ModItem::Impl(imp) => { 1011 ModItem::Impl(imp) => {
980 let module = ModuleId { 1012 let module = ModuleId {
981 krate: self.def_collector.def_map.krate, 1013 krate: self.def_collector.def_map.krate,
@@ -989,7 +1021,7 @@ impl ModCollector<'_, '_> {
989 ModItem::Function(id) => { 1021 ModItem::Function(id) => {
990 let func = &self.item_tree[id]; 1022 let func = &self.item_tree[id];
991 1023
992 self.collect_proc_macro_def(&func.name, attrs); 1024 self.collect_proc_macro_def(&func.name, &attrs);
993 1025
994 def = Some(DefData { 1026 def = Some(DefData {
995 id: FunctionLoc { 1027 id: FunctionLoc {
@@ -1009,7 +1041,7 @@ impl ModCollector<'_, '_> {
1009 // FIXME: check attrs to see if this is an attribute macro invocation; 1041 // FIXME: check attrs to see if this is an attribute macro invocation;
1010 // in which case we don't add the invocation, just a single attribute 1042 // in which case we don't add the invocation, just a single attribute
1011 // macro invocation 1043 // macro invocation
1012 self.collect_derives(attrs, it.ast_id.upcast()); 1044 self.collect_derives(&attrs, it.ast_id.upcast());
1013 1045
1014 def = Some(DefData { 1046 def = Some(DefData {
1015 id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } 1047 id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1026,7 +1058,7 @@ impl ModCollector<'_, '_> {
1026 // FIXME: check attrs to see if this is an attribute macro invocation; 1058 // FIXME: check attrs to see if this is an attribute macro invocation;
1027 // in which case we don't add the invocation, just a single attribute 1059 // in which case we don't add the invocation, just a single attribute
1028 // macro invocation 1060 // macro invocation
1029 self.collect_derives(attrs, it.ast_id.upcast()); 1061 self.collect_derives(&attrs, it.ast_id.upcast());
1030 1062
1031 def = Some(DefData { 1063 def = Some(DefData {
1032 id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } 1064 id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1043,7 +1075,7 @@ impl ModCollector<'_, '_> {
1043 // FIXME: check attrs to see if this is an attribute macro invocation; 1075 // FIXME: check attrs to see if this is an attribute macro invocation;
1044 // in which case we don't add the invocation, just a single attribute 1076 // in which case we don't add the invocation, just a single attribute
1045 // macro invocation 1077 // macro invocation
1046 self.collect_derives(attrs, it.ast_id.upcast()); 1078 self.collect_derives(&attrs, it.ast_id.upcast());
1047 1079
1048 def = Some(DefData { 1080 def = Some(DefData {
1049 id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } 1081 id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1279,18 +1311,35 @@ impl ModCollector<'_, '_> {
1279 self.def_collector.resolve_proc_macro(&macro_name); 1311 self.def_collector.resolve_proc_macro(&macro_name);
1280 } 1312 }
1281 1313
1282 fn collect_macro_rules(&mut self, mac: &MacroRules) { 1314 fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
1283 let ast_id = InFile::new(self.file_id, mac.ast_id); 1315 let krate = self.def_collector.def_map.krate;
1316 let mac = &self.item_tree[id];
1317 let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
1318 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1319
1320 let export_attr = attrs.by_key("macro_export");
1321
1322 let is_export = export_attr.exists();
1323 let is_local_inner = if is_export {
1324 export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it {
1325 tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
1326 ident.text.contains("local_inner_macros")
1327 }
1328 _ => false,
1329 })
1330 } else {
1331 false
1332 };
1284 1333
1285 // Case 1: builtin macros 1334 // Case 1: builtin macros
1286 if mac.is_builtin { 1335 if attrs.by_key("rustc_builtin_macro").exists() {
1287 let krate = self.def_collector.def_map.krate; 1336 let krate = self.def_collector.def_map.krate;
1288 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { 1337 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) {
1289 self.def_collector.define_macro( 1338 self.def_collector.define_macro(
1290 self.module_id, 1339 self.module_id,
1291 mac.name.clone(), 1340 mac.name.clone(),
1292 macro_id, 1341 macro_id,
1293 mac.is_export, 1342 is_export,
1294 ); 1343 );
1295 return; 1344 return;
1296 } 1345 }
@@ -1299,11 +1348,11 @@ impl ModCollector<'_, '_> {
1299 // Case 2: normal `macro_rules!` macro 1348 // Case 2: normal `macro_rules!` macro
1300 let macro_id = MacroDefId { 1349 let macro_id = MacroDefId {
1301 ast_id: Some(ast_id), 1350 ast_id: Some(ast_id),
1302 krate: Some(self.def_collector.def_map.krate), 1351 krate: self.def_collector.def_map.krate,
1303 kind: MacroDefKind::Declarative, 1352 kind: MacroDefKind::Declarative,
1304 local_inner: mac.is_local_inner, 1353 local_inner: is_local_inner,
1305 }; 1354 };
1306 self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, mac.is_export); 1355 self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, is_export);
1307 } 1356 }
1308 1357
1309 fn collect_macro_call(&mut self, mac: &MacroCall) { 1358 fn collect_macro_call(&mut self, mac: &MacroCall) {