diff options
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 5 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 20 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 16 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 29 |
4 files changed, 65 insertions, 5 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index bdba4c33e..e4bf5603c 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -772,7 +772,10 @@ impl ExprCollector<'_> { | |||
772 | | ast::Item::Module(_) | 772 | | ast::Item::Module(_) |
773 | | ast::Item::MacroCall(_) => return None, | 773 | | ast::Item::MacroCall(_) => return None, |
774 | ast::Item::MacroRules(def) => { | 774 | ast::Item::MacroRules(def) => { |
775 | return Some(Either::Right(def)); | 775 | return Some(Either::Right(ast::Macro::from(def))); |
776 | } | ||
777 | ast::Item::MacroDef(def) => { | ||
778 | return Some(Either::Right(ast::Macro::from(def))); | ||
776 | } | 779 | } |
777 | }; | 780 | }; |
778 | 781 | ||
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 1c9babf37..8cd0b18cc 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -143,6 +143,7 @@ impl ItemTree { | |||
143 | mods, | 143 | mods, |
144 | macro_calls, | 144 | macro_calls, |
145 | macro_rules, | 145 | macro_rules, |
146 | macro_defs, | ||
146 | exprs, | 147 | exprs, |
147 | vis, | 148 | vis, |
148 | generics, | 149 | generics, |
@@ -164,6 +165,7 @@ impl ItemTree { | |||
164 | mods.shrink_to_fit(); | 165 | mods.shrink_to_fit(); |
165 | macro_calls.shrink_to_fit(); | 166 | macro_calls.shrink_to_fit(); |
166 | macro_rules.shrink_to_fit(); | 167 | macro_rules.shrink_to_fit(); |
168 | macro_defs.shrink_to_fit(); | ||
167 | exprs.shrink_to_fit(); | 169 | exprs.shrink_to_fit(); |
168 | 170 | ||
169 | vis.arena.shrink_to_fit(); | 171 | vis.arena.shrink_to_fit(); |
@@ -283,6 +285,7 @@ struct ItemTreeData { | |||
283 | mods: Arena<Mod>, | 285 | mods: Arena<Mod>, |
284 | macro_calls: Arena<MacroCall>, | 286 | macro_calls: Arena<MacroCall>, |
285 | macro_rules: Arena<MacroRules>, | 287 | macro_rules: Arena<MacroRules>, |
288 | macro_defs: Arena<MacroDef>, | ||
286 | exprs: Arena<Expr>, | 289 | exprs: Arena<Expr>, |
287 | 290 | ||
288 | vis: ItemVisibilities, | 291 | vis: ItemVisibilities, |
@@ -431,6 +434,7 @@ mod_items! { | |||
431 | Mod in mods -> ast::Module, | 434 | Mod in mods -> ast::Module, |
432 | MacroCall in macro_calls -> ast::MacroCall, | 435 | MacroCall in macro_calls -> ast::MacroCall, |
433 | MacroRules in macro_rules -> ast::MacroRules, | 436 | MacroRules in macro_rules -> ast::MacroRules, |
437 | MacroDef in macro_defs -> ast::MacroDef, | ||
434 | } | 438 | } |
435 | 439 | ||
436 | macro_rules! impl_index { | 440 | macro_rules! impl_index { |
@@ -640,7 +644,7 @@ pub struct MacroCall { | |||
640 | 644 | ||
641 | #[derive(Debug, Clone, Eq, PartialEq)] | 645 | #[derive(Debug, Clone, Eq, PartialEq)] |
642 | pub struct MacroRules { | 646 | pub struct MacroRules { |
643 | /// For `macro_rules!` declarations, this is the name of the declared macro. | 647 | /// The name of the declared macro. |
644 | pub name: Name, | 648 | pub name: Name, |
645 | /// Has `#[macro_export]`. | 649 | /// Has `#[macro_export]`. |
646 | pub is_export: bool, | 650 | pub is_export: bool, |
@@ -651,6 +655,16 @@ pub struct MacroRules { | |||
651 | pub ast_id: FileAstId<ast::MacroRules>, | 655 | pub ast_id: FileAstId<ast::MacroRules>, |
652 | } | 656 | } |
653 | 657 | ||
658 | /// "Macros 2.0" macro definition. | ||
659 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
660 | pub struct MacroDef { | ||
661 | pub name: Name, | ||
662 | pub visibility: RawVisibilityId, | ||
663 | /// Has `#[rustc_builtin_macro]`. | ||
664 | pub is_builtin: bool, | ||
665 | pub ast_id: FileAstId<ast::MacroDef>, | ||
666 | } | ||
667 | |||
654 | // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array | 668 | // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array |
655 | // lengths, but we don't do much with them yet. | 669 | // lengths, but we don't do much with them yet. |
656 | #[derive(Debug, Clone, Eq, PartialEq)] | 670 | #[derive(Debug, Clone, Eq, PartialEq)] |
@@ -680,7 +694,8 @@ impl ModItem { | |||
680 | | ModItem::Trait(_) | 694 | | ModItem::Trait(_) |
681 | | ModItem::Impl(_) | 695 | | ModItem::Impl(_) |
682 | | ModItem::Mod(_) | 696 | | ModItem::Mod(_) |
683 | | ModItem::MacroRules(_) => None, | 697 | | ModItem::MacroRules(_) |
698 | | ModItem::MacroDef(_) => None, | ||
684 | ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), | 699 | ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), |
685 | ModItem::Const(konst) => Some(AssocItem::Const(*konst)), | 700 | ModItem::Const(konst) => Some(AssocItem::Const(*konst)), |
686 | ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), | 701 | ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), |
@@ -708,6 +723,7 @@ impl ModItem { | |||
708 | ModItem::Mod(it) => tree[it.index].ast_id().upcast(), | 723 | ModItem::Mod(it) => tree[it.index].ast_id().upcast(), |
709 | ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(), | 724 | ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(), |
710 | ModItem::MacroRules(it) => tree[it.index].ast_id().upcast(), | 725 | ModItem::MacroRules(it) => tree[it.index].ast_id().upcast(), |
726 | ModItem::MacroDef(it) => tree[it.index].ast_id().upcast(), | ||
711 | } | 727 | } |
712 | } | 728 | } |
713 | } | 729 | } |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index b39d7fb7a..1dc06a211 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -101,7 +101,8 @@ impl Ctx { | |||
101 | | ast::Item::ExternCrate(_) | 101 | | ast::Item::ExternCrate(_) |
102 | | ast::Item::Use(_) | 102 | | ast::Item::Use(_) |
103 | | ast::Item::MacroCall(_) | 103 | | ast::Item::MacroCall(_) |
104 | | ast::Item::MacroRules(_) => {} | 104 | | ast::Item::MacroRules(_) |
105 | | ast::Item::MacroDef(_) => {} | ||
105 | }; | 106 | }; |
106 | 107 | ||
107 | let attrs = Attrs::new(item, &self.hygiene); | 108 | let attrs = Attrs::new(item, &self.hygiene); |
@@ -122,6 +123,7 @@ impl Ctx { | |||
122 | ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast).map(Into::into), | 123 | ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast).map(Into::into), |
123 | ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), | 124 | ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), |
124 | ast::Item::MacroRules(ast) => self.lower_macro_rules(ast).map(Into::into), | 125 | ast::Item::MacroRules(ast) => self.lower_macro_rules(ast).map(Into::into), |
126 | ast::Item::MacroDef(ast) => self.lower_macro_def(ast).map(Into::into), | ||
125 | ast::Item::ExternBlock(ast) => { | 127 | ast::Item::ExternBlock(ast) => { |
126 | Some(ModItems(self.lower_extern_block(ast).into_iter().collect::<SmallVec<_>>())) | 128 | Some(ModItems(self.lower_extern_block(ast).into_iter().collect::<SmallVec<_>>())) |
127 | } | 129 | } |
@@ -561,6 +563,18 @@ impl Ctx { | |||
561 | Some(id(self.data().macro_rules.alloc(res))) | 563 | Some(id(self.data().macro_rules.alloc(res))) |
562 | } | 564 | } |
563 | 565 | ||
566 | fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<MacroDef>> { | ||
567 | let name = m.name().map(|it| it.as_name())?; | ||
568 | let attrs = Attrs::new(m, &self.hygiene); | ||
569 | |||
570 | let ast_id = self.source_ast_id_map.ast_id(m); | ||
571 | let visibility = self.lower_visibility(m); | ||
572 | |||
573 | let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); | ||
574 | let res = MacroDef { name, is_builtin, ast_id, visibility }; | ||
575 | Some(id(self.data().macro_defs.alloc(res))) | ||
576 | } | ||
577 | |||
564 | fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<ModItem> { | 578 | fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<ModItem> { |
565 | block.extern_item_list().map_or(Vec::new(), |list| { | 579 | block.extern_item_list().map_or(Vec::new(), |list| { |
566 | list.extern_items() | 580 | list.extern_items() |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 85cc342c4..c2f741060 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -976,6 +976,33 @@ impl ModCollector<'_, '_> { | |||
976 | } | 976 | } |
977 | ModItem::MacroCall(mac) => self.collect_macro_call(&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]), | 978 | ModItem::MacroRules(mac) => self.collect_macro_rules(&self.item_tree[mac]), |
979 | ModItem::MacroDef(id) => { | ||
980 | let mac = &self.item_tree[id]; | ||
981 | let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); | ||
982 | |||
983 | // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it | ||
984 | // to define builtin macros, so we support at least that part. | ||
985 | if mac.is_builtin { | ||
986 | let krate = self.def_collector.def_map.krate; | ||
987 | if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { | ||
988 | let vis = self | ||
989 | .def_collector | ||
990 | .def_map | ||
991 | .resolve_visibility( | ||
992 | self.def_collector.db, | ||
993 | self.module_id, | ||
994 | &self.item_tree[mac.visibility], | ||
995 | ) | ||
996 | .unwrap_or(Visibility::Public); | ||
997 | self.def_collector.update( | ||
998 | self.module_id, | ||
999 | &[(Some(mac.name.clone()), PerNs::macros(macro_id, vis))], | ||
1000 | vis, | ||
1001 | ImportType::Named, | ||
1002 | ); | ||
1003 | } | ||
1004 | } | ||
1005 | } | ||
979 | ModItem::Impl(imp) => { | 1006 | ModItem::Impl(imp) => { |
980 | let module = ModuleId { | 1007 | let module = ModuleId { |
981 | krate: self.def_collector.def_map.krate, | 1008 | krate: self.def_collector.def_map.krate, |
@@ -1280,7 +1307,7 @@ impl ModCollector<'_, '_> { | |||
1280 | } | 1307 | } |
1281 | 1308 | ||
1282 | fn collect_macro_rules(&mut self, mac: &MacroRules) { | 1309 | fn collect_macro_rules(&mut self, mac: &MacroRules) { |
1283 | let ast_id = InFile::new(self.file_id, mac.ast_id); | 1310 | let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); |
1284 | 1311 | ||
1285 | // Case 1: builtin macros | 1312 | // Case 1: builtin macros |
1286 | if mac.is_builtin { | 1313 | if mac.is_builtin { |