I would like to define a struct like this, but the compiler yields an error:
#![feature(generic_const_exprs)]
struct ArInt<const W: usize, const S: bool> {
iarr: [i32; { (W + 31 + (!S) as usize) / 32 }],
}
error: unconstrained generic constant
--> src/lib.rs:4:11
|
4 | iarr: [i32; { (W + 31 + (!S) as usize) / 32 }],
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: try adding a `where` bound using this expression: `where [(); { (W + 31 + (!S) as usize) / 32 }]:`
I made the following modification as per the compiler's suggestion and it works:
#![feature(generic_const_exprs)]
struct ArInt<const W: usize, const S: bool>
where
[(); { (W + 31 + (!S) as usize) / 32 }]:
{
iarr: [i32; { (W + 31 + (!S) as usize) / 32 }],
}
Can someone explain the where
clause's constraint meaning here? It looks weird.
In this context where [(); {(W + 31 + (!S) as usize)/32}]:
means more or less: "where [(); {(W + 31 + (!S) as usize)/32}]
is a possible type". This makes the allowed values clear from the get go. For example you can't do this:
let f: ArInt<usize::MAX, true>;
because usize::MAX + 31
would overflow. The where
clause makes that constraint visible without you needing to go through the implementation details to see it.