This is an example using HRTB:
struct S {
var1: i32,
var2: i32,
}
impl S
{
fn extract<F>(&self, f: F) -> &i32
where F: Fn(&S) -> &i32
{
f(self)
}
}
fn main() {
let var = S { var1: 1, var2: 2};
let ptr_to_var1 = var.extract(| s | &s.var1);
println!("{}", ptr_to_var1);
}
We know that the where
clause in extract
function actually means: where F: for <'f> Fn(&'f S) -> &'f i32
.
But if I wrote as below, it still compiles by latest version of rustc [rustc 1.21.0-nightly (c11f689d2 2017-08-29)].
impl S
{
fn extract<'a, F>(&'a self, f: F) -> &'a i32
where F: Fn(&'a S) -> &'a i32
{
f(self)
}
}
fn ext(s: &S) -> &i32 { &s.var2 }
fn main() {
let var = S { var1: 1, var2: 2};
let ptr_to_var1 = var.extract(ext);
println!("{}", ptr_to_var1);
}
And I remember that this piece of code was rejected by compiler several months ago. I don't know what's happened in this period, could anyone can explain that? When should I use a HRTB while not using lifetime ellision?