5656
5757use crate :: marker:: DiscriminantKind ;
5858use crate :: marker:: Tuple ;
59- use crate :: mem:: { self , align_of} ;
59+ use crate :: mem:: align_of;
6060
6161pub mod mir;
6262pub mod simd;
@@ -1027,7 +1027,7 @@ extern "rust-intrinsic" {
10271027
10281028 /// The size of the referenced value in bytes.
10291029 ///
1030- /// The stabilized version of this intrinsic is [`mem::size_of_val`].
1030+ /// The stabilized version of this intrinsic is [`crate:: mem::size_of_val`].
10311031 #[ rustc_const_unstable( feature = "const_size_of_val" , issue = "46571" ) ]
10321032 #[ rustc_nounwind]
10331033 pub fn size_of_val < T : ?Sized > ( _: * const T ) -> usize ;
@@ -1107,7 +1107,7 @@ extern "rust-intrinsic" {
11071107
11081108 /// Moves a value out of scope without running drop glue.
11091109 ///
1110- /// This exists solely for [`mem::forget_unsized`]; normal `forget` uses
1110+ /// This exists solely for [`crate:: mem::forget_unsized`]; normal `forget` uses
11111111 /// `ManuallyDrop` instead.
11121112 ///
11131113 /// Note that, unlike most intrinsics, this is safe to call;
@@ -1233,7 +1233,7 @@ extern "rust-intrinsic" {
12331233 /// Depending on what the code is doing, the following alternatives are preferable to
12341234 /// pointer-to-integer transmutation:
12351235 /// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a
1236- /// type for that buffer, it can use [`MaybeUninit`][mem::MaybeUninit].
1236+ /// type for that buffer, it can use [`MaybeUninit`][crate:: mem::MaybeUninit].
12371237 /// - If the code actually wants to work on the address the pointer points to, it can use `as`
12381238 /// casts or [`ptr.addr()`][pointer::addr].
12391239 ///
@@ -2317,7 +2317,7 @@ extern "rust-intrinsic" {
23172317 /// Therefore, implementations must not require the user to uphold
23182318 /// any safety invariants.
23192319 ///
2320- /// The to-be-stabilized version of this intrinsic is [`mem::variant_count`].
2320+ /// The to-be-stabilized version of this intrinsic is [`crate:: mem::variant_count`].
23212321 #[ rustc_const_unstable( feature = "variant_count" , issue = "73662" ) ]
23222322 #[ rustc_safe_intrinsic]
23232323 #[ rustc_nounwind]
@@ -2569,6 +2569,19 @@ extern "rust-intrinsic" {
25692569 #[ rustc_nounwind]
25702570 pub fn is_val_statically_known < T : Copy > ( arg : T ) -> bool ;
25712571
2572+ /// Returns the value of `cfg!(debug_assertions)`, but after monomorphization instead of in
2573+ /// macro expansion.
2574+ ///
2575+ /// This always returns `false` in const eval and Miri. The interpreter provides better
2576+ /// diagnostics than the checks that this is used to implement. However, this means
2577+ /// you should only be using this intrinsic to guard requirements that, if violated,
2578+ /// immediately lead to UB. Otherwise, const-eval and Miri will miss out on those
2579+ /// checks entirely.
2580+ ///
2581+ /// Since this is evaluated after monomorphization, branching on this value can be used to
2582+ /// implement debug assertions that are included in the precompiled standard library, but can
2583+ /// be optimized out by builds that monomorphize the standard library code with debug
2584+ /// assertions disabled. This intrinsic is primarily used by [`assert_unsafe_precondition`].
25722585 #[ rustc_const_unstable( feature = "delayed_debug_assertions" , issue = "none" ) ]
25732586 #[ rustc_safe_intrinsic]
25742587 #[ cfg( not( bootstrap) ) ]
@@ -2597,7 +2610,7 @@ pub(crate) const fn debug_assertions() -> bool {
25972610/// These checks are behind a condition which is evaluated at codegen time, not expansion time like
25982611/// [`debug_assert`]. This means that a standard library built with optimizations and debug
25992612/// assertions disabled will have these checks optimized out of its monomorphizations, but if a
2600- /// a caller of the standard library has debug assertions enabled and monomorphizes an expansion of
2613+ /// caller of the standard library has debug assertions enabled and monomorphizes an expansion of
26012614/// this macro, that monomorphization will contain the check.
26022615///
26032616/// Since these checks cannot be optimized out in MIR, some care must be taken in both call and
@@ -2606,8 +2619,8 @@ pub(crate) const fn debug_assertions() -> bool {
26062619/// combination of properties ensures that the code for the checks is only compiled once, and has a
26072620/// minimal impact on the caller's code size.
26082621///
2609- /// Caller should also introducing any other `let` bindings or any code outside this macro in order
2610- /// to call it. Since the precompiled standard library is built with full debuginfo and these
2622+ /// Callers should also avoid introducing any other `let` bindings or any code outside this macro in
2623+ /// order to call it. Since the precompiled standard library is built with full debuginfo and these
26112624/// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough
26122625/// debuginfo to have a measurable compile-time impact on debug builds.
26132626///
@@ -2659,33 +2672,12 @@ pub(crate) fn is_valid_allocation_size(size: usize, len: usize) -> bool {
26592672 len <= max_len
26602673}
26612674
2662- pub ( crate ) fn is_nonoverlapping_mono (
2663- src : * const ( ) ,
2664- dst : * const ( ) ,
2665- size : usize ,
2666- count : usize ,
2667- ) -> bool {
2668- let src_usize = src. addr ( ) ;
2669- let dst_usize = dst. addr ( ) ;
2670- let Some ( size) = size. checked_mul ( count) else {
2671- crate :: panicking:: panic_nounwind (
2672- "is_nonoverlapping: `size_of::<T>() * count` overflows a usize" ,
2673- )
2674- } ;
2675- let diff = src_usize. abs_diff ( dst_usize) ;
2676- // If the absolute distance between the ptrs is at least as big as the size of the buffer,
2677- // they do not overlap.
2678- diff >= size
2679- }
2680-
26812675/// Checks whether the regions of memory starting at `src` and `dst` of size
2682- /// `count * size_of::<T>()` do *not* overlap.
2683- #[ inline]
2684- pub ( crate ) fn is_nonoverlapping < T > ( src : * const T , dst : * const T , count : usize ) -> bool {
2676+ /// `count * size` do *not* overlap.
2677+ pub ( crate ) fn is_nonoverlapping ( src : * const ( ) , dst : * const ( ) , size : usize , count : usize ) -> bool {
26852678 let src_usize = src. addr ( ) ;
26862679 let dst_usize = dst. addr ( ) ;
2687- let Some ( size) = mem:: size_of :: < T > ( ) . checked_mul ( count) else {
2688- // Use panic_nounwind instead of Option::expect, so that this function is nounwind.
2680+ let Some ( size) = size. checked_mul ( count) else {
26892681 crate :: panicking:: panic_nounwind (
26902682 "is_nonoverlapping: `size_of::<T>() * count` overflows a usize" ,
26912683 )
@@ -2809,7 +2801,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
28092801 ) =>
28102802 is_aligned_and_not_null( src, align)
28112803 && is_aligned_and_not_null( dst, align)
2812- && is_nonoverlapping_mono ( src, dst, size, count)
2804+ && is_nonoverlapping ( src, dst, size, count)
28132805 ) ;
28142806 copy_nonoverlapping ( src, dst, count)
28152807 }
0 commit comments