I'm working on a crate which uses lifetimes to verify the correctness of code that would otherwise be prone to bugs. This involves the use of unsafe cells and lifetime phantom data. I'm down to one compile error, but I'm very stuck on it.
I've created a MCVE that achieves the same compile error in the same way. Rust Playground
use std::marker::PhantomData;
// owned
#[derive(Debug)]
struct Foo<'a> {
array: &'a [i32; 2],
index: usize,
}
impl<'a> Foo<'a> {
fn to_bar<'x, 'y>(&'y mut self) -> Bar<'x, 'y>
where 'a: 'x, 'a: 'y {
Bar {
array: self.array,
index: self.index,
phantom: PhantomData,
}
}
}
#[derive(Debug)]
struct Bar<'a, 'b: 'a> {
array: &'a [i32; 2],
index: usize,
phantom: PhantomData<&'b mut ()>,
}
impl<'a, 'b: 'a> Bar<'a, 'b> {
fn to_foo(&mut self) -> Foo<'a> {
Foo {
array: self.array,
index: self.index
}
}
}
fn baz<'a>(mut foo: Foo<'a>) -> Foo<'a> {
let foo_2 = {
let mut bar = foo.to_bar();
bar.to_foo()
};
if foo.index == 0 {
foo
} else {
foo_2
}
}
fn main() {}
I apologize that it is hard to tell what I am trying to achieve in this MCVE.
- I have a type
Foo
, which represents a view into a data structure,&[i32; 2]
. MultipleFoo
can view the same data structure simultaneously. - I have a type
Bar
, which represents a view into aFoo
. There must only be oneBar
for a givenFoo
at any moment. For this reason, I have introduced aPhantomData<&'b mut ()>
. - A
Bar
can produce a childFoo
, which is not dependent on theBar
, only the parentFoo
of theBar
. In the real code, this is used to traverse a tree ofFoo
. - I have a function
baz
which accepts aFoo
and returns either that sameFoo
or a childFoo
through the traversal system mentioned in the previous bullet point.
This is throwing a compile error:
error[E0597]: `foo` does not live long enough
--> src/main.rs:38:23
|
38 | let mut bar = foo.to_bar();
| ^^^ borrowed value does not live long enough
...
46 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 36:8...
--> src/main.rs:36:8
|
36 | fn baz<'a>(mut foo: Foo<'a>) -> Foo<'a> {
| ^^
Honestly, I cannot figure out what the error means. I would appreciate help.