I am trying to implement a trait with an associate type. This trait tries to implement a function that manipulates iterators over that type. However it fails to compile with the error "std::iter::Iterator<Item=<Self as StateMachine>::Item> does not have a constant size known at compile-time". I have tried different ways to no avail.
Here is the code (with some commented alternatives) of the trait:
Sized is a default bound for generic types in most positions. Most notably, it’s not the default for the trait itself (but you’re holding it behind a reference in the ReplacerIt anyway).
You don’t need to specify the generic types of ReplacerIt when you return it in replace_all.
Be a bit more liberal with whitespace when declaring generic types and their bounds
Right. I filled the traits with Sized aiming to remove those unknown size errors. Now I see that the only necessary 'Sized' is the 'where Self:Sized' on replace_all, which I am not even sure what it means. I guess that replace_all can only be called from a StateMachine of specific size.
Now that it compiles I can more calmly do aesthetic improvements like you suggest.
It depends. One can argue that accepting ?Sized makes your types more flexible (ie they can work with more types). Whether the flexibility is actually useful depends on the intended use cases.
In this case, you may actually want to keep Self: Sized requirement on replace_all if you intend to make StateMachine trait objects. There are certain rules (restrictions) on a trait to make it eligible for trait object formation (aka object safety), and one of them is no generic methods . Putting a where Self: Sized bound on that method “removes” the method from the trait object interface (ie it’s not callable on a trait object) and makes the trait object safe (assuming other requirements are met). You can take a look at Object Safety | Huon on the internet to explore object safety in more depth.
No problem. I forgot to mention that the canonical example of slapping where Self: Sized bounds on trait methods to allow the rest of the trait to be an object is exemplified by std's Iterator trait.