rust lifetime parameter must outlive the static lifetime
Asked Answered
E

1

6

So I'm following this tutorial to build a rogue-like and I've decided to start using the specs dispatcher to make registering and executing systems a bit easier.

To do that I've added a Dispatcher to my State struct:


use rltk::{GameState, Rltk};
use specs::world::World;
use specs::Dispatcher;


pub struct State<'a, 'b> {  // <-- Added new lifetime params here for dispacher
    pub ecs: World,
    pub dsp: Dispatcher<'a, 'b>,
}

But it's when I try to implement the GameSate trait for it I run into issues:

impl<'a, 'b> GameState for State<'a, 'b> {
    fn tick(&mut self, ctx: &mut Rltk) {
        ctx.cls();
        self.dsp.dispatch(&mut self.ecs);
        self.ecs.maintain();
    }
}

I get these errors:

error[E0478]: lifetime bound not satisfied
  --> src/sys/state.rs:96:14
   |
96 | impl<'a, 'b> GameState for State<'a, 'b> {
   |              ^^^^^^^^^
   |
note: lifetime parameter instantiated with the lifetime `'a` as defined on the impl at 96:6
  --> src/sys/state.rs:96:6
   |
96 | impl<'a, 'b> GameState for State<'a, 'b> {
   |      ^^
   = note: but lifetime parameter must outlive the static lifetime

error[E0478]: lifetime bound not satisfied
  --> src/sys/state.rs:96:14
   |
96 | impl<'a, 'b> GameState for State<'a, 'b> {
   |              ^^^^^^^^^
   |
note: lifetime parameter instantiated with the lifetime `'b` as defined on the impl at 96:10
  --> src/sys/state.rs:96:10
   |
96 | impl<'a, 'b> GameState for State<'a, 'b> {
   |          ^^
   = note: but lifetime parameter must outlive the static lifetime

It wants the lifetimes 'a, 'b to outlive 'static, which sounds impossible as I'm sure that 'static is the whole program's lifetime.

How do I resolve this?

Elegancy answered 23/1, 2020 at 13:55 Comment(0)
G
5

GameState requires that implementors must be 'static:

pub trait GameState: 'static {...}

In order to satisfy the 'static lifetime, your type must not contain any references shorter than 'static. So, if you can't make 'a and 'b both be 'static, the only option is not to put the Dispatcher inside State.

For lifetime 'a to "outlive 'static" means that 'a must be equal or longer than 'static (and yes, 'static is the longest lifetime possible). Rust issue for a similar error.

Gosse answered 23/1, 2020 at 14:6 Comment(4)
How do I make the lifetimes static?Elegancy
@Elegancy You can try this, but it likely won't work, if the Dispatcher inherently borrows something: change State to struct State { pub ecs: World, pub dsp: Dispatcher<'static, 'static> }, and fix the errors that result. I can't really give any advice on this concrete example, since I am unfamiliar with specs, but I am guessing that specs and rltk are not really designed to work together this way. Is there no other place to store the Dispatcher other than in the game state?Gosse
That worked! But I wonder, what are the repercussions or are there any caveats I should be aware of? I mean it should be fine as I intend for the dispatcher to live until the end of the program anyway so a 'static lifetime should be fine,Elegancy
Lifetimes exist to help the borrow checker understand your code/borrows better. Using them incorrectly usually means you won't be able to manage references to created structs properly, that is you'll get borrow checker errors where they don't make sense or that are too strict to make the code usable. Tricking the borrow checker (with unsafe code) will generally result in runtime segmentation faults or undefined behavior if you're reading junk where an object existed at some point - that is if you do it incorrectly.Ketty

© 2022 - 2024 — McMap. All rights reserved.