Reputation: 922
I am in the process of writing a trait with two associated constants: the first is a usize
, and the other is an array of usize
where with a length equal to the first constant. Essentially, my trait is equivalent to the following:
#![feature(const_trait_impl)]
#![feature(generic_const_exprs)]
trait Foo {
const SIZE: usize;
const ARR: [usize; Self::SIZE];
}
struct S;
impl const Foo for S {
const SIZE: usize = 2;
const ARR: [usize; Self::SIZE] = [1, 2];
}
fn main() {
const TEST: &[usize; 2] = &S::ARR;
println!("{:?}", TEST);
}
As of the current nightly build, this trait definition produces the following error:
error: unconstrained generic constant
--> src\main.rs:6:5
|
6 | const ARR: [usize; Self::SIZE];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); Self::SIZE]:`
Unfortunately, the suggested fix is not useful because any where
bound involving Self::SIZE
would be infinitely recursive. I was ready to give up until I discovered an alternative that seems to work:
#![feature(const_trait_impl)]
#![feature(generic_const_exprs)]
trait Bar {
const SIZE: usize;
fn arr() -> [usize; Self::SIZE];
}
struct S;
impl const Bar for S {
const SIZE: usize = 2;
fn arr() -> [usize; Self::SIZE] {
[1,2]
}
}
fn main() {
const TEST: &[usize; 2] = &S::arr();
println!("{:?}", TEST);
}
I am rather perplexed by this discrepancy, all things considered. Is there any way around it, or is it mostly just a matter of waiting for const
language support to improve?
Upvotes: 6
Views: 565
Reputation: 191
You can do as follows
trait Foo<const N : usize>{
const ARR : [usize; N];
}
struct S;
impl Foo<2> for S{
const ARR : [usize; 2] = [1, 2];
}
impl Foo<3> for S{
const ARR : [usize; 3] = [1, 2, 3];
}
fn main(){
const TEST : &[usize; 2] = &S::ARR;
println!("{:?}", TEST); // [1, 2]
const TEST2 : &[usize; 3] = &S::ARR;
println!("{:?}", TEST2); // [1, 2, 3]
}
Upvotes: 1