Confusing error E0499

Example:

#[allow(unconditional_recursion)]
fn bar<'a>(data: &'a mut Vec<&'a u8>) {
    bar(data);
    bar(data);
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0499]: cannot borrow `*data` as mutable more than once at a time
 --> src/lib.rs:4:9
  |
2 | fn bar<'a>(data: &'a mut Vec<&'a u8>) {
  |        -- lifetime `'a` defined here
3 |     bar(data);
  |     ---------
  |     |   |
  |     |   first mutable borrow occurs here
  |     argument requires that `*data` is borrowed for `'a`
4 |     bar(data);
  |         ^^^^ second mutable borrow occurs here

Please explain me why this error occures in this code?
But if we remove last lifetime 'a from function header:

fn bar<'a>(data: &'a mut Vec<&u8>) {

Then there is no error!

This has to do with lifetime subtyping.

Please read the relavant section in the nomicon before continuing with this answer.

First, because T in &mut T is invariant, and because you have &'a mut Vec<&'a u8> this means that 'a must be exactly the same lifetime in both places and moreover, that Rust isn't allowed to pick a shorter lifetime to try and satisfy the lifetime requirements.

Second, when you use a unique reference multiple times, Rust reborrows it and tries to shorten it's lifetime. But then you do that recursive call which requires identical lifetimes and this leads to the error. Rust is trying to shorten and keep the lifetimes identical at the same time, which is impossible.

In your second example, there is no relationship between the two lifetimes, so Rust is free to shorten the lifetime of the unique reference when it reborrows it.

Thanks a lot. Now I read this article. But it still quite difficult for me to understand.

Why Rust try to shrink lifetime and not consider a more 'big' lifetime with wich the two function calls can be successful?

Why following example with 'static lifetime rise the same error?

#[allow(unconditional_recursion)]
fn bar(data: &'static mut Vec<&'static u8>) {
    bar(data);
    bar(data);
}

The reference is mutable and therefore must be unique. If it's static, then the first use might keep around a copy of it in a global or something, and therefore you are not allowed to use it again after passing it anywhere.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.