I know why Vec<impl Fn> is not allowed in let bindings because the size of impl Fn is unknown at compile time - the compiler needs to know how much memory is required to be allocated for this array.
But why is it allowed in function signatures?
There's nothing fundamentally challenging about Vec<impl Fn()>. impl Trait is basically an anonymous generic, so this is just the type of a Vec that contains any quantity of the same type that implements Fn(). In your code, both f1 and f2 become fn() pointers, so they're the same type.
This doesn't work in let bindings because it's still in development. The error message links an issue with more info:
error[E0562]: `impl Trait` is not allowed in the type of variable bindings
--> src/main.rs:2:16
|
2 | let f: Vec<impl Fn()> = vec![|| {}];
| ^^^^^^^^^
|
= note: `impl Trait` is only allowed in arguments and return types of functions and methods
= note: see issue #63065 <https://github.com/rust-lang/rust/issues/63065> for more information
Adding to what @drewtato said: This isn't true. The size of impl Fn (and every other impl ??? type) is known at compile time. You may be thinking of dyn Fn, which size isn't known at compile time.
You can use impl ?Sized + Trait to disable the implicit Sized bound. (But yeah, the instability of impl Trait in let binding is unrelated to any of that.)
Yes, but it is not allowed in function signatures, not just let bindings.[1] So the "has-Sized-bound-or-not-ness" of any given impl ??? is still orthogonal to whether it is allowed in let bindings...
...in contrast to what was written in the OP.
And impl Trait + Sized + ?Sized is allowed, albeit pointless, except in macros perhaps (think impl $tr + ?Sized with $tr = Clone) âŠī¸