-
-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
const_assert is not compatible with const generics #40
Comments
Hi, has any one found a way around this issue? |
It seems to be possible in a limited form, using a combination of const generics and associated constants. Playground link. EDIT: I made a crude macro. |
Nice! |
Any update on this issue? The primary reason I found and tried The work-around seems like a completely different approach, correct? Is there a crate for the work-around? |
I think there is a tiny error in it. It should be: ($($list:ident : $ty:ty),* => $expr:expr) => {{
- struct Assert<$(const $list: usize,)*>;
+ struct Assert<$(const $list: $ty,)*>;
impl<$(const $list: $ty,)*> Assert<$($list,)*> {
const OK: u8 = 0 - !($expr) as u8;
}
Assert::<$($list,)*>::OK
}}; Moreover, it's (meanwhile?) possible to use impl<$(const $list: $ty,)*> Assert<$($list,)*> {
- const OK: u8 = 0 - !($expr) as u8;
+ const OK: () = assert!($expr);
}
Assert::<$($list,)*>::OK
}};
($expr:expr) => {
- const OK: u8 = 0 - !($expr) as u8;
+ const OK: () = assert!($expr);
}; And I think the scope of the second - ($expr:expr) => {
+ ($expr:expr) => {{
const OK: () = assert!($expr);
- };
+ }}; |
I don't think so. https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bee60f1ca0ac361c93cb5ac937e891c0 Honestly I don't even think this is a static-assertions problem, I believe this is a Rust problem. |
Okay, I found a workaround: The assert thing does work, you just have to reference the const at some point in the control flow of the program. pub struct Test<const X: usize> {}
impl<const X: usize> Test<X> {
const CHECK: () = assert!(X < 10);
fn new() -> Self {
let _ = Self::CHECK; // this is necessary for CHECK to evaluate at comp time
Self {}
}
}
pub fn main() {
let test = Test::<20>::new();
} Neither |
With the release of Rust 1.79 in June 2024, this is now possible using an inline const expression: const SHA256_DIGEST_LENGTH: usize = 32;
fn truncate_sha256_digest<const L: usize>(
digest: &[u8; SHA256_DIGEST_LENGTH as usize],
) -> [u8; L] {
const { assert!(L <= SHA256_DIGEST_LENGTH) };
...
} pub struct Test<const X: usize> {}
impl<const X: usize> Test<X> {
fn new() -> Self {
const { assert!(X < 10) };
Self {}
}
}
pub fn main() {
let test = Test::<20>::new();
} Playground link showing compile-time assertion error Cheers! |
Neat! Thank you for confirming this can now be done! |
The following code raises a compiler error. I was expecting
const_assert!
to statically assert the const generic fits the bound.Code Snippet
Error
The text was updated successfully, but these errors were encountered: