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