about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThomas Bahn <thomas@thomas-bahn.net>2020-12-19 23:13:50 +0100
committerThomas Bahn <thomas@thomas-bahn.net>2020-12-20 13:11:07 +0100
commitb05ab18aec28c5025212ad44a202072ed2f610d7 (patch)
tree4c24cf8947c9ed79b37dde8d54b7d55215ad6cb8
parentb1964e60b72c2d10e9fd4e801990f8af3f306ac0 (diff)
downloadrust-b05ab18aec28c5025212ad44a202072ed2f610d7.tar.gz
rust-b05ab18aec28c5025212ad44a202072ed2f610d7.zip
Fix pretty printing an AST representing `&(mut ident)`
`PatKind::Ref(PatKind::Ident(BindingMode::ByValue(Mutability::Mut), ..), ..)`
is an AST representing `&(mut ident)`. It was errorneously printed as
`&mut ident` which reparsed into a syntactically different AST.

This affected help diagnostics in the parser.
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs10
-rw-r--r--src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs9
-rw-r--r--src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr10
3 files changed, 28 insertions, 1 deletions
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index fdb129d9e2a..dcb6e115eda 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -2420,7 +2420,15 @@ impl<'a> State<'a> {
                 if mutbl == ast::Mutability::Mut {
                     self.s.word("mut ");
                 }
-                self.print_pat(inner);
+                if let PatKind::Ident(ast::BindingMode::ByValue(ast::Mutability::Mut), ..) =
+                    inner.kind
+                {
+                    self.popen();
+                    self.print_pat(inner);
+                    self.pclose();
+                } else {
+                    self.print_pat(inner);
+                }
             }
             PatKind::Lit(ref e) => self.print_expr(&**e),
             PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => {
diff --git a/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs
new file mode 100644
index 00000000000..a5e9b1db546
--- /dev/null
+++ b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.rs
@@ -0,0 +1,9 @@
+// Regression test for correct pretty-printing of an AST representing `&(mut x)` in help
+// suggestion diagnostic.
+
+fn main() {
+    let mut &x = &0;
+    //~^ ERROR `mut` must be attached to each individual binding
+    //~| HELP add `mut` to each binding
+    //~| SUGGESTION &(mut x)
+}
diff --git a/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr
new file mode 100644
index 00000000000..75b6c163b2c
--- /dev/null
+++ b/src/test/ui/pattern/issue-80186-mut-binding-help-suggestion.stderr
@@ -0,0 +1,10 @@
+error: `mut` must be attached to each individual binding
+  --> $DIR/issue-80186-mut-binding-help-suggestion.rs:5:9
+   |
+LL |     let mut &x = &0;
+   |         ^^^^^^ help: add `mut` to each binding: `&(mut x)`
+   |
+   = note: `mut` may be followed by `variable` and `variable @ pattern`
+
+error: aborting due to previous error
+