Is it possible to implement TryFrom with a generic type?

Is it possible to implement TryFrom<T> for a generic type T like this?

#[derive(Debug)]
struct A;

impl<T> TryFrom<T> for A {
    type Error = Infallible;
    fn try_from(_input: T) -> Result<Self, Self::Error> { Ok(A) }
}

(playground)

Attempting to compile this as-is produces the following compile error:

error[E0119]: conflicting implementations of trait `TryFrom<_>` for type `A`
 --> src/lib.rs:7:1
  |
7 | impl<T> TryFrom<T> for A {
  | ^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: conflicting implementation in crate `core`:
          - impl<T, U> TryFrom<U> for T
            where U: Into<T>;

My current understanding is that it's not possible to implement TryFrom<T> using a generic type parameter T like this because this impl means that for any and every type T that could possibly exist, TryFrom<T> is implemented for A. Some of these types T might also implement Into<A>and for those that do, an implementation of TryFrom<T> for A is already provided by the blanket impl defined in std: impl<T, U> TryFrom<U> for T where U: Into<T>.

Is this explanation correct? And if so, why isn't it possible to exclude all types T which might implement Into<A> using a trait bound like this?

trait MyTrait;
struct A;

impl<T: MyTrait> TryFrom<T> for A {
    type Error = Infallible;
    fn try_from(_input: T) -> Result<Self, Self::Error> { Ok(A) }
}

It seems to me that since MyTrait is a private trait, only types defined the same crate can implement it, and therefore impl<T: MyTrait> TryFrom<T> for A only applies to a finite set of types T which can all be proven not to implement Into<A> and therefore not introduce a trait impl conflict via the blanket impl. If this is not possible why not?

It's because of the coherence checking. Going through this may help:

https://rustc-dev-guide.rust-lang.org/coherence.html

A implements From<A> via From’s blanket implementation, and therefore the standard library implements TryFrom<A> for A, which overlaps with your implementation when T = A. Therefore, your implementation does overlap and even a perfect compiler must not allow it. (Update: this is incorrect, because there is no impl MyTrait for A.)

(If Rust had “not equals” bounds on type parameters, then you could require T != A, but this has the same kinds of issues as specialization.)

It would be convenient if there was a mechanism for "all T local to this crate". (Those are allowed if there is no actual overlap.)

In the meanwhile, if that's truly all you need, a macro can lighten the tedium of an implementation per local type.

True, but A does not implement MyTrait, so shouldn't A be excluded from the possible types of T via the trait bound T: MyTrait? If the entire crate was just

trait MyTrait {}
struct A;
struct B;
impl MyTrait for B {}

impl<T: MyTrait> TryFrom<T> for A {
    type Error = Infallible;
    fn try_from(_input: T) -> Result<Self, Self::Error> { Ok(A) }
}

Wouldn't B be the only possible type in the universe that could match the generic type parameter T in the impl<T: MyTrait> TryFrom<T> for A? If B is the only possible T and B does not implement Into<A>, it seems that there should be no trait impl conflict with the blanket impl from std.

I’m sorry, I missed that. My previous post is incorrect, then.

Hmmm. When I try to compile this:

use std::convert::Infallible;

trait MyTrait {}
pub struct A;
pub struct B;
impl MyTrait for B {}

impl<T: MyTrait> TryFrom<T> for A {
    type Error = Infallible;
    fn try_from(_input: T) -> Result<Self, Self::Error> { Ok(A) }
}

(Playground)

I still get the conflict with the blanket impl from std (impl<T, U> TryFrom<U> for T where U: Into<T>). Does anyone know why restricting the type of T in with the trait bound : MyTrait in impl<T: MyTrait> TryFrom<T> for A is not sufficient to satisfy the coherence checker? The way I see it, the only type that could ever match T is B which does not implement Into<A>, so I'm not seeing where the trait impl conflict is coming from.

Because privacy is not considered for coherence; there is no mechanism for "all T local to this crate".

hmmm I see. So does that make impl<T: AnyBound> TryFrom<T> for LocalType impossible?

There's no way to do that in the language currently, correct.