From bbad2b2182120abee70d59a57495c560444e5464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20du=20Garreau?= Date: Mon, 16 Nov 2020 15:40:33 +0100 Subject: [PATCH] Improve assert_eq! and assert_ne! It should improve compile times and reduce instruction cache use by moving the panic formatting to a monomorphised function --- library/core/src/lib.rs | 7 +++ library/core/src/macros/internals.rs | 85 ++++++++++++++++++++++++++++ library/core/src/macros/mod.rs | 26 ++++----- 3 files changed, 103 insertions(+), 15 deletions(-) create mode 100644 library/core/src/macros/internals.rs diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index fd4a76c1eb5..cc74656a296 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -173,6 +173,13 @@ #[macro_use] mod internal_macros; +#[doc(hidden)] +#[unstable( + feature = "macros_internals", + reason = "macros implementation detail", + issue = "none" +)] +pub use macros::internals as macros_internals; #[path = "num/shells/int_macros.rs"] #[macro_use] diff --git a/library/core/src/macros/internals.rs b/library/core/src/macros/internals.rs new file mode 100644 index 00000000000..39ac0b41f16 --- /dev/null +++ b/library/core/src/macros/internals.rs @@ -0,0 +1,85 @@ +use crate::{fmt, panic}; + +#[cold] +#[doc(hidden)] +#[unstable(feature = "macros_internals", reason = "macros implementation detail", issue = "none")] +#[track_caller] +pub fn assert_eq_failed(left: &T, right: &U) -> ! +where + T: fmt::Debug + ?Sized, + U: fmt::Debug + ?Sized, +{ + #[track_caller] + fn inner(left: &dyn fmt::Debug, right: &dyn fmt::Debug) -> ! { + panic!( + r#"assertion failed: `(left == right)` +left: `{:?}`, +right: `{:?}`"#, + left, right + ) + } + inner(&left, &right) +} + +#[cold] +#[doc(hidden)] +#[unstable(feature = "macros_internals", reason = "macros implementation detail", issue = "none")] +#[track_caller] +pub fn assert_eq_failed_args(left: &T, right: &U, args: fmt::Arguments<'_>) -> ! +where + T: fmt::Debug + ?Sized, + U: fmt::Debug + ?Sized, +{ + #[track_caller] + fn inner(left: &dyn fmt::Debug, right: &dyn fmt::Debug, args: fmt::Arguments<'_>) -> ! { + panic!( + r#"assertion failed: `(left == right)` +left: `{:?}`, +right: `{:?}: {}`"#, + left, right, args + ) + } + inner(&left, &right, args) +} + +#[cold] +#[doc(hidden)] +#[unstable(feature = "macros_internals", reason = "macros implementation detail", issue = "none")] +#[track_caller] +pub fn assert_ne_failed(left: &T, right: &U) -> ! +where + T: fmt::Debug + ?Sized, + U: fmt::Debug + ?Sized, +{ + #[track_caller] + fn inner(left: &dyn fmt::Debug, right: &dyn fmt::Debug) -> ! { + panic!( + r#"assertion failed: `(left != right)` +left: `{:?}`, +right: `{:?}`"#, + left, right + ) + } + inner(&left, &right) +} + +#[cold] +#[doc(hidden)] +#[unstable(feature = "macros_internals", reason = "macros implementation detail", issue = "none")] +#[track_caller] +pub fn assert_ne_failed_args(left: &T, right: &U, args: fmt::Arguments<'_>) -> ! +where + T: fmt::Debug + ?Sized, + U: fmt::Debug + ?Sized, +{ + #[track_caller] + fn inner(left: &dyn fmt::Debug, right: &dyn fmt::Debug, args: fmt::Arguments<'_>) -> ! { + panic!( + r#"assertion failed: `(left != right)` +left: `{:?}`, +right: `{:?}: {}`"#, + left, right, args + ) + } + inner(&left, &right, args) +} diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 7aaf5a5fd46..5061ca0c50d 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1,3 +1,7 @@ +#[unstable(feature = "macros_internals", reason = "macros implementation detail", issue = "none")] +#[doc(hidden)] +pub mod internals; + #[cfg(bootstrap)] #[doc(include = "panic.md")] #[macro_export] @@ -53,6 +57,7 @@ macro_rules! panic { /// ``` #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] +#[allow_internal_unstable(macros_internals)] macro_rules! assert_eq { ($left:expr, $right:expr $(,)?) => ({ match (&$left, &$right) { @@ -61,24 +66,19 @@ macro_rules! assert_eq { // 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::panic!(r#"assertion failed: `(left == right)` - left: `{:?}`, - right: `{:?}`"#, &*left_val, &*right_val) + $crate::macros_internals::assert_eq_failed(&*left_val, &*right_val); } } } }); ($left:expr, $right:expr, $($arg:tt)+) => ({ - match (&($left), &($right)) { + match (&$left, &$right) { (left_val, right_val) => { if !(*left_val == *right_val) { // 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::panic!(r#"assertion failed: `(left == right)` - left: `{:?}`, - right: `{:?}`: {}"#, &*left_val, &*right_val, - $crate::format_args!($($arg)+)) + $crate::macros_internals::assert_eq_failed_args(&*left_val, &*right_val, $crate::format_args!($($arg)+)); } } } @@ -104,6 +104,7 @@ macro_rules! assert_eq { /// ``` #[macro_export] #[stable(feature = "assert_ne", since = "1.13.0")] +#[allow_internal_unstable(macros_internals)] macro_rules! assert_ne { ($left:expr, $right:expr $(,)?) => ({ match (&$left, &$right) { @@ -112,9 +113,7 @@ macro_rules! assert_ne { // 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::panic!(r#"assertion failed: `(left != right)` - left: `{:?}`, - right: `{:?}`"#, &*left_val, &*right_val) + $crate::macros_internals::assert_eq_failed(&*left_val, &*right_val); } } } @@ -126,10 +125,7 @@ macro_rules! assert_ne { // 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::panic!(r#"assertion failed: `(left != right)` - left: `{:?}`, - right: `{:?}`: {}"#, &*left_val, &*right_val, - $crate::format_args!($($arg)+)) + $crate::macros_internals::assert_ne_failed_args(&*left_val, &*right_val, $crate::format_args!($($arg)+)); } } }