fn func_vecmut<'a>(v: &'a mut Vec<&'a i32>, s: &'a String) {}
fn func_vecmut_fresh_lf<'a, 'b>(v: &'a mut Vec<&'a i32>, s: &'b String) {}
fn func_vec<'a>(v: &'a Vec<&'a i32>, s: &'a String) {}
fn main() {
let mut v = vec![];
{
let s: String = String::from("abc");
/* Note: Below, only one function call is active at a time, other two commented out */
func_vecmut(&mut v, &s); // Understandably, compiler fails this.
func_vecmut_fresh_lf(&mut v, &s); // Understandably, compiler passes this i.e with fresh lifetime for String.
func_vec(&v, &s); // Why does compiler pass this?
}
}
In func_vecmut
(as I understand it), the compiler sees that the lifetime of String
is same as Vec
and the elements (i32
) that it holds. And since v
lives longer (defined outside the block), it extends the borrow to s
beyond the scope of the block (i.e afterlife for s
) and hence the following error:
error[E0597]: `s` does not live long enough
--> src/main.rs:13:30
|
13 | func_vecmut(&mut v, &s); // Understandably, compiler fails this.
| ^ borrowed value does not live long enough
...
16 | }
| - `s` dropped here while still borrowed
17 | }
| - borrowed value needs to live until here
The issue can be solved by giving a fresh lifetime to the String
argument (see func_vecmut_fresh_lf
).
But then, why does the compilation not fail for func_vec(&v, &s)
? The only difference being &mut Vec
. Is this something to do with the fact that immutable references are Copy
, whereas mutable ones are not? If it is, how? The function bodies are empty, what does the compiler infer here?