Lifetime bound on HRTB in trait bounds?

I'm writing a parser that accepts both slices (which have 'src sub-slices that can pass out of parser) and buffers (which have 'tmp sub-slices that can not pass out of parser, e.g. an IO wrapper that discards previous bytes), encountered lifetime issues again... Here's the simplified code:

pub trait Foo<'src> {
    type View<'tmp>
    where 'src: 'tmp;
}

pub trait Bar<'src, F: Foo<'src>> {
    type Viewed<'tmp>
    where 'src: 'tmp;
}

impl<'src, F> Bar<'src, F> for ()
where                       // ^^ error[E0478]: lifetime bound not satisfied
    F: for<'tmp> Foo<'src, View<'tmp> = &'tmp str>,
    // How can I tell rustc `'src: 'tmp` there?
{
    type Viewed<'tmp> = F::View<'tmp>
    where 'src: 'tmp;
}

Add 'src: 'tmp bound on HRTB seems the only way to get this code compile. Is there any way to do this currently?

AFAIK you currently can only get for<'every where 'other: 'every> .. bounds by smuggling a type that implies 'other: 'every into the bound underneath the for<..> binder. For example:

pub trait FooTy<'src, 'tmp, _Lifetimes = &'tmp &'src ()> {
    type View;
}

pub trait Foo<'src>
where
    Self: for<'tmp> FooTy<'src, 'tmp>,
    // Expands to `for<'tmp> Foo<'src, 'tmp, &'tmp &'src ()>`
    // implies `'src: 'tmp`                  ^^^^^^^^^^^^^^
{}

You can read more about this general approach here.

Here's a modified playground:

1 Like

This is a bit complicated for me, I need to sort out my thoughts... But at least I know for sure that GATs are not useful here.

Given the complexity behind these tricks, I may end up using unsafe Rust to avoid them and get a cleaner interface. :melting_face:

Anyway, thank you for your help!