I am experimenting with higher-ranked-trait bounds. In a minimal example, I created, there is a function taking a closure which takes a &str
and returning a &str
of the same lifetime 'a
. I explicitly declared the lifetimes on the Fn
trait.
fn foo(_: &for<'a> Fn(&'a str) -> &'a str) {
}
fn main() {
foo(&|s| s);
}
This works fine. If I annotate the type of the parameter in the closure to be of type &str
, I receive a lifetime error:
fn foo(_: &for<'a> Fn(&'a str) -> &'a str) {
}
fn main() {
foo(&|s: &str| s); // explicitly specified parameter type
}
That confuses me. For several reasons.
- Isn't the return type of the closure inferred to be of the same type as the parameter (with the same lifetime via lifetime elision)?
- The argument of
foo
is univerally quantified over all possible lifetimes. Why can't the type of the lifetime be arbitrary? Isn't'a
just a placeholder for some lifetime?
It works without specifying the type explicitly, but why? How are those two versions different?