aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/nameres
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r--crates/hir_def/src/nameres/collector.rs65
1 files changed, 28 insertions, 37 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index 19cd713ba..85cc342c4 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -11,7 +11,7 @@ use hir_expand::{
11 ast_id_map::FileAstId, 11 ast_id_map::FileAstId,
12 builtin_derive::find_builtin_derive, 12 builtin_derive::find_builtin_derive,
13 builtin_macro::find_builtin_macro, 13 builtin_macro::find_builtin_macro,
14 name::{name, AsName, Name}, 14 name::{AsName, Name},
15 proc_macro::ProcMacroExpander, 15 proc_macro::ProcMacroExpander,
16 HirFileId, MacroCallId, MacroDefId, MacroDefKind, 16 HirFileId, MacroCallId, MacroDefId, MacroDefKind,
17}; 17};
@@ -25,7 +25,9 @@ use crate::{
25 attr::Attrs, 25 attr::Attrs,
26 db::DefDatabase, 26 db::DefDatabase,
27 item_scope::{ImportType, PerNsGlobImports}, 27 item_scope::{ImportType, PerNsGlobImports},
28 item_tree::{self, ItemTree, ItemTreeId, MacroCall, Mod, ModItem, ModKind, StructDefKind}, 28 item_tree::{
29 self, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, StructDefKind,
30 },
29 nameres::{ 31 nameres::{
30 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, 32 diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
31 BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, 33 BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode,
@@ -972,7 +974,8 @@ impl ModCollector<'_, '_> {
972 status: PartialResolvedImport::Unresolved, 974 status: PartialResolvedImport::Unresolved,
973 }) 975 })
974 } 976 }
975 ModItem::MacroCall(mac) => self.collect_macro(&self.item_tree[mac]), 977 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::Impl(imp) => { 979 ModItem::Impl(imp) => {
977 let module = ModuleId { 980 let module = ModuleId {
978 krate: self.def_collector.def_map.krate, 981 krate: self.def_collector.def_map.krate,
@@ -1276,45 +1279,37 @@ impl ModCollector<'_, '_> {
1276 self.def_collector.resolve_proc_macro(&macro_name); 1279 self.def_collector.resolve_proc_macro(&macro_name);
1277 } 1280 }
1278 1281
1279 fn collect_macro(&mut self, mac: &MacroCall) { 1282 fn collect_macro_rules(&mut self, mac: &MacroRules) {
1280 let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); 1283 let ast_id = InFile::new(self.file_id, mac.ast_id);
1281 1284
1282 // Case 0: builtin macros 1285 // Case 1: builtin macros
1283 if mac.is_builtin { 1286 if mac.is_builtin {
1284 if let Some(name) = &mac.name { 1287 let krate = self.def_collector.def_map.krate;
1285 let krate = self.def_collector.def_map.krate; 1288 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) {
1286 if let Some(macro_id) = find_builtin_macro(name, krate, ast_id.ast_id) {
1287 self.def_collector.define_macro(
1288 self.module_id,
1289 name.clone(),
1290 macro_id,
1291 mac.is_export,
1292 );
1293 return;
1294 }
1295 }
1296 }
1297
1298 // Case 1: macro rules, define a macro in crate-global mutable scope
1299 if is_macro_rules(&mac.path) {
1300 if let Some(name) = &mac.name {
1301 let macro_id = MacroDefId {
1302 ast_id: Some(ast_id.ast_id),
1303 krate: Some(self.def_collector.def_map.krate),
1304 kind: MacroDefKind::Declarative,
1305 local_inner: mac.is_local_inner,
1306 };
1307 self.def_collector.define_macro( 1289 self.def_collector.define_macro(
1308 self.module_id, 1290 self.module_id,
1309 name.clone(), 1291 mac.name.clone(),
1310 macro_id, 1292 macro_id,
1311 mac.is_export, 1293 mac.is_export,
1312 ); 1294 );
1295 return;
1313 } 1296 }
1314 return;
1315 } 1297 }
1316 1298
1317 // Case 2: try to resolve in legacy scope and expand macro_rules 1299 // Case 2: normal `macro_rules!` macro
1300 let macro_id = MacroDefId {
1301 ast_id: Some(ast_id),
1302 krate: Some(self.def_collector.def_map.krate),
1303 kind: MacroDefKind::Declarative,
1304 local_inner: mac.is_local_inner,
1305 };
1306 self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, mac.is_export);
1307 }
1308
1309 fn collect_macro_call(&mut self, mac: &MacroCall) {
1310 let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone());
1311
1312 // Case 1: try to resolve in legacy scope and expand macro_rules
1318 if let Some(macro_call_id) = 1313 if let Some(macro_call_id) =
1319 ast_id.as_call_id(self.def_collector.db, self.def_collector.def_map.krate, |path| { 1314 ast_id.as_call_id(self.def_collector.db, self.def_collector.def_map.krate, |path| {
1320 path.as_ident().and_then(|name| { 1315 path.as_ident().and_then(|name| {
@@ -1332,7 +1327,7 @@ impl ModCollector<'_, '_> {
1332 return; 1327 return;
1333 } 1328 }
1334 1329
1335 // Case 3: resolve in module scope, expand during name resolution. 1330 // Case 2: resolve in module scope, expand during name resolution.
1336 // We rewrite simple path `macro_name` to `self::macro_name` to force resolve in module scope only. 1331 // We rewrite simple path `macro_name` to `self::macro_name` to force resolve in module scope only.
1337 if ast_id.path.is_ident() { 1332 if ast_id.path.is_ident() {
1338 ast_id.path.kind = PathKind::Super(0); 1333 ast_id.path.kind = PathKind::Super(0);
@@ -1370,10 +1365,6 @@ impl ModCollector<'_, '_> {
1370 } 1365 }
1371} 1366}
1372 1367
1373fn is_macro_rules(path: &ModPath) -> bool {
1374 path.as_ident() == Some(&name![macro_rules])
1375}
1376
1377#[cfg(test)] 1368#[cfg(test)]
1378mod tests { 1369mod tests {
1379 use crate::{db::DefDatabase, test_db::TestDB}; 1370 use crate::{db::DefDatabase, test_db::TestDB};