Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not suggest invalid code in pattern with loop #80941

Merged
merged 1 commit into from
Jan 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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(
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/borrowck/move-in-pattern-mut-in-loop.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
15 changes: 15 additions & 0 deletions src/test/ui/borrowck/move-in-pattern-mut-in-loop.stderr
Original file line number Diff line number Diff line change
@@ -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`
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's Some(x), we don't suggest ref mut x since I think the user should encounter a mutability error anyway (and it may be verbose). But if we should also suggest it, I'll do so (we could also tweak the wording in that case).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's probably fine too, because the user still gets a valid suggestion.

|
LL | if let Some(ref mut _x) = opt {}
| ^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0382`.