Problem using thiserror crate: try to define parametrized error types

I'm trying to define parametrized error types using the thiserror crate.
I wrote the following code and the use of the #[from] preventing the code to compile. Any idea how to fix this?

use thiserror::Error; // 2.0.0

#[derive(Debug,Error)]
pub enum ErrA {
    #[error("Ea")]
    Ea,
}

#[derive(Debug,Error)]
pub enum ErrB {
    #[error("Eb")]
    Eb,
}

struct A{}
struct B{}

pub trait ErrorSelector {
    type ErrType: std::error::Error;
}

impl ErrorSelector for A {
    type ErrType = ErrA;
}

impl ErrorSelector for B {
    type ErrType = ErrB;
}

#[derive(Debug,Error)]
pub enum MyErr<E: ErrorSelector + 'static> {
    #[error("MyErr::Input")]
    Input{
        #[from]
        source: E::ErrType,
    }    
}

fn main() {
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0119]: conflicting implementations of trait `From<MyErr<_>>` for type `MyErr<_>`
  --> src/lib.rs:35:9
   |
35 |         #[from]
   |         ^^^^^^^
   |
   = note: conflicting implementation in crate `core`:
           - impl<T> From<T> for T;

For more information about this error, try `rustc --explain E0119`.
error: could not compile `playground` (lib) due to 1 previous error

You can't have a generic From implementation of this kind regardless of whether you use thiserror to do it. You can still have your generic error type — just use explicit construction to do it. This will be easiest if you use a tuple variant:

pub enum MyErr<E: ErrorSelector + 'static> {
    #[error("MyErr::Input")]
    Input(#[source] E::ErrType),
}

fn some_function() -> Result<(), MyErr<A>> {
    ...
    some_fallible_operation().map_err(MyErr::Input)?;
    ...
}

Or, you can implement From for each of the specific cases:

impl From<ErrA> for MyErr<A> {...}
impl From<ErrB> for MyErr<B> {...}
2 Likes