diff options
Diffstat (limited to 'crates/hir_def/src/nameres')
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 65 |
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(¯o_name); | 1279 | self.def_collector.resolve_proc_macro(¯o_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 | ||
1373 | fn is_macro_rules(path: &ModPath) -> bool { | ||
1374 | path.as_ident() == Some(&name![macro_rules]) | ||
1375 | } | ||
1376 | |||
1377 | #[cfg(test)] | 1368 | #[cfg(test)] |
1378 | mod tests { | 1369 | mod tests { |
1379 | use crate::{db::DefDatabase, test_db::TestDB}; | 1370 | use crate::{db::DefDatabase, test_db::TestDB}; |