diff options
Diffstat (limited to 'crates')
34 files changed, 328 insertions, 270 deletions
diff --git a/crates/completion/src/render/macro_.rs b/crates/completion/src/render/macro_.rs index eb3209bee..6cfbd6c9b 100644 --- a/crates/completion/src/render/macro_.rs +++ b/crates/completion/src/render/macro_.rs | |||
@@ -144,7 +144,7 @@ mod tests { | |||
144 | use foo::<|>; | 144 | use foo::<|>; |
145 | //- /foo/lib.rs crate:foo | 145 | //- /foo/lib.rs crate:foo |
146 | #[macro_export] | 146 | #[macro_export] |
147 | macro_rules frobnicate { () => () } | 147 | macro_rules! frobnicate { () => () } |
148 | "#, | 148 | "#, |
149 | r#" | 149 | r#" |
150 | use foo::frobnicate; | 150 | use foo::frobnicate; |
@@ -154,11 +154,11 @@ use foo::frobnicate; | |||
154 | check_edit( | 154 | check_edit( |
155 | "frobnicate!", | 155 | "frobnicate!", |
156 | r#" | 156 | r#" |
157 | macro_rules frobnicate { () => () } | 157 | macro_rules! frobnicate { () => () } |
158 | fn main() { frob<|>!(); } | 158 | fn main() { frob<|>!(); } |
159 | "#, | 159 | "#, |
160 | r#" | 160 | r#" |
161 | macro_rules frobnicate { () => () } | 161 | macro_rules! frobnicate { () => () } |
162 | fn main() { frobnicate!(); } | 162 | fn main() { frobnicate!(); } |
163 | "#, | 163 | "#, |
164 | ); | 164 | ); |
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index 1e64a1614..107ad0690 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs | |||
@@ -110,8 +110,8 @@ impl HasSource for TypeAlias { | |||
110 | } | 110 | } |
111 | } | 111 | } |
112 | impl HasSource for MacroDef { | 112 | impl HasSource for MacroDef { |
113 | type Ast = ast::MacroCall; | 113 | type Ast = ast::MacroRules; |
114 | fn source(self, db: &dyn HirDatabase) -> InFile<ast::MacroCall> { | 114 | fn source(self, db: &dyn HirDatabase) -> InFile<ast::MacroRules> { |
115 | InFile { | 115 | InFile { |
116 | file_id: self.id.ast_id.expect("MacroDef without ast_id").file_id, | 116 | file_id: self.id.ast_id.expect("MacroDef without ast_id").file_id, |
117 | value: self.id.ast_id.expect("MacroDef without ast_id").to_node(db.upcast()), | 117 | value: self.id.ast_id.expect("MacroDef without ast_id").to_node(db.upcast()), |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index e4fc21ced..5959ac4ca 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -723,7 +723,7 @@ to_def_impls![ | |||
723 | (crate::EnumVariant, ast::Variant, enum_variant_to_def), | 723 | (crate::EnumVariant, ast::Variant, enum_variant_to_def), |
724 | (crate::TypeParam, ast::TypeParam, type_param_to_def), | 724 | (crate::TypeParam, ast::TypeParam, type_param_to_def), |
725 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), | 725 | (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), |
726 | (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros | 726 | (crate::MacroDef, ast::MacroRules, macro_rules_to_def), |
727 | (crate::Local, ast::IdentPat, bind_pat_to_def), | 727 | (crate::Local, ast::IdentPat, bind_pat_to_def), |
728 | ]; | 728 | ]; |
729 | 729 | ||
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index badcf0ae8..a333d7aea 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs | |||
@@ -149,7 +149,10 @@ impl SourceToDefCtx<'_, '_> { | |||
149 | } | 149 | } |
150 | 150 | ||
151 | // FIXME: use DynMap as well? | 151 | // FIXME: use DynMap as well? |
152 | pub(super) fn macro_call_to_def(&mut self, src: InFile<ast::MacroCall>) -> Option<MacroDefId> { | 152 | pub(super) fn macro_rules_to_def( |
153 | &mut self, | ||
154 | src: InFile<ast::MacroRules>, | ||
155 | ) -> Option<MacroDefId> { | ||
153 | let kind = MacroDefKind::Declarative; | 156 | let kind = MacroDefKind::Declarative; |
154 | let file_id = src.file_id.original_file(self.db.upcast()); | 157 | let file_id = src.file_id.original_file(self.db.upcast()); |
155 | let krate = self.file_to_def(file_id)?.krate; | 158 | let krate = self.file_to_def(file_id)?.krate; |
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 | } |
diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs index b1b432ded..bd9223825 100644 --- a/crates/hir_expand/src/builtin_macro.rs +++ b/crates/hir_expand/src/builtin_macro.rs | |||
@@ -63,7 +63,7 @@ macro_rules! register_builtin { | |||
63 | pub fn find_builtin_macro( | 63 | pub fn find_builtin_macro( |
64 | ident: &name::Name, | 64 | ident: &name::Name, |
65 | krate: CrateId, | 65 | krate: CrateId, |
66 | ast_id: AstId<ast::MacroCall>, | 66 | ast_id: AstId<ast::MacroRules>, |
67 | ) -> Option<MacroDefId> { | 67 | ) -> Option<MacroDefId> { |
68 | let kind = find_by_name(ident)?; | 68 | let kind = find_by_name(ident)?; |
69 | 69 | ||
@@ -515,12 +515,16 @@ mod tests { | |||
515 | fn expand_builtin_macro(ra_fixture: &str) -> String { | 515 | fn expand_builtin_macro(ra_fixture: &str) -> String { |
516 | let (db, file_id) = TestDB::with_single_file(&ra_fixture); | 516 | let (db, file_id) = TestDB::with_single_file(&ra_fixture); |
517 | let parsed = db.parse(file_id); | 517 | let parsed = db.parse(file_id); |
518 | let macro_rules: Vec<_> = | ||
519 | parsed.syntax_node().descendants().filter_map(ast::MacroRules::cast).collect(); | ||
518 | let macro_calls: Vec<_> = | 520 | let macro_calls: Vec<_> = |
519 | parsed.syntax_node().descendants().filter_map(ast::MacroCall::cast).collect(); | 521 | parsed.syntax_node().descendants().filter_map(ast::MacroCall::cast).collect(); |
520 | 522 | ||
521 | let ast_id_map = db.ast_id_map(file_id.into()); | 523 | let ast_id_map = db.ast_id_map(file_id.into()); |
522 | 524 | ||
523 | let expander = find_by_name(¯o_calls[0].name().unwrap().as_name()).unwrap(); | 525 | assert_eq!(macro_rules.len(), 1, "test must contain exactly 1 `macro_rules!`"); |
526 | assert_eq!(macro_calls.len(), 1, "test must contain exactly 1 macro call"); | ||
527 | let expander = find_by_name(¯o_rules[0].name().unwrap().as_name()).unwrap(); | ||
524 | 528 | ||
525 | let krate = CrateId(0); | 529 | let krate = CrateId(0); |
526 | let file_id = match expander { | 530 | let file_id = match expander { |
@@ -528,7 +532,7 @@ mod tests { | |||
528 | // the first one should be a macro_rules | 532 | // the first one should be a macro_rules |
529 | let def = MacroDefId { | 533 | let def = MacroDefId { |
530 | krate: Some(CrateId(0)), | 534 | krate: Some(CrateId(0)), |
531 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), | 535 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules[0]))), |
532 | kind: MacroDefKind::BuiltIn(expander), | 536 | kind: MacroDefKind::BuiltIn(expander), |
533 | local_inner: false, | 537 | local_inner: false, |
534 | }; | 538 | }; |
@@ -538,7 +542,7 @@ mod tests { | |||
538 | krate, | 542 | krate, |
539 | kind: MacroCallKind::FnLike(AstId::new( | 543 | kind: MacroCallKind::FnLike(AstId::new( |
540 | file_id.into(), | 544 | file_id.into(), |
541 | ast_id_map.ast_id(¯o_calls[1]), | 545 | ast_id_map.ast_id(¯o_calls[0]), |
542 | )), | 546 | )), |
543 | }; | 547 | }; |
544 | 548 | ||
@@ -549,12 +553,12 @@ mod tests { | |||
549 | // the first one should be a macro_rules | 553 | // the first one should be a macro_rules |
550 | let def = MacroDefId { | 554 | let def = MacroDefId { |
551 | krate: Some(krate), | 555 | krate: Some(krate), |
552 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), | 556 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules[0]))), |
553 | kind: MacroDefKind::BuiltInEager(expander), | 557 | kind: MacroDefKind::BuiltInEager(expander), |
554 | local_inner: false, | 558 | local_inner: false, |
555 | }; | 559 | }; |
556 | 560 | ||
557 | let args = macro_calls[1].token_tree().unwrap(); | 561 | let args = macro_calls[0].token_tree().unwrap(); |
558 | let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0; | 562 | let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0; |
559 | 563 | ||
560 | let arg_id = db.intern_eager_expansion({ | 564 | let arg_id = db.intern_eager_expansion({ |
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 1a9428514..ae3086a95 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs | |||
@@ -228,7 +228,7 @@ pub struct MacroDefId { | |||
228 | // (which will probably require touching this code), we can instead use | 228 | // (which will probably require touching this code), we can instead use |
229 | // that (and also remove the hacks for resolving built-in derives). | 229 | // that (and also remove the hacks for resolving built-in derives). |
230 | pub krate: Option<CrateId>, | 230 | pub krate: Option<CrateId>, |
231 | pub ast_id: Option<AstId<ast::MacroCall>>, | 231 | pub ast_id: Option<AstId<ast::MacroRules>>, |
232 | pub kind: MacroDefKind, | 232 | pub kind: MacroDefKind, |
233 | 233 | ||
234 | pub local_inner: bool, | 234 | pub local_inner: bool, |
diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs index 597a195d0..de97ec3c2 100644 --- a/crates/hir_ty/src/tests/macros.rs +++ b/crates/hir_ty/src/tests/macros.rs | |||
@@ -413,7 +413,6 @@ fn infer_local_macro() { | |||
413 | expect![[r#" | 413 | expect![[r#" |
414 | !0..6 '1usize': usize | 414 | !0..6 '1usize': usize |
415 | 10..89 '{ ...!(); }': () | 415 | 10..89 '{ ...!(); }': () |
416 | 16..65 'macro_... }': {unknown} | ||
417 | 74..76 '_a': usize | 416 | 74..76 '_a': usize |
418 | "#]], | 417 | "#]], |
419 | ); | 418 | ); |
diff --git a/crates/ide/src/file_structure.rs b/crates/ide/src/file_structure.rs index 415795e8c..c51531391 100644 --- a/crates/ide/src/file_structure.rs +++ b/crates/ide/src/file_structure.rs | |||
@@ -150,13 +150,7 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> { | |||
150 | }; | 150 | }; |
151 | Some(node) | 151 | Some(node) |
152 | }, | 152 | }, |
153 | ast::MacroCall(it) => { | 153 | ast::MacroRules(it) => decl(it), |
154 | match it.path().and_then(|it| it.segment()).and_then(|it| it.name_ref()) { | ||
155 | Some(path_segment) if path_segment.text() == "macro_rules" | ||
156 | => decl(it), | ||
157 | _ => None, | ||
158 | } | ||
159 | }, | ||
160 | _ => None, | 154 | _ => None, |
161 | } | 155 | } |
162 | } | 156 | } |
@@ -380,7 +374,7 @@ fn very_obsolete() {} | |||
380 | label: "mc", | 374 | label: "mc", |
381 | navigation_range: 284..286, | 375 | navigation_range: 284..286, |
382 | node_range: 271..303, | 376 | node_range: 271..303, |
383 | kind: MACRO_CALL, | 377 | kind: MACRO_RULES, |
384 | detail: None, | 378 | detail: None, |
385 | deprecated: false, | 379 | deprecated: false, |
386 | }, | 380 | }, |
@@ -389,7 +383,7 @@ fn very_obsolete() {} | |||
389 | label: "mcexp", | 383 | label: "mcexp", |
390 | navigation_range: 334..339, | 384 | navigation_range: 334..339, |
391 | node_range: 305..356, | 385 | node_range: 305..356, |
392 | kind: MACRO_CALL, | 386 | kind: MACRO_RULES, |
393 | detail: None, | 387 | detail: None, |
394 | deprecated: false, | 388 | deprecated: false, |
395 | }, | 389 | }, |
@@ -398,7 +392,7 @@ fn very_obsolete() {} | |||
398 | label: "mcexp", | 392 | label: "mcexp", |
399 | navigation_range: 387..392, | 393 | navigation_range: 387..392, |
400 | node_range: 358..409, | 394 | node_range: 358..409, |
401 | kind: MACRO_CALL, | 395 | kind: MACRO_RULES, |
402 | detail: None, | 396 | detail: None, |
403 | deprecated: false, | 397 | deprecated: false, |
404 | }, | 398 | }, |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 66f0f7950..675957fff 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -770,7 +770,7 @@ fn foo() { | |||
770 | } | 770 | } |
771 | "#, | 771 | "#, |
772 | expect![[r#" | 772 | expect![[r#" |
773 | m1 MACRO_CALL FileId(0) 0..46 29..31 Other | 773 | m1 MACRO_RULES FileId(0) 0..46 29..31 Other |
774 | 774 | ||
775 | FileId(0) 63..65 StructLiteral | 775 | FileId(0) 63..65 StructLiteral |
776 | FileId(0) 73..75 StructLiteral | 776 | FileId(0) 73..75 StructLiteral |
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index f5c6eabef..990b0f7d9 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -74,6 +74,7 @@ pub(crate) fn highlight( | |||
74 | let mut stack = HighlightedRangeStack::new(); | 74 | let mut stack = HighlightedRangeStack::new(); |
75 | 75 | ||
76 | let mut current_macro_call: Option<ast::MacroCall> = None; | 76 | let mut current_macro_call: Option<ast::MacroCall> = None; |
77 | let mut current_macro_rules: Option<ast::MacroRules> = None; | ||
77 | let mut format_string_highlighter = FormatStringHighlighter::default(); | 78 | let mut format_string_highlighter = FormatStringHighlighter::default(); |
78 | let mut macro_rules_highlighter = MacroRulesHighlighter::default(); | 79 | let mut macro_rules_highlighter = MacroRulesHighlighter::default(); |
79 | let mut inside_attribute = false; | 80 | let mut inside_attribute = false; |
@@ -106,28 +107,26 @@ pub(crate) fn highlight( | |||
106 | binding_hash: None, | 107 | binding_hash: None, |
107 | }); | 108 | }); |
108 | } | 109 | } |
109 | if let Some(name) = mc.is_macro_rules() { | ||
110 | macro_rules_highlighter.init(); | ||
111 | if let Some((highlight, binding_hash)) = highlight_element( | ||
112 | &sema, | ||
113 | &mut bindings_shadow_count, | ||
114 | syntactic_name_ref_highlighting, | ||
115 | name.syntax().clone().into(), | ||
116 | ) { | ||
117 | stack.add(HighlightedRange { | ||
118 | range: name.syntax().text_range(), | ||
119 | highlight, | ||
120 | binding_hash, | ||
121 | }); | ||
122 | } | ||
123 | } | ||
124 | current_macro_call = Some(mc.clone()); | 110 | current_macro_call = Some(mc.clone()); |
125 | continue; | 111 | continue; |
126 | } | 112 | } |
127 | WalkEvent::Leave(Some(mc)) => { | 113 | WalkEvent::Leave(Some(mc)) => { |
128 | assert!(current_macro_call == Some(mc)); | 114 | assert_eq!(current_macro_call, Some(mc)); |
129 | current_macro_call = None; | 115 | current_macro_call = None; |
130 | format_string_highlighter = FormatStringHighlighter::default(); | 116 | format_string_highlighter = FormatStringHighlighter::default(); |
117 | } | ||
118 | _ => (), | ||
119 | } | ||
120 | |||
121 | match event.clone().map(|it| it.into_node().and_then(ast::MacroRules::cast)) { | ||
122 | WalkEvent::Enter(Some(mac)) => { | ||
123 | macro_rules_highlighter.init(); | ||
124 | current_macro_rules = Some(mac); | ||
125 | continue; | ||
126 | } | ||
127 | WalkEvent::Leave(Some(mac)) => { | ||
128 | assert_eq!(current_macro_rules, Some(mac)); | ||
129 | current_macro_rules = None; | ||
131 | macro_rules_highlighter = MacroRulesHighlighter::default(); | 130 | macro_rules_highlighter = MacroRulesHighlighter::default(); |
132 | } | 131 | } |
133 | _ => (), | 132 | _ => (), |
@@ -163,6 +162,12 @@ pub(crate) fn highlight( | |||
163 | 162 | ||
164 | let range = element.text_range(); | 163 | let range = element.text_range(); |
165 | 164 | ||
165 | if current_macro_rules.is_some() { | ||
166 | if let Some(tok) = element.as_token() { | ||
167 | macro_rules_highlighter.advance(tok); | ||
168 | } | ||
169 | } | ||
170 | |||
166 | let element_to_highlight = if current_macro_call.is_some() && element.kind() != COMMENT { | 171 | let element_to_highlight = if current_macro_call.is_some() && element.kind() != COMMENT { |
167 | // Inside a macro -- expand it first | 172 | // Inside a macro -- expand it first |
168 | let token = match element.clone().into_token() { | 173 | let token = match element.clone().into_token() { |
@@ -173,9 +178,6 @@ pub(crate) fn highlight( | |||
173 | let parent = token.parent(); | 178 | let parent = token.parent(); |
174 | 179 | ||
175 | format_string_highlighter.check_for_format_string(&parent); | 180 | format_string_highlighter.check_for_format_string(&parent); |
176 | if let Some(tok) = element.as_token() { | ||
177 | macro_rules_highlighter.advance(tok); | ||
178 | } | ||
179 | 181 | ||
180 | // We only care Name and Name_ref | 182 | // We only care Name and Name_ref |
181 | match (token.kind(), parent.kind()) { | 183 | match (token.kind(), parent.kind()) { |
@@ -386,10 +388,14 @@ impl HighlightedRangeStack { | |||
386 | let mut res = self.stack.pop().unwrap(); | 388 | let mut res = self.stack.pop().unwrap(); |
387 | res.sort_by_key(|range| range.range.start()); | 389 | res.sort_by_key(|range| range.range.start()); |
388 | // Check that ranges are sorted and disjoint | 390 | // Check that ranges are sorted and disjoint |
389 | assert!(res | 391 | for (left, right) in res.iter().zip(res.iter().skip(1)) { |
390 | .iter() | 392 | assert!( |
391 | .zip(res.iter().skip(1)) | 393 | left.range.end() <= right.range.start(), |
392 | .all(|(left, right)| left.range.end() <= right.range.start())); | 394 | "left: {:#?}, right: {:#?}", |
395 | left, | ||
396 | right | ||
397 | ); | ||
398 | } | ||
393 | res | 399 | res |
394 | } | 400 | } |
395 | } | 401 | } |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index 396fd46fb..920956b51 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html | |||
@@ -95,7 +95,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
95 | <span class="comment documentation">/// ```</span> | 95 | <span class="comment documentation">/// ```</span> |
96 | <span class="comment documentation">/// </span><span class="macro injected">noop!</span><span class="punctuation injected">(</span><span class="numeric_literal injected">1</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected"> | 96 | <span class="comment documentation">/// </span><span class="macro injected">noop!</span><span class="punctuation injected">(</span><span class="numeric_literal injected">1</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected"> |
97 | </span><span class="comment documentation">/// ```</span> | 97 | </span><span class="comment documentation">/// ```</span> |
98 | <span class="macro">macro_rules!</span> <span class="macro declaration">noop</span> <span class="punctuation">{</span> | 98 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">noop</span> <span class="punctuation">{</span> |
99 | <span class="punctuation">(</span><span class="punctuation">$</span>expr<span class="punctuation">:</span>expr<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span> | 99 | <span class="punctuation">(</span><span class="punctuation">$</span>expr<span class="punctuation">:</span>expr<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span> |
100 | <span class="punctuation">$</span>expr | 100 | <span class="punctuation">$</span>expr |
101 | <span class="punctuation">}</span> | 101 | <span class="punctuation">}</span> |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html index d398e1ec8..c843b5085 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html | |||
@@ -35,13 +35,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
35 | 35 | ||
36 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 36 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
37 | </style> | 37 | </style> |
38 | <pre><code><span class="macro">macro_rules!</span> <span class="macro declaration">println</span> <span class="punctuation">{</span> | 38 | <pre><code><span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">println</span> <span class="punctuation">{</span> |
39 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">(</span><span class="punctuation">{</span> | 39 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">(</span><span class="punctuation">{</span> |
40 | <span class="punctuation">$</span>crate<span class="punctuation">:</span><span class="punctuation">:</span>io<span class="punctuation">:</span><span class="punctuation">:</span>_print<span class="punctuation">(</span><span class="punctuation">$</span>crate<span class="punctuation">:</span><span class="punctuation">:</span>format_args_nl<span class="punctuation">!</span><span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span> | 40 | <span class="punctuation">$</span>crate<span class="punctuation">:</span><span class="punctuation">:</span>io<span class="punctuation">:</span><span class="punctuation">:</span>_print<span class="punctuation">(</span><span class="punctuation">$</span>crate<span class="punctuation">:</span><span class="punctuation">:</span>format_args_nl<span class="punctuation">!</span><span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span> |
41 | <span class="punctuation">}</span><span class="punctuation">)</span> | 41 | <span class="punctuation">}</span><span class="punctuation">)</span> |
42 | <span class="punctuation">}</span> | 42 | <span class="punctuation">}</span> |
43 | #[rustc_builtin_macro] | 43 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span> |
44 | <span class="macro">macro_rules!</span> <span class="macro declaration">format_args_nl</span> <span class="punctuation">{</span> | 44 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">format_args_nl</span> <span class="punctuation">{</span> |
45 | <span class="punctuation">(</span><span class="punctuation">$</span>fmt<span class="punctuation">:</span>expr<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">{</span> <span class="comment">/* compiler built-in */</span> <span class="punctuation">}</span><span class="punctuation">}</span><span class="punctuation">;</span> | 45 | <span class="punctuation">(</span><span class="punctuation">$</span>fmt<span class="punctuation">:</span>expr<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">{</span> <span class="comment">/* compiler built-in */</span> <span class="punctuation">}</span><span class="punctuation">}</span><span class="punctuation">;</span> |
46 | <span class="punctuation">(</span><span class="punctuation">$</span>fmt<span class="punctuation">:</span>expr<span class="punctuation">,</span> <span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>args<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">{</span> <span class="comment">/* compiler built-in */</span> <span class="punctuation">}</span><span class="punctuation">}</span><span class="punctuation">;</span> | 46 | <span class="punctuation">(</span><span class="punctuation">$</span>fmt<span class="punctuation">:</span>expr<span class="punctuation">,</span> <span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>args<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">{</span> <span class="comment">/* compiler built-in */</span> <span class="punctuation">}</span><span class="punctuation">}</span><span class="punctuation">;</span> |
47 | <span class="punctuation">}</span> | 47 | <span class="punctuation">}</span> |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index a3b4f20e8..0569cf1e5 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -125,7 +125,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
125 | <span class="keyword">let</span> <span class="variable declaration">bar</span> <span class="operator">=</span> <span class="function">foobar</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 125 | <span class="keyword">let</span> <span class="variable declaration">bar</span> <span class="operator">=</span> <span class="function">foobar</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> |
126 | <span class="punctuation">}</span> | 126 | <span class="punctuation">}</span> |
127 | 127 | ||
128 | <span class="macro">macro_rules!</span> <span class="macro declaration">def_fn</span> <span class="punctuation">{</span> | 128 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">def_fn</span> <span class="punctuation">{</span> |
129 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>tt<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">}</span> | 129 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>tt<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">}</span> |
130 | <span class="punctuation">}</span> | 130 | <span class="punctuation">}</span> |
131 | 131 | ||
@@ -135,13 +135,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
135 | <span class="punctuation">}</span> | 135 | <span class="punctuation">}</span> |
136 | <span class="punctuation">}</span> | 136 | <span class="punctuation">}</span> |
137 | 137 | ||
138 | <span class="macro">macro_rules!</span> <span class="macro declaration">noop</span> <span class="punctuation">{</span> | 138 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">noop</span> <span class="punctuation">{</span> |
139 | <span class="punctuation">(</span><span class="punctuation">$</span>expr<span class="punctuation">:</span>expr<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span> | 139 | <span class="punctuation">(</span><span class="punctuation">$</span>expr<span class="punctuation">:</span>expr<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span> |
140 | <span class="punctuation">$</span>expr | 140 | <span class="punctuation">$</span>expr |
141 | <span class="punctuation">}</span> | 141 | <span class="punctuation">}</span> |
142 | <span class="punctuation">}</span> | 142 | <span class="punctuation">}</span> |
143 | 143 | ||
144 | <span class="macro">macro_rules!</span> <span class="macro declaration">keyword_frag</span> <span class="punctuation">{</span> | 144 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">keyword_frag</span> <span class="punctuation">{</span> |
145 | <span class="punctuation">(</span><span class="punctuation">$</span>type<span class="punctuation">:</span>ty<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">(</span><span class="punctuation">$</span>type<span class="punctuation">)</span> | 145 | <span class="punctuation">(</span><span class="punctuation">$</span>type<span class="punctuation">:</span>ty<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">(</span><span class="punctuation">$</span>type<span class="punctuation">)</span> |
146 | <span class="punctuation">}</span> | 146 | <span class="punctuation">}</span> |
147 | 147 | ||
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index 5d2cd30d1..d4a774261 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs | |||
@@ -217,7 +217,7 @@ impl NameClass { | |||
217 | let def: hir::TypeAlias = sema.to_def(&it)?; | 217 | let def: hir::TypeAlias = sema.to_def(&it)?; |
218 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) | 218 | Some(NameClass::Definition(Definition::ModuleDef(def.into()))) |
219 | }, | 219 | }, |
220 | ast::MacroCall(it) => { | 220 | ast::MacroRules(it) => { |
221 | let def = sema.to_def(&it)?; | 221 | let def = sema.to_def(&it)?; |
222 | Some(NameClass::Definition(Definition::Macro(def))) | 222 | Some(NameClass::Definition(Definition::Macro(def))) |
223 | }, | 223 | }, |
diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 654df898e..121063aea 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs | |||
@@ -404,13 +404,7 @@ fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> { | |||
404 | ast::TypeAlias(it) => decl(it), | 404 | ast::TypeAlias(it) => decl(it), |
405 | ast::Const(it) => decl(it), | 405 | ast::Const(it) => decl(it), |
406 | ast::Static(it) => decl(it), | 406 | ast::Static(it) => decl(it), |
407 | ast::MacroCall(it) => { | 407 | ast::MacroRules(it) => decl(it), |
408 | if it.is_macro_rules().is_some() { | ||
409 | decl(it) | ||
410 | } else { | ||
411 | None | ||
412 | } | ||
413 | }, | ||
414 | _ => None, | 408 | _ => None, |
415 | } | 409 | } |
416 | } | 410 | } |
diff --git a/crates/mbe/src/mbe_expander.rs b/crates/mbe/src/mbe_expander.rs index 97bce0536..a80b73db4 100644 --- a/crates/mbe/src/mbe_expander.rs +++ b/crates/mbe/src/mbe_expander.rs | |||
@@ -163,7 +163,7 @@ mod tests { | |||
163 | fn create_rules(macro_definition: &str) -> crate::MacroRules { | 163 | fn create_rules(macro_definition: &str) -> crate::MacroRules { |
164 | let source_file = ast::SourceFile::parse(macro_definition).ok().unwrap(); | 164 | let source_file = ast::SourceFile::parse(macro_definition).ok().unwrap(); |
165 | let macro_definition = | 165 | let macro_definition = |
166 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); | 166 | source_file.syntax().descendants().find_map(ast::MacroRules::cast).unwrap(); |
167 | 167 | ||
168 | let (definition_tt, _) = | 168 | let (definition_tt, _) = |
169 | ast_to_token_tree(¯o_definition.token_tree().unwrap()).unwrap(); | 169 | ast_to_token_tree(¯o_definition.token_tree().unwrap()).unwrap(); |
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs index 843054fe8..dff6e98c2 100644 --- a/crates/mbe/src/tests.rs +++ b/crates/mbe/src/tests.rs | |||
@@ -48,7 +48,7 @@ mod rule_parsing { | |||
48 | let macro_definition = format!(" macro_rules! m {{ {} }} ", arm_definition); | 48 | let macro_definition = format!(" macro_rules! m {{ {} }} ", arm_definition); |
49 | let source_file = ast::SourceFile::parse(¯o_definition).ok().unwrap(); | 49 | let source_file = ast::SourceFile::parse(¯o_definition).ok().unwrap(); |
50 | let macro_definition = | 50 | let macro_definition = |
51 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); | 51 | source_file.syntax().descendants().find_map(ast::MacroRules::cast).unwrap(); |
52 | 52 | ||
53 | let (definition_tt, _) = | 53 | let (definition_tt, _) = |
54 | ast_to_token_tree(¯o_definition.token_tree().unwrap()).unwrap(); | 54 | ast_to_token_tree(¯o_definition.token_tree().unwrap()).unwrap(); |
@@ -1668,7 +1668,7 @@ impl MacroFixture { | |||
1668 | fn parse_macro_to_tt(ra_fixture: &str) -> tt::Subtree { | 1668 | fn parse_macro_to_tt(ra_fixture: &str) -> tt::Subtree { |
1669 | let source_file = ast::SourceFile::parse(ra_fixture).ok().unwrap(); | 1669 | let source_file = ast::SourceFile::parse(ra_fixture).ok().unwrap(); |
1670 | let macro_definition = | 1670 | let macro_definition = |
1671 | source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); | 1671 | source_file.syntax().descendants().find_map(ast::MacroRules::cast).unwrap(); |
1672 | 1672 | ||
1673 | let (definition_tt, _) = ast_to_token_tree(¯o_definition.token_tree().unwrap()).unwrap(); | 1673 | let (definition_tt, _) = ast_to_token_tree(¯o_definition.token_tree().unwrap()).unwrap(); |
1674 | 1674 | ||
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs index ad29b82f7..8999829b4 100644 --- a/crates/parser/src/grammar/items.rs +++ b/crates/parser/src/grammar/items.rs | |||
@@ -232,6 +232,9 @@ fn items_without_modifiers(p: &mut Parser, m: Marker) -> Result<(), Marker> { | |||
232 | T![macro] => { | 232 | T![macro] => { |
233 | macro_def(p, m); | 233 | macro_def(p, m); |
234 | } | 234 | } |
235 | IDENT if p.at_contextual_kw("macro_rules") && p.nth(1) == BANG => { | ||
236 | macro_rules(p, m); | ||
237 | } | ||
235 | IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { | 238 | IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { |
236 | // test union_items | 239 | // test union_items |
237 | // union Foo {} | 240 | // union Foo {} |
@@ -363,6 +366,34 @@ pub(crate) fn item_list(p: &mut Parser) { | |||
363 | m.complete(p, ITEM_LIST); | 366 | m.complete(p, ITEM_LIST); |
364 | } | 367 | } |
365 | 368 | ||
369 | fn macro_rules(p: &mut Parser, m: Marker) { | ||
370 | assert!(p.at_contextual_kw("macro_rules")); | ||
371 | p.bump_remap(T![macro_rules]); | ||
372 | p.expect(T![!]); | ||
373 | |||
374 | if p.at(IDENT) { | ||
375 | name(p); | ||
376 | } | ||
377 | // Special-case `macro_rules! try`. | ||
378 | // This is a hack until we do proper edition support | ||
379 | |||
380 | // test try_macro_rules | ||
381 | // macro_rules! try { () => {} } | ||
382 | if p.at(T![try]) { | ||
383 | let m = p.start(); | ||
384 | p.bump_remap(IDENT); | ||
385 | m.complete(p, NAME); | ||
386 | } | ||
387 | |||
388 | match p.current() { | ||
389 | T!['{'] => { | ||
390 | token_tree(p); | ||
391 | } | ||
392 | _ => p.error("expected `{`"), | ||
393 | } | ||
394 | m.complete(p, MACRO_RULES); | ||
395 | } | ||
396 | |||
366 | // test macro_def | 397 | // test macro_def |
367 | // macro m { ($i:ident) => {} } | 398 | // macro m { ($i:ident) => {} } |
368 | // macro m($i:ident) {} | 399 | // macro m($i:ident) {} |
@@ -394,19 +425,6 @@ fn macro_call(p: &mut Parser) -> BlockLike { | |||
394 | 425 | ||
395 | pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike { | 426 | pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike { |
396 | p.expect(T![!]); | 427 | p.expect(T![!]); |
397 | if p.at(IDENT) { | ||
398 | name(p); | ||
399 | } | ||
400 | // Special-case `macro_rules! try`. | ||
401 | // This is a hack until we do proper edition support | ||
402 | |||
403 | // test try_macro_rules | ||
404 | // macro_rules! try { () => {} } | ||
405 | if p.at(T![try]) { | ||
406 | let m = p.start(); | ||
407 | p.bump_remap(IDENT); | ||
408 | m.complete(p, NAME); | ||
409 | } | ||
410 | 428 | ||
411 | match p.current() { | 429 | match p.current() { |
412 | T!['{'] => { | 430 | T!['{'] => { |
diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs index 8bc6688f3..5d6ec17a4 100644 --- a/crates/parser/src/syntax_kind/generated.rs +++ b/crates/parser/src/syntax_kind/generated.rs | |||
@@ -106,6 +106,7 @@ pub enum SyntaxKind { | |||
106 | EXISTENTIAL_KW, | 106 | EXISTENTIAL_KW, |
107 | UNION_KW, | 107 | UNION_KW, |
108 | RAW_KW, | 108 | RAW_KW, |
109 | MACRO_RULES_KW, | ||
109 | INT_NUMBER, | 110 | INT_NUMBER, |
110 | FLOAT_NUMBER, | 111 | FLOAT_NUMBER, |
111 | CHAR, | 112 | CHAR, |
@@ -135,6 +136,8 @@ pub enum SyntaxKind { | |||
135 | IMPL, | 136 | IMPL, |
136 | TYPE_ALIAS, | 137 | TYPE_ALIAS, |
137 | MACRO_CALL, | 138 | MACRO_CALL, |
139 | MACRO_RULES, | ||
140 | MACRO_ARM, | ||
138 | TOKEN_TREE, | 141 | TOKEN_TREE, |
139 | MACRO_DEF, | 142 | MACRO_DEF, |
140 | PAREN_TYPE, | 143 | PAREN_TYPE, |
@@ -258,7 +261,7 @@ impl SyntaxKind { | |||
258 | | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW | 261 | | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW |
259 | | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | STATIC_KW | STRUCT_KW | SUPER_KW | 262 | | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | STATIC_KW | STRUCT_KW | SUPER_KW |
260 | | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW | WHERE_KW | WHILE_KW | 263 | | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW | WHERE_KW | WHILE_KW |
261 | | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW | RAW_KW => true, | 264 | | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW | RAW_KW | MACRO_RULES_KW => true, |
262 | _ => false, | 265 | _ => false, |
263 | } | 266 | } |
264 | } | 267 | } |
@@ -361,4 +364,4 @@ impl SyntaxKind { | |||
361 | } | 364 | } |
362 | } | 365 | } |
363 | #[macro_export] | 366 | #[macro_export] |
364 | macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [lifetime] => { $ crate :: SyntaxKind :: LIFETIME } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } | 367 | macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [lifetime] => { $ crate :: SyntaxKind :: LIFETIME } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } |
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 30d11b146..0ad75214f 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs | |||
@@ -128,7 +128,6 @@ pub struct MacroCall { | |||
128 | pub(crate) syntax: SyntaxNode, | 128 | pub(crate) syntax: SyntaxNode, |
129 | } | 129 | } |
130 | impl ast::AttrsOwner for MacroCall {} | 130 | impl ast::AttrsOwner for MacroCall {} |
131 | impl ast::NameOwner for MacroCall {} | ||
132 | impl MacroCall { | 131 | impl MacroCall { |
133 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } | 132 | pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } |
134 | pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) } | 133 | pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) } |
@@ -273,6 +272,20 @@ impl Impl { | |||
273 | pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) } | 272 | pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) } |
274 | } | 273 | } |
275 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 274 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
275 | pub struct MacroRules { | ||
276 | pub(crate) syntax: SyntaxNode, | ||
277 | } | ||
278 | impl ast::AttrsOwner for MacroRules {} | ||
279 | impl ast::NameOwner for MacroRules {} | ||
280 | impl ast::VisibilityOwner for MacroRules {} | ||
281 | impl MacroRules { | ||
282 | pub fn macro_rules_token(&self) -> Option<SyntaxToken> { | ||
283 | support::token(&self.syntax, T![macro_rules]) | ||
284 | } | ||
285 | pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) } | ||
286 | pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) } | ||
287 | } | ||
288 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
276 | pub struct Module { | 289 | pub struct Module { |
277 | pub(crate) syntax: SyntaxNode, | 290 | pub(crate) syntax: SyntaxNode, |
278 | } | 291 | } |
@@ -1318,6 +1331,7 @@ pub enum Item { | |||
1318 | Fn(Fn), | 1331 | Fn(Fn), |
1319 | Impl(Impl), | 1332 | Impl(Impl), |
1320 | MacroCall(MacroCall), | 1333 | MacroCall(MacroCall), |
1334 | MacroRules(MacroRules), | ||
1321 | Module(Module), | 1335 | Module(Module), |
1322 | Static(Static), | 1336 | Static(Static), |
1323 | Struct(Struct), | 1337 | Struct(Struct), |
@@ -1374,7 +1388,6 @@ pub enum AssocItem { | |||
1374 | TypeAlias(TypeAlias), | 1388 | TypeAlias(TypeAlias), |
1375 | } | 1389 | } |
1376 | impl ast::AttrsOwner for AssocItem {} | 1390 | impl ast::AttrsOwner for AssocItem {} |
1377 | impl ast::NameOwner for AssocItem {} | ||
1378 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1391 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1379 | pub enum ExternItem { | 1392 | pub enum ExternItem { |
1380 | Fn(Fn), | 1393 | Fn(Fn), |
@@ -1383,7 +1396,6 @@ pub enum ExternItem { | |||
1383 | TypeAlias(TypeAlias), | 1396 | TypeAlias(TypeAlias), |
1384 | } | 1397 | } |
1385 | impl ast::AttrsOwner for ExternItem {} | 1398 | impl ast::AttrsOwner for ExternItem {} |
1386 | impl ast::NameOwner for ExternItem {} | ||
1387 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1399 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1388 | pub enum GenericParam { | 1400 | pub enum GenericParam { |
1389 | ConstParam(ConstParam), | 1401 | ConstParam(ConstParam), |
@@ -1666,6 +1678,17 @@ impl AstNode for Impl { | |||
1666 | } | 1678 | } |
1667 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 1679 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
1668 | } | 1680 | } |
1681 | impl AstNode for MacroRules { | ||
1682 | fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_RULES } | ||
1683 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
1684 | if Self::can_cast(syntax.kind()) { | ||
1685 | Some(Self { syntax }) | ||
1686 | } else { | ||
1687 | None | ||
1688 | } | ||
1689 | } | ||
1690 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
1691 | } | ||
1669 | impl AstNode for Module { | 1692 | impl AstNode for Module { |
1670 | fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE } | 1693 | fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE } |
1671 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 1694 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
@@ -3060,6 +3083,9 @@ impl From<Impl> for Item { | |||
3060 | impl From<MacroCall> for Item { | 3083 | impl From<MacroCall> for Item { |
3061 | fn from(node: MacroCall) -> Item { Item::MacroCall(node) } | 3084 | fn from(node: MacroCall) -> Item { Item::MacroCall(node) } |
3062 | } | 3085 | } |
3086 | impl From<MacroRules> for Item { | ||
3087 | fn from(node: MacroRules) -> Item { Item::MacroRules(node) } | ||
3088 | } | ||
3063 | impl From<Module> for Item { | 3089 | impl From<Module> for Item { |
3064 | fn from(node: Module) -> Item { Item::Module(node) } | 3090 | fn from(node: Module) -> Item { Item::Module(node) } |
3065 | } | 3091 | } |
@@ -3084,8 +3110,8 @@ impl From<Use> for Item { | |||
3084 | impl AstNode for Item { | 3110 | impl AstNode for Item { |
3085 | fn can_cast(kind: SyntaxKind) -> bool { | 3111 | fn can_cast(kind: SyntaxKind) -> bool { |
3086 | match kind { | 3112 | match kind { |
3087 | CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MODULE | 3113 | CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MACRO_RULES |
3088 | | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true, | 3114 | | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true, |
3089 | _ => false, | 3115 | _ => false, |
3090 | } | 3116 | } |
3091 | } | 3117 | } |
@@ -3098,6 +3124,7 @@ impl AstNode for Item { | |||
3098 | FN => Item::Fn(Fn { syntax }), | 3124 | FN => Item::Fn(Fn { syntax }), |
3099 | IMPL => Item::Impl(Impl { syntax }), | 3125 | IMPL => Item::Impl(Impl { syntax }), |
3100 | MACRO_CALL => Item::MacroCall(MacroCall { syntax }), | 3126 | MACRO_CALL => Item::MacroCall(MacroCall { syntax }), |
3127 | MACRO_RULES => Item::MacroRules(MacroRules { syntax }), | ||
3101 | MODULE => Item::Module(Module { syntax }), | 3128 | MODULE => Item::Module(Module { syntax }), |
3102 | STATIC => Item::Static(Static { syntax }), | 3129 | STATIC => Item::Static(Static { syntax }), |
3103 | STRUCT => Item::Struct(Struct { syntax }), | 3130 | STRUCT => Item::Struct(Struct { syntax }), |
@@ -3118,6 +3145,7 @@ impl AstNode for Item { | |||
3118 | Item::Fn(it) => &it.syntax, | 3145 | Item::Fn(it) => &it.syntax, |
3119 | Item::Impl(it) => &it.syntax, | 3146 | Item::Impl(it) => &it.syntax, |
3120 | Item::MacroCall(it) => &it.syntax, | 3147 | Item::MacroCall(it) => &it.syntax, |
3148 | Item::MacroRules(it) => &it.syntax, | ||
3121 | Item::Module(it) => &it.syntax, | 3149 | Item::Module(it) => &it.syntax, |
3122 | Item::Static(it) => &it.syntax, | 3150 | Item::Static(it) => &it.syntax, |
3123 | Item::Struct(it) => &it.syntax, | 3151 | Item::Struct(it) => &it.syntax, |
@@ -3582,6 +3610,11 @@ impl std::fmt::Display for Impl { | |||
3582 | std::fmt::Display::fmt(self.syntax(), f) | 3610 | std::fmt::Display::fmt(self.syntax(), f) |
3583 | } | 3611 | } |
3584 | } | 3612 | } |
3613 | impl std::fmt::Display for MacroRules { | ||
3614 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
3615 | std::fmt::Display::fmt(self.syntax(), f) | ||
3616 | } | ||
3617 | } | ||
3585 | impl std::fmt::Display for Module { | 3618 | impl std::fmt::Display for Module { |
3586 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 3619 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
3587 | std::fmt::Display::fmt(self.syntax(), f) | 3620 | std::fmt::Display::fmt(self.syntax(), f) |
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 820af2d20..c59a29eab 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs | |||
@@ -382,21 +382,6 @@ impl ast::Visibility { | |||
382 | } | 382 | } |
383 | } | 383 | } |
384 | 384 | ||
385 | impl ast::MacroCall { | ||
386 | pub fn is_macro_rules(&self) -> Option<ast::Name> { | ||
387 | let name_ref = self.path()?.segment()?.name_ref()?; | ||
388 | if name_ref.text() == "macro_rules" { | ||
389 | self.name() | ||
390 | } else { | ||
391 | None | ||
392 | } | ||
393 | } | ||
394 | |||
395 | pub fn is_bang(&self) -> bool { | ||
396 | self.is_macro_rules().is_none() | ||
397 | } | ||
398 | } | ||
399 | |||
400 | impl ast::LifetimeParam { | 385 | impl ast::LifetimeParam { |
401 | pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> { | 386 | pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> { |
402 | self.syntax() | 387 | self.syntax() |
@@ -476,5 +461,5 @@ impl ast::DocCommentsOwner for ast::Static {} | |||
476 | impl ast::DocCommentsOwner for ast::Const {} | 461 | impl ast::DocCommentsOwner for ast::Const {} |
477 | impl ast::DocCommentsOwner for ast::TypeAlias {} | 462 | impl ast::DocCommentsOwner for ast::TypeAlias {} |
478 | impl ast::DocCommentsOwner for ast::Impl {} | 463 | impl ast::DocCommentsOwner for ast::Impl {} |
479 | impl ast::DocCommentsOwner for ast::MacroCall {} | 464 | impl ast::DocCommentsOwner for ast::MacroRules {} |
480 | impl ast::DocCommentsOwner for ast::Use {} | 465 | impl ast::DocCommentsOwner for ast::Use {} |
diff --git a/crates/syntax/src/display.rs b/crates/syntax/src/display.rs index 8d2c7eae4..d33bde30c 100644 --- a/crates/syntax/src/display.rs +++ b/crates/syntax/src/display.rs | |||
@@ -76,7 +76,7 @@ pub fn type_label(node: &ast::TypeAlias) -> String { | |||
76 | label.trim().to_owned() | 76 | label.trim().to_owned() |
77 | } | 77 | } |
78 | 78 | ||
79 | pub fn macro_label(node: &ast::MacroCall) -> String { | 79 | pub fn macro_label(node: &ast::MacroRules) -> String { |
80 | let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); | 80 | let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); |
81 | let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; | 81 | let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; |
82 | format!("{}macro_rules! {}", vis, name) | 82 | format!("{}macro_rules! {}", vis, name) |
diff --git a/crates/syntax/src/parsing/text_tree_sink.rs b/crates/syntax/src/parsing/text_tree_sink.rs index 49842177a..ce27c3dd9 100644 --- a/crates/syntax/src/parsing/text_tree_sink.rs +++ b/crates/syntax/src/parsing/text_tree_sink.rs | |||
@@ -147,8 +147,8 @@ fn n_attached_trivias<'a>( | |||
147 | trivias: impl Iterator<Item = (SyntaxKind, &'a str)>, | 147 | trivias: impl Iterator<Item = (SyntaxKind, &'a str)>, |
148 | ) -> usize { | 148 | ) -> usize { |
149 | match kind { | 149 | match kind { |
150 | MACRO_CALL | CONST | TYPE_ALIAS | STRUCT | ENUM | VARIANT | FN | TRAIT | MODULE | 150 | MACRO_CALL | MACRO_RULES | CONST | TYPE_ALIAS | STRUCT | ENUM | VARIANT | FN | TRAIT |
151 | | RECORD_FIELD | STATIC | USE => { | 151 | | MODULE | RECORD_FIELD | STATIC | USE => { |
152 | let mut res = 0; | 152 | let mut res = 0; |
153 | let mut trivias = trivias.enumerate().peekable(); | 153 | let mut trivias = trivias.enumerate().peekable(); |
154 | 154 | ||
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index 6f45149bf..2ddaeb176 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs | |||
@@ -3,7 +3,9 @@ | |||
3 | mod block; | 3 | mod block; |
4 | 4 | ||
5 | use crate::{ | 5 | use crate::{ |
6 | algo, ast, match_ast, AstNode, SyntaxError, | 6 | algo, |
7 | ast::{self, VisibilityOwner}, | ||
8 | match_ast, AstNode, SyntaxError, | ||
7 | SyntaxKind::{CONST, FN, INT_NUMBER, TYPE_ALIAS}, | 9 | SyntaxKind::{CONST, FN, INT_NUMBER, TYPE_ALIAS}, |
8 | SyntaxNode, SyntaxToken, TextSize, T, | 10 | SyntaxNode, SyntaxToken, TextSize, T, |
9 | }; | 11 | }; |
@@ -99,6 +101,7 @@ pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> { | |||
99 | ast::RefType(it) => validate_trait_object_ref_ty(it, &mut errors), | 101 | ast::RefType(it) => validate_trait_object_ref_ty(it, &mut errors), |
100 | ast::PtrType(it) => validate_trait_object_ptr_ty(it, &mut errors), | 102 | ast::PtrType(it) => validate_trait_object_ptr_ty(it, &mut errors), |
101 | ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, &mut errors), | 103 | ast::FnPtrType(it) => validate_trait_object_fn_ptr_ret_ty(it, &mut errors), |
104 | ast::MacroRules(it) => validate_macro_rules(it, &mut errors), | ||
102 | _ => (), | 105 | _ => (), |
103 | } | 106 | } |
104 | } | 107 | } |
@@ -350,3 +353,12 @@ fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> { | |||
350 | } | 353 | } |
351 | None | 354 | None |
352 | } | 355 | } |
356 | |||
357 | fn validate_macro_rules(mac: ast::MacroRules, errors: &mut Vec<SyntaxError>) { | ||
358 | if let Some(vis) = mac.visibility() { | ||
359 | errors.push(SyntaxError::new( | ||
360 | "visibilities are not allowed on `macro_rules!` items", | ||
361 | vis.syntax().text_range(), | ||
362 | )); | ||
363 | } | ||
364 | } | ||
diff --git a/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast b/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast index 4cfd1bce4..9ad5b12b8 100644 --- a/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast +++ b/crates/syntax/test_data/parser/err/0002_duplicate_shebang.rast | |||
@@ -17,14 +17,17 @@ [email protected] | |||
17 | [email protected] "bin" | 17 | [email protected] "bin" |
18 | [email protected] | 18 | [email protected] |
19 | [email protected] "/" | 19 | [email protected] "/" |
20 | MACRO_CALL@32..41 | 20 | MACRO_CALL@32..35 |
21 | [email protected] | 21 | [email protected] |
22 | [email protected] | 22 | [email protected] |
23 | [email protected] | 23 | [email protected] |
24 | [email protected] "env" | 24 | [email protected] "env" |
25 | [email protected] " " | 25 | [email protected] " " |
26 | [email protected] | 26 | [email protected] |
27 | [email protected] "rusti" | 27 | [email protected] |
28 | [email protected] | ||
29 | [email protected] | ||
30 | [email protected] "rusti" | ||
28 | [email protected] "\n" | 31 | [email protected] "\n" |
29 | error 23..23: expected `[` | 32 | error 23..23: expected `[` |
30 | error 23..23: expected an item | 33 | error 23..23: expected an item |
@@ -35,5 +38,8 @@ error 31..31: expected `{`, `[`, `(` | |||
35 | error 31..31: expected SEMICOLON | 38 | error 31..31: expected SEMICOLON |
36 | error 31..31: expected an item | 39 | error 31..31: expected an item |
37 | error 35..35: expected BANG | 40 | error 35..35: expected BANG |
41 | error 35..35: expected `{`, `[`, `(` | ||
42 | error 35..35: expected SEMICOLON | ||
43 | error 41..41: expected BANG | ||
38 | error 41..41: expected `{`, `[`, `(` | 44 | error 41..41: expected `{`, `[`, `(` |
39 | error 41..41: expected SEMICOLON | 45 | error 41..41: expected SEMICOLON |
diff --git a/crates/syntax/test_data/parser/inline/ok/0062_mod_contents.rast b/crates/syntax/test_data/parser/inline/ok/0062_mod_contents.rast index de8217064..e4fb32de1 100644 --- a/crates/syntax/test_data/parser/inline/ok/0062_mod_contents.rast +++ b/crates/syntax/test_data/parser/inline/ok/0062_mod_contents.rast | |||
@@ -12,11 +12,8 @@ [email protected] | |||
12 | [email protected] "{" | 12 | [email protected] "{" |
13 | [email protected] "}" | 13 | [email protected] "}" |
14 | [email protected] "\n" | 14 | [email protected] "\n" |
15 | [email protected] | 15 | [email protected] |
16 | [email protected] | 16 | [email protected] "macro_rules" |
17 | [email protected] | ||
18 | [email protected] | ||
19 | [email protected] "macro_rules" | ||
20 | [email protected] "!" | 17 | [email protected] "!" |
21 | [email protected] " " | 18 | [email protected] " " |
22 | [email protected] | 19 | [email protected] |
diff --git a/crates/syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast b/crates/syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast index e757249f0..e84b9164f 100644 --- a/crates/syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast +++ b/crates/syntax/test_data/parser/inline/ok/0096_no_semi_after_block.rast | |||
@@ -82,32 +82,28 @@ [email protected] | |||
82 | [email protected] "{" | 82 | [email protected] "{" |
83 | [email protected] "}" | 83 | [email protected] "}" |
84 | [email protected] "\n " | 84 | [email protected] "\n " |
85 | [email protected] | 85 | [email protected] |
86 | [email protected] | 86 | [email protected] "macro_rules" |
87 | [email protected] | 87 | [email protected] "!" |
88 | [email protected] | 88 | [email protected] " " |
89 | [email protected] | 89 | [email protected] |
90 | [email protected] "macro_rules" | 90 | [email protected] "test" |
91 | [email protected] "!" | 91 | [email protected] " " |
92 | [email protected] " " | 92 | [email protected] |
93 | [email protected] | 93 | [email protected] "{" |
94 | [email protected] "test" | 94 | [email protected] "\n " |
95 | [email protected] " " | 95 | [email protected] |
96 | [email protected] | 96 | [email protected] "(" |
97 | [email protected] "{" | 97 | [email protected] ")" |
98 | [email protected] "\n " | 98 | [email protected] " " |
99 | [email protected] | 99 | [email protected] "=" |
100 | [email protected] "(" | 100 | [email protected] ">" |
101 | [email protected] ")" | 101 | [email protected] " " |
102 | [email protected] " " | 102 | [email protected] |
103 | [email protected] "=" | 103 | [email protected] "{" |
104 | [email protected] ">" | 104 | [email protected] "}" |
105 | [email protected] " " | 105 | [email protected] "\n " |
106 | [email protected] | 106 | [email protected] "}" |
107 | [email protected] "{" | ||
108 | [email protected] "}" | ||
109 | [email protected] "\n " | ||
110 | [email protected] "}" | ||
111 | [email protected] "\n " | 107 | [email protected] "\n " |
112 | [email protected] | 108 | [email protected] |
113 | [email protected] | 109 | [email protected] |
diff --git a/crates/syntax/test_data/parser/inline/ok/0160_try_macro_rules.rast b/crates/syntax/test_data/parser/inline/ok/0160_try_macro_rules.rast index 05b89d1c3..d1c22947b 100644 --- a/crates/syntax/test_data/parser/inline/ok/0160_try_macro_rules.rast +++ b/crates/syntax/test_data/parser/inline/ok/0160_try_macro_rules.rast | |||
@@ -1,9 +1,6 @@ | |||
1 | [email protected] | 1 | [email protected] |
2 | [email protected] | 2 | [email protected] |
3 | [email protected] | 3 | [email protected] "macro_rules" |
4 | [email protected] | ||
5 | [email protected] | ||
6 | [email protected] "macro_rules" | ||
7 | [email protected] "!" | 4 | [email protected] "!" |
8 | [email protected] " " | 5 | [email protected] " " |
9 | [email protected] | 6 | [email protected] |
diff --git a/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast b/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast index be60f7a8e..87d8ebcba 100644 --- a/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast +++ b/crates/syntax/test_data/parser/ok/0053_outer_attribute_on_macro_rules.rast | |||
@@ -1,5 +1,5 @@ | |||
1 | [email protected] | 1 | [email protected] |
2 | MACRO_CALL@0..64 | 2 | MACRO_RULES@0..64 |
3 | [email protected] "/// Some docs" | 3 | [email protected] "/// Some docs" |
4 | [email protected] "\n" | 4 | [email protected] "\n" |
5 | [email protected] | 5 | [email protected] |
@@ -11,10 +11,7 @@ [email protected] | |||
11 | [email protected] "macro_export" | 11 | [email protected] "macro_export" |
12 | [email protected] "]" | 12 | [email protected] "]" |
13 | [email protected] "\n" | 13 | [email protected] "\n" |
14 | [email protected] | 14 | [email protected] "macro_rules" |
15 | [email protected] | ||
16 | [email protected] | ||
17 | [email protected] "macro_rules" | ||
18 | [email protected] "!" | 15 | [email protected] "!" |
19 | [email protected] " " | 16 | [email protected] " " |
20 | [email protected] | 17 | [email protected] |