Assert! works in const contexts but assert_eq! does not?

I decided to mess around with some const stuff today and wrote the following code

fn main() {
    const VAL: u64 = const_foo(5);
    const {assert!(VAL == 15)}
    println!("Assert Passed!");
}

const fn const_foo(index: u64) -> u64 {
    match index {
        0 | 1 => index,
        _ => index + const_foo(index - 1)
    }
}

In rustrover the assert in main() has a warning that says "assert!(a == b) can be replaced with assert_eq!(a, b)", but when I replace the assert it gives a compile time error stating that assert_eq cannot be used in const contexts.

I dont see why assert_eq! cant work in const contexts like assert! can. Does anyone have an explanation as to why this is?

My guess would be it has to do with how the macros are written with respect to how inline consts work but i dont see why the two would have to be written that differently when assert_eq! is just a specialization of assert!

It needs const trait imps, in short.

1 Like

I see, so its due to the way they panic. from what i can gather from the macro definitions, the panic in assert! is built into the compiler whereas for assert_eq its has a bit more that it goes through before that. I just dont understand the reason behind that, couldnt assert_eq! just be turned into assert!(a == b) by the compiler and then evaluated that way instead, giving it the ability to be evaluated at compile time too?

Just after I typed this i decided to actually check the differences in the output of assert! and assert_eq! (ive only ever used assert! and i just expected them to give similar outputs) and now i see that assert_eq! actually prints out a and b, coupled with the issue you linked I see why its locked behind const trait impls, thanks for the help!

For primitive types, perhaps, but for non-primitives (non-integers? I didn't check), equality is defined via traits. (Ignoring the output concerns.)

1 Like