Hey
I'm having a fight with the lifetime checker.
Here's the code:
// fight.rs
struct Obj<'a> {}
fn aggregate() -> Vec<Obj> {
unimplemented!()
}
Not compiling with following error:
error[E0106]: missing lifetime specifier
--> fight.rs:4:23
|
4 | fn aggregate() -> Vec<Obj> {
| ^^^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
= help: consider giving it a 'static lifetime
error: aborting due to previous error(s)
I tried changing the return type with lifetime parameters:
fn aggregate<'a>() -> Vec<'a Obj>
fn aggregate<'a>() -> Vec<&'a Obj>
fn aggregate() -> Vec<'static Obj>
fn aggregate() -> Vec<&'static Obj>
And lots of other variations.
But nothing seems to work.
Can you help me please?
-
'static
is the only one that can work -- you can't produce any arbitrary lifetime yourself. aggregate()
would have to take an object with a lifetime for it to be able to return another object (with the same lifetime).
- The lifetime is a type parameter of
Obj
and that's how it should be specified where it's used.
Here's a compiling example.
// fight.rs
struct Obj<'a> {
_phantom: ::std::marker::PhantomData<&'a ()>,
}
fn aggregate() -> Vec<Obj<'static>> {
unimplemented!()
}
(Playground)
Note that to be able to define a struct with type parameters, you need to use all the type parameters. (These are needed for the compiler to figure out variances and to produce the correct drop
code.)
I don't know anything about your example, so I put a PhantomData
implying that the struct semantically contains an immutably borrowed reference to something.
I'd need more details to understand what you precisely need here.
1 Like
Ah, thanks. My problem was I didn't know where to put the lifetime in the return type. That solved my problem.
fn aggregate() -> Vec<Obj<'a>>
I need to use lifetimes because I store trait objects in a struct.
pub trait Provider {}
pub struct Plugin<'a> {
name: String,
providers: Vec<&'a (Provider + 'a)>,
}