Summary

Implement generics over integers, similar to integer templates in C++ ( template<int n> ). The point of this RFC is to just implement the bare essentials underneath a feature flag, and then flesh out the design with further RFCs.

Motivation

Algebraic Types: Matrices, Vectors, would all benefit from compile time integer generics. Matrix<2, 2> + Matrix<3, 3> doesn’t make any sense, and it’d be great to have a compile time error for that.

Compile Time Sizes: Like the StackVec example below; we have examples, mostly using typenum, but that’s a hack of the typesystem. It would be really nice to be able to write these without resorting to these kinds of crates.

Arrays: Our arrays are kind of terrible, this would make them slightly better. impl ing Clone for all arrays where T: Clone will fix an annoying ICE as well.

ing Clone for all arrays where will fix an annoying ICE as well. Physical Units: Saying that a kilometer is, at compile time, 1000 meters is a nice bonus.

Detailed Design

Basic Syntax

This utilizes the syntax of generics. It’s fairly simple.

fn adder<const n: u32>(m: u32) -> u32 { n + m } // There are better ways to implement this, but it's an example struct StackVec<T, const n: usize> where T: Default{ store: [T; n], len: usize, } impl<T, const n: usize> StackVec<T, const n> where T: Default { pub fn new() -> StackVec<T, n> { StackVec { store: [Default::default(); n], len: 0, } } }

which will be called as

println!("{}", adder::<const 4>(5)) // '9' // or let v = StackVec::<_, const 16>::new();

however, if you have a type

struct Wrapper<const n: usize>(pub [u8; n]);

then Rust will be able to unify the following

let w = Wrapper([u8; 15]);

to be a Wrapper<const 15> .

Ordering

The ordering of generic arguments shall be lifetime, type, constants.

struct BorrowedArray<'a, T, const n: usize>(&'a [T; n]);

Allowed Types

At first, we shall allow integer types of any size. This will likely be implemented in the compiler as a u64 for any constant. However, if there is demand later, we will be able to expand this system to full dependent types. This RFC does not cover that scope.

Where Clauses

Where clauses are not implemented by this RFC. If they are felt necessary, they can be added later, backwards compatibly.

Drawbacks

More complexity

Alternatives

We see alternatives like typenum. These are ingenious, but an unfortunate and ugly outcropping of us not having a necessary feature.

Unresolved Questions

Should we allow integers of any size? Or perhaps we should do like C++ does, and only have usize.

Should we only write const once per generic list? It gets annoying after a while to keep writing the same word over, and over.