Cannot derive on enum with variants wrapping associated types
SuperFluffy opened this issue · comments
Using the most recent thiserror
, I am getting an error when trying to compile the following example:
use thiserror::Error;
trait AssocError {
type Error: std::error::Error;
}
#[derive(Error, Debug)]
pub enum MyExpandedError<A>
where
A: AssocError,
{
#[error("My Foo error")]
Foo,
#[error("Error from associated type")]
Assoc(#[from] A::Error),
}
And this is the error:
error[E0119]: conflicting implementations of trait `std::convert::From<MyExpandedError<_>>` for type `MyExpandedError<_>`:
--> src/lib.rs:7:10
|
7 | #[derive(Error, Debug)]
| ^^^^^
|
= note: conflicting implementation in crate `core`:
- impl<T> std::convert::From<T> for T;
= note: this error originates in a derive macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0119`.
error: could not compile `thiserror_from`.
The compiler's message is correct here, you have a conflict with the From
impl in std. You're asking to generate impl<A> From<A::Error> for MyExpandedError<A> where A: AssocError
, but there might be a type A
for which A::Error = MyExpandedError<A>
, so your impl overlaps with impl From<T> for T
.
If you didn't intend for a From
impl, you should use #[source] instead of #[from]. Something like:
use std::fmt::{self, Debug};
use thiserror::Error;
pub trait AssocError {
type Error: std::error::Error + 'static;
}
#[derive(Error)]
pub enum MyExpandedError<A>
where
A: AssocError,
{
#[error("My Foo error")]
Foo,
#[error("Error from associated type")]
Assoc(#[source] A::Error),
}
impl<A> Debug for MyExpandedError<A>
where
A: AssocError,
{
fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
...
}
}
Good point, thank you. I didn't realize this at the time that doing this I could in principle create a recursive type definition.
I am a bit sad because not being able to impl<A> From<A::Error> for MyExpandError<A> where A: AssocError
means that I cannot apply the ?
operator. :-(