There is an MVP of const generics which has a solid implementation and a strong consensus on its design. We've been using it in std for over a year. We should stabilize it.
- The first step would be for us to define the specific boundaries of that subset, which this thread aims to do.
- The second step would be to create a new
min_const_generics
which enables only this subset of const generics. - The third step would be to document, test and stabilize that feature.
I've attempted to summarize the subset here, @eddyb, @varkor, @oli-obk and @lcnr should review it to see if they agree that this is the correct subset.
What types can be const generics
This subset would include a const parameter of any type which has structural equality. This includes all of the primitive types except for floats and any type made of structurally equal fields that have the structural equality attribute (in practice on stable this means types which derive Eq and PartialEq). Types with open type parameters would not be a valid type for a const generic (so no Foo<T, const X: T>
).
EDIT: Due to this issue, this may need to be restricted to just integral primitive types (ie the int types, bool, and char). Other types would probably be a nearer term addition beyond the MVP. https://github.com/rust-lang/compiler-team/issues/323
What expressions can be used in const generic position
Const parameters can be allowed as identity expressions. Otherwise, const generics can have any concrete expression that isn't based on open type or const parameters. That is, you can have [T; N]
, [T; 0]
, or [T; size_of::<u32>()]
, but you cannot have [T; T::ASSOC_CONST]
or [T; size_of::<U>()
or [T; N * 2]
. In other words, no computation based on open type or const parameters is permitted.
This is limiting, and prevents a lot of cool CTFE tricks that people like to do with const parameters, but it still covers a huge range of use cases. The most important is that it allows implementing traits for all arrays for most use cases (as long as all the arrays in the trait body are the same size, basically). This will make arrays a lot easier to use, as traits will be implemented for arrays larger than 32, and without requiring any macro magic either.
Where const generics can be used
This I'm less clear about. In the associated zulip chat, @lcnr mentioned "no where bounds," but I'm not sure exactly what they meant by this. Would we need to not allow using const parameters in where clauses? Is there any other position in which we could not allow const parameters to be used?