2

I'm struggling to understand lifetimes. I understand (I think) that specifying a lifetime with input parameters (i.e. foo<'a>(x: &'a String) -> &'a String {}) means that the returned value inherits the lifetime of the input parameter and will therefore live as long as that does. However, the code below compiles just fine without any input parameters, so I don't understand how the compiler knows I wanted the reference to Dragon::Green to live long enough to leave scope. Is the ownership getting moved to a higher scope, or is something else happening?

fn main() {
  let d;

  {
    let dtile = testtile();
    d = dtile;
  }
  
  println!("{:?}", d);
}

#[derive(PartialOrd, Ord, PartialEq, Eq, Debug)]
enum Dragon {
    White,
    Green,
    Red
}

fn testtile<'a>() -> &'a Dragon {
    &Dragon::Green
}
  • Tip: For simple enums like this, `#derive(Copy,Clone)]` as well, or for future planning, `Hash` can also come in handy. – tadman Feb 26 '23 at 19:12

1 Answers1

3

specifying a lifetime with input parameters (i.e. foo<'a>(x: &'a String) -> &'a String {}) means that the returned value inherits the lifetime of the input parameter

Not quite. Lifetime specifiers are descriptive, not prescriptive.

They help the borrow checker enforce rules around lifetimes.

Every reference has a lifetime. But sometimes you need to refer to that lifetime by name, and that's where lifetime specifiers come in.

In your example, what's happening is that the borrow checker sees that the reference returned by testtile must live as long as variable d. It then tries to find a concrete lifetime to substitute for the generic lifetime parameter 'a that would make that work.

In this case, that does indeed work. For example, if we specify that the reference has 'static lifetime, there's no problem. And given that a simple enum variant is really just a constant, there's no issue here.

In more complex cases, it might be that there's no valid way to find a lifetime to substitute for the lifetime parameter, though this would be more common if, for example, the Dragon struct itself contained references.

cadolphs
  • 9,014
  • 1
  • 24
  • 41