I do not understand what you mean by "a lower type of the collection type".
Apart from that, you have a few errors and unnecessary complications in your code:
You want a collection of dynamically-typed elements. Why the generic argument, then? You are specifically trying to opt out of static typing, so requiring a single generic type doesn't make any sense. You should just use Box<dyn Any>.
The only thing generic here should be the insert method: that works with any static type, which it then erases by putting it behind a Box<dyn Any>.
If you have a concrete type that implements Any but is notdyn Any (the concrete type, in your case dyn MyTrait), and you try to check the type_id() of it, then it will coerce to Any and you will never get a match or a succeeding downcast, because a trait object type is a distinct type from every underlying concrete type it was created from. You will not get any matches either if you get the levels of indirection wrong (e.g. Box<T> won't downcast to T, neither will &T, etc.)
It's useless and actually harmful to return &Box<T>. It gives you no more capabilities as a plain &T, it exposes an implementation detail, and it leads to unnecessary double indirection.
Instead of explicitly comparing TypeIds, you can use Any::is::T<>() to check against a type. If you want to filter on them and downcast the eligible elements to the requested concrete type, it's even better to .downcast_ref() and then .filter_map().
Fixing these errors, and simplifying-rationalizing the code further yields the following, which works as expected:
It seems that some of the expressions were not appropriate. My apologies.
First, I meant "a lower type of the collection type" as "a subtype of the element type (MyTrait) in the collection". ...In Rust's language, is it more appropriate to say "the type that implements the trait" rather than "subtype"?
And I specified dyn MyTrait as the type parameter for MixVec because I wanted to restrict the types that insert into the MyTrait subtype more than Any (Maybe the expression "arbitrary element types" was inappropriate).
To reword my previous statement, here is what I would like to achieve.
I want to specify the base type of elements to be stored in MixVec.
I want to be able to add data of that subtype in the insert method.
I want to be able to specify only the type of the subtype in select_by_type.
PS, I had no idea about filter_map. This looks like a good shortcut!
Rust has type erasure and dynamic dispatch (via dyn Trait), but it does not have trait-based subtyping. A type that implements Trait is not a subtype of dyn Trait (except dyn Trait itself).
dyn Trait is a concrete type, even though it does dynamic dispatch and is dynamically sized (does not implement Sized).
All those downcast, downcast_ref[1] methods on dyn Any and Box<dyn Any>[2] are how you perform the downcasting. Note that those are methods directly on the concrete types dyn Any and Box<dyn Any>, and are not part of the Any trait itself.
Rust doesn't have dyn Trait upcasting to super traits yet, but it plans to. Until then you have to explicitly program it in (example below).
In the playground below I added a trait with a supertrait bound on Any. That means that everything that implements MyTrait must also implement Any, and when you know that T: MyTrait, you also know that T: Any.
The as_any method is for upcasting, as mentioned above. This allows you to get a &dyn Any to the implementing type, so you can perform downcasting using the methods on dyn Any. You could add a downcast method to the trait itself too if you wanted.
Then you can store Box<dyn MyTrait> and use T: MyTrait bounds elsewhere.
You may want to use Box<dyn MyTrait + Send + Sync> or similar instead if you plan to use threads.
and no subtyping in the classical sense. (The only kind of subtyping is related to lifetimes and variance, and it's emphatically not what you are looking for.)
Furthermore, a trait is not a type. Therefore, no type can ever be a "subtype" of a trait. A type can implement a trait. There is also dyn Trait, which is a concrete type, distinct from all other types it is created from. Still no subtyping in sight.
If you want to restrict your elements to a given trait stricter than Any, you'll have to add that bound on the insert method. There's no way in Rust (as far as I know of) to be generic over a trait. You can only be generic over a type. There's simply no way to express that a collection should restrict its items to different traits specified at generic instantiation time.
So the only overall change I can suggest to my earlier code is to extend the signature of insert:
On nightly, you can sort of emulate it by being generic over T:?Sized (representing a trait object in practice) and adding a CoerceUnsized<T> bound to insert. As far as I know, however, there are no plans to stabilize CoerceUnsized in anything like its current form.
Thanks for the useful advice.
Especially "a trait is not a type" was a shock to me.
I see, so I can't directly specify it as a type parameter....
Apparently my mind is still dominated by classes...