Java Machine
Java Machine

Reputation: 83

Is it possible to use functions on Rust's constant generics

So say I'm writing a wrapper type for the array.

struct Array<const L: usize, T> {
    raw: [T;L]
}

And I have some function that mutates the length of the array wrapper, say the function is concatenation:

impl<const L: usize, T> Array<L, T> {
    fn concat<const L2: usize>(self, other: Array<L, T>) -> Array<{L + L2}, T> {todo!();}
}

When I try to compile this code, the rust compiler gets extremely mad. Thinking it might have something to do with adding types corresponding to implementing multiple, traits, i tried multiplication instead of addition, which also didn't work.

I know that rust can evaluate some expressions at compile time, is this just a case where that isn't allowed, or am I missing something?

Upvotes: 0

Views: 1921

Answers (1)

Masklinn
Masklinn

Reputation: 42207

When I try to compile this code, the rust compiler gets extremely mad. […] I know that rust can evaluate some expressions at compile time, is this just a case where that isn't allowed, or am I missing something?

You say that the compiler gets mad at you, but have you considered listening at what it was telling you?

Plugging your code into the playground, the first error is a trivial showstopper of

error: type parameters must be declared prior to const parameters
 --> src/lib.rs:1:30
  |
1 | struct Array<const L: usize, T> {
  |             -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const L: usize>

so it kind-of doesn't seem to because that's trivial to fix.

Now fixing that we get to the meat of the issue:

  = help: const parameters may only be used as standalone arguments, i.e. `L`
  = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions

that seems to explain the entirety of the thing: what's currently enabled in Rust is the

Const generics MVP

MVP as in minimum viable products aka the smallest featureset which can be useful, and what that translates to is explained in the introductory blog post.

The first limitation is

Only integral types are permitted for const generics

which is fine here because you're using integral types, but the second limitation is

No complex generic expressions in const arguments

What is a complex generic expression? Anything outside of:

  • A standalone const parameter.
  • A literal (i.e. an integer, bool, or character).
  • A concrete constant expression (enclosed by {}), involving no generic parameters.

What you're trying to do does not work (outside of nightly with both const_generics and const_evaluatable_checked enabled) because you're writing constant expressions involving at least one generic parameter, which is not part of the MVP.

Upvotes: 7

Related Questions