Unnamed repository; edit this file 'description' to name the repository.
Merge #11904
11904: internal: Wrap macros in expr position in `MacroExpr` node r=jonas-schievink a=jonas-schievink This lets us distinguish them from macros in item position just by looking at the syntax tree. Fixes https://github.com/rust-analyzer/rust-analyzer/issues/11854 bors r+ Co-authored-by: Jonas Schievink <[email protected]>
bors[bot] 2022-04-05
parent 5a6918f · parent 872b7b9 · commit b5eaf56
-rw-r--r--crates/hir/src/source_analyzer.rs4
-rw-r--r--crates/hir_def/src/body/lower.rs9
-rw-r--r--crates/hir_def/src/body/tests.rs28
-rw-r--r--crates/hir_def/src/body/tests/block.rs24
-rw-r--r--crates/hir_def/src/item_tree/lower.rs35
-rw-r--r--crates/hir_def/src/macro_expansion_tests/builtin_fn_macro.rs3
-rw-r--r--crates/hir_def/src/macro_expansion_tests/mbe.rs3
-rw-r--r--crates/hir_expand/src/lib.rs29
-rw-r--r--crates/hir_ty/src/tests/regression.rs28
-rw-r--r--crates/ide/src/highlight_related.rs2
-rw-r--r--crates/ide/src/syntax_tree.rs54
-rw-r--r--crates/ide/src/typing.rs11
-rw-r--r--crates/ide_assists/src/handlers/convert_bool_then.rs2
-rw-r--r--crates/ide_assists/src/handlers/extract_function.rs8
-rw-r--r--crates/ide_assists/src/handlers/remove_dbg.rs7
-rw-r--r--crates/ide_db/src/syntax_helpers/node_ext.rs7
-rw-r--r--crates/parser/src/grammar/expressions.rs2
-rw-r--r--crates/parser/src/grammar/expressions/atom.rs4
-rw-r--r--crates/parser/src/syntax_kind/generated.rs1
-rw-r--r--crates/parser/test_data/parser/err/0018_incomplete_fn.rast19
-rw-r--r--crates/parser/test_data/parser/err/0023_mismatched_paren.rast39
-rw-r--r--crates/parser/test_data/parser/inline/ok/0053_path_expr.rast19
-rw-r--r--crates/parser/test_data/parser/inline/ok/0096_no_semi_after_block.rast19
-rw-r--r--crates/parser/test_data/parser/inline/ok/0126_attr_on_expr_stmt.rast19
-rw-r--r--crates/parser/test_data/parser/inline/ok/0159_try_macro_fallback.rast21
-rw-r--r--crates/parser/test_data/parser/ok/0035_weird_exprs.rast701
-rw-r--r--crates/parser/test_data/parser/ok/0042_ufcs_call_list.rast19
-rw-r--r--crates/parser/test_data/parser/ok/0071_stmt_attr_placement.rast19
-rw-r--r--crates/syntax/rust.ungram5
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs36
-rw-r--r--crates/syntax/src/tests/ast_src.rs1
31 files changed, 636 insertions, 542 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 6f5908ceb7..91d02ab5c9 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -110,8 +110,8 @@ impl SourceAnalyzer {
fn expr_id(&self, db: &dyn HirDatabase, expr: &ast::Expr) -> Option<ExprId> {
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 d1cfc501e5..f0cb39ec36 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -506,7 +506,8 @@ impl ExprCollector<'_> {
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 @@ impl ExprCollector<'_> {
}
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 1d84da48fb..c9601f8552 100644
--- a/crates/hir_def/src/body/tests.rs
+++ b/crates/hir_def/src/body/tests.rs
@@ -80,6 +80,34 @@ fn main() { n_nuple!(1,2,3); }
}
#[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.
lower(
diff --git a/crates/hir_def/src/body/tests/block.rs b/crates/hir_def/src/body/tests/block.rs
index da1e99c829..0748212889 100644
--- a/crates/hir_def/src/body/tests/block.rs
+++ b/crates/hir_def/src/body/tests/block.rs
@@ -371,3 +371,27 @@ fn outer() {
"#]],
);
}
+
+#[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 b576815f87..3fa2d9d32c 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -48,22 +48,33 @@ impl<'a> Ctx<'a> {
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 @@ impl<'a> Ctx<'a> {
// 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 919dd6c07f..a28478ff4d 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 2cd70a84c5..c8c7b19aca 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 99cb493f32..537ea087f9 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -885,6 +885,16 @@ impl 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 @@ impl 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 65eb2da5af..be2b733a4b 100644
--- a/crates/hir_ty/src/tests/regression.rs
+++ b/crates/hir_ty/src/tests/regression.rs
@@ -445,34 +445,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(
r#"
diff --git a/crates/ide/src/highlight_related.rs b/crates/ide/src/highlight_related.rs
index baa015354f..84fdbc60f8 100644
--- a/crates/ide/src/highlight_related.rs
+++ b/crates/ide/src/highlight_related.rs
@@ -156,7 +156,7 @@ fn highlight_exit_points(
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 1771b56fe3..9003e7cd34 100644
--- a/crates/ide/src/syntax_tree.rs
+++ b/crates/ide/src/syntax_tree.rs
@@ -163,19 +163,20 @@ fn test() {
- [email protected] "\"\n fn foo() {\n ..."
+ [email protected] "\"\n fn foo() {\n ..."
@@ -214,19 +215,20 @@ fn test() {
}"#,
expect![[r#"
- [email protected] "\"\n fn foo() {\n ..."
+ [email protected] "\"\n fn foo() {\n ..."
"#]],
);
diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs
index 95a774df05..0095012791 100644
--- a/crates/ide/src/typing.rs
+++ b/crates/ide/src/typing.rs
@@ -602,6 +602,17 @@ sdasdasdasdasd
}
#[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 f07fde07c0..f9ec9326b6 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 c26e4b1c75..b2cda87f93 100644
--- a/crates/ide_assists/src/handlers/extract_function.rs
+++ b/crates/ide_assists/src/handlers/extract_function.rs
@@ -649,8 +649,8 @@ impl FunctionBody {
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<bool> {
- 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 ebea2d5dea..01cd32f55c 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::<Option<Vec<ast::Expr>>>()?;
- 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 3d72045838..f011a4a48a 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<ast::Expr>)
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 5d652fb8dc..b063c73a9d 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 e5f8e8199e..d137a02ee8 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<Marker>) -> 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<Marker>) -> 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 297809976e..628fa745e7 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 799720b557..6524d8e8fa 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 1176400634..4064a7a1ff 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 abd8accf41..48e123ab11 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 e4e215593e..f89cc15e72 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 cafd059f24..81b7f2b3cb 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 d11ac22efa..0adb678fa6 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 4ec703e517..9f06e2a945 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 "\n "
+ MOD_KW "mod"
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 "("
+ 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 " "
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 "
+ 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 "("
+ LET_KW "let"
+ WHITESPACE " "
+ AMP "&"
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 "("
+ COLON ":"
+ 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"
+ 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"
- 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 ">"
+ MACRO_EXPR
+ 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 "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 ")"
- 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 ff2121a58a..24a589ca2e 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 81797c35ba..1cafc775cd 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 cb58486eff..4e8d4b478b 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 6f236c01ce..f51282fff4 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -919,6 +919,14 @@ impl LoopExpr {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct MacroExpr {
+ pub(crate) syntax: SyntaxNode,
+}
+impl MacroExpr {
+ pub fn macro_call(&self) -> Option<MacroCall> { 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 @@ impl AstNode for LoopExpr {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
+impl AstNode for MacroExpr {
+ fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_EXPR }
+ 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 MatchExpr {
fn can_cast(kind: SyntaxKind) -> bool { kind == MATCH_EXPR }
fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3313,8 +3332,8 @@ impl From<Literal> for Expr {
impl From<LoopExpr> for Expr {
fn from(node: LoopExpr) -> Expr { Expr::LoopExpr(node) }
}
-impl From<MacroCall> for Expr {
- fn from(node: MacroCall) -> Expr { Expr::MacroCall(node) }
+impl From<MacroExpr> for Expr {
+ fn from(node: MacroExpr) -> Expr { Expr::MacroExpr(node) }
}
impl From<MacroStmts> for Expr {
fn from(node: MacroStmts) -> Expr { Expr::MacroStmts(node) }
@@ -3369,7 +3388,7 @@ impl AstNode for Expr {
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 @@ impl AstNode for Expr {
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 @@ impl AstNode for Expr {
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 @@ impl std::fmt::Display for LoopExpr {
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 e808cb4be4..2f6932a1ad 100644
--- a/crates/syntax/src/tests/ast_src.rs
+++ b/crates/syntax/src/tests/ast_src.rs
@@ -144,6 +144,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
"YIELD_EXPR",
"LET_EXPR",
"UNDERSCORE_EXPR",
+ "MACRO_EXPR",
"MATCH_EXPR",
"MATCH_ARM_LIST",
"MATCH_ARM",