是否可以 const assert trait const value 相等?

Is it possible to const assert trait const value equality?

我有一些示例代码,在其中我尝试使用 static_assertions crate。但我不确定这是否可能。

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!");
}

Playground

编译失败:

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)

我一直在阅读一些主题,例如:

但无法关联。

编辑:

在 trait 中将类型更改为 usize 时:

pub trait Foo {
    const ID: usize;
}

以上示例有效。所以我想这可能与 &'static str.

的类型有关

const_str and static_assertions 个板条箱的组合用于此目的:

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!");
}

根据@ChayimFriedman 的建议,由于生锈 1.57 可以使用普通的 assert!:

const _: () = assert!(const_str::equal!(A::ID, B::ID));

这里的问题是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

所以是的,这是可能的,但 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!");
}