Search code examples
rusttraits

Can a trait give default implementation for *some* methods of a parent trait?


Suppose we have a basic trait and an advanced trait as follows:

pub trait BasicTrait {
    fn key_method(&self);


    fn other_method(&self);
}

pub trait AdvancedTrait: BasicTrait {
    fn key_method_with_argument(&self, parameter: u32);
}

Now, every time someone will implement AdvancedTrait, the most likely implementation of BasicTrait::key_method(&self) is calling key_method_with_argument with some default argument. How can I provide this default implementation (idiomatically) so that anyone implementing AdvancedTrait will (1) only need to implement key_method_with_argument and any other required methods from BasicTrait, and (2) optionally implement key_method() and override the default implementation, only if needed?

Related questions:

having an impl block as proposed in the answer here does not work since the code is expected to implement all other methods of BasicTrait.


Solution

  • The feature you want is called specialization, and unfortunately it is nightly-only and has known soundness holes, so don't expect it to stabilize soon. However, here's how it looks like with it:

    #![feature(specialization)]
    
    pub trait BasicTrait {
        fn key_method(&self);
    
        fn other_method(&self);
    }
    
    pub trait AdvancedTrait: BasicTrait {
        fn key_method_with_argument(&self, parameter: u32);
    }
    
    default impl<T: AdvancedTrait> BasicTrait for T {
        default fn key_method(&self) {
            self.key_method_with_argument(12345);
        }
    }
    

    Playground.