5656
5757use crate :: marker:: DiscriminantKind ;
5858use crate :: marker:: Tuple ;
59- use crate :: mem:: { self , align_of} ;
59+ #[ cfg( doc) ]
60+ use crate :: mem;
61+ use crate :: mem:: align_of;
6062
6163pub mod mir;
6264pub mod simd;
@@ -2569,6 +2571,16 @@ extern "rust-intrinsic" {
25692571 #[ rustc_nounwind]
25702572 pub fn is_val_statically_known < T : Copy > ( arg : T ) -> bool ;
25712573
2574+ /// Returns the value of `cfg!(debug_assertions)`, but after monomorphization instead of in
2575+ /// macro expansion.
2576+ ///
2577+ /// This always returns `false` in const eval (including Miri). The interpreter provides better
2578+ /// diagnostics than the checks that this is used to implement.
2579+ ///
2580+ /// Since this is evaluated after monomorphization, branching on this value can be used to
2581+ /// implement debug assertions that are included in the precompiled standard library, but can
2582+ /// be optimized out by builds that monomorphize the standard library code with debug
2583+ /// assertions disabled. This intrinsic is primarily used by [`assert_unsafe_precondition`].
25722584 #[ rustc_const_unstable( feature = "delayed_debug_assertions" , issue = "none" ) ]
25732585 #[ rustc_safe_intrinsic]
25742586 #[ cfg( not( bootstrap) ) ]
@@ -2597,7 +2609,7 @@ pub(crate) const fn debug_assertions() -> bool {
25972609/// These checks are behind a condition which is evaluated at codegen time, not expansion time like
25982610/// [`debug_assert`]. This means that a standard library built with optimizations and debug
25992611/// 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
2612+ /// caller of the standard library has debug assertions enabled and monomorphizes an expansion of
26012613/// this macro, that monomorphization will contain the check.
26022614///
26032615/// Since these checks cannot be optimized out in MIR, some care must be taken in both call and
@@ -2606,8 +2618,8 @@ pub(crate) const fn debug_assertions() -> bool {
26062618/// combination of properties ensures that the code for the checks is only compiled once, and has a
26072619/// minimal impact on the caller's code size.
26082620///
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
2621+ /// Callers should also avoid introducing any other `let` bindings or any code outside this macro in
2622+ /// order to call it. Since the precompiled standard library is built with full debuginfo and these
26112623/// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough
26122624/// debuginfo to have a measurable compile-time impact on debug builds.
26132625///
@@ -2659,33 +2671,12 @@ pub(crate) fn is_valid_allocation_size(size: usize, len: usize) -> bool {
26592671 len <= max_len
26602672}
26612673
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-
26812674/// 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 {
2675+ /// `count * size` do *not* overlap.
2676+ pub ( crate ) fn is_nonoverlapping ( src : * const ( ) , dst : * const ( ) , size : usize , count : usize ) -> bool {
26852677 let src_usize = src. addr ( ) ;
26862678 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.
2679+ let Some ( size) = size. checked_mul ( count) else {
26892680 crate :: panicking:: panic_nounwind (
26902681 "is_nonoverlapping: `size_of::<T>() * count` overflows a usize" ,
26912682 )
@@ -2809,7 +2800,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
28092800 ) =>
28102801 is_aligned_and_not_null( src, align)
28112802 && is_aligned_and_not_null( dst, align)
2812- && is_nonoverlapping_mono ( src, dst, size, count)
2803+ && is_nonoverlapping ( src, dst, size, count)
28132804 ) ;
28142805 copy_nonoverlapping ( src, dst, count)
28152806 }
0 commit comments