- 
                Notifications
    You must be signed in to change notification settings 
- Fork 13.9k
Closed
Labels
C-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
// repro.rs
macro_rules! repro {
    () => {
        match () {
            () => true,
        }
    };
}
pub fn repro() -> bool {
    repro!() | true
}$ rustc --edition=2021 -Zunpretty=expanded lib.rs 
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
macro_rules! repro { () => { match() { () => true, } } ; }
pub fn repro() -> bool { match () { () => true, } | true }Another manifestation of the exact same pretty printer bug (in case this one is easier to incorporate into the test suite):
macro_rules! stringify_item {
    ($item:item) => {
        stringify!($item)
    };
}
macro_rules! repro {
    ($expr:expr) => {
        stringify_item! {
            pub fn repro() -> bool {
                $expr
            }
        }
    };
}
fn main() {
    println!("{}", repro!(match () { () => true } | true));
}$ cargo run
pub fn repro() -> bool { match () { () => true, } | true }The repro function in each of these outputs is syntactically invalid code, which is not what -Zunpretty=expanded or stringify! should be creating.
error: expected one of `...`, `..=`, `..`, `:`, or `|`, found `}`
 --> src/lib.rs:1:58
  |
1 | pub fn repro() -> bool { match () { () => true, } | true }
  |                                                          ^ expected one of `...`, `..=`, `..`, `:`, or `|`
  |
help: parentheses are required to parse this as an expression
  |
1 | pub fn repro() -> bool { (match () { () => true, }) | true }
  |                          +                        +
error[E0308]: mismatched types
 --> src/lib.rs:1:26
  |
1 | pub fn repro() -> bool { match () { () => true, } | true }
  |                          ^^^^^^^^^^^^^^^^^^^^^^^^- help: consider using a semicolon here
  |                          |
  |                          expected `()`, found `bool`The correct output in both cases would be either of the following syntactically valid outputs:
pub fn repro() -> bool { (match () { () => true, }) | true }pub fn repro() -> bool { (match () { () => true, } | true) }The rustc pretty printer already does parenthesis insertion in similar scenarios so it is a bug that it is not doing it here. For example:
// lib.rs
struct Struct {}
macro_rules! repro {
    () => {
        Struct {}
    };
}
pub fn repro() -> bool {
    match repro!() {
        _ => {}
    }
}$ rustc --edition=2021 -Zunpretty=expanded src/lib.rs 
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
struct Struct {}
macro_rules! repro { () => { Struct {} } ; }
pub fn repro() -> bool { match (Struct {}) { _ => {} } }Notice that the pretty printer put parens around Struct {} because match Struct {} { _ => {} } would not have been valid syntax.
Metadata
Metadata
Assignees
Labels
C-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.