about summary refs log tree commit diff
path: root/tests/ui-fulldeps/pprust-parenthesis-insertion.rs
AgeCommit message (Collapse)AuthorLines
2025-06-20Add an attribute-related parenthesization edge caseDavid Tolnay-0/+6
2025-06-20Add AST pretty-printer tests involving attr on binary operationDavid Tolnay-0/+9
This test currently fails (as expected). --- stderr ------------------------------- Pretty-printer lost necessary parentheses BEFORE: #[attr] (1 + 1) AFTER: #[attr] 1 + 1 Pretty-printer lost necessary parentheses BEFORE: #[attr] (1 as T) AFTER: #[attr] 1 as T Pretty-printer lost necessary parentheses BEFORE: #[attr] (x = 1) AFTER: #[attr] x = 1 Pretty-printer lost necessary parentheses BEFORE: #[attr] (x += 1) AFTER: #[attr] x += 1 ------------------------------------------
2025-06-19Preserve Paren expression's attributes during UnparenthesizeDavid Tolnay-0/+5
2025-06-17Rollup merge of #142371 - fee1-dead-contrib:push-xqlkumzurkus, r=petrochenkovJacob Pratt-2/+1
avoid `&mut P<T>` in `visit_expr` etc methods trying a different way than rust-lang/rust#141636 r? ghost
2025-06-13Add AST pretty-printer tests involving attr precedenceDavid Tolnay-0/+5
This test currently fails (as expected). --- stderr ------------------------------- Pretty-printer lost necessary parentheses BEFORE: (#[attr] loop {}).field AFTER: #[attr] loop {}.field ------------------------------------------
2025-06-13Rollup merge of #134847 - dtolnay:asymmetrical, r=fmeaseMatthias Krüger-2/+2
Implement asymmetrical precedence for closures and jumps I have been through a series of asymmetrical precedence designs in Syn, and finally have one that I like and is worth backporting into rustc. It is based on just 2 bits of state: `next_operator_can_begin_expr` and `next_operator_can_continue_expr`. Asymmetrical precedence is the thing that enables `(return 1) + 1` to require parentheses while `1 + return 1` does not, despite `+` always having stronger precedence than `return` [according to the Rust Reference](https://doc.rust-lang.org/1.83.0/reference/expressions.html#expression-precedence). This is facilitated by `next_operator_can_continue_expr`. Relatedly, it is the thing that enables `(return) - 1` to require parentheses while `return + 1` does not, despite `+` and `-` having exactly the same precedence. This is facilitated by `next_operator_can_begin_expr`. **Example:** ```rust macro_rules! repro { ($e:expr) => { $e - $e; $e + $e; }; } fn main() { repro!{return} repro!{return 1} } ``` `-Zunpretty=expanded` **Before:** ```console fn main() { (return) - (return); (return) + (return); (return 1) - (return 1); (return 1) + (return 1); } ``` **After:** ```console fn main() { (return) - return; return + return; (return 1) - return 1; (return 1) + return 1; } ```
2025-06-12avoid `&mut P<T>` in `visit_expr` etc methodsDeadbeef-2/+1
2025-05-29remove `visit_clobber` and move `DummyAstNode` to `rustc_expand`Deadbeef-2/+2
`visit_clobber` is not really useful except for one niche purpose involving generic code. We should just use the replace logic where we can.
2025-05-03Implement asymmetrical precedence for closures and jumpsDavid Tolnay-2/+2
2024-12-27Rollup merge of #134834 - dtolnay:unnamedcall, r=compiler-errorsDavid Tolnay-0/+3
Skip parenthesis around tuple struct field calls The pretty-printer previously did not distinguish between named vs unnamed fields when printing a function call containing a struct field. It would print the call as `(self.fun)()` for a named field which is correct, and `(self.0)()` for an unnamed field which is redundant. This PR changes function calls of tuple struct fields to print without parens. **Before:** ```rust struct Tuple(fn()); fn main() { let tuple = Tuple(|| {}); (tuple.0)(); } ``` **After:** ```rust struct Tuple(fn()); fn main() { let tuple = Tuple(|| {}); tuple.0(); } ```
2024-12-27Skip parenthesis around tuple struct field callsDavid Tolnay-1/+1
2024-12-27Add pretty-printer test of tuple field function callDavid Tolnay-0/+3
2024-12-27Skip parenthesis if `.` makes statement boundary unambiguousDavid Tolnay-2/+2
2024-12-27Add test of dot after eager statement boundary exprDavid Tolnay-0/+4
2024-12-22Rollup merge of #134599 - dtolnay:fulldepsparser, r=fmeaseMatthias Krüger-36/+7
Detect invalid exprs in parser used by pretty-printer tests This PR fixes a bug in https://github.com/rust-lang/rust/pull/133730 inherited from https://github.com/rust-lang/rust/pull/43742. Before this fix, the test might silently only operate on a prefix of some of the test cases in this table: https://github.com/rust-lang/rust/blob/13170cd787cb733ed24842ee825bcbd98dc01476/tests/ui-fulldeps/pprust-parenthesis-insertion.rs#L57 For example, adding the test case `1 .. 2 .. 3` (a syntactically invalid expression) into the table would unexpectedly succeed the test instead of crashing at this unwrap: https://github.com/rust-lang/rust/blob/13170cd787cb733ed24842ee825bcbd98dc01476/tests/ui-fulldeps/pprust-parenthesis-insertion.rs#L199-L200 because `parse_expr` would successfully parse just `1 .. 2` and disregard the last `.. 3`. This PR adds a check that `parse_expr` reaches `Eof`, ensuring all the test cases actually test the whole expression they look like they are supposed to.
2024-12-21Show which test case was found to be meaninglessDavid Tolnay-1/+3
2024-12-22Rollup merge of #134601 - dtolnay:dynstar, r=compiler-errorsMatthias Krüger-4/+0
Support pretty-printing `dyn*` trait objects - Tracking issue: https://github.com/rust-lang/rust/issues/102425
2024-12-21Extract ui-fulldeps expression parser into moduleDavid Tolnay-41/+4
2024-12-20Relocate dyn* test out of parenthesis insertion testDavid Tolnay-1/+0
2024-12-20Support pretty-printing dyn* trait objectsDavid Tolnay-3/+0
2024-12-20Change comparison operators to have Fixity::NoneDavid Tolnay-4/+2
2024-12-20Add some parenthesization test cases with operators that are not ↵David Tolnay-0/+8
left-associative
2024-12-20Check that pretty-printer parenthesis test operates on the whole test caseDavid Tolnay-1/+7
2024-12-21Rollup merge of #133782 - dtolnay:closuresjumps, r=spastorino,traviscrossMatthias Krüger-0/+6
Precedence improvements: closures and jumps This PR fixes some cases where rustc's pretty printers would redundantly parenthesize expressions that didn't need it. <table> <tr><th>Before</th><th>After</th></tr> <tr><td><code>return (|x: i32| x)</code></td><td><code>return |x: i32| x</code></td></tr> <tr><td><code>(|| -> &mut () { std::process::abort() }).clone()</code></td><td><code>|| -> &mut () { std::process::abort() }.clone()</code></td></tr> <tr><td><code>(continue) + 1</code></td><td><code>continue + 1</code></td></tr> </table> Tested by `echo "fn main() { let _ = $AFTER; }" | rustc -Zunpretty=expanded /dev/stdin`. The pretty-printer aims to render the syntax tree as it actually exists in rustc, as faithfully as possible, in Rust syntax. It can insert parentheses where forced by Rust's grammar in order to preserve the meaning of a macro-generated syntax tree, for example in the case of `a * $rhs` where $rhs is `b + c`. But for any expression parsed from source code, without a macro involved, there should never be a reason for inserting additional parentheses not present in the original. For closures and jumps (return, break, continue, yield, do yeet, become) the unneeded parentheses came from the precedence of some of these expressions being misidentified. In the same order as the table above: - Jumps and closures are supposed to have equal precedence. The [Rust Reference](https://doc.rust-lang.org/1.83.0/reference/expressions.html#expression-precedence) says so, and in Syn they do. There is no Rust syntax that would require making a precedence distinction between jumps and closures. But in rustc these were previously 2 distinct levels with the closure being lower, hence the parentheses around a closure inside a jump (but not a jump inside a closure). - When a closure is written with an explicit return type, the grammar [requires](https://doc.rust-lang.org/1.83.0/reference/expressions/closure-expr.html) that the closure body consists of exactly one block expression, not any other arbitrary expression as usual for closures. Parsing of the closure body does not continue after the block expression. So in `|| { 0 }.clone()` the clone is inside the closure body and applies to `{ 0 }`, whereas in `|| -> _ { 0 }.clone()` the clone is outside and applies to the closure as a whole. - Continue never needs parentheses. It was previously marked as having the lowest possible precedence but it should have been the highest, next to paths and loops and function calls, not next to jumps.
2024-12-03Visit Stmt span in MutVisitor::flat_map_stmtDavid Tolnay-8/+1
2024-12-03Visit BinOp span in MutVisitor::visit_exprDavid Tolnay-7/+0
2024-12-02Raise precedence of closure that has explicit return typeDavid Tolnay-1/+1
2024-12-02Add test of closure precedence with return typeDavid Tolnay-0/+3
2024-12-02Squash closures and jumps into a single precedence levelDavid Tolnay-1/+1
2024-12-02Add test of closure vs jump precedenceDavid Tolnay-0/+3
2024-12-01Add pretty-printer parenthesis insertion testDavid Tolnay-0/+242