Skip to content

Commit 2229863

Browse files
committed
Constify assert_eq! and assert_ne!
We provide an inferior type of formatting for use when panicking in compile time, which should not come with additional costs as the additional argument should be inlined and optimized away when in runtime
1 parent db137ba commit 2229863

File tree

4 files changed

+84
-6
lines changed

4 files changed

+84
-6
lines changed

library/core/src/macros/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ macro_rules! assert_eq {
4242
// The reborrows below are intentional. Without them, the stack slot for the
4343
// borrow is initialized even before the values are compared, leading to a
4444
// noticeable slow down.
45-
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::None);
45+
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::None, $crate::concat!("assertion failed: `", $crate::stringify!($left), " == ", $crate::stringify!($right), "`"));
4646
}
4747
}
4848
}
@@ -55,7 +55,7 @@ macro_rules! assert_eq {
5555
// The reborrows below are intentional. Without them, the stack slot for the
5656
// borrow is initialized even before the values are compared, leading to a
5757
// noticeable slow down.
58-
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::Some($crate::format_args!($($arg)+)));
58+
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::Some($crate::format_args!($($arg)+)), $crate::concat!("assertion failed: `", $crate::stringify!($left), " == ", $crate::stringify!($right), "`"));
5959
}
6060
}
6161
}
@@ -92,7 +92,7 @@ macro_rules! assert_ne {
9292
// The reborrows below are intentional. Without them, the stack slot for the
9393
// borrow is initialized even before the values are compared, leading to a
9494
// noticeable slow down.
95-
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::None);
95+
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::None, $crate::concat!("assertion failed: `", $crate::stringify!($left), " != ", $crate::stringify!($right), "`"));
9696
}
9797
}
9898
}
@@ -105,7 +105,7 @@ macro_rules! assert_ne {
105105
// The reborrows below are intentional. Without them, the stack slot for the
106106
// borrow is initialized even before the values are compared, leading to a
107107
// noticeable slow down.
108-
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::Some($crate::format_args!($($arg)+)));
108+
$crate::panicking::assert_failed(kind, &*left_val, &*right_val, $crate::option::Option::Some($crate::format_args!($($arg)+)), $crate::concat!("assertion failed: `", $crate::stringify!($left), " != ", $crate::stringify!($right), "`"));
109109
}
110110
}
111111
}

library/core/src/panicking.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,53 @@ pub enum AssertKind {
199199
#[cfg_attr(feature = "panic_immediate_abort", inline)]
200200
#[track_caller]
201201
#[doc(hidden)]
202-
pub fn assert_failed<T, U>(
202+
#[rustc_const_unstable(feature = "const_assert_eq", issue = "none")]
203+
pub const fn assert_failed<T, U>(
203204
kind: AssertKind,
204205
left: &T,
205206
right: &U,
206207
args: Option<fmt::Arguments<'_>>,
208+
string_for_const_msg: &str,
207209
) -> !
208210
where
209211
T: fmt::Debug + ?Sized,
210212
U: fmt::Debug + ?Sized,
211213
{
212-
assert_failed_inner(kind, &left, &right, args)
214+
#[track_caller]
215+
const fn assert_failed_const_impl<T: ?Sized, U: ?Sized>(
216+
_: AssertKind,
217+
_: &T,
218+
_: &U,
219+
_: Option<fmt::Arguments<'_>>,
220+
msg: &str,
221+
) -> ! {
222+
panic_str(msg)
223+
}
224+
225+
#[track_caller]
226+
#[inline]
227+
fn assert_failed_runtime_impl<T, U>(
228+
kind: AssertKind,
229+
left: &T,
230+
right: &U,
231+
args: Option<fmt::Arguments<'_>>,
232+
_: &str,
233+
) -> !
234+
where
235+
T: fmt::Debug + ?Sized,
236+
U: fmt::Debug + ?Sized,
237+
{
238+
assert_failed_inner(kind, &left, &right, args)
239+
}
240+
241+
// SAFETY: we are panicking in both branches, so this is consistent.
242+
unsafe {
243+
crate::intrinsics::const_eval_select(
244+
(kind, left, right, args, string_for_const_msg),
245+
assert_failed_const_impl,
246+
assert_failed_runtime_impl,
247+
)
248+
}
213249
}
214250

215251
/// Internal function for `assert_match!`

tests/ui/consts/assertions.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(const_assert_eq)]
2+
3+
const _BAD1: () = {
4+
assert_eq!(1, 2)
5+
}; //~^ ERROR: evaluation of constant value failed
6+
7+
const _BAD2: () = {
8+
assert_ne!(1, 1)
9+
}; //~^ ERROR: evaluation of constant value failed
10+
11+
const _BAD3: () = {
12+
assert!(false)
13+
}; //~^ ERROR: evaluation of constant value failed
14+
15+
fn main() {}

tests/ui/consts/assertions.stderr

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0080]: evaluation of constant value failed
2+
--> $DIR/assertions.rs:4:5
3+
|
4+
LL | assert_eq!(1, 2)
5+
| ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: `1 == 2`', $DIR/assertions.rs:4:5
6+
|
7+
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error[E0080]: evaluation of constant value failed
10+
--> $DIR/assertions.rs:8:5
11+
|
12+
LL | assert_ne!(1, 1)
13+
| ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: `1 != 1`', $DIR/assertions.rs:8:5
14+
|
15+
= note: this error originates in the macro `assert_ne` (in Nightly builds, run with -Z macro-backtrace for more info)
16+
17+
error[E0080]: evaluation of constant value failed
18+
--> $DIR/assertions.rs:12:5
19+
|
20+
LL | assert!(false)
21+
| ^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: false', $DIR/assertions.rs:12:5
22+
|
23+
= note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info)
24+
25+
error: aborting due to 3 previous errors
26+
27+
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)