summary refs log tree commit diff
path: root/library/core/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-05-03 20:56:34 +0000
committerbors <bors@rust-lang.org>2021-05-03 20:56:34 +0000
commit88f19c6dab716c6281af7602e30f413e809c5974 (patch)
treef7af4b32537043e9dfbdd884f811ee8fe0122d90 /library/core/src
parent9a1dfd2dc5c42a2ee84b4606aa08cdadf8c0ee87 (diff)
parent47c7b9c5788055ddbbb59d0d1fc909af7b48668d (diff)
downloadrust-1.52.0.tar.gz
rust-1.52.0.zip
Auto merge of #84864 - Mark-Simulacrum:stable-next, r=Mark-Simulacrum 1.52.0
[stable] 1.52.0 release

This includes the release notes (#84183) as well as cherry-picked commits from:

* [beta] revert PR #77885 #84710
* [beta] remove assert_matches #84759
* Revert PR 81473 to resolve (on beta) issues 81626 and 81658. #83171
* [beta] rustdoc revert deref recur #84868
*  Fix ICE of for-loop mut borrowck where no suggestions are available #83401

Additionally in "fresh work" we're also:

* reverting: directly expose copy and copy_nonoverlapping intrinsics #81238 to avoid https://github.com/rust-lang/rust/issues/84297 on 1.52
Diffstat (limited to 'library/core/src')
-rw-r--r--library/core/src/intrinsics.rs337
-rw-r--r--library/core/src/macros/mod.rs90
-rw-r--r--library/core/src/mem/mod.rs6
-rw-r--r--library/core/src/panicking.rs69
-rw-r--r--library/core/src/ptr/mod.rs16
-rw-r--r--library/core/src/ptr/mut_ptr.rs3
6 files changed, 221 insertions, 300 deletions
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index b5371d6b69d..073210c5b68 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -1742,157 +1742,6 @@ extern "rust-intrinsic" {
     /// Allocate at compile time. Should not be called at runtime.
     #[rustc_const_unstable(feature = "const_heap", issue = "79597")]
     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
@@ -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
 }
 
+/// 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")]
+        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
 /// `val`.
 ///
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 99894b5605e..a0a8eecbc25 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -110,60 +110,6 @@ macro_rules! assert_ne {
     });
 }
 
-/// Asserts that an expression matches any of the given patterns.
-///
-/// Like in a `match` expression, the pattern can be optionally followed by `if`
-/// and a guard expression that has access to names bound by the pattern.
-///
-/// On panic, this macro will print the value of the expression with its
-/// debug representation.
-///
-/// Like [`assert!`], this macro has a second form, where a custom
-/// panic message can be provided.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(assert_matches)]
-///
-/// let a = 1u32.checked_add(2);
-/// let b = 1u32.checked_sub(2);
-/// assert_matches!(a, Some(_));
-/// assert_matches!(b, None);
-///
-/// let c = Ok("abc".to_string());
-/// assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
-/// ```
-#[macro_export]
-#[unstable(feature = "assert_matches", issue = "82775")]
-#[allow_internal_unstable(core_panic)]
-macro_rules! assert_matches {
-    ($left:expr, $( $pattern:pat )|+ $( if $guard: expr )? $(,)?) => ({
-        match $left {
-            $( $pattern )|+ $( if $guard )? => {}
-            ref left_val => {
-                $crate::panicking::assert_matches_failed(
-                    left_val,
-                    $crate::stringify!($($pattern)|+ $(if $guard)?),
-                    $crate::option::Option::None
-                );
-            }
-        }
-    });
-    ($left:expr, $( $pattern:pat )|+ $( if $guard: expr )?, $($arg:tt)+) => ({
-        match $left {
-            $( $pattern )|+ $( if $guard )? => {}
-            ref left_val => {
-                $crate::panicking::assert_matches_failed(
-                    left_val,
-                    $crate::stringify!($($pattern)|+ $(if $guard)?),
-                    $crate::option::Option::Some($crate::format_args!($($arg)+))
-                );
-            }
-        }
-    });
-}
-
 /// Asserts that a boolean expression is `true` at runtime.
 ///
 /// This will invoke the [`panic!`] macro if the provided expression cannot be
@@ -262,42 +208,6 @@ macro_rules! debug_assert_ne {
     ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_ne!($($arg)*); })
 }
 
