Saxpy
Saxpy

Reputation: 139

Constrain trait by const generic expression in Rust

I am trying to get a better understanding of const generic expressions and I have not been able run the following

trait Foo<const N: usize> {}

impl<const N: usize> Foo<{ N * N }> for () {}

because

the const parameter N is not constrained by the impl trait, self type, or predicates

I have also tried calculating the square root compile time, but


trait Bar<const N: usize> {
    fn bar();
}

impl<const N: usize> Bar<N> for () {
    fn bar() {
        const L: i32 = 1 << N.ilog2();
    }
}

but am running into an issue on N

can't use generic parameters from outer function

I'm not understanding why the first example is failing to compile as Foo is bound by N*N which should resolve to a number.

Upvotes: 1

Views: 919

Answers (1)

cafce25
cafce25

Reputation: 27567

First of all expressions in const generic places are only allowed with a nightly compiler and #![feature(generic_const_exprs)] enabled, but even with that it still won't quite compile.

It's quite likely that generics which only appear in expressions will never be considered constrained because with arbitrary expressions the imposed constraints might be impossible or very hard to calculate.

The expanded explanation for E0207 isn't that helpful for this concrete example etiher cause it doesn't talk about expressions at all.

You can still sort of implement something like that by simply passing a second const generic as a dummy which directly receives the generic of the impl:

#![feature(generic_const_exprs)]
trait Bar<const N: usize, const M: usize> {
}

impl<const N: usize> Bar<N, {N*N}> for () {}

// just for demonstration purposes
fn print_bars<const N: usize, const M: usize>(_: impl Bar<N, M>) {
    println!("{N} {M}");
}

fn main() {
    print_bars::<2, 4>(());
    // print_bars::<2, 2>(()); // does not compile cause obviously this is not implemented by the above
}

Upvotes: 2

Related Questions