trait List /* supertypeclass */
{
type Next: List;
}
trait ListExtend: List
where
<Self as List>::Next: ListExtend
{}
when you run cargo check, it returns 148 and says
Checking tc_inheritance v0.1.0 (/home/rust/tc_inheritance)
error[E0277]: the trait bound `<<Self as List>::Next as List>::Next: ListExtend` is not satisfied
--> src/lib.rs:15:25
|
15 | <Self as List>::Next: ListExtend {}
| ^^^^^^^^^^ the trait `ListExtend` is not implemented for `<<Self as List>::Next as List>::Next`
|
note: required by a bound in `ListExtend`
--> src/lib.rs:15:25
|
12 | pub trait ListExtend
| ---------- required by a bound in this trait
...
15 | <Self as List>::Next: ListExtend {}
| ^^^^^^^^^^ required by this bound in `ListExtend`
help: consider further restricting the associated type
|
15 | <Self as List>::Next: ListExtend, <<Self as List>::Next as List>::Next: ListExtend {}
| ++++++++++++++++++++++++++++++++++++++++++++++++++
For more information about this error, try `rustc --explain E0277`.
error: could not compile `tc_inheritance` (lib) due to 1 previous error
rustc somehow wants to show<Self as List>::Next: ListExtend, but isn't that a premise?
Well, if I modify your code to use a supertrait bound:
trait List {
type Next: List;
}
trait ListExtend: List<Next: ListExtend> {}
then I get this error:
error[E0391]: cycle detected when computing the implied predicates of `ListExtend`
--> src/lib.rs:4:30
|
4 | trait ListExtend: List<Next: ListExtend> {}
| ^^^^^^^^^^
|
= note: ...which immediately requires computing the implied predicates of `ListExtend` again
note: cycle used when computing normalized predicates of `ListExtend`
--> src/lib.rs:4:1
|
4 | trait ListExtend: List<Next: ListExtend> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
So, this definitely isn't due to lack of elaboration because elaboration wouldn’t work either. I’m not familiar enough with type-level-list or induction shenanigans to say whether there's a way to have the original definition accepted.
I guess I'll also note that in the above workaround, it becomes a breaking change to remove the ListExtend bound from the associated type (which I'm guessing you're fine with, but FYI).