5

In rust, you can automatically implement a trait for any type that implements some other combination of traits. Ie:

impl<T: Foo + Bar> SomeTrait for T {
    some_function(&self) {
        /*...*/
    }
}

What I'm trying to do is define a relationship where Foo and Bar are both enough to implement SomeTrait by themselves. Basically, something like this:

impl<T: Foo> SomeTrait for T {
    some_function(&self) {
        /*...*/
    }
}

impl<T: Bar> SomeTrait for T {
    some_function(&self) {
        /*...*/
    }
}

This won't compile, because you're implementing SomeTrait for T twice and the compiler can't possibly know what to do in the case where T: Foo + Bar, but it'd be really nice to be able to do this.

Is there some way to "abstract" around this problem so that I can call some_function() on a T that implements Foo OR Bar? Or am I stuck with having to pick only one implementation?

nebulaeandstars
  • 229
  • 1
  • 8

2 Answers2

3

If you use nightly, you can use the marker_trait_attr feature. It allows you to have overlapping impls for a trait that has the attribute #[marker]. Note that the trait should have no associated items - it must be empty.

Thus, you can define a marker trait FooOrBar (I made it in a private module so it's sealed and people cannot implement it manually):

#![feature(marker_trait_attr)]

mod private {
    #[marker]
    pub trait FooOrBar {}
    impl<T: super::Foo> FooOrBar for T {}
    impl<T: super::Bar> FooOrBar for T {}
}

And then implement the trait SomeTrait for any type that implements FooOrBar:

impl<T: private::FooOrBar> SomeTrait for T {
    fn foo(&self) { /* ... */ }
}

Playground.

For stable, unfortunately, I don't think there is a way but a redesign.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
0

Turns out that there are some safety properties that need some serious thought before this can be a feature.

The only real way to get close to what I was after is using the specialisation feature, which is unstable for a number of reasons that are a bit beyond me.

Unfortunately, this does seem to mean that traits aren't quite as powerful as I originally thought, but there should always be other ways to approach this kind of scenario.

nebulaeandstars
  • 229
  • 1
  • 8