The following code doesn't compile:
use std::borrow::Borrow;
struct Inner<'a> {
v: Vec<&'a u8>,
}
struct Foo<'a> {
inner: Inner<'a>,
derp: Box<u8>,
}
impl<'a> Foo<'a> {
fn new() -> Foo<'a> {
let mut e = Foo {
inner: Inner { v: vec![] },
derp: Box::new(128),
};
e.inner.v.push(&*e.derp);
return e;
}
fn derp(&mut self) {
println!("{:?}", self.inner.v);
}
}
fn main() {
let mut f = Foo::new();
f.derp();
}
I get the following error:
error[E0597]: `*e.derp` does not live long enough
--> src/main.rs:18:25
|
18 | e.inner.v.push(&*e.derp);
| ^^^^^^^ does not live long enough
...
21 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 12:1...
--> src/main.rs:12:1
|
12 | / impl<'a> Foo<'a> {
13 | | fn new() -> Foo<'a> {
14 | | let mut e = Foo {
15 | | inner: Inner { v: vec![] },
... |
25 | | }
26 | | }
| |_^
I think that the value inside of the box does live for as long as 'a since it is a member of Foo, which has exactly that lifetime.
I wondered if the move of Foo at the end of the new function was confusing it, so if tried to do the append in derp. I get a different error:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> main.rs:20:27
|
20 | self.inner.v.push(& *self.derp);
| ^^^^^^^^^^
which gives me no indication of what lifetime the compiler thinks the boxed value has.
I think though that the value inside of the box does live for as long as 'a since it is a member of Foo which has exactly that lifetime.
It is possible to assign a new box to the derp member, at which point the old box will be dropped and the lifetime of the value in it ends.
I think what you are trying to do is impossible in safe Rust: cross-references between struct members are not supported. This comes up regularly as a question, but it's just not available in the language.
You can use Rc to work around this, perhaps in combination with RefCell.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With