Incorrect Inferred Lifetime of borrow


#1

Hi everyone,

i’ve got some code at hand and i fail to understand why it does not compile. Here is the gist of it:

struct A {
    i: u32
}

impl A {
    fn a(&mut self) {
        let x = self.b();
        self.i = 3;
    }
    fn b<'a>(&'a self) -> &'a u32 {
        &self.i
    }
}

The compiler complains that self.i = 3 is not allowed because the borrow from the earlier self.b() is still active. Consequently, this version of A.a compiles:

fn a(&mut self) {
    {
        let x = self.b();
    }
    
    self.i = 3;
}

Not storing the return value of self.b() also compiles; but i have to use the return value in my actual code.

Why is that? I just helped the compiler enforce that x is not used at the time when self.i = 3. Is it just that the compiler has room for improvement or am i missing something?


#2

The short of it is that a feature slated for release later this year, NLL (non-lexical lifetimes), will make your original code compile. You can search for that term/concept (ie NLL, non lexical lifetimes) to see plenty of discussion of this in various places :slight_smile:

Happy to answer any further questions here though.