'Lifetime reference among struct data fields

I have the following code which will throw me this error. Basically I want C to reference B which has reference to A.

How can I achieve this in Rust? Is it possible to do this with multiple life time?

Btw that I do not want to use Rc. Also I do not want C to own B.

struct A;

struct B<'a> {
    a: &'a A,
}

struct C<'a> {
    b: &'a B<'a>,
}

struct D<'a> {
    a: &'a A,
    b: B<'a>,
    c: C<'a>,
}

impl<'a> D<'a> {
    pub fn new(a: &'a A) -> D<'a> {
        let b = B { a };
        let c = C { b: &b };

        D { a, b, c }
    }
}

fn main() {
    let a = A;
    let d = D::new(&a);
}
error[E0515]: cannot return value referencing local variable `b`
  --> src/main.rs:22:9
   |
20 |         let c = C { b: &b };
   |                        -- `b` is borrowed here
21 | 
22 |         D { a, b, c }
   |         ^^^^^^^^^^^^^ returns a value referencing data owned by the current function

error[E0505]: cannot move out of `b` because it is borrowed
  --> src/main.rs:22:16
   |
17 | impl<'a> D<'a> {
   |      -- lifetime `'a` defined here
...
20 |         let c = C { b: &b };
   |                        -- borrow of `b` occurs here
21 | 
22 |         D { a, b, c }
   |         -------^-----
   |         |      |
   |         |      move out of `b` occurs here
   |         returning this value requires that `b` is borrowed for `'a`

Rust playground



Solution 1:[1]

Actually this seems to do the trick...

struct A
{
}

struct B<'a>
{
    pub a : &'a A
}

struct C<'a, 'b>
{
    pub b : &'b B<'a>
}

struct D<'a, 'b>
{
    a : &'a A,

    b : B<'a>,

    c : Option<C<'a, 'b>>
}

impl<'a, 'b> D<'a, 'b>
{
    pub fn new(_a:&'a A) -> D<'a, 'b>
    {
        let _b = B{ a : _a };
        D
        {
            a : _a,
            b : _b,
            c : None,
        }
    }

    pub fn calc(&'b mut self)
    {
        self.c = Some( C{ b : &self.b } );
    }
}

fn test()
{
    let a = A{};
    let mut d = D::new(&a);
    d.calc();
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 agoodname