about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2021-01-12 17:31:13 +0900
committerYuki Okushi <huyuumi.dev@gmail.com>2021-01-12 17:31:13 +0900
commit4362da13b128e897712140b3c11397e871e5b2fc (patch)
tree8851921ccec8d5c047a2cc4f7f5afcf153d456cc
parent04064416644eba7351b1a457c1de27d28a750c95 (diff)
downloadrust-4362da13b128e897712140b3c11397e871e5b2fc.tar.gz
rust-4362da13b128e897712140b3c11397e871e5b2fc.zip
Do not suggest invalid code in pattern with loop
-rw-r--r--compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs5
-rw-r--r--src/test/ui/borrowck/move-in-pattern-mut-in-loop.rs10
-rw-r--r--src/test/ui/borrowck/move-in-pattern-mut-in-loop.stderr15
3 files changed, 29 insertions, 1 deletions
diff --git a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
index db02ee67910..c745601c336 100644
--- a/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_mir/src/borrow_check/diagnostics/conflict_errors.rs
@@ -141,6 +141,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             self.add_moved_or_invoked_closure_note(location, used_place, &mut err);
 
             let mut is_loop_move = false;
+            let mut in_pattern = false;
 
             for move_site in &move_site_vec {
                 let move_out = self.move_data.moves[(*move_site).moi];
@@ -256,6 +257,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         "ref ".to_string(),
                         Applicability::MachineApplicable,
                     );
+                    in_pattern = true;
                 }
 
                 if let Some(DesugaringKind::ForLoop(_)) = move_span.desugaring_kind() {
@@ -302,7 +304,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             let place = &self.move_data.move_paths[mpi].place;
             let ty = place.ty(self.body, self.infcx.tcx).ty;
 
-            if is_loop_move {
+            // If we're in pattern, we do nothing in favor of the previous suggestion (#80913).
+            if is_loop_move & !in_pattern {
                 if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
                     // We have a `&mut` ref, we need to reborrow on each iteration (#62112).
                     err.span_suggestion_verbose(
diff --git a/src/test/ui/borrowck/move-in-pattern-mut-in-loop.rs b/src/test/ui/borrowck/move-in-pattern-mut-in-loop.rs
new file mode 100644
index 00000000000..4b42f9d4cd5
--- /dev/null
+++ b/src/test/ui/borrowck/move-in-pattern-mut-in-loop.rs
@@ -0,0 +1,10 @@
+// Regression test for #80913.
+
+fn main() {
+    let mut x = 42_i32;
+    let mut opt = Some(&mut x);
+    for _ in 0..5 {
+        if let Some(mut _x) = opt {}
+        //~^ ERROR: use of moved value
+    }
+}
diff --git a/src/test/ui/borrowck/move-in-pattern-mut-in-loop.stderr b/src/test/ui/borrowck/move-in-pattern-mut-in-loop.stderr
new file mode 100644
index 00000000000..9373e4d95fc
--- /dev/null
+++ b/src/test/ui/borrowck/move-in-pattern-mut-in-loop.stderr
@@ -0,0 +1,15 @@
+error[E0382]: use of moved value
+  --> $DIR/move-in-pattern-mut-in-loop.rs:7:21
+   |
+LL |         if let Some(mut _x) = opt {}
+   |                     ^^^^^^ value moved here, in previous iteration of loop
+   |
+   = note: move occurs because value has type `&mut i32`, which does not implement the `Copy` trait
+help: borrow this field in the pattern to avoid moving `opt.0`
+   |
+LL |         if let Some(ref mut _x) = opt {}
+   |                     ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.