Parenthesize block-like expressions in index base of pretty printer#154057
Parenthesize block-like expressions in index base of pretty printer#154057rust-bors[bot] merged 3 commits intorust-lang:mainfrom
Conversation
|
r? @BoxyUwU rustbot has assigned @BoxyUwU. Use Why was this reviewer chosen?The reviewer was selected based on:
|
This comment has been minimized.
This comment has been minimized.
ea61981 to
3a4869b
Compare
|
r? compiler |
|
r? fmease |
There was a problem hiding this comment.
Could you also fix Call exprs? They exhibit the same behavior. E.g.,
macro_rules! group { ($e:expr) => { $e } }
fn scope() { &group!({ drop })(0); }The AST pretty printer produces invalid Rust when a block expression is
the base of an index operation inside a macro expansion. This is a gap
in the existing `FixupContext` parenthesization machinery — the approach
handles statement position but not the case where a block-index is
nested inside another expression.
The following is a correct program:
```rust
macro_rules! block_arr {
() => {{ [0u8; 4] }};
}
macro_rules! as_slice {
() => {{ &block_arr!()[..] }};
}
fn main() { let _: &[u8] = as_slice!(); }
```
But `rustc -Zunpretty=expanded` produces output that is not valid Rust,
because the closing brace of `{ [0u8; 4] }` creates a statement
boundary, causing the parser to treat `[..]` as a separate expression:
```rust
fn main() { let _: &[u8] = { &{ [0u8; 4] }[..] }; }
```
```
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `[`
```
Fixed output after this change:
```rust
fn main() { let _: &[u8] = { &({ [0u8; 4] })[..] }; }
```
Since `{ ... }[...]` never parses as indexing a block regardless of
context, the fix unconditionally parenthesizes "complete" expressions
(block, match, if, loop, etc.) when they appear as the base of an index
operation.
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.
3a4869b to
56f43b5
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
There was a problem hiding this comment.
tests/pretty/block-index-paren.rs → tests/pretty/block-index-or-call-paren.rs or sth. like that?
Then I'll put it into the queue.
|
Thanks! @bors r+ rollup |
…uwer Rollup of 6 pull requests Successful merges: - #154912 (Remove `BuiltinLintDiag`) - #154598 (test `#[naked]` with `#[link_section = "..."]` on windows) - #154719 (Hexagon inline asm: add reg_pair, vreg, vreg_pair, and qreg register classes) - #154057 (Parenthesize block-like expressions in index base of pretty printer) - #154893 (make `expected_literal` positive) - #155002 (Clarify that `core::range` ranges do not have special syntax)
Rollup merge of #154057 - aytey:fix-block-index-paren, r=fmease Parenthesize block-like expressions in index base of pretty printer The AST pretty printer produces invalid Rust when a block expression is the base of an index operation inside a macro expansion. This is a gap in the parenthesization fix from #119105 — the `FixupContext` approach handles statement position but not the case where a block-index is nested inside another expression. The following is a correct program: ```rust macro_rules! block_arr { () => {{ [0u8; 4] }}; } macro_rules! as_slice { () => {{ &block_arr!()[..] }}; } fn main() { let _: &[u8] = as_slice!(); } ``` But `rustc -Zunpretty=expanded` produces output that is not valid Rust, because the closing brace of `{ [0u8; 4] }` creates a statement boundary, causing the parser to treat `[..]` as a separate expression: ```rust fn main() { let _: &[u8] = { &{ [0u8; 4] }[..] }; } ``` ``` error: expected one of `.`, `;`, `?`, `}`, or an operator, found `[` ``` Fixed output after this change: ```rust fn main() { let _: &[u8] = { &({ [0u8; 4] })[..] }; } ``` Since `{ ... }[...]` never parses as indexing a block regardless of context, the fix unconditionally parenthesizes "complete" expressions (block, match, if, loop, etc.) when they appear as the base of an index operation.
The AST pretty printer produces invalid Rust when a block expression is the base of an index operation inside a macro expansion. This is a gap in the parenthesization fix from #119105 — the
FixupContextapproach handles statement position but not the case where a block-index is nested inside another expression.The following is a correct program:
But
rustc -Zunpretty=expandedproduces output that is not valid Rust, because the closing brace of{ [0u8; 4] }creates a statement boundary, causing the parser to treat[..]as a separate expression:Fixed output after this change:
Since
{ ... }[...]never parses as indexing a block regardless of context, the fix unconditionally parenthesizes "complete" expressions (block, match, if, loop, etc.) when they appear as the base of an index operation.