diff options
author | Jonas Schievink <[email protected]> | 2020-12-15 14:37:37 +0000 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2020-12-15 14:37:37 +0000 |
commit | c1cb5953820f26d4d0a614650bc8c50cbc5a3ce6 (patch) | |
tree | 01ba67d97ce6f261154df59b268fe924af9add2a /crates/hir_def/src | |
parent | 39aae835fd70d06092c1be1add6eef3984439529 (diff) |
Move to upstream `macro_rules!` model
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 134 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 19 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 24 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 65 | ||||
-rw-r--r-- | crates/hir_def/src/path/lower.rs | 8 |
5 files changed, 132 insertions, 118 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 6c0de3ee8..bdba4c33e 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -566,66 +566,52 @@ impl ExprCollector<'_> { | |||
566 | syntax_ptr: AstPtr<ast::Expr>, | 566 | syntax_ptr: AstPtr<ast::Expr>, |
567 | mut collector: F, | 567 | mut collector: F, |
568 | ) { | 568 | ) { |
569 | if let Some(name) = e.is_macro_rules().map(|it| it.as_name()) { | 569 | // File containing the macro call. Expansion errors will be attached here. |
570 | let mac = MacroDefId { | 570 | let outer_file = self.expander.current_file_id; |
571 | krate: Some(self.expander.module.krate), | ||
572 | ast_id: Some(self.expander.ast_id(&e)), | ||
573 | kind: MacroDefKind::Declarative, | ||
574 | local_inner: false, | ||
575 | }; | ||
576 | self.body.item_scope.define_legacy_macro(name, mac); | ||
577 | 571 | ||
578 | // FIXME: do we still need to allocate this as missing ? | 572 | let macro_call = self.expander.to_source(AstPtr::new(&e)); |
579 | collector(self, None); | 573 | let res = self.expander.enter_expand(self.db, Some(&self.body.item_scope), e); |
580 | } else { | 574 | |
581 | // File containing the macro call. Expansion errors will be attached here. | 575 | match &res.err { |
582 | let outer_file = self.expander.current_file_id; | 576 | Some(ExpandError::UnresolvedProcMacro) => { |
583 | 577 | self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro( | |
584 | let macro_call = self.expander.to_source(AstPtr::new(&e)); | 578 | UnresolvedProcMacro { |
585 | let res = self.expander.enter_expand(self.db, Some(&self.body.item_scope), e); | ||
586 | |||
587 | match &res.err { | ||
588 | Some(ExpandError::UnresolvedProcMacro) => { | ||
589 | self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro( | ||
590 | UnresolvedProcMacro { | ||
591 | file: outer_file, | ||
592 | node: syntax_ptr.into(), | ||
593 | precise_location: None, | ||
594 | macro_name: None, | ||
595 | }, | ||
596 | )); | ||
597 | } | ||
598 | Some(err) => { | ||
599 | self.source_map.diagnostics.push(BodyDiagnostic::MacroError(MacroError { | ||
600 | file: outer_file, | 579 | file: outer_file, |
601 | node: syntax_ptr.into(), | 580 | node: syntax_ptr.into(), |
602 | message: err.to_string(), | 581 | precise_location: None, |
603 | })); | 582 | macro_name: None, |
604 | } | 583 | }, |
605 | None => {} | 584 | )); |
585 | } | ||
586 | Some(err) => { | ||
587 | self.source_map.diagnostics.push(BodyDiagnostic::MacroError(MacroError { | ||
588 | file: outer_file, | ||
589 | node: syntax_ptr.into(), | ||
590 | message: err.to_string(), | ||
591 | })); | ||
606 | } | 592 | } |
593 | None => {} | ||
594 | } | ||
607 | 595 | ||
608 | match res.value { | 596 | match res.value { |
609 | Some((mark, expansion)) => { | 597 | Some((mark, expansion)) => { |
610 | // FIXME: Statements are too complicated to recover from error for now. | 598 | // FIXME: Statements are too complicated to recover from error for now. |
611 | // It is because we don't have any hygenine for local variable expansion right now. | 599 | // It is because we don't have any hygenine for local variable expansion right now. |
612 | if T::can_cast(syntax::SyntaxKind::MACRO_STMTS) && res.err.is_some() { | 600 | if T::can_cast(syntax::SyntaxKind::MACRO_STMTS) && res.err.is_some() { |
613 | self.expander.exit(self.db, mark); | 601 | self.expander.exit(self.db, mark); |
614 | collector(self, None); | 602 | collector(self, None); |
615 | } else { | 603 | } else { |
616 | self.source_map | 604 | self.source_map.expansions.insert(macro_call, self.expander.current_file_id); |
617 | .expansions | ||
618 | .insert(macro_call, self.expander.current_file_id); | ||
619 | 605 | ||
620 | let item_tree = self.db.item_tree(self.expander.current_file_id); | 606 | let item_tree = self.db.item_tree(self.expander.current_file_id); |
621 | self.item_trees.insert(self.expander.current_file_id, item_tree); | 607 | self.item_trees.insert(self.expander.current_file_id, item_tree); |
622 | 608 | ||
623 | collector(self, Some(expansion)); | 609 | let id = collector(self, Some(expansion)); |
624 | self.expander.exit(self.db, mark); | 610 | self.expander.exit(self.db, mark); |
625 | } | 611 | id |
626 | } | 612 | } |
627 | None => collector(self, None), | ||
628 | } | 613 | } |
614 | None => collector(self, None), | ||
629 | } | 615 | } |
630 | } | 616 | } |
631 | 617 | ||
@@ -785,26 +771,44 @@ impl ExprCollector<'_> { | |||
785 | | ast::Item::ExternCrate(_) | 771 | | ast::Item::ExternCrate(_) |
786 | | ast::Item::Module(_) | 772 | | ast::Item::Module(_) |
787 | | ast::Item::MacroCall(_) => return None, | 773 | | ast::Item::MacroCall(_) => return None, |
774 | ast::Item::MacroRules(def) => { | ||
775 | return Some(Either::Right(def)); | ||
776 | } | ||
788 | }; | 777 | }; |
789 | 778 | ||
790 | Some((def, name)) | 779 | Some(Either::Left((def, name))) |
791 | }) | 780 | }) |
792 | .collect::<Vec<_>>(); | 781 | .collect::<Vec<_>>(); |
793 | 782 | ||
794 | for (def, name) in items { | 783 | for either in items { |
795 | self.body.item_scope.define_def(def); | 784 | match either { |
796 | if let Some(name) = name { | 785 | Either::Left((def, name)) => { |
797 | let vis = crate::visibility::Visibility::Public; // FIXME determine correctly | 786 | self.body.item_scope.define_def(def); |
798 | let has_constructor = match def { | 787 | if let Some(name) = name { |
799 | ModuleDefId::AdtId(AdtId::StructId(s)) => { | 788 | let vis = crate::visibility::Visibility::Public; // FIXME determine correctly |
800 | self.db.struct_data(s).variant_data.kind() != StructKind::Record | 789 | let has_constructor = match def { |
790 | ModuleDefId::AdtId(AdtId::StructId(s)) => { | ||
791 | self.db.struct_data(s).variant_data.kind() != StructKind::Record | ||
792 | } | ||
793 | _ => true, | ||
794 | }; | ||
795 | self.body.item_scope.push_res( | ||
796 | name.as_name(), | ||
797 | crate::per_ns::PerNs::from_def(def, vis, has_constructor), | ||
798 | ); | ||
801 | } | 799 | } |
802 | _ => true, | 800 | } |
803 | }; | 801 | Either::Right(e) => { |
804 | self.body.item_scope.push_res( | 802 | let mac = MacroDefId { |
805 | name.as_name(), | 803 | krate: Some(self.expander.module.krate), |
806 | crate::per_ns::PerNs::from_def(def, vis, has_constructor), | 804 | ast_id: Some(self.expander.ast_id(&e)), |
807 | ); | 805 | kind: MacroDefKind::Declarative, |
806 | local_inner: false, | ||
807 | }; | ||
808 | if let Some(name) = e.name() { | ||
809 | self.body.item_scope.define_legacy_macro(name.as_name(), mac); | ||
810 | } | ||
811 | } | ||
808 | } | 812 | } |
809 | } | 813 | } |
810 | } | 814 | } |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 864fad170..1c9babf37 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -142,6 +142,7 @@ impl ItemTree { | |||
142 | type_aliases, | 142 | type_aliases, |
143 | mods, | 143 | mods, |
144 | macro_calls, | 144 | macro_calls, |
145 | macro_rules, | ||
145 | exprs, | 146 | exprs, |
146 | vis, | 147 | vis, |
147 | generics, | 148 | generics, |
@@ -162,6 +163,7 @@ impl ItemTree { | |||
162 | type_aliases.shrink_to_fit(); | 163 | type_aliases.shrink_to_fit(); |
163 | mods.shrink_to_fit(); | 164 | mods.shrink_to_fit(); |
164 | macro_calls.shrink_to_fit(); | 165 | macro_calls.shrink_to_fit(); |
166 | macro_rules.shrink_to_fit(); | ||
165 | exprs.shrink_to_fit(); | 167 | exprs.shrink_to_fit(); |
166 | 168 | ||
167 | vis.arena.shrink_to_fit(); | 169 | vis.arena.shrink_to_fit(); |
@@ -280,6 +282,7 @@ struct ItemTreeData { | |||
280 | type_aliases: Arena<TypeAlias>, | 282 | type_aliases: Arena<TypeAlias>, |
281 | mods: Arena<Mod>, | 283 | mods: Arena<Mod>, |
282 | macro_calls: Arena<MacroCall>, | 284 | macro_calls: Arena<MacroCall>, |
285 | macro_rules: Arena<MacroRules>, | ||
283 | exprs: Arena<Expr>, | 286 | exprs: Arena<Expr>, |
284 | 287 | ||
285 | vis: ItemVisibilities, | 288 | vis: ItemVisibilities, |
@@ -427,6 +430,7 @@ mod_items! { | |||
427 | TypeAlias in type_aliases -> ast::TypeAlias, | 430 | TypeAlias in type_aliases -> ast::TypeAlias, |
428 | Mod in mods -> ast::Module, | 431 | Mod in mods -> ast::Module, |
429 | MacroCall in macro_calls -> ast::MacroCall, | 432 | MacroCall in macro_calls -> ast::MacroCall, |
433 | MacroRules in macro_rules -> ast::MacroRules, | ||
430 | } | 434 | } |
431 | 435 | ||
432 | macro_rules! impl_index { | 436 | macro_rules! impl_index { |
@@ -629,17 +633,22 @@ pub enum ModKind { | |||
629 | 633 | ||
630 | #[derive(Debug, Clone, Eq, PartialEq)] | 634 | #[derive(Debug, Clone, Eq, PartialEq)] |
631 | pub struct MacroCall { | 635 | pub struct MacroCall { |
632 | /// For `macro_rules!` declarations, this is the name of the declared macro. | ||
633 | pub name: Option<Name>, | ||
634 | /// Path to the called macro. | 636 | /// Path to the called macro. |
635 | pub path: ModPath, | 637 | pub path: ModPath, |
638 | pub ast_id: FileAstId<ast::MacroCall>, | ||
639 | } | ||
640 | |||
641 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
642 | pub struct MacroRules { | ||
643 | /// For `macro_rules!` declarations, this is the name of the declared macro. | ||
644 | pub name: Name, | ||
636 | /// Has `#[macro_export]`. | 645 | /// Has `#[macro_export]`. |
637 | pub is_export: bool, | 646 | pub is_export: bool, |
638 | /// Has `#[macro_export(local_inner_macros)]`. | 647 | /// Has `#[macro_export(local_inner_macros)]`. |
639 | pub is_local_inner: bool, | 648 | pub is_local_inner: bool, |
640 | /// Has `#[rustc_builtin_macro]`. | 649 | /// Has `#[rustc_builtin_macro]`. |
641 | pub is_builtin: bool, | 650 | pub is_builtin: bool, |
642 | pub ast_id: FileAstId<ast::MacroCall>, | 651 | pub ast_id: FileAstId<ast::MacroRules>, |
643 | } | 652 | } |
644 | 653 | ||
645 | // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array | 654 | // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array |
@@ -670,7 +679,8 @@ impl ModItem { | |||
670 | | ModItem::Static(_) | 679 | | ModItem::Static(_) |
671 | | ModItem::Trait(_) | 680 | | ModItem::Trait(_) |
672 | | ModItem::Impl(_) | 681 | | ModItem::Impl(_) |
673 | | ModItem::Mod(_) => None, | 682 | | ModItem::Mod(_) |
683 | | ModItem::MacroRules(_) => None, | ||
674 | ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), | 684 | ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), |
675 | ModItem::Const(konst) => Some(AssocItem::Const(*konst)), | 685 | ModItem::Const(konst) => Some(AssocItem::Const(*konst)), |
676 | ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), | 686 | ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), |
@@ -697,6 +707,7 @@ impl ModItem { | |||
697 | ModItem::TypeAlias(it) => tree[it.index].ast_id().upcast(), | 707 | ModItem::TypeAlias(it) => tree[it.index].ast_id().upcast(), |
698 | ModItem::Mod(it) => tree[it.index].ast_id().upcast(), | 708 | ModItem::Mod(it) => tree[it.index].ast_id().upcast(), |
699 | ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(), | 709 | ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(), |
710 | ModItem::MacroRules(it) => tree[it.index].ast_id().upcast(), | ||
700 | } | 711 | } |
701 | } | 712 | } |
702 | } | 713 | } |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 2939c6b1e..b39d7fb7a 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -84,8 +84,7 @@ impl Ctx { | |||
84 | | ast::Item::Fn(_) | 84 | | ast::Item::Fn(_) |
85 | | ast::Item::TypeAlias(_) | 85 | | ast::Item::TypeAlias(_) |
86 | | ast::Item::Const(_) | 86 | | ast::Item::Const(_) |
87 | | ast::Item::Static(_) | 87 | | ast::Item::Static(_) => { |
88 | | ast::Item::MacroCall(_) => { | ||
89 | // Skip this if we're already collecting inner items. We'll descend into all nodes | 88 | // Skip this if we're already collecting inner items. We'll descend into all nodes |
90 | // already. | 89 | // already. |
91 | if !inner { | 90 | if !inner { |
@@ -98,7 +97,11 @@ impl Ctx { | |||
98 | ast::Item::Trait(_) | ast::Item::Impl(_) | ast::Item::ExternBlock(_) => {} | 97 | ast::Item::Trait(_) | ast::Item::Impl(_) | ast::Item::ExternBlock(_) => {} |
99 | 98 | ||
100 | // These don't have inner items. | 99 | // These don't have inner items. |
101 | ast::Item::Module(_) | ast::Item::ExternCrate(_) | ast::Item::Use(_) => {} | 100 | ast::Item::Module(_) |
101 | | ast::Item::ExternCrate(_) | ||
102 | | ast::Item::Use(_) | ||
103 | | ast::Item::MacroCall(_) | ||
104 | | ast::Item::MacroRules(_) => {} | ||
102 | }; | 105 | }; |
103 | 106 | ||
104 | let attrs = Attrs::new(item, &self.hygiene); | 107 | let attrs = Attrs::new(item, &self.hygiene); |
@@ -118,6 +121,7 @@ impl Ctx { | |||
118 | )), | 121 | )), |
119 | ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast).map(Into::into), | 122 | ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast).map(Into::into), |
120 | ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), | 123 | 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), | ||
121 | ast::Item::ExternBlock(ast) => { | 125 | ast::Item::ExternBlock(ast) => { |
122 | Some(ModItems(self.lower_extern_block(ast).into_iter().collect::<SmallVec<_>>())) | 126 | Some(ModItems(self.lower_extern_block(ast).into_iter().collect::<SmallVec<_>>())) |
123 | } | 127 | } |
@@ -525,9 +529,15 @@ impl Ctx { | |||
525 | } | 529 | } |
526 | 530 | ||
527 | fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> { | 531 | fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> { |
528 | let name = m.name().map(|it| it.as_name()); | ||
529 | let attrs = Attrs::new(m, &self.hygiene); | ||
530 | let path = ModPath::from_src(m.path()?, &self.hygiene)?; | 532 | let path = ModPath::from_src(m.path()?, &self.hygiene)?; |
533 | let ast_id = self.source_ast_id_map.ast_id(m); | ||
534 | let res = MacroCall { path, ast_id }; | ||
535 | Some(id(self.data().macro_calls.alloc(res))) | ||
536 | } | ||
537 | |||
538 | fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> { | ||
539 | let name = m.name().map(|it| it.as_name())?; | ||
540 | let attrs = Attrs::new(m, &self.hygiene); | ||
531 | 541 | ||
532 | let ast_id = self.source_ast_id_map.ast_id(m); | 542 | let ast_id = self.source_ast_id_map.ast_id(m); |
533 | 543 | ||
@@ -547,8 +557,8 @@ impl Ctx { | |||
547 | }; | 557 | }; |
548 | 558 | ||
549 | let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); | 559 | let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); |
550 | let res = MacroCall { name, path, is_export, is_builtin, is_local_inner, ast_id }; | 560 | let res = MacroRules { name, is_export, is_builtin, is_local_inner, ast_id }; |
551 | Some(id(self.data().macro_calls.alloc(res))) | 561 | Some(id(self.data().macro_rules.alloc(res))) |
552 | } | 562 | } |
553 | 563 | ||
554 | fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<ModItem> { | 564 | fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<ModItem> { |
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}; |
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index 60fa7646b..609925012 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs | |||
@@ -122,11 +122,9 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> | |||
122 | // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 | 122 | // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 |
123 | // We follow what it did anyway :) | 123 | // We follow what it did anyway :) |
124 | if segments.len() == 1 && kind == PathKind::Plain { | 124 | if segments.len() == 1 && kind == PathKind::Plain { |
125 | if let Some(macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { | 125 | if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { |
126 | if macro_call.is_bang() { | 126 | if let Some(crate_id) = hygiene.local_inner_macros() { |
127 | if let Some(crate_id) = hygiene.local_inner_macros() { | 127 | kind = PathKind::DollarCrate(crate_id); |
128 | kind = PathKind::DollarCrate(crate_id); | ||
129 | } | ||
130 | } | 128 | } |
131 | } | 129 | } |
132 | } | 130 | } |