Skip to content

Commit 259b25b

Browse files
committed
Make const panic!("..") work in Rust 2021.
During const eval, this replaces calls to core::panicking::panic_fmt and std::panicking::being_panic_fmt with a call to a new const fn: core::panicking::const_panic_fmt. That function uses fmt::Arguments::as_str() to get the str and calls panic_str with that instead. panic!() invocations with formatting arguments are still not accepted, as the creation of such a fmt::Arguments cannot be done in constant functions right now.
1 parent 310eb55 commit 259b25b

File tree

4 files changed

+16
-2
lines changed

4 files changed

+16
-2
lines changed

core/src/fmt/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ impl<'a> Arguments<'a> {
337337
#[doc(hidden)]
338338
#[inline]
339339
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
340-
pub fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
340+
pub const fn new_v1(pieces: &'a [&'static str], args: &'a [ArgumentV1<'a>]) -> Arguments<'a> {
341341
Arguments { pieces, fmt: None, args }
342342
}
343343

@@ -350,7 +350,7 @@ impl<'a> Arguments<'a> {
350350
#[doc(hidden)]
351351
#[inline]
352352
#[unstable(feature = "fmt_internals", reason = "internal to format_args!", issue = "none")]
353-
pub fn new_v1_formatted(
353+
pub const fn new_v1_formatted(
354354
pieces: &'a [&'static str],
355355
args: &'a [ArgumentV1<'a>],
356356
fmt: &'a [rt::v1::Argument],

core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#![feature(cfg_target_has_atomic)]
7474
#![feature(const_heap)]
7575
#![feature(const_alloc_layout)]
76+
#![feature(const_arguments_as_str)]
7677
#![feature(const_assert_type)]
7778
#![feature(const_discriminant)]
7879
#![feature(const_cell_into_inner)]

core/src/panicking.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
7474
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
7575
#[cfg_attr(feature = "panic_immediate_abort", inline)]
7676
#[track_caller]
77+
#[cfg_attr(not(bootstrap), lang = "panic_fmt")] // needed for const-evaluated panics
7778
pub fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
7879
if cfg!(feature = "panic_immediate_abort") {
7980
super::intrinsics::abort()
@@ -92,6 +93,17 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
9293
unsafe { panic_impl(&pi) }
9394
}
9495

96+
/// This function is used instead of panic_fmt in const eval.
97+
#[cfg(not(bootstrap))]
98+
#[lang = "const_panic_fmt"]
99+
pub const fn const_panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
100+
if let Some(msg) = fmt.as_str() {
101+
panic_str(msg);
102+
} else {
103+
panic_str("???");
104+
}
105+
}
106+
95107
#[derive(Debug)]
96108
#[doc(hidden)]
97109
pub enum AssertKind {

std/src/panicking.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ pub fn panicking() -> bool {
448448
#[cfg_attr(not(feature = "panic_immediate_abort"), track_caller)]
449449
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
450450
#[cfg_attr(feature = "panic_immediate_abort", inline)]
451+
#[cfg_attr(all(not(bootstrap), not(test)), lang = "begin_panic_fmt")]
451452
pub fn begin_panic_fmt(msg: &fmt::Arguments<'_>) -> ! {
452453
if cfg!(feature = "panic_immediate_abort") {
453454
intrinsics::abort()

0 commit comments

Comments
 (0)