I have a trait Trait
with an associated type Trait::Associated
. I am trying to bound the trait by requiring that it be indexable by its associated type, as shown here:
use std::ops::Index;
pub trait Trait: Index<Trait::Associated> {
type Associated;
}
However, the compiler complains that the associated type is ambiguous
error[E0223]: ambiguous associated type --> src/main.rs:3:24 | 3 | pub trait Trait: Index<Trait::Associated> { | ^^^^^^^^^^^^^^^^^ ambiguous associated type | = note: specify the type using the syntax `<Type as Trait>::Associated`
I also tried referring to the associated type as Self::Associated
, but then the compiler protests about a cyclic reference between the type and the trait:
error[E0391]: cyclic dependency detected --> src/main.rs:3:1 | 3 | pub trait Trait: Index<Self::Associated> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cyclic reference | note: the cycle begins when computing the supertraits of `Trait`... --> src/main.rs:3:1 | 3 | pub trait Trait: Index<Self::Associated> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: ...which then again requires computing the supertraits of `Trait`, completing the cycle.
Finally, I also tried explicitly implementing Index
for Trait
:
pub trait Trait {
type Associated;
}
impl<T: Trait> Index<T::Associated> for T {
type Output = str;
fn index(&self, associated: T::Associated) -> &'static str {
"sup"
}
}
Unfortunately that fails too:
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g. `MyStruct<T>`) --> src/main.rs:7:1 | 7 | impl<T: Trait> Index<T::Associated> for T { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type | = note: only traits defined in the current crate can be implemented for a type parameter
Am I trying to do something unreasonable here? Is there a way of achieving something similar, without having to use generics?
I think the following provides the semantics you want, taking the approach of your second attempt.
You are close, very close.
The
Trait
does not assume that any reference toTrait
in its definition refers to the current type. After all, you could wish to refer to other types also implementingTrait
.In order to specify that you want a specific type, you should heed the compilers note: use
<Type as Trait>::Associated
, whereType
is the current type.When defining the
Trait
, how do you refer to the concrete type for which it will be instantiated? You useSelf
!The solution is: