Why can the unsafe function pointer be as the function operand?

⚓ Rust    📅 2025-08-19    👤 surdeus    👁️ 5      

surdeus

Call expressions - The Rust Reference says:

For non-function types, the expression f(...) uses the method on one of the following traits based on the function operand:

The non-function types, as indicated by the link, refer to function item types. In this example:

fn set(i:i32){}
fn main(){
   (&set)(0);  // #1
}

#1 is of type reference to F, where F is a function item type. Therefore, it can be explained by this rule because &F implements Fn* traits. However, consider this example:

unsafe fn foo(i:i32){}
fn main(){
  let f = foo as unsafe fn(i32);
  unsafe{
    f(0);
 }
}

f is of type unsafe function pointer, fn - Rust says:

In addition, all safe function pointers implement Fn, FnMut, and FnOnce, because these traits are specially known to the compiler.

The wording emphasizes safe, in other words, unsafe function pointers don't implement Fn, FnMut, and FnOnce. Furthermore, the (unsafe)function pointers aren't function item types, so why is f(0) is a valid call expression?

3 posts - 2 participants

Read full topic

🏷️ Rust_feed