Disambiguating associated types from super traits in a trait object
vitalyd opened this issue · 7 comments
Suppose you have a trait:
trait Foo: std::ops::Index<usize> + std::ops::Index<isize> {}
How do you declare a Foo
trait object, say a Box
? The Output
associated types need to be specified but they need to be disambiguated between the two super traits. Projections that I’ve tried don’t seem to work but it’s possible I didn’t try the right incarnation.
This stems from the https://users.rust-lang.org/t/how-to-specify-associated-types-with-same-name-in-generics/15677 post.
The trait system is pretty broken on all fronts. I hope it gets overhauled completely when HKT comes along.
Triage: I'm not aware of a way to do this.
Repro from a duplicate issue:
trait Foo {
type Error;
}
trait Bar {
type Error;
}
trait Cake : Foo + Bar {}
struct S {
f: Box<Cake<Error = i32>>,
}
fn main() {}
There's a similar disambiguation problem here:
trait A {
type C;
}
trait B: A {
type C;
}
struct S(Box<dyn B<C=()>>);
though this is less of an issue because it's unlikely B
would be defined this way in practice.
It's possible to work around this by defining an intermediate trait (thanks @estebank):
trait Foo {
type Error;
}
trait Bar {
type Error;
}
trait Cake : Foo + Bar {}
trait Cake2 : Cake where Self : Foo<Error = i32>, Self : Bar<Error = u64> {}
struct S {
f: Box<dyn Cake2>,
}
Here's a somewhat complete example of how the above could work (without having to add implementations for Cake2
for every relevant type):
impl<T> Cake2 for T where T: Cake + Foo<Error = i32> + Bar<Error = u64> {}