I'm trying to implement a trait that has a supertrait, like so:
trait A {
fn do_a(&self);
}
trait B: A {
fn do_b(&self);
}
struct S {}
impl B for S {
fn do_a(&self) {}
fn do_b(&self) {}
}
When I run cargo build I get these compiler errors:
error[E0407]: method `do_a` is not a member of trait `B`
--> src/example.rs:12:5
|
12 | fn do_a(&self) {}
| ^^^^^^^^^^^^^^^^^ not a member of trait `B`
error[E0277]: the trait bound `example::S: example::A` is not satisfied
--> src/example.rs:11:6
|
5 | trait B: A {
| - required by this bound in `example::B`
...
11 | impl B for S {
| ^ the trait `example::A` is not implemented for `example::S`
I keep re-reading about supertraits, but I'm having trouble understanding this error.
trait B: A
is telling the program to do.do_a(&self) {}
satisfies A
.What am I missing here? Is my mental model wrong, or is my code missing some necessary boilerplate, or both?
I believe that the syntax is more about bounding the type (e.g. a type T
that implements B
must necessarily implement A
) than inheritance in the object-oriented sense. If you write out the impl
s separately it compiles fine:
trait A {
fn do_a(&self);
}
trait B: A {
fn do_b(&self);
}
struct S {}
impl A for S {
fn do_a(&self) {}
}
impl B for S {
fn do_b(&self) {}
}
N.B. that if you remove the impl
for A
the code no longer compiles, the constraint that an impl
of B
must also impl A
is no longer satisfied.