So, let's say you have a F: for<'f> Fn(&'f str). What happens when you pass it to this?
fn a<G: Fn(In), In>(_: G) {}
The answer is that the compiler has to choose a single type to resolve the In type parameter. So it chooses a single lifetime, 'static say, and you can pass in your F: Fn(&'static str). It's no longer higher-ranked, because generic type parameters must resolve to a single type (and types that differ by lifetime only are still distinct types).
There is a way partially around this with custom traits, but it's a pain and wrecks a lot of inference. The key trick is to avoid "naming" higher-ranked things with type parameters. (More details.)
But I don't think it helps with this type-erased form, because you basically want to end up with something like
trait BorrowingFn {
type In<'a>;
type Out<'a>;
fn call<'a>(&self, input: Self::In<'a>) -> Self::Out<'a>;
}
let _ = &dyn BorrowingFn< ... ? ... >
and we don't have a way to support or even specify GATs/higher-ranked things in trait objects yet.
// Imaginary syntax for some future Rust
dyn BorrowingFn<for<'x, 'y> In<'x> = &'x String, Out<'y> = &'y str>>
As for the 'static bounds, a fn(&'a str): 'static bound fails for example; the lifetime relationship is syntactical in nature. It's probably the same thing going on with Fn, but I also think it's not your actual problem and just a symptom, so I won't dig any further.
(fn(&str): 'static is a bound that can be met.)