I have the following code:
struct MakeVec<F: FnOnce(usize) -> Vec<u8>> {
f: F,
}
impl<F: FnOnce(usize) -> Vec<u8>> MakeVec<F> {
fn new(f: F) -> MakeVec<F> {
MakeVec { f }
}
fn new_std() -> MakeVec<impl FnOnce(usize) -> Vec<u8>> {
MakeVec { f: |n| vec![0; n] }
}
}
I want new
to take a function supplied by the user, while new_std
uses the vec!
macro from the standard library in a closure. The client shouldn't need to know the concrete type of the closure, only that it impl
's the right trait. This code compiles.
However, when you try to call the function, the compiler tries to infer the type of F
, and fails:
error[E0284]: type annotations required: cannot resolve `<_ as std::ops::FnOnce<(usize,)>>::Output == std::vec::Vec<u8>`
--> src/main.rs:16:13
|
16 | let _ = MakeVec::new_std();
| ^^^^^^^^^^^^^^^^
|
note: required by `<MakeVec<F>>::new_std`
--> src/main.rs:10:5
|
10 | fn new_std() -> MakeVec<impl FnOnce(usize) -> Vec<u8>> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Is there a way to make this work? Putting new_std
in its own impl
block doesn't seem to work since it would require writing down the type of the closure, which you can't do.
NOTE: I know you can do this with a bare function, but I'd prefer it to be an associated constructor, as that's the idiomatic way to do it.