about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch13
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs16
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs18
-rw-r--r--compiler/rustc_mir_transform/src/jump_threading.rs4
-rw-r--r--library/core/src/alloc/global.rs32
-rw-r--r--library/core/src/cell.rs51
-rw-r--r--library/core/src/cell/once.rs3
-rw-r--r--library/core/src/cmp.rs356
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/sync/atomic.rs6
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--tests/ui/asm/const-error.rs6
-rw-r--r--tests/ui/asm/const-error.stderr9
13 files changed, 299 insertions, 217 deletions
diff --git a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch
index a3f370af916..646928893e9 100644
--- a/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0027-stdlib-128bit-atomic-operations.patch
@@ -82,19 +82,6 @@ index d9de37e..8293fce 100644
  #[cfg(target_has_atomic_load_store = "ptr")]
  macro_rules! atomic_int_ptr_sized {
      ( $($target_pointer_width:literal $align:literal)* ) => { $(
-diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
-index 58b9ba4..91bbd0a 100644
---- a/library/core/src/cell.rs
-+++ b/library/core/src/cell.rs
-@@ -2246,8 +2246,6 @@ unsafe_cell_primitive_into_inner! {
-     u32 "32"
-     i64 "64"
-     u64 "64"
--    i128 "128"
--    u128 "128"
-     isize "ptr"
-     usize "ptr"
- }
 --
 2.26.2.7.g19db9cfb68
 
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 89d4c460160..b34f5b48b78 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -221,7 +221,9 @@ pub enum Const<'tcx> {
 }
 
 impl<'tcx> Const<'tcx> {
-    pub fn identity_unevaluated(
+    /// Creates an unevaluated const from a `DefId` for a const item.
+    /// The binders of the const item still need to be instantiated.
+    pub fn from_unevaluated(
         tcx: TyCtxt<'tcx>,
         def_id: DefId,
     ) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
@@ -329,18 +331,6 @@ impl<'tcx> Const<'tcx> {
         }
     }
 
-    /// Normalizes the constant to a value or an error if possible.
-    #[inline]
-    pub fn normalize(self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
-        match self.eval(tcx, param_env, DUMMY_SP) {
-            Ok(val) => Self::Val(val, self.ty()),
-            Err(ErrorHandled::Reported(guar, _span)) => {
-                Self::Ty(Ty::new_error(tcx, guar.into()), ty::Const::new_error(tcx, guar.into()))
-            }
-            Err(ErrorHandled::TooGeneric(_span)) => self,
-        }
-    }
-
     #[inline]
     pub fn try_eval_scalar(
         self,
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index fbd45f59a4f..2ffad0b4834 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -699,23 +699,17 @@ impl<'tcx> Cx<'tcx> {
                             }
                         }
                         hir::InlineAsmOperand::Const { ref anon_const } => {
-                            let value = mir::Const::identity_unevaluated(
-                                tcx,
-                                anon_const.def_id.to_def_id(),
-                            )
-                            .instantiate_identity()
-                            .normalize(tcx, self.param_env);
+                            let value =
+                                mir::Const::from_unevaluated(tcx, anon_const.def_id.to_def_id())
+                                    .instantiate_identity();
                             let span = tcx.def_span(anon_const.def_id);
 
                             InlineAsmOperand::Const { value, span }
                         }
                         hir::InlineAsmOperand::SymFn { ref anon_const } => {
-                            let value = mir::Const::identity_unevaluated(
-                                tcx,
-                                anon_const.def_id.to_def_id(),
-                            )
-                            .instantiate_identity()
-                            .normalize(tcx, self.param_env);
+                            let value =
+                                mir::Const::from_unevaluated(tcx, anon_const.def_id.to_def_id())
+                                    .instantiate_identity();
                             let span = tcx.def_span(anon_const.def_id);
 
                             InlineAsmOperand::SymFn { value, span }
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index 9d85b5ba5a7..91fbc91e1e7 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -516,9 +516,7 @@ impl<'a, 'tcx> TOFinder<'a, 'tcx> {
                     // Avoid handling them, though this could be extended in the future.
                     return;
                 }
-                let Some(value) =
-                    value.const_.normalize(self.tcx, self.param_env).try_to_scalar_int()
-                else {
+                let Some(value) = value.const_.try_eval_scalar_int(self.tcx, self.param_env) else {
                     return;
                 };
                 let conds = conditions.map(self.arena, |c| Condition {
diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs
index a6f799c4a7d..68f00d07529 100644
--- a/library/core/src/alloc/global.rs
+++ b/library/core/src/alloc/global.rs
@@ -124,8 +124,8 @@ pub unsafe trait GlobalAlloc {
     ///
     /// # Safety
     ///
-    /// This function is unsafe because undefined behavior can result
-    /// if the caller does not ensure that `layout` has non-zero size.
+    /// `layout` must have non-zero size. Attempting to allocate for a zero-sized `layout` may
+    /// result in undefined behavior.
     ///
     /// (Extension subtraits might provide more specific bounds on
     /// behavior, e.g., guarantee a sentinel address or a null pointer
@@ -156,14 +156,14 @@ pub unsafe trait GlobalAlloc {
     ///
     /// # Safety
     ///
-    /// This function is unsafe because undefined behavior can result
-    /// if the caller does not ensure all of the following:
+    /// The caller must ensure:
     ///
-    /// * `ptr` must denote a block of memory currently allocated via
-    ///   this allocator,
+    /// * `ptr` is a block of memory currently allocated via this allocator and,
     ///
-    /// * `layout` must be the same layout that was used
-    ///   to allocate that block of memory.
+    /// * `layout` is the same layout that was used to allocate that block of
+    ///   memory.
+    ///
+    /// Otherwise undefined behavior can result.
     #[stable(feature = "global_alloc", since = "1.28.0")]
     unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout);
 
@@ -172,7 +172,8 @@ pub unsafe trait GlobalAlloc {
     ///
     /// # Safety
     ///
-    /// This function is unsafe for the same reasons that `alloc` is.
+    /// The caller has to ensure that `layout` has non-zero size. Like `alloc`
+    /// zero sized `layout` can result in undefined behaviour.
     /// However the allocated block of memory is guaranteed to be initialized.
     ///
     /// # Errors
@@ -220,20 +221,21 @@ pub unsafe trait GlobalAlloc {
     ///
     /// # Safety
     ///
-    /// This function is unsafe because undefined behavior can result
-    /// if the caller does not ensure all of the following:
+    /// The caller must ensure that:
     ///
-    /// * `ptr` must be currently allocated via this allocator,
+    /// * `ptr` is allocated via this allocator,
     ///
-    /// * `layout` must be the same layout that was used
+    /// * `layout` is the same layout that was used
     ///   to allocate that block of memory,
     ///
-    /// * `new_size` must be greater than zero.
+    /// * `new_size` is greater than zero.
     ///
     /// * `new_size`, when rounded up to the nearest multiple of `layout.align()`,
-    ///   must not overflow `isize` (i.e., the rounded value must be less than or
+    ///   does not overflow `isize` (i.e., the rounded value must be less than or
     ///   equal to `isize::MAX`).
     ///
+    /// If these are not followed, undefined behaviour can result.
+    ///
     /// (Extension subtraits might provide more specific bounds on
     /// behavior, e.g., guarantee a sentinel address or a null pointer
     /// in response to a zero-size allocation request.)
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index c99f1aece4f..de212581e82 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -514,7 +514,8 @@ impl<T> Cell<T> {
     /// assert_eq!(five, 5);
     /// ```
     #[stable(feature = "move_cell", since = "1.17.0")]
-    #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
+    #[rustc_const_stable(feature = "const_cell_into_inner", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_allow_const_fn_unstable(const_precise_live_drops)]
     pub const fn into_inner(self) -> T {
         self.value.into_inner()
     }
@@ -857,7 +858,8 @@ impl<T> RefCell<T> {
     /// let five = c.into_inner();
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
+    #[rustc_const_stable(feature = "const_cell_into_inner", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_allow_const_fn_unstable(const_precise_live_drops)]
     #[inline]
     pub const fn into_inner(self) -> T {
         // Since this function takes `self` (the `RefCell`) by value, the
@@ -2100,8 +2102,8 @@ impl<T> UnsafeCell<T> {
     /// ```
     #[inline(always)]
     #[stable(feature = "rust1", since = "1.0.0")]
-    // When this is const stabilized, please remove `primitive_into_inner` below.
-    #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
+    #[rustc_const_stable(feature = "const_cell_into_inner", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_allow_const_fn_unstable(const_precise_live_drops)]
     pub const fn into_inner(self) -> T {
         self.value
     }
@@ -2247,47 +2249,6 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
 #[unstable(feature = "dispatch_from_dyn", issue = "none")]
 impl<T: DispatchFromDyn<U>, U> DispatchFromDyn<UnsafeCell<U>> for UnsafeCell<T> {}
 
-// Special cases of UnsafeCell::into_inner where T is a primitive. These are
-// used by Atomic*::into_inner.
-//
-// The real UnsafeCell::into_inner cannot be used yet in a stable const function.
-// That is blocked on a "precise drop analysis" unstable const feature.
-// https://github.com/rust-lang/rust/issues/73255
-macro_rules! unsafe_cell_primitive_into_inner {
-    ($($primitive:ident $atomic:literal)*) => {
-        $(
-            #[cfg(target_has_atomic_load_store = $atomic)]
-            impl UnsafeCell<$primitive> {
-                pub(crate) const fn primitive_into_inner(self) -> $primitive {
-                    self.value
-                }
-            }
-        )*
-    };
-}
-
-unsafe_cell_primitive_into_inner! {
-    i8 "8"
-    u8 "8"
-    i16 "16"
-    u16 "16"
-    i32 "32"
-    u32 "32"
-    i64 "64"
-    u64 "64"
-    i128 "128"
-    u128 "128"
-    isize "ptr"
-    usize "ptr"
-}
-
-#[cfg(target_has_atomic_load_store = "ptr")]
-impl<T> UnsafeCell<*mut T> {
-    pub(crate) const fn primitive_into_inner(self) -> *mut T {
-        self.value
-    }
-}
-
 /// [`UnsafeCell`], but [`Sync`].
 ///
 /// This is just an `UnsafeCell`, except it implements `Sync`
diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs
index 87df8a4e272..14c587e0c48 100644
--- a/library/core/src/cell/once.rs
+++ b/library/core/src/cell/once.rs
@@ -309,7 +309,8 @@ impl<T> OnceCell<T> {
     /// ```
     #[inline]
     #[stable(feature = "once_cell", since = "1.70.0")]
-    #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")]
+    #[rustc_const_stable(feature = "const_cell_into_inner", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_allow_const_fn_unstable(const_precise_live_drops)]
     pub const fn into_inner(self) -> Option<T> {
         // Because `into_inner` takes `self` by value, the compiler statically verifies
         // that it is not currently borrowed. So it is safe to move out `Option<T>`.
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 818a36002e7..4377b4993b8 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -275,49 +275,56 @@ pub macro PartialEq($item:item) {
 /// Trait for comparisons corresponding to [equivalence relations](
 /// https://en.wikipedia.org/wiki/Equivalence_relation).
 ///
-/// This means, that in addition to `a == b` and `a != b` being strict inverses,
-/// the relation must be (for all `a`, `b` and `c`):
+/// The primary difference to [`PartialEq`] is the additional requirement for reflexivity. A type
+/// that implements [`PartialEq`] guarantees that for all `a`, `b` and `c`:
 ///
-/// - reflexive: `a == a`;
-/// - symmetric: `a == b` implies `b == a` (required by `PartialEq` as well); and
-/// - transitive: `a == b` and `b == c` implies `a == c` (required by `PartialEq` as well).
+/// - symmetric: `a == b` implies `b == a` and `a != b` implies `!(a == b)`
+/// - transitive: `a == b` and `b == c` implies `a == c`
 ///
-/// This property cannot be checked by the compiler, and therefore `Eq` implies
-/// [`PartialEq`], and has no extra methods.
+/// `Eq`, which builds on top of [`PartialEq`] also implies:
+///
+/// - reflexive: `a == a`
+///
+/// This property cannot be checked by the compiler, and therefore `Eq` is a trait without methods.
 ///
 /// Violating this property is a logic error. The behavior resulting from a logic error is not
 /// specified, but users of the trait must ensure that such logic errors do *not* result in
 /// undefined behavior. This means that `unsafe` code **must not** rely on the correctness of these
 /// methods.
 ///
-/// Implement `Eq` in addition to `PartialEq` if it's guaranteed that
-/// `PartialEq::eq(a, a)` always returns `true` (reflexivity), in addition to
-/// the symmetric and transitive properties already required by `PartialEq`.
+/// Floating point types such as [`f32`] and [`f64`] implement only [`PartialEq`] but *not* `Eq`
+/// because `NaN` != `NaN`.
 ///
 /// ## Derivable
 ///
-/// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has
-/// no extra methods, it is only informing the compiler that this is an
-/// equivalence relation rather than a partial equivalence relation. Note that
-/// the `derive` strategy requires all fields are `Eq`, which isn't
+/// This trait can be used with `#[derive]`. When `derive`d, because `Eq` has no extra methods, it
+/// is only informing the compiler that this is an equivalence relation rather than a partial
+/// equivalence relation. Note that the `derive` strategy requires all fields are `Eq`, which isn't
 /// always desired.
 ///
 /// ## How can I implement `Eq`?
 ///
-/// If you cannot use the `derive` strategy, specify that your type implements
-/// `Eq`, which has no methods:
+/// If you cannot use the `derive` strategy, specify that your type implements `Eq`, which has no
+/// extra methods:
 ///
 /// ```
-/// enum BookFormat { Paperback, Hardback, Ebook }
+/// enum BookFormat {
+///     Paperback,
+///     Hardback,
+///     Ebook,
+/// }
+///
 /// struct Book {
 ///     isbn: i32,
 ///     format: BookFormat,
 /// }
+///
 /// impl PartialEq for Book {
 ///     fn eq(&self, other: &Self) -> bool {
 ///         self.isbn == other.isbn
 ///     }
 /// }
+///
 /// impl Eq for Book {}
 /// ```
 #[doc(alias = "==")]
@@ -325,11 +332,9 @@ pub macro PartialEq($item:item) {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Eq"]
 pub trait Eq: PartialEq<Self> {
-    // this method is used solely by #[derive(Eq)] to assert
-    // that every component of a type implements `Eq`
-    // itself. The current deriving infrastructure means doing this
-    // assertion without using a method on this trait is nearly
-    // impossible.
+    // this method is used solely by `impl Eq or #[derive(Eq)]` to assert that every component of a
+    // type implements `Eq` itself. The current deriving infrastructure means doing this assertion
+    // without using a method on this trait is nearly impossible.
     //
     // This should never be implemented by hand.
     #[doc(hidden)]
@@ -693,17 +698,14 @@ impl<T: Clone> Clone for Reverse<T> {
 
 /// Trait for types that form a [total order](https://en.wikipedia.org/wiki/Total_order).
 ///
-/// Implementations must be consistent with the [`PartialOrd`] implementation, and ensure
-/// `max`, `min`, and `clamp` are consistent with `cmp`:
+/// Implementations must be consistent with the [`PartialOrd`] implementation, and ensure `max`,
+/// `min`, and `clamp` are consistent with `cmp`:
 ///
 /// - `partial_cmp(a, b) == Some(cmp(a, b))`.
 /// - `max(a, b) == max_by(a, b, cmp)` (ensured by the default implementation).
 /// - `min(a, b) == min_by(a, b, cmp)` (ensured by the default implementation).
-/// - For `a.clamp(min, max)`, see the [method docs](#method.clamp)
-///   (ensured by the default implementation).
-///
-/// It's easy to accidentally make `cmp` and `partial_cmp` disagree by
-/// deriving some of the traits and manually implementing others.
+/// - For `a.clamp(min, max)`, see the [method docs](#method.clamp) (ensured by the default
+///   implementation).
 ///
 /// Violating these requirements is a logic error. The behavior resulting from a logic error is not
 /// specified, but users of the trait must ensure that such logic errors do *not* result in
@@ -712,15 +714,14 @@ impl<T: Clone> Clone for Reverse<T> {
 ///
 /// ## Corollaries
 ///
-/// From the above and the requirements of `PartialOrd`, it follows that for
-/// all `a`, `b` and `c`:
+/// From the above and the requirements of `PartialOrd`, it follows that for all `a`, `b` and `c`:
 ///
 /// - exactly one of `a < b`, `a == b` or `a > b` is true; and
-/// - `<` is transitive: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
+/// - `<` is transitive: `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and
+///   `>`.
 ///
-/// Mathematically speaking, the `<` operator defines a strict [weak order]. In
-/// cases where `==` conforms to mathematical equality, it also defines a
-/// strict [total order].
+/// Mathematically speaking, the `<` operator defines a strict [weak order]. In cases where `==`
+/// conforms to mathematical equality, it also defines a strict [total order].
 ///
 /// [weak order]: https://en.wikipedia.org/wiki/Weak_ordering
 /// [total order]: https://en.wikipedia.org/wiki/Total_order
@@ -730,13 +731,12 @@ impl<T: Clone> Clone for Reverse<T> {
 /// This trait can be used with `#[derive]`.
 ///
 /// When `derive`d on structs, it will produce a
-/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering
-/// based on the top-to-bottom declaration order of the struct's members.
+/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering based on the
+/// top-to-bottom declaration order of the struct's members.
 ///
-/// When `derive`d on enums, variants are ordered primarily by their discriminants.
-/// Secondarily, they are ordered by their fields.
-/// By default, the discriminant is smallest for variants at the top, and
-/// largest for variants at the bottom. Here's an example:
+/// When `derive`d on enums, variants are ordered primarily by their discriminants. Secondarily,
+/// they are ordered by their fields. By default, the discriminant is smallest for variants at the
+/// top, and largest for variants at the bottom. Here's an example:
 ///
 /// ```
 /// #[derive(PartialEq, Eq, PartialOrd, Ord)]
@@ -748,8 +748,7 @@ impl<T: Clone> Clone for Reverse<T> {
 /// assert!(E::Top < E::Bottom);
 /// ```
 ///
-/// However, manually setting the discriminants can override this default
-/// behavior:
+/// However, manually setting the discriminants can override this default behavior:
 ///
 /// ```
 /// #[derive(PartialEq, Eq, PartialOrd, Ord)]
@@ -765,51 +764,178 @@ impl<T: Clone> Clone for Reverse<T> {
 ///
 /// Lexicographical comparison is an operation with the following properties:
 ///  - Two sequences are compared element by element.
-///  - The first mismatching element defines which sequence is lexicographically less or greater than the other.
-///  - If one sequence is a prefix of another, the shorter sequence is lexicographically less than the other.
-///  - If two sequences have equivalent elements and are of the same length, then the sequences are lexicographically equal.
+///  - The first mismatching element defines which sequence is lexicographically less or greater
+///    than the other.
+///  - If one sequence is a prefix of another, the shorter sequence is lexicographically less than
+///    the other.
+///  - If two sequences have equivalent elements and are of the same length, then the sequences are
+///    lexicographically equal.
 ///  - An empty sequence is lexicographically less than any non-empty sequence.
 ///  - Two empty sequences are lexicographically equal.
 ///
 /// ## How can I implement `Ord`?
 ///
-/// `Ord` requires that the type also be [`PartialOrd`] and [`Eq`] (which requires [`PartialEq`]).
+/// `Ord` requires that the type also be [`PartialOrd`], [`PartialEq`], and [`Eq`].
 ///
-/// Then you must define an implementation for [`cmp`]. You may find it useful to use
-/// [`cmp`] on your type's fields.
+/// Because `Ord` implies a stronger ordering relationship than [`PartialOrd`], and both `Ord` and
+/// [`PartialOrd`] must agree, you must choose how to implement `Ord` **first**. You can choose to
+/// derive it, or implement it manually. If you derive it, you should derive all four traits. If you
+/// implement it manually, you should manually implement all four traits, based on the
+/// implementation of `Ord`.
 ///
-/// Here's an example where you want to sort people by height only, disregarding `id`
-/// and `name`:
+/// Here's an example where you want to define the `Character` comparison by `health` and
+/// `experience` only, disregarding the field `mana`:
 ///
 /// ```
 /// use std::cmp::Ordering;
 ///
-/// #[derive(Eq)]
-/// struct Person {
-///     id: u32,
-///     name: String,
-///     height: u32,
+/// struct Character {
+///     health: u32,
+///     experience: u32,
+///     mana: f32,
 /// }
 ///
-/// impl Ord for Person {
-///     fn cmp(&self, other: &Self) -> Ordering {
-///         self.height.cmp(&other.height)
+/// impl Ord for Character {
+///     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+///         self.experience
+///             .cmp(&other.experience)
+///             .then(self.health.cmp(&other.health))
 ///     }
 /// }
 ///
-/// impl PartialOrd for Person {
+/// impl PartialOrd for Character {
 ///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
 ///         Some(self.cmp(other))
 ///     }
 /// }
 ///
-/// impl PartialEq for Person {
+/// impl PartialEq for Character {
 ///     fn eq(&self, other: &Self) -> bool {
-///         self.height == other.height
+///         self.health == other.health && self.experience == other.experience
+///     }
+/// }
+///
+/// impl Eq for Character {}
+/// ```
+///
+/// If all you need is to `slice::sort` a type by a field value, it can be simpler to use
+/// `slice::sort_by_key`.
+///
+/// ## Examples of incorrect `Ord` implementations
+///
+/// ```
+/// use std::cmp::Ordering;
+///
+/// #[derive(Debug)]
+/// struct Character {
+///     health: f32,
+/// }
+///
+/// impl Ord for Character {
+///     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+///         if self.health < other.health {
+///             Ordering::Less
+///         } else if self.health > other.health {
+///             Ordering::Greater
+///         } else {
+///             Ordering::Equal
+///         }
+///     }
+/// }
+///
+/// impl PartialOrd for Character {
+///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+///         Some(self.cmp(other))
+///     }
+/// }
+///
+/// impl PartialEq for Character {
+///     fn eq(&self, other: &Self) -> bool {
+///         self.health == other.health
+///     }
+/// }
+///
+/// impl Eq for Character {}
+///
+/// let a = Character { health: 4.5 };
+/// let b = Character { health: f32::NAN };
+///
+/// // Mistake: floating-point values do not form a total order and using the built-in comparison
+/// // operands to implement `Ord` irregardless of that reality does not change it. Use
+/// // `f32::total_cmp` if you need a total order for floating-point values.
+///
+/// // Reflexivity requirement of `Ord` is not given.
+/// assert!(a == a);
+/// assert!(b != b);
+///
+/// // Antisymmetry requirement of `Ord` is not given. Only one of a < c and c < a is allowed to be
+/// // true, not both or neither.
+/// assert_eq!((a < b) as u8 + (b < a) as u8, 0);
+/// ```
+///
+/// ```
+/// use std::cmp::Ordering;
+///
+/// #[derive(Debug)]
+/// struct Character {
+///     health: u32,
+///     experience: u32,
+/// }
+///
+/// impl PartialOrd for Character {
+///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+///         Some(self.cmp(other))
+///     }
+/// }
+///
+/// impl Ord for Character {
+///     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+///         if self.health < 50 {
+///             self.health.cmp(&other.health)
+///         } else {
+///             self.experience.cmp(&other.experience)
+///         }
+///     }
+/// }
+///
+/// // For performance reasons implementing `PartialEq` this way is not the idiomatic way, but it
+/// // ensures consistent behavior between `PartialEq`, `PartialOrd` and `Ord` in this example.
+/// impl PartialEq for Character {
+///     fn eq(&self, other: &Self) -> bool {
+///         self.cmp(other) == Ordering::Equal
 ///     }
 /// }
+///
+/// impl Eq for Character {}
+///
+/// let a = Character {
+///     health: 3,
+///     experience: 5,
+/// };
+/// let b = Character {
+///     health: 10,
+///     experience: 77,
+/// };
+/// let c = Character {
+///     health: 143,
+///     experience: 2,
+/// };
+///
+/// // Mistake: The implementation of `Ord` compares different fields depending on the value of
+/// // `self.health`, the resulting order is not total.
+///
+/// // Transitivity requirement of `Ord` is not given. If a is smaller than b and b is smaller than
+/// // c, by transitive property a must also be smaller than c.
+/// assert!(a < b && b < c && c < a);
+///
+/// // Antisymmetry requirement of `Ord` is not given. Only one of a < c and c < a is allowed to be
+/// // true, not both or neither.
+/// assert_eq!((a < c) as u8 + (c < a) as u8, 2);
 /// ```
 ///
+/// The documentation of [`PartialOrd`] contains further examples, for example it's wrong for
+/// [`PartialOrd`] and [`PartialEq`] to disagree.
+///
 /// [`cmp`]: Ord::cmp
 #[doc(alias = "<")]
 #[doc(alias = ">")]
@@ -924,8 +1050,12 @@ pub macro Ord($item:item) {
 
 /// Trait for types that form a [partial order](https://en.wikipedia.org/wiki/Partial_order).
 ///
-/// The `lt`, `le`, `gt`, and `ge` methods of this trait can be called using
-/// the `<`, `<=`, `>`, and `>=` operators, respectively.
+/// The `lt`, `le`, `gt`, and `ge` methods of this trait can be called using the `<`, `<=`, `>`, and
+/// `>=` operators, respectively.
+///
+/// This trait should **only** contain the comparison logic for a type **if one plans on only
+/// implementing `PartialOrd` but not [`Ord`]**. Otherwise the comparison logic should be in [`Ord`]
+/// and this trait implemented with `Some(self.cmp(other))`.
 ///
 /// The methods of this trait must be consistent with each other and with those of [`PartialEq`].
 /// The following conditions must hold:
@@ -937,26 +1067,25 @@ pub macro Ord($item:item) {
 /// 5. `a >= b` if and only if `a > b || a == b`
 /// 6. `a != b` if and only if `!(a == b)`.
 ///
-/// Conditions 2–5 above are ensured by the default implementation.
-/// Condition 6 is already ensured by [`PartialEq`].
+/// Conditions 2–5 above are ensured by the default implementation. Condition 6 is already ensured
+/// by [`PartialEq`].
 ///
 /// If [`Ord`] is also implemented for `Self` and `Rhs`, it must also be consistent with
-/// `partial_cmp` (see the documentation of that trait for the exact requirements). It's
-/// easy to accidentally make them disagree by deriving some of the traits and manually
-/// implementing others.
+/// `partial_cmp` (see the documentation of that trait for the exact requirements). It's easy to
+/// accidentally make them disagree by deriving some of the traits and manually implementing others.
 ///
-/// The comparison relations must satisfy the following conditions
-/// (for all `a`, `b`, `c` of type `A`, `B`, `C`):
+/// The comparison relations must satisfy the following conditions (for all `a`, `b`, `c` of type
+/// `A`, `B`, `C`):
 ///
-/// - **Transitivity**: if `A: PartialOrd<B>` and `B: PartialOrd<C>` and `A:
-///   PartialOrd<C>`, then `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
-///   This must also work for longer chains, such as when `A: PartialOrd<B>`, `B: PartialOrd<C>`,
-///   `C: PartialOrd<D>`, and `A: PartialOrd<D>` all exist.
-/// - **Duality**: if `A: PartialOrd<B>` and `B: PartialOrd<A>`, then `a < b` if and only if `b > a`.
+/// - **Transitivity**: if `A: PartialOrd<B>` and `B: PartialOrd<C>` and `A: PartialOrd<C>`, then `a
+///   < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`. This must also
+///   work for longer chains, such as when `A: PartialOrd<B>`, `B: PartialOrd<C>`, `C:
+///   PartialOrd<D>`, and `A: PartialOrd<D>` all exist.
+/// - **Duality**: if `A: PartialOrd<B>` and `B: PartialOrd<A>`, then `a < b` if and only if `b >
+///   a`.
 ///
-/// Note that the `B: PartialOrd<A>` (dual) and `A: PartialOrd<C>`
-/// (transitive) impls are not forced to exist, but these requirements apply
-/// whenever they do exist.
+/// Note that the `B: PartialOrd<A>` (dual) and `A: PartialOrd<C>` (transitive) impls are not forced
+/// to exist, but these requirements apply whenever they do exist.
 ///
 /// Violating these requirements is a logic error. The behavior resulting from a logic error is not
 /// specified, but users of the trait must ensure that such logic errors do *not* result in
@@ -992,12 +1121,10 @@ pub macro Ord($item:item) {
 ///
 /// ## Strict and non-strict partial orders
 ///
-/// The `<` and `>` operators behave according to a *strict* partial order.
-/// However, `<=` and `>=` do **not** behave according to a *non-strict*
-/// partial order.
-/// That is because mathematically, a non-strict partial order would require
-/// reflexivity, i.e. `a <= a` would need to be true for every `a`. This isn't
-/// always the case for types that implement `PartialOrd`, for example:
+/// The `<` and `>` operators behave according to a *strict* partial order. However, `<=` and `>=`
+/// do **not** behave according to a *non-strict* partial order. That is because mathematically, a
+/// non-strict partial order would require reflexivity, i.e. `a <= a` would need to be true for
+/// every `a`. This isn't always the case for types that implement `PartialOrd`, for example:
 ///
 /// ```
 /// let a = f64::sqrt(-1.0);
@@ -1009,13 +1136,12 @@ pub macro Ord($item:item) {
 /// This trait can be used with `#[derive]`.
 ///
 /// When `derive`d on structs, it will produce a
-/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering
-/// based on the top-to-bottom declaration order of the struct's members.
+/// [lexicographic](https://en.wikipedia.org/wiki/Lexicographic_order) ordering based on the
+/// top-to-bottom declaration order of the struct's members.
 ///
-/// When `derive`d on enums, variants are primarily ordered by their discriminants.
-/// Secondarily, they are ordered by their fields.
-/// By default, the discriminant is smallest for variants at the top, and
-/// largest for variants at the bottom. Here's an example:
+/// When `derive`d on enums, variants are primarily ordered by their discriminants. Secondarily,
+/// they are ordered by their fields. By default, the discriminant is smallest for variants at the
+/// top, and largest for variants at the bottom. Here's an example:
 ///
 /// ```
 /// #[derive(PartialEq, PartialOrd)]
@@ -1027,8 +1153,7 @@ pub macro Ord($item:item) {
 /// assert!(E::Top < E::Bottom);
 /// ```
 ///
-/// However, manually setting the discriminants can override this default
-/// behavior:
+/// However, manually setting the discriminants can override this default behavior:
 ///
 /// ```
 /// #[derive(PartialEq, PartialOrd)]
@@ -1046,8 +1171,8 @@ pub macro Ord($item:item) {
 /// generated from default implementations.
 ///
 /// However it remains possible to implement the others separately for types which do not have a
-/// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 ==
-/// false` (cf. IEEE 754-2008 section 5.11).
+/// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 == false`
+/// (cf. IEEE 754-2008 section 5.11).
 ///
 /// `PartialOrd` requires your type to be [`PartialEq`].
 ///
@@ -1056,7 +1181,6 @@ pub macro Ord($item:item) {
 /// ```
 /// use std::cmp::Ordering;
 ///
-/// #[derive(Eq)]
 /// struct Person {
 ///     id: u32,
 ///     name: String,
@@ -1080,11 +1204,13 @@ pub macro Ord($item:item) {
 ///         self.height == other.height
 ///     }
 /// }
+///
+/// impl Eq for Person {}
 /// ```
 ///
-/// You may also find it useful to use [`partial_cmp`] on your type's fields. Here
-/// is an example of `Person` types who have a floating-point `height` field that
-/// is the only field to be used for sorting:
+/// You may also find it useful to use [`partial_cmp`] on your type's fields. Here is an example of
+/// `Person` types who have a floating-point `height` field that is the only field to be used for
+/// sorting:
 ///
 /// ```
 /// use std::cmp::Ordering;
@@ -1108,6 +1234,38 @@ pub macro Ord($item:item) {
 /// }
 /// ```
 ///
+/// ## Examples of incorrect `PartialOrd` implementations
+///
+/// ```
+/// use std::cmp::Ordering;
+///
+/// #[derive(PartialEq, Debug)]
+/// struct Character {
+///     health: u32,
+///     experience: u32,
+/// }
+///
+/// impl PartialOrd for Character {
+///     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+///         Some(self.health.cmp(&other.health))
+///     }
+/// }
+///
+/// let a = Character {
+///     health: 10,
+///     experience: 5,
+/// };
+/// let b = Character {
+///     health: 10,
+///     experience: 77,
+/// };
+///
+/// // Mistake: `PartialEq` and `PartialOrd` disagree with each other.
+///
+/// assert_eq!(a.partial_cmp(&b).unwrap(), Ordering::Equal); // a == b according to `PartialOrd`.
+/// assert_ne!(a, b); // a != b according to `PartialEq`.
+/// ```
+///
 /// # Examples
 ///
 /// ```
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 01cadd78cc0..817d9e3b962 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -118,7 +118,6 @@
 #![feature(const_array_into_iter_constructors)]
 #![feature(const_bigint_helper_methods)]
 #![feature(const_black_box)]
-#![feature(const_cell_into_inner)]
 #![feature(const_char_encode_utf16)]
 #![feature(const_char_encode_utf8)]
 #![feature(const_eval_select)]
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index be85f507129..42b68e28273 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -596,7 +596,7 @@ impl AtomicBool {
     #[stable(feature = "atomic_access", since = "1.15.0")]
     #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
     pub const fn into_inner(self) -> bool {
-        self.v.primitive_into_inner() != 0
+        self.v.into_inner() != 0
     }
 
     /// Loads a value from the bool.
@@ -1413,7 +1413,7 @@ impl<T> AtomicPtr<T> {
     #[stable(feature = "atomic_access", since = "1.15.0")]
     #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
     pub const fn into_inner(self) -> *mut T {
-        self.p.primitive_into_inner()
+        self.p.into_inner()
     }
 
     /// Loads a value from the pointer.
@@ -2408,7 +2408,7 @@ macro_rules! atomic_int {
             #[$stable_access]
             #[rustc_const_stable(feature = "const_atomic_into_inner", since = "1.79.0")]
             pub const fn into_inner(self) -> $int_type {
-                self.v.primitive_into_inner()
+                self.v.into_inner()
             }
 
             /// Loads a value from the atomic integer.
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 604c0d48743..4f2190f78bf 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -18,7 +18,6 @@
 #![feature(const_align_offset)]
 #![feature(const_array_from_ref)]
 #![feature(const_black_box)]
-#![feature(const_cell_into_inner)]
 #![feature(const_hash)]
 #![feature(const_heap)]
 #![feature(const_ip)]
diff --git a/tests/ui/asm/const-error.rs b/tests/ui/asm/const-error.rs
index 40d0590c33e..8c722906284 100644
--- a/tests/ui/asm/const-error.rs
+++ b/tests/ui/asm/const-error.rs
@@ -1,14 +1,16 @@
 //@ only-x86_64
 //@ needs-asm-support
+//@ check-pass
 
-// Test to make sure that we emit const errors eagerly for inline asm
+// Test to make sure that we emit const errors late for inline asm,
+// which is consistent with inline const blocks.
 
 use std::arch::asm;
 
 fn test<T>() {
     unsafe {
+        // No error here, as this does not get monomorphized.
         asm!("/* {} */", const 1 / 0);
-        //~^ ERROR evaluation of
     }
 }
 
diff --git a/tests/ui/asm/const-error.stderr b/tests/ui/asm/const-error.stderr
deleted file mode 100644
index 02e54457e89..00000000000
--- a/tests/ui/asm/const-error.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0080]: evaluation of `test::<T>::{constant#0}` failed
-  --> $DIR/const-error.rs:10:32
-   |
-LL |         asm!("/* {} */", const 1 / 0);
-   |                                ^^^^^ attempt to divide `1_i32` by zero
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0080`.