impl<T> From<T> for MyError conflict?

Hello,

I've got a "blind" MyError empty struct as a generic error indicator that needs to be used for various "backend errors" in an embedded setup.

MyError is used by a driver so that things like some_spi.write()? can be used and the error will simply convert to MyError.

Problem is I can't add a blanket

impl<E> From<E> for MyError {
  fn from(_: E) {
    MyError
  }
}

because apparently it conflicts with core's impl<T> From<T> for T.

How is that correct tho? Core's version is using the same T both in the From and the destination... I guess it's because impl From<PinError> for PinError is a sub-case?

How can this be worked-around to provide a blanket "to-MyError" for any type that's NOT MyError ?

The impl from stdlib says that any value of type T can be converted into itself. This means that a MyError value can be turned into a MyError value.
Because of that, it conflicts with your own impl, which would allow the same thing. But if that were legal, rust would not know which one to use.

This is unfortunately not currently possible without defining you own From trait. The best you can do is implement From for some large class of types that doesn’t include yours.

Specialization will eventually fix this, but it has a history of soundness problems that force major redesigns— At this point, I wouldn’t recommend making any plans based on it.

This is unfortunate. Sadly I can't do specialized implementations because I have 0 knowledge of the types. This is a generic driver that has no knowledge of the backend providers.

I guess I'll have to give up on using ? and .is_err() map the backend errors manually.

I’ve gotten bit by this particular issue myself, and I’d really like it to be fixed. If somebody writing code for your system knows the actual error types, you can provide an IntoMyError marker trait, so that they just have to impl IntoMyError for SpecificErrorType {} to enable ? conversion— as long as MyError doesn’t implement the trait, you shouldn’t have the conflict.

You can still use ? this way:

result.map_err(|_| MyError)?;

You could write a trait to make that shorter:

result.blah()?;

and if you don't care about the error, you can use Option as the error type, and:

result.ok()?;

I'm afraid the orphan rules make this impossible. The IntoMyError is provided by my driver crate, SpecificBackendError is provided by whatever crate the user's code imports and the user is in the middle.

Yes I think I'll have to do this.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.