about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2022-09-05 05:00:26 +0000
committerMichael Goulet <michael@errs.io>2022-09-05 05:00:33 +0000
commit7e226e6d3f5dc5c39a222091f7a234c1480e1cbd (patch)
tree5b764285c954a5357fa4f72b30800e68299d13d9
parenta2cdcb3fea2baae5d20eabaa412e0d2f5b98c318 (diff)
downloadrust-7e226e6d3f5dc5c39a222091f7a234c1480e1cbd.tar.gz
rust-7e226e6d3f5dc5c39a222091f7a234c1480e1cbd.zip
Look at move place's type when suggesting mutable reborrow
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs1
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs9
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs2
-rw-r--r--src/test/ui/borrowck/reborrow-sugg-move-then-borrow.rs26
-rw-r--r--src/test/ui/borrowck/reborrow-sugg-move-then-borrow.stderr24
5 files changed, 56 insertions, 6 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 5971f7623f2..a2e4641f66d 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -198,7 +198,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     move_span,
                     move_spans,
                     *moved_place,
-                    Some(used_place),
                     partially_str,
                     loop_message,
                     move_msg,
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 683084cf09d..2d849316f92 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -970,7 +970,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         move_span: Span,
         move_spans: UseSpans<'tcx>,
         moved_place: Place<'tcx>,
-        used_place: Option<PlaceRef<'tcx>>,
         partially_str: &str,
         loop_message: &str,
         move_msg: &str,
@@ -1058,9 +1057,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                                 place_name, partially_str, loop_message
                             ),
                         );
-                        // If we have a `&mut` ref, we need to reborrow.
-                        if let Some(ty::Ref(_, _, hir::Mutability::Mut)) = used_place
-                            .map(|used_place| used_place.ty(self.body, self.infcx.tcx).ty.kind())
+                        // If the moved place was a `&mut` ref, then we can
+                        // suggest to reborrow it where it was moved, so it
+                        // will still be valid by the time we get to the usage.
+                        if let ty::Ref(_, _, hir::Mutability::Mut) =
+                            moved_place.ty(self.body, self.infcx.tcx).ty.kind()
                         {
                             // If we are in a loop this will be suggested later.
                             if !is_loop_move {
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 16c2f9ccc6a..bb06a94635c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -401,7 +401,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         };
         if let Some(use_spans) = use_spans {
             self.explain_captures(
-                &mut err, span, span, use_spans, move_place, None, "", "", "", false, true,
+                &mut err, span, span, use_spans, move_place, "", "", "", false, true,
             );
         }
         err
diff --git a/src/test/ui/borrowck/reborrow-sugg-move-then-borrow.rs b/src/test/ui/borrowck/reborrow-sugg-move-then-borrow.rs
new file mode 100644
index 00000000000..31eba074008
--- /dev/null
+++ b/src/test/ui/borrowck/reborrow-sugg-move-then-borrow.rs
@@ -0,0 +1,26 @@
+// Tests the suggestion to reborrow the first move site
+// when we move then borrow a `&mut` ref.
+
+struct State;
+
+impl IntoIterator for &mut State {
+    type IntoIter = std::vec::IntoIter<()>;
+    type Item = ();
+
+    fn into_iter(self) -> Self::IntoIter {
+        vec![].into_iter()
+    }
+}
+
+fn once(f: impl FnOnce()) {}
+
+fn fill_memory_blocks_mt(state: &mut State) {
+    for _ in state {}
+    //~^ HELP consider creating a fresh reborrow of `state` here
+    fill_segment(state);
+    //~^ ERROR borrow of moved value: `state`
+}
+
+fn fill_segment(state: &mut State) {}
+
+fn main() {}
diff --git a/src/test/ui/borrowck/reborrow-sugg-move-then-borrow.stderr b/src/test/ui/borrowck/reborrow-sugg-move-then-borrow.stderr
new file mode 100644
index 00000000000..13a2005e2ef
--- /dev/null
+++ b/src/test/ui/borrowck/reborrow-sugg-move-then-borrow.stderr
@@ -0,0 +1,24 @@
+error[E0382]: borrow of moved value: `state`
+  --> $DIR/reborrow-sugg-move-then-borrow.rs:20:18
+   |
+LL | fn fill_memory_blocks_mt(state: &mut State) {
+   |                          ----- move occurs because `state` has type `&mut State`, which does not implement the `Copy` trait
+LL |     for _ in state {}
+   |              ----- `state` moved due to this implicit call to `.into_iter()`
+LL |
+LL |     fill_segment(state);
+   |                  ^^^^^ value borrowed here after move
+   |
+note: this function takes ownership of the receiver `self`, which moves `state`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   |
+LL |     fn into_iter(self) -> Self::IntoIter;
+   |                  ^^^^
+help: consider creating a fresh reborrow of `state` here
+   |
+LL |     for _ in &mut *state {}
+   |              ++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.