From 56f43b5142ff41a450e85ff241778fe45eb988e2 Mon Sep 17 00:00:00 2001 From: "Andrew V. Teylu" Date: Wed, 8 Apr 2026 14:52:01 +0100 Subject: [PATCH] Parenthesize block-like expressions in call callee of pretty printer When a macro expands to a call whose callee is a block (or other "complete" expression like `match`, `if`, `loop`), the AST pretty printer emits the callee without parentheses. In statement position the closing brace ends the expression and the argument list is parsed as a separate tuple expression, producing a parse error. --- compiler/rustc_ast_pretty/src/pprust/state/expr.rs | 10 +++++++++- tests/pretty/block-index-paren.pp | 4 ++++ tests/pretty/block-index-paren.rs | 6 ++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index f0f8dfa0a67e..701152e9f952 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -235,7 +235,15 @@ fn print_expr_call(&mut self, func: &ast::Expr, args: &[Box], fixup: // In order to call a named field, needs parens: `(self.fun)()` // But not for an unnamed field: `self.0()` ast::ExprKind::Field(_, name) => !name.is_numeric(), - _ => func_fixup.precedence(func) < ExprPrecedence::Unambiguous, + // Block-like expressions (block, match, if, loop, ...) never + // parse as the callee of a call, regardless of context: the + // closing brace ends the expression and `(args)` becomes a + // separate tuple. Parenthesize them so the call survives a + // pretty-print round trip. + _ => { + func_fixup.precedence(func) < ExprPrecedence::Unambiguous + || classify::expr_is_complete(func) + } }; self.print_expr_cond_paren(func, needs_paren, func_fixup); diff --git a/tests/pretty/block-index-paren.pp b/tests/pretty/block-index-paren.pp index 65c61bd68e14..e5ad92be082f 100644 --- a/tests/pretty/block-index-paren.pp +++ b/tests/pretty/block-index-paren.pp @@ -10,4 +10,8 @@ macro_rules! block_arr { () => {{ [0u8; 4] }}; } macro_rules! as_slice { () => {{ &block_arr!()[..] }}; } +macro_rules! group { ($e:expr) => { $e }; } + +fn scope() { &({ drop })(0); } + fn main() { let _: &[u8] = { &({ [0u8; 4] })[..] }; } diff --git a/tests/pretty/block-index-paren.rs b/tests/pretty/block-index-paren.rs index 7ec05059fc1d..71e1cdff7b79 100644 --- a/tests/pretty/block-index-paren.rs +++ b/tests/pretty/block-index-paren.rs @@ -9,4 +9,10 @@ macro_rules! as_slice { () => {{ &block_arr!()[..] }}; } +macro_rules! group { + ($e:expr) => { $e }; +} + +fn scope() { &group!({ drop })(0); } + fn main() { let _: &[u8] = as_slice!(); }