Closed
Description
The pretty printer fails to include necessary parens around some block expressions
In particular, consider this code (stored in /tmp/demo5.rs
):
#![allow(unused_parens)]
macro_rules! add1_block {
($e:expr) => {
{ let val = 1; $e + val }
}
}
macro_rules! add1_paren_block {
($e:expr) => {
({ let val = 1; $e + val })
}
}
fn main() {
let w = add1_block!(2);
let x = { add1_block!(3) as u64 };
let y = add1_paren_block!(4);
let z = { add1_paren_block!(5) as u64 };
println!("w: {} x: {} y: {} z: {}", w, x, y, z);
}
The above code compiles and runs, and you can even run it through the non-expanding pretty printer and compile that and run it:
% ./x86_64-apple-darwin/stage1/bin/rustc /tmp/demo5.rs && ./demo5
w: 3 x: 4 y: 5 z: 6
% rustc -Z unstable-options --pretty=normal /tmp/demo5.rs -o /tmp/demo5_normal.rs && rustc /tmp/demo5_normal.rs && ./demo5_normal
w: 3 x: 4 y: 5 z: 6
%
However, if you apply --pretty=expanded
, then the generated source fails to compile:
% rustc -Z unstable-options --pretty=expanded /tmp/demo5.rs -o /tmp/demo5_expanded.rs && rustc /tmp/demo5_expanded.rs && ./demo5_expanded
/tmp/demo5_expanded.rs:12:40: 12:42 error: expected identifier, found keyword `as`
/tmp/demo5_expanded.rs:12 let x = { { let val = 1; 3 + val } as u64 };
^~
/tmp/demo5_expanded.rs:12:43: 12:46 error: expected one of `!`, `.`, `::`, `;`, `{`, `}`, or an operator, found `u64`
/tmp/demo5_expanded.rs:12 let x = { { let val = 1; 3 + val } as u64 };
^~~
%
The reason for this is that the use of add1_block
within a cast as the last expression of a block is interpreted as a statement, rather than part of an expression. So you need to wrap it in parentheses (the way that add1_paren_block
does) if you want the generated output source to be robust enough to be recompiled.