How to propagate error out of a closure? (Rust, winit crate's event loop)

646 views Asked by At

"this_function_returns_error" returns Result and I need to propagate it back to main. Signature of the run function: https://docs.rs/winit/0.25.0/winit/event_loop/struct.EventLoop.html#method.run

Simplified example of what I need mean:

use winit::{
    event::{Event, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
    window::WindowBuilder,
};

fn main() -> Result<(), SomeError> {
    let event_loop = EventLoop::new();
    let window = WindowBuilder::new().build(&event_loop).unwrap();

    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Wait;

        match event {
            Event::WindowEvent {
                event: WindowEvent::CloseRequested,
                window_id,
            } if window_id == window.id() => *control_flow = ControlFlow::Exit,
            _ => (),
        }
        this_function_returns_error()?;
    });
}

Compiler is pointing out that:

position of closure in run method: this function should return Result or Option to accept ?

but I am not sure if I can even return the result from this closure as it is argument to winit's function.

1

There are 1 answers

0
Masklinn On BEST ANSWER

I am not sure if I can even return the result from this closure as it is argument to winit's function.

No you can't, the type of the event loop handler is:

FnMut(Event<'_, T>, &EventLoopWindowTarget<T>, &mut ControlFlow)

there's no return value in there.

Not only that, but the event loop runner is typed:

pub fn run<F>(self, event_handler: F) -> !

The -> ! means it never returns.

It will exit, but I assume it straight up terminates the current process[0], because its type annotation clearly says it will never yield back control to the enclosing main.

[0] and indeed that's exactly what every implementation seems to do: they run the underlying event loop, and if that ever terminates they just go ::std::process::exit(0);.