I have a simple trait which has a function which accepts an associate type.
pub trait Pipe {
type Item;
fn push(&mut self, value: Self::Item);
}
Now I want to do something with a Pipe that accepts references rather than owned values.
pub fn do_something_ref<T>(trait_inst: T)
where
T: Pipe<Item = &usize>
{
let val: usize = 5;
trait_inst.push(&val);
}
The references will not live longer than the caller context lifetime. Maybe the Pipe clones the value. Maybe it will just println it. But it will not be allowed to store it since that would violate the caller context lifetime.
However the code above give an error: error[E0637]: `&` without an explicit lifetime name cannot be used here.
How can I make this work?
Here's my attempt.
So, it seems that higher ranked trait bounds (HRTB) are useful here. If I can say "P: Pipe<Item = &'a> for all possible 'a" then that would mean the Pipe would accept very short-lived references.
pub fn do_something_ref<T>(trait_inst: T)
where
for <'a> T: Pipe<Item = &'a usize>
{
let val: usize = 5;
trait_inst.push(&val);
}
I think this should work, but it doesn't compile either: error[E0582]: binding for associated type `Item` references lifetime `'a`, which does not appear in the trait input types.
Is that error a bug?
Could be https://github.com/rust-lang/rust/issues/49601 ?
So it seems this error only happens because the 'a isn't in a spot that the compiler recognizes as valid for for<'a>. So I tried to find some workaround by adding an unused lifetime parameter or helper traits, and although I found some solutions which initially compiled, none actually work when you try to use them.
How can I get this to work how I want? Thanks!