Hi Rustaceans,
here's another thread about lifetime problems.
I have the following code:
/// Stores information about how a type must be converted into bytes
/// This info is retrieved at runtime!
struct SomeInfo;
/// Trait to group different rust data types in a single vector,
/// since in the end only the bytes matter.
trait Foo {
fn into_buf(&self, info: &SomeInfo) -> Vec<u8>;
}
// Implementations of `Foo` on various types...
impl Foo for &str {
fn into_buf(&self, _info: &SomeInfo) -> Vec<u8> {
// converting to bytes depending on `info` omitted here
self.as_bytes().into()
}
}
impl Foo for f64 {
fn into_buf(&self, _info: &SomeInfo) -> Vec<u8> {
// converting to bytes depending on `info` omitted here
self.to_le_bytes().try_into().unwrap()
}
}
// and many more...
/// Put the trait element list in a wrapper for convenience.
struct Bar {
args: Vec<Box<dyn Foo>>,
}
impl Bar {
fn new() -> Self {
Self { args: Vec::new() }
}
fn add(mut self, arg: impl Foo) -> Self {
self.args.push(Box::new(arg));
self
}
// yes we can implement the `IntoIterator` trait instead -
// this is just a dirty and quick solution
fn into_iter(self) -> std::vec::IntoIter<Box<dyn Foo>> {
self.args.into_iter()
}
}
fn get_the_info_from_somewhere() -> SomeInfo {
SomeInfo
}
/// Some type that executes something and relies on the trait elements list...
struct FooBar {}
impl FooBar {
fn new() -> Self {
Self {}
}
fn execute(&self, bars: Bar) {
for foo in bars.into_iter() {
// a lot of other function calls here, which will gather
// runtime information to parse the buffers
let info = get_the_info_from_somewhere();
let buf = foo.into_buf(&info);
println!("{buf:?}");
}
}
}
fn main() {
let bar = Bar::new().add("something").add("another").add(542.2f64);
let foo_bar = FooBar::new();
foo_bar.execute(bar);
}
Compiling this will result in the following error:
error[E0310]: the parameter type `impl Foo` may not live long enough
--> src/main.rs:39:24
|
39 | self.args.push(Box::new(arg));
| ^^^^^^^^^^^^^ ...so that the type `impl Foo` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
38 | fn add(mut self, arg: impl Foo + 'static) -> Self {
| +++++++++
For more information about this error, try `rustc --explain E0310`.
The hint of the compiler, to restrict Impl Foo
to be 'static
, doesn't help me here, since I want to use references as well in calls to Bar::add()
.
How can I solve this problem? I tried to add a marker of type PhantdomData<'a>
to the Bar
struct, and then add a longer lifetime 'b: 'a
to the add()
function to tell the compiler, the impl Foo
s live longer than a Bar
instance itself, but it didn't work. I am a little bit lost here right now.
Best regards 0xBIT