I'm having trouble understanding how the following example, distilled from this code, compiles:
trait A: B {}
trait B {}
impl<T> B for T where T: A {}
struct Foo;
impl A for Foo {}
fn main() {}
My current understanding is that
trait A: Bdeclares a trait A with the supertrait B. The Rust reference on traits states
Supertraits are traits that are required to be implemented for a type to implement a specific trait.
impl<T> B for T where T:Aimplements B for any type with the trait A .
I expect impl A for Foo to fail because before A is implemented for Foo, the blanket implementation can't implement B for Foo, which is required.
My most plausible model for what rustc does while compiling the snippet is as follows:
- implement A for Foo, deferring the check that Foo implements B to a later stage
- implement B for Foo with the blanket implementation, since Foo now implements A
- check that Foo implements B as required by the trait bound
A: B
Is this in some way close to the truth? Is there any documentation I missed explaining the order in which implementations are processed?