The trait `std::marker::Sized` is not implemented for `error::Error`

Hey everyone,

I have following impl:

impl KeyPair {
    pub fn new_key_pair() -> Result<Self, Error> {
        let (pub_sign_, sec_sign_) = gen_sign_keypair();
        let keypair = Self {
            pub_sign: pub_sign_,
            sec_sign: sec_sign_,
        };
        Ok(keypair)
    }
}

But because of the dynamic error type it outputs following error message:

error[E0277]: the size for values of type `(dyn error::Error + 'static)` cannot be known at compilation time
  --> src/lib.rs:19:5
   |
19 | /     pub fn new_key_pair() -> Result<Self, Error> {
20 | |         let (pub_sign_, sec_sign_) = gen_sign_keypair();
21 | |         let keypair = Self {
22 | |             pub_sign: pub_sign_,
...  |
26 | |         Ok(keypair)
27 | |     }
   | |_____^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `(dyn error::Error + 'static)`
   = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-sized>
   = note: required by `std::result::Result`

What do I need to do?
Thanks!

Use Box<dyn Error> or the anyhow crate.

The Error is a trait (similar to an abstract base class or interface in OO languages), which other objects can implement. So potentially anything could implement the Error interface, and the actual size of that thing can also be anything from 0 to nine quintillion bytes.

You get an error here because behind the scenes functions have to return a specific number of bytes known ahead of time rather than something abstract. Box<dyn Error> works because it's a pointer that has the same number of bytes as two usize elements, so it's well-known how to return it.

11 Likes