Rust: Use of moved value error in the `for` iterator could give a hint about borrowing

Created on 17 May 2015  路  2Comments  路  Source: rust-lang/rust

fn main() {
    let a = vec![1, 2, 3];
    for i in a {
        for j in a {
            println!("{} * {} = {}", i, j, i * j);
        }
    }
}

currently gives:

<anon>:4:18: 4:19 error: use of moved value: `a`
<anon>:4         for j in a {
                          ^
note: in expansion of for loop expansion
<anon>:4:9: 6:10 note: expansion site
note: in expansion of for loop expansion
<anon>:3:5: 7:6 note: expansion site
<anon>:3:14: 3:15 note: `a` moved here because it has type `collections::vec::Vec<i32>`, which is non-copyable
<anon>:3     for i in a {
                      ^
note: in expansion of for loop expansion
<anon>:3:5: 7:6 note: expansion site
error: aborting due to previous error

Of course, we all know that for i in &a etc. is correct here, but this is not very obvious to beginners. We may want to give a contextual hint for "use of moved value" errors among others---probably as a second note following the original move.

(Feel free to make this a metabug if there are other such examples.)

A-diagnostics C-enhancement E-needs-mentor T-compiler WG-compiler-errors

Most helpful comment

This would definitely help. I couldn't figure that error out until I found this post.

All 2 comments

This would definitely help. I couldn't figure that error out until I found this post.

Triage: no change, same output with new style. It should check wether the first move happened in a for loop and suggest changing both places for borrows.

error[E0382]: use of moved value: `a`
 --> src/main.rs:4:18
  |
3 |     for i in a {
  |              - value moved here
  |              |
  |              help: consider borrowing `a` instead: `&a`
4 |         for j in a {
  |                  ^ value used here after move
  |                  |
  |                  help: consider borrowing `a` instead: `&a`
  = note: move occurs because `a` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait

Another case to consider is when moving after a borrow, which should also suggest borrowing instead of moving:

error[E0505]: cannot move out of `a` because it is borrowed
 --> src/main.rs:4:18
  |
3 |     for i in &a {
  |               - borrow of `a` occurs here
4 |         for j in a {
  |                  ^ move out of `a` occurs here
  |                  |
  |                  help: consider borrowing `a` instead: `&a`

error[E0382]: use of moved value: `a`
 --> src/main.rs:4:18
  |
4 |         for j in a {
  |                  ^ value moved here in previous iteration of loop
  |                  |
  |                  help: consider borrowing `a` instead: `&a`
  = note: move occurs because `a` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait

error: aborting due to 2 previous errors

Also, the second error should probably avoid showing multiple borrow errors for the same span, as fixing one would also fix the other.

Was this page helpful?
0 / 5 - 0 ratings