I have some code like this
struct A<'a> {
b: B,
c: C<'a>,
}
struct B {}
struct C<'a> {
b: &'a B
}
impl<'a> A<'a> {
fn new() -> Self {
let b = B {};
Self {
b,
c: C { b: &b },
}
}
}
where I get the error
error[E0515]: cannot return value referencing local variable `b`
--> src/dummy.rs:16:9
|
16 | / Self {
17 | | b,
18 | | c: C { b: &b },
| | -- `b` is borrowed here
19 | | }
| |_________^ returns a value referencing data owned by the current function
error[E0382]: borrow of moved value: `b`
--> src/dummy.rs:18:23
|
14 | let b = B {};
| - move occurs because `b` has type `B`, which does not implement the `Copy` trait
...
17 | b,
| - value moved here
18 | c: C { b: &b },
| ^^ value borrowed here after move
Some errors have detailed explanations: E0382, E0515.
For more information about an error, try `rustc --explain E0382`.
I think I understand the error, that of course b has a transferred ownership to that new object of A and therefore it seems like there is no guarantee for the lifetime of the object of C when it borrows from B. However because the object of C has its ownership also transferred to the object of A, the lifetime of the object of C as well as b should be the same, right?
How can I express that in Rust that I can create objects of A where I have an object of B and an object of C that also references to that object of B as B and C will have the same lifetime (the one of A)?
As pointed out in the comments and the duplicate question, you can't.
If you want to keep your current code structure, you are forced to use reference counters.
use std::{cell::RefCell, rc::Rc};
struct A {
b: Rc<RefCell<B>>,
c: C,
}
struct B {}
struct C {
b: Rc<RefCell<B>>,
}
impl A {
fn new() -> Self {
let b = Rc::new(RefCell::new(B {}));
Self {
b: b.clone(),
c: C { b },
}
}
}
However, I think it would be more benefitial to refactor your code structure to avoid this problem in the first place. This of course depends on the specific usecase.
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