Closed
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.