Consider the following (playground):
fn require_static(_: impl 'static + Fn()) {}
fn generic<T>() {}
fn works<T>() {
require_static(|| generic::<T>());
}
fn does_not_work<T>() {
let generic_t = generic::<T>;
require_static(move || generic_t()); //~ `T` may not live long enough
}
fn also_does_not_work<T>() {
require_static(generic::<T>); //~ `T` may not live long enough
}
Is it justified that works
compiles but neither does_not_work
nor also_does_not_work
do not? It seems to me that the borrow-checker is either overly optimistic in the succeeding case or overly pessimistic in the failing cases. I'm struggling to see how the latter two can be unsound whilst the former is sound.
In particular, in works
the closure || generic::<T>()
is determined to satisfy a 'static
lifetime bound: however it (and therefore generic::<T>
) might not be invoked until after T
is no longer valid. I haven't been able to exploit this to demonstrate unsoundness, but it feels to me that it shouldn't be allowed?
Is this a known issue, or have I misunderstood the situation?
(This is a spin-off from rust - "The parameter type `T` must be valid for the static lifetime" Only when not in `async` block - Stack Overflow).