Missing Lifetime Parameters When Instantiating Object

I'm trying to instantiate a new Dispatcher object like so:

fn build_dispatcher() -> Dispatcher {
    specs::DispatcherBuilder::new()
        .with_thread_local(RenderingSystem)
        .build()
}

I get a compiler error stating that this function is missing lifetime specifiers, and expects 2 params. If I provide an argument in the function signature with a reference, then the error goes away and it compiles fine. I'll get warnings because I'm not actually using that reference anywhere in the function itself, but it will compile.

My guess as to why the compiler allows the code with the reference argument is because all references need lifetimes associated with it, the compiler will auto-generate lifetimes if it can infer it, and it is able to successfully infer lifetimes in this case when arguments are provided.

The thing is: I don't need any arguments, and I'm not returning any references. I tried to explicitly add a lifetime parameter, but I have no clue of what to associate it to. My RenderingSystem struct implements a trait that has a lifetime associated with it, so I'm sure that has something to do with the error:

impl<'a> System<'a> for RenderingSystem {
    type SystemData = (
        ReadStorage<'a, Position>,
        Write<'a, GameState>,
    );

    fn run(&mut self, data: Self::SystemData) {
        /* omitted for brevity */
    }
}

Here's the furthest I've gotten so far:

fn build_dispatcher<'a>() -> Dispatcher { // where to use 'a though?
    specs::DispatcherBuilder::new()
        .with_thread_local(RenderingSystem)
        .build()
}

The specs::Dispatcher type has two lifetime parameters:

pub struct Dispatcher<'a, 'b>

Since your function can return a Dispatcher with any lifetime, you can take both of those as parameters to build_dispatcher, so the caller of the function can choose these lifetimes:

fn build_dispatcher<'a, 'b>() -> Dispatcher<'a, 'b>

Ok, so you can annotate return values that aren't references. Thanks for the help, it worked :slight_smile:

I had a feeling I could do that from some of the function signatures that my editor's intellisense would show, but I couldn't find that syntax documented anywhere in The Book. I tried it, but only with a single lifetime param instead of 2.

Btw, could you shed some light on why providing anything with a reference compiles? For example, this seems to work:

fn build_dispatcher(world: &World) -> Dispatcher {
    specs::DispatcherBuilder::new()
        .with_thread_local(RenderingSystem)
        .build()
}

I get the feeling that I'm asking about very specific implementation details of the compiler though...

The lifetime elision rules allow you to leave out lifetimes if they are the same for the argument and the return type. Your example is shorthand for:

fn build_dispatcher<'a>(world: &'a World) -> Dispatcher<'a, 'a>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.