| //@ compile-flags: -Zunpretty=expanded |
| //@ check-pass |
| |
| // This test covers the AST pretty-printer's insertion of parentheses in some |
| // macro metavariable edge cases. Synthetic parentheses (i.e. not appearing in |
| // the syntax tree) need to be printed in order for the printed code to be valid |
| // Rust syntax. We also test negative cases: the pretty-printer should not be |
| // synthesizing parentheses indiscriminately; only where necessary. |
| |
| #![feature(let_chains)] |
| #![feature(if_let_guard)] |
| |
| macro_rules! expr { |
| ($expr:expr) => { $expr }; |
| } |
| |
| macro_rules! stmt { |
| ($stmt:stmt) => { $stmt }; |
| } |
| |
| fn break_labeled_loop() { |
| let no_paren = 'outer: loop { |
| break 'outer expr!('inner: loop { break 'inner 1; } + 1); |
| }; |
| |
| let paren_around_break_value = 'outer: loop { |
| break expr!('inner: loop { break 'inner 1; } + 1); |
| }; |
| |
| macro_rules! breaking { |
| ($value:expr) => { |
| break $value |
| }; |
| } |
| |
| let paren_around_break_value = loop { |
| breaking!('inner: loop { break 'inner 1; } + 1); |
| }; |
| } |
| |
| fn if_let() { |
| macro_rules! if_let { |
| ($pat:pat, $expr:expr) => { |
| if let $pat = $expr {} |
| }; |
| } |
| |
| if let no_paren = true && false {} |
| if_let!(paren_around_binary, true && false); |
| if_let!(no_paren, true); |
| |
| struct Struct {} |
| match () { |
| _ if let no_paren = Struct {} => {} |
| } |
| } |
| |
| fn let_else() { |
| let no_paren = expr!(1 + 1) else { return; }; |
| let paren_around_loop = expr!(loop {}) else { return; }; |
| } |
| |
| fn local() { |
| macro_rules! let_expr_minus_one { |
| ($pat:pat, $expr:expr) => { |
| let $pat = $expr - 1; |
| }; |
| } |
| |
| let void; |
| let_expr_minus_one!(no_paren, match void {}); |
| |
| macro_rules! let_expr_else_return { |
| ($pat:pat, $expr:expr) => { |
| let $pat = $expr else { return; }; |
| }; |
| } |
| |
| let_expr_else_return!(no_paren, void()); |
| } |
| |
| fn match_arm() { |
| macro_rules! match_arm { |
| ($pat:pat, $expr:expr) => { |
| match () { $pat => $expr } |
| }; |
| } |
| |
| match_arm!(no_paren, 1 - 1); |
| match_arm!(paren_around_brace, { 1 } - 1); |
| } |
| |
| /// https://github.com/rust-lang/rust/issues/98790 |
| fn stmt_boundary() { |
| macro_rules! expr_as_stmt { |
| ($expr:expr) => { |
| stmt!($expr) |
| }; |
| } |
| |
| let paren_around_match; |
| expr_as_stmt!(match paren_around_match {} | true); |
| |
| macro_rules! minus_one { |
| ($expr:expr) => { |
| expr_as_stmt!($expr - 1) |
| }; |
| } |
| |
| let (no_paren, paren_around_loop); |
| minus_one!(no_paren); |
| minus_one!(match paren_around_match {}); |
| minus_one!(match paren_around_match {}()); |
| minus_one!(match paren_around_match {}[0]); |
| minus_one!(loop { break paren_around_loop; }); |
| } |
| |
| fn vis_inherited() { |
| macro_rules! vis_inherited { |
| ($vis:vis struct) => { |
| $vis struct Struct; |
| }; |
| } |
| |
| vis_inherited!(struct); |
| } |