Skip to content

Commit 7e226e6

Browse files
Look at move place's type when suggesting mutable reborrow
1 parent a2cdcb3 commit 7e226e6

File tree

5 files changed

+56
-6
lines changed

5 files changed

+56
-6
lines changed

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

-1
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
198198
move_span,
199199
move_spans,
200200
*moved_place,
201-
Some(used_place),
202201
partially_str,
203202
loop_message,
204203
move_msg,

compiler/rustc_borrowck/src/diagnostics/mod.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
970970
move_span: Span,
971971
move_spans: UseSpans<'tcx>,
972972
moved_place: Place<'tcx>,
973-
used_place: Option<PlaceRef<'tcx>>,
974973
partially_str: &str,
975974
loop_message: &str,
976975
move_msg: &str,
@@ -1058,9 +1057,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10581057
place_name, partially_str, loop_message
10591058
),
10601059
);
1061-
// If we have a `&mut` ref, we need to reborrow.
1062-
if let Some(ty::Ref(_, _, hir::Mutability::Mut)) = used_place
1063-
.map(|used_place| used_place.ty(self.body, self.infcx.tcx).ty.kind())
1060+
// If the moved place was a `&mut` ref, then we can
1061+
// suggest to reborrow it where it was moved, so it
1062+
// will still be valid by the time we get to the usage.
1063+
if let ty::Ref(_, _, hir::Mutability::Mut) =
1064+
moved_place.ty(self.body, self.infcx.tcx).ty.kind()
10641065
{
10651066
// If we are in a loop this will be suggested later.
10661067
if !is_loop_move {

compiler/rustc_borrowck/src/diagnostics/move_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
401401
};
402402
if let Some(use_spans) = use_spans {
403403
self.explain_captures(
404-
&mut err, span, span, use_spans, move_place, None, "", "", "", false, true,
404+
&mut err, span, span, use_spans, move_place, "", "", "", false, true,
405405
);
406406
}
407407
err
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Tests the suggestion to reborrow the first move site
2+
// when we move then borrow a `&mut` ref.
3+
4+
struct State;
5+
6+
impl IntoIterator for &mut State {
7+
type IntoIter = std::vec::IntoIter<()>;
8+
type Item = ();
9+
10+
fn into_iter(self) -> Self::IntoIter {
11+
vec![].into_iter()
12+
}
13+
}
14+
15+
fn once(f: impl FnOnce()) {}
16+
17+
fn fill_memory_blocks_mt(state: &mut State) {
18+
for _ in state {}
19+
//~^ HELP consider creating a fresh reborrow of `state` here
20+
fill_segment(state);
21+
//~^ ERROR borrow of moved value: `state`
22+
}
23+
24+
fn fill_segment(state: &mut State) {}
25+
26+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
error[E0382]: borrow of moved value: `state`
2+
--> $DIR/reborrow-sugg-move-then-borrow.rs:20:18
3+
|
4+
LL | fn fill_memory_blocks_mt(state: &mut State) {
5+
| ----- move occurs because `state` has type `&mut State`, which does not implement the `Copy` trait
6+
LL | for _ in state {}
7+
| ----- `state` moved due to this implicit call to `.into_iter()`
8+
LL |
9+
LL | fill_segment(state);
10+
| ^^^^^ value borrowed here after move
11+
|
12+
note: this function takes ownership of the receiver `self`, which moves `state`
13+
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
14+
|
15+
LL | fn into_iter(self) -> Self::IntoIter;
16+
| ^^^^
17+
help: consider creating a fresh reborrow of `state` here
18+
|
19+
LL | for _ in &mut *state {}
20+
| ++++++
21+
22+
error: aborting due to previous error
23+
24+
For more information about this error, try `rustc --explain E0382`.

0 commit comments

Comments
 (0)