How do I bound a trait with a supertrait that uses the trait's associated type as a parameter?

Viewed 2961

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?

Playground.

2 Answers
Related