Fn pointer vs closures, dynamic or static dispatch


I couldn’t find definitive answers about the following so I need clarification.

Are function pointers (eg. fn(i32) -> i32) dynamically dispatched?

Are closures always dynamically dispatched?


They both can be statically dispatched, even inlined, if there’s not too much indirection for the compiler/optimizer to see through.


In a non-optimized build, function pointers are indirect calls, closures used as trait objects Box<Fn()> are also indirect calls, and closures used as generic type arguments fn foo<F: Fn()>(closure: F, ...) are monomorphized and become direct calls.

When optimizing, the first two categories may be devirtualized as the previous comment.


Got it. Thanks.