Associated const in traits with const generics

This is a variant on another question posted earlier. Increasingly unclear whether this is a design question, so asking separately here for someone who better understands associated const in traits with const generics.

const C0: usize = 1;

pub struct SliceVec<T, const N: usize> {
    pub len: usize,
    pub buff: [MaybeUninit<T>; N],
}

impl<T, const N: usize> SliceVec<T, N> {
     const fn max_len(&self) -> usize {
        N
    }
}

trait T<const N: usize> {
    const C: usize;
    fn f(v: &SliceVec<usize, N>) {}
}

pub struct F<const N: usize> {
    pub s: SliceVec<usize, N>,
}

impl<const N: usize> T<N> for F<N> {
    const C: usize = N * C0;
    fn f(v: &SliceVec<usize, N>) {
        let mut V: SliceVec<usize, { F::C }> = SliceVec {
            //let mut V: SliceVec<usize, {Self::C0}> = SliceVec { // generic `Self` types are currently not permitted
            len: F::C,
            buff: [MaybeUninit::new(0); F::C],
        };
     }
 }

cannot infer the value of const parameter N declared on the trait Trait

const generic paramters can't depend on associated constants from traits yet (in a generic context).

1 Like

Thanks for the response!

yet

Is there an effort to make this?

That would be the rest of const-generics :slight_smile:

Apologies, not particularly up to date. Is the best way to follow the RFC?

Yes, you can also follow associated PRs (under the const-generics tag)

min_const_generics is just the first step, and only provides the most minimal interface to get started, but it was never meant to be the final step. const-generics is just such a big feature that it makes sense to stabilize it in parts, as they get done.

1 Like

Finding this a bit difficult to follow, probably since this is the first time needing a feature not yet on nightly. How do PRs from the feature list for const_generics get to nightly? How to know when building upstream will have const generic parameters that depend on associated constants?

Digging a bit more, I found this issue, which might be more helpful

1 Like

For some reason, think this what is happening, but not understanding totally. buff has array length with generic parameter, right?

no it doesn't work either

should without C

And now your not using a associated const from a trait in a generic context (which is currently not implemented or allowed). :slight_smile:

That issue is just for arrays, though, right?

No, it's an issue with all const generic parameters, arrays used to be special cased as the only types with const generic paramters so that's why the tracking issue just says array lengths. (Note: this special casing made them near useless in a generic context, which is why const-generics is such a useful feature, but also why it's so much work to implement)

What makes buff different from an array with a const generic parameter?

Nothing, it is an array with a const generic parameter. (I think I might not be explaining something properly, am I misunderstanding what you are trying to ask?)

Do not think so, think probably I am the one not explaining properly. Thanks for the patience. In other words, if array lengths do not support const generic parameters, why does buff work when it is an array that has length that is const generic?

For all arrays [T; N], N is that array's const generic parameter, in the same way that T is it's type parameter. So all arrays have const generic parameters.

I'm assuming your talking about this.

impl<const N: usize> T<N> for F<N> {
    fn f(v: &SliceVec<usize, N>) {
        let mut V = SliceVec {
            len: 10,
            buff: [MaybeUninit::new(0); 10],
        };
     }
 }

That's what const-generics was designed to do, allow you to generalize over all arrays. But work isn't complete, so associated consts don't work just yet.

I forgot to add, in this case you are initializing SliceVec with a literal 10, so V's type is inferred to be SliceVec<i32, 10>, (it doesn't depend on N, altough it could with min_const_generics)

I'm assuming your talking about this

No, referring to definition:

pub struct SliceVec<T, const N: usize> {
    pub len: usize,
    pub buff: [MaybeUninit<T>; N],
}

Why does SliceVec work? Why can rustc not make type inference? Probably worth adding that type annotations needed occurs before cannot infer the value of const parameter N declared on the trait Trait