Passing trait-associated constant as const-generic parameter

Playground link

pub trait State
{
    const LEN: usize;
}

#[derive(Debug)]
pub struct Vector<const N: usize>{
    inner: [u32; N]
}
impl<const N:usize> Vector<N> {
    pub fn zeros() -> Self {
        Self {
            inner: [0; N]
        }
    }
}

pub struct MyState;
impl State for MyState {
    const LEN: usize = 4;
}

pub fn foobar<T: State>(_s: T)
{
    // let u1 = Vector::< { <T as State>::LEN } >::zeros();
    // println!("{:?}", u1);
    let u2 = Vector::< <T as State>::LEN >::zeros();
    println!("{:?}", u2);
}

pub fn main()
{
    let st = MyState;
    foobar(st);
}

Hopefully the code above makes it clear what I am trying to do. What I expected was for foobar() to create a Vector struct containing an array of length 4 and print it. But it fails to compile.

The error message unhelpfully suggests surrounding the parameter to Vector in curly braces. On doing that, I instead get an error saying generic parameters may not be used in const operations.

Is this something that is not currently possible? Is there an RFC or issue tracking this?

Thanks.

Turns out that this is possible in nightly. Here's the working version in case anyone is interested:

#![feature(const_generics)]
#![feature(const_evaluatable_checked)]

pub trait State
{
    const LEN: usize;
}

#[derive(Debug)]
pub struct Vector<const N: usize>{
    inner: [u32; N]
}
impl<const N:usize> Vector<N> {
    pub fn zeros() -> Self {
        Self {
            inner: [0; N]
        }
    }
}

pub struct MyState;
impl State for MyState {
    const LEN: usize = 4;
}

pub fn foobar<T: State>(_s: T) where [(); { <T as State>::LEN }]:
{
    let u1 = Vector::< { <T as State>::LEN } >::zeros();
    println!("{:?}", u1);
}

pub fn main()
{
    let st = MyState;
    foobar(st);
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.