I define a trait CityTask which is depending on another trait, Task: CityTask: Task. How can I use objects implementing CityTask where are expected Task ?
There is an example (where I added some things like Send, Sync, etc to be closer than my "real" code):
I've been playing around with the same idea for a few minutes now, and I'm a bit disappointed about the assembly when panic=abort isn't set :-/ (even though at least it still seems to have removed the main loop, but some destructor calls remain which will end up doing nothing)
rust subtrait is not inheritence/subtyping (so called is-a relation) of typical object-oriented languages.
in rust, a type implementing a subtrait can call methods defined in its supertraits. however, direct trait upcasting is still experimental.
to be honest, many "conventional" OOP patterns are not easy to express in rust, but I believe many of those "legacy" patterns are not needed in the first place, if your language have an advanced/sophisticated type system.
I might have had a little bit to do myself with finding an issue that motivated the revert to leave time for fixing some issues
(I wouldn't have anticipated that the whole process would delay it by over year though)
That is true. While trait upcasting is designed to be cheap if possible, as soon as you have multiple supertraits next to each other, it might no longer be a no-op in the current implementation (when the vtable pointer needs adjusting), in which case doing it behind another level of indirection (in a Vec) can't be an implicit cast.
That being said, I personally wouldn't be surprised if we got there eventually; some sort of combination of
allowing some marker on (at most) one supertrait, to allow the API to stably promise no-op convertibility to that supertrait
(or perhaps even an automatism; that's a design question around whether there are any semver-compatibility concerns)
some framework of extended subtyping&variance / or a separate system of safe transmutations, to lift such no-op-convertibility properties through containers like Vec<_>
I feel like, with Rust's standing regarding performance & safety, it seems almost certainly a desireable enough feature to make happen eventually.
It's not currently possible to upcast dyn CityTask to dyn Task, but dyn CityTask still implementsTask.
I would also generally recommend adding implementations of your traits for Box,[1] when possible; if you do this, then you can make the function simpler and even more generic, and allow it to be used without boxing and dyn when that suits the situation:
I agree with @kpreid that there is no actual need for trait upcasting in the example. Moreover, despite the naming, the transformation from dyn SubTrait to dyn SuperTrait is a coercion, not an actual type upcast -- there is no sub/supertype relation between the two dyn types. Which is why even when you have trait upcasting, you need to create a new Vec as in @nerditation's example. So (given what's been shared), I think you're better off without it.