Documentation regarding using traits for associated types

Viewed 34

I'm unclear as to why traits are usable within the RHS of the type syntax for what I recognize as an associated type. I searched through the language reference and could not find it, but am not sure if I did not find it due to lack of familiarity/understanding, or because it's as of yet undocumented.

Here is a playground with the same code.

trait ATrait {
    fn a(&self) -> f64;
}

trait BTrait {
    fn b(&self) -> f64;
}

trait Container {
    // Why can we just use 'traits'?
    type Item: ATrait + BTrait;
    fn describe_container() -> i32;
}

struct ContainerType;
impl Container for ContainerType {
    type Item = ItemType;
    fn describe_container() -> i32 {
        42
    }
}

struct ItemType;
impl ATrait for ItemType {
    fn a(&self) -> f64 {
        3.141
    }
}

impl BTrait for ItemType {
    fn b(&self) -> f64 {
        2.718
    }
}

fn main() {
    let _ct = ContainerType {};
    ContainerType::describe_container();
}
1 Answers

It appears in the reference here. Specifically, AssociatedItem refers to TypeAlias, and it includes ( : TypeParamBounds )? and mentions (at the end of the page) that:

A type alias with TypeParamBounds may only specified when used as an associated type in a trait.

These bounds mean that for every type that implement the trait, the type provided for this associated type will have to implement the mentioned traits. In your example, ItemType, specified as Container::Item for ContainerType, must implement ATrait and BTrait, or errors will be emitted:

error[E0277]: the trait bound `ItemType: BTrait` is not satisfied
  --> src/main.rs:17:17
   |
17 |     type Item = ItemType;
   |                 ^^^^^^^^ the trait `BTrait` is not implemented for `ItemType`
   |
note: required by a bound in `Container::Item`
  --> src/main.rs:11:25
   |
11 |     type Item: ATrait + BTrait;
   |                         ^^^^^^ required by this bound in `Container::Item`

error[E0277]: the trait bound `ItemType: ATrait` is not satisfied
  --> src/main.rs:17:17
   |
17 |     type Item = ItemType;
   |                 ^^^^^^^^ the trait `ATrait` is not implemented for `ItemType`
   |
note: required by a bound in `Container::Item`
  --> src/main.rs:11:16
   |
11 |     type Item: ATrait + BTrait;
   |                ^^^^^^ required by this bound in `Container::Item`
Related