diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2020-12-15 15:37:37 +0100 |
|---|---|---|
| committer | Jonas Schievink <jonasschievink@gmail.com> | 2020-12-15 15:37:37 +0100 |
| commit | c1cb5953820f26d4d0a614650bc8c50cbc5a3ce6 (patch) | |
| tree | 01ba67d97ce6f261154df59b268fe924af9add2a | |
| parent | 39aae835fd70d06092c1be1add6eef3984439529 (diff) | |
| download | rust-c1cb5953820f26d4d0a614650bc8c50cbc5a3ce6.tar.gz rust-c1cb5953820f26d4d0a614650bc8c50cbc5a3ce6.zip | |
Move to upstream `macro_rules!` model
36 files changed, 322 insertions, 272 deletions
diff --git a/Cargo.lock b/Cargo.lock index ec8ad11cb41..ff2c33f45d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1827,9 +1827,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" [[package]] name = "ungrammar" -version = "1.1.4" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0cd89993af555540e2436fc6adb8479b0dbe386339a136397952e9c89e17a9" +checksum = "873186a460627379e7e28880a0d33b729c205634f6f021321f50b323235e62d7" [[package]] name = "unicase" diff --git a/Cargo.toml b/Cargo.toml index e30ef0e2f6e..59d36fbc1d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,3 +25,5 @@ debug = 0 # Set this to 1 or 2 to get more useful backtraces in debugger. # chalk-solve = { path = "../chalk/chalk-solve" } # chalk-ir = { path = "../chalk/chalk-ir" } # chalk-recursive = { path = "../chalk/chalk-recursive" } + +# ungrammar = { path = "../ungrammar" } diff --git a/crates/completion/src/render/macro_.rs b/crates/completion/src/render/macro_.rs index eb3209bee3d..6cfbd6c9ba8 100644 --- a/crates/completion/src/render/macro_.rs +++ b/crates/completion/src/render/macro_.rs @@ -144,7 +144,7 @@ mod tests { use foo::<|>; //- /foo/lib.rs crate:foo #[macro_export] -macro_rules frobnicate { () => () } +macro_rules! frobnicate { () => () } "#, r#" use foo::frobnicate; @@ -154,11 +154,11 @@ use foo::frobnicate; check_edit( "frobnicate!", r#" -macro_rules frobnicate { () => () } +macro_rules! frobnicate { () => () } fn main() { frob<|>!(); } "#, r#" -macro_rules frobnicate { () => () } +macro_rules! frobnicate { () => () } fn main() { frobnicate!(); } "#, ); diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs index 1e64a1614b3..107ad06904d 100644 --- a/crates/hir/src/has_source.rs +++ b/crates/hir/src/has_source.rs @@ -110,8 +110,8 @@ impl HasSource for TypeAlias { } } impl HasSource for MacroDef { - type Ast = ast::MacroCall; - fn source(self, db: &dyn HirDatabase) -> InFile<ast::MacroCall> { + type Ast = ast::MacroRules; + fn source(self, db: &dyn HirDatabase) -> InFile<ast::MacroRules> { InFile { file_id: self.id.ast_id.expect("MacroDef without ast_id").file_id, 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 e4fc21cedf9..5959ac4ca9e 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -723,7 +723,7 @@ to_def_impls![ (crate::EnumVariant, ast::Variant, enum_variant_to_def), (crate::TypeParam, ast::TypeParam, type_param_to_def), (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def), - (crate::MacroDef, ast::MacroCall, macro_call_to_def), // this one is dubious, not all calls are macros + (crate::MacroDef, ast::MacroRules, macro_rules_to_def), (crate::Local, ast::IdentPat, bind_pat_to_def), ]; diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index badcf0ae807..a333d7aea9d 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<'_, '_> { } // FIXME: use DynMap as well? - pub(super) fn macro_call_to_def(&mut self, src: InFile<ast::MacroCall>) -> Option<MacroDefId> { + pub(super) fn macro_rules_to_def( + &mut self, + src: InFile<ast::MacroRules>, + ) -> Option<MacroDefId> { let kind = MacroDefKind::Declarative; let file_id = src.file_id.original_file(self.db.upcast()); 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 6c0de3ee88b..bdba4c33ea4 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs @@ -566,66 +566,52 @@ impl ExprCollector<'_> { syntax_ptr: AstPtr<ast::Expr>, mut collector: F, ) { - if let Some(name) = e.is_macro_rules().map(|it| it.as_name()) { - let mac = MacroDefId { - krate: Some(self.expander.module.krate), - ast_id: Some(self.expander.ast_id(&e)), - kind: MacroDefKind::Declarative, - local_inner: false, - }; - self.body.item_scope.define_legacy_macro(name, mac); + // File containing the macro call. Expansion errors will be attached here. + let outer_file = self.expander.current_file_id; - // FIXME: do we still need to allocate this as missing ? - collector(self, None); - } else { - // File containing the macro call. Expansion errors will be attached here. - let outer_file = self.expander.current_file_id; - - let macro_call = self.expander.to_source(AstPtr::new(&e)); - let res = self.expander.enter_expand(self.db, Some(&self.body.item_scope), e); - - match &res.err { - Some(ExpandError::UnresolvedProcMacro) => { - self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro( - UnresolvedProcMacro { - file: outer_file, - node: syntax_ptr.into(), - precise_location: None, - macro_name: None, - }, - )); - } - Some(err) => { - self.source_map.diagnostics.push(BodyDiagnostic::MacroError(MacroError { + let macro_call = self.expander.to_source(AstPtr::new(&e)); + let res = self.expander.enter_expand(self.db, Some(&self.body.item_scope), e); + + match &res.err { + Some(ExpandError::UnresolvedProcMacro) => { + self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro( + UnresolvedProcMacro { file: outer_file, node: syntax_ptr.into(), - message: err.to_string(), - })); - } - None => {} + precise_location: None, + macro_name: None, + }, + )); + } + Some(err) => { + self.source_map.diagnostics.push(BodyDiagnostic::MacroError(MacroError { + file: outer_file, + node: syntax_ptr.into(), + message: err.to_string(), + })); } + None => {} + } - match res.value { - Some((mark, expansion)) => { - // FIXME: Statements are too complicated to recover from error for now. - // It is because we don't have any hygenine for local variable expansion right now. - if T::can_cast(syntax::SyntaxKind::MACRO_STMTS) && res.err.is_some() { - self.expander.exit(self.db, mark); - collector(self, None); - } else { - self.source_map - .expansions - .insert(macro_call, self.expander.current_file_id); + match res.value { + Some((mark, expansion)) => { + // FIXME: Statements are too complicated to recover from error for now. + // It is because we don't have any hygenine for local variable expansion right now. + if T::can_cast(syntax::SyntaxKind::MACRO_STMTS) && res.err.is_some() { + self.expander.exit(self.db, mark); + collector(self, None); + } else { + self.source_map.expansions.insert(macro_call, self.expander.current_file_id); - let item_tree = self.db.item_tree(self.expander.current_file_id); - self.item_trees.insert(self.expander.current_file_id, item_tree); + let item_tree = self.db.item_tree(self.expander.current_file_id); + self.item_trees.insert(self.expander.current_file_id, item_tree); - collector(self, Some(expansion)); - self.expander.exit(self.db, mark); - } + let id = collector(self, Some(expansion)); + self.expander.exit(self.db, mark); + id } - None => collector(self, None), } + None => collector(self, None), } } @@ -785,26 +771,44 @@ impl ExprCollector<'_> { | ast::Item::ExternCrate(_) | ast::Item::Module(_) | ast::Item::MacroCall(_) => return None, + ast::Item::MacroRules(def) => { + return Some(Either::Right(def)); + } }; - Some((def, name)) + Some(Either::Left((def, name))) }) .collect::<Vec<_>>(); - for (def, name) in items { - self.body.item_scope.define_def(def); - if let Some(name) = name { - let vis = crate::visibility::Visibility::Public; // FIXME determine correctly - let has_constructor = match def { - ModuleDefId::AdtId(AdtId::StructId(s)) => { - self.db.struct_data(s).variant_data.kind() != StructKind::Record + for either in items { + match either { + Either::Left((def, name)) => { + self.body.item_scope.define_def(def); + if let Some(name) = name { + let vis = crate::visibility::Visibility::Public; // FIXME determine correctly + let has_constructor = match def { + ModuleDefId::AdtId(AdtId::StructId(s)) => { + self.db.struct_data(s).variant_data.kind() != StructKind::Record + } + _ => true, + }; + self.body.item_scope.push_res( + name.as_name(), + crate::per_ns::PerNs::from_def(def, vis, has_constructor), + ); } - _ => true, - }; - self.body.item_scope.push_res( - name.as_name(), - crate::per_ns::PerNs::from_def(def, vis, has_constructor), - ); + } + Either::Right(e) => { + let mac = MacroDefId { + krate: Some(self.expander.module.krate), + ast_id: Some(self.expander.ast_id(&e)), + kind: MacroDefKind::Declarative, + local_inner: false, + }; + if let Some(name) = e.name() { + self.body.item_scope.define_legacy_macro(name.as_name(), mac); + } + } } } } diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 864fad170fc..1c9babf3712 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -142,6 +142,7 @@ impl ItemTree { type_aliases, mods, macro_calls, + macro_rules, exprs, vis, generics, @@ -162,6 +163,7 @@ impl ItemTree { type_aliases.shrink_to_fit(); mods.shrink_to_fit(); macro_calls.shrink_to_fit(); + macro_rules.shrink_to_fit(); exprs.shrink_to_fit(); vis.arena.shrink_to_fit(); @@ -280,6 +282,7 @@ struct ItemTreeData { type_aliases: Arena<TypeAlias>, mods: Arena<Mod>, macro_calls: Arena<MacroCall>, + macro_rules: Arena<MacroRules>, exprs: Arena<Expr>, vis: ItemVisibilities, @@ -427,6 +430,7 @@ mod_items! { TypeAlias in type_aliases -> ast::TypeAlias, Mod in mods -> ast::Module, MacroCall in macro_calls -> ast::MacroCall, + MacroRules in macro_rules -> ast::MacroRules, } macro_rules! impl_index { @@ -629,17 +633,22 @@ pub enum ModKind { #[derive(Debug, Clone, Eq, PartialEq)] pub struct MacroCall { - /// For `macro_rules!` declarations, this is the name of the declared macro. - pub name: Option<Name>, /// Path to the called macro. pub path: ModPath, + pub ast_id: FileAstId<ast::MacroCall>, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct MacroRules { + /// For `macro_rules!` declarations, this is the name of the declared macro. + pub name: Name, /// Has `#[macro_export]`. pub is_export: bool, /// Has `#[macro_export(local_inner_macros)]`. pub is_local_inner: bool, /// Has `#[rustc_builtin_macro]`. pub is_builtin: bool, - pub ast_id: FileAstId<ast::MacroCall>, + pub ast_id: FileAstId<ast::MacroRules>, } // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array @@ -670,7 +679,8 @@ impl ModItem { | ModItem::Static(_) | ModItem::Trait(_) | ModItem::Impl(_) - | ModItem::Mod(_) => None, + | ModItem::Mod(_) + | ModItem::MacroRules(_) => None, ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), ModItem::Const(konst) => Some(AssocItem::Const(*konst)), ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), @@ -697,6 +707,7 @@ impl ModItem { ModItem::TypeAlias(it) => tree[it.index].ast_id().upcast(), ModItem::Mod(it) => tree[it.index].ast_id().upcast(), ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(), + ModItem::MacroRules(it) => tree[it.index].ast_id().upcast(), } } } diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 2939c6b1e30..b39d7fb7ac1 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 { | ast::Item::Fn(_) | ast::Item::TypeAlias(_) | ast::Item::Const(_) - | ast::Item::Static(_) - | ast::Item::MacroCall(_) => { + | ast::Item::Static(_) => { // Skip this if we're already collecting inner items. We'll descend into all nodes // already. if !inner { @@ -98,7 +97,11 @@ impl Ctx { ast::Item::Trait(_) | ast::Item::Impl(_) | ast::Item::ExternBlock(_) => {} // These don't have inner items. - ast::Item::Module(_) | ast::Item::ExternCrate(_) | ast::Item::Use(_) => {} + ast::Item::Module(_) + | ast::Item::ExternCrate(_) + | ast::Item::Use(_) + | ast::Item::MacroCall(_) + | ast::Item::MacroRules(_) => {} }; let attrs = Attrs::new(item, &self.hygiene); @@ -118,6 +121,7 @@ impl Ctx { )), ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast).map(Into::into), ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), + ast::Item::MacroRules(ast) => self.lower_macro_rules(ast).map(Into::into), ast::Item::ExternBlock(ast) => { Some(ModItems(self.lower_extern_block(ast).into_iter().collect::<SmallVec<_>>())) } @@ -525,9 +529,15 @@ impl Ctx { } fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> { - let name = m.name().map(|it| it.as_name()); - let attrs = Attrs::new(m, &self.hygiene); let path = ModPath::from_src(m.path()?, &self.hygiene)?; + let ast_id = self.source_ast_id_map.ast_id(m); + let res = MacroCall { path, ast_id }; + Some(id(self.data().macro_calls.alloc(res))) + } + + fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> { + let name = m.name().map(|it| it.as_name())?; + let attrs = Attrs::new(m, &self.hygiene); let ast_id = self.source_ast_id_map.ast_id(m); @@ -547,8 +557,8 @@ impl Ctx { }; let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); - let res = MacroCall { name, path, is_export, is_builtin, is_local_inner, ast_id }; - Some(id(self.data().macro_calls.alloc(res))) + let res = MacroRules { name, is_export, is_builtin, is_local_inner, ast_id }; + Some(id(self.data().macro_rules.alloc(res))) } 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 19cd713ba04..85cc342c446 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -11,7 +11,7 @@ use hir_expand::{ ast_id_map::FileAstId, builtin_derive::find_builtin_derive, builtin_macro::find_builtin_macro, - name::{name, AsName, Name}, + name::{AsName, Name}, proc_macro::ProcMacroExpander, HirFileId, MacroCallId, MacroDefId, MacroDefKind, }; @@ -25,7 +25,9 @@ use crate::{ attr::Attrs, db::DefDatabase, item_scope::{ImportType, PerNsGlobImports}, - item_tree::{self, ItemTree, ItemTreeId, MacroCall, Mod, ModItem, ModKind, StructDefKind}, + item_tree::{ + self, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, StructDefKind, + }, nameres::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, @@ -972,7 +974,8 @@ impl ModCollector<'_, '_> { status: PartialResolvedImport::Unresolved, }) } - ModItem::MacroCall(mac) => self.collect_macro(&self.item_tree[mac]), + ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), + ModItem::MacroRules(mac) => self.collect_macro_rules(&self.item_tree[mac]), ModItem::Impl(imp) => { let module = ModuleId { krate: self.def_collector.def_map.krate, @@ -1276,45 +1279,37 @@ impl ModCollector<'_, '_> { self.def_collector.resolve_proc_macro(¯o_name); } - fn collect_macro(&mut self, mac: &MacroCall) { - let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); + fn collect_macro_rules(&mut self, mac: &MacroRules) { + let ast_id = InFile::new(self.file_id, mac.ast_id); - // Case 0: builtin macros + // Case 1: builtin macros if mac.is_builtin { - if let Some(name) = &mac.name { - let krate = self.def_collector.def_map.krate; - if let Some(macro_id) = find_builtin_macro(name, krate, ast_id.ast_id) { - self.def_collector.define_macro( - self.module_id, - name.clone(), - macro_id, - mac.is_export, - ); - return; - } - } - } - - // Case 1: macro rules, define a macro in crate-global mutable scope - if is_macro_rules(&mac.path) { - if let Some(name) = &mac.name { - let macro_id = MacroDefId { - ast_id: Some(ast_id.ast_id), - krate: Some(self.def_collector.def_map.krate), - kind: MacroDefKind::Declarative, - local_inner: mac.is_local_inner, - }; + let krate = self.def_collector.def_map.krate; + if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { self.def_collector.define_macro( self.module_id, - name.clone(), + mac.name.clone(), macro_id, mac.is_export, ); + return; } - return; } - // Case 2: try to resolve in legacy scope and expand macro_rules + // Case 2: normal `macro_rules!` macro + let macro_id = MacroDefId { + ast_id: Some(ast_id), + krate: Some(self.def_collector.def_map.krate), + kind: MacroDefKind::Declarative, + local_inner: mac.is_local_inner, + }; + self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, mac.is_export); + } + + fn collect_macro_call(&mut self, mac: &MacroCall) { + let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); + + // Case 1: try to resolve in legacy scope and expand macro_rules if let Some(macro_call_id) = ast_id.as_call_id(self.def_collector.db, self.def_collector.def_map.krate, |path| { path.as_ident().and_then(|name| { @@ -1332,7 +1327,7 @@ impl ModCollector<'_, '_> { return; } - // Case 3: resolve in module scope, expand during name resolution. + // Case 2: resolve in module scope, expand during name resolution. // We rewrite simple path `macro_name` to `self::macro_name` to force resolve in module scope only. if ast_id.path.is_ident() { ast_id.path.kind = PathKind::Super(0); @@ -1370,10 +1365,6 @@ impl ModCollector<'_, '_> { } } -fn is_macro_rules(path: &ModPath) -> bool { - path.as_ident() == Some(&name![macro_rules]) -} - #[cfg(test)] mod tests { 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 60fa7646b2c..60992501295 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> // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 // We follow what it did anyway :) if segments.len() == 1 && kind == PathKind::Plain { - if let Some(macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { - if macro_call.is_bang() { - if let Some(crate_id) = hygiene.local_inner_macros() { - kind = PathKind::DollarCrate(crate_id); - } + if let Some(_macro_call) = path.syntax().parent().and_then(ast::MacroCall::cast) { + if let Some(crate_id) = hygiene.local_inner_macros() { + kind = PathKind::DollarCrate(crate_id); } } } diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs index b1b432ded2c..bd92238257c 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 { pub fn find_builtin_macro( ident: &name::Name, krate: CrateId, - ast_id: AstId<ast::MacroCall>, + ast_id: AstId<ast::MacroRules>, ) -> Option<MacroDefId> { let kind = find_by_name(ident)?; @@ -515,12 +515,16 @@ mod tests { fn expand_builtin_macro(ra_fixture: &str) -> String { let (db, file_id) = TestDB::with_single_file(&ra_fixture); let parsed = db.parse(file_id); + let macro_rules: Vec<_> = + parsed.syntax_node().descendants().filter_map(ast::MacroRules::cast).collect(); let macro_calls: Vec<_> = parsed.syntax_node().descendants().filter_map(ast::MacroCall::cast).collect(); let ast_id_map = db.ast_id_map(file_id.into()); - let expander = find_by_name(¯o_calls[0].name().unwrap().as_name()).unwrap(); + assert_eq!(macro_rules.len(), 1, "test must contain exactly 1 `macro_rules!`"); + assert_eq!(macro_calls.len(), 1, "test must contain exactly 1 macro call"); + let expander = find_by_name(¯o_rules[0].name().unwrap().as_name()).unwrap(); let krate = CrateId(0); let file_id = match expander { @@ -528,7 +532,7 @@ mod tests { // the first one should be a macro_rules let def = MacroDefId { krate: Some(CrateId(0)), - ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), + ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules[0]))), kind: MacroDefKind::BuiltIn(expander), local_inner: false, }; @@ -538,7 +542,7 @@ mod tests { krate, kind: MacroCallKind::FnLike(AstId::new( file_id.into(), - ast_id_map.ast_id(¯o_calls[1]), + ast_id_map.ast_id(¯o_calls[0]), )), }; @@ -549,12 +553,12 @@ mod tests { // the first one should be a macro_rules let def = MacroDefId { krate: Some(krate), - ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), + ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_rules[0]))), kind: MacroDefKind::BuiltInEager(expander), local_inner: false, }; - let args = macro_calls[1].token_tree().unwrap(); + let args = macro_calls[0].token_tree().unwrap(); let parsed_args = mbe::ast_to_token_tree(&args).unwrap().0; let arg_id = db.intern_eager_expansion({ diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 1a942851434..ae3086a95bd 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs @@ -228,7 +228,7 @@ pub struct MacroDefId { // (which will probably require touching this code), we can instead use // that (and also remove the hacks for resolving built-in derives). pub krate: Option<CrateId>, - pub ast_id: Option<AstId<ast::MacroCall>>, + pub ast_id: Option<AstId<ast::MacroRules>>, pub kind: MacroDefKind, pub local_inner: bool, diff --git a/crates/hir_ty/src/tests/macros.rs b/crates/hir_ty/src/tests/macros.rs index 597a195d024..de97ec3c206 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() { expect![[r#" !0..6 '1usize': usize 10..89 '{ ...!(); }': () - 16..65 'macro_... }': {unknown} 74..76 '_a': usize "#]], ); diff --git a/crates/ide/src/file_structure.rs b/crates/ide/src/file_structure.rs index 415795e8cde..c5153139142 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> { }; Some(node) }, - ast::MacroCall(it) => { - match it.path().and_then(|it| it.segment()).and_then(|it| it.name_ref()) { - Some(path_segment) if path_segment.text() == "macro_rules" - => decl(it), - _ => None, - } - }, + ast::MacroRules(it) => decl(it), _ => None, } } @@ -380,7 +374,7 @@ fn very_obsolete() {} label: "mc", navigation_range: 284..286, node_range: 271..303, - kind: MACRO_CALL, + kind: MACRO_RULES, detail: None, deprecated: false, }, @@ -389,7 +383,7 @@ fn very_obsolete() {} label: "mcexp", navigation_range: 334..339, node_range: 305..356, - kind: MACRO_CALL, + kind: MACRO_RULES, detail: None, deprecated: false, }, @@ -398,7 +392,7 @@ fn very_obsolete() {} label: "mcexp", navigation_range: 387..392, node_range: 358..409, - kind: MACRO_CALL, + kind: MACRO_RULES, detail: None, deprecated: false, }, diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 66f0f7950f4..675957fff6f 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs @@ -770,7 +770,7 @@ fn foo() { } "#, expect![[r#" - m1 MACRO_CALL FileId(0) 0..46 29..31 Other + m1 MACRO_RULES FileId(0) 0..46 29..31 Other FileId(0) 63..65 StructLiteral FileId(0) 73..75 StructLiteral diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index f5c6eabeffc..990b0f7d955 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -74,6 +74,7 @@ pub(crate) fn highlight( let mut stack = HighlightedRangeStack::new(); let mut current_macro_call: Option<ast::MacroCall> = None; + let mut current_macro_rules: Option<ast::MacroRules> = None; let mut format_string_highlighter = FormatStringHighlighter::default(); let mut macro_rules_highlighter = MacroRulesHighlighter::default(); let mut inside_attribute = false; @@ -106,28 +107,26 @@ pub(crate) fn highlight( binding_hash: None, }); } - if let Some(name) = mc.is_macro_rules() { - macro_rules_highlighter.init(); - if let Some((highlight, binding_hash)) = highlight_element( - &sema, - &mut bindings_shadow_count, - syntactic_name_ref_highlighting, - name.syntax().clone().into(), - ) { - stack.add(HighlightedRange { - range: name.syntax().text_range(), - highlight, - binding_hash, - }); - } - } current_macro_call = Some(mc.clone()); continue; } WalkEvent::Leave(Some(mc)) => { - assert!(current_macro_call == Some(mc)); + assert_eq!(current_macro_call, Some(mc)); current_macro_call = None; format_string_highlighter = FormatStringHighlighter::default(); + } + _ => (), + } + + match event.clone().map(|it| it.into_node().and_then(ast::MacroRules::cast)) { + WalkEvent::Enter(Some(mac)) => { + macro_rules_highlighter.init(); + current_macro_rules = Some(mac); + continue; + } + WalkEvent::Leave(Some(mac)) => { + assert_eq!(current_macro_rules, Some(mac)); + current_macro_rules = None; macro_rules_highlighter = MacroRulesHighlighter::default(); } _ => (), @@ -163,6 +162,12 @@ pub(crate) fn highlight( let range = element.text_range(); + if current_macro_rules.is_some() { + if let Some(tok) = element.as_token() { + macro_rules_highlighter.advance(tok); + } + } + let element_to_highlight = if current_macro_call.is_some() && element.kind() != COMMENT { // Inside a macro -- expand it first let token = match element.clone().into_token() { @@ -173,9 +178,6 @@ pub(crate) fn highlight( let parent = token.parent(); format_string_highlighter.check_for_format_string(&parent); - if let Some(tok) = element.as_token() { - macro_rules_highlighter.advance(tok); - } // We only care Name and Name_ref match (token.kind(), parent.kind()) { @@ -386,10 +388,14 @@ impl HighlightedRangeStack { let mut res = self.stack.pop().unwrap(); res.sort_by_key(|range| range.range.start()); // Check that ranges are sorted and disjoint - assert!(res - .iter() - .zip(res.iter().skip(1)) - .all(|(left, right)| left.range.end() <= right.range.start())); + for (left, right) in res.iter().zip(res.iter().skip(1)) { + assert!( + left.range.end() <= right.range.start(), + "left: {:#?}, right: {:#?}", + left, + right + ); + } res } } 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 396fd46fbde..920956b51f0 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 <span class="comment documentation">/// ```</span> <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"> </span><span class="comment documentation">/// ```</span> -<span class="macro">macro_rules!</span> <span class="macro declaration">noop</span> <span class="punctuation">{</span> +<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">noop</span> <span class="punctuation">{</span> <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> <span class="punctuation">$</span>expr <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 d398e1ec85b..c843b5085d5 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 .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } </style> -<pre><code><span class="macro">macro_rules!</span> <span class="macro declaration">println</span> <span class="punctuation">{</span> +<pre><code><span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">println</span> <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>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>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> <span class="punctuation">}</span><span class="punctuation">)</span> <span class="punctuation">}</span> -#[rustc_builtin_macro] -<span class="macro">macro_rules!</span> <span class="macro declaration">format_args_nl</span> <span class="punctuation">{</span> +<span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span> +<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">format_args_nl</span> <span class="punctuation">{</span> <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> <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> <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 a3b4f20e870..0569cf1e5a7 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 <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> <span class="punctuation">}</span> -<span class="macro">macro_rules!</span> <span class="macro declaration">def_fn</span> <span class="punctuation">{</span> +<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">def_fn</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>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> <span class="punctuation">}</span> @@ -135,13 +135,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd <span class="punctuation">}</span> <span class="punctuation">}</span> -<span class="macro">macro_rules!</span> <span class="macro declaration">noop</span> <span class="punctuation">{</span> +<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">noop</span> <span class="punctuation">{</span> <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> <span class="punctuation">$</span>expr <span class="punctuation">}</span> <span class="punctuation">}</span> -<span class="macro">macro_rules!</span> <span class="macro declaration">keyword_frag</span> <span class="punctuation">{</span> +<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">keyword_frag</span> <span class="punctuation">{</span> <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> <span class="punctuation">}</span> diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index 5d2cd30d1e6..d4a774261c5 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs @@ -217,7 +217,7 @@ impl NameClass { let def: hir::TypeAlias = sema.to_def(&it)?; Some(NameClass::Definition(Definition::ModuleDef(def.into()))) }, - ast::MacroCall(it) => { + ast::MacroRules(it) => { let def = sema.to_def(&it)?; Some(NameClass::Definition(Definition::Macro(def))) }, diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 654df898e93..121063aeab7 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)> { ast::TypeAlias(it) => decl(it), ast::Const(it) => decl(it), ast::Static(it) => decl(it), - ast::MacroCall(it) => { - if it.is_macro_rules().is_some() { - decl(it) - } else { - None - } - }, + ast::MacroRules(it) => decl(it), _ => None, } } diff --git a/crates/mbe/src/mbe_expander.rs b/crates/mbe/src/mbe_expander.rs index 97bce0536f4..a80b73db4c4 100644 --- a/crates/mbe/src/mbe_expander.rs +++ b/crates/mbe/src/mbe_expander.rs @@ -163,7 +163,7 @@ mod tests { fn create_rules(macro_definition: &str) -> crate::MacroRules { let source_file = ast::SourceFile::parse(macro_definition).ok().unwrap(); let macro_definition = - source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); + source_file.syntax().descendants().find_map(ast::MacroRules::cast).unwrap(); let (definition_tt, _) = 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 843054fe854..dff6e98c2da 100644 --- a/crates/mbe/src/tests.rs +++ b/crates/mbe/src/tests.rs @@ -48,7 +48,7 @@ mod rule_parsing { let macro_definition = format!(" macro_rules! m {{ {} }} ", arm_definition); let source_file = ast::SourceFile::parse(¯o_definition).ok().unwrap(); let macro_definition = - source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); + source_file.syntax().descendants().find_map(ast::MacroRules::cast).unwrap(); let (definition_tt, _) = ast_to_token_tree(¯o_definition.token_tree().unwrap()).unwrap(); @@ -1668,7 +1668,7 @@ impl MacroFixture { fn parse_macro_to_tt(ra_fixture: &str) -> tt::Subtree { let source_file = ast::SourceFile::parse(ra_fixture).ok().unwrap(); let macro_definition = - source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); + source_file.syntax().descendants().find_map(ast::MacroRules::cast).unwrap(); let (definition_tt, _) = ast_to_token_tree(¯o_definition.token_tree().unwrap()).unwrap(); diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs index ad29b82f778..8999829b437 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> { T![macro] => { macro_def(p, m); } + IDENT if p.at_contextual_kw("macro_rules") && p.nth(1) == BANG => { + macro_rules(p, m); + } IDENT if p.at_contextual_kw("union") && p.nth(1) == IDENT => { // test union_items // union Foo {} @@ -363,6 +366,34 @@ pub(crate) fn item_list(p: &mut Parser) { m.complete(p, ITEM_LIST); } +fn macro_rules(p: &mut Parser, m: Marker) { + assert!(p.at_contextual_kw("macro_rules")); + p.bump_remap(T![macro_rules]); + p.expect(T![!]); + + if p.at(IDENT) { + name(p); + } + // Special-case `macro_rules! try`. + // This is a hack until we do proper edition support + + // test try_macro_rules + // macro_rules! try { () => {} } + if p.at(T![try]) { + let m = p.start(); + p.bump_remap(IDENT); + m.complete(p, NAME); + } + + match p.current() { + T!['{'] => { + token_tree(p); + } + _ => p.error("expected `{`"), + } + m.complete(p, MACRO_RULES); +} + // test macro_def // macro m { ($i:ident) => {} } // macro m($i:ident) {} @@ -394,19 +425,6 @@ fn macro_call(p: &mut Parser) -> BlockLike { pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike { p.expect(T![!]); - if p.at(IDENT) { - name(p); - } - // Special-case `macro_rules! try`. - // This is a hack until we do proper edition support - - // test try_macro_rules - // macro_rules! try { () => {} } - if p.at(T![try]) { - let m = p.start(); - p.bump_remap(IDENT); - m.complete(p, NAME); - } match p.current() { T!['{'] => { diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs index 8bc6688f3cc..5d6ec17a4cc 100644 --- a/crates/parser/src/syntax_kind/generated.rs +++ b/crates/parser/src/syntax_kind/generated.rs @@ -106,6 +106,7 @@ pub enum SyntaxKind { EXISTENTIAL_KW, UNION_KW, RAW_KW, + MACRO_RULES_KW, INT_NUMBER, FLOAT_NUMBER, CHAR, @@ -135,6 +136,8 @@ pub enum SyntaxKind { IMPL, TYPE_ALIAS, MACRO_CALL, + MACRO_RULES, + MACRO_ARM, TOKEN_TREE, MACRO_DEF, PAREN_TYPE, @@ -258,7 +261,7 @@ impl SyntaxKind { | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | STATIC_KW | STRUCT_KW | SUPER_KW | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW | WHERE_KW | WHILE_KW - | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW | RAW_KW => true, + | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW | RAW_KW | MACRO_RULES_KW => true, _ => false, } } @@ -361,4 +364,4 @@ impl SyntaxKind { } } #[macro_export] -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 } ; } +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 30d11b14649..0ad75214fc4 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -128,7 +128,6 @@ pub struct MacroCall { pub(crate) syntax: SyntaxNode, } impl ast::AttrsOwner for MacroCall {} -impl ast::NameOwner for MacroCall {} impl MacroCall { pub fn path(&self) -> Option<Path> { support::child(&self.syntax) } pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) } @@ -273,6 +272,20 @@ impl Impl { pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MacroRules { + pub(crate) syntax: SyntaxNode, +} +impl ast::AttrsOwner for MacroRules {} +impl ast::NameOwner for MacroRules {} +impl ast::VisibilityOwner for MacroRules {} +impl MacroRules { + pub fn macro_rules_token(&self) -> Option<SyntaxToken> { + support::token(&self.syntax, T![macro_rules]) + } + pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) } + pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) } +} +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Module { pub(crate) syntax: SyntaxNode, } @@ -1318,6 +1331,7 @@ pub enum Item { Fn(Fn), Impl(Impl), MacroCall(MacroCall), + MacroRules(MacroRules), Module(Module), Static(Static), Struct(Struct), @@ -1374,7 +1388,6 @@ pub enum AssocItem { TypeAlias(TypeAlias), } impl ast::AttrsOwner for AssocItem {} -impl ast::NameOwner for AssocItem {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ExternItem { Fn(Fn), @@ -1383,7 +1396,6 @@ pub enum ExternItem { TypeAlias(TypeAlias), } impl ast::AttrsOwner for ExternItem {} -impl ast::NameOwner for ExternItem {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum GenericParam { ConstParam(ConstParam), @@ -1666,6 +1678,17 @@ impl AstNode for Impl { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } +impl AstNode for MacroRules { + fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_RULES } + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} impl AstNode for Module { fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE } fn cast(syntax: SyntaxNode) -> Option<Self> { @@ -3060,6 +3083,9 @@ impl From<Impl> for Item { impl From<MacroCall> for Item { fn from(node: MacroCall) -> Item { Item::MacroCall(node) } } +impl From<MacroRules> for Item { + fn from(node: MacroRules) -> Item { Item::MacroRules(node) } +} impl From<Module> for Item { fn from(node: Module) -> Item { Item::Module(node) } } @@ -3084,8 +3110,8 @@ impl From<Use> for Item { impl AstNode for Item { fn can_cast(kind: SyntaxKind) -> bool { match kind { - CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MODULE - | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true, + CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MACRO_RULES + | MODULE | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true, _ => false, } } @@ -3098,6 +3124,7 @@ impl AstNode for Item { FN => Item::Fn(Fn { syntax }), IMPL => Item::Impl(Impl { syntax }), MACRO_CALL => Item::MacroCall(MacroCall { syntax }), + MACRO_RULES => Item::MacroRules(MacroRules { syntax }), MODULE => Item::Module(Module { syntax }), STATIC => Item::Static(Static { syntax }), STRUCT => Item::Struct(Struct { syntax }), @@ -3118,6 +3145,7 @@ impl AstNode for Item { Item::Fn(it) => &it.syntax, Item::Impl(it) => &it.syntax, Item::MacroCall(it) => &it.syntax, + Item::MacroRules(it) => &it.syntax, Item::Module(it) => &it.syntax, Item::Static(it) => &it.syntax, Item::Struct(it) => &it.syntax, @@ -3582,6 +3610,11 @@ impl std::fmt::Display for Impl { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for MacroRules { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for Module { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 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 820af2d20b0..c59a29eab30 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs @@ -382,21 +382,6 @@ impl ast::Visibility { } } -impl ast::MacroCall { - pub fn is_macro_rules(&self) -> Option<ast::Name> { - let name_ref = self.path()?.segment()?.name_ref()?; - if name_ref.text() == "macro_rules" { - self.name() - } else { - None - } - } - - pub fn is_bang(&self) -> bool { - self.is_macro_rules().is_none() - } -} - impl ast::LifetimeParam { pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> { self.syntax() @@ -476,5 +461,5 @@ impl ast::DocCommentsOwner for ast::Static {} impl ast::DocCommentsOwner for ast::Const {} impl ast::DocCommentsOwner for ast::TypeAlias {} impl ast::DocCommentsOwner for ast::Impl {} -impl ast::DocCommentsOwner for ast::MacroCall {} +impl ast::DocCommentsOwner for ast::MacroRules {} impl ast::DocCommentsOwner for ast::Use {} diff --git a/crates/syntax/src/display.rs b/crates/syntax/src/display.rs index 8d2c7eae447..d33bde30c59 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 { label.trim().to_owned() } -pub fn macro_label(node: &ast::MacroCall) -> String { +pub fn macro_label(node: &ast::MacroRules) -> String { let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default(); let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" }; 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 49842177a8a..ce27c3dd96a 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>( trivias: impl Iterator<Item = (SyntaxKind, &'a str)>, ) -> usize { match kind { - MACRO_CALL | CONST | TYPE_ALIAS | STRUCT | ENUM | VARIANT | FN | TRAIT | MODULE - | RECORD_FIELD | STATIC | USE => { + MACRO_CALL | MACRO_RULES | CONST | TYPE_ALIAS | STRUCT | ENUM | VARIANT | FN | TRAIT + | MODULE | RECORD_FIELD | STATIC | USE => { let mut res = 0; let mut trivias = trivias.enumerate().peekable(); 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 4cfd1bce4b1..9ad5b12b8b8 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 @@ SOURCE_FILE@0..42 IDENT@28..31 "bin" ERROR@31..32 SLASH@31..32 "/" - MACRO_CALL@32..41 + MACRO_CALL@32..35 PATH@32..35 PATH_SEGMENT@32..35 NAME_REF@32..35 IDENT@32..35 "env" - WHITESPACE@35..36 " " - NAME@36..41 - IDENT@36..41 "rusti" + WHITESPACE@35..36 " " + MACRO_CALL@36..41 + PATH@36..41 + PATH_SEGMENT@36..41 + NAME_REF@36..41 + IDENT@36..41 "rusti" WHITESPACE@41..42 "\n" error 23..23: expected `[` error 23..23: expected an item @@ -35,5 +38,8 @@ error 31..31: expected `{`, `[`, `(` error 31..31: expected SEMICOLON error 31..31: expected an item error 35..35: expected BANG +error 35..35: expected `{`, `[`, `(` +error 35..35: expected SEMICOLON +error 41..41: expected BANG error 41..41: expected `{`, `[`, `(` 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 de8217064f1..e4fb32de11c 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 @@ SOURCE_FILE@0..70 L_CURLY@9..10 "{" R_CURLY@10..11 "}" WHITESPACE@11..12 "\n" - MACRO_CALL@12..31 - PATH@12..23 - PATH_SEGMENT@12..23 - NAME_REF@12..23 - IDENT@12..23 "macro_rules" + MACRO_RULES@12..31 + MACRO_RULES_KW@12..23 "macro_rules" BANG@23..24 "!" WHITESPACE@24..25 " " NAME@25..28 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 e757249f06d..e84b9164ff1 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 @@ SOURCE_FILE@0..167 L_CURLY@102..103 "{" R_CURLY@103..104 "}" WHITESPACE@104..109 "\n " - EXPR_STMT@109..152 - MACRO_CALL@109..152 - PATH@109..120 - PATH_SEGMENT@109..120 - NAME_REF@109..120 - IDENT@109..120 "macro_rules" - BANG@120..121 "!" - WHITESPACE@121..122 " " - NAME@122..126 - IDENT@122..126 "test" - WHITESPACE@126..127 " " - TOKEN_TREE@127..152 - L_CURLY@127..128 "{" - WHITESPACE@128..138 "\n " - TOKEN_TREE@138..140 - L_PAREN@138..139 "(" - R_PAREN@139..140 ")" - WHITESPACE@140..141 " " - EQ@141..142 "=" - R_ANGLE@142..143 ">" - WHITESPACE@143..144 " " - TOKEN_TREE@144..146 - L_CURLY@144..145 "{" - R_CURLY@145..146 "}" - WHITESPACE@146..151 "\n " - R_CURLY@151..152 "}" + MACRO_RULES@109..152 + MACRO_RULES_KW@109..120 "macro_rules" + BANG@120..121 "!" + WHITESPACE@121..122 " " + NAME@122..126 + IDENT@122..126 "test" + WHITESPACE@126..127 " " + TOKEN_TREE@127..152 + L_CURLY@127..128 "{" + WHITESPACE@128..138 "\n " + TOKEN_TREE@138..140 + L_PAREN@138..139 "(" + R_PAREN@139..140 ")" + WHITESPACE@140..141 " " + EQ@141..142 "=" + R_ANGLE@142..143 ">" + WHITESPACE@143..144 " " + TOKEN_TREE@144..146 + L_CURLY@144..145 "{" + R_CURLY@145..146 "}" + WHITESPACE@146..151 "\n " + R_CURLY@151..152 "}" WHITESPACE@152..157 "\n " MACRO_CALL@157..164 PATH@157..161 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 05b89d1c369..d1c22947b5e 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 @@ SOURCE_FILE@0..30 - MACRO_CALL@0..29 - PATH@0..11 - PATH_SEGMENT@0..11 - NAME_REF@0..11 - IDENT@0..11 "macro_rules" + MACRO_RULES@0..29 + MACRO_RULES_KW@0..11 "macro_rules" BANG@11..12 "!" WHITESPACE@12..13 " " NAME@13..16 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 be60f7a8ed8..87d8ebcba5b 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 @@ SOURCE_FILE@0..65 - MACRO_CALL@0..64 + MACRO_RULES@0..64 COMMENT@0..13 "/// Some docs" WHITESPACE@13..14 "\n" ATTR@14..29 @@ -11,10 +11,7 @@ SOURCE_FILE@0..65 IDENT@16..28 "macro_export" R_BRACK@28..29 "]" WHITESPACE@29..30 "\n" - PATH@30..41 - PATH_SEGMENT@30..41 - NAME_REF@30..41 - IDENT@30..41 "macro_rules" + MACRO_RULES_KW@30..41 "macro_rules" BANG@41..42 "!" WHITESPACE@42..43 " " NAME@43..46 diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index 8ceaaf60eb4..72a4c10f549 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs @@ -70,7 +70,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { "match", "mod", "move", "mut", "pub", "ref", "return", "self", "static", "struct", "super", "trait", "true", "try", "type", "unsafe", "use", "where", "while", ], - contextual_keywords: &["auto", "default", "existential", "union", "raw"], + contextual_keywords: &["auto", "default", "existential", "union", "raw", "macro_rules"], literals: &["INT_NUMBER", "FLOAT_NUMBER", "CHAR", "BYTE", "STRING", "BYTE_STRING"], tokens: &[ "ERROR", @@ -98,6 +98,8 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { "IMPL", "TYPE_ALIAS", "MACRO_CALL", + "MACRO_RULES", + "MACRO_ARM", "TOKEN_TREE", "MACRO_DEF", "PAREN_TYPE", |
