Description
Despite them being ZSTs and Copy
, which would allow Fn
/ FnMut
impls on top of FnOnce
.
This small example:
fn foo(f: impl FnOnce()) { f() }
pub fn test() {
// Not passed directly in call to avoid inferring `closure` to `FnOnce`.
let closure = || {};
foo(closure);
}
will cause a ClosureOnceShim
to be generated, which takes the ZST closure, borrows it, and passes it to the actual closure "function", that has been inferred to be Fn
(I think?).
While correct, it's an extra function between the caller and the closure, and there's a potential risk of LLVM doing not-that-nice (e.g. inlining-related) things (and mergefunc might not work here).
This seems tricky to fix, since parts of the compiler assume that e.g. a closure implements FnMut
if it can be called with a mutable reference to its environment, and if it implements FnMut
and not Fn
, then its "codegen'd function" must have a FnMut::call_mut
signature.
cc @rust-lang/wg-codegen