1
Fork 0

Rollup merge of #101431 - compiler-errors:move-place-ty-for-move-place-sugg, r=cjgillot

Look at move place's type when suggesting mutable reborrow

Not sure why we are looking at the use site's ty instead of the move site's ty in order to suggest reborrowing the move site, but it was suppressing a perfectly valid reborrow suggestion.

r? `@estebank` who i think touched this last in 520461f1fb, though that was quite a while ago so feel free to reassign.
This commit is contained in:
fee1-dead 2022-09-25 22:06:37 +08:00 committed by GitHub
commit 084029f39d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 56 additions and 6 deletions

View file

@ -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,

View file

@ -972,7 +972,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,
@ -1060,9 +1059,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 {

View file

@ -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

View file

@ -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() {}

View file

@ -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`.