56
56
57
57
use crate :: marker:: DiscriminantKind ;
58
58
use crate :: marker:: Tuple ;
59
- use crate :: mem:: { self , align_of} ;
59
+ use crate :: mem:: align_of;
60
+ #[ cfg( doc) ]
61
+ use crate :: mem;
60
62
61
63
pub mod mir;
62
64
pub mod simd;
@@ -2569,6 +2571,16 @@ extern "rust-intrinsic" {
2569
2571
#[ rustc_nounwind]
2570
2572
pub fn is_val_statically_known < T : Copy > ( arg : T ) -> bool ;
2571
2573
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`].
2572
2584
#[ rustc_const_unstable( feature = "delayed_debug_assertions" , issue = "none" ) ]
2573
2585
#[ rustc_safe_intrinsic]
2574
2586
#[ cfg( not( bootstrap) ) ]
@@ -2597,7 +2609,7 @@ pub(crate) const fn debug_assertions() -> bool {
2597
2609
/// These checks are behind a condition which is evaluated at codegen time, not expansion time like
2598
2610
/// [`debug_assert`]. This means that a standard library built with optimizations and debug
2599
2611
/// 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
2601
2613
/// this macro, that monomorphization will contain the check.
2602
2614
///
2603
2615
/// 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 {
2606
2618
/// combination of properties ensures that the code for the checks is only compiled once, and has a
2607
2619
/// minimal impact on the caller's code size.
2608
2620
///
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
2611
2623
/// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough
2612
2624
/// debuginfo to have a measurable compile-time impact on debug builds.
2613
2625
///
@@ -2659,33 +2671,12 @@ pub(crate) fn is_valid_allocation_size(size: usize, len: usize) -> bool {
2659
2671
len <= max_len
2660
2672
}
2661
2673
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
-
2681
2674
/// 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 {
2685
2677
let src_usize = src. addr ( ) ;
2686
2678
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 {
2689
2680
crate :: panicking:: panic_nounwind (
2690
2681
"is_nonoverlapping: `size_of::<T>() * count` overflows a usize" ,
2691
2682
)
@@ -2809,7 +2800,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
2809
2800
) =>
2810
2801
is_aligned_and_not_null( src, align)
2811
2802
&& is_aligned_and_not_null( dst, align)
2812
- && is_nonoverlapping_mono ( src, dst, size, count)
2803
+ && is_nonoverlapping ( src, dst, size, count)
2813
2804
) ;
2814
2805
copy_nonoverlapping ( src, dst, count)
2815
2806
}
0 commit comments