Search code examples
rusttraits

Is there any way to implement a trait with the same struct of different generic constraints in Rust?


Suppose I have a struct S<T> and I want implement it to trait Default with different constraints of generic type T:

struct S<T> { ... }


impl<T> Default for S<T> 
where
    T: Ord
{
    fn default() -> Self {
        Self::new()
    }
}

impl<T> Default for S<T>
where
    T: Ord + Default
{
    fn default() -> Self {
        Self::build(T::default())
    }
}

However, the compiler complains:

error[E0119]: conflicting implementations of trait std::default::Default for type S<_>

Is there any way to compile such code?


Solution

  • There is no way to do this in stable Rust.

    You can use the (unstable and unsound!) specialization feature on nightly Rust:

    #![feature(specialization)]
    
    struct S<T> {
        x: Option<T>
    }
    
    impl<T> S<T> {
        fn new() -> Self { Self { x: None } }
        fn build(x: T) -> Self { Self { x: Some(x) } }
    }
    
    
    impl<T> Default for S<T> 
    where
        T: Ord
    {
        default fn default() -> Self {
            Self::new()
        }
    }
    
    impl<T> Default for S<T>
    where
        T: Ord + Default
    {
        fn default() -> Self {
            Self::build(T::default())
        }
    }
    

    https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=ee24c383878f7a32c53d12211b69ab4f