Inferred type of a function assigned to an untyped variable
⚓ Rust 📅 2025-11-12 👤 surdeus 👁️ 5I thought that, unlike closures, functions have well-defined types, like fn(), which is the same as fn() -> (), fn(bool, u8) -> (bool, u16) etc . (And similar for unsafe fn, like unsafe fn(), unsafe fn(bool, u8) -> (bool, u16) etc.)
But, when I assign a function identifier/path to an untyped variable, it has some other (unique?) type, as mentioned in this error:
no method named use_it found for fn item fn() {zero_args_unit} in the current scope
pub trait ZeroArgsUnitFnTrait {
fn use_it(&self) {}
}
type ZeroArgsUnitFnType = fn();
impl ZeroArgsUnitFnTrait for ZeroArgsUnitFnType {}
fn zero_args_unit() {}
// Compiles
fn assign_fn_to_typed_var() {
let f: fn() -> () = zero_args_unit;
f.use_it();
let f: ZeroArgsUnitFnType = zero_args_unit;
f.use_it();
}
// Fails to compile
fn assign_fn_to_untyped_var() {
let f = zero_args_unit;
f.use_it();
}
// Fails to compile
fn direct_no_assign() {
zero_args_unit.use_it();
}
Are those actual unnamed types accessible somehow, or can I at least implement trait(s) for them somehow (ideally separately for safe and unsafe ones, or just limiting to safe ones)? Or what are such types called and where can I read about them?
Or, a more specialized problem, please: How can I detect at compile time (in macro_rules!) whether a given function is safe (rather than unsafe), but without a compiler error. Or, rather, how do I ensure that a given function actually is not safe, but unsafe (and issue a compile error is the function is safe)? (I cannot use #[forbid(unused_unsafe)] and then unsafe {...}, because instead of a function identifier/path I may be given an expression that yields the function, and the actual expression itself may include unsafe{...}).
3 posts - 3 participants
🏷️ Rust_feed