Computing Array Size with Const Generics

Hi everyone,

I'm playing around with const generics on nightly and am running into a weird error that I don't really understand. A minimal example would be the following:

struct Vector<T, const N: usize>([T; 2 * N]);

When compiling, I get the following error:

error: unconstrained generic constant
  --> src/lib.rs:23:34
   |
23 | struct Vector<T, const N: usize>([T; 2 * N]);
   |                                  ^^^^^^^^^^
   |
help: consider adding a `where` bound for this expression
  --> src/lib.rs:23:38
   |
23 | struct Vector<T, const N: usize>([T; 2 * N]);
   |                                      ^^^^^

I don't really know what to make of this Error. Could someone explain to me what the problem is and how to fix it?

#![feature(const_generics)]
#![feature(const_evaluatable_checked)]
#![allow(incomplete_features)]
struct Vector<T, const N: usize>([T; 2 * N])
where
    [T; 2 * N]: Sized;

Playground. The bound is necessary since 2*N may overflow. It's likely to look different whenever it makes it to the stable version.

1 Like

According to the design document, you need to "mention" some type containing 2*N in e.g. a where bound in order to be able to use it. As far as my understanding goes, intuitively this could be useful because:

  • Vector<T, N> is only a valid type whenever 2*N does not overflow
  • Having this constraint be implicit would implicitly expose the fact that the type Vector contains something using 2*N. (And lead to breaking changes more easily.)

The document also mentions the current way to make this kind of type work: adding a where bound mentioning the expression, without any constraints

#![feature(const_generics)]
#![feature(const_evaluatable_checked)]
struct Vector<T, const N: usize>([T; 2 * N])
where
    [(); 2 * N]: ;

(similar to what @quinedot just posted)

2 Likes

A recent discussion about const_evaluatable_checked on the internals forum can be found here:

Thank you to everyone, this clears up my confusion