Skip to content

Commit 5c39b29

Browse files
committed
move const_panic/assert macros into core::panic module (since they are just internal helpers)
1 parent 5605568 commit 5c39b29

19 files changed

+299
-319
lines changed

Diff for: library/core/src/char/methods.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! impl char {}
22
33
use super::*;
4-
use crate::macros::const_panic;
4+
use crate::panic::const_panic;
55
use crate::slice;
66
use crate::str::from_utf8_unchecked_mut;
77
use crate::unicode::printable::is_printable;

Diff for: library/core/src/ffi/c_str.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ impl CStr {
413413
#[rustc_allow_const_fn_unstable(const_eval_select)]
414414
pub const unsafe fn from_bytes_with_nul_unchecked(bytes: &[u8]) -> &CStr {
415415
const_eval_select!(
416-
(bytes: &[u8]) -> &CStr:
416+
@capture { bytes: &[u8] } -> &CStr:
417417
if const {
418418
// Saturating so that an empty slice panics in the assert with a good
419419
// message, not here due to underflow.
@@ -429,7 +429,7 @@ impl CStr {
429429

430430
// SAFETY: See runtime cast comment below.
431431
unsafe { &*(bytes as *const [u8] as *const CStr) }
432-
} else #[inline] {
432+
} else {
433433
// Chance at catching some UB at runtime with debug builds.
434434
debug_assert!(!bytes.is_empty() && bytes[bytes.len() - 1] == 0);
435435

@@ -735,7 +735,7 @@ impl AsRef<CStr> for CStr {
735735
#[rustc_allow_const_fn_unstable(const_eval_select)]
736736
const unsafe fn strlen(ptr: *const c_char) -> usize {
737737
const_eval_select!(
738-
(s: *const c_char = ptr) -> usize:
738+
@capture { s: *const c_char = ptr } -> usize:
739739
if const {
740740
let mut len = 0;
741741

@@ -745,7 +745,7 @@ const unsafe fn strlen(ptr: *const c_char) -> usize {
745745
}
746746

747747
len
748-
} else #[inline] {
748+
} else {
749749
extern "C" {
750750
/// Provided by libc or compiler_builtins.
751751
fn strlen(s: *const c_char) -> usize;

Diff for: library/core/src/intrinsics.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -2791,31 +2791,36 @@ where
27912791
/// A macro to make it easier to invoke const_eval_select. Use as follows:
27922792
/// ```rust,ignore (just a macro example)
27932793
/// const_eval_select!(
2794-
/// #[inline]
2795-
/// (arg1: i32 = some_expr, arg2: T = other_expr) -> U:
2796-
/// if const {
2794+
/// @capture { arg1: i32 = some_expr, arg2: T = other_expr } -> U:
2795+
/// if const #[attributes_for_const_arm] {
27972796
/// // Compile-time code goes here.
2798-
/// } else {
2797+
/// } else #[attributes_for_runtime_arm] {
27992798
/// // Run-time code goes here.
28002799
/// }
28012800
/// )
28022801
/// ```
2802+
/// The `@capture` block declares which surrounding variables / expressions can be
2803+
/// used inside the `if const`.
2804+
/// Note that the two arms of this `if` really each become their own function, which is why the
2805+
/// macro supports setting attributes for those functions. The runtime function is always
2806+
/// markes as `#[inline]`.
2807+
///
2808+
/// See [`const_eval_select()`] for the rules and requirements around that intrinsic.
28032809
pub(crate) macro const_eval_select {
28042810
(
2811+
@capture { $($arg:ident : $ty:ty = $val:expr),* $(,)? } $( -> $ret:ty )? :
28052812
$(#[$attr:meta])*
2806-
($($arg:ident : $ty:ty = $val:expr),* $(,)?) $( -> $ret:ty )?:
28072813
if const
28082814
$(#[$compiletime_attr:meta])* $compiletime:block
28092815
else
28102816
$(#[$runtime_attr:meta])* $runtime:block
28112817
) => {{
2812-
$(#[$attr])*
28132818
$(#[$runtime_attr])*
2819+
#[inline]
28142820
fn runtime($($arg: $ty),*) $( -> $ret )? {
28152821
$runtime
28162822
}
28172823

2818-
$(#[$attr])*
28192824
$(#[$compiletime_attr])*
28202825
const fn compiletime($($arg: $ty),*) $( -> $ret )? {
28212826
// Don't warn if one of the arguments is unused.
@@ -2829,16 +2834,14 @@ pub(crate) macro const_eval_select {
28292834
// We support leaving away the `val` expressions for *all* arguments
28302835
// (but not for *some* arguments, that's too tricky).
28312836
(
2832-
$(#[$attr:meta])*
2833-
($($arg:ident : $ty:ty),* $(,)?) -> $ret:ty:
2837+
@capture { $($arg:ident : $ty:ty),* $(,)? } $( -> $ret:ty )? :
28342838
if const
28352839
$(#[$compiletime_attr:meta])* $compiletime:block
28362840
else
28372841
$(#[$runtime_attr:meta])* $runtime:block
28382842
) => {
28392843
$crate::intrinsics::const_eval_select!(
2840-
$(#[$attr])*
2841-
($($arg : $ty = $arg),*) -> $ret:
2844+
@capture { $($arg : $ty = $arg),* } $(-> $ret)? :
28422845
if const
28432846
$(#[$compiletime_attr])* $compiletime
28442847
else
@@ -3794,7 +3797,7 @@ pub(crate) const fn miri_promise_symbolic_alignment(ptr: *const (), align: usize
37943797
}
37953798

37963799
const_eval_select!(
3797-
(ptr: *const (), align: usize):
3800+
@capture { ptr: *const (), align: usize}:
37983801
if const {
37993802
// Do nothing.
38003803
} else {

Diff for: library/core/src/macros/mod.rs

-58
Original file line numberDiff line numberDiff line change
@@ -12,51 +12,6 @@ macro_rules! panic {
1212
};
1313
}
1414

15-
/// Helper macro for panicking in a `const fn`.
16-
/// Invoke as:
17-
/// ```rust,ignore (just an example)
18-
/// core::macros::const_panic!("boring message", "flavored message {a} {b:?}", a: u32 = foo.len(), b: Something = bar);
19-
/// ```
20-
/// where the first message will be printed in const-eval,
21-
/// and the second message will be printed at runtime.
22-
// All uses of this macro are FIXME(const-hack).
23-
#[unstable(feature = "panic_internals", issue = "none")]
24-
#[doc(hidden)]
25-
pub macro const_panic {
26-
($const_msg:literal, $runtime_msg:literal, $($arg:ident : $ty:ty = $val:expr),* $(,)?) => {{
27-
// Wrap call to `const_eval_select` in a function so that we can
28-
// add the `rustc_allow_const_fn_unstable`. This is okay to do
29-
// because both variants will panic, just with different messages.
30-
#[rustc_allow_const_fn_unstable(const_eval_select)]
31-
#[inline(always)]
32-
#[track_caller]
33-
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_panic", since = "CURRENT_RUSTC_VERSION"))]
34-
const fn do_panic($($arg: $ty),*) -> ! {
35-
$crate::intrinsics::const_eval_select!(
36-
#[inline]
37-
#[track_caller]
38-
($($arg: $ty),*) -> !:
39-
if const {
40-
$crate::panic!($const_msg)
41-
} else {
42-
$crate::panic!($runtime_msg)
43-
}
44-
)
45-
}
46-
47-
do_panic($($val),*)
48-
}},
49-
// We support leaving away the `val` expressions for *all* arguments
50-
// (but not for *some* arguments, that's too tricky).
51-
($const_msg:literal, $runtime_msg:literal, $($arg:ident : $ty:ty),* $(,)?) => {
52-
$crate::macros::const_panic!(
53-
$const_msg,
54-
$runtime_msg,
55-
$($arg: $ty = $arg),*
56-
)
57-
},
58-
}
59-
6015
/// Asserts that two expressions are equal to each other (using [`PartialEq`]).
6116
///
6217
/// Assertions are always checked in both debug and release builds, and cannot
@@ -241,19 +196,6 @@ pub macro assert_matches {
241196
},
242197
}
243198

244-
/// A version of `assert` that prints a non-formatting message in const contexts.
245-
///
246-
/// See [`const_panic!`].
247-
#[unstable(feature = "panic_internals", issue = "none")]
248-
#[doc(hidden)]
249-
pub macro const_assert {
250-
($condition: expr, $const_msg:literal, $runtime_msg:literal, $($arg:tt)*) => {{
251-
if !$crate::intrinsics::likely($condition) {
252-
$crate::macros::const_panic!($const_msg, $runtime_msg, $($arg)*)
253-
}
254-
}}
255-
}
256-
257199
/// A macro for defining `#[cfg]` match-like statements.
258200
///
259201
/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of

Diff for: library/core/src/num/f128.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
use crate::convert::FloatToInt;
1515
#[cfg(not(test))]
1616
use crate::intrinsics;
17-
use crate::macros::const_assert;
1817
use crate::mem;
1918
use crate::num::FpCategory;
19+
use crate::panic::const_assert;
2020

2121
/// Basic mathematical constants.
2222
#[unstable(feature = "f128", issue = "116909")]

Diff for: library/core/src/num/f16.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
use crate::convert::FloatToInt;
1515
#[cfg(not(test))]
1616
use crate::intrinsics;
17-
use crate::macros::const_assert;
1817
use crate::mem;
1918
use crate::num::FpCategory;
19+
use crate::panic::const_assert;
2020

2121
/// Basic mathematical constants.
2222
#[unstable(feature = "f16", issue = "116909")]

Diff for: library/core/src/num/f32.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
use crate::convert::FloatToInt;
1515
#[cfg(not(test))]
1616
use crate::intrinsics;
17-
use crate::macros::const_assert;
1817
use crate::mem;
1918
use crate::num::FpCategory;
19+
use crate::panic::const_assert;
2020

2121
/// The radix or base of the internal representation of `f32`.
2222
/// Use [`f32::RADIX`] instead.

Diff for: library/core/src/num/f64.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
use crate::convert::FloatToInt;
1515
#[cfg(not(test))]
1616
use crate::intrinsics;
17-
use crate::macros::const_assert;
1817
use crate::mem;
1918
use crate::num::FpCategory;
19+
use crate::panic::const_assert;
2020

2121
/// The radix or base of the internal representation of `f64`.
2222
/// Use [`f64::RADIX`] instead.

Diff for: library/core/src/num/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
#![stable(feature = "rust1", since = "1.0.0")]
44

5-
use crate::macros::const_panic;
5+
use crate::panic::const_panic;
66
use crate::str::FromStr;
77
use crate::ub_checks::assert_unsafe_precondition;
88
use crate::{ascii, intrinsics, mem};

Diff for: library/core/src/panic.rs

+56
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,59 @@ pub unsafe trait PanicPayload: crate::fmt::Display {
189189
None
190190
}
191191
}
192+
193+
/// Helper macro for panicking in a `const fn`.
194+
/// Invoke as:
195+
/// ```rust,ignore (just an example)
196+
/// core::macros::const_panic!("boring message", "flavored message {a} {b:?}", a: u32 = foo.len(), b: Something = bar);
197+
/// ```
198+
/// where the first message will be printed in const-eval,
199+
/// and the second message will be printed at runtime.
200+
// All uses of this macro are FIXME(const-hack).
201+
#[unstable(feature = "panic_internals", issue = "none")]
202+
#[doc(hidden)]
203+
pub macro const_panic {
204+
($const_msg:literal, $runtime_msg:literal, $($arg:ident : $ty:ty = $val:expr),* $(,)?) => {{
205+
// Wrap call to `const_eval_select` in a function so that we can
206+
// add the `rustc_allow_const_fn_unstable`. This is okay to do
207+
// because both variants will panic, just with different messages.
208+
#[rustc_allow_const_fn_unstable(const_eval_select)]
209+
#[inline(always)]
210+
#[track_caller]
211+
#[cfg_attr(bootstrap, rustc_const_stable(feature = "const_panic", since = "CURRENT_RUSTC_VERSION"))]
212+
const fn do_panic($($arg: $ty),*) -> ! {
213+
$crate::intrinsics::const_eval_select!(
214+
@capture { $($arg: $ty),* } -> !:
215+
if const #[track_caller] {
216+
$crate::panic!($const_msg)
217+
} else #[track_caller] {
218+
$crate::panic!($runtime_msg)
219+
}
220+
)
221+
}
222+
223+
do_panic($($val),*)
224+
}},
225+
// We support leaving away the `val` expressions for *all* arguments
226+
// (but not for *some* arguments, that's too tricky).
227+
($const_msg:literal, $runtime_msg:literal, $($arg:ident : $ty:ty),* $(,)?) => {
228+
$crate::panic::const_panic!(
229+
$const_msg,
230+
$runtime_msg,
231+
$($arg: $ty = $arg),*
232+
)
233+
},
234+
}
235+
236+
/// A version of `assert` that prints a non-formatting message in const contexts.
237+
///
238+
/// See [`const_panic!`].
239+
#[unstable(feature = "panic_internals", issue = "none")]
240+
#[doc(hidden)]
241+
pub macro const_assert {
242+
($condition: expr, $const_msg:literal, $runtime_msg:literal, $($arg:tt)*) => {{
243+
if !$crate::intrinsics::likely($condition) {
244+
$crate::panic::const_panic!($const_msg, $runtime_msg, $($arg)*)
245+
}
246+
}}
247+
}

Diff for: library/core/src/panicking.rs

+29-33
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
)]
3030

3131
use crate::fmt;
32+
use crate::intrinsics::const_eval_select;
3233
use crate::panic::{Location, PanicInfo};
3334

3435
#[cfg(feature = "panic_immediate_abort")]
@@ -89,40 +90,35 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
8990
#[cfg_attr(not(bootstrap), rustc_const_stable_indirect)] // must follow stable const rules since it is exposed to stable
9091
#[rustc_allow_const_fn_unstable(const_eval_select)]
9192
pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! {
92-
#[inline] // this should always be inlined into `panic_nounwind_fmt`
93-
#[track_caller]
94-
fn runtime(fmt: fmt::Arguments<'_>, force_no_backtrace: bool) -> ! {
95-
if cfg!(feature = "panic_immediate_abort") {
96-
super::intrinsics::abort()
93+
const_eval_select!(
94+
@capture { fmt: fmt::Arguments<'_>, force_no_backtrace: bool } -> !:
95+
if const #[track_caller] {
96+
// We don't unwind anyway at compile-time so we can call the regular `panic_fmt`.
97+
panic_fmt(fmt)
98+
} else #[track_caller] {
99+
if cfg!(feature = "panic_immediate_abort") {
100+
super::intrinsics::abort()
101+
}
102+
103+
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
104+
// that gets resolved to the `#[panic_handler]` function.
105+
extern "Rust" {
106+
#[lang = "panic_impl"]
107+
fn panic_impl(pi: &PanicInfo<'_>) -> !;
108+
}
109+
110+
// PanicInfo with the `can_unwind` flag set to false forces an abort.
111+
let pi = PanicInfo::new(
112+
&fmt,
113+
Location::caller(),
114+
/* can_unwind */ false,
115+
force_no_backtrace,
116+
);
117+
118+
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
119+
unsafe { panic_impl(&pi) }
97120
}
98-
99-
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
100-
// that gets resolved to the `#[panic_handler]` function.
101-
extern "Rust" {
102-
#[lang = "panic_impl"]
103-
fn panic_impl(pi: &PanicInfo<'_>) -> !;
104-
}
105-
106-
// PanicInfo with the `can_unwind` flag set to false forces an abort.
107-
let pi = PanicInfo::new(
108-
&fmt,
109-
Location::caller(),
110-
/* can_unwind */ false,
111-
force_no_backtrace,
112-
);
113-
114-
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
115-
unsafe { panic_impl(&pi) }
116-
}
117-
118-
#[inline]
119-
#[track_caller]
120-
const fn comptime(fmt: fmt::Arguments<'_>, _force_no_backtrace: bool) -> ! {
121-
// We don't unwind anyway at compile-time so we can call the regular `panic_fmt`.
122-
panic_fmt(fmt);
123-
}
124-
125-
super::intrinsics::const_eval_select((fmt, force_no_backtrace), comptime, runtime);
121+
)
126122
}
127123

128124
// Next we define a bunch of higher-level wrappers that all bottom out in the two core functions

0 commit comments

Comments
 (0)