By changing your trait definition to:
// Hack: introduce an implicit `where Self : 'b` bound
trait BufferedInput<'b, B, _whereSelfOutlivesb = &'b Self> {
fn read(&'_ mut self, buf: B) -> &'b [u8];
}
then something like:
for<'local>
&'static [u8] : BufferedInput<'local, <S as Storage<'local>>::Buffer>
,
will yield a constraint that only uses small enough 'local lifetimes,
and from there:
impl<'i, 'j : 'i> BufferedInput<'i, ()> for &'j [u8] {
/// Directly borrow data from `self`, do not copy,
/// return data that borrow from `self`
fn read(&'_ mut self, _buf: ()) -> &'i [u8] {
self
}
}
yields a correctly higher-order bound for &[u8].
By the way, don't worry if the solution does not seem obvious to come by "alone", it's a kind of messy area of the language which will get better / clearer once we have generic_associated_types ![]()