How do you implement a trait for T where T: Foo OR Bar
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?
Solution 1:
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.