directly expose copy and copy_nonoverlapping intrinsics · rust-lang/rust@18d12ad (original) (raw)
`@@ -1730,6 +1730,157 @@ extern "rust-intrinsic" {
`
1730
1730
`/// Allocate at compile time. Should not be called at runtime.
`
1731
1731
`#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
`
1732
1732
`pub fn const_allocate(size: usize, align: usize) -> *mut u8;
`
``
1733
+
``
1734
`` +
/// Copies count * size_of::<T>()
bytes from src
to dst
. The source
``
``
1735
`+
/// and destination must not overlap.
`
``
1736
`+
///
`
``
1737
`` +
/// For regions of memory which might overlap, use [copy
] instead.
``
``
1738
`+
///
`
``
1739
`` +
/// copy_nonoverlapping
is semantically equivalent to C's [memcpy
], but
``
``
1740
`+
/// with the argument order swapped.
`
``
1741
`+
///
`
``
1742
`` +
/// [memcpy
]: https://en.cppreference.com/w/c/string/byte/memcpy
``
``
1743
`+
///
`
``
1744
`+
/// # Safety
`
``
1745
`+
///
`
``
1746
`+
/// Behavior is undefined if any of the following conditions are violated:
`
``
1747
`+
///
`
``
1748
`` +
/// * src
must be [valid] for reads of count * size_of::<T>()
bytes.
``
``
1749
`+
///
`
``
1750
`` +
/// * dst
must be [valid] for writes of count * size_of::<T>()
bytes.
``
``
1751
`+
///
`
``
1752
`` +
/// * Both src
and dst
must be properly aligned.
``
``
1753
`+
///
`
``
1754
`` +
/// * The region of memory beginning at src
with a size of `count *
``
``
1755
`` +
/// size_of::()` bytes must not overlap with the region of memory
``
``
1756
`` +
/// beginning at dst
with the same size.
``
``
1757
`+
///
`
``
1758
`` +
/// Like [read
], copy_nonoverlapping
creates a bitwise copy of T
, regardless of
``
``
1759
`` +
/// whether T
is [Copy
]. If T
is not [Copy
], using both the values
``
``
1760
`` +
/// in the region beginning at *src
and the region beginning at *dst
can
``
``
1761
`+
/// [violate memory safety][read-ownership].
`
``
1762
`+
///
`
``
1763
`` +
/// Note that even if the effectively copied size (count * size_of::<T>()
) is
``
``
1764
`` +
/// 0
, the pointers must be non-NULL and properly aligned.
``
``
1765
`+
///
`
``
1766
`` +
/// [read
]: crate::ptr::read
``
``
1767
`+
/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
`
``
1768
`+
/// [valid]: crate::ptr#safety
`
``
1769
`+
///
`
``
1770
`+
/// # Examples
`
``
1771
`+
///
`
``
1772
`` +
/// Manually implement [Vec::append
]:
``
``
1773
`+
///
`
``
1774
/// ```
``
1775
`+
/// use std::ptr;
`
``
1776
`+
///
`
``
1777
`` +
/// /// Moves all the elements of src
into dst
, leaving src
empty.
``
``
1778
`+
/// fn append(dst: &mut Vec, src: &mut Vec) {
`
``
1779
`+
/// let src_len = src.len();
`
``
1780
`+
/// let dst_len = dst.len();
`
``
1781
`+
///
`
``
1782
`` +
/// // Ensure that dst
has enough capacity to hold all of src
.
``
``
1783
`+
/// dst.reserve(src_len);
`
``
1784
`+
///
`
``
1785
`+
/// unsafe {
`
``
1786
`` +
/// // The call to offset is always safe because Vec
will never
``
``
1787
`` +
/// // allocate more than isize::MAX
bytes.
``
``
1788
`+
/// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
`
``
1789
`+
/// let src_ptr = src.as_ptr();
`
``
1790
`+
///
`
``
1791
`` +
/// // Truncate src
without dropping its contents. We do this first,
``
``
1792
`+
/// // to avoid problems in case something further down panics.
`
``
1793
`+
/// src.set_len(0);
`
``
1794
`+
///
`
``
1795
`+
/// // The two regions cannot overlap because mutable references do
`
``
1796
`+
/// // not alias, and two different vectors cannot own the same
`
``
1797
`+
/// // memory.
`
``
1798
`+
/// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
`
``
1799
`+
///
`
``
1800
`` +
/// // Notify dst
that it now holds the contents of src
.
``
``
1801
`+
/// dst.set_len(dst_len + src_len);
`
``
1802
`+
/// }
`
``
1803
`+
/// }
`
``
1804
`+
///
`
``
1805
`+
/// let mut a = vec!['r'];
`
``
1806
`+
/// let mut b = vec!['u', 's', 't'];
`
``
1807
`+
///
`
``
1808
`+
/// append(&mut a, &mut b);
`
``
1809
`+
///
`
``
1810
`+
/// assert_eq!(a, &['r', 'u', 's', 't']);
`
``
1811
`+
/// assert!(b.is_empty());
`
``
1812
/// ```
``
1813
`+
///
`
``
1814
`` +
/// [Vec::append
]: ../../std/vec/struct.Vec.html#method.append
``
``
1815
`+
#[doc(alias = "memcpy")]
`
``
1816
`+
#[stable(feature = "rust1", since = "1.0.0")]
`
``
1817
`+
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
`
``
1818
`+
pub fn copy_nonoverlapping(src: *const T, dst: *mut T, count: usize);
`
``
1819
+
``
1820
`` +
/// Copies count * size_of::<T>()
bytes from src
to dst
. The source
``
``
1821
`+
/// and destination may overlap.
`
``
1822
`+
///
`
``
1823
`+
/// If the source and destination will never overlap,
`
``
1824
`` +
/// [copy_nonoverlapping
] can be used instead.
``
``
1825
`+
///
`
``
1826
`` +
/// copy
is semantically equivalent to C's [memmove
], but with the argument
``
``
1827
`` +
/// order swapped. Copying takes place as if the bytes were copied from src
``
``
1828
`` +
/// to a temporary array and then copied from the array to dst
.
``
``
1829
`+
///
`
``
1830
`` +
/// [memmove
]: https://en.cppreference.com/w/c/string/byte/memmove
``
``
1831
`+
///
`
``
1832
`+
/// # Safety
`
``
1833
`+
///
`
``
1834
`+
/// Behavior is undefined if any of the following conditions are violated:
`
``
1835
`+
///
`
``
1836
`` +
/// * src
must be [valid] for reads of count * size_of::<T>()
bytes.
``
``
1837
`+
///
`
``
1838
`` +
/// * dst
must be [valid] for writes of count * size_of::<T>()
bytes.
``
``
1839
`+
///
`
``
1840
`` +
/// * Both src
and dst
must be properly aligned.
``
``
1841
`+
///
`
``
1842
`` +
/// Like [read
], copy
creates a bitwise copy of T
, regardless of
``
``
1843
`` +
/// whether T
is [Copy
]. If T
is not [Copy
], using both the values
``
``
1844
`` +
/// in the region beginning at *src
and the region beginning at *dst
can
``
``
1845
`+
/// [violate memory safety][read-ownership].
`
``
1846
`+
///
`
``
1847
`` +
/// Note that even if the effectively copied size (count * size_of::<T>()
) is
``
``
1848
`` +
/// 0
, the pointers must be non-NULL and properly aligned.
``
``
1849
`+
///
`
``
1850
`` +
/// [read
]: crate::ptr::read
``
``
1851
`+
/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
`
``
1852
`+
/// [valid]: crate::ptr#safety
`
``
1853
`+
///
`
``
1854
`+
/// # Examples
`
``
1855
`+
///
`
``
1856
`+
/// Efficiently create a Rust vector from an unsafe buffer:
`
``
1857
`+
///
`
``
1858
/// ```
``
1859
`+
/// use std::ptr;
`
``
1860
`+
///
`
``
1861
`+
/// /// # Safety
`
``
1862
`+
/// ///
`
``
1863
`` +
/// /// * ptr
must be correctly aligned for its type and non-zero.
``
``
1864
`` +
/// /// * ptr
must be valid for reads of elts
contiguous elements of type T
.
``
``
1865
`` +
/// /// * Those elements must not be used after calling this function unless T: Copy
.
``
``
1866
`+
/// # #[allow(dead_code)]
`
``
1867
`+
/// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec {
`
``
1868
`+
/// let mut dst = Vec::with_capacity(elts);
`
``
1869
`+
///
`
``
1870
`+
/// // SAFETY: Our precondition ensures the source is aligned and valid,
`
``
1871
`` +
/// // and Vec::with_capacity
ensures that we have usable space to write them.
``
``
1872
`+
/// ptr::copy(ptr, dst.as_mut_ptr(), elts);
`
``
1873
`+
///
`
``
1874
`+
/// // SAFETY: We created it with this much capacity earlier,
`
``
1875
`` +
/// // and the previous copy
has initialized these elements.
``
``
1876
`+
/// dst.set_len(elts);
`
``
1877
`+
/// dst
`
``
1878
`+
/// }
`
``
1879
/// ```
``
1880
`+
#[doc(alias = "memmove")]
`
``
1881
`+
#[stable(feature = "rust1", since = "1.0.0")]
`
``
1882
`+
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
`
``
1883
`+
pub fn copy(src: *const T, dst: *mut T, count: usize);
`
1733
1884
`}
`
1734
1885
``
1735
1886
`// Some functions are defined here because they accidentally got made
`
`@@ -1755,192 +1906,6 @@ pub(crate) fn is_nonoverlapping(src: *const T, dst: *const T, count: usize) -
`
1755
1906
` diff >= size
`
1756
1907
`}
`
1757
1908
``
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::()` 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(dst: &mut Vec, src: &mut Vec) {
`
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(src: *const T, dst: *mut T, count: usize) {
`
1844
``
`-
extern "rust-intrinsic" {
`
1845
``
`-
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
`
1846
``
`-
fn copy_nonoverlapping(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(ptr: *const T, elts: usize) -> Vec {
`
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(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(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
``
-
1944
1909
`` /// Sets count * size_of::<T>()
bytes of memory starting at dst
to
``
1945
1910
`` /// val
.
``
1946
1911
`///
`