I would recommend reading my blog to see how closures are desugared before making changes to it. My blog gives a detailed account of how closures are desugared, including little bits sich as mhow the move keyword interacts with closures.
Basically closures have a hidden enviornment parameter which is made explicit by the Fn* traits, so the struct containing the captured enviornment only needs to contain the enviornment, no need to store a function pointer.
Because for each closure, the compiler creates a new environment struct;
If you really need explicit types for your closures, then you have to do the unsugaring yourself instead of letting the compiler do it.
What currently prevents us from doing it in stable is the fact that Fn traits are unstable: it is still unclear whether their current design is good enough to become future-proof; it may thus change in the future, which would be a breaking change if it were stable.
Obviously stable Fn traits would be a very sweet thing to have, indeed.
This may be surprising, but monomorphisation is that powerful of a tool that you don't require function pointers around, it's all done statically (this is one of the places where Rust just blatantly outperforms C).
Since @RustyYato's blog post already covers closures, I will give an example of monomorphisation vs parameter that does not involve closures, since they are not needed to show the example:
That is, even though we call it with a One argument (c.f.repeat_hi_static(One); ), the "number 1" information of One is not within its struct but within its type (in a similar vein as to why a &[u8; 4] contains just an address whilst a &[u8]contains both an address and a size).
In a similar fashion, a closure's "call function" is relative to the type of the closure.