From 872b7b9660d99a2f556d8b53edb489767b386859 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 5 Apr 2022 17:42:07 +0200 Subject: [PATCH] Wrap macros in expr position in `MacroExpr` node --- crates/hir/src/source_analyzer.rs | 4 +- crates/hir_def/src/body/lower.rs | 9 +- crates/hir_def/src/body/tests.rs | 28 + crates/hir_def/src/body/tests/block.rs | 24 + crates/hir_def/src/item_tree/lower.rs | 35 +- .../macro_expansion_tests/builtin_fn_macro.rs | 3 +- .../hir_def/src/macro_expansion_tests/mbe.rs | 3 +- crates/hir_expand/src/lib.rs | 29 +- crates/hir_ty/src/tests/regression.rs | 28 - crates/ide/src/highlight_related.rs | 2 +- crates/ide/src/syntax_tree.rs | 54 +- crates/ide/src/typing.rs | 11 + .../src/handlers/convert_bool_then.rs | 2 +- .../src/handlers/extract_function.rs | 8 +- crates/ide_assists/src/handlers/remove_dbg.rs | 7 +- crates/ide_db/src/syntax_helpers/node_ext.rs | 7 +- crates/parser/src/grammar/expressions.rs | 2 +- crates/parser/src/grammar/expressions/atom.rs | 4 +- crates/parser/src/syntax_kind/generated.rs | 1 + .../parser/err/0018_incomplete_fn.rast | 19 +- .../parser/err/0023_mismatched_paren.rast | 39 +- .../parser/inline/ok/0053_path_expr.rast | 19 +- .../inline/ok/0096_no_semi_after_block.rast | 19 +- .../inline/ok/0126_attr_on_expr_stmt.rast | 19 +- .../inline/ok/0159_try_macro_fallback.rast | 21 +- .../test_data/parser/ok/0035_weird_exprs.rast | 713 +++++++++--------- .../parser/ok/0042_ufcs_call_list.rast | 19 +- .../parser/ok/0071_stmt_attr_placement.rast | 19 +- crates/syntax/rust.ungram | 5 +- crates/syntax/src/ast/generated/nodes.rs | 36 +- crates/syntax/src/tests/ast_src.rs | 1 + 31 files changed, 642 insertions(+), 548 deletions(-) diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index 6f5908ceb70..91d02ab5c93 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -110,8 +110,8 @@ fn body(&self) -> Option<&Body> { fn expr_id(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option { let src = match expr { - ast::Expr::MacroCall(call) => { - self.expand_expr(db, InFile::new(self.file_id, call.clone()))? + ast::Expr::MacroExpr(expr) => { + self.expand_expr(db, InFile::new(self.file_id, expr.macro_call()?.clone()))? } _ => InFile::new(self.file_id, expr.clone()), }; diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index d1cfc501e5f..f0cb39ec362 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs @@ -506,7 +506,8 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option { None => self.alloc_expr(Expr::Missing, syntax_ptr), } } - ast::Expr::MacroCall(e) => { + ast::Expr::MacroExpr(e) => { + let e = e.macro_call()?; let macro_ptr = AstPtr::new(&e); let id = self.collect_macro_call(e, macro_ptr.clone(), true, |this, expansion| { expansion.map(|it| this.collect_expr(it)) @@ -629,7 +630,11 @@ fn collect_stmt(&mut self, s: ast::Stmt) { } let has_semi = stmt.semicolon_token().is_some(); // Note that macro could be expended to multiple statements - if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { + if let Some(ast::Expr::MacroExpr(e)) = stmt.expr() { + let m = match e.macro_call() { + Some(it) => it, + None => return, + }; let macro_ptr = AstPtr::new(&m); let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); diff --git a/crates/hir_def/src/body/tests.rs b/crates/hir_def/src/body/tests.rs index 1d84da48fb9..c9601f85527 100644 --- a/crates/hir_def/src/body/tests.rs +++ b/crates/hir_def/src/body/tests.rs @@ -79,6 +79,34 @@ macro_rules! n_nuple { ); } +#[test] +fn issue_3642_bad_macro_stackover() { + lower( + r#" +#[macro_export] +macro_rules! match_ast { + (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) }; + + (match ($node:expr) { + $( ast::$ast:ident($it:ident) => $res:expr, )* + _ => $catch_all:expr $(,)? + }) => {{ + $( if let Some($it) = ast::$ast::cast($node.clone()) { $res } else )* + { $catch_all } + }}; +} + +fn main() { + let anchor = match_ast! { + match parent { + as => {}, + _ => return None + } + }; +}"#, + ); +} + #[test] fn macro_resolve() { // Regression test for a path resolution bug introduced with inner item handling. diff --git a/crates/hir_def/src/body/tests/block.rs b/crates/hir_def/src/body/tests/block.rs index da1e99c829d..07482128898 100644 --- a/crates/hir_def/src/body/tests/block.rs +++ b/crates/hir_def/src/body/tests/block.rs @@ -371,3 +371,27 @@ mod tests { "#]], ); } + +#[test] +fn stmt_macro_expansion_with_trailing_expr() { + cov_mark::check!(macro_stmt_with_trailing_macro_expr); + check_at( + r#" +macro_rules! mac { + () => { mac!($) }; + ($x:tt) => { fn inner() {} }; +} +fn foo() { + mac!(); + $0 +} + "#, + expect![[r#" + block scope + inner: v + + crate + foo: v + "#]], + ) +} diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index b576815f877..3fa2d9d32cc 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -48,22 +48,33 @@ pub(super) fn lower_module_items(mut self, item_owner: &dyn HasModuleItem) -> It pub(super) fn lower_macro_stmts(mut self, stmts: ast::MacroStmts) -> ItemTree { self.tree.top_level = stmts .statements() - .filter_map(|stmt| match stmt { - ast::Stmt::Item(item) => Some(item), - // Macro calls can be both items and expressions. The syntax library always treats - // them as expressions here, so we undo that. - ast::Stmt::ExprStmt(es) => match es.expr()? { - ast::Expr::MacroCall(call) => { - cov_mark::hit!(macro_call_in_macro_stmts_is_added_to_item_tree); - Some(call.into()) - } + .filter_map(|stmt| { + match stmt { + ast::Stmt::Item(item) => Some(item), + // Macro calls can be both items and expressions. The syntax library always treats + // them as expressions here, so we undo that. + ast::Stmt::ExprStmt(es) => match es.expr()? { + ast::Expr::MacroExpr(expr) => { + cov_mark::hit!(macro_call_in_macro_stmts_is_added_to_item_tree); + Some(expr.macro_call()?.into()) + } + _ => None, + }, _ => None, - }, - _ => None, + } }) .flat_map(|item| self.lower_mod_item(&item)) .collect(); + if let Some(ast::Expr::MacroExpr(tail_macro)) = stmts.expr() { + if let Some(call) = tail_macro.macro_call() { + cov_mark::hit!(macro_stmt_with_trailing_macro_expr); + if let Some(mod_item) = self.lower_mod_item(&call.into()) { + self.tree.top_level.push(mod_item); + } + } + } + self.tree } @@ -75,7 +86,7 @@ pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> ItemTree { // Macro calls can be both items and expressions. The syntax library always treats // them as expressions here, so we undo that. ast::Stmt::ExprStmt(es) => match es.expr()? { - ast::Expr::MacroCall(call) => self.lower_mod_item(&call.into()), + ast::Expr::MacroExpr(expr) => self.lower_mod_item(&expr.macro_call()?.into()), _ => None, }, _ => None, diff --git a/crates/hir_def/src/macro_expansion_tests/builtin_fn_macro.rs b/crates/hir_def/src/macro_expansion_tests/builtin_fn_macro.rs index 919dd6c07f0..a28478ff4d8 100644 --- a/crates/hir_def/src/macro_expansion_tests/builtin_fn_macro.rs +++ b/crates/hir_def/src/macro_expansion_tests/builtin_fn_macro.rs @@ -249,8 +249,7 @@ macro_rules! format_args { fn main() { let _ = - // +errors - format_args!("{} {:?}", a.); + format_args!/*+errors*/("{} {:?}", a.); } "#, expect![[r##" diff --git a/crates/hir_def/src/macro_expansion_tests/mbe.rs b/crates/hir_def/src/macro_expansion_tests/mbe.rs index 2cd70a84c53..c8c7b19acaa 100644 --- a/crates/hir_def/src/macro_expansion_tests/mbe.rs +++ b/crates/hir_def/src/macro_expansion_tests/mbe.rs @@ -530,8 +530,7 @@ macro_rules! m { } fn f() -> i32 { - // +tree - m!{} + m!/*+tree*/{} } "#, expect![[r#" diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 99cb493f327..537ea087f9e 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs @@ -885,6 +885,16 @@ pub fn from_call_site(call: &ast::MacroCall) -> ExpandTo { None => return ExpandTo::Statements, }; + // FIXME: macros in statement position are treated as expression statements, they should + // probably be their own statement kind. The *grand*parent indicates what's valid. + if parent.kind() == MACRO_EXPR + && parent + .parent() + .map_or(true, |p| matches!(p.kind(), EXPR_STMT | STMT_LIST | MACRO_STMTS)) + { + return ExpandTo::Statements; + } + match parent.kind() { MACRO_ITEMS | SOURCE_FILE | ITEM_LIST => ExpandTo::Items, MACRO_STMTS | EXPR_STMT | STMT_LIST => ExpandTo::Statements, @@ -895,23 +905,10 @@ pub fn from_call_site(call: &ast::MacroCall) -> ExpandTo { | CLOSURE_EXPR | FIELD_EXPR | FOR_EXPR | IF_EXPR | INDEX_EXPR | LET_EXPR | MATCH_ARM | MATCH_EXPR | MATCH_GUARD | METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR | RANGE_EXPR | RECORD_EXPR_FIELD | REF_EXPR | RETURN_EXPR | TRY_EXPR - | TUPLE_EXPR | WHILE_EXPR => ExpandTo::Expr, + | TUPLE_EXPR | WHILE_EXPR | MACRO_EXPR => ExpandTo::Expr, _ => { - match ast::LetStmt::cast(parent) { - Some(let_stmt) => { - if let Some(true) = let_stmt.initializer().map(|it| it.syntax() == syn) { - ExpandTo::Expr - } else if let Some(true) = let_stmt.ty().map(|it| it.syntax() == syn) { - ExpandTo::Type - } else { - ExpandTo::Pattern - } - } - None => { - // Unknown , Just guess it is `Items` - ExpandTo::Items - } - } + // Unknown , Just guess it is `Items` + ExpandTo::Items } } } diff --git a/crates/hir_ty/src/tests/regression.rs b/crates/hir_ty/src/tests/regression.rs index 65eb2da5afc..be2b733a4b1 100644 --- a/crates/hir_ty/src/tests/regression.rs +++ b/crates/hir_ty/src/tests/regression.rs @@ -444,34 +444,6 @@ fn test() { ); } -#[test] -fn issue_3642_bad_macro_stackover() { - check_no_mismatches( - r#" -#[macro_export] -macro_rules! match_ast { - (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) }; - - (match ($node:expr) { - $( ast::$ast:ident($it:ident) => $res:expr, )* - _ => $catch_all:expr $(,)? - }) => {{ - $( if let Some($it) = ast::$ast::cast($node.clone()) { $res } else )* - { $catch_all } - }}; -} - -fn main() { - let anchor = match_ast! { - match parent { - as => {}, - _ => return None - } - }; -}"#, - ); -} - #[test] fn issue_3999_slice() { check_infer( diff --git a/crates/ide/src/highlight_related.rs b/crates/ide/src/highlight_related.rs index baa015354f8..84fdbc60f87 100644 --- a/crates/ide/src/highlight_related.rs +++ b/crates/ide/src/highlight_related.rs @@ -156,7 +156,7 @@ fn hl( highlights.push(HighlightedRange { category: None, range: token.text_range() }); } } - ast::Expr::MethodCallExpr(_) | ast::Expr::CallExpr(_) | ast::Expr::MacroCall(_) => { + ast::Expr::MethodCallExpr(_) | ast::Expr::CallExpr(_) | ast::Expr::MacroExpr(_) => { if sema.type_of_expr(&expr).map_or(false, |ty| ty.original.is_never()) { highlights.push(HighlightedRange { category: None, diff --git a/crates/ide/src/syntax_tree.rs b/crates/ide/src/syntax_tree.rs index 1771b56fe38..9003e7cd34d 100644 --- a/crates/ide/src/syntax_tree.rs +++ b/crates/ide/src/syntax_tree.rs @@ -163,19 +163,20 @@ fn foo() { L_CURLY@10..11 "{" WHITESPACE@11..16 "\n " EXPR_STMT@16..58 - MACRO_CALL@16..57 - PATH@16..22 - PATH_SEGMENT@16..22 - NAME_REF@16..22 - IDENT@16..22 "assert" - BANG@22..23 "!" - TOKEN_TREE@23..57 - L_PAREN@23..24 "(" - STRING@24..52 "\"\n fn foo() {\n ..." - COMMA@52..53 "," - WHITESPACE@53..54 " " - STRING@54..56 "\"\"" - R_PAREN@56..57 ")" + MACRO_EXPR@16..57 + MACRO_CALL@16..57 + PATH@16..22 + PATH_SEGMENT@16..22 + NAME_REF@16..22 + IDENT@16..22 "assert" + BANG@22..23 "!" + TOKEN_TREE@23..57 + L_PAREN@23..24 "(" + STRING@24..52 "\"\n fn foo() {\n ..." + COMMA@52..53 "," + WHITESPACE@53..54 " " + STRING@54..56 "\"\"" + R_PAREN@56..57 ")" SEMICOLON@57..58 ";" WHITESPACE@58..59 "\n" R_CURLY@59..60 "}" @@ -214,19 +215,20 @@ fn foo() { }"#, expect![[r#" EXPR_STMT@16..58 - MACRO_CALL@16..57 - PATH@16..22 - PATH_SEGMENT@16..22 - NAME_REF@16..22 - IDENT@16..22 "assert" - BANG@22..23 "!" - TOKEN_TREE@23..57 - L_PAREN@23..24 "(" - STRING@24..52 "\"\n fn foo() {\n ..." - COMMA@52..53 "," - WHITESPACE@53..54 " " - STRING@54..56 "\"\"" - R_PAREN@56..57 ")" + MACRO_EXPR@16..57 + MACRO_CALL@16..57 + PATH@16..22 + PATH_SEGMENT@16..22 + NAME_REF@16..22 + IDENT@16..22 "assert" + BANG@22..23 "!" + TOKEN_TREE@23..57 + L_PAREN@23..24 "(" + STRING@24..52 "\"\n fn foo() {\n ..." + COMMA@52..53 "," + WHITESPACE@53..54 " " + STRING@54..56 "\"\"" + R_PAREN@56..57 ")" SEMICOLON@57..58 ";" "#]], ); diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs index 95a774df05e..00950127910 100644 --- a/crates/ide/src/typing.rs +++ b/crates/ide/src/typing.rs @@ -601,6 +601,17 @@ mod m {} ); } + #[test] + fn noop_in_item_position_with_macro() { + type_char_noop('{', r#"$0println!();"#); + type_char_noop( + '{', + r#" +fn main() $0println!("hello"); +}"#, + ); + } + #[test] fn adds_closing_brace_for_use_tree() { type_char( diff --git a/crates/ide_assists/src/handlers/convert_bool_then.rs b/crates/ide_assists/src/handlers/convert_bool_then.rs index f07fde07c03..f9ec9326b65 100644 --- a/crates/ide_assists/src/handlers/convert_bool_then.rs +++ b/crates/ide_assists/src/handlers/convert_bool_then.rs @@ -111,7 +111,7 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext) -> | ast::Expr::ForExpr(_) | ast::Expr::IfExpr(_) | ast::Expr::LoopExpr(_) - | ast::Expr::MacroCall(_) + | ast::Expr::MacroExpr(_) | ast::Expr::MatchExpr(_) | ast::Expr::PrefixExpr(_) | ast::Expr::RangeExpr(_) diff --git a/crates/ide_assists/src/handlers/extract_function.rs b/crates/ide_assists/src/handlers/extract_function.rs index c26e4b1c751..b2cda87f93e 100644 --- a/crates/ide_assists/src/handlers/extract_function.rs +++ b/crates/ide_assists/src/handlers/extract_function.rs @@ -649,8 +649,8 @@ fn analyze( ast::Expr::PathExpr(path_expr) => { cb(path_expr.path().and_then(|it| it.as_single_name_ref())) } - ast::Expr::MacroCall(call) => { - if let Some(tt) = call.token_tree() { + ast::Expr::MacroExpr(expr) => { + if let Some(tt) = expr.macro_call().and_then(|call| call.token_tree()) { tt.syntax() .children_with_tokens() .flat_map(SyntaxElement::into_token) @@ -923,7 +923,7 @@ fn reference_is_exclusive( /// checks if this expr requires `&mut` access, recurses on field access fn expr_require_exclusive_access(ctx: &AssistContext, expr: &ast::Expr) -> Option { - if let ast::Expr::MacroCall(_) = expr { + if let ast::Expr::MacroExpr(_) = expr { // FIXME: expand macro and check output for mutable usages of the variable? return None; } @@ -1015,7 +1015,7 @@ fn path_element_of_reference( None })?; stdx::always!( - matches!(path, ast::Expr::PathExpr(_) | ast::Expr::MacroCall(_)), + matches!(path, ast::Expr::PathExpr(_) | ast::Expr::MacroExpr(_)), "unexpected expression type for variable usage: {:?}", path ); diff --git a/crates/ide_assists/src/handlers/remove_dbg.rs b/crates/ide_assists/src/handlers/remove_dbg.rs index ebea2d5dea8..01cd32f55c6 100644 --- a/crates/ide_assists/src/handlers/remove_dbg.rs +++ b/crates/ide_assists/src/handlers/remove_dbg.rs @@ -39,15 +39,16 @@ pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { .map(|mut tokens| syntax::hacks::parse_expr_from_str(&tokens.join(""))) .collect::>>()?; - let parent = macro_call.syntax().parent()?; + let macro_expr = ast::MacroExpr::cast(macro_call.syntax().parent()?)?; + let parent = macro_expr.syntax().parent()?; let (range, text) = match &*input_expressions { // dbg!() [] => { match_ast! { match parent { ast::StmtList(__) => { - let range = macro_call.syntax().text_range(); - let range = match whitespace_start(macro_call.syntax().prev_sibling_or_token()) { + let range = macro_expr.syntax().text_range(); + let range = match whitespace_start(macro_expr.syntax().prev_sibling_or_token()) { Some(start) => range.cover_offset(start), None => range, }; diff --git a/crates/ide_db/src/syntax_helpers/node_ext.rs b/crates/ide_db/src/syntax_helpers/node_ext.rs index 3d720458382..f011a4a48a3 100644 --- a/crates/ide_db/src/syntax_helpers/node_ext.rs +++ b/crates/ide_db/src/syntax_helpers/node_ext.rs @@ -62,11 +62,6 @@ pub fn preorder_expr(start: &ast::Expr, cb: &mut dyn FnMut(WalkEvent) match ast::Stmt::cast(node.clone()) { // Don't skip subtree since we want to process the expression child next Some(ast::Stmt::ExprStmt(_)) | Some(ast::Stmt::LetStmt(_)) => (), - // This might be an expression - Some(ast::Stmt::Item(ast::Item::MacroCall(mcall))) => { - cb(WalkEvent::Enter(ast::Expr::MacroCall(mcall))); - preorder.skip_subtree(); - } // skip inner items which might have their own expressions Some(ast::Stmt::Item(_)) => preorder.skip_subtree(), None => { @@ -319,7 +314,7 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) { | ast::Expr::ForExpr(_) | ast::Expr::IndexExpr(_) | ast::Expr::Literal(_) - | ast::Expr::MacroCall(_) + | ast::Expr::MacroExpr(_) | ast::Expr::MacroStmts(_) | ast::Expr::MethodCallExpr(_) | ast::Expr::ParenExpr(_) diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs index 5d652fb8dc8..b063c73a9d6 100644 --- a/crates/parser/src/grammar/expressions.rs +++ b/crates/parser/src/grammar/expressions.rs @@ -552,7 +552,7 @@ fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) { } T![!] if !p.at(T![!=]) => { let block_like = items::macro_call_after_excl(p); - (m.complete(p, MACRO_CALL), block_like) + (m.complete(p, MACRO_CALL).precede(p).complete(p, MACRO_EXPR), block_like) } _ => (m.complete(p, PATH_EXPR), BlockLike::NotBlock), } diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index e5f8e8199e1..d137a02ee83 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -605,6 +605,7 @@ fn try_block_expr(p: &mut Parser, m: Option) -> CompletedMarker { if p.nth_at(1, T![!]) { // test try_macro_fallback // fn foo() { try!(Ok(())); } + let macro_call = p.start(); let path = p.start(); let path_segment = p.start(); let name_ref = p.start(); @@ -613,7 +614,8 @@ fn try_block_expr(p: &mut Parser, m: Option) -> CompletedMarker { path_segment.complete(p, PATH_SEGMENT); path.complete(p, PATH); let _block_like = items::macro_call_after_excl(p); - return m.complete(p, MACRO_CALL); + macro_call.complete(p, MACRO_CALL); + return m.complete(p, MACRO_EXPR); } p.bump(T![try]); diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs index 297809976ee..628fa745e75 100644 --- a/crates/parser/src/syntax_kind/generated.rs +++ b/crates/parser/src/syntax_kind/generated.rs @@ -190,6 +190,7 @@ pub enum SyntaxKind { YIELD_EXPR, LET_EXPR, UNDERSCORE_EXPR, + MACRO_EXPR, MATCH_EXPR, MATCH_ARM_LIST, MATCH_ARM, diff --git a/crates/parser/test_data/parser/err/0018_incomplete_fn.rast b/crates/parser/test_data/parser/err/0018_incomplete_fn.rast index 799720b5574..6524d8e8fa9 100644 --- a/crates/parser/test_data/parser/err/0018_incomplete_fn.rast +++ b/crates/parser/test_data/parser/err/0018_incomplete_fn.rast @@ -104,15 +104,16 @@ SOURCE_FILE IDENT "entries" COLON ":" WHITESPACE " " - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "vec" - BANG "!" - TOKEN_TREE - L_BRACK "[" - R_BRACK "]" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "vec" + BANG "!" + TOKEN_TREE + L_BRACK "[" + R_BRACK "]" WHITESPACE " " R_CURLY "}" R_PAREN ")" diff --git a/crates/parser/test_data/parser/err/0023_mismatched_paren.rast b/crates/parser/test_data/parser/err/0023_mismatched_paren.rast index 1176400634c..4064a7a1ff2 100644 --- a/crates/parser/test_data/parser/err/0023_mismatched_paren.rast +++ b/crates/parser/test_data/parser/err/0023_mismatched_paren.rast @@ -12,26 +12,27 @@ SOURCE_FILE STMT_LIST L_CURLY "{" WHITESPACE "\n " - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "foo" - BANG "!" - WHITESPACE " " - TOKEN_TREE - L_PAREN "(" - WHITESPACE "\n " - IDENT "bar" - COMMA "," + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "foo" + BANG "!" WHITESPACE " " - STRING "\"baz\"" - COMMA "," - WHITESPACE " " - INT_NUMBER "1" - COMMA "," - WHITESPACE " " - FLOAT_NUMBER "2.0" + TOKEN_TREE + L_PAREN "(" + WHITESPACE "\n " + IDENT "bar" + COMMA "," + WHITESPACE " " + STRING "\"baz\"" + COMMA "," + WHITESPACE " " + INT_NUMBER "1" + COMMA "," + WHITESPACE " " + FLOAT_NUMBER "2.0" WHITESPACE "\n " R_CURLY "}" WHITESPACE " " diff --git a/crates/parser/test_data/parser/inline/ok/0053_path_expr.rast b/crates/parser/test_data/parser/inline/ok/0053_path_expr.rast index abd8accf41c..48e123ab11b 100644 --- a/crates/parser/test_data/parser/inline/ok/0053_path_expr.rast +++ b/crates/parser/test_data/parser/inline/ok/0053_path_expr.rast @@ -81,15 +81,16 @@ SOURCE_FILE WHITESPACE " " EQ "=" WHITESPACE " " - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "format" - BANG "!" - TOKEN_TREE - L_PAREN "(" - R_PAREN ")" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "format" + BANG "!" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" R_CURLY "}" diff --git a/crates/parser/test_data/parser/inline/ok/0096_no_semi_after_block.rast b/crates/parser/test_data/parser/inline/ok/0096_no_semi_after_block.rast index e4e215593ee..f89cc15e721 100644 --- a/crates/parser/test_data/parser/inline/ok/0096_no_semi_after_block.rast +++ b/crates/parser/test_data/parser/inline/ok/0096_no_semi_after_block.rast @@ -110,15 +110,16 @@ SOURCE_FILE WHITESPACE "\n " R_CURLY "}" WHITESPACE "\n " - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "test" - BANG "!" - TOKEN_TREE - L_CURLY "{" - R_CURLY "}" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "test" + BANG "!" + TOKEN_TREE + L_CURLY "{" + R_CURLY "}" WHITESPACE "\n" R_CURLY "}" WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast b/crates/parser/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast index cafd059f24c..81b7f2b3cbb 100644 --- a/crates/parser/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast +++ b/crates/parser/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast @@ -35,7 +35,7 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n " EXPR_STMT - MACRO_CALL + MACRO_EXPR ATTR POUND "#" L_BRACK "[" @@ -46,14 +46,15 @@ SOURCE_FILE IDENT "B" R_BRACK "]" WHITESPACE " " - PATH - PATH_SEGMENT - NAME_REF - IDENT "bar" - BANG "!" - TOKEN_TREE - L_CURLY "{" - R_CURLY "}" + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + BANG "!" + TOKEN_TREE + L_CURLY "{" + R_CURLY "}" WHITESPACE "\n " EXPR_STMT BLOCK_EXPR diff --git a/crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rast b/crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rast index d11ac22efa6..0adb678fa65 100644 --- a/crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rast +++ b/crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rast @@ -13,22 +13,23 @@ SOURCE_FILE L_CURLY "{" WHITESPACE " " EXPR_STMT - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "try" - BANG "!" - TOKEN_TREE - L_PAREN "(" - IDENT "Ok" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "try" + BANG "!" TOKEN_TREE L_PAREN "(" + IDENT "Ok" TOKEN_TREE L_PAREN "(" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" R_PAREN ")" R_PAREN ")" - R_PAREN ")" SEMICOLON ";" WHITESPACE " " R_CURLY "}" diff --git a/crates/parser/test_data/parser/ok/0035_weird_exprs.rast b/crates/parser/test_data/parser/ok/0035_weird_exprs.rast index 4ec703e517c..9f06e2a9457 100644 --- a/crates/parser/test_data/parser/ok/0035_weird_exprs.rast +++ b/crates/parser/test_data/parser/ok/0035_weird_exprs.rast @@ -396,24 +396,25 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n " EXPR_STMT - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "assert" - BANG "!" - TOKEN_TREE - L_PAREN "(" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "assert" + BANG "!" TOKEN_TREE L_PAREN "(" - IDENT "i" - DOT "." - IDENT "get" TOKEN_TREE L_PAREN "(" + IDENT "i" + DOT "." + IDENT "get" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" R_PAREN ")" R_PAREN ")" - R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" R_CURLY "}" @@ -887,24 +888,7 @@ SOURCE_FILE PAREN_EXPR L_PAREN "(" BIN_EXPR - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "assert" - BANG "!" - TOKEN_TREE - L_PAREN "(" - TOKEN_TREE - L_PAREN "(" - TRUE_KW "true" - R_PAREN ")" - R_PAREN ")" - WHITESPACE " " - EQ2 "==" - WHITESPACE " " - PAREN_EXPR - L_PAREN "(" + MACRO_EXPR MACRO_CALL PATH PATH_SEGMENT @@ -913,11 +897,30 @@ SOURCE_FILE BANG "!" TOKEN_TREE L_PAREN "(" - IDENT "p" TOKEN_TREE L_PAREN "(" + TRUE_KW "true" R_PAREN ")" R_PAREN ")" + WHITESPACE " " + EQ2 "==" + WHITESPACE " " + PAREN_EXPR + L_PAREN "(" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "assert" + BANG "!" + TOKEN_TREE + L_PAREN "(" + IDENT "p" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" + R_PAREN ")" R_PAREN ")" R_PAREN ")" SEMICOLON ";" @@ -934,22 +937,23 @@ SOURCE_FILE PAREN_EXPR L_PAREN "(" BIN_EXPR - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "assert" - BANG "!" - TOKEN_TREE - L_PAREN "(" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "assert" + BANG "!" TOKEN_TREE L_PAREN "(" - IDENT "p" TOKEN_TREE L_PAREN "(" + IDENT "p" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" R_PAREN ")" R_PAREN ")" - R_PAREN ")" WHITESPACE " " EQ2 "==" WHITESPACE " " @@ -978,19 +982,20 @@ SOURCE_FILE PAREN_EXPR L_PAREN "(" BIN_EXPR - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "println" - BANG "!" - TOKEN_TREE - L_PAREN "(" - STRING "\"{}\"" - COMMA "," - WHITESPACE " " - INT_NUMBER "0" - R_PAREN ")" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "println" + BANG "!" + TOKEN_TREE + L_PAREN "(" + STRING "\"{}\"" + COMMA "," + WHITESPACE " " + INT_NUMBER "0" + R_PAREN ")" WHITESPACE " " EQ2 "==" WHITESPACE " " @@ -1130,16 +1135,17 @@ SOURCE_FILE WHITESPACE " " FAT_ARROW "=>" WHITESPACE " " - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "panic" - BANG "!" - TOKEN_TREE - L_PAREN "(" - STRING "\"wat\"" - R_PAREN ")" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "panic" + BANG "!" + TOKEN_TREE + L_PAREN "(" + STRING "\"wat\"" + R_PAREN ")" WHITESPACE " " R_CURLY "}" WHITESPACE " " @@ -1176,16 +1182,17 @@ SOURCE_FILE WHITESPACE " " EQ "=" WHITESPACE " " - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "println" - BANG "!" - TOKEN_TREE - L_PAREN "(" - STRING "\"lincoln\"" - R_PAREN ")" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "println" + BANG "!" + TOKEN_TREE + L_PAREN "(" + STRING "\"lincoln\"" + R_PAREN ")" SEMICOLON ";" WHITESPACE " " R_CURLY "}" @@ -1204,107 +1211,108 @@ SOURCE_FILE L_CURLY "{" WHITESPACE "\n " EXPR_STMT - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "assert_eq" - BANG "!" - TOKEN_TREE - L_PAREN "(" - IDENT "String" - COLON ":" - COLON ":" - IDENT "from" - TOKEN_TREE - L_PAREN "(" - STRING "\"..................................................\"" - R_PAREN ")" - COMMA "," - WHITESPACE "\n " - IDENT "format" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "assert_eq" BANG "!" TOKEN_TREE L_PAREN "(" - STRING "\"{:?}\"" + IDENT "String" + COLON ":" + COLON ":" + IDENT "from" + TOKEN_TREE + L_PAREN "(" + STRING "\"..................................................\"" + R_PAREN ")" COMMA "," - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE "\n " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." - WHITESPACE " " - DOT "." - DOT "." + WHITESPACE "\n " + IDENT "format" + BANG "!" + TOKEN_TREE + L_PAREN "(" + STRING "\"{:?}\"" + COMMA "," + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE "\n " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + WHITESPACE " " + DOT "." + DOT "." + R_PAREN ")" R_PAREN ")" - R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" R_CURLY "}" @@ -1353,141 +1361,142 @@ SOURCE_FILE L_CURLY "{" WHITESPACE "\n " EXPR_STMT - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "assert_eq" - BANG "!" - TOKEN_TREE - L_PAREN "(" - INT_NUMBER "8u8" - COMMA "," - WHITESPACE " " + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "assert_eq" + BANG "!" TOKEN_TREE - L_CURLY "{" - WHITESPACE "\n " - IDENT "macro_rules" - BANG "!" - WHITESPACE " " - IDENT "u8" + L_PAREN "(" + INT_NUMBER "8u8" + COMMA "," WHITESPACE " " TOKEN_TREE L_CURLY "{" - WHITESPACE "\n " - TOKEN_TREE - L_PAREN "(" - IDENT "u8" - R_PAREN ")" + WHITESPACE "\n " + IDENT "macro_rules" + BANG "!" WHITESPACE " " - EQ "=" - R_ANGLE ">" + IDENT "u8" WHITESPACE " " TOKEN_TREE L_CURLY "{" - WHITESPACE "\n " - MOD_KW "mod" + WHITESPACE "\n " + TOKEN_TREE + L_PAREN "(" + IDENT "u8" + R_PAREN ")" WHITESPACE " " - IDENT "u8" + EQ "=" + R_ANGLE ">" WHITESPACE " " TOKEN_TREE L_CURLY "{" - WHITESPACE "\n " - PUB_KW "pub" - WHITESPACE " " - FN_KW "fn" - WHITESPACE " " - IDENT "u8" - L_ANGLE "<" - LIFETIME_IDENT "'u8" - COLON ":" - WHITESPACE " " - LIFETIME_IDENT "'u8" - WHITESPACE " " - PLUS "+" - WHITESPACE " " - LIFETIME_IDENT "'u8" - R_ANGLE ">" - TOKEN_TREE - L_PAREN "(" - IDENT "u8" - COLON ":" - WHITESPACE " " - AMP "&" - LIFETIME_IDENT "'u8" - WHITESPACE " " - IDENT "u8" - R_PAREN ")" - WHITESPACE " " - MINUS "-" - R_ANGLE ">" - WHITESPACE " " - AMP "&" - LIFETIME_IDENT "'u8" + WHITESPACE "\n " + MOD_KW "mod" WHITESPACE " " IDENT "u8" WHITESPACE " " TOKEN_TREE L_CURLY "{" - WHITESPACE "\n " - STRING "\"u8\"" - SEMICOLON ";" - WHITESPACE "\n " - IDENT "u8" WHITESPACE "\n " + PUB_KW "pub" + WHITESPACE " " + FN_KW "fn" + WHITESPACE " " + IDENT "u8" + L_ANGLE "<" + LIFETIME_IDENT "'u8" + COLON ":" + WHITESPACE " " + LIFETIME_IDENT "'u8" + WHITESPACE " " + PLUS "+" + WHITESPACE " " + LIFETIME_IDENT "'u8" + R_ANGLE ">" + TOKEN_TREE + L_PAREN "(" + IDENT "u8" + COLON ":" + WHITESPACE " " + AMP "&" + LIFETIME_IDENT "'u8" + WHITESPACE " " + IDENT "u8" + R_PAREN ")" + WHITESPACE " " + MINUS "-" + R_ANGLE ">" + WHITESPACE " " + AMP "&" + LIFETIME_IDENT "'u8" + WHITESPACE " " + IDENT "u8" + WHITESPACE " " + TOKEN_TREE + L_CURLY "{" + WHITESPACE "\n " + STRING "\"u8\"" + SEMICOLON ";" + WHITESPACE "\n " + IDENT "u8" + WHITESPACE "\n " + R_CURLY "}" + WHITESPACE "\n " R_CURLY "}" - WHITESPACE "\n " + WHITESPACE "\n " R_CURLY "}" - WHITESPACE "\n " + SEMICOLON ";" + WHITESPACE "\n " R_CURLY "}" + WHITESPACE "\n\n " + IDENT "u8" + BANG "!" + TOKEN_TREE + L_PAREN "(" + IDENT "u8" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n " - R_CURLY "}" - WHITESPACE "\n\n " - IDENT "u8" - BANG "!" - TOKEN_TREE - L_PAREN "(" - IDENT "u8" - R_PAREN ")" - SEMICOLON ";" - WHITESPACE "\n " - LET_KW "let" - WHITESPACE " " - AMP "&" - IDENT "u8" - COLON ":" - WHITESPACE " " - AMP "&" - IDENT "u8" - WHITESPACE " " - EQ "=" - WHITESPACE " " - IDENT "u8" - COLON ":" - COLON ":" - IDENT "u8" - TOKEN_TREE - L_PAREN "(" + LET_KW "let" + WHITESPACE " " AMP "&" - INT_NUMBER "8u8" - R_PAREN ")" - SEMICOLON ";" - WHITESPACE "\n " - CRATE_KW "crate" - COLON ":" - COLON ":" - IDENT "u8" - TOKEN_TREE - L_PAREN "(" - INT_NUMBER "0u8" - R_PAREN ")" - SEMICOLON ";" - WHITESPACE "\n " - IDENT "u8" - WHITESPACE "\n " - R_CURLY "}" - R_PAREN ")" + IDENT "u8" + COLON ":" + WHITESPACE " " + AMP "&" + IDENT "u8" + WHITESPACE " " + EQ "=" + WHITESPACE " " + IDENT "u8" + COLON ":" + COLON ":" + IDENT "u8" + TOKEN_TREE + L_PAREN "(" + AMP "&" + INT_NUMBER "8u8" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n " + CRATE_KW "crate" + COLON ":" + COLON ":" + IDENT "u8" + TOKEN_TREE + L_PAREN "(" + INT_NUMBER "0u8" + R_PAREN ")" + SEMICOLON ";" + WHITESPACE "\n " + IDENT "u8" + WHITESPACE "\n " + R_CURLY "}" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n " R_CURLY "}" @@ -1508,69 +1517,70 @@ SOURCE_FILE L_CURLY "{" WHITESPACE "\n " EXPR_STMT - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "assert_eq" - BANG "!" - TOKEN_TREE - L_PAREN "(" - IDENT "String" - COLON ":" - COLON ":" - IDENT "from" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "assert_eq" + BANG "!" TOKEN_TREE L_PAREN "(" - STRING "\"><>\"" + IDENT "String" + COLON ":" + COLON ":" + IDENT "from" + TOKEN_TREE + L_PAREN "(" + STRING "\"><>\"" + R_PAREN ")" + COMMA "," + WHITESPACE "\n " + IDENT "String" + COLON ":" + COLON ":" + L_ANGLE "<" + R_ANGLE ">" + COLON ":" + COLON ":" + IDENT "from" + COLON ":" + COLON ":" + L_ANGLE "<" + R_ANGLE ">" + TOKEN_TREE + L_PAREN "(" + STRING "\"><>\"" + R_PAREN ")" + DOT "." + IDENT "chars" + COLON ":" + COLON ":" + L_ANGLE "<" + R_ANGLE ">" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" + DOT "." + IDENT "rev" + COLON ":" + COLON ":" + L_ANGLE "<" + R_ANGLE ">" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" + DOT "." + IDENT "collect" + COLON ":" + COLON ":" + L_ANGLE "<" + IDENT "String" + R_ANGLE ">" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" R_PAREN ")" - COMMA "," - WHITESPACE "\n " - IDENT "String" - COLON ":" - COLON ":" - L_ANGLE "<" - R_ANGLE ">" - COLON ":" - COLON ":" - IDENT "from" - COLON ":" - COLON ":" - L_ANGLE "<" - R_ANGLE ">" - TOKEN_TREE - L_PAREN "(" - STRING "\"><>\"" - R_PAREN ")" - DOT "." - IDENT "chars" - COLON ":" - COLON ":" - L_ANGLE "<" - R_ANGLE ">" - TOKEN_TREE - L_PAREN "(" - R_PAREN ")" - DOT "." - IDENT "rev" - COLON ":" - COLON ":" - L_ANGLE "<" - R_ANGLE ">" - TOKEN_TREE - L_PAREN "(" - R_PAREN ")" - DOT "." - IDENT "collect" - COLON ":" - COLON ":" - L_ANGLE "<" - IDENT "String" - R_ANGLE ">" - TOKEN_TREE - L_PAREN "(" - R_PAREN ")" - R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" R_CURLY "}" @@ -1741,17 +1751,18 @@ SOURCE_FILE SEMICOLON ";" WHITESPACE "\n " EXPR_STMT - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "assert" - BANG "!" - TOKEN_TREE - L_PAREN "(" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "assert" BANG "!" - IDENT "val" - R_PAREN ")" + TOKEN_TREE + L_PAREN "(" + BANG "!" + IDENT "val" + R_PAREN ")" SEMICOLON ";" WHITESPACE "\n" R_CURLY "}" diff --git a/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast b/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast index ff2121a58a6..24a589ca2e1 100644 --- a/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast +++ b/crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast @@ -42,15 +42,16 @@ SOURCE_FILE STMT_LIST L_CURLY "{" WHITESPACE "\n " - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "unimplemented" - BANG "!" - TOKEN_TREE - L_PAREN "(" - R_PAREN ")" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "unimplemented" + BANG "!" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" WHITESPACE "\n " R_CURLY "}" WHITESPACE "\n" diff --git a/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast b/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast index 81797c35ba1..1cafc775cdf 100644 --- a/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast +++ b/crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast @@ -38,15 +38,16 @@ SOURCE_FILE IDENT "B" R_BRACK "]" WHITESPACE " " - MACRO_CALL - PATH - PATH_SEGMENT - NAME_REF - IDENT "bar" - BANG "!" - TOKEN_TREE - L_PAREN "(" - R_PAREN ")" + MACRO_EXPR + MACRO_CALL + PATH + PATH_SEGMENT + NAME_REF + IDENT "bar" + BANG "!" + TOKEN_TREE + L_PAREN "(" + R_PAREN ")" QUESTION "?" WHITESPACE " " R_CURLY "}" diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram index cb58486eff0..4e8d4b478b5 100644 --- a/crates/syntax/rust.ungram +++ b/crates/syntax/rust.ungram @@ -342,7 +342,7 @@ Expr = | IndexExpr | Literal | LoopExpr -| MacroCall +| MacroExpr | MacroStmts | MatchExpr | MethodCallExpr @@ -360,6 +360,9 @@ Expr = | LetExpr | UnderscoreExpr +MacroExpr = + MacroCall + Literal = Attr* value:( 'int_number' | 'float_number' diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 6f236c01ce1..f51282fff48 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -918,6 +918,14 @@ impl LoopExpr { pub fn loop_token(&self) -> Option { support::token(&self.syntax, T![loop]) } } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct MacroExpr { + pub(crate) syntax: SyntaxNode, +} +impl MacroExpr { + pub fn macro_call(&self) -> Option { support::child(&self.syntax) } +} + #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct MatchExpr { pub(crate) syntax: SyntaxNode, @@ -1518,7 +1526,7 @@ pub enum Expr { IndexExpr(IndexExpr), Literal(Literal), LoopExpr(LoopExpr), - MacroCall(MacroCall), + MacroExpr(MacroExpr), MacroStmts(MacroStmts), MatchExpr(MatchExpr), MethodCallExpr(MethodCallExpr), @@ -2532,6 +2540,17 @@ fn cast(syntax: SyntaxNode) -> Option { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } +impl AstNode for MacroExpr { + fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_EXPR } + fn cast(syntax: SyntaxNode) -> Option { + if Self::can_cast(syntax.kind()) { + Some(Self { syntax }) + } else { + None + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} impl AstNode for MatchExpr { fn can_cast(kind: SyntaxKind) -> bool { kind == MATCH_EXPR } fn cast(syntax: SyntaxNode) -> Option { @@ -3313,8 +3332,8 @@ fn from(node: Literal) -> Expr { Expr::Literal(node) } impl From for Expr { fn from(node: LoopExpr) -> Expr { Expr::LoopExpr(node) } } -impl From for Expr { - fn from(node: MacroCall) -> Expr { Expr::MacroCall(node) } +impl From for Expr { + fn from(node: MacroExpr) -> Expr { Expr::MacroExpr(node) } } impl From for Expr { fn from(node: MacroStmts) -> Expr { Expr::MacroStmts(node) } @@ -3369,7 +3388,7 @@ fn can_cast(kind: SyntaxKind) -> bool { match kind { ARRAY_EXPR | AWAIT_EXPR | BIN_EXPR | BLOCK_EXPR | BOX_EXPR | BREAK_EXPR | CALL_EXPR | CAST_EXPR | CLOSURE_EXPR | CONTINUE_EXPR | FIELD_EXPR | FOR_EXPR | IF_EXPR - | INDEX_EXPR | LITERAL | LOOP_EXPR | MACRO_CALL | MACRO_STMTS | MATCH_EXPR + | INDEX_EXPR | LITERAL | LOOP_EXPR | MACRO_EXPR | MACRO_STMTS | MATCH_EXPR | METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR | RANGE_EXPR | RECORD_EXPR | REF_EXPR | RETURN_EXPR | TRY_EXPR | TUPLE_EXPR | WHILE_EXPR | YIELD_EXPR | LET_EXPR | UNDERSCORE_EXPR => true, @@ -3394,7 +3413,7 @@ fn cast(syntax: SyntaxNode) -> Option { INDEX_EXPR => Expr::IndexExpr(IndexExpr { syntax }), LITERAL => Expr::Literal(Literal { syntax }), LOOP_EXPR => Expr::LoopExpr(LoopExpr { syntax }), - MACRO_CALL => Expr::MacroCall(MacroCall { syntax }), + MACRO_EXPR => Expr::MacroExpr(MacroExpr { syntax }), MACRO_STMTS => Expr::MacroStmts(MacroStmts { syntax }), MATCH_EXPR => Expr::MatchExpr(MatchExpr { syntax }), METHOD_CALL_EXPR => Expr::MethodCallExpr(MethodCallExpr { syntax }), @@ -3433,7 +3452,7 @@ fn syntax(&self) -> &SyntaxNode { Expr::IndexExpr(it) => &it.syntax, Expr::Literal(it) => &it.syntax, Expr::LoopExpr(it) => &it.syntax, - Expr::MacroCall(it) => &it.syntax, + Expr::MacroExpr(it) => &it.syntax, Expr::MacroStmts(it) => &it.syntax, Expr::MatchExpr(it) => &it.syntax, Expr::MethodCallExpr(it) => &it.syntax, @@ -4506,6 +4525,11 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for MacroExpr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for MatchExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/crates/syntax/src/tests/ast_src.rs b/crates/syntax/src/tests/ast_src.rs index e808cb4be44..2f6932a1add 100644 --- a/crates/syntax/src/tests/ast_src.rs +++ b/crates/syntax/src/tests/ast_src.rs @@ -144,6 +144,7 @@ pub(crate) struct KindsSrc<'a> { "YIELD_EXPR", "LET_EXPR", "UNDERSCORE_EXPR", + "MACRO_EXPR", "MATCH_EXPR", "MATCH_ARM_LIST", "MATCH_ARM",