@@ -1742,157 +1742,6 @@ extern "rust-intrinsic" {
17421742 /// Allocate at compile time. Should not be called at runtime.
17431743 #[ rustc_const_unstable( feature = "const_heap" , issue = "79597" ) ]
17441744 pub fn const_allocate ( size : usize , align : usize ) -> * mut u8 ;
1745-
1746- /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1747- /// and destination must *not* overlap.
1748- ///
1749- /// For regions of memory which might overlap, use [`copy`] instead.
1750- ///
1751- /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
1752- /// with the argument order swapped.
1753- ///
1754- /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
1755- ///
1756- /// # Safety
1757- ///
1758- /// Behavior is undefined if any of the following conditions are violated:
1759- ///
1760- /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
1761- ///
1762- /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
1763- ///
1764- /// * Both `src` and `dst` must be properly aligned.
1765- ///
1766- /// * The region of memory beginning at `src` with a size of `count *
1767- /// size_of::<T>()` bytes must *not* overlap with the region of memory
1768- /// beginning at `dst` with the same size.
1769- ///
1770- /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
1771- /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
1772- /// in the region beginning at `*src` and the region beginning at `*dst` can
1773- /// [violate memory safety][read-ownership].
1774- ///
1775- /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
1776- /// `0`, the pointers must be non-NULL and properly aligned.
1777- ///
1778- /// [`read`]: crate::ptr::read
1779- /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
1780- /// [valid]: crate::ptr#safety
1781- ///
1782- /// # Examples
1783- ///
1784- /// Manually implement [`Vec::append`]:
1785- ///
1786- /// ```
1787- /// use std::ptr;
1788- ///
1789- /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
1790- /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
1791- /// let src_len = src.len();
1792- /// let dst_len = dst.len();
1793- ///
1794- /// // Ensure that `dst` has enough capacity to hold all of `src`.
1795- /// dst.reserve(src_len);
1796- ///
1797- /// unsafe {
1798- /// // The call to offset is always safe because `Vec` will never
1799- /// // allocate more than `isize::MAX` bytes.
1800- /// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
1801- /// let src_ptr = src.as_ptr();
1802- ///
1803- /// // Truncate `src` without dropping its contents. We do this first,
1804- /// // to avoid problems in case something further down panics.
1805- /// src.set_len(0);
1806- ///
1807- /// // The two regions cannot overlap because mutable references do
1808- /// // not alias, and two different vectors cannot own the same
1809- /// // memory.
1810- /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
1811- ///
1812- /// // Notify `dst` that it now holds the contents of `src`.
1813- /// dst.set_len(dst_len + src_len);
1814- /// }
1815- /// }
1816- ///
1817- /// let mut a = vec!['r'];
1818- /// let mut b = vec!['u', 's', 't'];
1819- ///
1820- /// append(&mut a, &mut b);
1821- ///
1822- /// assert_eq!(a, &['r', 'u', 's', 't']);
1823- /// assert!(b.is_empty());
1824- /// ```
1825- ///
1826- /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
1827- #[ doc( alias = "memcpy" ) ]
1828- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1829- #[ rustc_const_unstable( feature = "const_intrinsic_copy" , issue = "80697" ) ]
1830- pub fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) ;
1831-
1832- /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1833- /// and destination may overlap.
1834- ///
1835- /// If the source and destination will *never* overlap,
1836- /// [`copy_nonoverlapping`] can be used instead.
1837- ///
1838- /// `copy` is semantically equivalent to C's [`memmove`], but with the argument
1839- /// order swapped. Copying takes place as if the bytes were copied from `src`
1840- /// to a temporary array and then copied from the array to `dst`.
1841- ///
1842- /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
1843- ///
1844- /// # Safety
1845- ///
1846- /// Behavior is undefined if any of the following conditions are violated:
1847- ///
1848- /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
1849- ///
1850- /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
1851- ///
1852- /// * Both `src` and `dst` must be properly aligned.
1853- ///
1854- /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
1855- /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
1856- /// in the region beginning at `*src` and the region beginning at `*dst` can
1857- /// [violate memory safety][read-ownership].
1858- ///
1859- /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
1860- /// `0`, the pointers must be non-NULL and properly aligned.
1861- ///
1862- /// [`read`]: crate::ptr::read
1863- /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
1864- /// [valid]: crate::ptr#safety
1865- ///
1866- /// # Examples
1867- ///
1868- /// Efficiently create a Rust vector from an unsafe buffer:
1869- ///
1870- /// ```
1871- /// use std::ptr;
1872- ///
1873- /// /// # Safety
1874- /// ///
1875- /// /// * `ptr` must be correctly aligned for its type and non-zero.
1876- /// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
1877- /// /// * Those elements must not be used after calling this function unless `T: Copy`.
1878- /// # #[allow(dead_code)]
1879- /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
1880- /// let mut dst = Vec::with_capacity(elts);
1881- ///
1882- /// // SAFETY: Our precondition ensures the source is aligned and valid,
1883- /// // and `Vec::with_capacity` ensures that we have usable space to write them.
1884- /// ptr::copy(ptr, dst.as_mut_ptr(), elts);
1885- ///
1886- /// // SAFETY: We created it with this much capacity earlier,
1887- /// // and the previous `copy` has initialized these elements.
1888- /// dst.set_len(elts);
1889- /// dst
1890- /// }
1891- /// ```
1892- #[ doc( alias = "memmove" ) ]
1893- #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1894- #[ rustc_const_unstable( feature = "const_intrinsic_copy" , issue = "80697" ) ]
1895- pub fn copy < T > ( src : * const T , dst : * mut T , count : usize ) ;
18961745}
18971746
18981747// Some functions are defined here because they accidentally got made
@@ -1906,6 +1755,204 @@ pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
19061755 !ptr. is_null ( ) && ptr as usize % mem:: align_of :: < T > ( ) == 0
19071756}
19081757
1758+ /// Checks whether the regions of memory starting at `src` and `dst` of size
1759+ /// `count * size_of::<T>()` do *not* overlap.
1760+ pub ( crate ) fn is_nonoverlapping < T > ( src : * const T , dst : * const T , count : usize ) -> bool {
1761+ let src_usize = src as usize ;
1762+ let dst_usize = dst as usize ;
1763+ let size = mem:: size_of :: < T > ( ) . checked_mul ( count) . unwrap ( ) ;
1764+ let diff = if src_usize > dst_usize { src_usize - dst_usize } else { dst_usize - src_usize } ;
1765+ // If the absolute distance between the ptrs is at least as big as the size of the buffer,
1766+ // they do not overlap.
1767+ diff >= size
1768+ }
1769+
1770+ /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1771+ /// and destination must *not* overlap.
1772+ ///
1773+ /// For regions of memory which might overlap, use [`copy`] instead.
1774+ ///
1775+ /// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
1776+ /// with the argument order swapped.
1777+ ///
1778+ /// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
1779+ ///
1780+ /// # Safety
1781+ ///
1782+ /// Behavior is undefined if any of the following conditions are violated:
1783+ ///
1784+ /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
1785+ ///
1786+ /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
1787+ ///
1788+ /// * Both `src` and `dst` must be properly aligned.
1789+ ///
1790+ /// * The region of memory beginning at `src` with a size of `count *
1791+ /// size_of::<T>()` bytes must *not* overlap with the region of memory
1792+ /// beginning at `dst` with the same size.
1793+ ///
1794+ /// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
1795+ /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
1796+ /// in the region beginning at `*src` and the region beginning at `*dst` can
1797+ /// [violate memory safety][read-ownership].
1798+ ///
1799+ /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
1800+ /// `0`, the pointers must be non-NULL and properly aligned.
1801+ ///
1802+ /// [`read`]: crate::ptr::read
1803+ /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
1804+ /// [valid]: crate::ptr#safety
1805+ ///
1806+ /// # Examples
1807+ ///
1808+ /// Manually implement [`Vec::append`]:
1809+ ///
1810+ /// ```
1811+ /// use std::ptr;
1812+ ///
1813+ /// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
1814+ /// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
1815+ /// let src_len = src.len();
1816+ /// let dst_len = dst.len();
1817+ ///
1818+ /// // Ensure that `dst` has enough capacity to hold all of `src`.
1819+ /// dst.reserve(src_len);
1820+ ///
1821+ /// unsafe {
1822+ /// // The call to offset is always safe because `Vec` will never
1823+ /// // allocate more than `isize::MAX` bytes.
1824+ /// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
1825+ /// let src_ptr = src.as_ptr();
1826+ ///
1827+ /// // Truncate `src` without dropping its contents. We do this first,
1828+ /// // to avoid problems in case something further down panics.
1829+ /// src.set_len(0);
1830+ ///
1831+ /// // The two regions cannot overlap because mutable references do
1832+ /// // not alias, and two different vectors cannot own the same
1833+ /// // memory.
1834+ /// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
1835+ ///
1836+ /// // Notify `dst` that it now holds the contents of `src`.
1837+ /// dst.set_len(dst_len + src_len);
1838+ /// }
1839+ /// }
1840+ ///
1841+ /// let mut a = vec!['r'];
1842+ /// let mut b = vec!['u', 's', 't'];
1843+ ///
1844+ /// append(&mut a, &mut b);
1845+ ///
1846+ /// assert_eq!(a, &['r', 'u', 's', 't']);
1847+ /// assert!(b.is_empty());
1848+ /// ```
1849+ ///
1850+ /// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
1851+ #[ doc( alias = "memcpy" ) ]
1852+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1853+ #[ rustc_const_unstable( feature = "const_intrinsic_copy" , issue = "80697" ) ]
1854+ #[ inline]
1855+ pub const unsafe fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) {
1856+ extern "rust-intrinsic" {
1857+ #[ rustc_const_unstable( feature = "const_intrinsic_copy" , issue = "80697" ) ]
1858+ fn copy_nonoverlapping < T > ( src : * const T , dst : * mut T , count : usize ) ;
1859+ }
1860+
1861+ // FIXME: Perform these checks only at run time
1862+ /*if cfg!(debug_assertions)
1863+ && !(is_aligned_and_not_null(src)
1864+ && is_aligned_and_not_null(dst)
1865+ && is_nonoverlapping(src, dst, count))
1866+ {
1867+ // Not panicking to keep codegen impact smaller.
1868+ abort();
1869+ }*/
1870+
1871+ // SAFETY: the safety contract for `copy_nonoverlapping` must be
1872+ // upheld by the caller.
1873+ unsafe { copy_nonoverlapping ( src, dst, count) }
1874+ }
1875+
1876+ /// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
1877+ /// and destination may overlap.
1878+ ///
1879+ /// If the source and destination will *never* overlap,
1880+ /// [`copy_nonoverlapping`] can be used instead.
1881+ ///
1882+ /// `copy` is semantically equivalent to C's [`memmove`], but with the argument
1883+ /// order swapped. Copying takes place as if the bytes were copied from `src`
1884+ /// to a temporary array and then copied from the array to `dst`.
1885+ ///
1886+ /// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
1887+ ///
1888+ /// # Safety
1889+ ///
1890+ /// Behavior is undefined if any of the following conditions are violated:
1891+ ///
1892+ /// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
1893+ ///
1894+ /// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
1895+ ///
1896+ /// * Both `src` and `dst` must be properly aligned.
1897+ ///
1898+ /// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
1899+ /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
1900+ /// in the region beginning at `*src` and the region beginning at `*dst` can
1901+ /// [violate memory safety][read-ownership].
1902+ ///
1903+ /// Note that even if the effectively copied size (`count * size_of::<T>()`) is
1904+ /// `0`, the pointers must be non-NULL and properly aligned.
1905+ ///
1906+ /// [`read`]: crate::ptr::read
1907+ /// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
1908+ /// [valid]: crate::ptr#safety
1909+ ///
1910+ /// # Examples
1911+ ///
1912+ /// Efficiently create a Rust vector from an unsafe buffer:
1913+ ///
1914+ /// ```
1915+ /// use std::ptr;
1916+ ///
1917+ /// /// # Safety
1918+ /// ///
1919+ /// /// * `ptr` must be correctly aligned for its type and non-zero.
1920+ /// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
1921+ /// /// * Those elements must not be used after calling this function unless `T: Copy`.
1922+ /// # #[allow(dead_code)]
1923+ /// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
1924+ /// let mut dst = Vec::with_capacity(elts);
1925+ ///
1926+ /// // SAFETY: Our precondition ensures the source is aligned and valid,
1927+ /// // and `Vec::with_capacity` ensures that we have usable space to write them.
1928+ /// ptr::copy(ptr, dst.as_mut_ptr(), elts);
1929+ ///
1930+ /// // SAFETY: We created it with this much capacity earlier,
1931+ /// // and the previous `copy` has initialized these elements.
1932+ /// dst.set_len(elts);
1933+ /// dst
1934+ /// }
1935+ /// ```
1936+ #[ doc( alias = "memmove" ) ]
1937+ #[ stable( feature = "rust1" , since = "1.0.0" ) ]
1938+ #[ rustc_const_unstable( feature = "const_intrinsic_copy" , issue = "80697" ) ]
1939+ #[ inline]
1940+ pub const unsafe fn copy < T > ( src : * const T , dst : * mut T , count : usize ) {
1941+ extern "rust-intrinsic" {
1942+ #[ rustc_const_unstable( feature = "const_intrinsic_copy" , issue = "80697" ) ]
1943+ fn copy < T > ( src : * const T , dst : * mut T , count : usize ) ;
1944+ }
1945+
1946+ // FIXME: Perform these checks only at run time
1947+ /*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
1948+ // Not panicking to keep codegen impact smaller.
1949+ abort();
1950+ }*/
1951+
1952+ // SAFETY: the safety contract for `copy` must be upheld by the caller.
1953+ unsafe { copy ( src, dst, count) }
1954+ }
1955+
19091956/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
19101957/// `val`.
19111958///
0 commit comments