FixedSizeArray as proper array generalization


#1

I have a pretty stupid idea. Why not add associated constant named Size to FixedSizeArray trait? This way trait will be able to fully represent arrays of any size at compile time. And no hacks or additions to type system. And all the implementations like impl Foo for Foo<[T; N]> can be replaced with just impl Foo for Foo<FixedSizeArray>, where all the impl functions will be able to depend on Self::Size.


#2

FixedSizeArray is going to be removed soon: https://github.com/rust-lang/rust/issues/27778

You could send a PR to arrayvec’s array trait. But it would need to be under a cargo feature so that arrayvec still works under stable.


#3

My main idea was to allow genericity over array size. Compiler was the one responsible to generate impls of FixedSizeArray with specific Size. Though, as I see, associated consts are still not here.

Arrayvec is heap-allocated as I understand. I was mainly speaking about fixed-size arrays, which are one of few ‘magic’ types in Rust.

I’m mostly against non-type generic parameters, as this might push Rust into C++ template hell.

Anyway, thanks for info.


#4

associated constants can be (ab)used as value-generics if they get a few more bugs fixed.

The trait doesn’t care about the implementation. And as you can see here, it’s implemented for arrays of fixed size. Adding the associated constant here would be trivial.

The compiler didn’t generate the impls, the standard library implemented them manually for arrays up to 32 elements. It would be wonderful if the compiler generated arbitrary impls, or if we had value generics do do so in library code.


#5

An ArrayVec is one contiguous value just like a [i32; 5] is — it lives on the heap or the stack, depending on where the programmer stores it. ArrayVec<A> is just a wrapper around a fixed size array A and a length field.

For example, you could call a Vec<ArrayVec<[i32; 5]>> or Box<ArrayVec<[i32; 1024]>> heap allocated — the actual data lives in the heap. While the data in xs does not touch the heap: let xs = ArrayVec::<[i32; 5]>::new().