1

I am trying to construct a struct in 2 steps as shown below.

#[derive(Default)]
struct A<'a> {
    a: Vec<i32>,
    b: Vec<&'a i32>
}

impl<'a> A<'a> {
    pub fn new() -> Self {
        let mut x = A::default();
        x.a = vec![1, 2, 3];  //  --- STEP 1 ---
        x.b = x.a             //  --- STEP 2 ---
            .iter()
            .filter_map(|v| match v {
                v if *v >= 2 => Some(v),
                _ => None
            })
            .collect();
        x
    }
}

fn main() {
    let _ = A::new();
}

This code does not compile (https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b95afd64be06faaf4f26c36e77166c1b). I am not able to figure out why.

I expect that labeling the lifetime of every element A::b as the same as A should ensure that I am not borrowing the values after they have been moved. That is the borrow of x.a cannot outlive the move of x at return.

Why is the borrow checker complaining?

ssb
  • 7,422
  • 10
  • 36
  • 61
  • 2
    It's common (not only in Rust) to solve this kind of problem by storing indices instead of references, so `b: Vec`. This makes it so the data structure is not invalidated by returning it from `new`. Note that self-referential structs *are* allowed as long as they aren't moved or mutated, so you can build an `A` and use it in place or by reference - just moving ownership (by passing it to or returning it from a function, for instance) is unsound. – trent Oct 31 '19 at 11:44

0 Answers0