0

What enables a function trait type (std::ops::Fn) to be used where an fn type (e.g. closure, function definition, fn pointer type) is expected?

fn take_closure<F: Fn(u32) -> u32>(_f: F) {}

fn id(x: u32) -> u32 {
    x
}

fn main() {
    take_closure(id);
}

Is it:

I'm asking more about mental model than about concrete implementation.

Edit

updated the example, previously the example showed conversion the other way. Sorry about that. I created a separate question to ask about conversion the other way: What enables a closure type to be used where a function pointer type to be used in Rust?

Max Heiber
  • 14,346
  • 12
  • 59
  • 97
  • 2
    Note that there is no coercion from `Fn` (the trait) to `fn` (the function pointer). However there _is_ a coercion between the namaless function type (its identity?) to the `fn` function pointer. – rodrigo Dec 28 '21 at 14:09
  • Aren't types implementing `Fn` automagically coerced, so long as they don't capture variables from the environment? – Teymour Dec 28 '21 at 17:11

1 Answers1

4

It is the former (the implementations are produced by the compiler). From the documentation.

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

I sometimes think of this as fn is a Fn which does not capture anything from the environment.

blackgreen
  • 34,072
  • 23
  • 111
  • 129
Teymour
  • 1,832
  • 1
  • 13
  • 34
  • @ChayimFriedman you're both right. My example was out of sync with my question. Your answer is accurate for `Fn` to `fn`, @TeymourAldridge's answer is accurate for `fn` to `Fn`, which is what I meant to ask about. – Max Heiber Dec 29 '21 at 14:03