Passing various unboxed closures to function w/ GATs

I previously got help with this unboxed closure issue by creating several implementations:

With the Stabilization of GATs, is there any way to combine these 3 implementations? Thanks!

Working code...

use wasm_bindgen::closure::Closure;

/* POC: Use traits instead of nested calls
 * i.e.
 * let x = myFn.set_closure_fnmut();
 * instead of
 * let x = Closure::wrap(Box::new(myFn) as Box<dyn FnMut(Event)>);
pub trait SetClosureFnOnce<Dyn: ?Sized> {
    fn set_closure_fnonce(self) -> Closure<Dyn>;

impl<F> SetClosureFnOnce<dyn FnMut()> for F
    F: FnOnce() + 'static,
    fn set_closure_fnonce(self) -> Closure<dyn FnMut()> {
        let cb_boxed = Box::new(self) as Box<dyn FnOnce()>;
pub trait SetClosureFnMut<Dyn: ?Sized> {
    fn set_closure_fnmut(self) -> Closure<Dyn>;

impl<F> SetClosureFnMut<dyn FnMut()> for F
    F: FnMut() + 'static,
    fn set_closure_fnmut(self) -> Closure<dyn FnMut()> {
        let cb_boxed = Box::new(self) as Box<dyn FnMut()>;

impl<F, A, R> SetClosureFnMut<dyn FnMut(A) -> R> for F
    F: FnMut(A) -> R + 'static,
    A: wasm_bindgen::convert::FromWasmAbi + 'static,
    R: wasm_bindgen::convert::IntoWasmAbi + 'static,
    fn set_closure_fnmut(self) -> Closure<dyn FnMut(A) -> R> {
        let cb_boxed = Box::new(self) as Box<dyn FnMut(A) -> R>;

I'm not sure how GATs would help – neither of these traits has any associated types.

Are you trying to specify that if any given function/closure type F implements Fn, then the wrapper should wrap dyn Fn, if it's FnMut, then the wrapper should be dyn FnMut, etc.? Because that likely requires specialization.

The goal was a function that does:
Input: unboxed closure
Output: boxed closure

But since the closures come in different forms (Fn, FnOnce, FnMut), I have to have these varying implementations.

Yes, that's exactly what I suspected. I still don't think GATs solve this, because you want different impls for different, overlapping traits.

OK. Thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.