I learned that the ? operator requires the function's result error type (let's call it F) to implement From<E>, where E is the error type of the expression I'm applying the operator.
I also recently learned that if I implement From<E> for F, I also get a "free" implementation of Into<F> for E. However, the reciprocal is not true; if I implement Into<E> for F I don't get an implementation of From<F> for E.
My question is, why doesn't the ? operator require the expression's result error type to implement Into<F> instead of requiring F to implement From<E>? Wouldn't it be more flexible?
Library authors should not directly implement this trait, but should prefer implementing the From trait, which offers greater flexibility and provides an equivalent Into implementation for free, thanks to a blanket implementation in the standard library.
So discouraging people from incorrectly implementing Into is not necessarily a bad thing.
I see, so the idea is to force the programmer to write more code if there's a desire or need to use Into. I understand that now, thanks!
I do think it's a high price to pay in some occasions, though (e.g.: the need to return an error type of another crate in your function, so you can't code a new From implementation), but that's just my 2 cents
That's a pretty complicated example, but it helped me see that there's an advantage to use From in some cases. That convinced me that From is a superior approach
What I actually meant was that there are situations where I would like to return their error type, after converting from my error type, and the ? operator would reduce the amount of code necessary.
I think I'm confused. I didn't think your example would work. Wasn't there a rule that I can't implement a trait for a type that's not from my crate? I thought you couldn't implement From for external types. Did I understand things incorrectly?
Thank you very much for your reply, I didn't even know I was missing something.
For non-generic traits, that's true - you cannot implement a foreign non-generic trait for a foreign type. With generic traits, you can use local types in the remote trait and still stay within the orphan rules. The following has more details: