Conflicting implementations for trait `core::convert::From`


#1

The following snippet gives me a compiler error:

use std::convert::From;

trait Trait {
    type A;
}

struct Type<T: Trait>(pub T::A);

impl<T: Trait> From<T::A> for Type<T> {
    fn from(a: T::A) -> Type<T> {
        Type(a)
    }
}
<anon>:9:1: 13:2 error: conflicting implementations for trait `core::convert::From` [E0119]
<anon>: 9 impl<T: Trait> From<T::A> for Type<T> {
<anon>:10     fn from(a: T::A) -> Type<T> {
<anon>:11         Type(a)
<anon>:12     }
<anon>:13 }
<anon>:9:1: 13:2 help: see the detailed explanation for E0119
<anon>:9:1: 13:2 note: conflicting implementation in crate `core`
<anon>: 9 impl<T: Trait> From<T::A> for Type<T> {
<anon>:10     fn from(a: T::A) -> Type<T> {
<anon>:11         Type(a)
<anon>:12     }
<anon>:13 }
error: aborting due to previous error
playpen: application terminated with error code 101

Where do I find the conflicting implementation and how can I make the snippet work?

Thanks!


#2

that already implemented inside std::convert as generic:

// From (and thus Into) is reflexive
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> From<T> for T {
    fn from(t: T) -> T { t }
}

you don’t have to declare, it works out of the box:

use std::convert::From;

trait Trait {
    type A;
}

struct Type<T: Trait>(pub T::A);

impl Trait for i32 {
    type A = i32;
}

fn main() {
    let x = Type::<i32>(0);
    let y = Type::from(x);
}

#3

Thank you for your swift reply. I still do not quite understand how this particular instance of From can apply here. While I understand the reflexive implementation from T to T I fail to see how it can apply to convert T::A to Type<T>.


#4

In the presence of

impl<T> From<T> for T {
    fn from(t: T) -> T { t }
}

someone could do

struct Bad;

impl Trait for Bad {
    type A = Type<Bad>;
}

making your implementation conflict with that one.


#5

I see. Thanks a lot!


#6

It seems that generic displace your task. You can use own trait with special behaviour:

use std::convert::From;

trait Trait {
    type A;
}

struct Type<T: Trait>(pub T::A);

impl Trait for i32 {
    type A = u64;
}

pub trait MyFrom<T> {
    fn my_from(T) -> Self;
}

impl<X, T: Trait<A=X>> MyFrom<X> for Type<T> {
    fn my_from(a: X) -> Type<T> {
        Type(a)
    }
}

fn main() {
    let x: Type<i32> = Type::my_from(0u64);
}

I’ll try to be curious about this conflict…


#7

Conflict isn’t complicated in this form:

impl<S, T: Trait<A=S>> From<S> for Type<T> {
    fn from(s: S) -> Self {
        Type(s)
    }
}

S can be Type. Type to Type is reflexive conversion.
Use more slender implementation.