Hi,
I have trouble understanding why this won't compile (playground link):
trait TestingA {
type Error;
}
trait ErrorA {}
trait TestingB: TestingA
where
Self::Error: ErrorA
{}
fn testinga<T: TestingB>(){}
It leads to the following error:
Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `<T as TestingA>::Error: ErrorA` is not satisfied
--> src/lib.rs:12:16
|
12 | fn testinga<T: TestingB>(){}
| ^^^^^^^^ the trait `ErrorA` is not implemented for `<T as TestingA>::Error`
|
note: required by a bound in `TestingB`
--> src/lib.rs:9:18
|
7 | trait TestingB: TestingA
| -------- required by a bound in this trait
8 | where
9 | Self::Error: ErrorA
| ^^^^^^ required by this bound in `TestingB`
help: consider further restricting the associated type
|
12 | fn testinga<T: TestingB>() where <T as TestingA>::Error: ErrorA{}
| ++++++++++++++++++++++++++++++++++++
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (lib) due to previous error
The compiler suggestion does fix the issue, but I do not understand why this doesn't compile.
The TestingB
definition requires the Self::Error: ErrorA
bound, so I don't understand why T: TestingB
does not automatically imply that T::Error: ErrorA
. Am I misunderstanding how where
clauses work on trait definitions?
In my case it's a significant issue because TestingB
is actually a supper trait of 3 traits, so it would mean having 4 bounds everywhere, which is really verbose (and the purpose of TestingB
is actually to have a single trait bound rather than 4, it does not define any actual behavior).
I was able to fix the issue by refactoring a bit (playground link), but I'm still confused by the initial error:
trait TestingA {
type Error;
}
trait ErrorA {}
trait TestingB: TestingA<Error = <Self as TestingB>::Error>
{
type Error: ErrorA;
}
fn testinga<T: TestingB>(){}