Skip to content

Pretty-printing adds additional parentheses, breaking the proc-macro reparse check #75734

Closed
@Aaron1011

Description

@Aaron1011

The following code:

fn main() {
    &|_: u8| {};
}

is pretty-printed as:

fn main() { &(|_: u8| { }); }

The extra parenthesis completely change the structure of the re-parsed TokenStream (we now have tokens wrapped in a TokenTree::Delimited), breaking the pretty-print and reparse check done during proc-macro expansion. This results in an instance of #43081.

This behavior was introduced by #43742. The PR description states that is intended to "make pprust easier to use with programmatically constructed ASTs." - however, I can't find a concrete example of code that is affected by this.

I see a few possible ways of fixing this:

  1. Try to ignore this type of 'unnecessary' parentheses when we compare the original and re-parsed tokens. This seems extremely difficult, since we can't know which parenthesis are necessary without actually parsing the TokenStream.
  2. Skip inserting these extra parentheses during pretty-printing for proc-macro expansion, but insert them during all other pretty-printing. This should work correctly, but represents yet another hack needed by the pretty-print/reparsing code.
  3. Partially revert pprust: fix parenthesization of exprs #43742 - we would still insert parenthesis when pretty-printing the HIR, but we would rely solely on ExprKind::Paren when pretty-printing the AST. I'm not exactly certain what the consequences of doing this are. Do we ever end up pretty-printing code-generated AST nodes (e.g. from builtin macros), other than when explicitly requested via -Z unpretty=expanded?

If we could get it to work without breaking anything, solution 3 seems like the cleanest way of solving this.

cc @petrochenkov

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-prettyArea: Pretty printing (including `-Z unpretty`)A-proc-macrosArea: Procedural macros

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions