Why lifetimes in function trait are not default to late bound while the functions' are late bound

The lifetime in function trait like Fn is late bound but the lifetime in the function like get(&str) is late bound.

Thus the for<'a> syntax is needed for the function trait to indicate the lifetime is late bound.

Why does not make the lifetime of the function trait late bound to be aligned with the function?

If 80% of the cases, we will need the for<'a> syntax to indicate late bound for function trait, is it better to make it default to late bound?

Did you misphrase something here?

Anyway, whether a lifetime is late bound for a function item or not depends on if it appears in any where clauses. dyn Fn(..) and function pointer fn(..) types don't have where clauses. They either support all lifetimes modulo implied bounds, or support specific lifetimes. Lifetime elision in the arguments corresponds to the former, which one could call late bound I suppose. The more common terminology is that the type is higher-ranked.

It's not required; part of their special syntax is that you can elide higher-ranked lifetimes. dyn Fn(&str) and dyn for<'a> Fn(&'a str) are the same type; F: Fn(&str) and F: for<'a> Fn(&'a str) are the same bound.

Thank you for the explanation!!
I get my thought based on reading the nomicon Higher-Rank Trait Bounds - The Rustonomicon

In the page, it say // where F: Fn(&'??? (u8, u16)) -> &'??? u8,

If Fn is default to late bound, is it OK we just write

impl<F> Closure<F>
     where F: Fn(& (u8, u16)) -> & u8,

I might misread the page due to my limit knowledge on HRTB

That page does read a little odd on its own in my opinion, since it's starting from working code and trying to "desugar" it. And their other section on "desugaring" lifetimes in a function body

  1. Is not a desugaring (it's non-compiing pseudo-syntax)
  2. Is a totally different scenario than a trait bound
  3. Is pretty misleading IMO as lifetimes don't correspond to lexical scopes[1]

But at any rate, the end conclusion (which is accurate) is that these do the same thing:

impl<F> Closure<F>
    where F: Fn(&(u8, u16)) -> &u8,
impl<F> Closure<F>
    where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,

  1. at least since NLL landed in 2018 â†Šī¸Ž

1 Like