about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2020-02-09 13:19:06 +0000
committerMatthew Jasper <mjjasper1@gmail.com>2020-02-09 13:19:06 +0000
commitfa5a3c35dcda3c82d0c10837cdcbf747e833eabd (patch)
tree15770b9480c8ec601784f6ac3c54b4b9673228e9
parent64ea639c12df0594dd891b1ba0b439c8c5eacd83 (diff)
downloadrust-fa5a3c35dcda3c82d0c10837cdcbf747e833eabd.tar.gz
rust-fa5a3c35dcda3c82d0c10837cdcbf747e833eabd.zip
Don't parse `mut a @ b` as `mut a @ mut b`
-rw-r--r--src/librustc_parse/parser/pat.rs11
-rw-r--r--src/test/ui/pattern/bindings-after-at/nested-binding-mode-lint.rs13
-rw-r--r--src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.rs13
-rw-r--r--src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr21
-rw-r--r--src/test/ui/pattern/bindings-after-at/nested-binding-modes-ref.rs13
-rw-r--r--src/test/ui/pattern/bindings-after-at/nested-binding-modes-ref.stderr15
6 files changed, 82 insertions, 4 deletions
diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs
index e07b0733739..985185230f2 100644
--- a/src/librustc_parse/parser/pat.rs
+++ b/src/librustc_parse/parser/pat.rs
@@ -542,11 +542,14 @@ impl<'a> Parser<'a> {
             }
 
             fn visit_pat(&mut self, pat: &mut P<Pat>) {
-                if let PatKind::Ident(BindingMode::ByValue(ref mut m @ Mutability::Not), ..) =
-                    pat.kind
-                {
-                    *m = Mutability::Mut;
+                if let PatKind::Ident(ref mut bm, ..) = pat.kind {
+                    if let BindingMode::ByValue(ref mut m @ Mutability::Not) = bm {
+                        *m = Mutability::Mut;
+                    }
                     self.0 = true;
+                    // Don't recurse into the subpattern, mut on the outer
+                    // binding doesn't affect the inner bindings.
+                    return;
                 }
                 noop_visit_pat(pat, self);
             }
diff --git a/src/test/ui/pattern/bindings-after-at/nested-binding-mode-lint.rs b/src/test/ui/pattern/bindings-after-at/nested-binding-mode-lint.rs
new file mode 100644
index 00000000000..497d94a3db0
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/nested-binding-mode-lint.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+#![feature(bindings_after_at)]
+#![deny(unused_mut)]
+
+fn main() {
+    let mut is_mut @ not_mut = 42;
+    &mut is_mut;
+    &not_mut;
+    let not_mut @ mut is_mut = 42;
+    &mut is_mut;
+    &not_mut;
+}
diff --git a/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.rs b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.rs
new file mode 100644
index 00000000000..54f04117f7d
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.rs
@@ -0,0 +1,13 @@
+#![feature(bindings_after_at)]
+
+fn main() {
+    let mut is_mut @ not_mut = 42;
+    &mut is_mut;
+    &mut not_mut;
+    //~^ ERROR cannot borrow
+
+    let not_mut @ mut is_mut = 42;
+    &mut is_mut;
+    &mut not_mut;
+    //~^ ERROR cannot borrow
+}
diff --git a/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr
new file mode 100644
index 00000000000..a8d5e4c4c69
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-mut.stderr
@@ -0,0 +1,21 @@
+error[E0596]: cannot borrow `not_mut` as mutable, as it is not declared as mutable
+  --> $DIR/nested-binding-modes-mut.rs:6:5
+   |
+LL |     let mut is_mut @ not_mut = 42;
+   |                      ------- help: consider changing this to be mutable: `mut not_mut`
+LL |     &mut is_mut;
+LL |     &mut not_mut;
+   |     ^^^^^^^^^^^^ cannot borrow as mutable
+
+error[E0596]: cannot borrow `not_mut` as mutable, as it is not declared as mutable
+  --> $DIR/nested-binding-modes-mut.rs:11:5
+   |
+LL |     let not_mut @ mut is_mut = 42;
+   |         -------------------- help: consider changing this to be mutable: `mut not_mut`
+LL |     &mut is_mut;
+LL |     &mut not_mut;
+   |     ^^^^^^^^^^^^ cannot borrow as mutable
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/pattern/bindings-after-at/nested-binding-modes-ref.rs b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-ref.rs
new file mode 100644
index 00000000000..d5086aec93e
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-ref.rs
@@ -0,0 +1,13 @@
+#![feature(bindings_after_at)]
+
+fn main() {
+    let ref is_ref @ is_val = 42;
+    *is_ref;
+    *is_val;
+    //~^ ERROR cannot be dereferenced
+
+    let is_val @ ref is_ref = 42;
+    *is_ref;
+    *is_val;
+    //~^ ERROR cannot be dereferenced
+}
diff --git a/src/test/ui/pattern/bindings-after-at/nested-binding-modes-ref.stderr b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-ref.stderr
new file mode 100644
index 00000000000..9cc928d2149
--- /dev/null
+++ b/src/test/ui/pattern/bindings-after-at/nested-binding-modes-ref.stderr
@@ -0,0 +1,15 @@
+error[E0614]: type `{integer}` cannot be dereferenced
+  --> $DIR/nested-binding-modes-ref.rs:6:5
+   |
+LL |     *is_val;
+   |     ^^^^^^^
+
+error[E0614]: type `{integer}` cannot be dereferenced
+  --> $DIR/nested-binding-modes-ref.rs:11:5
+   |
+LL |     *is_val;
+   |     ^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0614`.