Rollup merge of #83945 - SkiFire13:fix-83924, r=estebank
Add suggestion to reborrow mutable references when they're moved in a for loop Address #83924
This commit is contained in:
commit
d7d42ccfd2
4 changed files with 83 additions and 1 deletions
|
@ -264,7 +264,24 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
|
|
||||||
if let Some(DesugaringKind::ForLoop(_)) = move_span.desugaring_kind() {
|
if let Some(DesugaringKind::ForLoop(_)) = move_span.desugaring_kind() {
|
||||||
let sess = self.infcx.tcx.sess;
|
let sess = self.infcx.tcx.sess;
|
||||||
if let Ok(snippet) = sess.source_map().span_to_snippet(move_span) {
|
let ty = used_place.ty(self.body, self.infcx.tcx).ty;
|
||||||
|
// If we have a `&mut` ref, we need to reborrow.
|
||||||
|
if let ty::Ref(_, _, hir::Mutability::Mut) = ty.kind() {
|
||||||
|
// If we are in a loop this will be suggested later.
|
||||||
|
if !is_loop_move {
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
move_span.shrink_to_lo(),
|
||||||
|
&format!(
|
||||||
|
"consider creating a fresh reborrow of {} here",
|
||||||
|
self.describe_place(moved_place.as_ref())
|
||||||
|
.map(|n| format!("`{}`", n))
|
||||||
|
.unwrap_or_else(|| "the mutable reference".to_string()),
|
||||||
|
),
|
||||||
|
format!("&mut *"),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if let Ok(snippet) = sess.source_map().span_to_snippet(move_span) {
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
move_span,
|
move_span,
|
||||||
"consider borrowing to avoid moving into the for loop",
|
"consider borrowing to avoid moving into the for loop",
|
||||||
|
|
20
src/test/ui/issues/issue-83924.fixed
Normal file
20
src/test/ui/issues/issue-83924.fixed
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut values = vec![10, 11, 12];
|
||||||
|
let v = &mut values;
|
||||||
|
|
||||||
|
let mut max = 0;
|
||||||
|
|
||||||
|
for n in &mut *v {
|
||||||
|
max = std::cmp::max(max, *n);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("max is {}", max);
|
||||||
|
println!("Converting to percentages of maximum value...");
|
||||||
|
for n in v {
|
||||||
|
//~^ ERROR: use of moved value: `v` [E0382]
|
||||||
|
*n = 100 * (*n) / max;
|
||||||
|
}
|
||||||
|
println!("values: {:#?}", values);
|
||||||
|
}
|
20
src/test/ui/issues/issue-83924.rs
Normal file
20
src/test/ui/issues/issue-83924.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// run-rustfix
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut values = vec![10, 11, 12];
|
||||||
|
let v = &mut values;
|
||||||
|
|
||||||
|
let mut max = 0;
|
||||||
|
|
||||||
|
for n in v {
|
||||||
|
max = std::cmp::max(max, *n);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("max is {}", max);
|
||||||
|
println!("Converting to percentages of maximum value...");
|
||||||
|
for n in v {
|
||||||
|
//~^ ERROR: use of moved value: `v` [E0382]
|
||||||
|
*n = 100 * (*n) / max;
|
||||||
|
}
|
||||||
|
println!("values: {:#?}", values);
|
||||||
|
}
|
25
src/test/ui/issues/issue-83924.stderr
Normal file
25
src/test/ui/issues/issue-83924.stderr
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
error[E0382]: use of moved value: `v`
|
||||||
|
--> $DIR/issue-83924.rs:15:14
|
||||||
|
|
|
||||||
|
LL | let v = &mut values;
|
||||||
|
| - move occurs because `v` has type `&mut Vec<i32>`, which does not implement the `Copy` trait
|
||||||
|
...
|
||||||
|
LL | for n in v {
|
||||||
|
| - `v` moved due to this implicit call to `.into_iter()`
|
||||||
|
...
|
||||||
|
LL | for n in v {
|
||||||
|
| ^ value used here after move
|
||||||
|
|
|
||||||
|
note: this function takes ownership of the receiver `self`, which moves `v`
|
||||||
|
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
||||||
|
|
|
||||||
|
LL | fn into_iter(self) -> Self::IntoIter;
|
||||||
|
| ^^^^
|
||||||
|
help: consider creating a fresh reborrow of `v` here
|
||||||
|
|
|
||||||
|
LL | for n in &mut *v {
|
||||||
|
| ^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0382`.
|
Loading…
Add table
Add a link
Reference in a new issue