62
62
#![ allow( missing_docs) ]
63
63
64
64
use crate :: marker:: { DiscriminantKind , Tuple } ;
65
- use crate :: mem:: SizedTypeProperties ;
66
- use crate :: { ptr, ub_checks} ;
65
+ use crate :: ptr;
67
66
68
67
pub mod fallback;
69
68
pub mod mir;
@@ -74,6 +73,7 @@ pub mod simd;
74
73
#[ cfg( all( target_has_atomic = "8" , target_has_atomic = "32" , target_has_atomic = "ptr" ) ) ]
75
74
use crate :: sync:: atomic:: { self , AtomicBool , AtomicI32 , AtomicIsize , AtomicU32 , Ordering } ;
76
75
76
+ /// This is an accidentally-stable alias to [`ptr::drop_in_place`]; use that instead.
77
77
#[ stable( feature = "drop_in_place" , since = "1.8.0" ) ]
78
78
#[ rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead" ]
79
79
#[ deprecated( note = "no longer an intrinsic - use `ptr::drop_in_place` directly" , since = "1.52.0" ) ]
@@ -3336,7 +3336,7 @@ pub const unsafe fn typed_swap_nonoverlapping<T>(x: *mut T, y: *mut T) {
3336
3336
/// `#[inline]`), gating assertions on `ub_checks()` rather than `cfg!(ub_checks)` means that
3337
3337
/// assertions are enabled whenever the *user crate* has UB checks enabled. However, if the
3338
3338
/// user has UB checks disabled, the checks will still get optimized out. This intrinsic is
3339
- /// primarily used by [`ub_checks::assert_unsafe_precondition`].
3339
+ /// primarily used by [`crate:: ub_checks::assert_unsafe_precondition`].
3340
3340
#[ rustc_intrinsic_const_stable_indirect] // just for UB checks
3341
3341
#[ inline( always) ]
3342
3342
#[ rustc_intrinsic]
@@ -3625,306 +3625,38 @@ impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
3625
3625
#[ rustc_intrinsic]
3626
3626
pub const fn ptr_metadata < P : ptr:: Pointee < Metadata = M > + ?Sized , M > ( ptr : * const P ) -> M ;
3627
3627
3628
- // Some functions are defined here because they accidentally got made
3629
- // available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
3630
- // (`transmute` also falls into this category, but it cannot be wrapped due to the
3631
- // check that `T` and `U` have the same size.)
3632
-
3633
- /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
3634
- /// and destination must *not* overlap.
3635
- ///
3636
- /// For regions of memory which might overlap, use [`copy`] instead.
3637
- ///
3638
- /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
3639
- /// with the source and destination arguments swapped,
3640
- /// and `count` counting the number of `T`s instead of bytes.
3641
- ///
3642
- /// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the
3643
- /// requirements of `T`. The initialization state is preserved exactly.
3644
- ///
3645
- /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
3646
- ///
3647
- /// # Safety
3648
- ///
3649
- /// Behavior is undefined if any of the following conditions are violated:
3650
- ///
3651
- /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
3652
- ///
3653
- /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
3654
- ///
3655
- /// * Both `src` and `dst` must be properly aligned.
3656
- ///
3657
- /// * The region of memory beginning at `src` with a size of `count *
3658
- /// size_of::<T>()` bytes must *not* overlap with the region of memory
3659
- /// beginning at `dst` with the same size.
3660
- ///
3661
- /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
3662
- /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
3663
- /// in the region beginning at `*src` and the region beginning at `*dst` can
3664
- /// [violate memory safety][read-ownership].
3665
- ///
3666
- /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
3667
- /// `0`, the pointers must be properly aligned.
3668
- ///
3669
- /// [`read`]: crate::ptr::read
3670
- /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
3671
- /// [valid]: crate::ptr#safety
3672
- ///
3673
- /// # Examples
3674
- ///
3675
- /// Manually implement [`Vec::append`]:
3676
- ///
3677
- /// ```
3678
- /// use std::ptr;
3679
- ///
3680
- /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
3681
- /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
3682
- /// let src_len = src.len();
3683
- /// let dst_len = dst.len();
3684
- ///
3685
- /// // Ensure that `dst` has enough capacity to hold all of `src`.
3686
- /// dst.reserve(src_len);
3687
- ///
3688
- /// unsafe {
3689
- /// // The call to add is always safe because `Vec` will never
3690
- /// // allocate more than `isize::MAX` bytes.
3691
- /// let dst_ptr = dst.as_mut_ptr().add(dst_len);
3692
- /// let src_ptr = src.as_ptr();
3693
- ///
3694
- /// // Truncate `src` without dropping its contents. We do this first,
3695
- /// // to avoid problems in case something further down panics.
3696
- /// src.set_len(0);
3697
- ///
3698
- /// // The two regions cannot overlap because mutable references do
3699
- /// // not alias, and two different vectors cannot own the same
3700
- /// // memory.
3701
- /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
3702
- ///
3703
- /// // Notify `dst` that it now holds the contents of `src`.
3704
- /// dst.set_len(dst_len + src_len);
3705
- /// }
3706
- /// }
3707
- ///
3708
- /// let mut a = vec!['r'];
3709
- /// let mut b = vec!['u', 's', 't'];
3710
- ///
3711
- /// append(&mut a, &mut b);
3712
- ///
3713
- /// assert_eq!(a, &['r', 'u', 's', 't']);
3714
- /// assert!(b.is_empty());
3715
- /// ```
3716
- ///
3717
- /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
3718
- #[ doc( alias = "memcpy" ) ]
3628
+ /// This is an accidentally-stable alias to [`ptr::copy_nonoverlapping`]; use that instead.
3629
+ // Note (intentionally not in the doc comment): `ptr::copy_nonoverlapping` adds some extra
3630
+ // debug assertions; if you are writing compiler tests or code inside the standard library
3631
+ // that wants to avoid those debug assertions, directly call this intrinsic instead.
3719
3632
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
3720
3633
#[ rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead" ]
3721
3634
#[ rustc_const_stable( feature = "const_intrinsic_copy" , since = "1.83.0" ) ]
3722
- #[ inline( always) ]
3723
- #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
3724
- #[ rustc_diagnostic_item = "ptr_copy_nonoverlapping" ]
3725
- pub const unsafe fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) {
3726
- #[ rustc_intrinsic_const_stable_indirect]
3727
- #[ rustc_nounwind]
3728
- #[ rustc_intrinsic]
3729
- const unsafe fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) ;
3730
-
3731
- ub_checks:: assert_unsafe_precondition!(
3732
- check_language_ub,
3733
- "ptr::copy_nonoverlapping requires that both pointer arguments are aligned and non-null \
3734
- and the specified memory ranges do not overlap",
3735
- (
3736
- src: * const ( ) = src as * const ( ) ,
3737
- dst: * mut ( ) = dst as * mut ( ) ,
3738
- size: usize = size_of:: <T >( ) ,
3739
- align: usize = align_of:: <T >( ) ,
3740
- count: usize = count,
3741
- ) => {
3742
- let zero_size = count == 0 || size == 0 ;
3743
- ub_checks:: maybe_is_aligned_and_not_null( src, align, zero_size)
3744
- && ub_checks:: maybe_is_aligned_and_not_null( dst, align, zero_size)
3745
- && ub_checks:: maybe_is_nonoverlapping( src, dst, size, count)
3746
- }
3747
- ) ;
3748
-
3749
- // SAFETY: the safety contract for `copy_nonoverlapping` must be
3750
- // upheld by the caller.
3751
- unsafe { copy_nonoverlapping ( src, dst, count) }
3752
- }
3635
+ #[ rustc_nounwind]
3636
+ #[ rustc_intrinsic]
3637
+ pub const unsafe fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) ;
3753
3638
3754
- /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
3755
- /// and destination may overlap.
3756
- ///
3757
- /// If the source and destination will *never* overlap,
3758
- /// [`copy_nonoverlapping`] can be used instead.
3759
- ///
3760
- /// `copy` is semantically equivalent to C's [`memmove`], but
3761
- /// with the source and destination arguments swapped,
3762
- /// and `count` counting the number of `T`s instead of bytes.
3763
- /// Copying takes place as if the bytes were copied from `src`
3764
- /// to a temporary array and then copied from the array to `dst`.
3765
- ///
3766
- /// The copy is "untyped" in the sense that data may be uninitialized or otherwise violate the
3767
- /// requirements of `T`. The initialization state is preserved exactly.
3768
- ///
3769
- /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
3770
- ///
3771
- /// # Safety
3772
- ///
3773
- /// Behavior is undefined if any of the following conditions are violated:
3774
- ///
3775
- /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
3776
- ///
3777
- /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes, and must remain valid even
3778
- /// when `src` is read for `count * size_of::<T>()` bytes. (This means if the memory ranges
3779
- /// overlap, the `dst` pointer must not be invalidated by `src` reads.)
3780
- ///
3781
- /// * Both `src` and `dst` must be properly aligned.
3782
- ///
3783
- /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
3784
- /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
3785
- /// in the region beginning at `*src` and the region beginning at `*dst` can
3786
- /// [violate memory safety][read-ownership].
3787
- ///
3788
- /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
3789
- /// `0`, the pointers must be properly aligned.
3790
- ///
3791
- /// [`read`]: crate::ptr::read
3792
- /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
3793
- /// [valid]: crate::ptr#safety
3794
- ///
3795
- /// # Examples
3796
- ///
3797
- /// Efficiently create a Rust vector from an unsafe buffer:
3798
- ///
3799
- /// ```
3800
- /// use std::ptr;
3801
- ///
3802
- /// /// # Safety
3803
- /// ///
3804
- /// /// * `ptr` must be correctly aligned for its type and non-zero.
3805
- /// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
3806
- /// /// * Those elements must not be used after calling this function unless `T: Copy`.
3807
- /// # #[allow(dead_code)]
3808
- /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
3809
- /// let mut dst = Vec::with_capacity(elts);
3810
- ///
3811
- /// // SAFETY: Our precondition ensures the source is aligned and valid,
3812
- /// // and `Vec::with_capacity` ensures that we have usable space to write them.
3813
- /// unsafe { ptr::copy(ptr, dst.as_mut_ptr(), elts); }
3814
- ///
3815
- /// // SAFETY: We created it with this much capacity earlier,
3816
- /// // and the previous `copy` has initialized these elements.
3817
- /// unsafe { dst.set_len(elts); }
3818
- /// dst
3819
- /// }
3820
- /// ```
3821
- #[ doc( alias = "memmove" ) ]
3639
+ /// This is an accidentally-stable alias to [`ptr::copy`]; use that instead.
3640
+ // Note (intentionally not in the doc comment): `ptr::copy` adds some extra
3641
+ // debug assertions; if you are writing compiler tests or code inside the standard library
3642
+ // that wants to avoid those debug assertions, directly call this intrinsic instead.
3822
3643
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
3823
3644
#[ rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead" ]
3824
3645
#[ rustc_const_stable( feature = "const_intrinsic_copy" , since = "1.83.0" ) ]
3825
- #[ inline( always) ]
3826
- #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
3827
- #[ rustc_diagnostic_item = "ptr_copy" ]
3828
- pub const unsafe fn copy < T > ( src : * const T , dst : * mut T , count : usize ) {
3829
- #[ rustc_intrinsic_const_stable_indirect]
3830
- #[ rustc_nounwind]
3831
- #[ rustc_intrinsic]
3832
- const unsafe fn copy < T > ( src : * const T , dst : * mut T , count : usize ) ;
3833
-
3834
- // SAFETY: the safety contract for `copy` must be upheld by the caller.
3835
- unsafe {
3836
- ub_checks:: assert_unsafe_precondition!(
3837
- check_language_ub,
3838
- "ptr::copy requires that both pointer arguments are aligned and non-null" ,
3839
- (
3840
- src: * const ( ) = src as * const ( ) ,
3841
- dst: * mut ( ) = dst as * mut ( ) ,
3842
- align: usize = align_of:: <T >( ) ,
3843
- zero_size: bool = T :: IS_ZST || count == 0 ,
3844
- ) =>
3845
- ub_checks:: maybe_is_aligned_and_not_null( src, align, zero_size)
3846
- && ub_checks:: maybe_is_aligned_and_not_null( dst, align, zero_size)
3847
- ) ;
3848
- copy ( src, dst, count)
3849
- }
3850
- }
3646
+ #[ rustc_nounwind]
3647
+ #[ rustc_intrinsic]
3648
+ pub const unsafe fn copy < T > ( src : * const T , dst : * mut T , count : usize ) ;
3851
3649
3852
- /// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
3853
- /// `val`.
3854
- ///
3855
- /// `write_bytes` is similar to C's [`memset`], but sets `count *
3856
- /// size_of::<T>()` bytes to `val`.
3857
- ///
3858
- /// [`memset`]: https://en.cppreference.com/w/c/string/byte/memset
3859
- ///
3860
- /// # Safety
3861
- ///
3862
- /// Behavior is undefined if any of the following conditions are violated:
3863
- ///
3864
- /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
3865
- ///
3866
- /// * `dst` must be properly aligned.
3867
- ///
3868
- /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
3869
- /// `0`, the pointer must be properly aligned.
3870
- ///
3871
- /// Additionally, note that changing `*dst` in this way can easily lead to undefined behavior (UB)
3872
- /// later if the written bytes are not a valid representation of some `T`. For instance, the
3873
- /// following is an **incorrect** use of this function:
3874
- ///
3875
- /// ```rust,no_run
3876
- /// unsafe {
3877
- /// let mut value: u8 = 0;
3878
- /// let ptr: *mut bool = &mut value as *mut u8 as *mut bool;
3879
- /// let _bool = ptr.read(); // This is fine, `ptr` points to a valid `bool`.
3880
- /// ptr.write_bytes(42u8, 1); // This function itself does not cause UB...
3881
- /// let _bool = ptr.read(); // ...but it makes this operation UB! ⚠️
3882
- /// }
3883
- /// ```
3884
- ///
3885
- /// [valid]: crate::ptr#safety
3886
- ///
3887
- /// # Examples
3888
- ///
3889
- /// Basic usage:
3890
- ///
3891
- /// ```
3892
- /// use std::ptr;
3893
- ///
3894
- /// let mut vec = vec![0u32; 4];
3895
- /// unsafe {
3896
- /// let vec_ptr = vec.as_mut_ptr();
3897
- /// ptr::write_bytes(vec_ptr, 0xfe, 2);
3898
- /// }
3899
- /// assert_eq!(vec, [0xfefefefe, 0xfefefefe, 0, 0]);
3900
- /// ```
3901
- #[ doc( alias = "memset" ) ]
3650
+ /// This is an accidentally-stable alias to [`ptr::write_bytes`]; use that instead.
3651
+ // Note (intentionally not in the doc comment): `ptr::write_bytes` adds some extra
3652
+ // debug assertions; if you are writing compiler tests or code inside the standard library
3653
+ // that wants to avoid those debug assertions, directly call this intrinsic instead.
3902
3654
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
3903
3655
#[ rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead" ]
3904
- #[ rustc_const_stable( feature = "const_ptr_write" , since = "1.83.0" ) ]
3905
- #[ inline( always) ]
3906
- #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
3907
- #[ rustc_diagnostic_item = "ptr_write_bytes" ]
3908
- pub const unsafe fn write_bytes < T > ( dst : * mut T , val : u8 , count : usize ) {
3909
- #[ rustc_intrinsic_const_stable_indirect]
3910
- #[ rustc_nounwind]
3911
- #[ rustc_intrinsic]
3912
- const unsafe fn write_bytes < T > ( dst : * mut T , val : u8 , count : usize ) ;
3913
-
3914
- // SAFETY: the safety contract for `write_bytes` must be upheld by the caller.
3915
- unsafe {
3916
- ub_checks:: assert_unsafe_precondition!(
3917
- check_language_ub,
3918
- "ptr::write_bytes requires that the destination pointer is aligned and non-null" ,
3919
- (
3920
- addr: * const ( ) = dst as * const ( ) ,
3921
- align: usize = align_of:: <T >( ) ,
3922
- zero_size: bool = T :: IS_ZST || count == 0 ,
3923
- ) => ub_checks:: maybe_is_aligned_and_not_null( addr, align, zero_size)
3924
- ) ;
3925
- write_bytes ( dst, val, count)
3926
- }
3927
- }
3656
+ #[ rustc_const_stable( feature = "const_intrinsic_copy" , since = "1.83.0" ) ]
3657
+ #[ rustc_nounwind]
3658
+ #[ rustc_intrinsic]
3659
+ pub const unsafe fn write_bytes < T > ( dst : * mut T , val : u8 , count : usize ) ;
3928
3660
3929
3661
/// Returns the minimum of two `f16` values.
3930
3662
///
0 commit comments