1
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?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
soupybionics
  • 4,200
  • 6
  • 31
  • 43
  • 1
    I believe your question is answered by the answers of [Why does linking lifetimes matter only with mutable references?](https://stackoverflow.com/questions/32165917/why-does-linking-lifetimes-matter-only-with-mutable-references). If you disagree, please [edit] your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Jun 14 '18 at 13:38
  • *The function bodies are empty, what does the compiler infer here?* — The compiler does not infer anything when calling a function. It **only** uses the function signature. See [Why are explicit lifetimes needed in Rust?](https://stackoverflow.com/q/31609137/155423) for more. – Shepmaster Jun 14 '18 at 13:39
  • Possible duplicate of [Why does linking lifetimes matter only with mutable references?](https://stackoverflow.com/questions/32165917/why-does-linking-lifetimes-matter-only-with-mutable-references) – ljedrz Jun 16 '18 at 10:08

0 Answers0