0

So I have something like this code

pub struct LObject {
    pub num: usize,
}

pub struct CObject<'a> {
    pub num: usize,
    pub l_object: &'a LObject,
}


pub struct MR<'a> {
    pub c_objects: Vec<CObject<'a>>,
    pub l_objects: Vec<LObject>,
}

pub fn create_mr<'a>() -> MR<'a> {
    
    let mut c_objects: Vec<CObject> = Vec::new();

    let l_objects: Vec<LObject> = vec![
        LObject { num: 1 },
        LObject { num: 2 },
        LObject { num: 3 },
    ];
    
    for i in 0..l_objects.len() {
        let c_object = CObject { num: i, l_object: &l_objects[i] };
        c_objects.push(c_object);
    }
    
    MR{
        c_objects,
        l_objects
    }
}


fn main() {
    let mr = create_mr();
}

Which fails with

error[E0515]: cannot return value referencing local variable `l_objects`
  --> src/main.rs:31:5
   |
27 |           let c_object = CObject { num: i, l_object: &l_objects[i] };
   |                                                       --------- `l_objects` is borrowed here
...
31 | /     MR{
32 | |         c_objects,
33 | |         l_objects
34 | |     }
   | |_____^ returns a value referencing data owned by the current function

error[E0505]: cannot move out of `l_objects` because it is borrowed
  --> src/main.rs:33:9
   |
16 |   pub fn create_mr<'a>() -> MR<'a> {
   |                    -- lifetime `'a` defined here
...
20 |       let l_objects: Vec<LObject> = vec![
   |           --------- binding `l_objects` declared here
...
27 |           let c_object = CObject { num: i, l_object: &l_objects[i] };
   |                                                       --------- borrow of `l_objects` occurs here
...
31 | /     MR{
32 | |         c_objects,
33 | |         l_objects
   | |         ^^^^^^^^^ move out of `l_objects` occurs here
34 | |     }
   | |_____- returning this value requires that `l_objects` is borrowed for `'a`

The thing is I need to create CObject to have references to LObject or I run into OOM. I then need to create MR to contain a vector of both CObjects and LObjects. IS there a way around this? I can think of referencing by index of the vector but I want to avoid this solution.

jlcv
  • 1,688
  • 5
  • 21
  • 50
  • This amounts to a self-referential struct (`c_objects` references `l_objects`) which you can't really express through Rust's lifetimes. See [Why can't I store a value and a reference to that value in the same struct?](/q/32300132/2189130) There's a few solutions: you can use shared ownership (`Rc`/`Arc`), for referencing into vectors using indexes is a common route, or if you really need this property the third-party crates listed in the linked Q&A can help work around it. – kmdreko May 30 '23 at 23:05

0 Answers0