TL DR
A function fn foo<'a, T>(&'a mut T) where T: Trait<'a>
makes the lifetime 'a
early-bound. As a result, let f = foo<T>
cannot be used in a place that requires late-bound lifetime 'a
.
The solution is, wrap the function into a closure let f = |bar: &mut _| foo<T>
, this closure will be an fn with late-bound 'a
again.
Original post
Hi Rustaceans, recently I was building a project which requires to have an abstraction of a bytes buffer that can produce (parse) some type T.
The trait definition looks like this:
pub trait Produce<T> {
fn produce<'b>(&'b mut self) -> Result<T>
where
// how to declare for all the lifetime in T, they are shorter than 'b?
}
I'd like to make T
not only work for owned types but also borrowed types. This means all the lifetimes in T must be shorter than the self-borrow lifetime 'b
. I know rust allows us to have a bound T:'b
indicates all the references in T
live longer than 'b
. However, does rust provide similar syntax for the opposite?
Edit1
The original description was not complete to my whole problem. After discussing in the threads below, I think it would be better to put the whole problem here.
pub trait Produce<'a, T> {
fn produce(&'a mut self) -> T;
}
// Get a function pointer of different type T based on flag
fn get_fptr(flag: bool) -> fn(p: &mut Foo) {
fn inner<T>(p: &mut Foo)
where
for<'a> Foo: Produce<'a, T>,
T: std::fmt::Debug
{
println!("{:?}", Produce::<T>::produce(p));
}
if flag {
inner::<&str>
} else {
inner::<i32>
}
}
pub struct Foo(String);
impl<'a> Produce<'a, i32> for Foo {
fn produce(&'a mut self) -> i32 {
1
}
}
impl<'a> Produce<'a, &'a str> for Foo {
fn produce(&'a mut self) -> &'a str {
&self.0
}
}
fn main() {
let mut foo = Foo("bar".into());
let fptrs = vec![get_fptr(true), get_fptr(false)];
for _ in 0..10 {
for &f in &fptrs {
f(&mut foo)
}
}
}
The use case is that, there exists a produce trait to describe a producer, which can produce owned values and borrowed values (borrow from itself).
Now we'd like to store a bunch of function pointers based on a flag, where each of the function pointers calls the producer to produce a specific type of value.
However, the compiler is complaining about the lifetime.
Edit2
After some investigation, I think this might caused by that for<'a> Produce<'a,T>
asks for a late bound lifetime however the implementation impl<'a> Produce<'a, &'a str> for Foo
implicitly means where Self: 'a
so that 'a
becomes early bound. Does anyone aware of some tricks to make the impl late bound?