Reputation: 139
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
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