I'm using the following code in order to run my render::exec
function on each occurrence of a RedrawRequested
event (issued by Glium):
event_loop.run(move |event, _, control_flow| {
match event {
Event::RedrawRequested(_) => {
let mut target = display.draw();
render::exec(&mut target, &mut ctx, &font, &mut cache);
target.finish().unwrap();
}
// ...
_ => ()
}
});
The issue is, I'm getting the following error on the &font
reference:
borrowed data cannot be stored outside of its closure
font
is indeed created before the call to event_loop.run
, since it is a rusttype::Font
struct that I need in order to render text inside my Glium app. I understand that since this is a move
closure, the data from font
will be free'd at the end of it, so the borrow checker doesn't allow font
to be created outside of the closure, because it isn't ensured that the closure won't be called more than once (and indeed, it is called more than once).
I tried to circumvent this by removing the move
keyword, but then the following error is triggered on each one of the variables that I borrow from inside the closure:
closure may outlive the current function, but it borrows `ctx`, which is owned by the current function
may outlive borrowed value `ctx`
I understand that since the borrow checker cannot be ensured that these variables will last at least as long as the closure, it won't allow the latter to be referenced from inside the former.
Therefore, I need a way to ensure the borrow checker that these variables will last at least as long as the closure. One way to do that normally would be to pass them as parameters to the closure, but I actually cannot change the list of parameters that is passed, since I'm using event_loop.run
, which has the following signature:
pub fn run<F>(self, event_handler: F) -> !
where F: 'static + FnMut(Event<'_, T>, &EventLoopWindowTarget<T>, &mut ControlFlow)
I went through the Glutin docs and couldn't find a way to store any data into the EventLoop
(which is the type that dereferencing EventLoopWindowTarget
gives), nor into the ControlFlow
that is passed as a param.
That's not correct. It doesn't care that the
font
is created before the closure, because it's moved into the closure afterwards. Likewise calling the closure more than once, doesn't matter, the font now belongs to the closure.A closure is a structure with an associated function, all the variables that are part of the environment are really set as members of the structure from which they can be pulled when calling the function in order to fill the free variables. That's about it. It has no specific issue with creating items outside the closure (how else would you close over them?), or with calling closures multiple times.
What the error is saying is that inside the closure you're borrowing something and you're trying to move that borrow outside the closure.