Thanks to visit codestin.com
Credit goes to github.com

Skip to content
16 changes: 12 additions & 4 deletions library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ macro_rules! assert_eq {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = $crate::panicking::AssertKind::Eq;
let left_name = stringify!($left);
let right_name = stringify!($right);
// The reborrows below are intentional. Without them, the stack slot for the
// borrow is initialized even before the values are compared, leading to a
// noticeable slow down.
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::None);
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, left_name, right_name, $crate::option::Option::None);
}
}
}
Expand All @@ -52,10 +54,12 @@ macro_rules! assert_eq {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = $crate::panicking::AssertKind::Eq;
let left_name = stringify!($left);
let right_name = stringify!($right);
// The reborrows below are intentional. Without them, the stack slot for the
// borrow is initialized even before the values are compared, leading to a
// noticeable slow down.
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::Some($crate::format_args!($($arg)+)));
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, left_name, right_name, $crate::option::Option::Some($crate::format_args!($($arg)+)));
}
}
}
Expand Down Expand Up @@ -89,10 +93,12 @@ macro_rules! assert_ne {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = $crate::panicking::AssertKind::Ne;
let left_name = stringify!($left);
let right_name = stringify!($right);
// The reborrows below are intentional. Without them, the stack slot for the
// borrow is initialized even before the values are compared, leading to a
// noticeable slow down.
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::None);
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, left_name, right_name, $crate::option::Option::None);
}
}
}
Expand All @@ -102,10 +108,12 @@ macro_rules! assert_ne {
(left_val, right_val) => {
if *left_val == *right_val {
let kind = $crate::panicking::AssertKind::Ne;
let left_name = stringify!($left);
let right_name = stringify!($right);
// The reborrows below are intentional. Without them, the stack slot for the
// borrow is initialized even before the values are compared, leading to a
// noticeable slow down.
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::Some($crate::format_args!($($arg)+)));
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, left_name, right_name, $crate::option::Option::Some($crate::format_args!($($arg)+)));
}
}
}
Expand Down
34 changes: 23 additions & 11 deletions library/core/src/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,17 @@ pub enum AssertKind {
#[doc(hidden)]
pub fn assert_failed<T, U>(
kind: AssertKind,
left: &T,
right: &U,
left_val: &T,
right_val: &U,
left_name: &'static str,
right_name: &'static str,
args: Option<fmt::Arguments<'_>>,
) -> !
where
T: fmt::Debug + ?Sized,
U: fmt::Debug + ?Sized,
{
assert_failed_inner(kind, &left, &right, args)
assert_failed_inner(kind, &left_val, &right_val, &left_name, &right_name, args)
}

/// Internal function for `assert_match!`
Expand All @@ -198,15 +200,24 @@ pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
fmt::Display::fmt(self.0, f)
}
}
assert_failed_inner(AssertKind::Match, &left, &Pattern(right), args);
assert_failed_inner(
AssertKind::Match,
&left,
&Pattern(right),
stringify!(&left),
stringify!(&right),
args,
);
}

/// Non-generic version of the above functions, to avoid code bloat.
#[track_caller]
fn assert_failed_inner(
kind: AssertKind,
left: &dyn fmt::Debug,
right: &dyn fmt::Debug,
left_val: &dyn fmt::Debug,
right_val: &dyn fmt::Debug,
left_name: &'static str,
right_name: &'static str,
args: Option<fmt::Arguments<'_>>,
) -> ! {
let op = match kind {
Expand All @@ -217,16 +228,17 @@ fn assert_failed_inner(

match args {
Some(args) => panic!(
r#"assertion failed: `(left {} right)`
r#"assertion failed: `({left_name} {} {right_name})`
left: `{:?}`,
Comment on lines +231 to 232
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The at: here shouldn't be followed by a formatting specifier that we print, this is meant to be where the location goes, which is printed by the caller of assert_failed_inner, so we should just finish the output here. The args that you're printing here is the error message and should come before left.

Suggested change
r#"assertion failed: `({left_name} {} {right_name})`
left: `{:?}`,
r#"assertion failed: `({left_name} {op} {right_name})`
Error: {args},
left: `{left_val:?}`,

right: `{:?}`: {}"#,
op, left, right, args
right: `{:?}`:
at: {}"#,
op, left_val, right_val, args
),
Comment on lines +233 to 236
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
right: `{:?}`:
at: {}"#,
op, left_val, right_val, args
),
right: `{right_val:?}`,
at: "#),

None => panic!(
r#"assertion failed: `(left {} right)`
r#"assertion failed: `({left_name} {} {right_name})`
left: `{:?}`,
right: `{:?}`"#,
Comment on lines +238 to 240
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
r#"assertion failed: `({left_name} {} {right_name})`
left: `{:?}`,
right: `{:?}`"#,
r#"assertion failed: `({left_name} {op} {right_name})`
left: `{left_val:?}`,
right: `{right_val:?}`,
at: "#),

op, left, right,
op, left_val, right_val,
),
}
}