Sometimes a counter-example can be more helpful than a lengthy explanation.
Let's start from
and now imagine it being used:
let s = String::from("Hello, World!");
let partial
: _ // some type Anon : for<'b> Fn(&'b str) -> &'b str
= bar(&s) // `partial` closure contains `a = &s` // ---+
; // | lifetime 'a
drop(s); // make `&s` dangle <-----------------------------+
partial("Hello"); // Error, cannot use an object with a dangling reference
So, as you can see, although there may be a second lifetime 'b
involved for the final returned thinggy, the closure object resulting from a partial application, which captures the input a: &'a str
, is itself "infected" with the 'a
lifetime bound.
That is, the Anon
type has a Anon : 'a
bound
In other words,
Anon : 'a,
Anon : for<'b> Fn(&'b str) -> &'b str,
Anon : 'a
+ for<'b> Fn(&'b str) -> &'b str,
Anon : 'a + for<'b> Fn(&'b str) -> &'b str,
which written in an existential manner leads to bar()
return type being:
impl 'a + for<'b> Fn(&'b str) -> &'b str
Hence the need to add a 'a
bound to the impl ...
returned existential type.
This can be even more confusing given that it is customary in Rust (rather arbitrarily truth be told) to write the lifetime bounds after the trait bounds, resulting in
impl for<'b> Fn(&'b str) -> &'b str + 'a
which visually seems to say that there is a lifetime 'a
bound attached to the returned &'b str
When you don't specify a lifetime bound on an impl
existential type, i.e., when you elide the lifetime bounds implicitly, then Rust uses the 'static
lifetime "to fill the gap / hole / elided lifetime":
impl /* */ for<'b> Fn(&'b str) -> &'b str
==
impl 'static + for<'b> Fn(&'b str) -> &'b str
- Playground with the same error message as in the OP, but using
'static
explicitely
So, your error message was just telling you that in your signature you were (implicitly) claiming that the closure returned by the partial application was not borrowing any local ('static
bound), which was a lie given that it captured the local a: &'a str
, which was itself borrowing a potentially local str
.