This is basically higher-kinded types; the associated type is parameterised by the lifetime, as there's no connection between the lifetime declared in the function and the one in the type (as you noted). A proposed syntax for the functionality is something like:
trait Combine {
type O<'x>;
fn f<'a>(&self, &'a [u8]) -> Self::O<'a>;
}
// ...
struct Ident<C: Consume>(C);
impl<C: Consume> Consume for Ident<C> {
type O<'x> = &'x [u8];
fn f<'a>(&self, s: &'a [u8]) -> &'a [u8] {
&s[1..]
}
}
Unfortunately, this doesn't work now.
The for
syntax is a little bit related (although it is handling higher-rankedness, rather than high-kindedness), but it doesn't work for that exact code. However, it is helpful if one moves the lifetime to the trait, as @gkoz demonstrates, then a bound that was T: Combine
should be written T: for<'a> Combine<'a>
and should (I think) achieve the same purpose.