I thought I prettu much understood lifetime basics

90 points swaan79 39 comments

Like the title says, I thought my mental model for lifetimes was fairly good. I don't claim to be an expert but I generally don't get blocked by them anymore.

But now I have a really short code snippet that doesn't work and I don't understand what's wrong with it:

pub struct Thing<'a> {
    data: &'a mut [u8],
}

impl<'a> Thing<'a> {
    pub fn get_it<'s>(&'s mut self) -> &'a [u8] {
        self.data
    }
}

The error I get is:

error: lifetime may not live long enough
--> <source>:9:9
  |
7 | impl<'a> Thing<'a> {
  |      -- lifetime `'a` defined here
8 |     pub fn get_it<'s>(&'s mut self) -> &'a [u8] {
  |                   -- lifetime `'s` defined here
9 |         self.data
  |         ^^^^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'s`
  |
  = help: consider adding the following bound: `'s: 'a`

error: aborting due to 1 previous error

(godbolt)

So what I'm trying to do is that Thing gets a mutable reference to a buffer when it's created and then the get_it returns a slice from that buffer (simplified here as returning the entire slice). I figured that would just work because I return something that should outlive self to begin with. But that clearly doesn't work.

If I add the 's: 'a bound, I'm saying that the reference to self must outlive the buffer, which doesn't really matter I think. Or is it related to data being mutable reference? If I remove all the mut's it compiles just fine.

What am I missing?

Thanks