// check-pass // FamilyType (GAT workaround) pub trait FamilyLt<'a> { type Out; } struct RefMutFamily(std::marker::PhantomData, ()); impl<'a, T: 'a> FamilyLt<'a> for RefMutFamily { type Out = &'a mut T; } pub trait Execute { type E: Inject; fn execute(self, value: <::I as FamilyLt>::Out); } pub trait Inject where Self: Sized, { type I: for<'a> FamilyLt<'a>; fn inject(_: &()) -> ::Out; } impl Inject for RefMutFamily { type I = Self; fn inject(_: &()) -> ::Out { unimplemented!() } } // This struct is only used to give a hint to the compiler about the type `Q` struct Annotate(std::marker::PhantomData); impl Annotate { fn new() -> Self { Self(std::marker::PhantomData) } } // This function annotate a closure so it can have Higher-Rank Lifetime Bounds // // See 'annotate' workaround: https://github.com/rust-lang/rust/issues/58052 fn annotate(_q: Annotate, func: F) -> impl Execute + 'static where F: for<'r> FnOnce(<::I as FamilyLt<'r>>::Out) + 'static, Q: Inject + 'static, { let wrapper: Wrapper = Wrapper(std::marker::PhantomData, func); wrapper } struct Wrapper(std::marker::PhantomData, F); impl Execute for Wrapper where Q: Inject, F: for<'r> FnOnce(<::I as FamilyLt<'r>>::Out), { type E = Q; fn execute(self, value: <::I as FamilyLt>::Out) { (self.1)(value) } } struct Task { _processor: Box, } // This function consume the closure fn task

(processor: P) -> Task where P: Execute + 'static { Task { _processor: Box::new(move || { let q = P::E::inject(&()); processor.execute(q); }) } } fn main() { task(annotate( Annotate::>::new(), |value: &mut usize| { *value = 2; } )); }