The original code doesn't compile because type coercion only happens on the top level, not in the type parameters. For example, &String coerces to &str, but Option<&String> doesn't coerce to Option<&str>, and Fn(&String) doesn't coerce to Fn(&str).
fn()->T is covariant in T, which as defined there implies that if T is a subtype of U, then fn()->T is a subtype of fn()->U.
! is a subtype of i32, which should imply that the function panic, being of type fn()->!, should also be considered to be (a subtype) of type fn()->i32.
panic is not of type fn() -> !. It has an anonymous type, which happens to implement Fn() -> ! (note the capitalization). It does not implement Fn() -> i32, which is the trait requirement of unwrap_or_else. panic can be coerced to fn() -> !, but even if you do that it will still not implement Fn() -> i32 because they are different traits.
Moreover, ! is also not a subtype of i32. ! is coercible to i32, but that does not make a subtype relationship (previous discussion about this topic). For essentially the same reason, &String is coercible to &str, but &&String is not coercible to &&str.
Subtyping in Rust has to do with lifetimes. fn() -> &'static stris a subtype of fn() -> &'a str (actually that last one is hard to express, but you get the point). No lifetimes = no subtyping.
No, subtyping only applies to lifetimes. All other subtyping-like relations are merely conversions that the language support, and they are not subject to covariance.