HRTB over type?

Assume I have a handler trait, a very complicated trait, and a function whose input implements the trait. The return type is also very complicated.

pub trait Handler<T> {
  fn handle(&mut self, input: T);
}

pub trait VeryComplicated {
  /* a lot of functions */
}

pub fn show(t: &mut impl VeryComplicated) -> impl Iterator<Item = i64>{
// do something
}

and then I have a generic function, that wants to handle the return type

fn do_something<T1: VeryComplicated, T2: /* how to bound it? */>(x: &mut T1, handler: &mut T2) {
 let r = show(t1);
 handler.handle(r);
}

The problem is how to bound the generic param T2 if it's impossible to get the returned type of show. If I can bound T2 like "for every R: Iterator<Item = i64>, T2 implements Handler<R>", the problem is solved.

That would be non-lifetime binders. We don't have them yet. It's probably a ways off.

Alternatively, TAIT would open up some possibilities. But without TAIT, T2 is presumably something along the lines of "for every iterator", since it can't directly name the specific return type from show and implement Handler<ThatType> either.

In the meanwhile: since T2 presumably works with any iterator to be able to handle the return of show, it will work with a type erased iterator, so you can:

fn do_something<T1, T2>(x: &mut T1, handler: &mut T2)
where
    T1: VeryComplicated, 
    T2: for<'any> Handler<&'any mut dyn Iterator<Item = i64>>,
{
    let mut r = show(x);
    handler.handle(&mut r);
}

Thank you for advising a good workaround, but dyn introduces runtime overhead. How to solve this problem if TAIT become stable?

type ShowIter<'vc, VC> = impl Iterator<Item = i64>;

#[define_opaque(ShowIter)]
pub fn show<VC: VeryComplicated>(t: &mut VC) -> ShowIter<'vc, VC> {
    ...
}

fn do_something<T1, T2>(x: &mut T1, handler: &mut T2)
where
    T1: VeryComplicated, 
    T2: for<'any> Handler<ShowIter<'any, T1>>,
{
    let r = show(x);
    handler.handle(r);
}
1 Like