Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Rust empty explicit generic argument for Option<impl Fn(i64)>

I have Option<impl Fn(i64) -> i64> as an argument to a function apply() and I want to pass None value. apply(None). How do I write the apply(None) function call correctly so it compiles?

fn main(){
    let a = apply(Some(|i| i + 1));
    
    let b = apply(None);
    let b2 = apply(None::<dyn Fn(i64) -> i64>);
    
    println!("a: {0}; b: {1}", a, b)
}

fn apply(f: Option<impl Fn(i64) -> i64>) -> i64 {
    let i = 0_i64;
    match f {
        Some(f) => f(i),
        None => i,
    }
}

compile error:

Compiling playground v0.0.1 (/playground)
error[E0282]: type annotations needed
 --> src/main.rs:4:16
  |
4 |     let b = apply(None);
  |                   ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
  |
help: consider specifying the generic argument
  |
4 |     let b = apply(None::<T>);
  |                       +++++

error[E0283]: type annotations needed
  --> src/main.rs:4:16
   |
4  |     let b = apply(None);
   |             ----- ^^^^ cannot infer type of the type parameter `T` declared on the enum `Option`
   |             |
   |             required by a bound introduced by this call
   |
   = note: multiple `impl`s satisfying `_: Fn<(i64,)>` found in the following crates: `alloc`, `core`:
           - impl<A, F> Fn<A> for &F
             where A: Tuple, F: Fn<A>, F: ?Sized;
           - impl<Args, F, A> Fn<Args> for Box<F, A>
             where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
note: required by a bound in `apply`
  --> src/main.rs:10:25
   |
10 | fn apply(f: Option<impl Fn(i64) -> i64>) -> i64 {
   |                         ^^^^^^^^^^^^^^ required by this bound in `apply`
help: consider specifying the generic argument
   |
4  |     let b = apply(None::<T>);
   |                       +++++

Some errors have detailed explanations: E0282, E0283.
For more information about an error, try `rustc --explain E0282`.

I tried let b2 = apply(None::<dyn Fn(i64) -> i64>); but it still doesn’t compile the errors are

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

 Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `dyn Fn(i64) -> i64` cannot be known at compilation time
 --> src/main.rs:5:20
  |
5 |     let b2 = apply(None::<dyn Fn(i64) -> i64>);
  |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `Sized` is not implemented for `dyn Fn(i64) -> i64`
note: required by a bound in `None`
 --> /rustc/eb26296b556cef10fb713a38f3d16b9886080f26/library/core/src/option.rs:567:5

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (bin "playground") due to previous error

>Solution :

The type dyn Fn(i64) -> i64 is unsized, meaning you can’t store it in an enum like Option.

But a trait object reference is sized, so you can use &dyn instead:

apply(None::<&dyn Fn(i64) -> i64>);

However, it’s probably better to use a function pointer type instead:

apply(None::<fn(i64) -> i64>);

playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading