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
60
61
61
pub mod mir;
62
62
pub mod simd;
@@ -1027,7 +1027,7 @@ extern "rust-intrinsic" {
1027
1027
1028
1028
/// The size of the referenced value in bytes.
1029
1029
///
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`].
1031
1031
#[ rustc_const_unstable( feature = "const_size_of_val" , issue = "46571" ) ]
1032
1032
#[ rustc_nounwind]
1033
1033
pub fn size_of_val < T : ?Sized > ( _: * const T ) -> usize ;
@@ -1107,7 +1107,7 @@ extern "rust-intrinsic" {
1107
1107
1108
1108
/// Moves a value out of scope without running drop glue.
1109
1109
///
1110
- /// This exists solely for [`mem::forget_unsized`]; normal `forget` uses
1110
+ /// This exists solely for [`crate:: mem::forget_unsized`]; normal `forget` uses
1111
1111
/// `ManuallyDrop` instead.
1112
1112
///
1113
1113
/// Note that, unlike most intrinsics, this is safe to call;
@@ -1233,7 +1233,7 @@ extern "rust-intrinsic" {
1233
1233
/// Depending on what the code is doing, the following alternatives are preferable to
1234
1234
/// pointer-to-integer transmutation:
1235
1235
/// - 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].
1237
1237
/// - If the code actually wants to work on the address the pointer points to, it can use `as`
1238
1238
/// casts or [`ptr.addr()`][pointer::addr].
1239
1239
///
@@ -2317,7 +2317,7 @@ extern "rust-intrinsic" {
2317
2317
/// Therefore, implementations must not require the user to uphold
2318
2318
/// any safety invariants.
2319
2319
///
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`].
2321
2321
#[ rustc_const_unstable( feature = "variant_count" , issue = "73662" ) ]
2322
2322
#[ rustc_safe_intrinsic]
2323
2323
#[ rustc_nounwind]
@@ -2569,6 +2569,19 @@ extern "rust-intrinsic" {
2569
2569
#[ rustc_nounwind]
2570
2570
pub fn is_val_statically_known < T : Copy > ( arg : T ) -> bool ;
2571
2571
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`].
2572
2585
#[ rustc_const_unstable( feature = "delayed_debug_assertions" , issue = "none" ) ]
2573
2586
#[ rustc_safe_intrinsic]
2574
2587
#[ cfg( not( bootstrap) ) ]
@@ -2597,7 +2610,7 @@ pub(crate) const fn debug_assertions() -> bool {
2597
2610
/// These checks are behind a condition which is evaluated at codegen time, not expansion time like
2598
2611
/// [`debug_assert`]. This means that a standard library built with optimizations and debug
2599
2612
/// 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
2601
2614
/// this macro, that monomorphization will contain the check.
2602
2615
///
2603
2616
/// 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 {
2606
2619
/// combination of properties ensures that the code for the checks is only compiled once, and has a
2607
2620
/// minimal impact on the caller's code size.
2608
2621
///
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
2611
2624
/// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough
2612
2625
/// debuginfo to have a measurable compile-time impact on debug builds.
2613
2626
///
@@ -2659,33 +2672,12 @@ pub(crate) fn is_valid_allocation_size(size: usize, len: usize) -> bool {
2659
2672
len <= max_len
2660
2673
}
2661
2674
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
2675
/// 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 {
2685
2678
let src_usize = src. addr ( ) ;
2686
2679
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 {
2689
2681
crate :: panicking:: panic_nounwind (
2690
2682
"is_nonoverlapping: `size_of::<T>() * count` overflows a usize" ,
2691
2683
)
@@ -2809,7 +2801,7 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
2809
2801
) =>
2810
2802
is_aligned_and_not_null( src, align)
2811
2803
&& is_aligned_and_not_null( dst, align)
2812
- && is_nonoverlapping_mono ( src, dst, size, count)
2804
+ && is_nonoverlapping ( src, dst, size, count)
2813
2805
) ;
2814
2806
copy_nonoverlapping ( src, dst, count)
2815
2807
}
0 commit comments