I am using sdl2 crate and I am trying to create a simple "context" object with timer inside of it. I have the following code
extern crate sdl2;
struct Ctx<'a, 'b> {
timer: sdl2::timer::Timer<'a, 'b>,
}
impl<'a,'b> Ctx<'a, 'b> {
pub fn new() -> Ctx<'a,'b> {
let sdl_context = sdl2::init().unwrap();
let timer_subsystem = sdl_context.timer().unwrap();
let timer = timer_subsystem.add_timer(100, Box::new(|| -> u32 { 100 }));
Ctx { timer }
}
}
pub fn main() {
let _ = Ctx::new();
}
The problem is that add_timer() seem to borrow timer_subsystem object, and it prevents timer to be moved out of the function.
error[E0515]: cannot return value referencing local variable `timer_subsystem`
--> src/main.rs:13:9
|
11 | let timer = timer_subsystem.add_timer(100, Box::new(|| -> u32 { 100 }));
| ----------------------------------------------------------- `timer_subsystem` is borrowed here
12 |
13 | Ctx { timer }
| ^^^^^^^^^^^^^ returns a value referencing data owned by the current function
However, if I look into add_timer(), I cannot see why does the reference is considered still alive. In fact the self reference is not used in the function at all:
https://docs.rs/sdl2/latest/src/sdl2/timer.rs.html#17-32
pub fn add_timer<'b, 'c>(&'b self, delay: u32, callback: TimerCallback<'c>) -> Timer<'b, 'c> {
unsafe {
let callback = Box::new(callback);
let timer_id = sys::SDL_AddTimer(
delay,
Some(c_timer_callback),
mem::transmute_copy(&callback),
);
Timer {
callback: Some(callback),
raw: timer_id,
_marker: PhantomData,
}
}
}
I was trying to put both timer and timer_subsystem to Ctx (to make sure their lifetime is the same), but it didn't help. Neither wrapping them with Box<> (to prevent having a dangling pointer after timer_subsystem was moved), but neither worked.
Why of I have a reference to local data here and how can I properly return the timer object?