Trait object as a source for errortype which derives snafu

I'm getting compilation error for this code.Here I want have trait object as a source for an errortype which derives snafu

use snafu::prelude::*;

trait Baz{}

#[derive(Debug, Snafu)]
enum Layer3Error {
    SomeError{source: Box<dyn Baz>}
}

fn main() {
    
}

error

error[E0277]: `(dyn Baz + 'static)` doesn't implement `Debug`
 --> src/main.rs:7:15
  |
5 | #[derive(Debug, Snafu)]
  |          ----- in this derive macro expansion
6 | enum Layer3Error {
7 |     SomeError{source: Box<dyn Baz>}
  |               ^^^^^^^^^^^^^^^^^^^^ `(dyn Baz + 'static)` cannot be formatted using `{:?}` because it doesn't implement `Debug`
  |
  = help: the trait `Debug` is not implemented for `(dyn Baz + 'static)`
  = help: the following other types implement trait `Debug`:
            (dyn Any + 'static)
            (dyn Any + Send + 'static)
            (dyn Any + Send + Sync + 'static)
  = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: `dyn Baz` doesn't implement `std::fmt::Display`
 --> src/main.rs:7:15
  |
5 | #[derive(Debug, Snafu)]
  |                 ----- in this derive macro expansion
6 | enum Layer3Error {
7 |     SomeError{source: Box<dyn Baz>}
  |               ^^^^^^ `dyn Baz` cannot be formatted with the default formatter
  |
  = help: the trait `std::fmt::Display` is not implemented for `dyn Baz`
  = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
  = help: the trait `std::fmt::Display` is implemented for `Box<T, A>`
  = note: this error originates in the macro `$crate::format_args` which comes from the expansion of the derive macro `Snafu` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0599]: the method `as_error_source` exists for reference `&Box<(dyn Baz + 'static)>`, but its trait bounds were not satisfied
   --> src/main.rs:5:17
    |
3   |   trait Baz{}
    |   ---------
    |   |
    |   doesn't satisfy `dyn Baz: AsErrorSource`
    |   doesn't satisfy `dyn Baz: Sized`
    |   doesn't satisfy `dyn Baz: snafu::Error`
4   |
5   |   #[derive(Debug, Snafu)]
    |                   ^^^^^ method cannot be called on `&Box<(dyn Baz + 'static)>` due to unsatisfied trait bounds
    |
   ::: /home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:199:1
    |
199 | / pub struct Box<
200 | |     T: ?Sized,
201 | |     #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
202 | | >(Unique<T>, A);
    | | -
    | | |
    | |_doesn't satisfy `Box<dyn Baz>: AsErrorSource`
    |   doesn't satisfy `Box<dyn Baz>: snafu::Error`
    |
    = note: the following trait bounds were not satisfied:
            `Box<dyn Baz>: snafu::Error`
            which is required by `Box<dyn Baz>: AsErrorSource`
            `&Box<dyn Baz>: snafu::Error`
            which is required by `&Box<dyn Baz>: AsErrorSource`
            `dyn Baz: Sized`
            which is required by `dyn Baz: AsErrorSource`
            `dyn Baz: snafu::Error`
            which is required by `dyn Baz: AsErrorSource`
    = note: this error originates in the derive macro `Snafu` (in Nightly builds, run with -Z macro-backtrace for more info)

Some errors have detailed explanations: E0277, E0599.
For more information about an error, try `rustc --explain E0277`.
error: could not compile `snafu_ex` due to 3 previous errors

Well, the compiler told you exactly what the problem is. There's nothing in Box<dyn Baz> that refers to the Debug trait, so how would the formatting mechanism know how to format it?

You probably need to add Debug as a supertrait to Baz.

AFAIK the source need to implement std::error::Error (which in turn requires Debug and Display) since it will be used to implement the source method of the Error implementation for your type.

1 Like