Why this code compile failed?

#[derive(Default)]
pub struct Builder<T:Fn()> {
    decoder:Option<T>
}

impl<T:Fn()> Builder<T> {
    pub fn new() -> Self {
        //Builder {
        //    decoder:None,
        //}
        Builder::default()
    }
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `T: Default` is not satisfied
  --> src/lib.rs:11:9
   |
11 |         Builder::default()
   |         ^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `T`
   |
   = note: required because of the requirements on the impl of `Default` for `Builder<T>`
   = note: required by `std::default::Default::default`
help: consider further restricting this bound
   |
6  | impl<T:Fn() + Default> Builder<T> {
   |             ^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`

To learn more, run the command again with --verbose.

Can someone explain this? Thanks

Because the Fn traits doesn't impl the Default trait

The derive macro just isn't smart enough; it requires the type parameters to all implement Default too. You can implement it yourself though:

impl<T: Fn()> Default for Builder<T> {
    fn default() -> Self {
        Self { decoder: None }
    }
}
1 Like

I expand the Default macro and got something like this

impl<T> Default for Builder<T> {
    fn default() -> Self {
        Self {
            decoder:Default:::default()
        }
    }
}

But Option already implment Default for all type T, and it does not require T is Default. I don't understand why it faile here.

The macro expansion has an extra where T: Default bound on the generated impl, something like:

impl<T> Default for Builder<T> where T: Default { ... }

Thanks, I just overlooked this line.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.