error-chain icon indicating copy to clipboard operation
error-chain copied to clipboard

Error links cause conflicting From implementations when used cross-crate

Open dflemstr opened this issue 7 years ago • 6 comments

I have this minimal repository that reproduces the issue: https://github.com/dflemstr/error-chain-test

Running cargo build in the b directory yields:

$ cargo build
   Compiling b v0.1.0 (file:///home/dflemstr/github.com/dflemstr/error-chain-test/b)
error[E0119]: conflicting implementations of trait `std::convert::From<ErrorKind>` for type `ErrorKind`:
 --> src/lib.rs:5:1
  |
5 | error_chain! {
  | ^
  |
  = note: conflicting implementation in crate `core`
  = note: this error originates in a macro outside of the current crate

error: aborting due to previous error

error: Could not compile `b`.

To learn more, run the command again with --verbose.

dflemstr avatar Nov 28 '16 22:11 dflemstr

I hate conflicting implementations of From XD Does anyone knows how we can see WHICH implementation conflicts?

Yamakaky avatar Nov 28 '16 22:11 Yamakaky

Here's the output of cargo expand: https://gist.github.com/dflemstr/1b1a4ae1465fa72b42c4866c8a82d86a

EDIT: Accidentally uploaded the wrong gist, fixed now

dflemstr avatar Nov 28 '16 22:11 dflemstr

I'm totally new to this and am just passing through, but doesn't the example code say to put the error_chain!{} invocation inside of a mod errors{} to avoid conflicts...? Looking through your gist, it seems that impl From<<a::Error as ::error_chain::ChainedError>::ErrorKind> for ErrorKind is resolving to the exact ErrorKind that's being implemented, thus the conflicting implementation in the 'core' crate is actually impl From<T> for T which is just "Things can be converted to themselves" implementation provided for all types.

For <a::Error as ::error_chain::ChainedError>::ErrorKind to resolve, first you have to look at a::Error's impl of ::error_chain::ChainedError. In the macro expansion, the trait is implemented with type ErrorKind = ErrorKind. This would be in the A crate, so the fully qualified version would be type ErrorKind = a::ErrorKind. Therefore it all finally resolves to: impl From<a::ErrorKind> for b::ErrorKind

But, because the error_chain! macro isn't in a submodule, its methods are marked pub, which means they're part of the crate's public interface. Which means that the compiler could convert a::ErrorKind to a::Error through From<ErrorKind> for Error in the A crate, then through From<a::Error> for Error in the B crate, and then through From<Error> for ErrorKind in the B crate, thus resulting in: impl From <ErrorKind> for ErrorKind in the B crate. Which is conflicting with imple From <T> for T.

I honestly don't know if the rust compiler checks and/or cares about long conversion chains. I also don't know if it'll use From trait definitions in a crate that has no "use" statements. However, It does seem odd to have these things part of the crate interface. The recommended way of encapsulating the macro in a mod error {} submodule and then use error::* would not make these conversion operators public, from what I understand about rust. You'd need a pub use to do that. It would make sense then why the link{} section is so important, if those definitions aren't public.

I'm still a noob in some areas of rust and an expert in others, so I don't know what I don't know. I might be totally wrong. But this is what my intuition tells me, and it's a great time to learn a little part of the language.

Edit: Also note that I do not (currently) have access to a working rust installation, so I cannot test my hypothesis.

Phlosioneer avatar Dec 01 '16 06:12 Phlosioneer

The issue still happens with the error chains in different modules though.

dflemstr avatar Dec 01 '16 08:12 dflemstr

As I've found out from https://www.reddit.com/r/rust/comments/5fv9ar/details_of_implicit_coercion/ , most of what I thought I knew is hogwash. Just go ahead and ignore me, sorry!

Phlosioneer avatar Dec 01 '16 16:12 Phlosioneer

Fixed by https://github.com/brson/error-chain/pull/75, could you try master?

Yamakaky avatar Dec 03 '16 19:12 Yamakaky