Conflict with blanket implementation on `TryFrom` implementation

Hey all,

Having what I think is a noob question and issue on a blanket implementation conflict with the TryFrom trait. Here is the code that you can try to compile in the playground:

use std::convert::Infallible;

struct MyType;

impl<U: TryInto<MyType>> TryFrom<&U> for MyType {
    type Error = Infallible;

    fn try_from(value: &U) -> Result<Self, Self::Error> {
        value.try_into()
    }
}

I get the following error:

  |
5 | impl<T: TryInto<MyType>> TryFrom<&T> for MyType {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: conflicting implementation in crate `core`:
          - impl<T, U> TryFrom<U> for T
            where U: Into<T>;
  = note: downstream crates may implement trait `std::convert::From<&_>` for type `MyType

Now I understand why trying to implement impl<U: TryInto<MyType>> TryFrom<U> for MyType should fail to compile, since the bound U: Into<T> implies U: TryInto<T> and thus I would get a conflict with the blanket implementation. What I don't get is why would I not be able to write it with TryFrom<&U>? Would such a conflict imply that implementating TryFrom<U> gets me TryFrom<&U> (which I don't think is the case)?

Thanks in advance for your help!

I think the issue is there is nothing stopping both impl From<TheirType> for MyType as well as impl From<&TheirType> for MyType from existing in a downstream crate. The issue isn't that both impl's have to exist, just that they could.

3 Likes