Trait binding propagation confusion (no loops)

Not quite sure why this isn't working.

trait A {
    type DataTypeForA;
}

trait FloatA: A<DataTypeForA = f32> {}
impl<T> FloatA for T where T: A<DataTypeForA = f32> {}

trait B {
    type DataTypeForB: A;
}

trait FloatB: B
where
    Self::DataTypeForB: FloatA,
{
}
impl<T> FloatB for T
where
    T: B,
    T::DataTypeForB: FloatA,
{
}

trait C: FloatB {}
impl<L> C for L where L: FloatB {}

fn main() {}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0271]: type mismatch resolving `<<Self as B>::DataTypeForB as A>::DataTypeForA == f32`
  --> src/main.rs:24:10
   |
24 | trait C: FloatB {}
   |          ^^^^^^ expected `f32`, found associated type
   |
   = note:         expected type `f32`
           found associated type `<<Self as B>::DataTypeForB as A>::DataTypeForA`
   = help: consider constraining the associated type `<<Self as B>::DataTypeForB as A>::DataTypeForA` to `f32`
   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
note: required for `<Self as B>::DataTypeForB` to implement `FloatA`
  --> src/main.rs:6:9
   |
6  | impl<T> FloatA for T where T: A<DataTypeForA = f32> {}
   |         ^^^^^^     ^            ------------------ unsatisfied trait bound introduced here
note: required by a bound in `FloatB`
  --> src/main.rs:14:25
   |
12 | trait FloatB: B
   |       ------ required by a bound in this trait
13 | where
14 |     Self::DataTypeForB: FloatA,
   |                         ^^^^^^ required by this bound in `FloatB`

error[E0271]: type mismatch resolving `<<L as B>::DataTypeForB as A>::DataTypeForA == f32`
  --> src/main.rs:25:26
   |
25 | impl<L> C for L where L: FloatB {}
   |                          ^^^^^^ expected `f32`, found associated type
   |
   = note:         expected type `f32`
           found associated type `<<L as B>::DataTypeForB as A>::DataTypeForA`
   = help: consider constraining the associated type `<<L as B>::DataTypeForB as A>::DataTypeForA` to `f32`
   = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
note: required for `<L as B>::DataTypeForB` to implement `FloatA`
  --> src/main.rs:6:9
   |
6  | impl<T> FloatA for T where T: A<DataTypeForA = f32> {}
   |         ^^^^^^     ^            ------------------ unsatisfied trait bound introduced here
note: required by a bound in `FloatB`
  --> src/main.rs:14:25
   |
12 | trait FloatB: B
   |       ------ required by a bound in this trait
13 | where
14 |     Self::DataTypeForB: FloatA,
   |                         ^^^^^^ required by this bound in `FloatB`

For more information about this error, try `rustc --explain E0271`.
error: could not compile `playground` (bin "playground") due to 2 previous errors

This bound won't implicitly apply elsewhere.

trait FloatB: B
where
    Self::DataTypeForB: FloatA,

If you add it to both trait C and the impl, it compiles.

There may be another way by threading the associated types (with stricter bounds) through the trait heirarchy.

Like so. Now the bound is part of a supertrait bound and is implied everywhere FloatB is used.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.