[Idea] Fully Dynamic Trait Object

I'm reading some ECMA-335 text today, which is about the design of dotnet CLI. There's something called typed reference there, which consist of static data type and the address of data, which reminds me of the trait objects in rust.

So, in rust, one way to think about the trait objects is: it's actually a more generic type constrained by const generics, taking some metadata matching a trait as the constant, and the resulting type automatically implements the trait.

And by removing the constant bound, maybe there can be a dynany type. Its relationship to dyn Trait is just like &[T] to &[T; 3]. Using a AsRef/AsMut, the Trait part of &dyn Trait can be erased, transformed into a &dynany type, and by specifying the metadata for some trait as constant generics, &dynany can TryInto some &dyn Trait.

In this idea, Box<dynany> can supply uniform storage for every value, and &dynany can supply uniform storage for shared pointers.

1 Like

Like std::any::Any


Yeah, sounds exactly like Any to me.

(Side note: its usefulness/necessity is much more limited in Rust. I have no idea about how idiomatic/widespread/useful/necessary it is on the CLR, but usually in Rust it certainly is/should be a last resort solution, unlike strongly-typed existentials.)

But Any is flawed, almost useless in its current state. You can't turn another trait object directly into &dyn Any, nor try to turn it back.

Whenever you want to use it, something like Object in https://docs.rs/query_interface/ will be more useful.

1 Like

You can turn another trait into the one you want if you use a simple extension trait.

trait ExtWithAny: FooTrait + Any {
    fn as_any(&self) -> &dyn Any;

    fn as_base(&self) -> &dyn FooTrait;

impl<T: FooTrait + Any> ExtWithAny for T {
    fn as_any(&self) -> &dyn Any { self }

    fn as_base(&self) -> &dyn FooTrait { self }

You can add other methods to this to convert between other pointer types. There's even a crate that does this for you, if only I could remember its name.

Then you use this extension trait instead of the bae trait, and everything works out.


A few related crates: