Usually, when I have some lifetimes problem, I can find a workaround. But now I'm stuck.
I need to implement Context
object which is mutable and contains a reference to a mutable parent context. Something like this:
struct Context<'a> {
parent: Option<&'a mut Context<'a>>
}
impl<'a> Context<'a> {
fn child<'b: 'a>(&'b mut self) -> Context<'b> {
Context {
parent: Some(self),
}
}
}
Seems legit, type checks fine.
However, I cannot call this child
function:
fn this_doesnt_work(context: &mut Context) {
let mut child = context.child();
}
error is:
13 | fn this_doesnt_work(context: &mut Context) {
| ------------
| |
| these two types are declared with different lifetimes...
14 | let mut child = context.child();
| ^^^^^ ...but data from `context` flows into `context` here
This makes a little sense to me, so I tried this workaround: specify the same lifetime in &mut
and Context
. This works:
fn this_doesnt_work<'a>(context: &'a mut Context<'a>) {
let mut child = context.child();
}
However, this function no longer can be called from a closure:
fn this_doesnt_work_either<'a>(context: &'a mut Context<'a>) {
(0..10).map(|i| this_doesnt_work_either(context));
}
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in function call due to conflicting requirements
--> src/main.rs:18:21
|
18 | (0..10).map(|i| this_doesnt_work_either(context));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime '_ as defined on the body at 18:17...
--> src/main.rs:18:17
|
18 | (0..10).map(|i| this_doesnt_work_either(context));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:18:45
|
18 | (0..10).map(|i| this_doesnt_work_either(context));
| ^^^^^^^
note: but, the lifetime must be valid for the lifetime 'a as defined on the function body at 17:28...
--> src/main.rs:17:28
|
17 | fn this_doesnt_work_either<'a>(context: &'a mut Context<'a>) {
| ^^
= note: ...so that the expression is assignable:
expected &mut Context<'_>
found &mut Context<'a>
The fun fact is that last snippet works fine when lifetimes are different:
fn this_doesnt_work_either(context: &mut Context) {
(0..10).map(|i| this_doesnt_work_either(context));
}
So I'm stuck.
- If I specify the same lifetime in
&mut
andContext
,child
function cannot be called from closure. - If I don't specify lifetime, then
child
function doesn't work.
Help?