Description
We currently have four macros for runtime assertions: assert!
, assert_eq!
, debug_assert!
, and debug_assert_eq!
. See https://github.com/rust-lang/rust/blob/master/src/libcore/macros.rs#L50 for their definitions, which are all quite simple. The reason for having the _eq
form for both assert!
and debug_assert!
is because equality checks are the most common kinds of assertions (assert_eq!
is found 7100 times in the Rust repo, vs 4600 for assert!
) and that by encoding the intent of the assertion we can produce a better error message, like so:
assert!(1 == 2); // task '<main>' failed at 'assertion failed: 1 == 2'
assert_eq!(1, 2); // task '<main>' failed at 'assertion failed: `(left == right) && (right == left)` (left: `1`, right: `2`)', assert.rs:2
However, I don't see a reason for the existence of this extra macro. I propose that we leverage our existing macro_rules!
facilities to special-case the form assert!(a == b)
such that it implements the current logic of assert_eq!
. In non-tested copy-pasted code:
macro_rules! assert(
($cond1:expr == $cond2:expr) => ({ // literally just the inner bit of the assert_eq! definition
let c1 = $cond1;
let c2 = $cond2;
if c1 != c2 || c2 != c1 {
fail!("expressions not equal, left: {}, right: {}", c1, c2);
}
})
($cond:expr) => ( // the current assert! definition starts here
if !$cond {
fail!(concat!("assertion failed: ", stringify!($cond)))
}
);
($cond:expr, $($arg:tt)*) => (
if !$cond {
fail!($($arg)*)
}
);
)
Does anyone see any problems with this?