aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-03-28 16:43:11 +0100
committerGitHub <[email protected]>2021-03-28 16:43:11 +0100
commitbb1d925dab36372c6bd1fb5671bb68ce938ff009 (patch)
treead32fbab8caf6563961b1366c726d8323fb303f5 /crates/hir_def/src
parentce6bb5ccca48b177f6cd12b42b4c52f3e1b44e0c (diff)
parent772987911851d6480ec8c905c0cac1e2f881152c (diff)
Merge #8212
8212: Basic support macro 2.0 r=jonas-schievink a=edwin0cheng Turn out it is quite straight forward :) r @jonas-schievink ![m2](https://user-images.githubusercontent.com/11014119/112712565-6eb99380-8f0b-11eb-88de-5d7f974dfe6d.png) Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r--crates/hir_def/src/nameres/collector.rs102
-rw-r--r--crates/hir_def/src/nameres/tests/macros.rs18
2 files changed, 81 insertions, 39 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index d8fabe49b..d58135ec9 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -25,8 +25,8 @@ use crate::{
25 derive_macro_as_call_id, 25 derive_macro_as_call_id,
26 item_scope::{ImportType, PerNsGlobImports}, 26 item_scope::{ImportType, PerNsGlobImports},
27 item_tree::{ 27 item_tree::{
28 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, 28 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroDef, MacroRules, Mod, ModItem,
29 StructDefKind, 29 ModKind, StructDefKind,
30 }, 30 },
31 macro_call_as_call_id, 31 macro_call_as_call_id,
32 nameres::{ 32 nameres::{
@@ -395,7 +395,7 @@ impl DefCollector<'_> {
395 /// macro_rules! foo { () => {} } 395 /// macro_rules! foo { () => {} }
396 /// use foo as bar; 396 /// use foo as bar;
397 /// ``` 397 /// ```
398 fn define_macro( 398 fn define_macro_rules(
399 &mut self, 399 &mut self,
400 module_id: LocalModuleId, 400 module_id: LocalModuleId,
401 name: Name, 401 name: Name,
@@ -430,6 +430,21 @@ impl DefCollector<'_> {
430 self.def_map.modules[module_id].scope.define_legacy_macro(name, mac); 430 self.def_map.modules[module_id].scope.define_legacy_macro(name, mac);
431 } 431 }
432 432
433 /// Define a macro 2.0 macro
434 ///
435 /// The scoped of macro 2.0 macro is equal to normal function
436 fn define_macro_def(
437 &mut self,
438 module_id: LocalModuleId,
439 name: Name,
440 macro_: MacroDefId,
441 vis: &RawVisibility,
442 ) {
443 let vis =
444 self.def_map.resolve_visibility(self.db, module_id, vis).unwrap_or(Visibility::Public);
445 self.update(module_id, &[(Some(name), PerNs::macros(macro_, vis))], vis, ImportType::Named);
446 }
447
433 /// Define a proc macro 448 /// Define a proc macro
434 /// 449 ///
435 /// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped. 450 /// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped.
@@ -1067,40 +1082,7 @@ impl ModCollector<'_, '_> {
1067 } 1082 }
1068 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), 1083 ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]),
1069 ModItem::MacroRules(id) => self.collect_macro_rules(id), 1084 ModItem::MacroRules(id) => self.collect_macro_rules(id),
1070 ModItem::MacroDef(id) => { 1085 ModItem::MacroDef(id) => self.collect_macro_def(id),
1071 let mac = &self.item_tree[id];
1072 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1073
1074 // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it
1075 // to define builtin macros, so we support at least that part.
1076 let attrs = self.item_tree.attrs(
1077 self.def_collector.db,
1078 krate,
1079 ModItem::from(id).into(),
1080 );
1081 if attrs.by_key("rustc_builtin_macro").exists() {
1082 let krate = self.def_collector.def_map.krate;
1083 let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
1084 .or_else(|| find_builtin_derive(&mac.name, krate, ast_id));
1085 if let Some(macro_id) = macro_id {
1086 let vis = self
1087 .def_collector
1088 .def_map
1089 .resolve_visibility(
1090 self.def_collector.db,
1091 self.module_id,
1092 &self.item_tree[mac.visibility],
1093 )
1094 .unwrap_or(Visibility::Public);
1095 self.def_collector.update(
1096 self.module_id,
1097 &[(Some(mac.name.clone()), PerNs::macros(macro_id, vis))],
1098 vis,
1099 ImportType::Named,
1100 );
1101 }
1102 }
1103 }
1104 ModItem::Impl(imp) => { 1086 ModItem::Impl(imp) => {
1105 let module = self.def_collector.def_map.module_id(self.module_id); 1087 let module = self.def_collector.def_map.module_id(self.module_id);
1106 let impl_id = 1088 let impl_id =
@@ -1420,7 +1402,7 @@ impl ModCollector<'_, '_> {
1420 if attrs.by_key("rustc_builtin_macro").exists() { 1402 if attrs.by_key("rustc_builtin_macro").exists() {
1421 let krate = self.def_collector.def_map.krate; 1403 let krate = self.def_collector.def_map.krate;
1422 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { 1404 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) {
1423 self.def_collector.define_macro( 1405 self.def_collector.define_macro_rules(
1424 self.module_id, 1406 self.module_id,
1425 mac.name.clone(), 1407 mac.name.clone(),
1426 macro_id, 1408 macro_id,
@@ -1436,7 +1418,49 @@ impl ModCollector<'_, '_> {
1436 kind: MacroDefKind::Declarative(ast_id), 1418 kind: MacroDefKind::Declarative(ast_id),
1437 local_inner: is_local_inner, 1419 local_inner: is_local_inner,
1438 }; 1420 };
1439 self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, is_export); 1421 self.def_collector.define_macro_rules(
1422 self.module_id,
1423 mac.name.clone(),
1424 macro_id,
1425 is_export,
1426 );
1427 }
1428
1429 fn collect_macro_def(&mut self, id: FileItemTreeId<MacroDef>) {
1430 let krate = self.def_collector.def_map.krate;
1431 let mac = &self.item_tree[id];
1432 let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
1433
1434 // Case 1: bulitin macros
1435 let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
1436 if attrs.by_key("rustc_builtin_macro").exists() {
1437 let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
1438 .or_else(|| find_builtin_derive(&mac.name, krate, ast_id));
1439
1440 if let Some(macro_id) = macro_id {
1441 self.def_collector.define_macro_def(
1442 self.module_id,
1443 mac.name.clone(),
1444 macro_id,
1445 &self.item_tree[mac.visibility],
1446 );
1447 }
1448 return;
1449 }
1450
1451 // Case 2: normal `macro`
1452 let macro_id = MacroDefId {
1453 krate: self.def_collector.def_map.krate,
1454 kind: MacroDefKind::Declarative(ast_id),
1455 local_inner: false,
1456 };
1457
1458 self.def_collector.define_macro_def(
1459 self.module_id,
1460 mac.name.clone(),
1461 macro_id,
1462 &self.item_tree[mac.visibility],
1463 );
1440 } 1464 }
1441 1465
1442 fn collect_macro_call(&mut self, mac: &MacroCall) { 1466 fn collect_macro_call(&mut self, mac: &MacroCall) {
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs
index 6d3cb8d7a..c37f915ab 100644
--- a/crates/hir_def/src/nameres/tests/macros.rs
+++ b/crates/hir_def/src/nameres/tests/macros.rs
@@ -837,3 +837,21 @@ fn collects_derive_helpers() {
837 _ => unreachable!(), 837 _ => unreachable!(),
838 } 838 }
839} 839}
840
841#[test]
842fn resolve_macro_def() {
843 check(
844 r#"
845//- /lib.rs
846pub macro structs($($i:ident),*) {
847 $(struct $i { field: u32 } )*
848}
849structs!(Foo);
850"#,
851 expect![[r#"
852 crate
853 Foo: t
854 structs: m
855 "#]],
856 );
857}