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

`///

`