2

Consider the following scenario:

  • I want to implement a trait Do on all the types that implement a trait CanDo.
  • Out of the types that CanDo, some implement a trait CanDoQuickly.
  • I would like Do to be implemented in one way for those types that CanDo, but not CanDoQuickly, and in another way for those types that CanDoQuickly.

I know that, in Rust, we have no negative trait bounds. My intuition is that we should probably be able to use opt-in built-in to achieve this (although, I did try unsuccessfully).

I am wondering if it is at all possible, no matter the complexity of the code, to achieve what I would like to do on stable Rust. If not, is it a design choice? Is it inherently bad to want to do something like this? It sounds like such a common problem to me that I'd be very surprised to find out it's a deprecated practice.

Matteo Monti
  • 8,362
  • 19
  • 68
  • 114
  • Probably dupe of https://stackoverflow.com/questions/45898130/trait-specialization – hellow May 24 '19 at 07:51
  • That question seems to address the question "why doesn't it work?", but not the question "is it possible to do such a thing?". – Matteo Monti May 24 '19 at 08:14

1 Answers1

2

It is possible on nightly with the still unstable specialization feature and a default implementation (see also the tracking issue for specialization):

#![feature(specialization)]

trait DoIt {
    fn do_it(&self);
}

impl<T> DoIt for T
where
    T: CanDo,
{
    default fn do_it(&self) {
        self.do_impl()
    }
}

impl<T> DoIt for T
where
    T: CanDoQuickly,
{
    fn do_it(&self) {
        self.do_quickly_impl()
    }
}

trait CanDo {
    fn do_impl(&self) {
        println!("slowly");
    }
}

trait CanDoQuickly: CanDo {
    fn do_quickly_impl(&self) {
        println!("quickly");
    }
}

struct S1;
impl CanDo for S1 {}
impl CanDoQuickly for S1 {}

struct S2;
impl CanDo for S2 {}

fn main() {
    S1.do_it();
    S2.do_it();
}
hellow
  • 12,430
  • 7
  • 56
  • 79
starblue
  • 55,348
  • 14
  • 97
  • 151
  • I see. Interesting! Is there an estimate on how long it could take for `specialization` to make it into stable Rust? Does your answer imply that it is impossible to do the same thing in stable Rust? – Matteo Monti May 24 '19 at 08:46
  • As for the timeline, that is what the tracking issue is for. It's more than three years old and the remaining issues don't look easy, so I wouldn't hold my breath. – starblue May 24 '19 at 11:07