Search code examples
rust

Rust into implementation conflict core


I have a Result like enum:

enum Choice<A, B> {
    A(A),
    B(B),
} 

I wanted this type to implement Into if both generics are T.
Attempt 1:

impl<T> Into<T> for Choice<T, T> {
    fn into(self) -> T {
        let (Choice::A(x) | Choice::B(x)) = self;
        x
    }
}

Gets me:

conflicting implementation in crate `core`:
            - impl<T, U> Into<U> for T
              where U: From<T>;

Attempt 2:

impl<T> From<Choice<T, T>> for T {
    fn from(x: Choice<T, T>) -> Self {
        let (Choice::A(x) | Choice::B(x)) = x;
        x
    }
}

Gets me:

implementing a foreign trait is only possible if at least one of the types  
for which it is implemented is local, and no uncovered type parameters  
appear before that first local type

Edit: i understand both these errors i am just trying to find out if there is another way to get Into implemented.


Solution

  • Edit: i understand both these errors i am just trying to find out if there is another way to get Into implemented.

    No, you can't. This might change in the future. The only working scenario is to use types where the compiler knows that From<Choice<..>> is not implemented. This would work:

    impl Into<i32> for Choice<i32, i32> {
        fn into(self) -> i32 { todo!() }
    }
    

    Here, i32 does not implement From<Choice<..>>. Using any other type that implements From (or could implement, like generic types) results in a conflict with the blanket implementation by std::core.

    The following, non-generic implementation for Into, fails to compile for the same reason:

    struct Other;
    
    impl<T> From<Choice<T, T>> for Other {
        fn from(_value: Choice<T, T>) -> Self { todo!() }
    }
    
    impl Into<Other> for Choice<Other, Other> {
        fn into(self) -> Other { todo!() }
    }