Skip to content

Commit d731552

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

File tree

13 files changed

+193
-197
lines changed

13 files changed

+193
-197
lines changed

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;

library/core/src/intrinsics.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2803,7 +2803,7 @@ where
28032803
pub(crate) macro const_eval_select {
28042804
(
28052805
$(#[$attr:meta])*
2806-
($($arg:ident : $ty:ty = $val:expr),* $(,)?) $( -> $ret:ty )?:
2806+
($($arg:ident : $ty:ty = $val:expr),* $(,)?) $( -> $ret:ty )? :
28072807
if const
28082808
$(#[$compiletime_attr:meta])* $compiletime:block
28092809
else
@@ -2830,15 +2830,15 @@ pub(crate) macro const_eval_select {
28302830
// (but not for *some* arguments, that's too tricky).
28312831
(
28322832
$(#[$attr:meta])*
2833-
($($arg:ident : $ty:ty),* $(,)?) -> $ret:ty:
2833+
($($arg:ident : $ty:ty),* $(,)?) $( -> $ret:ty )? :
28342834
if const
28352835
$(#[$compiletime_attr:meta])* $compiletime:block
28362836
else
28372837
$(#[$runtime_attr:meta])* $runtime:block
28382838
) => {
28392839
$crate::intrinsics::const_eval_select!(
28402840
$(#[$attr])*
2841-
($($arg : $ty = $arg),*) -> $ret:
2841+
($($arg : $ty = $arg),*) $(-> $ret)? :
28422842
if const
28432843
$(#[$compiletime_attr])* $compiletime
28442844
else

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

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")]

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")]

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.

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.

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};

library/core/src/panic.rs

+58
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,61 @@ 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+
#[inline]
215+
#[track_caller]
216+
($($arg: $ty),*) -> !:
217+
if const {
218+
$crate::panic!($const_msg)
219+
} else {
220+
$crate::panic!($runtime_msg)
221+
}
222+
)
223+
}
224+
225+
do_panic($($val),*)
226+
}},
227+
// We support leaving away the `val` expressions for *all* arguments
228+
// (but not for *some* arguments, that's too tricky).
229+
($const_msg:literal, $runtime_msg:literal, $($arg:ident : $ty:ty),* $(,)?) => {
230+
$crate::panic::const_panic!(
231+
$const_msg,
232+
$runtime_msg,
233+
$($arg: $ty = $arg),*
234+
)
235+
},
236+
}
237+
238+
/// A version of `assert` that prints a non-formatting message in const contexts.
239+
///
240+
/// See [`const_panic!`].
241+
#[unstable(feature = "panic_internals", issue = "none")]
242+
#[doc(hidden)]
243+
pub macro const_assert {
244+
($condition: expr, $const_msg:literal, $runtime_msg:literal, $($arg:tt)*) => {{
245+
if !$crate::intrinsics::likely($condition) {
246+
$crate::panic::const_panic!($const_msg, $runtime_msg, $($arg)*)
247+
}
248+
}}
249+
}

library/core/src/slice/ascii.rs

+75-77
Original file line numberDiff line numberDiff line change
@@ -351,89 +351,87 @@ pub const fn is_ascii_simple(mut bytes: &[u8]) -> bool {
351351
const fn is_ascii(s: &[u8]) -> bool {
352352
// The runtime version behaves the same as the compiletime version, it's
353353
// just more optimized.
354-
return const_eval_select((s,), compiletime, runtime);
355-
356-
const fn compiletime(s: &[u8]) -> bool {
357-
is_ascii_simple(s)
358-
}
359-
360-
#[inline]
361-
fn runtime(s: &[u8]) -> bool {
362-
const USIZE_SIZE: usize = mem::size_of::<usize>();
363-
364-
let len = s.len();
365-
let align_offset = s.as_ptr().align_offset(USIZE_SIZE);
366-
367-
// If we wouldn't gain anything from the word-at-a-time implementation, fall
368-
// back to a scalar loop.
369-
//
370-
// We also do this for architectures where `size_of::<usize>()` isn't
371-
// sufficient alignment for `usize`, because it's a weird edge case.
372-
if len < USIZE_SIZE || len < align_offset || USIZE_SIZE < mem::align_of::<usize>() {
373-
return is_ascii_simple(s);
374-
}
354+
const_eval_select!(
355+
(s: &[u8]) -> bool:
356+
if const {
357+
is_ascii_simple(s)
358+
} else #[inline] {
359+
const USIZE_SIZE: usize = mem::size_of::<usize>();
360+
361+
let len = s.len();
362+
let align_offset = s.as_ptr().align_offset(USIZE_SIZE);
363+
364+
// If we wouldn't gain anything from the word-at-a-time implementation, fall
365+
// back to a scalar loop.
366+
//
367+
// We also do this for architectures where `size_of::<usize>()` isn't
368+
// sufficient alignment for `usize`, because it's a weird edge case.
369+
if len < USIZE_SIZE || len < align_offset || USIZE_SIZE < mem::align_of::<usize>() {
370+
return is_ascii_simple(s);
371+
}
375372

376-
// We always read the first word unaligned, which means `align_offset` is
377-
// 0, we'd read the same value again for the aligned read.
378-
let offset_to_aligned = if align_offset == 0 { USIZE_SIZE } else { align_offset };
373+
// We always read the first word unaligned, which means `align_offset` is
374+
// 0, we'd read the same value again for the aligned read.
375+
let offset_to_aligned = if align_offset == 0 { USIZE_SIZE } else { align_offset };
379376

380-
let start = s.as_ptr();
381-
// SAFETY: We verify `len < USIZE_SIZE` above.
382-
let first_word = unsafe { (start as *const usize).read_unaligned() };
377+
let start = s.as_ptr();
378+
// SAFETY: We verify `len < USIZE_SIZE` above.
379+
let first_word = unsafe { (start as *const usize).read_unaligned() };
383380

384-
if contains_nonascii(first_word) {
385-
return false;
386-
}
387-
// We checked this above, somewhat implicitly. Note that `offset_to_aligned`
388-
// is either `align_offset` or `USIZE_SIZE`, both of are explicitly checked
389-
// above.
390-
debug_assert!(offset_to_aligned <= len);
391-
392-
// SAFETY: word_ptr is the (properly aligned) usize ptr we use to read the
393-
// middle chunk of the slice.
394-
let mut word_ptr = unsafe { start.add(offset_to_aligned) as *const usize };
395-
396-
// `byte_pos` is the byte index of `word_ptr`, used for loop end checks.
397-
let mut byte_pos = offset_to_aligned;
398-
399-
// Paranoia check about alignment, since we're about to do a bunch of
400-
// unaligned loads. In practice this should be impossible barring a bug in
401-
// `align_offset` though.
402-
// While this method is allowed to spuriously fail in CTFE, if it doesn't
403-
// have alignment information it should have given a `usize::MAX` for
404-
// `align_offset` earlier, sending things through the scalar path instead of
405-
// this one, so this check should pass if it's reachable.
406-
debug_assert!(word_ptr.is_aligned_to(mem::align_of::<usize>()));
407-
408-
// Read subsequent words until the last aligned word, excluding the last
409-
// aligned word by itself to be done in tail check later, to ensure that
410-
// tail is always one `usize` at most to extra branch `byte_pos == len`.
411-
while byte_pos < len - USIZE_SIZE {
412-
// Sanity check that the read is in bounds
413-
debug_assert!(byte_pos + USIZE_SIZE <= len);
414-
// And that our assumptions about `byte_pos` hold.
415-
debug_assert!(word_ptr.cast::<u8>() == start.wrapping_add(byte_pos));
416-
417-
// SAFETY: We know `word_ptr` is properly aligned (because of
418-
// `align_offset`), and we know that we have enough bytes between `word_ptr` and the end
419-
let word = unsafe { word_ptr.read() };
420-
if contains_nonascii(word) {
381+
if contains_nonascii(first_word) {
421382
return false;
422383
}
384+
// We checked this above, somewhat implicitly. Note that `offset_to_aligned`
385+
// is either `align_offset` or `USIZE_SIZE`, both of are explicitly checked
386+
// above.
387+
debug_assert!(offset_to_aligned <= len);
388+
389+
// SAFETY: word_ptr is the (properly aligned) usize ptr we use to read the
390+
// middle chunk of the slice.
391+
let mut word_ptr = unsafe { start.add(offset_to_aligned) as *const usize };
392+
393+
// `byte_pos` is the byte index of `word_ptr`, used for loop end checks.
394+
let mut byte_pos = offset_to_aligned;
395+
396+
// Paranoia check about alignment, since we're about to do a bunch of
397+
// unaligned loads. In practice this should be impossible barring a bug in
398+
// `align_offset` though.
399+
// While this method is allowed to spuriously fail in CTFE, if it doesn't
400+
// have alignment information it should have given a `usize::MAX` for
401+
// `align_offset` earlier, sending things through the scalar path instead of
402+
// this one, so this check should pass if it's reachable.
403+
debug_assert!(word_ptr.is_aligned_to(mem::align_of::<usize>()));
404+
405+
// Read subsequent words until the last aligned word, excluding the last
406+
// aligned word by itself to be done in tail check later, to ensure that
407+
// tail is always one `usize` at most to extra branch `byte_pos == len`.
408+
while byte_pos < len - USIZE_SIZE {
409+
// Sanity check that the read is in bounds
410+
debug_assert!(byte_pos + USIZE_SIZE <= len);
411+
// And that our assumptions about `byte_pos` hold.
412+
debug_assert!(word_ptr.cast::<u8>() == start.wrapping_add(byte_pos));
413+
414+
// SAFETY: We know `word_ptr` is properly aligned (because of
415+
// `align_offset`), and we know that we have enough bytes between `word_ptr` and the end
416+
let word = unsafe { word_ptr.read() };
417+
if contains_nonascii(word) {
418+
return false;
419+
}
420+
421+
byte_pos += USIZE_SIZE;
422+
// SAFETY: We know that `byte_pos <= len - USIZE_SIZE`, which means that
423+
// after this `add`, `word_ptr` will be at most one-past-the-end.
424+
word_ptr = unsafe { word_ptr.add(1) };
425+
}
423426

424-
byte_pos += USIZE_SIZE;
425-
// SAFETY: We know that `byte_pos <= len - USIZE_SIZE`, which means that
426-
// after this `add`, `word_ptr` will be at most one-past-the-end.
427-
word_ptr = unsafe { word_ptr.add(1) };
428-
}
429-
430-
// Sanity check to ensure there really is only one `usize` left. This should
431-
// be guaranteed by our loop condition.
432-
debug_assert!(byte_pos <= len && len - byte_pos <= USIZE_SIZE);
427+
// Sanity check to ensure there really is only one `usize` left. This should
428+
// be guaranteed by our loop condition.
429+
debug_assert!(byte_pos <= len && len - byte_pos <= USIZE_SIZE);
433430

434-
// SAFETY: This relies on `len >= USIZE_SIZE`, which we check at the start.
435-
let last_word = unsafe { (start.add(len - USIZE_SIZE) as *const usize).read_unaligned() };
431+
// SAFETY: This relies on `len >= USIZE_SIZE`, which we check at the start.
432+
let last_word = unsafe { (start.add(len - USIZE_SIZE) as *const usize).read_unaligned() };
436433

437-
!contains_nonascii(last_word)
438-
}
434+
!contains_nonascii(last_word)
435+
}
436+
)
439437
}

library/core/src/slice/index.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Indexing implementations for `[T]`.
22
3-
use crate::macros::const_panic;
3+
use crate::panic::const_panic;
44
use crate::ub_checks::assert_unsafe_precondition;
55
use crate::{ops, range};
66

0 commit comments

Comments
 (0)