6262#![ allow( missing_docs) ]
6363
6464use crate :: marker:: { DiscriminantKind , Tuple } ;
65- use crate :: mem:: SizedTypeProperties ;
66- use crate :: { ptr, ub_checks} ;
65+ use crate :: ptr;
6766
6867pub mod fallback;
6968pub mod mir;
@@ -74,6 +73,7 @@ pub mod simd;
7473#[ cfg( all( target_has_atomic = "8" , target_has_atomic = "32" , target_has_atomic = "ptr" ) ) ]
7574use crate :: sync:: atomic:: { self , AtomicBool , AtomicI32 , AtomicIsize , AtomicU32 , Ordering } ;
7675
76+ /// This is an accidentally-stable alias to [`ptr::drop_in_place`]; use that instead.
7777#[ stable( feature = "drop_in_place" , since = "1.8.0" ) ]
7878#[ rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead" ]
7979#[ deprecated( note = "no longer an intrinsic - use `ptr::drop_in_place` directly" , since = "1.52.0" ) ]
@@ -3625,306 +3625,38 @@ impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
36253625#[ rustc_intrinsic]
36263626pub const fn ptr_metadata < P : ptr:: Pointee < Metadata = M > + ?Sized , M > ( ptr : * const P ) -> M ;
36273627
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.
37193632#[ stable( feature = "rust1" , since = "1.0.0" ) ]
37203633#[ rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead" ]
37213634#[ 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 ) ;
37533638
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.
38223643#[ stable( feature = "rust1" , since = "1.0.0" ) ]
38233644#[ rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead" ]
38243645#[ 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 ) ;
38513649
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.
39023654#[ stable( feature = "rust1" , since = "1.0.0" ) ]
39033655#[ 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 ) ;
39283660
39293661/// Returns the minimum of two `f16` values.
39303662///
0 commit comments