Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using generic parameters in const operations [duplicate]

Tags:

generics

rust

I'm trying to generalize some algebraic operations in Rust (like for groups, rings, fields, etc), and I ran into this problem trying to implement the cross product of two "sets" (Vec's).

(Note that this is using const_generics in the nightly toolchain.)

fn CrossProduct<T, const N: usize, const M: usize>(lhs: Vec<[T;N]>, rhs: Vec<[T;M]>) -> Vec<[T;N+M]> {
    let mut out: Vec<[T;N+M]> = Vec::with_capacity(lhs.len() * rhs.len());

    for i in 0..lhs.len() {
        for j in 0..rhs.len() {
            let mut inner: [T; N+M] = [lhs[i][0]; N+M];
            for idx in 1..N {
                inner[idx] = lhs[i][idx];
            }
            for idx in 0..M {
                inner[idx + N] = rhs[j][idx];
            }
            out.push(inner);
        }
    }
    out
}

Wherever I have the expression [T;N+M], I get an error that says constant expression depends on a generic parameter, which makes no sense.

like image 741
rmcwhorter99 Avatar asked Jan 23 '26 16:01

rmcwhorter99


1 Answers

Your code does actually compile on the latest nightly, all you need is a couple of feature flags.

#![feature(const_generics)]
#![feature(const_evaluatable_checked)]
fn CrossProduct<T: Copy, const N: usize, const M: usize>(lhs: Vec<[T;N]>, rhs: Vec<[T;M]>) -> Vec<[T;N+M]> {
    let mut out: Vec<[T;N+M]> = Vec::with_capacity(lhs.len() * rhs.len());

    for i in 0..lhs.len() {
        for j in 0..rhs.len() {
            let mut inner: [T; N+M] = [lhs[i][0]; N+M];
            for idx in 1..N {
                inner[idx] = lhs[i][idx];
            }
            for idx in 0..M {
                inner[idx + N] = rhs[j][idx];
            }
            out.push(inner);
        }
    }
    out
}

fn main() {
    let a = vec![[1i32,2,3],[1,2,3],[1,2,3]];
    let b = vec![[1,2,3],[1,2,3],[1,2,3]];
    println!("{:?}", CrossProduct(a, b));
}

And when trying to compile with just #![feature(min_const_generics)], compiler actually recommends this solution:

error: generic parameters may not be used in const operations
 --> src/main.rs:2:102
  |
2 | fn CrossProduct<T: Copy, const N: usize, const M: usize>(lhs: Vec<[T;N]>, rhs: Vec<[T;M]>) -> Vec<[T;N+M]> {
  |                                                                                                      ^ cannot perform const operation using `N`
  |
  = help: const parameters may only be used as standalone arguments, i.e. `N`
  = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions
like image 173
Ivan C Avatar answered Jan 26 '26 08:01

Ivan C



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!