Ruxo
Ruxo

Reputation: 359

Why Rust enforces 'static lifetime even I have specified one? Can I override it?

Can anyone suggest what I'm doing wrong. I'm writing a Callback structure for indirectly calling a closure, this code will be used with a C library.

I've tried to explicit declaring lifetime for a Callback class, but Rust enforces me the 'static lifetime, where I know it is not static. My code looks like this:

use std::ffi::c_void;
use std::marker::PhantomData;

struct Callback<'h> {
    f: Box<dyn FnMut()>,
    r: *const c_void,
    _lifetime: PhantomData<&'h ()>
}

impl<'h> Callback<'h> {
    fn new<F>(handler: F) -> Self where F: FnMut() + Send + 'h {
        let f = Box::new(handler);
        let r = f.as_ref() as *const dyn FnMut() as *const c_void;
        Callback::<'h> { f, r, _lifetime: PhantomData }
    }
}

The compiler error is following:

error[E0310]: the parameter type `F` may not live long enough
  --> src\main.rs:14:26
   |
14 |         Callback::<'h> { f, r, _lifetime: PhantomData }
   |                          ^ ...so that the type `F` will meet its required lifetime bounds
   |
help: consider adding an explicit lifetime bound...
   |
11 |     fn new<F>(handler: F) -> Self where F: FnMut() + Send + 'h + 'static {
   |                                                                +++++++++

If I use the suggested 'static lifetime, then the closure has to be static which it's not my intention.

How to force Rust to trust my lifetime? Is there any workaround? Or, is there any other ways to achieve the same goal?

Upvotes: 0

Views: 149

Answers (1)

kmdreko
kmdreko

Reputation: 59817

Storing Box<dyn Trait> in a struct field will have a default 'static constraint on the trait object. You can relax this by annotating it with 'h instead:

struct Callback<'h> {
    f: Box<dyn FnMut() + 'h>, // <------------
    r: *const c_void,
    _lifetime: PhantomData<&'h ()>
}

With that change you probably don't need _lifetime anymore.

Upvotes: 2

Related Questions