Why can the unsafe function pointer be as the function operand?
⚓ Rust 📅 2025-08-19 👤 surdeus 👁️ 13Call 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:
FnorAsyncFn— shared reference.FnMutorAsyncFnMut— mutable reference.FnOnceorAsyncFnOnce— value.
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, andFnOnce, 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
🏷️ Rust_feed