Consider this example:
use std::marker::PhantomData;
struct Scope<'a,'b>(PhantomData<* mut &'a ()>,PhantomData<* mut &'b ()>);
impl<'a,'env> Scope<'a,'env>{
fn spawn<F>(&'a self,mut f:F) where F:FnMut()+'a{
f();
}
}
fn scope_spawn<'b,F>(mut f:F)
where F: for<'a> FnOnce(&'a Scope<'a,'b>){
}
fn main(){
let mut i = 0;
scope_spawn(|s|{
s.spawn(||{
i = 1;
});
});
}
This example is Ok. However, if change the above code to the following:
use std::marker::PhantomData;
struct Scope<'a>(PhantomData<* mut &'a ()>);
impl<'a,'env> Scope<'a>{
fn spawn<F>(&'a self,mut f:F) where F:FnMut()+'a{
f();
}
}
fn scope_spawn<'b,F>(mut f:F)
where F: for<'a> FnOnce(&'a Scope<'a>){
}
fn main(){
let mut i = 0;
scope_spawn(|s|{
s.spawn(||{
i = 1; // #1
});
});
}
Simply remove the second lifetime for Scope
, the compiler will report an error at #1
argument requires that
i
is borrowed for'static
What's the reason here? I suspect, in the second example, where F: for<'a> FnOnce(&'a Scope<'a>)
, the lifetime 'a
denotes any lifetime, the trait bound F:FnMut()+'a
in Scope::spawn
can only be satisfied if F:FnMut() + 'static
, so, i
is required to borrow for 'static
.
In the first example, I think, since the reference type&'a Scope<'a,'b>
in where F: for<'a> FnOnce(&'a Scope<'a,'b>)
implicit 'b:'a
and 'b
is a specific lifetime when instantiate the function scope_spawn
, hence it constraints that 'a
cannot be any lifetime. I don't know whether this is a correct understanding.
If my understanding is right, It seems that where F: for<'a> FnOnce(&'a Scope<'a,'b>)
is not a HRTB anymore because 'a
does not denote any lifetime?