Skip to content

Commit 4b87907

Browse files
committed
Try to improve performance by reducing the size of involved types
1 parent 3b03d3a commit 4b87907

File tree

9 files changed

+231
-327
lines changed

9 files changed

+231
-327
lines changed

library/core/src/macros/mod.rs

+33-23
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,22 @@ macro_rules! panic {
3131
/// ```
3232
#[macro_export]
3333
#[stable(feature = "rust1", since = "1.0.0")]
34-
#[allow_internal_unstable(core_panic)]
34+
#[allow_internal_unstable(core_panic, panic_internals)]
3535
macro_rules! assert_eq {
3636
($left:expr, $right:expr $(,)?) => ({
3737
match (&$left, &$right) {
3838
(left_val, right_val) => {
3939
if !(*left_val == *right_val) {
40-
let kind = $crate::panicking::AssertKind::Eq;
4140
// The reborrows below are intentional. Without them, the stack slot for the
4241
// borrow is initialized even before the values are compared, leading to a
4342
// noticeable slow down.
4443
$crate::panicking::assert_failed(
45-
kind,
46-
$crate::stringify!($left),
44+
&$crate::panic::assert_info::BinaryAssertionStaticData {
45+
kind: $crate::panic::assert_info::BinaryAssertKind::Eq,
46+
left_expr: $crate::stringify!($left),
47+
right_expr: $crate::stringify!($right),
48+
},
4749
&*left_val,
48-
$crate::stringify!($right),
4950
&*right_val,
5051
$crate::option::Option::None,
5152
);
@@ -57,15 +58,16 @@ macro_rules! assert_eq {
5758
match (&$left, &$right) {
5859
(left_val, right_val) => {
5960
if !(*left_val == *right_val) {
60-
let kind = $crate::panicking::AssertKind::Eq;
6161
// The reborrows below are intentional. Without them, the stack slot for the
6262
// borrow is initialized even before the values are compared, leading to a
6363
// noticeable slow down.
6464
$crate::panicking::assert_failed(
65-
kind,
66-
$crate::stringify!($left),
65+
&$crate::panic::assert_info::BinaryAssertionStaticData {
66+
kind: $crate::panic::assert_info::BinaryAssertKind::Eq,
67+
left_expr: $crate::stringify!($left),
68+
right_expr: $crate::stringify!($right),
69+
},
6770
&*left_val,
68-
$crate::stringify!($right),
6971
&*right_val,
7072
$crate::option::Option::Some($crate::format_args!($($arg)+)),
7173
);
@@ -94,21 +96,22 @@ macro_rules! assert_eq {
9496
/// ```
9597
#[macro_export]
9698
#[stable(feature = "assert_ne", since = "1.13.0")]
97-
#[allow_internal_unstable(core_panic)]
99+
#[allow_internal_unstable(core_panic, panic_internals)]
98100
macro_rules! assert_ne {
99101
($left:expr, $right:expr $(,)?) => ({
100102
match (&$left, &$right) {
101103
(left_val, right_val) => {
102104
if *left_val == *right_val {
103-
let kind = $crate::panicking::AssertKind::Ne;
104105
// The reborrows below are intentional. Without them, the stack slot for the
105106
// borrow is initialized even before the values are compared, leading to a
106107
// noticeable slow down.
107108
$crate::panicking::assert_failed(
108-
kind,
109-
$crate::stringify!($left),
109+
&$crate::panic::assert_info::BinaryAssertionStaticData {
110+
kind: $crate::panic::assert_info::BinaryAssertKind::Ne,
111+
left_expr: $crate::stringify!($left),
112+
right_expr: $crate::stringify!($right),
113+
},
110114
&*left_val,
111-
$crate::stringify!($right),
112115
&*right_val,
113116
$crate::option::Option::None,
114117
);
@@ -120,15 +123,16 @@ macro_rules! assert_ne {
120123
match (&($left), &($right)) {
121124
(left_val, right_val) => {
122125
if *left_val == *right_val {
123-
let kind = $crate::panicking::AssertKind::Ne;
124126
// The reborrows below are intentional. Without them, the stack slot for the
125127
// borrow is initialized even before the values are compared, leading to a
126128
// noticeable slow down.
127129
$crate::panicking::assert_failed(
128-
kind,
129-
$crate::stringify!($left),
130+
&$crate::panic::assert_info::BinaryAssertionStaticData {
131+
kind: $crate::panic::assert_info::BinaryAssertKind::Ne,
132+
left_expr: $crate::stringify!($left),
133+
right_expr: $crate::stringify!($right),
134+
},
130135
&*left_val,
131-
$crate::stringify!($right),
132136
&*right_val,
133137
$crate::option::Option::Some($crate::format_args!($($arg)+)),
134138
);
@@ -165,17 +169,20 @@ macro_rules! assert_ne {
165169
/// assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
166170
/// ```
167171
#[unstable(feature = "assert_matches", issue = "82775")]
168-
#[allow_internal_unstable(core_panic)]
172+
#[allow_internal_unstable(core_panic, panic_internals)]
169173
#[rustc_macro_transparency = "semitransparent"]
170174
pub macro assert_matches {
171175
($left:expr, $(|)? $( $pattern:pat_param )|+ $( if $guard: expr )? $(,)?) => ({
172176
match $left {
173177
$( $pattern )|+ $( if $guard )? => {}
174178
ref left_val => {
175179
$crate::panicking::assert_matches_failed(
176-
$crate::stringify!($left),
180+
&$crate::panic::assert_info::BinaryAssertionStaticData {
181+
kind: $crate::panic::assert_info::BinaryAssertKind::Match,
182+
left_expr: $crate::stringify!($left),
183+
right_expr: $crate::stringify!($($pattern)|+ $(if $guard)?),
184+
},
177185
left_val,
178-
$crate::stringify!($($pattern)|+ $(if $guard)?),
179186
$crate::option::Option::None
180187
);
181188
}
@@ -186,9 +193,12 @@ pub macro assert_matches {
186193
$( $pattern )|+ $( if $guard )? => {}
187194
ref left_val => {
188195
$crate::panicking::assert_matches_failed(
189-
$crate::stringify!($left),
196+
&$crate::panic::assert_info::BinaryAssertionStaticData {
197+
kind: $crate::panic::assert_info::BinaryAssertKind::Match,
198+
left_expr: $crate::stringify!($left),
199+
right_expr: $crate::stringify!($($pattern)|+ $(if $guard)?),
200+
},
190201
left_val,
191-
$crate::stringify!($($pattern)|+ $(if $guard)?),
192202
$crate::option::Option::Some($crate::format_args!($($arg)+))
193203
);
194204
}

library/core/src/panic.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,23 @@
22
33
#![stable(feature = "core_panic_info", since = "1.41.0")]
44

5-
mod location;
6-
mod panic_info;
7-
mod unwind_safe;
85
#[unstable(
96
feature = "panic_internals",
107
reason = "internal details of the implementation of the `panic!` and related macros",
118
issue = "none"
129
)]
1310
#[doc(hidden)]
1411
pub mod assert_info;
12+
mod location;
1513
#[unstable(
1614
feature = "panic_internals",
1715
reason = "internal details of the implementation of the `panic!` and related macros",
1816
issue = "none"
1917
)]
2018
#[doc(hidden)]
21-
pub mod extra_info;
19+
pub mod panic_description;
20+
mod panic_info;
21+
mod unwind_safe;
2222

2323
use crate::any::Any;
2424

@@ -50,10 +50,7 @@ pub macro panic_2015 {
5050
$crate::panicking::panic_display(&$arg)
5151
),
5252
($fmt:expr, $($arg:tt)+) => (
53-
$crate::panicking::panic_fmt(
54-
$crate::const_format_args!($fmt, $($arg)+),
55-
$crate::option::Option::None,
56-
)
53+
$crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
5754
),
5855
}
5956

@@ -71,10 +68,7 @@ pub macro panic_2021 {
7168
$crate::panicking::panic_display(&$arg)
7269
),
7370
($($t:tt)+) => (
74-
$crate::panicking::panic_fmt(
75-
$crate::const_format_args!($($t)+),
76-
$crate::option::Option::None,
77-
)
71+
$crate::panicking::panic_fmt($crate::const_format_args!($($t)+))
7872
),
7973
}
8074

library/core/src/panic/assert_info.rs

+68-44
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,97 @@
1-
use crate::fmt::Debug;
1+
use crate::fmt::{self, Debug};
22

33
/// Information about a failed assertion.
44
#[derive(Debug)]
55
pub struct AssertInfo<'a> {
66
/// The assertion that failed.
77
pub assertion: Assertion<'a>,
8-
/// The name of the macro that triggered the panic.
9-
pub macro_name: &'static str,
108
/// Optional additional message to include in the failure report.
119
pub message: Option<crate::fmt::Arguments<'a>>,
1210
}
1311

12+
impl fmt::Display for AssertInfo<'_> {
13+
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
14+
match self.assertion {
15+
Assertion::Binary(ref assertion) => match self.message {
16+
Some(message) => write!(
17+
formatter,
18+
r#"assertion failed: `(left {} right)`
19+
left: `{:?}`,
20+
right: `{:?}`: {}"#,
21+
assertion.static_data.kind.op(),
22+
assertion.left_val,
23+
assertion.right_val,
24+
message
25+
),
26+
None => write!(
27+
formatter,
28+
r#"assertion failed: `(left {} right)`
29+
left: `{:?}`,
30+
right: `{:?}`"#,
31+
assertion.static_data.kind.op(),
32+
assertion.left_val,
33+
assertion.right_val
34+
),
35+
},
36+
}
37+
}
38+
}
39+
1440
/// Details about the expression that failed an assertion.
1541
#[derive(Debug)]
1642
pub enum Assertion<'a> {
17-
/// The failed assertion is a boolean expression.
18-
///
19-
/// This variant is only used for expressions that can't be described more specifically
20-
/// by another variant.
21-
Bool(BoolAssertion),
22-
23-
/// The failed assertion is a binary comparison expression.
24-
///
25-
/// This is used by `assert_eq!()`, `assert_ne!()` and expressions like
26-
/// `assert!(x > 10)`.
43+
/// The failed assertion is a binary expression.
2744
Binary(BinaryAssertion<'a>),
2845
}
2946

30-
/// Information about a failed boolean assertion.
31-
///
32-
/// The expression was asserted to be true, but it evaluated to false.
33-
///
34-
/// This struct is only used for assertion failures that can't be described more specifically
35-
/// by another assertion type.
47+
/// Information about a failed binary assertion.
3648
#[derive(Debug)]
37-
pub struct BoolAssertion {
38-
/// The expression that was evaluated to false.
39-
pub expr: &'static str,
49+
pub struct BinaryAssertion<'a> {
50+
/// Static information about the failed assertion.
51+
pub static_data: &'static BinaryAssertionStaticData,
52+
/// The left value of the binary assertion.
53+
pub left_val: &'a dyn Debug,
54+
/// The right value of the binary assertion.
55+
pub right_val: &'a dyn Debug,
4056
}
4157

42-
/// Information about a failed binary comparison assertion.
58+
/// Information about a binary assertion that can be constructed at compile time.
4359
///
44-
/// The left expression was compared with the right expression using `op`,
45-
/// and the comparison evaluted to false.
46-
///
47-
/// This struct is used for `assert_eq!()`, `assert_ne!()` and expressions like
48-
/// `assert!(x > 10)`.
60+
/// This struct helps to reduce the size `AssertInfo`.
4961
#[derive(Debug)]
50-
pub struct BinaryAssertion<'a> {
51-
/// The operator used to compare left and right.
52-
pub op: &'static str,
53-
/// The left expression as string.
62+
pub struct BinaryAssertionStaticData {
63+
/// The kind of the binary assertion
64+
pub kind: BinaryAssertKind,
65+
/// The left expression of the binary assertion.
5466
pub left_expr: &'static str,
55-
/// The right expression as string.
67+
/// The right expression of the binary assertion.
5668
pub right_expr: &'static str,
57-
/// The value of the left expression.
58-
pub left_val: &'a dyn Debug,
59-
/// The value of the right expression.
60-
pub right_val: &'a dyn Debug,
6169
}
6270

63-
impl<'a> From<BoolAssertion> for Assertion<'a> {
64-
fn from(other: BoolAssertion) -> Self {
65-
Self::Bool(other)
66-
}
71+
/// The kind of a binary assertion
72+
#[derive(Debug)]
73+
pub enum BinaryAssertKind {
74+
Eq,
75+
Ne,
76+
Match,
6777
}
6878

69-
impl<'a> From<BinaryAssertion<'a>> for Assertion<'a> {
70-
fn from(other: BinaryAssertion<'a>) -> Self {
71-
Self::Binary(other)
79+
impl BinaryAssertKind {
80+
/// The name of the macro that triggered the panic.
81+
pub fn macro_name(&self) -> &'static str {
82+
match self {
83+
Self::Eq { .. } => "assert_eq",
84+
Self::Ne { .. } => "assert_ne",
85+
Self::Match { .. } => "assert_matches",
86+
}
87+
}
88+
89+
/// Symbolic representation of the binary assertion.
90+
pub fn op(&self) -> &'static str {
91+
match self {
92+
Self::Eq { .. } => "==",
93+
Self::Ne { .. } => "!=",
94+
Self::Match { .. } => "matches",
95+
}
7296
}
7397
}

library/core/src/panic/extra_info.rs

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use crate::fmt;
2+
use crate::panic::assert_info::AssertInfo;
3+
4+
/// Describes the cause of the panic.
5+
#[doc(hidden)]
6+
#[derive(Debug, Copy, Clone)]
7+
#[non_exhaustive]
8+
pub enum PanicDescription<'a> {
9+
/// Formatted arguments that were passed to the panic.
10+
Message(&'a fmt::Arguments<'a>),
11+
/// Information about the assertion that caused the panic.
12+
AssertInfo(&'a AssertInfo<'a>),
13+
}
14+
15+
#[unstable(
16+
feature = "panic_internals",
17+
reason = "internal details of the implementation of the `panic!` and related macros",
18+
issue = "none"
19+
)]
20+
impl fmt::Display for PanicDescription<'_> {
21+
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
22+
match self {
23+
Self::Message(message) => write!(formatter, "{}", message),
24+
Self::AssertInfo(info) => write!(formatter, "{}", info),
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)