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
panic can be coerced to
fn() -> !, but even if you do that it will still not implement
Fn() -> i32 because they are different traits.
! is also not a subtype of
! 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
&&String is not coercible to
Subtyping in Rust has to do with lifetimes.
fn() -> &'static str is a subtype of
fn() -> &'a str (actually that last one is hard to express, but you get the point). No lifetimes = no subtyping.