Auto merge of #86003 - pnkfelix:issue-84297-revert-81238, r=Mark-Simulacrum
Make copy/copy_nonoverlapping fn's again Make copy/copy_nonoverlapping fn's again, rather than intrinsics. This a short-term change to address issue #84297. It effectively reverts PRs #81167 #81238 (and part of #82967), #83091, and parts of #79684.
This commit is contained in:
commit
eab201df70
15 changed files with 225 additions and 414 deletions
|
@ -1742,157 +1742,6 @@ extern "rust-intrinsic" {
|
||||||
/// Allocate at compile time. Should not be called at runtime.
|
/// Allocate at compile time. Should not be called at runtime.
|
||||||
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
|
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
|
||||||
pub fn const_allocate(size: usize, align: usize) -> *mut u8;
|
pub fn const_allocate(size: usize, align: usize) -> *mut u8;
|
||||||
|
|
||||||
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
|
||||||
/// and destination must *not* overlap.
|
|
||||||
///
|
|
||||||
/// For regions of memory which might overlap, use [`copy`] instead.
|
|
||||||
///
|
|
||||||
/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
|
|
||||||
/// with the argument order swapped.
|
|
||||||
///
|
|
||||||
/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// Behavior is undefined if any of the following conditions are violated:
|
|
||||||
///
|
|
||||||
/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
|
|
||||||
///
|
|
||||||
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
|
|
||||||
///
|
|
||||||
/// * Both `src` and `dst` must be properly aligned.
|
|
||||||
///
|
|
||||||
/// * The region of memory beginning at `src` with a size of `count *
|
|
||||||
/// size_of::<T>()` bytes must *not* overlap with the region of memory
|
|
||||||
/// beginning at `dst` with the same size.
|
|
||||||
///
|
|
||||||
/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
|
|
||||||
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
|
|
||||||
/// in the region beginning at `*src` and the region beginning at `*dst` can
|
|
||||||
/// [violate memory safety][read-ownership].
|
|
||||||
///
|
|
||||||
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
|
|
||||||
/// `0`, the pointers must be non-null and properly aligned.
|
|
||||||
///
|
|
||||||
/// [`read`]: crate::ptr::read
|
|
||||||
/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
|
|
||||||
/// [valid]: crate::ptr#safety
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Manually implement [`Vec::append`]:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::ptr;
|
|
||||||
///
|
|
||||||
/// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
|
|
||||||
/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
|
|
||||||
/// let src_len = src.len();
|
|
||||||
/// let dst_len = dst.len();
|
|
||||||
///
|
|
||||||
/// // Ensure that `dst` has enough capacity to hold all of `src`.
|
|
||||||
/// dst.reserve(src_len);
|
|
||||||
///
|
|
||||||
/// unsafe {
|
|
||||||
/// // The call to offset is always safe because `Vec` will never
|
|
||||||
/// // allocate more than `isize::MAX` bytes.
|
|
||||||
/// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
|
|
||||||
/// let src_ptr = src.as_ptr();
|
|
||||||
///
|
|
||||||
/// // Truncate `src` without dropping its contents. We do this first,
|
|
||||||
/// // to avoid problems in case something further down panics.
|
|
||||||
/// src.set_len(0);
|
|
||||||
///
|
|
||||||
/// // The two regions cannot overlap because mutable references do
|
|
||||||
/// // not alias, and two different vectors cannot own the same
|
|
||||||
/// // memory.
|
|
||||||
/// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
|
|
||||||
///
|
|
||||||
/// // Notify `dst` that it now holds the contents of `src`.
|
|
||||||
/// dst.set_len(dst_len + src_len);
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// let mut a = vec!['r'];
|
|
||||||
/// let mut b = vec!['u', 's', 't'];
|
|
||||||
///
|
|
||||||
/// append(&mut a, &mut b);
|
|
||||||
///
|
|
||||||
/// assert_eq!(a, &['r', 'u', 's', 't']);
|
|
||||||
/// assert!(b.is_empty());
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
|
|
||||||
#[doc(alias = "memcpy")]
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
|
||||||
pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
|
||||||
|
|
||||||
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
|
||||||
/// and destination may overlap.
|
|
||||||
///
|
|
||||||
/// If the source and destination will *never* overlap,
|
|
||||||
/// [`copy_nonoverlapping`] can be used instead.
|
|
||||||
///
|
|
||||||
/// `copy` is semantically equivalent to C's [`memmove`], but with the argument
|
|
||||||
/// order swapped. Copying takes place as if the bytes were copied from `src`
|
|
||||||
/// to a temporary array and then copied from the array to `dst`.
|
|
||||||
///
|
|
||||||
/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// Behavior is undefined if any of the following conditions are violated:
|
|
||||||
///
|
|
||||||
/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
|
|
||||||
///
|
|
||||||
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
|
|
||||||
///
|
|
||||||
/// * Both `src` and `dst` must be properly aligned.
|
|
||||||
///
|
|
||||||
/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
|
|
||||||
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
|
|
||||||
/// in the region beginning at `*src` and the region beginning at `*dst` can
|
|
||||||
/// [violate memory safety][read-ownership].
|
|
||||||
///
|
|
||||||
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
|
|
||||||
/// `0`, the pointers must be non-null and properly aligned.
|
|
||||||
///
|
|
||||||
/// [`read`]: crate::ptr::read
|
|
||||||
/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
|
|
||||||
/// [valid]: crate::ptr#safety
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Efficiently create a Rust vector from an unsafe buffer:
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::ptr;
|
|
||||||
///
|
|
||||||
/// /// # Safety
|
|
||||||
/// ///
|
|
||||||
/// /// * `ptr` must be correctly aligned for its type and non-zero.
|
|
||||||
/// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
|
|
||||||
/// /// * Those elements must not be used after calling this function unless `T: Copy`.
|
|
||||||
/// # #[allow(dead_code)]
|
|
||||||
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
|
|
||||||
/// let mut dst = Vec::with_capacity(elts);
|
|
||||||
///
|
|
||||||
/// // SAFETY: Our precondition ensures the source is aligned and valid,
|
|
||||||
/// // and `Vec::with_capacity` ensures that we have usable space to write them.
|
|
||||||
/// ptr::copy(ptr, dst.as_mut_ptr(), elts);
|
|
||||||
///
|
|
||||||
/// // SAFETY: We created it with this much capacity earlier,
|
|
||||||
/// // and the previous `copy` has initialized these elements.
|
|
||||||
/// dst.set_len(elts);
|
|
||||||
/// dst
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[doc(alias = "memmove")]
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
|
||||||
pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some functions are defined here because they accidentally got made
|
// 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 {
|
||||||
!ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
|
!ptr.is_null() && ptr as usize % mem::align_of::<T>() == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
||||||
|
/// and destination must *not* overlap.
|
||||||
|
///
|
||||||
|
/// For regions of memory which might overlap, use [`copy`] instead.
|
||||||
|
///
|
||||||
|
/// `copy_nonoverlapping` is semantically equivalent to C's [`memcpy`], but
|
||||||
|
/// with the argument order swapped.
|
||||||
|
///
|
||||||
|
/// [`memcpy`]: https://en.cppreference.com/w/c/string/byte/memcpy
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Behavior is undefined if any of the following conditions are violated:
|
||||||
|
///
|
||||||
|
/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
|
||||||
|
///
|
||||||
|
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
|
||||||
|
///
|
||||||
|
/// * Both `src` and `dst` must be properly aligned.
|
||||||
|
///
|
||||||
|
/// * The region of memory beginning at `src` with a size of `count *
|
||||||
|
/// size_of::<T>()` bytes must *not* overlap with the region of memory
|
||||||
|
/// beginning at `dst` with the same size.
|
||||||
|
///
|
||||||
|
/// Like [`read`], `copy_nonoverlapping` creates a bitwise copy of `T`, regardless of
|
||||||
|
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using *both* the values
|
||||||
|
/// in the region beginning at `*src` and the region beginning at `*dst` can
|
||||||
|
/// [violate memory safety][read-ownership].
|
||||||
|
///
|
||||||
|
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
|
||||||
|
/// `0`, the pointers must be non-null and properly aligned.
|
||||||
|
///
|
||||||
|
/// [`read`]: crate::ptr::read
|
||||||
|
/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
|
||||||
|
/// [valid]: crate::ptr#safety
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Manually implement [`Vec::append`]:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::ptr;
|
||||||
|
///
|
||||||
|
/// /// Moves all the elements of `src` into `dst`, leaving `src` empty.
|
||||||
|
/// fn append<T>(dst: &mut Vec<T>, src: &mut Vec<T>) {
|
||||||
|
/// let src_len = src.len();
|
||||||
|
/// let dst_len = dst.len();
|
||||||
|
///
|
||||||
|
/// // Ensure that `dst` has enough capacity to hold all of `src`.
|
||||||
|
/// dst.reserve(src_len);
|
||||||
|
///
|
||||||
|
/// unsafe {
|
||||||
|
/// // The call to offset is always safe because `Vec` will never
|
||||||
|
/// // allocate more than `isize::MAX` bytes.
|
||||||
|
/// let dst_ptr = dst.as_mut_ptr().offset(dst_len as isize);
|
||||||
|
/// let src_ptr = src.as_ptr();
|
||||||
|
///
|
||||||
|
/// // Truncate `src` without dropping its contents. We do this first,
|
||||||
|
/// // to avoid problems in case something further down panics.
|
||||||
|
/// src.set_len(0);
|
||||||
|
///
|
||||||
|
/// // The two regions cannot overlap because mutable references do
|
||||||
|
/// // not alias, and two different vectors cannot own the same
|
||||||
|
/// // memory.
|
||||||
|
/// ptr::copy_nonoverlapping(src_ptr, dst_ptr, src_len);
|
||||||
|
///
|
||||||
|
/// // Notify `dst` that it now holds the contents of `src`.
|
||||||
|
/// dst.set_len(dst_len + src_len);
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// let mut a = vec!['r'];
|
||||||
|
/// let mut b = vec!['u', 's', 't'];
|
||||||
|
///
|
||||||
|
/// append(&mut a, &mut b);
|
||||||
|
///
|
||||||
|
/// assert_eq!(a, &['r', 'u', 's', 't']);
|
||||||
|
/// assert!(b.is_empty());
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [`Vec::append`]: ../../std/vec/struct.Vec.html#method.append
|
||||||
|
#[doc(alias = "memcpy")]
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
||||||
|
#[inline]
|
||||||
|
pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
|
||||||
|
extern "rust-intrinsic" {
|
||||||
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
||||||
|
pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Perform these checks only at run time
|
||||||
|
/*if cfg!(debug_assertions)
|
||||||
|
&& !(is_aligned_and_not_null(src)
|
||||||
|
&& is_aligned_and_not_null(dst)
|
||||||
|
&& is_nonoverlapping(src, dst, count))
|
||||||
|
{
|
||||||
|
// Not panicking to keep codegen impact smaller.
|
||||||
|
abort();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// SAFETY: the safety contract for `copy_nonoverlapping` must be
|
||||||
|
// upheld by the caller.
|
||||||
|
unsafe { copy_nonoverlapping(src, dst, count) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copies `count * size_of::<T>()` bytes from `src` to `dst`. The source
|
||||||
|
/// and destination may overlap.
|
||||||
|
///
|
||||||
|
/// If the source and destination will *never* overlap,
|
||||||
|
/// [`copy_nonoverlapping`] can be used instead.
|
||||||
|
///
|
||||||
|
/// `copy` is semantically equivalent to C's [`memmove`], but with the argument
|
||||||
|
/// order swapped. Copying takes place as if the bytes were copied from `src`
|
||||||
|
/// to a temporary array and then copied from the array to `dst`.
|
||||||
|
///
|
||||||
|
/// [`memmove`]: https://en.cppreference.com/w/c/string/byte/memmove
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Behavior is undefined if any of the following conditions are violated:
|
||||||
|
///
|
||||||
|
/// * `src` must be [valid] for reads of `count * size_of::<T>()` bytes.
|
||||||
|
///
|
||||||
|
/// * `dst` must be [valid] for writes of `count * size_of::<T>()` bytes.
|
||||||
|
///
|
||||||
|
/// * Both `src` and `dst` must be properly aligned.
|
||||||
|
///
|
||||||
|
/// Like [`read`], `copy` creates a bitwise copy of `T`, regardless of
|
||||||
|
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the values
|
||||||
|
/// in the region beginning at `*src` and the region beginning at `*dst` can
|
||||||
|
/// [violate memory safety][read-ownership].
|
||||||
|
///
|
||||||
|
/// Note that even if the effectively copied size (`count * size_of::<T>()`) is
|
||||||
|
/// `0`, the pointers must be non-null and properly aligned.
|
||||||
|
///
|
||||||
|
/// [`read`]: crate::ptr::read
|
||||||
|
/// [read-ownership]: crate::ptr::read#ownership-of-the-returned-value
|
||||||
|
/// [valid]: crate::ptr#safety
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// Efficiently create a Rust vector from an unsafe buffer:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::ptr;
|
||||||
|
///
|
||||||
|
/// /// # Safety
|
||||||
|
/// ///
|
||||||
|
/// /// * `ptr` must be correctly aligned for its type and non-zero.
|
||||||
|
/// /// * `ptr` must be valid for reads of `elts` contiguous elements of type `T`.
|
||||||
|
/// /// * Those elements must not be used after calling this function unless `T: Copy`.
|
||||||
|
/// # #[allow(dead_code)]
|
||||||
|
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
|
||||||
|
/// let mut dst = Vec::with_capacity(elts);
|
||||||
|
///
|
||||||
|
/// // SAFETY: Our precondition ensures the source is aligned and valid,
|
||||||
|
/// // and `Vec::with_capacity` ensures that we have usable space to write them.
|
||||||
|
/// ptr::copy(ptr, dst.as_mut_ptr(), elts);
|
||||||
|
///
|
||||||
|
/// // SAFETY: We created it with this much capacity earlier,
|
||||||
|
/// // and the previous `copy` has initialized these elements.
|
||||||
|
/// dst.set_len(elts);
|
||||||
|
/// dst
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[doc(alias = "memmove")]
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
||||||
|
#[inline]
|
||||||
|
pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
|
||||||
|
extern "rust-intrinsic" {
|
||||||
|
#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
|
||||||
|
fn copy<T>(src: *const T, dst: *mut T, count: usize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Perform these checks only at run time
|
||||||
|
/*if cfg!(debug_assertions) && !(is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)) {
|
||||||
|
// Not panicking to keep codegen impact smaller.
|
||||||
|
abort();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// SAFETY: the safety contract for `copy` must be upheld by the caller.
|
||||||
|
unsafe { copy(src, dst, count) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
|
/// Sets `count * size_of::<T>()` bytes of memory starting at `dst` to
|
||||||
/// `val`.
|
/// `val`.
|
||||||
///
|
///
|
||||||
|
|
|
@ -682,8 +682,7 @@ pub unsafe fn uninitialized<T>() -> T {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
|
pub fn swap<T>(x: &mut T, y: &mut T) {
|
||||||
pub const fn swap<T>(x: &mut T, y: &mut T) {
|
|
||||||
// SAFETY: the raw pointers have been created from safe mutable references satisfying all the
|
// SAFETY: the raw pointers have been created from safe mutable references satisfying all the
|
||||||
// constraints on `ptr::swap_nonoverlapping_one`
|
// constraints on `ptr::swap_nonoverlapping_one`
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -813,8 +812,7 @@ pub fn take<T: Default>(dest: &mut T) -> T {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
|
#[must_use = "if you don't need the old value, you can just assign the new value directly"]
|
||||||
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
|
pub fn replace<T>(dest: &mut T, src: T) -> T {
|
||||||
pub const fn replace<T>(dest: &mut T, src: T) -> T {
|
|
||||||
// SAFETY: We read from `dest` but directly write `src` into it afterwards,
|
// SAFETY: We read from `dest` but directly write `src` into it afterwards,
|
||||||
// such that the old value is not duplicated. Nothing is dropped and
|
// such that the old value is not duplicated. Nothing is dropped and
|
||||||
// nothing here can panic.
|
// nothing here can panic.
|
||||||
|
|
|
@ -430,8 +430,7 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
|
pub(crate) unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
|
||||||
pub(crate) const unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
|
|
||||||
// NOTE(eddyb) SPIR-V's Logical addressing model doesn't allow for arbitrary
|
// NOTE(eddyb) SPIR-V's Logical addressing model doesn't allow for arbitrary
|
||||||
// reinterpretation of values as (chunkable) byte arrays, and the loop in the
|
// reinterpretation of values as (chunkable) byte arrays, and the loop in the
|
||||||
// block optimization in `swap_nonoverlapping_bytes` is hard to rewrite back
|
// block optimization in `swap_nonoverlapping_bytes` is hard to rewrite back
|
||||||
|
@ -564,8 +563,7 @@ const unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
|
pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
|
||||||
pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
|
|
||||||
// SAFETY: the caller must guarantee that `dst` is valid to be
|
// SAFETY: the caller must guarantee that `dst` is valid to be
|
||||||
// cast to a mutable reference (valid for writes, aligned, initialized),
|
// cast to a mutable reference (valid for writes, aligned, initialized),
|
||||||
// and cannot overlap `src` since `dst` must point to a distinct
|
// and cannot overlap `src` since `dst` must point to a distinct
|
||||||
|
@ -871,14 +869,18 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
|
pub unsafe fn write<T>(dst: *mut T, src: T) {
|
||||||
pub const unsafe fn write<T>(dst: *mut T, src: T) {
|
// We are calling the intrinsics directly to avoid function calls in the generated code
|
||||||
|
// as `intrinsics::copy_nonoverlapping` is a wrapper function.
|
||||||
|
extern "rust-intrinsic" {
|
||||||
|
fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
|
||||||
|
}
|
||||||
|
|
||||||
// SAFETY: the caller must guarantee that `dst` is valid for writes.
|
// SAFETY: the caller must guarantee that `dst` is valid for writes.
|
||||||
// `dst` cannot overlap `src` because the caller has mutable access
|
// `dst` cannot overlap `src` because the caller has mutable access
|
||||||
// to `dst` while `src` is owned by this function.
|
// to `dst` while `src` is owned by this function.
|
||||||
unsafe {
|
unsafe {
|
||||||
copy_nonoverlapping(&src as *const T, dst, 1);
|
copy_nonoverlapping(&src as *const T, dst, 1);
|
||||||
// We are calling the intrinsic directly to avoid function calls in the generated code.
|
|
||||||
intrinsics::forget(src);
|
intrinsics::forget(src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1002,9 +1002,8 @@ impl<T: ?Sized> *mut T {
|
||||||
///
|
///
|
||||||
/// [`ptr::write`]: crate::ptr::write()
|
/// [`ptr::write`]: crate::ptr::write()
|
||||||
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
#[stable(feature = "pointer_methods", since = "1.26.0")]
|
||||||
#[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub const unsafe fn write(self, val: T)
|
pub unsafe fn write(self, val: T)
|
||||||
where
|
where
|
||||||
T: Sized,
|
T: Sized,
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,53 +49,3 @@ fn mut_ptr_read() {
|
||||||
const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() };
|
const UNALIGNED: u16 = unsafe { UNALIGNED_PTR.read_unaligned() };
|
||||||
assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
|
assert_eq!(UNALIGNED, u16::from_ne_bytes([0x23, 0x45]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn write() {
|
|
||||||
use core::ptr;
|
|
||||||
|
|
||||||
const fn write_aligned() -> i32 {
|
|
||||||
let mut res = 0;
|
|
||||||
unsafe {
|
|
||||||
ptr::write(&mut res as *mut _, 42);
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
|
||||||
const ALIGNED: i32 = write_aligned();
|
|
||||||
assert_eq!(ALIGNED, 42);
|
|
||||||
|
|
||||||
const fn write_unaligned() -> [u16; 2] {
|
|
||||||
let mut two_aligned = [0u16; 2];
|
|
||||||
unsafe {
|
|
||||||
let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
|
|
||||||
ptr::write_unaligned(unaligned_ptr, u16::from_ne_bytes([0x23, 0x45]));
|
|
||||||
}
|
|
||||||
two_aligned
|
|
||||||
}
|
|
||||||
const UNALIGNED: [u16; 2] = write_unaligned();
|
|
||||||
assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn mut_ptr_write() {
|
|
||||||
const fn aligned() -> i32 {
|
|
||||||
let mut res = 0;
|
|
||||||
unsafe {
|
|
||||||
(&mut res as *mut i32).write(42);
|
|
||||||
}
|
|
||||||
res
|
|
||||||
}
|
|
||||||
const ALIGNED: i32 = aligned();
|
|
||||||
assert_eq!(ALIGNED, 42);
|
|
||||||
|
|
||||||
const fn write_unaligned() -> [u16; 2] {
|
|
||||||
let mut two_aligned = [0u16; 2];
|
|
||||||
unsafe {
|
|
||||||
let unaligned_ptr = (two_aligned.as_mut_ptr() as *mut u8).add(1) as *mut u16;
|
|
||||||
unaligned_ptr.write_unaligned(u16::from_ne_bytes([0x23, 0x45]));
|
|
||||||
}
|
|
||||||
two_aligned
|
|
||||||
}
|
|
||||||
const UNALIGNED: [u16; 2] = write_unaligned();
|
|
||||||
assert_eq!(UNALIGNED, [u16::from_ne_bytes([0x00, 0x23]), u16::from_ne_bytes([0x45, 0x00])]);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
// error-pattern: any use of this value will cause an error
|
|
||||||
|
|
||||||
#![feature(const_ptr_read)]
|
|
||||||
#![feature(const_ptr_offset)]
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
use std::ptr;
|
|
||||||
|
|
||||||
const DATA: [u32; 1] = [42];
|
|
||||||
|
|
||||||
const PAST_END_PTR: *const u32 = unsafe { DATA.as_ptr().add(1) };
|
|
||||||
|
|
||||||
const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
|
|
||||||
const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
|
|
||||||
const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
|
||||||
|
|
|
||||||
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
|
||||||
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
|
||||||
| inside `_READ` at $DIR/out_of_bounds_read.rs:13:33
|
|
||||||
|
|
|
||||||
::: $DIR/out_of_bounds_read.rs:13:5
|
|
||||||
|
|
|
||||||
LL | const _READ: u32 = unsafe { ptr::read(PAST_END_PTR) };
|
|
||||||
| ------------------------------------------------------
|
|
||||||
|
|
|
||||||
= note: `#[deny(const_err)]` on by default
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
|
||||||
|
|
|
||||||
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
|
||||||
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
|
||||||
| inside `ptr::const_ptr::<impl *const u32>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
|
|
||||||
| inside `_CONST_READ` at $DIR/out_of_bounds_read.rs:14:39
|
|
||||||
|
|
|
||||||
::: $DIR/out_of_bounds_read.rs:14:5
|
|
||||||
|
|
|
||||||
LL | const _CONST_READ: u32 = unsafe { PAST_END_PTR.read() };
|
|
||||||
| --------------------------------------------------------
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
|
||||||
|
|
|
||||||
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
| |
|
|
||||||
| memory access failed: pointer must be in-bounds at offset 8, but is outside bounds of alloc6 which has size 4
|
|
||||||
| inside `std::ptr::read::<u32>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
|
||||||
| inside `ptr::mut_ptr::<impl *mut u32>::read` at $SRC_DIR/core/src/ptr/mut_ptr.rs:LL:COL
|
|
||||||
| inside `_MUT_READ` at $DIR/out_of_bounds_read.rs:15:37
|
|
||||||
|
|
|
||||||
::: $DIR/out_of_bounds_read.rs:15:5
|
|
||||||
|
|
|
||||||
LL | const _MUT_READ: u32 = unsafe { (PAST_END_PTR as *mut u32).read() };
|
|
||||||
| --------------------------------------------------------------------
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
// ignore-tidy-linelength
|
|
||||||
#![feature(const_mut_refs, const_intrinsic_copy, const_ptr_offset)]
|
|
||||||
use std::{ptr, mem};
|
|
||||||
|
|
||||||
const COPY_ZERO: () = unsafe {
|
|
||||||
// Since we are not copying anything, this should be allowed.
|
|
||||||
let src = ();
|
|
||||||
let mut dst = ();
|
|
||||||
ptr::copy_nonoverlapping(&src as *const _ as *const i32, &mut dst as *mut _ as *mut i32, 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
const COPY_OOB_1: () = unsafe {
|
|
||||||
let mut x = 0i32;
|
|
||||||
let dangle = (&mut x as *mut i32).wrapping_add(10);
|
|
||||||
// Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs.
|
|
||||||
ptr::copy_nonoverlapping(0x100 as *const i32, dangle, 0); //~ ERROR any use of this value will cause an error
|
|
||||||
//~| memory access failed: pointer must be in-bounds
|
|
||||||
//~| previously accepted
|
|
||||||
};
|
|
||||||
const COPY_OOB_2: () = unsafe {
|
|
||||||
let x = 0i32;
|
|
||||||
let dangle = (&x as *const i32).wrapping_add(10);
|
|
||||||
// Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs.
|
|
||||||
ptr::copy_nonoverlapping(dangle, 0x100 as *mut i32, 0); //~ ERROR any use of this value will cause an error
|
|
||||||
//~| memory access failed: pointer must be in-bounds
|
|
||||||
//~| previously accepted
|
|
||||||
};
|
|
||||||
|
|
||||||
const COPY_SIZE_OVERFLOW: () = unsafe {
|
|
||||||
let x = 0;
|
|
||||||
let mut y = 0;
|
|
||||||
ptr::copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1)); //~ ERROR any use of this value will cause an error
|
|
||||||
//~| overflow computing total size of `copy`
|
|
||||||
//~| previously accepted
|
|
||||||
};
|
|
||||||
const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe {
|
|
||||||
let x = 0;
|
|
||||||
let mut y = 0;
|
|
||||||
ptr::copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1)); //~ ERROR any use of this value will cause an error
|
|
||||||
//~| overflow computing total size of `copy_nonoverlapping`
|
|
||||||
//~| previously accepted
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $DIR/copy-intrinsic.rs:16:5
|
|
||||||
|
|
|
||||||
LL | / const COPY_OOB_1: () = unsafe {
|
|
||||||
LL | | let mut x = 0i32;
|
|
||||||
LL | | let dangle = (&mut x as *mut i32).wrapping_add(10);
|
|
||||||
LL | | // Even if the first ptr is an int ptr and this is a ZST copy, we should detect dangling 2nd ptrs.
|
|
||||||
LL | | ptr::copy_nonoverlapping(0x100 as *const i32, dangle, 0);
|
|
||||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc4 which has size 4
|
|
||||||
LL | |
|
|
||||||
LL | |
|
|
||||||
LL | | };
|
|
||||||
| |__-
|
|
||||||
|
|
|
||||||
= note: `#[deny(const_err)]` on by default
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $DIR/copy-intrinsic.rs:24:5
|
|
||||||
|
|
|
||||||
LL | / const COPY_OOB_2: () = unsafe {
|
|
||||||
LL | | let x = 0i32;
|
|
||||||
LL | | let dangle = (&x as *const i32).wrapping_add(10);
|
|
||||||
LL | | // Even if the second ptr is an int ptr and this is a ZST copy, we should detect dangling 1st ptrs.
|
|
||||||
LL | | ptr::copy_nonoverlapping(dangle, 0x100 as *mut i32, 0);
|
|
||||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 40, but is outside bounds of alloc6 which has size 4
|
|
||||||
LL | |
|
|
||||||
LL | |
|
|
||||||
LL | | };
|
|
||||||
| |__-
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $DIR/copy-intrinsic.rs:32:5
|
|
||||||
|
|
|
||||||
LL | / const COPY_SIZE_OVERFLOW: () = unsafe {
|
|
||||||
LL | | let x = 0;
|
|
||||||
LL | | let mut y = 0;
|
|
||||||
LL | | ptr::copy(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
|
|
||||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy`
|
|
||||||
LL | |
|
|
||||||
LL | |
|
|
||||||
LL | | };
|
|
||||||
| |__-
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: any use of this value will cause an error
|
|
||||||
--> $DIR/copy-intrinsic.rs:39:5
|
|
||||||
|
|
|
||||||
LL | / const COPY_NONOVERLAPPING_SIZE_OVERFLOW: () = unsafe {
|
|
||||||
LL | | let x = 0;
|
|
||||||
LL | | let mut y = 0;
|
|
||||||
LL | | ptr::copy_nonoverlapping(&x, &mut y, 1usize << (mem::size_of::<usize>() * 8 - 1));
|
|
||||||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ overflow computing total size of `copy_nonoverlapping`
|
|
||||||
LL | |
|
|
||||||
LL | |
|
|
||||||
LL | | };
|
|
||||||
| |__-
|
|
||||||
|
|
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
|
||||||
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
|
||||||
|
|
9
src/test/ui/intrinsics/issue-84297-reifying-copy.rs
Normal file
9
src/test/ui/intrinsics/issue-84297-reifying-copy.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _unused = if true {
|
||||||
|
core::ptr::copy::<i32>
|
||||||
|
} else {
|
||||||
|
core::ptr::copy_nonoverlapping::<i32>
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
// check-fail
|
// check-fail
|
||||||
|
|
||||||
#![feature(intrinsics)]
|
#![feature(core_intrinsics, intrinsics)]
|
||||||
|
|
||||||
fn a() {
|
fn a() {
|
||||||
let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute;
|
let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute;
|
||||||
|
@ -14,8 +14,8 @@ fn b() {
|
||||||
|
|
||||||
fn c() {
|
fn c() {
|
||||||
let _ = [
|
let _ = [
|
||||||
std::intrinsics::copy_nonoverlapping::<i32>,
|
std::intrinsics::likely,
|
||||||
std::intrinsics::copy::<i32>,
|
std::intrinsics::unlikely,
|
||||||
//~^ ERROR cannot coerce
|
//~^ ERROR cannot coerce
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,11 +22,11 @@ LL | let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize)
|
||||||
error[E0308]: cannot coerce intrinsics to function pointers
|
error[E0308]: cannot coerce intrinsics to function pointers
|
||||||
--> $DIR/reify-intrinsic.rs:18:9
|
--> $DIR/reify-intrinsic.rs:18:9
|
||||||
|
|
|
|
||||||
LL | std::intrinsics::copy::<i32>,
|
LL | std::intrinsics::unlikely,
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
|
||||||
|
|
|
|
||||||
= note: expected type `unsafe extern "rust-intrinsic" fn(_, _, _) {copy_nonoverlapping::<i32>}`
|
= note: expected type `extern "rust-intrinsic" fn(_) -> _ {likely}`
|
||||||
found fn item `unsafe extern "rust-intrinsic" fn(_, _, _) {std::intrinsics::copy::<i32>}`
|
found fn item `extern "rust-intrinsic" fn(_) -> _ {unlikely}`
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ const fn g(x: &mut [u32; 8]) {
|
||||||
//~| ERROR mutable references are not allowed
|
//~| ERROR mutable references are not allowed
|
||||||
//~| ERROR use of mutable static is unsafe
|
//~| ERROR use of mutable static is unsafe
|
||||||
//~| constant functions cannot refer to statics
|
//~| constant functions cannot refer to statics
|
||||||
|
//~| ERROR calls in constant functions are limited to constant functions
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -30,6 +30,12 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||||
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
= note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
|
||||||
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
= help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0015]: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
--> $DIR/thread-local-static.rs:9:5
|
||||||
|
|
|
||||||
|
LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
|
error[E0133]: use of mutable static is unsafe and requires unsafe function or block
|
||||||
--> $DIR/thread-local-static.rs:9:23
|
--> $DIR/thread-local-static.rs:9:23
|
||||||
|
|
|
|
||||||
|
@ -38,7 +44,7 @@ LL | std::mem::swap(x, &mut STATIC_VAR_2)
|
||||||
|
|
|
|
||||||
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
= note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0013, E0133, E0658.
|
Some errors have detailed explanations: E0013, E0015, E0133, E0658.
|
||||||
For more information about an error, try `rustc --explain E0013`.
|
For more information about an error, try `rustc --explain E0013`.
|
||||||
|
|
|
@ -116,8 +116,8 @@ pub const PERMISSIONS_FROM_MODE: [&str; 7] = ["std", "os", "imp", "unix", "fs",
|
||||||
pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
|
pub const POLL: [&str; 4] = ["core", "task", "poll", "Poll"];
|
||||||
pub const POLL_PENDING: [&str; 5] = ["core", "task", "poll", "Poll", "Pending"];
|
pub const POLL_PENDING: [&str; 5] = ["core", "task", "poll", "Poll", "Pending"];
|
||||||
pub const POLL_READY: [&str; 5] = ["core", "task", "poll", "Poll", "Ready"];
|
pub const POLL_READY: [&str; 5] = ["core", "task", "poll", "Poll", "Ready"];
|
||||||
pub const PTR_COPY: [&str; 4] = ["core", "intrinsics", "", "copy"];
|
pub const PTR_COPY: [&str; 3] = ["core", "intrinsics", "copy"];
|
||||||
pub const PTR_COPY_NONOVERLAPPING: [&str; 4] = ["core", "intrinsics", "", "copy_nonoverlapping"];
|
pub const PTR_COPY_NONOVERLAPPING: [&str; 3] = ["core", "intrinsics", "copy_nonoverlapping"];
|
||||||
pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"];
|
pub const PTR_EQ: [&str; 3] = ["core", "ptr", "eq"];
|
||||||
pub const PTR_NULL: [&str; 3] = ["core", "ptr", "null"];
|
pub const PTR_NULL: [&str; 3] = ["core", "ptr", "null"];
|
||||||
pub const PTR_NULL_MUT: [&str; 3] = ["core", "ptr", "null_mut"];
|
pub const PTR_NULL_MUT: [&str; 3] = ["core", "ptr", "null_mut"];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue