Skip to content

pretty printer fails to include necessary parens around some block expressions #22450

Closed
@pnkfelix

Description

@pnkfelix

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-prettyArea: Pretty printing (including `-Z unpretty`)C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions