Consider this bare-bones example
type T = usize;
type U1 = String;
type U2 = bool;
pub struct U {
pub one: U1, // not Copy
pub two: U2,
}
fn doit(u_instance: U) -> Vec<U2> {
let _moved: U1 = u_instance.one;
Vec::<T>::new()
.iter()
.map(|_completely_unrelated_to_u_instance: &T| u_instance.two)
.collect()
}
The error message that the compiler generates (shown in full, below), highlights 3 portions of the code:
-
line 14:
|_completely_unrelated_to_u_instance: &T|
(value borrowed here after partial move) -
line 11:
u_instance.one
(value partially moved here) -
line 14:
u_instance
(borrow occurs due to use in closure)
In my shell 1. is highlighted in bright red underlined with heavy ^^^^^^
, while 2. & 3. are highlighted in a more toned-down blue and underlined with lighter -----
I think that 2. and 3. are spot on, completely relevant and helpful in understanding the problem, while 1. is a red herring ... and yet the compiler makes the most noise about it.
Am I missing some subtlety which would explain why 1. is a good message? I appreciate that the closure is trying to borrow u_instance
(and that it can't because it has already been partially moved) but the borrowing is not happening in the closure's parameter list, which is where the message claims it is happening.
In short, I think that the message would be much better without 1.
Full error message
For completeness, here is the error message in full:
error[E0382]: borrow of partially moved value: `u_instance`
--> src/lib.rs:14:14
|
11 | let _moved: U1 = u_instance.one;
| -------------- value partially moved here
...
14 | .map(|_completely_unrelated_to_u_instance: &T| u_instance.two)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---------- borrow occurs due to use in closure
| |
| value borrowed here after partial move
|
= note: partial move occurs because `u_instance.one` has type `String`, which does not implement the `Copy` trait