Reputation: 42756
I have some example code, in where I tried to use static_assertions
crate. But I am not sure it is even possible.
use static_assertions::{const_assert_eq, const_assert_ne};
pub trait Foo {
const ID: &'static str;
}
struct A;
struct B;
impl Foo for A {
const ID: &'static str = "A";
}
impl Foo for B {
const ID: &'static str = "B";
}
const fn assert_ids() {
const_assert_ne!(A::ID, B::ID);
}
fn main() {
assert_ids();
println!("Compiles successfully!");
}
Fails compiling with:
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> src\main.rs:35:5
|
35 | const_assert_ne!(A::ID, B::ID);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: this error originates in the macro `const_assert_ne` (in Nightly builds, run with -Z macro-backtrace for more info)
I have been reading on some threads like:
but couldn't related it.
EDIT:
When changing the type to usize
in the trait:
pub trait Foo {
const ID: usize;
}
The above example works. So I guess it may be related to the type being &'static str
.
Upvotes: 1
Views: 4226
Reputation: 42756
A combination of const_str
and static_assertions
crates worked for the purpose:
use static_assertions::{const_assert};
use const_str;
pub trait Foo {
const ID: &'static str;
}
struct A;
struct B;
impl Foo for A {
const ID: &'static str = "A";
}
impl Foo for B {
const ID: &'static str = "B";
}
const fn assert_ids() {
const_assert!(!const_str::equal!(A::ID, B::ID));
}
fn main() {
assert_ids();
println!("Compiles successfully!");
}
As per @ChayimFriedman suggestion, since rust 1.57
it is possible to use plain assert!
:
const _: () = assert!(const_str::equal!(A::ID, B::ID));
Upvotes: 4
Reputation: 26757
The problem here is that str::eq()
is not const. For now you can only compare primitive type such as integers, chars, bools. I don't know if there is a tracking issue for str and slice. #67792
So yes it's possible but not with str
:
pub trait Foo {
const ID: i32;
}
struct A;
struct B;
impl Foo for A {
const ID: i32 = 42;
}
impl Foo for B {
const ID: i32 = 3;
}
const fn assert_ids() {
if A::ID == B::ID {
panic!("nooooo");
}
}
fn main() {
assert_ids();
println!("Compiles successfully!");
}
Upvotes: 3