Auto merge of #119427 - dtolnay:maccall, r=compiler-errors
Fix, document, and test parser and pretty-printer edge cases related to braced macro calls _Review note: this is a deceptively small PR because it comes with 145 lines of docs and 196 lines of tests, and only 25 lines of compiler code changed. However, I recommend reviewing it 1 commit at a time because much of the effect of the code changes is non-local i.e. affecting code that is not visible in the final state of the PR. I have paid attention that reviewing the PR one commit at a time is as easy as I can make it. All of the code you need to know about is touched in those commits, even if some of those changes disappear by the end of the stack._ This is a follow-up to https://github.com/rust-lang/rust/pull/119105. One case that is not relevant to `-Zunpretty=expanded`, but which came up as I'm porting #119105 and #118726 into `syn`'s printer and `prettyplease`'s printer where it **is** relevant, and is also relevant to rustc's `stringify!`, is statement boundaries in the vicinity of braced macro calls. Rustc's AST pretty-printer produces invalid syntax for statements that begin with a braced macro call: ```rust macro_rules! stringify_item { ($i:item) => { stringify!($i) }; } macro_rules! repro { ($e:expr) => { stringify_item!(fn main() { $e + 1; }) }; } fn main() { println!("{}", repro!(m! {})); } ``` **Before this PR:** output is not valid Rust syntax. ```console fn main() { m! {} + 1; } ``` ```console error: leading `+` is not supported --> <anon>:1:19 | 1 | fn main() { m! {} + 1; } | ^ unexpected `+` | help: try removing the `+` | 1 - fn main() { m! {} + 1; } 1 + fn main() { m! {} 1; } | ``` **After this PR:** valid syntax. ```console fn main() { (m! {}) + 1; } ```
This commit is contained in:
commit
8cc6f34653
12 changed files with 517 additions and 57 deletions
|
@ -677,6 +677,33 @@ trait UnusedDelimLint {
|
|||
}
|
||||
|
||||
// Check if LHS needs parens to prevent false-positives in cases like `fn x() -> u8 { ({ 0 } + 1) }`.
|
||||
//
|
||||
// FIXME: https://github.com/rust-lang/rust/issues/119426
|
||||
// The syntax tree in this code is from after macro expansion, so the
|
||||
// current implementation has both false negatives and false positives
|
||||
// related to expressions containing macros.
|
||||
//
|
||||
// macro_rules! m1 {
|
||||
// () => {
|
||||
// 1
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// fn f1() -> u8 {
|
||||
// // Lint says parens are not needed, but they are.
|
||||
// (m1! {} + 1)
|
||||
// }
|
||||
//
|
||||
// macro_rules! m2 {
|
||||
// () => {
|
||||
// loop { break 1; }
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// fn f2() -> u8 {
|
||||
// // Lint says parens are needed, but they are not.
|
||||
// (m2!() + 1)
|
||||
// }
|
||||
{
|
||||
let mut innermost = inner;
|
||||
loop {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue