I want to create a function which accepts an optional callback function as argument. When I provide a function the code compiles without error. But when I provide None, then I get a compile error.
Compiling playground v0.0.1 (/playground)
error[E0284]: type annotations needed: cannot satisfy `for<'r> <_ as FnOnce<(&'r [u8],)>>::Output == bool`
--> src/main.rs:19:18
|
11 | pub fn new(fn_block_mode: Option<F>) -> Self {
| -------------------------------------------- required by `AdvReader::<F>::new`
...
19 | let reader = AdvReader::new(None);
| ^^^^^^^^^^^^^^ cannot satisfy `for<'r> <_ as FnOnce<(&'r [u8],)>>::Output == bool`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0284`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
It can't figure out what the F in AdvReader<F> is when you give it None. It could be anything that meets your trait bounds, and there are many possibilities. The same will be true of any generic.
Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `(dyn for<'r> Fn(&'r [u8]) -> bool + Send + 'static)` cannot be known at compilation time
--> src/main.rs:19:41
|
19 | let reader = AdvReader::new(None as Option<dyn Fn(&[u8]) -> bool + Send + 'static>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `(dyn for<'r> Fn(&'r [u8]) -> bool + Send + 'static)`
error[E0277]: the size for values of type `dyn for<'r> Fn(&'r [u8]) -> bool + Send` cannot be known at compilation time
--> src/main.rs:19:33
|
11 | pub fn new(fn_block_mode: Option<F>) -> Self {
| -------------------------------------------- required by `AdvReader::<F>::new`
...
19 | let reader = AdvReader::new(None as Option<dyn Fn(&[u8]) -> bool + Send + 'static>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn for<'r> Fn(&'r [u8]) -> bool + Send`
error[E0277]: the size for values of type `dyn for<'r> Fn(&'r [u8]) -> bool + Send` cannot be known at compilation time
--> src/main.rs:19:18
|
3 | pub struct AdvReader<F: Fn(&[u8]) -> bool + Send + 'static>
| - required by this bound in `AdvReader`
...
19 | let reader = AdvReader::new(None as Option<dyn Fn(&[u8]) -> bool + Send + 'static>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `dyn for<'r> Fn(&'r [u8]) -> bool + Send`
help: consider relaxing the implicit `Sized` restriction
|
3 | pub struct AdvReader<F: Fn(&[u8]) -> bool + Send + 'static + ?Sized>
| ^^^^^^^^
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`
To learn more, run the command again with --verbose.
I can's speak for the OP but they came back with the dyn in reply to function pointers being suggested already, so I assumed they have a reason for the switch.
I think the confusion at the root of this question comes down to the difference between fn and Fn. I remember this tripped me up when I was starting out.
I suggested:
let reader = AdvReader::new(None as Option<fn(&[u8]) -> bool>);
and the original poster replied:
but in actuality, they tried this:
let reader = AdvReader::new(None as Option<dyn Fn(&[u8]) -> bool + Send + 'static>);
Bottom line. Fn is a trait that bounds function pointers and closures, and fn is the syntax to declare a concrete function pointer type. But many newcomers (myself in the past included) mix them up.