I've recently come across a borrow checker message I've never seen before which I'm trying to understand. Here is the code to reproduce it (simplified, real-life example was more complex) - playground:
fn foo(v1: &mut Vec<u8>, v2: &mut Vec<u8>, which: bool) {
let dest = if which { &mut v1 } else { &mut v2 };
dest.push(1);
}
It fails to compile with the following error:
error[E0623]: lifetime mismatch
--> src/main.rs:2:44
|
1 | fn foo(v1: &mut Vec<u8>, v2: &mut Vec<u8>, which: bool) {
| ------------ ------------ these two types are declared with different lifetimes...
2 | let dest = if which { &mut v1 } else { &mut v2 };
| ^^^^^^^ ...but data from `v2` flows into `v1` here
...followed by another one about data flowing from v1
into v2
.
My question is: what does this error mean? What is data flow and how does it occur between the two variables, given that the code is only pushing Copy
data to one of them?
If I follow the compiler and force the lifetimes of v1
and v2
to match, the function compiles (playground):
fn foo<'a>(mut v1: &'a mut Vec<u8>, mut v2: &'a mut Vec<u8>, which: bool) {
let dest = if which { &mut v1 } else { &mut v2 };
dest.push(1);
}
However, on further inspection it turned out that the original code was needlessly complex, left over from when v1
and v2
were actual Vec
s, and not references. A simpler and more natural variant is to set dest
not to &mut v1
and &mut v2
, but to the simpler v1
and v2
, which are references to begin with. And that compiles too (playground):
fn foo(v1: &mut Vec<u8>, v2: &mut Vec<u8>, which: bool) {
let dest = if which { v1 } else { v2 };
dest.push(1);
}
In this seemingly equivalent formulation lifetimes of v1
and v2
matching are no longer a requirement.
&mut v1
is very different fromv1
, "given that the code is only pushing Copy data to one of them?" that not the problem, the borrow checker see you want to put two variable with different lifetime intodest
. "...but data fromv2
flows intov1
here" that only the compiler side that see it that way, lifetime should be the same from v1. You already solve the problem so I don't understand what trouble you – Eadest
in the last snippet, but not in the first one. This is all superbly explained in Francis's answer. – Cabalism