I have the following piece of code (it's a self-contained example I wrote to try to isolate the problem with a slightly bigger piece of code):
trait T<'a> {
fn insert(&mut self, param: &'a u8) ->();
}
struct Noop {}
impl<'a> T<'a> for Noop {
fn insert(&mut self, param: &'a u8) { }
}
struct Storage<'a> {
items: Vec<&'a u8>,
parent: Box<dyn T<'a>>
}
impl<'a> Storage<'a> {
fn new(parent: Box<dyn T<'a>>) -> Self { Storage {items: vec![], parent } }
}
impl<'a> T<'a> for Storage<'a> {
fn insert(&mut self, param: &'a u8) {
self.items.push(param);
self.parent.insert(param);
}
}
fn foo<'x>(param: &'x u8) {
let mut one_layer: Storage<'x> = Storage::<'x>::new(Box::new(Noop {}));
one_layer.insert(param);
// let mut two_layers: Storage<'x> = Storage::<'x>::new(Box::new(Storage::<'x>::new(Box::new(Noop {}))));
// two_layers.insert(param);
}
When I uncomment the last two lines, the code starts failing to compile with:
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> src\repro.rs:30:35
|
30 | let two_layers: Storage<'x> = Storage::<'x>::new(Box::new(Storage::<'x>::new(Box::new(Noop {}))));
| ^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'x` as defined on the function body at 27:8...
--> src\repro.rs:27:8
|
27 | fn foo<'x>(param: &'x u8) {
| ^^
note: ...so that the types are compatible
--> src\repro.rs:30:35
|
30 | let two_layers: Storage<'x> = Storage::<'x>::new(Box::new(Storage::<'x>::new(Box::new(Noop {}))));
| ^^^^^^^^^^^^^^^^^^
= note: expected `repro::Storage<'_>`
found `repro::Storage<'x>`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
--> src\repro.rs:30:54
|
30 | let two_layers: Storage<'x> = Storage::<'x>::new(Box::new(Storage::<'x>::new(Box::new(Noop {}))));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `std::boxed::Box<(dyn repro::T<'_> + 'static)>`
found `std::boxed::Box<dyn repro::T<'_>>`
It appears that the lifetime inference didn't figure out that Box::new(Noop {}))
is supposed to be Box<dyn T<'x>>
. How do I get it to work, preferably modifying only the foo
function?
I read the error explanation for E0495, but it is very basic and doesn't explain my case.