Problem with lifetimes (newbie I think)

Let's suppose I have code like this:

struct Struct0 {
   s1: Struct1,
   v: Vec<Box<dyn Tr>>
}

impl Struct0 {
    fn a(&mut self) {
        self.v = self.s1.func();
    }
}

struct Struct1 {}

impl<'a> Struct1 {
    fn func(&'a self) -> Vec<Box<dyn Tr + 'a>> {
        vec![Box::new(Struct2 { some_reference: &self } )]
    }
}

trait Tr {
    //...
}

struct Struct2<'a> {
   some_reference: &'a Struct1
}

impl Tr for Struct2<'_> {
    //...
}

fn main() {
    
}

This gives the following error:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
 --> src/main.rs:8:26
  |
8 |         self.v = self.s1.func();
  |                          ^^^^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 7:5...
 --> src/main.rs:7:5
  |
7 | /     fn a(&mut self) {
8 | |         self.v = self.s1.func();
9 | |     }
  | |_____^
note: ...so that reference does not outlive borrowed content
 --> src/main.rs:8:18
  |
8 |         self.v = self.s1.func();
  |                  ^^^^^^^
  = note: but, the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
 --> src/main.rs:8:18
  |
8 |         self.v = self.s1.func();
  |                  ^^^^^^^^^^^^^^
  = note: expected `std::vec::Vec<std::boxed::Box<(dyn Tr + 'static)>>`
             found `std::vec::Vec<std::boxed::Box<dyn Tr>>`

How can I get this assignment to work?

This seems to work. The problem seems to be that v: Vec<Box<dyn Tr >> seems to default to mean v: Vec<Box<dyn Tr + 'static>>, so it needs to be made explicit that it's not.

I'm pretty sure your issue is that you have a self-referential structure. Struct0 owns a Struct1 and a collection of dyn Tr where each dyn Tr indirectly stores a reference (through Struct2) to the Struct1 owned by Struct0. You'd need to use Rc or Arc references (or rethink your design as self-referential struct can be quite tricky in Rust):

use std::rc::{Rc, Weak};
fn main() {
    let mut s0 = Struct0 {
        s1: Rc::new(Struct1 {}),
        v: vec![],
    };
    s0.a();
    s0.a();
}


struct Struct0 {
    s1: Rc<Struct1>,
    v: Vec<Box<dyn Tr>>,
}

impl Struct0 {
    fn a(&mut self) {
        self.v = self.s1.func();
    }
}

struct Struct1 {}

impl Struct1 {
    fn func(self: &Rc<Self>) -> Vec<Box<dyn Tr>> {
        vec![Box::new(Struct2 {
            some_reference: Rc::downgrade(self),
        })]
    }
}

trait Tr {
    //...
}

struct Struct2 {
    some_reference: Weak<Struct1>,
}

impl Tr for Struct2 {
    //...
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.