Skip to content

Commit 1e88a17

Browse files
committed
Auto merge of rust-lang#80205 - tomprogrammer:prettyprint-pattern-mut-binding, r=davidtwco
Fix pretty printing an AST representing `&(mut ident)` The PR fixes a misguiding help diagnostic in the parser that I reported in rust-lang#80186. I discovered that the parsers recovery and reporting logic was correct but the pretty printer produced wrong code for the example. (Details in rust-lang#80186 (comment)) Example: ```rust #![allow(unused_variables)] fn main() { let mut &x = &0; } ``` The AST fragment `PatKind::Ref(PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..), Mutability::Not)` was printed to be `&mut ident`. But this wouldn't round trip through parsing again, because then it would be: `PatKind::Ref(PatKind::Ident(BindingMode::ByValue(Mutability::Not), ..), Mutability::Mut)` Now the pretty-printer prints `&(mut ident)`. Reparsing that code results in the AST fragment `PatKind::Ref(PatKind::Paren(PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..)), Mutability::Not)` which I think should behave like the original pattern. Old diagnostic: ``` error: `mut` must be attached to each individual binding --> src/main.rs:3:9 | 3 | let mut &x = &0; | ^^^^^^ help: add `mut` to each binding: `&mut x` | = note: `mut` may be followed by `variable` and `variable @ pattern` ``` New diagnostic: ``` error: `mut` must be attached to each individual binding --> src/main.rs:3:9 | 3 | let mut &x = &0; | ^^^^^^ help: add `mut` to each binding: `&(mut x)` | = note: `mut` may be followed by `variable` and `variable @ pattern` ``` Fixes rust-lang#80186
2 parents 463ce40 + b05ab18 commit 1e88a17

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

compiler/rustc_ast_pretty/src/pprust/state.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -2420,7 +2420,15 @@ impl<'a> State<'a> {
24202420
if mutbl == ast::Mutability::Mut {
24212421
self.s.word("mut ");
24222422
}
2423-
self.print_pat(inner);
2423+
if let PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Mut), ..) =
2424+
inner.kind
2425+
{
2426+
self.popen();
2427+
self.print_pat(inner);
2428+
self.pclose();
2429+
} else {
2430+
self.print_pat(inner);
2431+
}
24242432
}
24252433
PatKind::Lit(ref e) => self.print_expr(&**e),
24262434
PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Regression test for correct pretty-printing of an AST representing `&(mut x)` in help
2+
// suggestion diagnostic.
3+
4+
fn main() {
5+
let mut &x = &0;
6+
//~^ ERROR `mut` must be attached to each individual binding
7+
//~| HELP add `mut` to each binding
8+
//~| SUGGESTION &(mut x)
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: `mut` must be attached to each individual binding
2+
--> $DIR/issue-80186-mut-binding-help-suggestion.rs:5:9
3+
|
4+
LL | let mut &x = &0;
5+
| ^^^^^^ help: add `mut` to each binding: `&(mut x)`
6+
|
7+
= note: `mut` may be followed by `variable` and `variable @ pattern`
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)