error[E0382]: use of moved value: `foo`
--> src/main.rs:5:8
|
2 | fn work(foo: Vec<usize>) -> Result<Vec<usize>, Vec<usize>> {
| --- move occurs because `foo` has type `Vec<usize>`, which does not implement the `Copy` trait
3 | Err(()).map_err(|_| foo)?;
| --- --- variable moved due to use in closure
| |
| value moved into closure here
4 |
5 | Ok(foo)
| ^^^ value used here after move
I thought the borrow checker was smart enough to see that only one of two "ownership transfer paths" can occur here. Why is it insisting that foo has been moved? I really don't want to clone() in this case.
The function always calls map_err, and always passes it a closure that owns foo, so foo is always moved whether or not the ? then causes an early return.
If the body of map_err were inlined into your function, and your closure inlined into that, then maybe the compiler could see that the two moves of foo were on mutually exclusive paths. But this isn’t how the compiler works: Checking a function body is local and does not depend on other function bodies. (This has important benefits; for example, changes to the body of a library function won’t break callers of that function.)
Instead, you’ll need to do the “inlining” manually by using a control-flow expression like if or match:
fn work(foo: Vec<usize>) -> Result<Vec<usize>, Vec<usize>> {
let result = get_result();
if let Err(_) = result {
return Err(foo);
}
Ok(foo)
}
could you provide some more details into what you are trying to do? Why do you need to return the vector in both an error and a non-error case? Or is this just for educational purposes?