Struct vs enum lifetime differences

958 views Asked by At

Why does this work

#[derive(Debug)]
pub struct Foo<'a,'b> {
    s : &'a str,
    n : &'b i32
}
#[test]
fn test_struct() {
    let f = Foo { s : &"bar" , n : &17 };
    println!("{:?}",f);
}

but this doesn't

#[derive(Debug)]
pub enum Bar<'a,'b> {
    Baz ( &'a str),
    Fub ( &'b i32)
}
#[test]
fn test_struct() {
    let b = Bar::Baz(&"Foo");
    let c = Bar::Fub(&17);
    println!("{:?} {:?}",b,c);
}

The error is (part of a bigger file so ignore line numbers)

src\lib.rs:176:27: 176:29 error: borrowed value does not live long enough
src\lib.rs:176         let c = Bar::Fub(&17);
                       ^~~~~~~~~~~~~~~~~~~~~~

To me it seems like let c = Bar::Fub(&17), the 17 lasts the same life time as the previous line where "Foo" is created on the stack. If I modify it slightly and do

let h = &17;
let c = Bar::Fub(&h);

In which case it's completely clear that h lasts longer than Bar::Fub(). SoI'm not sure how I can can get this to work.

This is a follow up to Lifetime parameters for an enum within a struct

1

There are 1 answers

1
oli_obk On BEST ANSWER

To me it seems like let c = Bar::Fub(&17), the 17 lasts the same life time as the previous line where "Foo" is created on the stack

A string literal always has 'static lifetime and will therefor always live long enough.

I think the issue is that you are hitting is the fact that an enum expression is actually somewhat of a a function call. Somewhat meaning that the lifetime of the argument is ignored in the computation of the Enum's lifetime. The Enum's lifetime apparently is marginally larger, as if you wrote:

let c: Bar;
let x = &17;
c = Bar::Fub(x);

which is already addressed in Scope of addresses: Does not live long enough

In which case it's completely clear that h lasts longer than Bar::Fub().

Yes, the lifetimes are clear here, and it works in the Playpen:

let x = &17;
let c = Bar::Fub(x);

so I'm not sure what you are asking.