I have a file format that is made up of containers of containers. I've memory-mapped the file and each child structure contains a reference to the bytes in that memory-map. I'm trying to implement a Filterable
trait that allows me to parse the containers in succession and pull out a vector of child containers.
I've attempted to capture the behavior in the simplified version below. Everything references the same lifetime 'mmap
, so I don't see why the compiler is insisting that I have an additional 'static
lifetime.
use memmap::MmapOptions; // 0.7.0
use std::fs::File;
type Filtered<'mmap> = Box<dyn Filterable<'mmap>>;
type Collection<'mmap> = Vec<Filtered<'mmap>>;
struct Foo<'mmap> {
body: &'mmap [u8],
}
struct Bar<'mmap> {
body: &'mmap [u8],
}
trait Filterable<'mmap> {
fn filtered(&'mmap self) -> Collection<'mmap>;
}
impl<'mmap> Filterable<'mmap> for Foo<'mmap> {
fn filtered(&'mmap self) -> Collection<'mmap> {
let bytes: &'mmap [u8] = self.body;
vec![Box::new(Bar { body: self.body }) as Filtered<'mmap>]
}
}
impl<'mmap> Filterable<'mmap> for Bar<'mmap> {
fn filtered(&'mmap self) -> Collection<'mmap> {
vec![]
}
}
fn main() {
let file = File::open("any_file_will_do").unwrap();
let mmap = unsafe { MmapOptions::new().map(&file).unwrap() };
let foo = Foo { body: &mmap };
let bars = foo.filtered();
}
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'mmap` due to conflicting requirements
--> src/main.rs:21:23
|
21 | vec![Box::new(Bar { body: self.body }) as Filtered<'mmap>]
| ^^^
|
note: first, the lifetime cannot outlive the lifetime `'mmap` as defined on the impl at 18:6...
--> src/main.rs:18:6
|
18 | impl<'mmap> Filterable<'mmap> for Foo<'mmap> {
| ^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:21:35
|
21 | vec![Box::new(Bar { body: self.body }) as Filtered<'mmap>]
| ^^^^^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
--> src/main.rs:21:14
|
21 | vec![Box::new(Bar { body: self.body }) as Filtered<'mmap>]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `Box<(dyn Filterable<'mmap> + 'static)>`
found `Box<dyn Filterable<'mmap>>`