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