Oddly enough, it doesn't even allow it in unsafe code, not with a normal cast. You have to use transmute. I believe this is due to concerns about targets where function and data pointers have different representations.
I believe it has more to do with the fact that function pointers are effectively &'static T (static references) and references are forbidden from being null. But it's probably a bit of both.
In other words `0usize as fn ()` is insta-undefined behavior, and you can't have that in safe code.
No, Rust does not allow safe conversions from integers to function pointers. The code `main as usize as fn()` will result in a "non-primitive cast" error. In order to convert from an integer or raw pointer to a function pointer, the unsafe function `std::mem::transmute` must be used.
In that case, then a linter warning seems more appropriate for pointer->int than requiring "unsafe". I feel "unsafe" should not be diluted to mean "unwise". But what do I know, I'm a C++ programmer...
The broader topic of whether it is safe, or wise, to cast between pointers and integers in general is an area of active research. Ralf Jung's blog is required reading on this topic: https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html