Rfcs: Accept extra parameters in assert_eq!, pass them to panic!

Created on 1 May 2016  路  6Comments  路  Source: rust-lang/rfcs

The assert! macro has a one-argument form that simply takes a boolean expression, and a "detailed" form where extra arguments are passed to panic!, allowing the user to change the panic message.

The assert_eq! macro however only has one form: two arguments that are compared for equality.

https://twitter.com/natpryce/status/656110689082286080?s=09

@ rustlang's assert_eq macro doesn't take a msg param, so I pass it tuples of values & context to get good diagnostics. What do others do?

I propose adding another form form assert_eq! where additional arguments are passed to panic!. But unlike assert!, I think this should add to the default message instead of replacing it. Something like:

macro_rules! assert_eq {
    ($left:expr , $right:expr) => ({
        match (&($left), &($right)) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    panic!("assertion failed: `(left == right)` \
                           (left: `{:?}`, right: `{:?}`)", left_val, right_val)
                }
            }
        }
    });
    ($left:expr , $right:expr, $fmt:expr, $($arg:tt)*) => ({
        match (&($left), &($right)) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    panic!(concat!("assertion failed: `(left == right)` \
                                   (left: `{:?}`, right: `{:?}`) ", $fmt),
                           left_val, right_val, $($arg)*)
                }
            }
        }
    });
}

CC @alexcrichton

T-libs

Most helpful comment

Good idea. I would be more inclined toward making the whole format string customisable though:

assert_eq!(..., ..., "blah blah '{left}' '{right}' blah {}", some_value);
    ($left:expr , $right:expr, $fmt:expr, $($arg:tt)*) => ({
        match (&($left), &($right)) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    panic!($fmt, left=left_val, right=right_val, $($arg)*)
                }
            }
        }
    });

All 6 comments

Good idea. I would be more inclined toward making the whole format string customisable though:

assert_eq!(..., ..., "blah blah '{left}' '{right}' blah {}", some_value);
    ($left:expr , $right:expr, $fmt:expr, $($arg:tt)*) => ({
        match (&($left), &($right)) {
            (left_val, right_val) => {
                if !(*left_val == *right_val) {
                    panic!($fmt, left=left_val, right=right_val, $($arg)*)
                }
            }
        }
    });

This has always been strange, especially considering that without this functionality, it could be a normal function instead.

@bjz I proposed concatenating instead of replacing the format string based on the assumption that, if you use assert_eq! instead of assert! with == you always want to print/format the two values.

@ticki With a function instead of a macro, the potentially-expensive string formatting would have to be done even when it鈥檚 not necessary (when the two values are equal and the assertion succeeds).

With a function instead of a macro, the potentially-expensive string formatting would have to be done even when it鈥檚 not necessary (when the two values are equal and the assertion succeeds).

Oh, don't get me wrong. I simple state that, as it is currently, having it as a macro is unnecessary since there is _no formatting involved_.

rust-lang/rust#33976 was merged, can this be closed?

Indeed!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rust-highfive picture rust-highfive  路  4Comments

torkleyy picture torkleyy  路  3Comments

clarfonthey picture clarfonthey  路  3Comments

3442853561 picture 3442853561  路  3Comments

burdges picture burdges  路  3Comments