diff options
Diffstat (limited to 'library/core/src')
| -rw-r--r-- | library/core/src/alloc/layout.rs | 1 | ||||
| -rw-r--r-- | library/core/src/ascii/ascii_char.rs | 1 | ||||
| -rw-r--r-- | library/core/src/char/convert.rs | 1 | ||||
| -rw-r--r-- | library/core/src/hint.rs | 2 | ||||
| -rw-r--r-- | library/core/src/intrinsics/mod.rs | 31 | ||||
| -rw-r--r-- | library/core/src/lib.rs | 3 | ||||
| -rw-r--r-- | library/core/src/macros/mod.rs | 43 | ||||
| -rw-r--r-- | library/core/src/num/int_macros.rs | 12 | ||||
| -rw-r--r-- | library/core/src/num/nonzero.rs | 2 | ||||
| -rw-r--r-- | library/core/src/num/uint_macros.rs | 10 | ||||
| -rw-r--r-- | library/core/src/ops/index_range.rs | 1 | ||||
| -rw-r--r-- | library/core/src/option.rs | 30 | ||||
| -rw-r--r-- | library/core/src/ptr/alignment.rs | 1 | ||||
| -rw-r--r-- | library/core/src/ptr/const_ptr.rs | 26 | ||||
| -rw-r--r-- | library/core/src/ptr/mod.rs | 14 | ||||
| -rw-r--r-- | library/core/src/ptr/mut_ptr.rs | 38 | ||||
| -rw-r--r-- | library/core/src/ptr/non_null.rs | 1 | ||||
| -rw-r--r-- | library/core/src/result.rs | 30 | ||||
| -rw-r--r-- | library/core/src/slice/index.rs | 6 | ||||
| -rw-r--r-- | library/core/src/slice/mod.rs | 8 | ||||
| -rw-r--r-- | library/core/src/slice/raw.rs | 3 | ||||
| -rw-r--r-- | library/core/src/str/traits.rs | 4 | ||||
| -rw-r--r-- | library/core/src/ub_checks.rs | 6 | 
23 files changed, 189 insertions, 85 deletions
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs index e8a03aadc33..380f67f91f9 100644 --- a/library/core/src/alloc/layout.rs +++ b/library/core/src/alloc/layout.rs @@ -126,6 +126,7 @@ impl Layout { #[rustc_const_stable(feature = "const_alloc_layout_unchecked", since = "1.36.0")] #[must_use] #[inline] + #[track_caller] pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self { assert_unsafe_precondition!( check_library_ub, diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs index 48de4f17b1b..0b72b4780f1 100644 --- a/library/core/src/ascii/ascii_char.rs +++ b/library/core/src/ascii/ascii_char.rs @@ -503,6 +503,7 @@ impl AsciiChar { /// something useful. It might be tightened before stabilization.) #[unstable(feature = "ascii_char", issue = "110998")] #[inline] + #[track_caller] pub const unsafe fn digit_unchecked(d: u8) -> Self { assert_unsafe_precondition!( check_language_ub, diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs index fd17f92f7be..78cd89fefae 100644 --- a/library/core/src/char/convert.rs +++ b/library/core/src/char/convert.rs @@ -22,6 +22,7 @@ pub(super) const fn from_u32(i: u32) -> Option<char> { #[inline] #[must_use] #[allow(unnecessary_transmutes)] +#[track_caller] pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char { // SAFETY: the caller must guarantee that `i` is a valid char value. unsafe { diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index 8ea9de7e9e5..696d323c66d 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -98,7 +98,7 @@ use crate::{intrinsics, ub_checks}; #[inline] #[stable(feature = "unreachable", since = "1.27.0")] #[rustc_const_stable(feature = "const_unreachable_unchecked", since = "1.57.0")] -#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[track_caller] pub const unsafe fn unreachable_unchecked() -> ! { ub_checks::assert_unsafe_precondition!( check_language_ub, diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 23bafa778bc..32642a13b42 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -1,7 +1,10 @@ //! Compiler intrinsics. //! -//! The corresponding definitions are in <https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/intrinsic.rs>. -//! The corresponding const implementations are in <https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/intrinsics.rs>. +//! These are the imports making intrinsics available to Rust code. The actual implementations live in the compiler. +//! Some of these intrinsics are lowered to MIR in <https://github.com/rust-lang/rust/blob/master/compiler/rustc_mir_transform/src/lower_intrinsics.rs>. +//! The remaining intrinsics are implemented for the LLVM backend in <https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs> +//! and <https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/intrinsic.rs>, +//! and for const evaluation in <https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/intrinsics.rs>. //! //! # Const intrinsics //! @@ -20,28 +23,14 @@ //! //! The volatile intrinsics provide operations intended to act on I/O //! memory, which are guaranteed to not be reordered by the compiler -//! across other volatile intrinsics. See the LLVM documentation on -//! [[volatile]]. -//! -//! [volatile]: https://llvm.org/docs/LangRef.html#volatile-memory-accesses +//! across other volatile intrinsics. See [`read_volatile`][ptr::read_volatile] +//! and [`write_volatile`][ptr::write_volatile]. //! //! # Atomics //! //! The atomic intrinsics provide common atomic operations on machine -//! words, with multiple possible memory orderings. They obey the same -//! semantics as C++11. See the LLVM documentation on [[atomics]]. -//! -//! [atomics]: https://llvm.org/docs/Atomics.html -//! -//! A quick refresher on memory ordering: -//! -//! * Acquire - a barrier for acquiring a lock. Subsequent reads and writes -//! take place after the barrier. -//! * Release - a barrier for releasing a lock. Preceding reads and writes -//! take place before the barrier. -//! * Sequentially consistent - sequentially consistent operations are -//! guaranteed to happen in order. This is the standard mode for working -//! with atomic types and is equivalent to Java's `volatile`. +//! words, with multiple possible memory orderings. See the +//! [atomic types][crate::sync::atomic] docs for details. //! //! # Unwinding //! @@ -2634,7 +2623,7 @@ pub const fn three_way_compare<T: Copy>(lhs: T, rhss: T) -> crate::cmp::Ordering #[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")] #[rustc_nounwind] #[rustc_intrinsic] -#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[track_caller] #[miri::intrinsic_fallback_is_spec] // the fallbacks all `assume` to tell Miri pub const unsafe fn disjoint_bitor<T: ~const fallback::DisjointBitOr>(a: T, b: T) -> T { // SAFETY: same preconditions as this function. diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index c49513f7a6d..989ab80b77d 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -225,10 +225,11 @@ pub mod assert_matches { // We don't export this through #[macro_export] for now, to avoid breakage. #[unstable(feature = "autodiff", issue = "124509")] +#[cfg(not(bootstrap))] /// Unstable module containing the unstable `autodiff` macro. pub mod autodiff { #[unstable(feature = "autodiff", issue = "124509")] - pub use crate::macros::builtin::autodiff; + pub use crate::macros::builtin::{autodiff_forward, autodiff_reverse}; } #[unstable(feature = "contracts", issue = "128044")] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 4742add0957..e70a1dab6e9 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -1519,20 +1519,41 @@ pub(crate) mod builtin { ($file:expr $(,)?) => {{ /* compiler built-in */ }}; } - /// Automatic Differentiation macro which allows generating a new function to compute - /// the derivative of a given function. It may only be applied to a function. - /// The expected usage syntax is - /// `#[autodiff(NAME, MODE, INPUT_ACTIVITIES, OUTPUT_ACTIVITY)]` - /// where: - /// NAME is a string that represents a valid function name. - /// MODE is any of Forward, Reverse, ForwardFirst, ReverseFirst. - /// INPUT_ACTIVITIES consists of one valid activity for each input parameter. - /// OUTPUT_ACTIVITY must not be set if we implicitly return nothing (or explicitly return - /// `-> ()`). Otherwise it must be set to one of the allowed activities. + /// This macro uses forward-mode automatic differentiation to generate a new function. + /// It may only be applied to a function. The new function will compute the derivative + /// of the function to which the macro was applied. + /// + /// The expected usage syntax is: + /// `#[autodiff_forward(NAME, INPUT_ACTIVITIES, OUTPUT_ACTIVITY)]` + /// + /// - `NAME`: A string that represents a valid function name. + /// - `INPUT_ACTIVITIES`: Specifies one valid activity for each input parameter. + /// - `OUTPUT_ACTIVITY`: Must not be set if the function implicitly returns nothing + /// (or explicitly returns `-> ()`). Otherwise, it must be set to one of the allowed activities. + #[unstable(feature = "autodiff", issue = "124509")] + #[allow_internal_unstable(rustc_attrs)] + #[rustc_builtin_macro] + #[cfg(not(bootstrap))] + pub macro autodiff_forward($item:item) { + /* compiler built-in */ + } + + /// This macro uses reverse-mode automatic differentiation to generate a new function. + /// It may only be applied to a function. The new function will compute the derivative + /// of the function to which the macro was applied. + /// + /// The expected usage syntax is: + /// `#[autodiff_reverse(NAME, INPUT_ACTIVITIES, OUTPUT_ACTIVITY)]` + /// + /// - `NAME`: A string that represents a valid function name. + /// - `INPUT_ACTIVITIES`: Specifies one valid activity for each input parameter. + /// - `OUTPUT_ACTIVITY`: Must not be set if the function implicitly returns nothing + /// (or explicitly returns `-> ()`). Otherwise, it must be set to one of the allowed activities. #[unstable(feature = "autodiff", issue = "124509")] #[allow_internal_unstable(rustc_attrs)] #[rustc_builtin_macro] - pub macro autodiff($item:item) { + #[cfg(not(bootstrap))] + pub macro autodiff_reverse($item:item) { /* compiler built-in */ } diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 84e1482ed31..f320a194271 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -555,7 +555,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { assert_unsafe_precondition!( check_language_ub, @@ -705,7 +705,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { assert_unsafe_precondition!( check_language_ub, @@ -855,7 +855,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { assert_unsafe_precondition!( check_language_ub, @@ -1199,7 +1199,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_neg(self) -> Self { assert_unsafe_precondition!( check_language_ub, @@ -1327,7 +1327,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { assert_unsafe_precondition!( check_language_ub, @@ -1448,7 +1448,7 @@ macro_rules! int_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { assert_unsafe_precondition!( check_language_ub, diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 8a8b2733d5e..a279f002772 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -388,6 +388,7 @@ where #[rustc_const_stable(feature = "nonzero", since = "1.28.0")] #[must_use] #[inline] + #[track_caller] pub const unsafe fn new_unchecked(n: T) -> Self { match Self::new(n) { Some(n) => n, @@ -428,6 +429,7 @@ where #[unstable(feature = "nonzero_from_mut", issue = "106290")] #[must_use] #[inline] + #[track_caller] pub unsafe fn from_mut_unchecked(n: &mut T) -> &mut Self { match Self::from_mut(n) { Some(n) => n, diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index f38d809c154..10597854ff8 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -601,7 +601,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_add(self, rhs: Self) -> Self { assert_unsafe_precondition!( check_language_ub, @@ -791,7 +791,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_sub(self, rhs: Self) -> Self { assert_unsafe_precondition!( check_language_ub, @@ -974,7 +974,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_mul(self, rhs: Self) -> Self { assert_unsafe_precondition!( check_language_ub, @@ -1588,7 +1588,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self { assert_unsafe_precondition!( check_language_ub, @@ -1709,7 +1709,7 @@ macro_rules! uint_impl { #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self { assert_unsafe_precondition!( check_language_ub, diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs index c645c996eb7..507fa9460be 100644 --- a/library/core/src/ops/index_range.rs +++ b/library/core/src/ops/index_range.rs @@ -19,6 +19,7 @@ impl IndexRange { /// # Safety /// - `start <= end` #[inline] + #[track_caller] pub(crate) const unsafe fn new_unchecked(start: usize, end: usize) -> Self { ub_checks::assert_unsafe_precondition!( check_library_ub, diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 1d264b26076..675556b07a8 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1253,6 +1253,36 @@ impl<T> Option<T> { } } + /// Maps an `Option<T>` to a `U` by applying function `f` to the contained + /// value if the option is [`Some`], otherwise if [`None`], returns the + /// [default value] for the type `U`. + /// + /// # Examples + /// + /// ``` + /// #![feature(result_option_map_or_default)] + /// + /// let x: Option<&str> = Some("hi"); + /// let y: Option<&str> = None; + /// + /// assert_eq!(x.map_or_default(|x| x.len()), 2); + /// assert_eq!(y.map_or_default(|y| y.len()), 0); + /// ``` + /// + /// [default value]: Default::default + #[inline] + #[unstable(feature = "result_option_map_or_default", issue = "138099")] + pub fn map_or_default<U, F>(self, f: F) -> U + where + U: Default, + F: FnOnce(T) -> U, + { + match self { + Some(t) => f(t), + None => U::default(), + } + } + /// Transforms the `Option<T>` into a [`Result<T, E>`], mapping [`Some(v)`] to /// [`Ok(v)`] and [`None`] to [`Err(err)`]. /// diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs index 19311e39b45..3e66e271f03 100644 --- a/library/core/src/ptr/alignment.rs +++ b/library/core/src/ptr/alignment.rs @@ -73,6 +73,7 @@ impl Alignment { /// It must *not* be zero. #[unstable(feature = "ptr_alignment_type", issue = "102070")] #[inline] + #[track_caller] pub const unsafe fn new_unchecked(align: usize) -> Self { assert_unsafe_precondition!( check_language_ub, diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs index 19ed7599a51..31267bfb1f9 100644 --- a/library/core/src/ptr/const_ptr.rs +++ b/library/core/src/ptr/const_ptr.rs @@ -442,7 +442,7 @@ impl<T: ?Sized> *const T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn offset(self, count: isize) -> *const T where T: Sized, @@ -495,7 +495,7 @@ impl<T: ?Sized> *const T { #[inline(always)] #[stable(feature = "pointer_byte_offsets", since = "1.75.0")] #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn byte_offset(self, count: isize) -> Self { // SAFETY: the caller must uphold the safety contract for `offset`. unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) } @@ -794,7 +794,7 @@ impl<T: ?Sized> *const T { #[stable(feature = "ptr_sub_ptr", since = "1.87.0")] #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")] #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize where T: Sized, @@ -839,7 +839,7 @@ impl<T: ?Sized> *const T { #[stable(feature = "ptr_sub_ptr", since = "1.87.0")] #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")] #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn byte_offset_from_unsigned<U: ?Sized>(self, origin: *const U) -> usize { // SAFETY: the caller must uphold the safety contract for `offset_from_unsigned`. unsafe { self.cast::<u8>().offset_from_unsigned(origin.cast::<u8>()) } @@ -953,7 +953,7 @@ impl<T: ?Sized> *const T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn add(self, count: usize) -> Self where T: Sized, @@ -1005,7 +1005,7 @@ impl<T: ?Sized> *const T { #[inline(always)] #[stable(feature = "pointer_byte_offsets", since = "1.75.0")] #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn byte_add(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `add`. unsafe { self.cast::<u8>().add(count).with_metadata_of(self) } @@ -1059,7 +1059,7 @@ impl<T: ?Sized> *const T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, @@ -1117,7 +1117,7 @@ impl<T: ?Sized> *const T { #[inline(always)] #[stable(feature = "pointer_byte_offsets", since = "1.75.0")] #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn byte_sub(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `sub`. unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) } @@ -1290,7 +1290,7 @@ impl<T: ?Sized> *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn read(self) -> T where T: Sized, @@ -1311,7 +1311,7 @@ impl<T: ?Sized> *const T { /// [`ptr::read_volatile`]: crate::ptr::read_volatile() #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub unsafe fn read_volatile(self) -> T where T: Sized, @@ -1331,7 +1331,7 @@ impl<T: ?Sized> *const T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn read_unaligned(self) -> T where T: Sized, @@ -1351,7 +1351,7 @@ impl<T: ?Sized> *const T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn copy_to(self, dest: *mut T, count: usize) where T: Sized, @@ -1371,7 +1371,7 @@ impl<T: ?Sized> *const T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) where T: Sized, diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 35a909f6904..99c4211cea8 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1377,6 +1377,7 @@ pub const unsafe fn swap<T>(x: *mut T, y: *mut T) { #[rustc_const_stable(feature = "const_swap_nonoverlapping", since = "1.88.0")] #[rustc_diagnostic_item = "ptr_swap_nonoverlapping"] #[rustc_allow_const_fn_unstable(const_eval_select)] // both implementations behave the same +#[track_caller] pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) { ub_checks::assert_unsafe_precondition!( check_library_ub, @@ -1557,6 +1558,7 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, bytes: NonZero<usize #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_replace", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_replace"] +#[track_caller] pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T { // SAFETY: the caller must guarantee that `dst` is valid to be // cast to a mutable reference (valid for writes, aligned, initialized), @@ -1684,7 +1686,7 @@ pub const unsafe fn replace<T>(dst: *mut T, src: T) -> T { #[inline] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] -#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[track_caller] #[rustc_diagnostic_item = "ptr_read"] pub const unsafe fn read<T>(src: *const T) -> T { // It would be semantically correct to implement this via `copy_nonoverlapping` @@ -1802,7 +1804,7 @@ pub const unsafe fn read<T>(src: *const T) -> T { #[inline] #[stable(feature = "ptr_unaligned", since = "1.17.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] -#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[track_caller] #[rustc_diagnostic_item = "ptr_read_unaligned"] pub const unsafe fn read_unaligned<T>(src: *const T) -> T { let mut tmp = MaybeUninit::<T>::uninit(); @@ -1901,7 +1903,7 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_write"] -#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[track_caller] pub const unsafe fn write<T>(dst: *mut T, src: T) { // Semantically, it would be fine for this to be implemented as a // `copy_nonoverlapping` and appropriate drop suppression of `src`. @@ -2005,7 +2007,7 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) { #[stable(feature = "ptr_unaligned", since = "1.17.0")] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[rustc_diagnostic_item = "ptr_write_unaligned"] -#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[track_caller] pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) { // SAFETY: the caller must guarantee that `dst` is valid for writes. // `dst` cannot overlap `src` because the caller has mutable access @@ -2079,7 +2081,7 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) { /// ``` #[inline] #[stable(feature = "volatile", since = "1.9.0")] -#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[track_caller] #[rustc_diagnostic_item = "ptr_read_volatile"] pub unsafe fn read_volatile<T>(src: *const T) -> T { // SAFETY: the caller must uphold the safety contract for `volatile_load`. @@ -2160,7 +2162,7 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T { #[inline] #[stable(feature = "volatile", since = "1.9.0")] #[rustc_diagnostic_item = "ptr_write_volatile"] -#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces +#[track_caller] pub unsafe fn write_volatile<T>(dst: *mut T, src: T) { // SAFETY: the caller must uphold the safety contract for `volatile_store`. unsafe { diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs index 53aa3ab4938..b1b3379d741 100644 --- a/library/core/src/ptr/mut_ptr.rs +++ b/library/core/src/ptr/mut_ptr.rs @@ -438,7 +438,7 @@ impl<T: ?Sized> *mut T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn offset(self, count: isize) -> *mut T where T: Sized, @@ -493,7 +493,7 @@ impl<T: ?Sized> *mut T { #[inline(always)] #[stable(feature = "pointer_byte_offsets", since = "1.75.0")] #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn byte_offset(self, count: isize) -> Self { // SAFETY: the caller must uphold the safety contract for `offset`. unsafe { self.cast::<u8>().offset(count).with_metadata_of(self) } @@ -968,7 +968,7 @@ impl<T: ?Sized> *mut T { #[stable(feature = "ptr_sub_ptr", since = "1.87.0")] #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")] #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn offset_from_unsigned(self, origin: *const T) -> usize where T: Sized, @@ -990,7 +990,7 @@ impl<T: ?Sized> *mut T { #[stable(feature = "ptr_sub_ptr", since = "1.87.0")] #[rustc_const_stable(feature = "const_ptr_sub_ptr", since = "1.87.0")] #[inline] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn byte_offset_from_unsigned<U: ?Sized>(self, origin: *mut U) -> usize { // SAFETY: the caller must uphold the safety contract for `byte_offset_from_unsigned`. unsafe { (self as *const T).byte_offset_from_unsigned(origin) } @@ -1044,7 +1044,7 @@ impl<T: ?Sized> *mut T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn add(self, count: usize) -> Self where T: Sized, @@ -1096,7 +1096,7 @@ impl<T: ?Sized> *mut T { #[inline(always)] #[stable(feature = "pointer_byte_offsets", since = "1.75.0")] #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn byte_add(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `add`. unsafe { self.cast::<u8>().add(count).with_metadata_of(self) } @@ -1150,7 +1150,7 @@ impl<T: ?Sized> *mut T { #[must_use = "returns a new pointer rather than modifying its argument"] #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn sub(self, count: usize) -> Self where T: Sized, @@ -1208,7 +1208,7 @@ impl<T: ?Sized> *mut T { #[inline(always)] #[stable(feature = "pointer_byte_offsets", since = "1.75.0")] #[rustc_const_stable(feature = "const_pointer_byte_offsets", since = "1.75.0")] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn byte_sub(self, count: usize) -> Self { // SAFETY: the caller must uphold the safety contract for `sub`. unsafe { self.cast::<u8>().sub(count).with_metadata_of(self) } @@ -1375,7 +1375,7 @@ impl<T: ?Sized> *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn read(self) -> T where T: Sized, @@ -1396,7 +1396,7 @@ impl<T: ?Sized> *mut T { /// [`ptr::read_volatile`]: crate::ptr::read_volatile() #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub unsafe fn read_volatile(self) -> T where T: Sized, @@ -1416,7 +1416,7 @@ impl<T: ?Sized> *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn read_unaligned(self) -> T where T: Sized, @@ -1436,7 +1436,7 @@ impl<T: ?Sized> *mut T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn copy_to(self, dest: *mut T, count: usize) where T: Sized, @@ -1456,7 +1456,7 @@ impl<T: ?Sized> *mut T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) where T: Sized, @@ -1476,7 +1476,7 @@ impl<T: ?Sized> *mut T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn copy_from(self, src: *const T, count: usize) where T: Sized, @@ -1496,7 +1496,7 @@ impl<T: ?Sized> *mut T { #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")] #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn copy_from_nonoverlapping(self, src: *const T, count: usize) where T: Sized, @@ -1526,7 +1526,7 @@ impl<T: ?Sized> *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn write(self, val: T) where T: Sized, @@ -1545,7 +1545,7 @@ impl<T: ?Sized> *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn write_bytes(self, val: u8, count: usize) where T: Sized, @@ -1566,7 +1566,7 @@ impl<T: ?Sized> *mut T { /// [`ptr::write_volatile`]: crate::ptr::write_volatile() #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub unsafe fn write_volatile(self, val: T) where T: Sized, @@ -1586,7 +1586,7 @@ impl<T: ?Sized> *mut T { #[stable(feature = "pointer_methods", since = "1.26.0")] #[rustc_const_stable(feature = "const_ptr_write", since = "1.83.0")] #[inline(always)] - #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces + #[track_caller] pub const unsafe fn write_unaligned(self, val: T) where T: Sized, diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index 7c9b898f8e9..226b5229f17 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -216,6 +216,7 @@ impl<T: ?Sized> NonNull<T> { #[stable(feature = "nonnull", since = "1.25.0")] #[rustc_const_stable(feature = "const_nonnull_new_unchecked", since = "1.25.0")] #[inline] + #[track_caller] pub const unsafe fn new_unchecked(ptr: *mut T) -> Self { // SAFETY: the caller must guarantee that `ptr` is non-null. unsafe { diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 736ffb7d0ca..ef2da5e8fbf 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -858,6 +858,36 @@ impl<T, E> Result<T, E> { } } + /// Maps a `Result<T, E>` to a `U` by applying function `f` to the contained + /// value if the result is [`Ok`], otherwise if [`Err`], returns the + /// [default value] for the type `U`. + /// + /// # Examples + /// + /// ``` + /// #![feature(result_option_map_or_default)] + /// + /// let x: Result<_, &str> = Ok("foo"); + /// let y: Result<&str, _> = Err("bar"); + /// + /// assert_eq!(x.map_or_default(|x| x.len()), 3); + /// assert_eq!(y.map_or_default(|y| y.len()), 0); + /// ``` + /// + /// [default value]: Default::default + #[inline] + #[unstable(feature = "result_option_map_or_default", issue = "138099")] + pub fn map_or_default<U, F>(self, f: F) -> U + where + U: Default, + F: FnOnce(T) -> U, + { + match self { + Ok(t) => f(t), + Err(_) => U::default(), + } + } + /// Maps a `Result<T, E>` to `Result<T, F>` by applying a function to a /// contained [`Err`] value, leaving an [`Ok`] value untouched. /// diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 409bad9f061..b18d316c73a 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -239,6 +239,7 @@ unsafe impl<T> SliceIndex<[T]> for usize { } #[inline] + #[track_caller] unsafe fn get_unchecked(self, slice: *const [T]) -> *const T { assert_unsafe_precondition!( check_language_ub, @@ -258,6 +259,7 @@ unsafe impl<T> SliceIndex<[T]> for usize { } #[inline] + #[track_caller] unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T { assert_unsafe_precondition!( check_library_ub, @@ -307,6 +309,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange { } #[inline] + #[track_caller] unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { assert_unsafe_precondition!( check_library_ub, @@ -321,6 +324,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange { } #[inline] + #[track_caller] unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { assert_unsafe_precondition!( check_library_ub, @@ -386,6 +390,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { } #[inline] + #[track_caller] unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] { assert_unsafe_precondition!( check_library_ub, @@ -410,6 +415,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { } #[inline] + #[track_caller] unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] { assert_unsafe_precondition!( check_library_ub, diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 26520123a8d..4f7e1440880 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -631,6 +631,7 @@ impl<T> [T] { #[rustc_no_implicit_autorefs] #[inline] #[must_use] + #[track_caller] pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output where I: SliceIndex<Self>, @@ -674,6 +675,7 @@ impl<T> [T] { #[rustc_no_implicit_autorefs] #[inline] #[must_use] + #[track_caller] pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output where I: SliceIndex<Self>, @@ -935,6 +937,7 @@ impl<T> [T] { /// [`swap`]: slice::swap /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html #[unstable(feature = "slice_swap_unchecked", issue = "88539")] + #[track_caller] pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) { assert_unsafe_precondition!( check_library_ub, @@ -1307,6 +1310,7 @@ impl<T> [T] { #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")] #[inline] #[must_use] + #[track_caller] pub const unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]] { assert_unsafe_precondition!( check_language_ub, @@ -1502,6 +1506,7 @@ impl<T> [T] { #[rustc_const_stable(feature = "slice_as_chunks", since = "1.88.0")] #[inline] #[must_use] + #[track_caller] pub const unsafe fn as_chunks_unchecked_mut<const N: usize>(&mut self) -> &mut [[T; N]] { assert_unsafe_precondition!( check_language_ub, @@ -2061,6 +2066,7 @@ impl<T> [T] { #[rustc_const_stable(feature = "const_slice_split_at_unchecked", since = "1.77.0")] #[inline] #[must_use] + #[track_caller] pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) { // FIXME(const-hack): the const function `from_raw_parts` is used to make this // function const; previously the implementation used @@ -2114,6 +2120,7 @@ impl<T> [T] { #[rustc_const_stable(feature = "const_slice_split_at_mut", since = "1.83.0")] #[inline] #[must_use] + #[track_caller] pub const unsafe fn split_at_mut_unchecked(&mut self, mid: usize) -> (&mut [T], &mut [T]) { let len = self.len(); let ptr = self.as_mut_ptr(); @@ -4642,6 +4649,7 @@ impl<T> [T] { /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html #[stable(feature = "get_many_mut", since = "1.86.0")] #[inline] + #[track_caller] pub unsafe fn get_disjoint_unchecked_mut<I, const N: usize>( &mut self, indices: [I; N], diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 3582c7e8b3f..40da69c1562 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -120,6 +120,7 @@ use crate::{array, ptr, ub_checks}; #[rustc_const_stable(feature = "const_slice_from_raw_parts", since = "1.64.0")] #[must_use] #[rustc_diagnostic_item = "slice_from_raw_parts"] +#[track_caller] pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] { // SAFETY: the caller must uphold the safety contract for `from_raw_parts`. unsafe { @@ -174,6 +175,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] #[rustc_const_stable(feature = "const_slice_from_raw_parts_mut", since = "1.83.0")] #[must_use] #[rustc_diagnostic_item = "slice_from_raw_parts_mut"] +#[track_caller] pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] { // SAFETY: the caller must uphold the safety contract for `from_raw_parts_mut`. unsafe { @@ -270,6 +272,7 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T] { /// [valid]: ptr#safety #[unstable(feature = "slice_from_ptr_range", issue = "89792")] #[rustc_const_unstable(feature = "const_slice_from_ptr_range", issue = "89792")] +#[track_caller] pub const unsafe fn from_ptr_range<'a, T>(range: Range<*const T>) -> &'a [T] { // SAFETY: the caller must uphold the safety contract for `from_ptr_range`. unsafe { from_raw_parts(range.start, range.end.offset_from_unsigned(range.start)) } diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index 77c70b978fd..4baf9aacad7 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -186,6 +186,7 @@ unsafe impl SliceIndex<str> for ops::Range<usize> { } } #[inline] + #[track_caller] unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { let slice = slice as *const [u8]; @@ -213,6 +214,7 @@ unsafe impl SliceIndex<str> for ops::Range<usize> { } } #[inline] + #[track_caller] unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { let slice = slice as *mut [u8]; @@ -288,6 +290,7 @@ unsafe impl SliceIndex<str> for range::Range<usize> { } } #[inline] + #[track_caller] unsafe fn get_unchecked(self, slice: *const str) -> *const Self::Output { let slice = slice as *const [u8]; @@ -315,6 +318,7 @@ unsafe impl SliceIndex<str> for range::Range<usize> { } } #[inline] + #[track_caller] unsafe fn get_unchecked_mut(self, slice: *mut str) -> *mut Self::Output { let slice = slice as *mut [u8]; diff --git a/library/core/src/ub_checks.rs b/library/core/src/ub_checks.rs index 9eb71922218..a7caaeb95cd 100644 --- a/library/core/src/ub_checks.rs +++ b/library/core/src/ub_checks.rs @@ -63,11 +63,13 @@ macro_rules! assert_unsafe_precondition { #[rustc_no_mir_inline] #[inline] #[rustc_nounwind] + #[track_caller] const fn precondition_check($($name:$ty),*) { if !$e { - ::core::panicking::panic_nounwind(concat!("unsafe precondition(s) violated: ", $message, + let msg = concat!("unsafe precondition(s) violated: ", $message, "\n\nThis indicates a bug in the program. \ - This Undefined Behavior check is optional, and cannot be relied on for safety.")); + This Undefined Behavior check is optional, and cannot be relied on for safety."); + ::core::panicking::panic_nounwind_fmt(::core::fmt::Arguments::new_const(&[msg]), false); } }  | 
