`'1` must outlive `'a`

struct App<'a> {
    state: Option<State<'a>>,
    window: Option<Window>,
}

impl<'a> ApplicationHandler for App<'a> {
    fn resumed(&mut self, event_loop: &ActiveEventLoop) {
        let window = event_loop.create_window(Window::default_attributes()).unwrap();
        self.window = Some(window);
        
       self.state = if let Some(window) = &self.window {
            let future_state = State::new(window);
            let result = tokio::runtime::Runtime::new()
                .unwrap()
                .block_on(future_state);
            Some(result)
        } else { None };
    }
}

How do I force that '1 outlives 'a?
impl<'a> ApplicationHandler for App<'a> {
| -- lifetime 'a defined here
18 | fn resumed(&mut self, event_loop: &ActiveEventLoop) {
| - let's call the lifetime of this reference '1
...
22 | self.state = if let Some(window) = &self.window {
| ^^^^^^^^^^ assignment requires that '1 must outlive 'a

It looks like State borrows from Window. This would be a self-referential type, which rust doesn't natively support. Would it be possible to merge State into your App such that it can directly access the window field? Or equivalently directly store the Window in your State rather than borrowing it?

By the way resumed can be called multiple times over the lifespan of your program. You should only create your window the first time resumed is called to prevent windows from accumulating.

1 Like

If this is winit + wgpu, then you should solve this problem by not passing &window to create_surface(), but Arc<Window> instead, which you can share by cloning instead of borrowing. Then the surface lifetime becomes 'static and there is no self-referentiality, and your struct has no lifetime parameter. The structs would be like:

struct App<'a> {
    state: Option<State>,
    window: Option<Arc<Window>>,
}

struct State {
    surface: wgpu::Surface<'static>,
    ...
}
3 Likes