Constant heterogeneous vector

Hello, rust world! Would be theoretically possible to create a constant (immutable) vector of heterogeneous types (without changes to rust's internal type system i.e. --a normal user could implement it without changing the core language itself)? I've been thinking of creating one, but wanted to know if it's even worth the effort (or if one already exists). Importantly, I want to maintain type-checking (so the compiler can validate before-hand that the type at some index must be T). On reflection, I think I've probably answered my own question...

The problem with the idea of a heterogenous vector is what the type of the indexing operation is:

impl HetVec {
    fn get(&self, index: usize) -> &??? {...}
}

What do you fill in for ???? A type cannot depend on a value (the index), so it must be some concrete type.

One possible answer is that the vector contains types that all implement a common trait, in which case the signature can be

    fn get(&self, index: usize) -> &dyn ValueTrait {...}

and the implementation of the vector can be fairly straightforward (though unsafe) code — it just needs to copy values of various sizes into one memory allocation (in the fashion of an arena allocator), while building a table of offsets or pointers to use for indexing. It'd be slightly tricky to write it generic over different traits, but I think possible (the caller must supply a closure to perform the coercion from the &MyConcreteType to &dyn ValueTrait).

Another answer, if you just want to identify the elements with numbers, is to use a tuple, which can contain any types and can be "indexed" with the tuple.123 syntax. But in this case you cannot use a run-time chosen index.

Yeah. Tuples are not ideal for what I ultimately want (although I am making do). What I would want is the return value to be whatever the type is, but the indexing operation would have to be const (deduced at compile time), similar to a tuple. As long as this constraint holds, then we can know statically what the return value should be (since the type and size of the vector cannot be mutated in any (safe) way after initialization). Since this is probably impossible to do without modifying the type system, unfortunately.

Really, I just want variadic generics :frowning: !

Have you tried HList?

1 Like