How to interpret a lifetime parameter of self in impl statements

Hi. I've recently started to learn Rust.
Now, I'm having a hard time to understand lifetime parameters inside a impl statement.

Here's a code I have:

struct A<'a> {
    a: &'a i32
}

impl<'a> A<'a> {
    fn setup(&'a mut self) {
        self.a = &1
    }

    fn run(&'a self) {
        println!("{}", self.a)
    }
}

pub fn main() {
    let mut a = A {a: &0};
    a.setup();
    a.run()
}

When I tried to compile the above code, I got the following error:

Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `a` as immutable because it is also borrowed as mutable
  --> src/main.rs:18:5
   |
17 |     a.setup();
   |     --------- mutable borrow occurs here
18 |     a.run()
   |     ^^^^^^^
   |     |
   |     immutable borrow occurs here
   |     mutable borrow later used here

For more information about this error, try `rustc --explain E0502`.
error: could not compile `playground` due to previous error

However, it worked just by rewriting the function setup like this:

    fn setup(&mut self) {
        self.a = &1
    }

What makes these two functions identical?
I thought that the latter setup equals to fn setup<'b>(&'b mut self), and then the actual lifetime passed to 'b would be the one that variable a in main has.
And, I believe that same thing happens to the original definition of setup.

Does anyone explain why the latter one is fine, but the former one is not?

This is an anti-pattern that should be avoided. And read through

4 Likes

Thank you so much. Now, it makes sence.
When the funciton setup(&'a mut self) was invoked in the main and the controll was returned to the main, though the argument &'a mut self is already out of scope, it won't die since the life time equals to the struct A, right?
On the other hand, the lifetime of the argument would be just there if the parameter 'a was omitted.

No, the &'a mut A<'a>, the unqiue access to A<'a> was moved into the setup scope and wasn't returned to main (since setup doesn't return &'a ....

Yes. If 'a is omitted, the unqiue access to A<'a> will be reborrowed, meaning &'a_short_lifetime_from_unique_access mut A<'a> is generated and moved into setup, with the unique access &'a mut A<'a> always available (or rather able to be reborrowed).

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.