-/// Asserts that an expression matches any of the given patterns.
-///
-/// Like in a `match` expression, the pattern can be optionally followed by `if`
-/// and a guard expression that has access to names bound by the pattern.
-///
-/// On panic, this macro will print the value of the expression with its
-/// debug representation.
-///
-/// Unlike [`assert_matches!`], `debug_assert_matches!` statements are only
-/// enabled in non optimized builds by default. An optimized build will not
-/// execute `debug_assert_matches!` statements unless `-C debug-assertions` is
-/// passed to the compiler. This makes `debug_assert_matches!` useful for
-/// checks that are too expensive to be present in a release build but may be
-/// helpful during development. The result of expanding `debug_assert_matches!`
-/// is always type checked.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(assert_matches)]
-///
-/// let a = 1u32.checked_add(2);
-/// let b = 1u32.checked_sub(2);
-/// debug_assert_matches!(a, Some(_));
-/// debug_assert_matches!(b, None);
-///
-/// let c = Ok("abc".to_string());
-/// debug_assert_matches!(c, Ok(x) | Err(x) if x.len() < 100);
-/// ```
-#[macro_export]
-#[unstable(feature = "assert_matches", issue = "82775")]
-#[allow_internal_unstable(assert_matches)]
-macro_rules! debug_assert_matches {
-    ($($arg:tt)*) => (if $crate::cfg!(debug_assertions) { $crate::assert_matches!($($arg)*); })
-}
-
 /// Returns whether the given expression matches any of the given patterns.
 ///
 /// Like in a `match` expression, the pattern can be optionally followed by `if`
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 37e8d65db6a..c4f0d917674 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -682,8 +682,7 @@ pub unsafe fn uninitialized<T>() -> T {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
-pub const fn swap<T>(x: &mut T, y: &mut T) {
+pub fn swap<T>(x: &mut T, y: &mut T) {
     // SAFETY: the raw pointers have been created from safe mutable references satisfying all the
     // constraints on `ptr::swap_nonoverlapping_one`
     unsafe {
@@ -813,8 +812,7 @@ pub fn take<T: Default>(dest: &mut T) -> T {
 #[inline]
 #[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"]
-#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
-pub const fn replace<T>(dest: &mut T, src: T) -> T {
+pub fn replace<T>(dest: &mut T, src: T) -> T {
     // SAFETY: We read from `dest` but directly write `src` into it afterwards,
     // such that the old value is not duplicated. Nothing is dropped and
     // nothing here can panic.
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index 3e3e96fcd7f..35d9b2c5d26 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -97,7 +97,6 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
 pub enum AssertKind {
     Eq,
     Ne,
-    Match,
 }
 
 /// Internal function for `assert_eq!` and `assert_ne!` macros
@@ -114,54 +113,32 @@ where
     T: fmt::Debug + ?Sized,
     U: fmt::Debug + ?Sized,
 {
-    assert_failed_inner(kind, &left, &right, args)
-}
-
-/// Internal function for `assert_match!`
-#[cold]
-#[track_caller]
-#[doc(hidden)]
-pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
-    left: &T,
-    right: &str,
-    args: Option<fmt::Arguments<'_>>,
-) -> ! {
-    // Use the Display implementation to display the pattern.
-    struct Pattern<'a>(&'a str);
-    impl fmt::Debug for Pattern<'_> {
-        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            fmt::Display::fmt(self.0, f)
-        }
-    }
-    assert_failed_inner(AssertKind::Match, &left, &Pattern(right), args);
-}
-
-/// Non-generic version of the above functions, to avoid code bloat.
-#[track_caller]
-fn assert_failed_inner(
-    kind: AssertKind,
-    left: &dyn fmt::Debug,
-    right: &dyn fmt::Debug,
-    args: Option<fmt::Arguments<'_>>,
-) -> ! {
-    let op = match kind {
-        AssertKind::Eq => "==",
-        AssertKind::Ne => "!=",
-        AssertKind::Match => "matches",
-    };
-
-    match args {
-        Some(args) => panic!(
-            r#"assertion failed: `(left {} right)`
+    #[track_caller]
+    fn inner(
+        kind: AssertKind,
+        left: &dyn fmt::Debug,
+        right: &dyn fmt::Debug,
+        args: Option<fmt::Arguments<'_>>,
+    ) -> ! {
+        let op = match kind {
+            AssertKind::Eq => "==",
+            AssertKind::Ne => "!=",
+        };
+
+        match args {
+            Some(args) => panic!(
+                r#"assertion failed: `(left {} right)`
   left: `{:?}`,
  right: `{:?}`: {}"#,
-            op, left, right, args
-        ),
-        None => panic!(
-            r#"assertion failed: `(left {} right)`
+                op, left, right, args
+            ),
+            None => panic!(
+                r#"assertion failed: `(left {} right)`
   left: `{:?}`,
  right: `{:?}`"#,
-            op, left, right,
-        ),
+                op, left, right,
+            ),
+        }
     }
+    inner(kind, &left, &right, args)
 }
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 3a27f01444b..fd24469bd3c 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -463,8 +463,7 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
 }
 
 #[inline]
-#[rustc_const_unstable(feature = "const_swap", issue = "83163")]
-pub(crate) const unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
+pub(crate) unsafe fn swap_nonoverlapping_one<T>(x: *mut T, y: *mut T) {
     // For types smaller than the block optimization below,
     // just swap directly to avoid pessimizing codegen.
     if mem::size_of::<T>() < 32 {
@@ -584,8 +583,7 @@ const unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_replace", issue = "83164")]
-pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
+pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
     // SAFETY: the caller must guarantee that `dst` is valid to be
     // cast to a mutable reference (valid for writes, aligned, initialized),
     // and cannot overlap `src` since `dst` must point to a distinct
@@ -898,14 +896,18 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
 /// ```
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
-pub const unsafe fn write<T>(dst: *mut T, src: T) {
+pub 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.
     // `dst` cannot overlap `src` because the caller has mutable access
     // to `dst` while `src` is owned by this function.
     unsafe {
         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);
     }
 }
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index fa09cf85435..a9de2333bc0 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1013,9 +1013,8 @@ impl<T: ?Sized> *mut T {
     ///
     /// [`ptr::write`]: crate::ptr::write()
     #[stable(feature = "pointer_methods", since = "1.26.0")]
-    #[rustc_const_unstable(feature = "const_ptr_write", issue = "none")]
     #[inline]
-    pub const unsafe fn write(self, val: T)
+    pub unsafe fn write(self, val: T)
     where
         T: Sized,
     {