What is the most idiomatic/best way to abstract over many optional and independent capabilities of types via traits?

Thanks for your input!

Reading your text, I noticed that the main problem really seems to be whether methods like add_foo should be considered additional behavior or behavior that is implicitly part of "offering "foo" and Mut". You make a point that it's probably best to see it as additional behavior that should live in its own trait.

Again, I'm not sure if what you describe is "too restrictive". Maybe it's what I want.

I guess that this underlying question of whether add_foo is additional or a part of Foo + Mut cannot be answered for such a dummy example, but might be different for each actual real world use case. For this purpose, I have another example, which is still simplified but matches the semantics of my real code a lot better:

Not so dummy example

Again, we have a List base trait and the capability Mut. Thinking about doubly linked vs singly linked lists, let's have a second capability called Backwards, which means that the list can be traversed backwards. To refer to elements in the list, say we have this opaque type Handle (often also called cursor) which can be set by the list implementation (this would be a wrapper around a pointer to one list node). This all in code:

trait List {
    type Value;
    type Handle;
    fn first_element(&self) -> Option<Self::Handle>;
    fn next_element(&self, h: Self::Handle) -> Option<Self::Handle>;
    fn value_of(&self, h: Self::Handle) -> &Self::Value;
}

We also have the following methods, which are shown here with the "One trait per combination of capabilities" solution:

trait ListMut: List {
    fn insert_after(&mut self, h: Self::Handle, value: Self::Value);
}

trait BackwardsList: List {
    fn previous_element(&self, h: Self::Handle) -> Option<Self::Handle>;
}

trait BackwardsListMut: ListMut + BackwardsList {
    fn insert_before(&mut self, h: Self::Handle, value: Self::Value);
}

Let's ask the question again: should insert_before be in a separate trait because we think of it as additional capability? Or is it more natural to require insert_before to be implemented if BackwardsList and ListMut are also implemented?

In this particular example, I would say the latter: from a users perspective, there is no reason not to be able to call insert_before if you already know that ListMut and BackwardsList are implemented. It seems like a necessary consequence to me. What do you think?