about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_attr_parsing/src/attributes/crate_level.rs24
-rw-r--r--compiler/rustc_attr_parsing/src/context.rs6
-rw-r--r--compiler/rustc_hir/src/attrs/data_structures.rs6
-rw-r--r--compiler/rustc_hir/src/attrs/encode_cross_crate.rs4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs18
-rw-r--r--library/core/src/any.rs3
-rw-r--r--library/core/src/array/equality.rs46
-rw-r--r--library/core/src/ascii/ascii_char.rs3
-rw-r--r--library/core/src/cmp.rs162
-rw-r--r--library/core/src/convert/mod.rs9
-rw-r--r--library/core/src/num/nonzero.rs17
-rw-r--r--library/core/src/ops/control_flow.rs3
-rw-r--r--library/core/src/option.rs9
-rw-r--r--library/core/src/range.rs6
-rw-r--r--library/core/src/result.rs3
-rw-r--r--library/core/src/slice/cmp.rs43
-rw-r--r--library/core/src/str/traits.rs3
-rw-r--r--library/core/src/tuple.rs12
-rw-r--r--library/coretests/tests/alloc.rs24
-rw-r--r--library/coretests/tests/char.rs43
-rw-r--r--library/coretests/tests/cmp.rs6
-rw-r--r--library/coretests/tests/hash/mod.rs13
-rw-r--r--library/coretests/tests/lib.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs17
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs14
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs10
-rw-r--r--tests/ui/attributes/malformed-no-std.rs25
-rw-r--r--tests/ui/attributes/malformed-no-std.stderr86
-rw-r--r--tests/ui/consts/const_cmp_type_id.rs5
-rw-r--r--tests/ui/consts/const_cmp_type_id.stderr8
-rw-r--r--tests/ui/consts/fn_trait_refs.rs3
-rw-r--r--tests/ui/consts/fn_trait_refs.stderr22
-rw-r--r--tests/ui/consts/missing-larger-array-impl.stderr10
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs12
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr131
-rw-r--r--tests/ui/lint/unused/unused-attr-duplicate.stderr24
-rw-r--r--tests/ui/suggestions/issue-71394-no-from-impl.stderr6
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.rs4
-rw-r--r--tests/ui/traits/const-traits/const-impl-trait.stderr17
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-use.rs3
-rw-r--r--tests/ui/traits/const-traits/const_derives/derive-const-use.stderr11
-rw-r--r--tests/ui/unpretty/exhaustive.hir.stdout2
43 files changed, 591 insertions, 286 deletions
diff --git a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
index d23a7ae72f8..0b2c05482bf 100644
--- a/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
+++ b/compiler/rustc_attr_parsing/src/attributes/crate_level.rs
@@ -176,3 +176,27 @@ impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser {
         })
     }
 }
+
+pub(crate) struct NoCoreParser;
+
+impl<S: Stage> NoArgsAttributeParser<S> for NoCoreParser {
+    const PATH: &[Symbol] = &[sym::no_core];
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
+    // because it's a crate-level attribute, we already warn about it.
+    // Putting target limitations here would give duplicate warnings
+    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore;
+    const TYPE: AttributeType = AttributeType::CrateLevel;
+}
+
+pub(crate) struct NoStdParser;
+
+impl<S: Stage> NoArgsAttributeParser<S> for NoStdParser {
+    const PATH: &[Symbol] = &[sym::no_std];
+    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
+    // because it's a crate-level attribute, we already warn about it.
+    // Putting target limitations here would give duplicate warnings
+    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
+    const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd;
+    const TYPE: AttributeType = AttributeType::CrateLevel;
+}
diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs
index d2b35090135..b3ab1d3edd6 100644
--- a/compiler/rustc_attr_parsing/src/context.rs
+++ b/compiler/rustc_attr_parsing/src/context.rs
@@ -25,8 +25,8 @@ use crate::attributes::codegen_attrs::{
 };
 use crate::attributes::confusables::ConfusablesParser;
 use crate::attributes::crate_level::{
-    CrateNameParser, MoveSizeLimitParser, PatternComplexityLimitParser, RecursionLimitParser,
-    TypeLengthLimitParser,
+    CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser,
+    RecursionLimitParser, TypeLengthLimitParser,
 };
 use crate::attributes::deprecation::DeprecationParser;
 use crate::attributes::dummy::DummyParser;
@@ -223,8 +223,10 @@ attribute_parsers!(
         Single<WithoutArgs<MacroEscapeParser>>,
         Single<WithoutArgs<MarkerParser>>,
         Single<WithoutArgs<MayDangleParser>>,
+        Single<WithoutArgs<NoCoreParser>>,
         Single<WithoutArgs<NoImplicitPreludeParser>>,
         Single<WithoutArgs<NoMangleParser>>,
+        Single<WithoutArgs<NoStdParser>>,
         Single<WithoutArgs<NonExhaustiveParser>>,
         Single<WithoutArgs<ParenSugarParser>>,
         Single<WithoutArgs<PassByValueParser>>,
diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs
index b4c1b61b9b5..ea11a99efbc 100644
--- a/compiler/rustc_hir/src/attrs/data_structures.rs
+++ b/compiler/rustc_hir/src/attrs/data_structures.rs
@@ -579,12 +579,18 @@ pub enum AttributeKind {
     /// Represents `#[naked]`
     Naked(Span),
 
+    /// Represents `#[no_core]`
+    NoCore(Span),
+
     /// Represents `#[no_implicit_prelude]`
     NoImplicitPrelude(Span),
 
     /// Represents `#[no_mangle]`
     NoMangle(Span),
 
+    /// Represents `#[no_std]`
+    NoStd(Span),
+
     /// Represents `#[non_exhaustive]`
     NonExhaustive(Span),
 
diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
index 0e208be3497..55521c15854 100644
--- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
+++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs
@@ -64,8 +64,10 @@ impl AttributeKind {
             MoveSizeLimit { .. } => No,
             MustUse { .. } => Yes,
             Naked(..) => No,
+            NoCore(..) => No,
             NoImplicitPrelude(..) => No,
-            NoMangle(..) => Yes,      // Needed for rustdoc
+            NoMangle(..) => Yes, // Needed for rustdoc
+            NoStd(..) => No,
             NonExhaustive(..) => Yes, // Needed for rustdoc
             Optimize(..) => No,
             ParenSugar(..) => No,
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 38a6b4b16c9..2562d2e0b83 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -274,6 +274,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     | AttributeKind::MoveSizeLimit { .. }
                     | AttributeKind::TypeLengthLimit { .. }
                     | AttributeKind::PatternComplexityLimit { .. }
+                    | AttributeKind::NoCore { .. }
+                    | AttributeKind::NoStd { .. }
                 ) => { /* do nothing  */ }
                 Attribute::Unparsed(attr_item) => {
                     style = Some(attr_item.style);
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index c82043f0222..149f5e638b1 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -27,8 +27,8 @@ use rustc_middle::ty::print::{
     with_forced_trimmed_paths,
 };
 use rustc_middle::ty::{
-    self, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
-    Upcast,
+    self, GenericArgKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
+    TypeVisitableExt, Upcast,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_span::{BytePos, DUMMY_SP, STDLIB_STABLE_CRATES, Span, Symbol, sym};
@@ -2316,7 +2316,19 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 cand
             })
             .collect();
-        impl_candidates.sort_by_key(|cand| (cand.similarity, cand.trait_ref.to_string()));
+        impl_candidates.sort_by_key(|cand| {
+            // When suggesting array types, sort them by the length of the array, not lexicographically (#135098)
+            let len = if let GenericArgKind::Type(ty) = cand.trait_ref.args[0].kind()
+                && let ty::Array(_, len) = ty.kind()
+            {
+                // Deprioritize suggestions for parameterized arrays.
+                len.try_to_target_usize(self.tcx).unwrap_or(u64::MAX)
+            } else {
+                0
+            };
+
+            (cand.similarity, len, cand.trait_ref.to_string())
+        });
         let mut impl_candidates: Vec<_> =
             impl_candidates.into_iter().map(|cand| cand.trait_ref).collect();
         impl_candidates.dedup();
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index e7d9763d46e..76ea2d18a82 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -705,7 +705,8 @@ impl dyn Any + Send + Sync {
 ///     std::mem::forget(fake_one_ring);
 /// }
 /// ```
-#[derive(Clone, Copy, Eq, PartialOrd, Ord)]
+#[derive(Copy, PartialOrd, Ord)]
+#[derive_const(Clone, Eq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "type_id"]
 pub struct TypeId {
diff --git a/library/core/src/array/equality.rs b/library/core/src/array/equality.rs
index 1ad2cca64a3..c2c7ccf0daa 100644
--- a/library/core/src/array/equality.rs
+++ b/library/core/src/array/equality.rs
@@ -1,9 +1,10 @@
 use crate::cmp::BytewiseEq;
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<[U; N]> for [T; N]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<[U; N]> for [T; N]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &[U; N]) -> bool {
@@ -16,9 +17,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<[U]> for [T; N]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<[U]> for [T; N]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &[U]) -> bool {
@@ -37,9 +39,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<[U; N]> for [T]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<[U; N]> for [T]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &[U; N]) -> bool {
@@ -58,9 +61,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<&[U]> for [T; N]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<&[U]> for [T; N]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &&[U]) -> bool {
@@ -73,9 +77,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<[U; N]> for &[T]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<[U; N]> for &[T]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &[U; N]) -> bool {
@@ -88,9 +93,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<&mut [U]> for [T; N]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<&mut [U]> for [T; N]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &&mut [U]) -> bool {
@@ -103,9 +109,10 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T, U, const N: usize> PartialEq<[U; N]> for &mut [T]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T, U, const N: usize> const PartialEq<[U; N]> for &mut [T]
 where
-    T: PartialEq<U>,
+    T: [const] PartialEq<U>,
 {
     #[inline]
     fn eq(&self, other: &[U; N]) -> bool {
@@ -122,14 +129,18 @@ where
 // __impl_slice_eq2! { [A; $N], &'b mut [B; $N] }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Eq, const N: usize> Eq for [T; N] {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] Eq, const N: usize> const Eq for [T; N] {}
 
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 trait SpecArrayEq<Other, const N: usize>: Sized {
     fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool;
     fn spec_ne(a: &[Self; N], b: &[Other; N]) -> bool;
 }
 
-impl<T: PartialEq<Other>, Other, const N: usize> SpecArrayEq<Other, N> for T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] PartialEq<Other>, Other, const N: usize> const SpecArrayEq<Other, N> for T {
     default fn spec_eq(a: &[Self; N], b: &[Other; N]) -> bool {
         a[..] == b[..]
     }
@@ -138,7 +149,8 @@ impl<T: PartialEq<Other>, Other, const N: usize> SpecArrayEq<Other, N> for T {
     }
 }
 
-impl<T: BytewiseEq<U>, U, const N: usize> SpecArrayEq<U, N> for T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] BytewiseEq<U>, U, const N: usize> const SpecArrayEq<U, N> for T {
     fn spec_eq(a: &[T; N], b: &[U; N]) -> bool {
         // SAFETY: Arrays are compared element-wise, and don't add any padding
         // between elements, so when the elements are `BytewiseEq`, we can
diff --git a/library/core/src/ascii/ascii_char.rs b/library/core/src/ascii/ascii_char.rs
index 49d540314a2..178af2c0e3b 100644
--- a/library/core/src/ascii/ascii_char.rs
+++ b/library/core/src/ascii/ascii_char.rs
@@ -54,7 +54,8 @@ use crate::{assert_unsafe_precondition, fmt};
 /// [chart]: https://www.unicode.org/charts/PDF/U0000.pdf
 /// [NIST FIPS 1-2]: https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub1-2-1977.pdf
 /// [NamesList]: https://www.unicode.org/Public/15.0.0/ucd/NamesList.txt
-#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
+#[derive(Copy, Hash)]
+#[derive_const(Clone, Eq, PartialEq, Ord, PartialOrd)]
 #[unstable(feature = "ascii_char", issue = "110998")]
 #[repr(u8)]
 pub enum AsciiChar {
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 0812322f3fb..94536f25b41 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -29,7 +29,7 @@ mod bytewise;
 pub(crate) use bytewise::BytewiseEq;
 
 use self::Ordering::*;
-use crate::marker::PointeeSized;
+use crate::marker::{Destruct, PointeeSized};
 use crate::ops::ControlFlow;
 
 /// Trait for comparisons using the equality operator.
@@ -334,7 +334,9 @@ pub macro PartialEq($item:item) {
 #[doc(alias = "!=")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Eq"]
-pub trait Eq: PartialEq<Self> + PointeeSized {
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub trait Eq: [const] PartialEq<Self> + PointeeSized {
     // 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.
@@ -380,8 +382,8 @@ pub struct AssertParamIsEq<T: Eq + PointeeSized> {
 ///
 /// assert_eq!(2.cmp(&1), Ordering::Greater);
 /// ```
-#[derive(Clone, Copy, Eq, PartialOrd, Ord, Debug, Hash)]
-#[derive_const(PartialEq)]
+#[derive(Copy, Debug, Hash)]
+#[derive_const(Clone, Eq, PartialOrd, Ord, PartialEq)]
 #[stable(feature = "rust1", since = "1.0.0")]
 // This is a lang item only so that `BinOp::Cmp` in MIR can return it.
 // It has no special behavior, but does require that the three variants
@@ -635,7 +637,11 @@ impl Ordering {
     #[inline]
     #[must_use]
     #[stable(feature = "ordering_chaining", since = "1.17.0")]
-    pub fn then_with<F: FnOnce() -> Ordering>(self, f: F) -> Ordering {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    pub const fn then_with<F>(self, f: F) -> Ordering
+    where
+        F: [const] FnOnce() -> Ordering + [const] Destruct,
+    {
         match self {
             Equal => f(),
             _ => self,
@@ -659,13 +665,15 @@ impl Ordering {
 /// v.sort_by_key(|&num| (num > 3, Reverse(num)));
 /// assert_eq!(v, vec![3, 2, 1, 6, 5, 4]);
 /// ```
-#[derive(PartialEq, Eq, Debug, Copy, Default, Hash)]
+#[derive(Copy, Debug, Hash)]
+#[derive_const(PartialEq, Eq, Default)]
 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
 #[repr(transparent)]
 pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T);
 
 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
-impl<T: PartialOrd> PartialOrd for Reverse<T> {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] PartialOrd> const PartialOrd for Reverse<T> {
     #[inline]
     fn partial_cmp(&self, other: &Reverse<T>) -> Option<Ordering> {
         other.0.partial_cmp(&self.0)
@@ -690,7 +698,8 @@ impl<T: PartialOrd> PartialOrd for Reverse<T> {
 }
 
 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
-impl<T: Ord> Ord for Reverse<T> {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] Ord> const Ord for Reverse<T> {
     #[inline]
     fn cmp(&self, other: &Reverse<T>) -> Ordering {
         other.0.cmp(&self.0)
@@ -957,7 +966,9 @@ impl<T: Clone> Clone for Reverse<T> {
 #[doc(alias = ">=")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Ord"]
-pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub trait Ord: [const] Eq + [const] PartialOrd<Self> + PointeeSized {
     /// This method returns an [`Ordering`] between `self` and `other`.
     ///
     /// By convention, `self.cmp(&other)` returns the ordering matching the expression
@@ -1011,7 +1022,7 @@ pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
     #[rustc_diagnostic_item = "cmp_ord_max"]
     fn max(self, other: Self) -> Self
     where
-        Self: Sized,
+        Self: Sized + [const] Destruct,
     {
         if other < self { self } else { other }
     }
@@ -1050,7 +1061,7 @@ pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
     #[rustc_diagnostic_item = "cmp_ord_min"]
     fn min(self, other: Self) -> Self
     where
-        Self: Sized,
+        Self: Sized + [const] Destruct,
     {
         if other < self { other } else { self }
     }
@@ -1076,7 +1087,7 @@ pub trait Ord: Eq + PartialOrd<Self> + PointeeSized {
     #[stable(feature = "clamp", since = "1.50.0")]
     fn clamp(self, min: Self, max: Self) -> Self
     where
-        Self: Sized,
+        Self: Sized + [const] Destruct,
     {
         assert!(min <= max);
         if self < min {
@@ -1341,6 +1352,8 @@ pub macro Ord($item:item) {
 )]
 #[rustc_diagnostic_item = "PartialOrd"]
 #[allow(multiple_supertrait_upcastable)] // FIXME(sized_hierarchy): remove this
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
     /// This method returns an ordering between `self` and `other` values if one exists.
     ///
@@ -1481,13 +1494,14 @@ pub trait PartialOrd<Rhs: PointeeSized = Self>: PartialEq<Rhs> + PointeeSized {
     }
 }
 
-fn default_chaining_impl<T, U>(
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+const fn default_chaining_impl<T, U>(
     lhs: &T,
     rhs: &U,
-    p: impl FnOnce(Ordering) -> bool,
+    p: impl [const] FnOnce(Ordering) -> bool + [const] Destruct,
 ) -> ControlFlow<bool>
 where
-    T: PartialOrd<U> + PointeeSized,
+    T: [const] PartialOrd<U> + PointeeSized,
     U: PointeeSized,
 {
     // It's important that this only call `partial_cmp` once, not call `eq` then
@@ -1545,7 +1559,8 @@ pub macro PartialOrd($item:item) {
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "cmp_min"]
-pub fn min<T: Ord>(v1: T, v2: T) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn min<T: [const] Ord + [const] Destruct>(v1: T, v2: T) -> T {
     v1.min(v2)
 }
 
@@ -1575,7 +1590,12 @@ pub fn min<T: Ord>(v1: T, v2: T) -> T {
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
-pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn min_by<T: [const] Destruct, F: [const] FnOnce(&T, &T) -> Ordering>(
+    v1: T,
+    v2: T,
+    compare: F,
+) -> T {
     if compare(&v1, &v2).is_le() { v1 } else { v2 }
 }
 
@@ -1600,7 +1620,13 @@ pub fn min_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
-pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn min_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> T
+where
+    T: [const] Destruct,
+    F: [const] FnMut(&T) -> K + [const] Destruct,
+    K: [const] Ord + [const] Destruct,
+{
     if f(&v2) < f(&v1) { v2 } else { v1 }
 }
 
@@ -1640,7 +1666,8 @@ pub fn min_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "cmp_max"]
-pub fn max<T: Ord>(v1: T, v2: T) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn max<T: [const] Ord + [const] Destruct>(v1: T, v2: T) -> T {
     v1.max(v2)
 }
 
@@ -1670,7 +1697,12 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
-pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn max_by<T: [const] Destruct, F: [const] FnOnce(&T, &T) -> Ordering>(
+    v1: T,
+    v2: T,
+    compare: F,
+) -> T {
     if compare(&v1, &v2).is_gt() { v1 } else { v2 }
 }
 
@@ -1695,7 +1727,13 @@ pub fn max_by<T, F: FnOnce(&T, &T) -> Ordering>(v1: T, v2: T, compare: F) -> T {
 #[inline]
 #[must_use]
 #[stable(feature = "cmp_min_max_by", since = "1.53.0")]
-pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn max_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> T
+where
+    T: [const] Destruct,
+    F: [const] FnMut(&T) -> K + [const] Destruct,
+    K: [const] Ord + [const] Destruct,
+{
     if f(&v2) < f(&v1) { v1 } else { v2 }
 }
 
@@ -1739,9 +1777,10 @@ pub fn max_by_key<T, F: FnMut(&T) -> K, K: Ord>(v1: T, v2: T, mut f: F) -> T {
 #[inline]
 #[must_use]
 #[unstable(feature = "cmp_minmax", issue = "115939")]
-pub fn minmax<T>(v1: T, v2: T) -> [T; 2]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn minmax<T>(v1: T, v2: T) -> [T; 2]
 where
-    T: Ord,
+    T: [const] Ord,
 {
     if v2 < v1 { [v2, v1] } else { [v1, v2] }
 }
@@ -1773,9 +1812,10 @@ where
 #[inline]
 #[must_use]
 #[unstable(feature = "cmp_minmax", issue = "115939")]
-pub fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn minmax_by<T, F>(v1: T, v2: T, compare: F) -> [T; 2]
 where
-    F: FnOnce(&T, &T) -> Ordering,
+    F: [const] FnOnce(&T, &T) -> Ordering,
 {
     if compare(&v1, &v2).is_le() { [v1, v2] } else { [v2, v1] }
 }
@@ -1801,10 +1841,11 @@ where
 #[inline]
 #[must_use]
 #[unstable(feature = "cmp_minmax", issue = "115939")]
-pub fn minmax_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> [T; 2]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+pub const fn minmax_by_key<T, F, K>(v1: T, v2: T, mut f: F) -> [T; 2]
 where
-    F: FnMut(&T) -> K,
-    K: Ord,
+    F: [const] FnMut(&T) -> K + [const] Destruct,
+    K: [const] Ord + [const] Destruct,
 {
     if f(&v2) < f(&v1) { [v2, v1] } else { [v1, v2] }
 }
@@ -1830,7 +1871,8 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl PartialEq for () {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const PartialEq for () {
         #[inline]
         fn eq(&self, _other: &()) -> bool {
             true
@@ -1848,7 +1890,8 @@ mod impls {
     macro_rules! eq_impl {
         ($($t:ty)*) => ($(
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl Eq for $t {}
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl const Eq for $t {}
         )*)
     }
 
@@ -1896,7 +1939,8 @@ mod impls {
     macro_rules! partial_ord_impl {
         ($($t:ty)*) => ($(
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl PartialOrd for $t {
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl const PartialOrd for $t {
                 #[inline]
                 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
                     match (*self <= *other, *self >= *other) {
@@ -1913,7 +1957,8 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl PartialOrd for () {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const PartialOrd for () {
         #[inline]
         fn partial_cmp(&self, _: &()) -> Option<Ordering> {
             Some(Equal)
@@ -1921,7 +1966,8 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl PartialOrd for bool {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const PartialOrd for bool {
         #[inline]
         fn partial_cmp(&self, other: &bool) -> Option<Ordering> {
             Some(self.cmp(other))
@@ -1935,7 +1981,8 @@ mod impls {
     macro_rules! ord_impl {
         ($($t:ty)*) => ($(
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl PartialOrd for $t {
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl const PartialOrd for $t {
                 #[inline]
                 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
                     Some(crate::intrinsics::three_way_compare(*self, *other))
@@ -1945,7 +1992,8 @@ mod impls {
             }
 
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl Ord for $t {
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl const Ord for $t {
                 #[inline]
                 fn cmp(&self, other: &Self) -> Ordering {
                     crate::intrinsics::three_way_compare(*self, *other)
@@ -1955,7 +2003,8 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl Ord for () {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const Ord for () {
         #[inline]
         fn cmp(&self, _other: &()) -> Ordering {
             Equal
@@ -1963,7 +2012,8 @@ mod impls {
     }
 
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl Ord for bool {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const Ord for bool {
         #[inline]
         fn cmp(&self, other: &bool) -> Ordering {
             // Casting to i8's and converting the difference to an Ordering generates
@@ -1998,7 +2048,8 @@ mod impls {
     ord_impl! { char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 }
 
     #[unstable(feature = "never_type", issue = "35121")]
-    impl PartialEq for ! {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const PartialEq for ! {
         #[inline]
         fn eq(&self, _: &!) -> bool {
             *self
@@ -2006,10 +2057,12 @@ mod impls {
     }
 
     #[unstable(feature = "never_type", issue = "35121")]
-    impl Eq for ! {}
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const Eq for ! {}
 
     #[unstable(feature = "never_type", issue = "35121")]
-    impl PartialOrd for ! {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const PartialOrd for ! {
         #[inline]
         fn partial_cmp(&self, _: &!) -> Option<Ordering> {
             *self
@@ -2017,7 +2070,8 @@ mod impls {
     }
 
     #[unstable(feature = "never_type", issue = "35121")]
-    impl Ord for ! {
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl const Ord for ! {
         #[inline]
         fn cmp(&self, _: &!) -> Ordering {
             *self
@@ -2042,9 +2096,10 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized, B: PointeeSized> PartialOrd<&B> for &A
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized, B: PointeeSized> const PartialOrd<&B> for &A
     where
-        A: PartialOrd<B>,
+        A: [const] PartialOrd<B>,
     {
         #[inline]
         fn partial_cmp(&self, other: &&B) -> Option<Ordering> {
@@ -2084,9 +2139,10 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized> Ord for &A
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized> const Ord for &A
     where
-        A: Ord,
+        A: [const] Ord,
     {
         #[inline]
         fn cmp(&self, other: &Self) -> Ordering {
@@ -2094,7 +2150,8 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized> Eq for &A where A: Eq {}
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized> const Eq for &A where A: [const] Eq {}
 
     // &mut pointers
 
@@ -2114,9 +2171,10 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized, B: PointeeSized> PartialOrd<&mut B> for &mut A
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized, B: PointeeSized> const PartialOrd<&mut B> for &mut A
     where
-        A: PartialOrd<B>,
+        A: [const] PartialOrd<B>,
     {
         #[inline]
         fn partial_cmp(&self, other: &&mut B) -> Option<Ordering> {
@@ -2156,9 +2214,10 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized> Ord for &mut A
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized> const Ord for &mut A
     where
-        A: Ord,
+        A: [const] Ord,
     {
         #[inline]
         fn cmp(&self, other: &Self) -> Ordering {
@@ -2166,7 +2225,8 @@ mod impls {
         }
     }
     #[stable(feature = "rust1", since = "1.0.0")]
-    impl<A: PointeeSized> Eq for &mut A where A: Eq {}
+    #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+    impl<A: PointeeSized> const Eq for &mut A where A: [const] Eq {}
 
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index a3cfd85974a..89cda30c030 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -963,17 +963,20 @@ impl const PartialEq for Infallible {
 }
 
 #[stable(feature = "convert_infallible", since = "1.34.0")]
-impl Eq for Infallible {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl const Eq for Infallible {}
 
 #[stable(feature = "convert_infallible", since = "1.34.0")]
-impl PartialOrd for Infallible {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl const PartialOrd for Infallible {
     fn partial_cmp(&self, _other: &Self) -> Option<crate::cmp::Ordering> {
         match *self {}
     }
 }
 
 #[stable(feature = "convert_infallible", since = "1.34.0")]
-impl Ord for Infallible {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl const Ord for Infallible {
     fn cmp(&self, _other: &Self) -> crate::cmp::Ordering {
         match *self {}
     }
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 0f38081c355..1b7c28bb95a 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -4,7 +4,7 @@ use super::{IntErrorKind, ParseIntError};
 use crate::clone::UseCloned;
 use crate::cmp::Ordering;
 use crate::hash::{Hash, Hasher};
-use crate::marker::{Freeze, StructuralPartialEq};
+use crate::marker::{Destruct, Freeze, StructuralPartialEq};
 use crate::ops::{BitOr, BitOrAssign, Div, DivAssign, Neg, Rem, RemAssign};
 use crate::panic::{RefUnwindSafe, UnwindSafe};
 use crate::str::FromStr;
@@ -220,12 +220,14 @@ where
 impl<T> StructuralPartialEq for NonZero<T> where T: ZeroablePrimitive + StructuralPartialEq {}
 
 #[stable(feature = "nonzero", since = "1.28.0")]
-impl<T> Eq for NonZero<T> where T: ZeroablePrimitive + Eq {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T> const Eq for NonZero<T> where T: ZeroablePrimitive + [const] Eq {}
 
 #[stable(feature = "nonzero", since = "1.28.0")]
-impl<T> PartialOrd for NonZero<T>
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T> const PartialOrd for NonZero<T>
 where
-    T: ZeroablePrimitive + PartialOrd,
+    T: ZeroablePrimitive + [const] PartialOrd,
 {
     #[inline]
     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
@@ -254,9 +256,12 @@ where
 }
 
 #[stable(feature = "nonzero", since = "1.28.0")]
-impl<T> Ord for NonZero<T>
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T> const Ord for NonZero<T>
 where
-    T: ZeroablePrimitive + Ord,
+    // FIXME(const_hack): the T: ~const Destruct should be inferred from the Self: ~const Destruct.
+    // See https://github.com/rust-lang/rust/issues/144207
+    T: ZeroablePrimitive + [const] Ord + [const] Destruct,
 {
     #[inline]
     fn cmp(&self, other: &Self) -> Ordering {
diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs
index 73b74d53323..b760a7c4e21 100644
--- a/library/core/src/ops/control_flow.rs
+++ b/library/core/src/ops/control_flow.rs
@@ -83,7 +83,8 @@ use crate::{convert, ops};
 #[must_use]
 // ControlFlow should not implement PartialOrd or Ord, per RFC 3058:
 // https://rust-lang.github.io/rfcs/3058-try-trait-v2.html#traits-for-controlflow
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Copy, Debug, Hash)]
+#[derive_const(Clone, PartialEq, Eq)]
 pub enum ControlFlow<B, C = ()> {
     /// Move on to the next phase of the operation as normal.
     #[stable(feature = "control_flow_enum_type", since = "1.55.0")]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 198636c67d0..886d581b0a6 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -585,7 +585,8 @@ use crate::{cmp, convert, hint, mem, slice};
 
 /// The `Option` type. See [the module level documentation](self) for more.
 #[doc(search_unbox)]
-#[derive(Copy, Eq, Debug, Hash)]
+#[derive(Copy, Debug, Hash)]
+#[derive_const(Eq)]
 #[rustc_diagnostic_item = "Option"]
 #[lang = "Option"]
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -2363,7 +2364,8 @@ impl<T: [const] PartialEq> const PartialEq for Option<T> {
 // https://github.com/rust-lang/rust/issues/49892, although still
 // not optimal.
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: PartialOrd> PartialOrd for Option<T> {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] PartialOrd> const PartialOrd for Option<T> {
     #[inline]
     fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
         match (self, other) {
@@ -2376,7 +2378,8 @@ impl<T: PartialOrd> PartialOrd for Option<T> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Ord> Ord for Option<T> {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] Ord> const Ord for Option<T> {
     #[inline]
     fn cmp(&self, other: &Self) -> cmp::Ordering {
         match (self, other) {
diff --git a/library/core/src/range.rs b/library/core/src/range.rs
index 8c49123fdaf..a096a8ceafc 100644
--- a/library/core/src/range.rs
+++ b/library/core/src/range.rs
@@ -49,7 +49,8 @@ pub use crate::ops::{Bound, IntoBounds, OneSidedRange, RangeBounds, RangeFull, R
 /// assert_eq!(3 + 4 + 5, Range::from(3..6).into_iter().sum());
 /// ```
 #[lang = "RangeCopy"]
-#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
+#[derive(Copy, Hash)]
+#[derive_const(Clone, Default, PartialEq, Eq)]
 #[unstable(feature = "new_range_api", issue = "125687")]
 pub struct Range<Idx> {
     /// The lower bound of the range (inclusive).
@@ -424,7 +425,8 @@ impl<T> const From<legacy::RangeInclusive<T>> for RangeInclusive<T> {
 /// assert_eq!(2 + 3 + 4, RangeFrom::from(2..).into_iter().take(3).sum());
 /// ```
 #[lang = "RangeFromCopy"]
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+#[derive(Copy, Hash)]
+#[derive_const(Clone, PartialEq, Eq)]
 #[unstable(feature = "new_range_api", issue = "125687")]
 pub struct RangeFrom<Idx> {
     /// The lower bound of the range (inclusive).
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 7dffab9b316..5c1f64bfe14 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -542,7 +542,8 @@ use crate::{convert, fmt, hint};
 ///
 /// See the [module documentation](self) for details.
 #[doc(search_unbox)]
-#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
+#[derive(Copy, Debug, Hash)]
+#[derive_const(PartialEq, PartialOrd, Eq, Ord)]
 #[must_use = "this `Result` may be an `Err` variant, which should be handled"]
 #[rustc_diagnostic_item = "Result"]
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs
index 0d801306984..103630aba0f 100644
--- a/library/core/src/slice/cmp.rs
+++ b/library/core/src/slice/cmp.rs
@@ -23,7 +23,8 @@ where
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Eq> Eq for [T] {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<T: [const] Eq> const Eq for [T] {}
 
 /// Implements comparison of slices [lexicographically](Ord#lexicographical-comparison).
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -34,7 +35,7 @@ impl<T: Ord> Ord for [T] {
 }
 
 #[inline]
-fn as_underlying(x: ControlFlow<bool>) -> u8 {
+const fn as_underlying(x: ControlFlow<bool>) -> u8 {
     // SAFETY: This will only compile if `bool` and `ControlFlow<bool>` have the same
     // size (which isn't guaranteed but this is libcore). Because they have the same
     // size, it's a niched implementation, which in one byte means there can't be
@@ -154,12 +155,16 @@ where
 }
 
 #[doc(hidden)]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 // intermediate trait for specialization of slice's PartialOrd
 trait SlicePartialOrd: Sized {
     fn partial_compare(left: &[Self], right: &[Self]) -> Option<Ordering>;
 }
 
 #[doc(hidden)]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 // intermediate trait for specialization of slice's PartialOrd chaining methods
 trait SliceChain: Sized {
     fn chaining_lt(left: &[Self], right: &[Self]) -> ControlFlow<bool>;
@@ -231,14 +236,17 @@ where
 }
 */
 
-impl<A: AlwaysApplicableOrd> SlicePartialOrd for A {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<A: [const] AlwaysApplicableOrd> const SlicePartialOrd for A {
     fn partial_compare(left: &[A], right: &[A]) -> Option<Ordering> {
         Some(SliceOrd::compare(left, right))
     }
 }
 
 #[rustc_specialization_trait]
-trait AlwaysApplicableOrd: SliceOrd + Ord {}
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+trait AlwaysApplicableOrd: [const] SliceOrd + [const] Ord {}
 
 macro_rules! always_applicable_ord {
     ($([$($p:tt)*] $t:ty,)*) => {
@@ -257,6 +265,8 @@ always_applicable_ord! {
 }
 
 #[doc(hidden)]
+#[const_trait]
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
 // intermediate trait for specialization of slice's Ord
 trait SliceOrd: Sized {
     fn compare(left: &[Self], right: &[Self]) -> Ordering;
@@ -282,17 +292,24 @@ impl<A: Ord> SliceOrd for A {
 /// * For every `x` and `y` of this type, `Ord(x, y)` must return the same
 ///   value as `Ord::cmp(transmute::<_, u8>(x), transmute::<_, u8>(y))`.
 #[rustc_specialization_trait]
-unsafe trait UnsignedBytewiseOrd: Ord {}
+#[const_trait]
+unsafe trait UnsignedBytewiseOrd: [const] Ord {}
 
-unsafe impl UnsignedBytewiseOrd for bool {}
-unsafe impl UnsignedBytewiseOrd for u8 {}
-unsafe impl UnsignedBytewiseOrd for NonZero<u8> {}
-unsafe impl UnsignedBytewiseOrd for Option<NonZero<u8>> {}
-unsafe impl UnsignedBytewiseOrd for ascii::Char {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+unsafe impl const UnsignedBytewiseOrd for bool {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+unsafe impl const UnsignedBytewiseOrd for u8 {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+unsafe impl const UnsignedBytewiseOrd for NonZero<u8> {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+unsafe impl const UnsignedBytewiseOrd for Option<NonZero<u8>> {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+unsafe impl const UnsignedBytewiseOrd for ascii::Char {}
 
 // `compare_bytes` compares a sequence of unsigned bytes lexicographically, so
 // use it if the requirements for `UnsignedBytewiseOrd` are fulfilled.
-impl<A: Ord + UnsignedBytewiseOrd> SliceOrd for A {
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<A: [const] Ord + [const] UnsignedBytewiseOrd> const SliceOrd for A {
     #[inline]
     fn compare(left: &[Self], right: &[Self]) -> Ordering {
         // Since the length of a slice is always less than or equal to
@@ -317,7 +334,9 @@ impl<A: Ord + UnsignedBytewiseOrd> SliceOrd for A {
 }
 
 // Don't generate our own chaining loops for `memcmp`-able things either.
-impl<A: PartialOrd + UnsignedBytewiseOrd> SliceChain for A {
+
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl<A: [const] PartialOrd + [const] UnsignedBytewiseOrd> const SliceChain for A {
     #[inline]
     fn chaining_lt(left: &[Self], right: &[Self]) -> ControlFlow<bool> {
         match SliceOrd::compare(left, right) {
diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs
index 5adae62b7e6..a7cc943994c 100644
--- a/library/core/src/str/traits.rs
+++ b/library/core/src/str/traits.rs
@@ -32,7 +32,8 @@ impl const PartialEq for str {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl Eq for str {}
+#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+impl const Eq for str {}
 
 /// Implements comparison operations on strings.
 ///
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index 2cdee1803a9..3892f831076 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -23,7 +23,8 @@ macro_rules! tuple_impls {
         maybe_tuple_doc! {
             $($T)+ @
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T: PartialEq),+> PartialEq for ($($T,)+) {
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl<$($T: [const] PartialEq),+> const PartialEq for ($($T,)+) {
                 #[inline]
                 fn eq(&self, other: &($($T,)+)) -> bool {
                     $( ${ignore($T)} self.${index()} == other.${index()} )&&+
@@ -38,7 +39,8 @@ macro_rules! tuple_impls {
         maybe_tuple_doc! {
             $($T)+ @
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T: Eq),+> Eq for ($($T,)+)
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl<$($T: [const] Eq),+> const Eq for ($($T,)+)
             {}
         }
 
@@ -66,7 +68,8 @@ macro_rules! tuple_impls {
         maybe_tuple_doc! {
             $($T)+ @
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl<$($T: [const] PartialOrd),+> const PartialOrd for ($($T,)+)
             {
                 #[inline]
                 fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
@@ -110,7 +113,8 @@ macro_rules! tuple_impls {
         maybe_tuple_doc! {
             $($T)+ @
             #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($T: Ord),+> Ord for ($($T,)+)
+            #[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
+            impl<$($T: [const] Ord),+> const Ord for ($($T,)+)
             {
                 #[inline]
                 fn cmp(&self, other: &($($T,)+)) -> Ordering {
diff --git a/library/coretests/tests/alloc.rs b/library/coretests/tests/alloc.rs
index 72fdf82c1f8..a4af6fd32a1 100644
--- a/library/coretests/tests/alloc.rs
+++ b/library/coretests/tests/alloc.rs
@@ -56,6 +56,30 @@ fn layout_array_edge_cases() {
 }
 
 #[test]
+fn layout_errors() {
+    let layout = Layout::new::<[u8; 2]>();
+    // Should error if the alignment is not a power of two.
+    assert!(layout.align_to(3).is_err());
+
+    // The remaining assertions ensure that the methods error on arithmetic overflow as the
+    // alignment cannot overflow `isize`.
+    let size = layout.size();
+    let size_max = isize::MAX as usize;
+    let align_max = size_max / size;
+
+    assert!(layout.align_to(size_max + 1).is_err());
+
+    assert!(layout.repeat(align_max).is_ok());
+    assert!(layout.repeat(align_max + 1).is_err());
+
+    assert!(layout.repeat_packed(align_max).is_ok());
+    assert!(layout.repeat_packed(align_max + 1).is_err());
+
+    let next = Layout::from_size_align(size_max, 1).unwrap();
+    assert!(layout.extend(next).is_err());
+}
+
+#[test]
 fn layout_debug_shows_log2_of_alignment() {
     // `Debug` is not stable, but here's what it does right now
     let layout = Layout::from_size_align(24576, 8192).unwrap();
diff --git a/library/coretests/tests/char.rs b/library/coretests/tests/char.rs
index 852f073bae1..6f94065b2d9 100644
--- a/library/coretests/tests/char.rs
+++ b/library/coretests/tests/char.rs
@@ -220,6 +220,7 @@ fn test_escape_default() {
     }
     assert_eq!(string('\n'), "\\n");
     assert_eq!(string('\r'), "\\r");
+    assert_eq!(string('\t'), "\\t");
     assert_eq!(string('\''), "\\'");
     assert_eq!(string('"'), "\\\"");
     assert_eq!(string(' '), " ");
@@ -417,3 +418,45 @@ fn eu_iterator_specializations() {
     check('\u{12340}');
     check('\u{10FFFF}');
 }
+
+#[test]
+#[should_panic]
+fn test_from_digit_radix_too_high() {
+    let _ = char::from_digit(0, 37);
+}
+
+#[test]
+fn test_from_digit_invalid_radix() {
+    assert!(char::from_digit(10, 9).is_none());
+}
+
+#[test]
+#[should_panic]
+fn test_to_digit_radix_too_low() {
+    let _ = 'a'.to_digit(1);
+}
+
+#[test]
+#[should_panic]
+fn test_to_digit_radix_too_high() {
+    let _ = 'a'.to_digit(37);
+}
+
+#[test]
+fn test_as_ascii_invalid() {
+    assert!('❤'.as_ascii().is_none());
+}
+
+#[test]
+#[should_panic]
+fn test_encode_utf8_raw_buffer_too_small() {
+    let mut buf = [0u8; 1];
+    let _ = char::encode_utf8_raw('ß'.into(), &mut buf);
+}
+
+#[test]
+#[should_panic]
+fn test_encode_utf16_raw_buffer_too_small() {
+    let mut buf = [0u16; 1];
+    let _ = char::encode_utf16_raw('𐐷'.into(), &mut buf);
+}
diff --git a/library/coretests/tests/cmp.rs b/library/coretests/tests/cmp.rs
index 6c4e2146f91..55e35a4a725 100644
--- a/library/coretests/tests/cmp.rs
+++ b/library/coretests/tests/cmp.rs
@@ -215,19 +215,18 @@ fn cmp_default() {
     assert_eq!(Fool(false), Fool(true));
 }
 
-/* FIXME(#110395)
 mod const_cmp {
     use super::*;
 
     struct S(i32);
 
-    impl PartialEq for S {
+    impl const PartialEq for S {
         fn eq(&self, other: &Self) -> bool {
             self.0 == other.0
         }
     }
 
-    impl PartialOrd for S {
+    impl const PartialOrd for S {
         fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
             let ret = match (self.0, other.0) {
                 (a, b) if a > b => Ordering::Greater,
@@ -247,4 +246,3 @@ mod const_cmp {
     const _: () = assert!(S(0) < S(1));
     const _: () = assert!(S(1) > S(0));
 }
-*/
diff --git a/library/coretests/tests/hash/mod.rs b/library/coretests/tests/hash/mod.rs
index 1f10a4733b0..043a3ee7423 100644
--- a/library/coretests/tests/hash/mod.rs
+++ b/library/coretests/tests/hash/mod.rs
@@ -53,12 +53,14 @@ fn test_writer_hasher() {
     assert_eq!(hash(&5_u16), 5);
     assert_eq!(hash(&5_u32), 5);
     assert_eq!(hash(&5_u64), 5);
+    assert_eq!(hash(&5_u128), 5);
     assert_eq!(hash(&5_usize), 5);
 
     assert_eq!(hash(&5_i8), 5);
     assert_eq!(hash(&5_i16), 5);
     assert_eq!(hash(&5_i32), 5);
     assert_eq!(hash(&5_i64), 5);
+    assert_eq!(hash(&5_i128), 5);
     assert_eq!(hash(&5_isize), 5);
 
     assert_eq!(hash(&false), 0);
@@ -85,6 +87,17 @@ fn test_writer_hasher() {
     let ptr = ptr::without_provenance_mut::<i32>(5_usize);
     assert_eq!(hash(&ptr), 5);
 
+    // Use a newtype to test the `Hash::hash_slice` default implementation.
+    struct Byte(u8);
+
+    impl Hash for Byte {
+        fn hash<H: Hasher>(&self, state: &mut H) {
+            state.write_u8(self.0)
+        }
+    }
+
+    assert_eq!(hash(&[Byte(b'a')]), 97 + 1);
+
     if cfg!(miri) {
         // Miri cannot hash pointers
         return;
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 1bdaa6965f6..a246c806140 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -13,8 +13,10 @@
 #![feature(bool_to_result)]
 #![feature(bstr)]
 #![feature(cfg_target_has_reliable_f16_f128)]
+#![feature(char_internals)]
 #![feature(char_max_len)]
 #![feature(clone_to_uninit)]
+#![feature(const_cmp)]
 #![feature(const_convert)]
 #![feature(const_destruct)]
 #![feature(const_eval_select)]
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 0b75e85772f..1458b0beefa 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1383,14 +1383,17 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS
         }
     }
 
-    // Build jemalloc on AArch64 with support for page sizes up to 64K
-    // See: https://github.com/rust-lang/rust/pull/135081
     // See also the "JEMALLOC_SYS_WITH_LG_PAGE" setting in the tool build step.
-    if builder.config.jemalloc(target)
-        && target.starts_with("aarch64")
-        && env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none()
-    {
-        cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16");
+    if builder.config.jemalloc(target) && env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() {
+        // Build jemalloc on AArch64 with support for page sizes up to 64K
+        // See: https://github.com/rust-lang/rust/pull/135081
+        if target.starts_with("aarch64") {
+            cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16");
+        }
+        // Build jemalloc on LoongArch with support for page sizes up to 16K
+        else if target.starts_with("loongarch") {
+            cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "14");
+        }
     }
 }
 
diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs
index 6870bf3eddc..dcc4898cae1 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -228,12 +228,18 @@ pub fn prepare_tool_cargo(
     // own copy
     cargo.env("LZMA_API_STATIC", "1");
 
-    // Build jemalloc on AArch64 with support for page sizes up to 64K
-    // See: https://github.com/rust-lang/rust/pull/135081
     // Note that `miri` always uses jemalloc. As such, there is no checking of the jemalloc build flag.
     // See also the "JEMALLOC_SYS_WITH_LG_PAGE" setting in the compile build step.
-    if target.starts_with("aarch64") && env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() {
-        cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16");
+    if env::var_os("JEMALLOC_SYS_WITH_LG_PAGE").is_none() {
+        // Build jemalloc on AArch64 with support for page sizes up to 64K
+        // See: https://github.com/rust-lang/rust/pull/135081
+        if target.starts_with("aarch64") {
+            cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "16");
+        }
+        // Build jemalloc on LoongArch with support for page sizes up to 16K
+        else if target.starts_with("loongarch") {
+            cargo.env("JEMALLOC_SYS_WITH_LG_PAGE", "14");
+        }
     }
 
     // CFG_RELEASE is needed by rustfmt (and possibly other tools) which
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 14b64eb4d54..e1077bdf4b1 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -2133,17 +2133,11 @@ pub fn std_or_core(cx: &LateContext<'_>) -> Option<&'static str> {
 }
 
 pub fn is_no_std_crate(cx: &LateContext<'_>) -> bool {
-    cx.tcx
-        .hir_attrs(hir::CRATE_HIR_ID)
-        .iter()
-        .any(|attr| attr.has_name(sym::no_std))
+    find_attr!(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), AttributeKind::NoStd(..))
 }
 
 pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
-    cx.tcx
-        .hir_attrs(hir::CRATE_HIR_ID)
-        .iter()
-        .any(|attr| attr.has_name(sym::no_core))
+    find_attr!(cx.tcx.hir_attrs(hir::CRATE_HIR_ID), AttributeKind::NoCore(..))
 }
 
 /// Check if parent of a hir node is a trait implementation block.
diff --git a/tests/ui/attributes/malformed-no-std.rs b/tests/ui/attributes/malformed-no-std.rs
new file mode 100644
index 00000000000..528ecb549b0
--- /dev/null
+++ b/tests/ui/attributes/malformed-no-std.rs
@@ -0,0 +1,25 @@
+#![feature(no_core)]
+// these all still apply no_std and then later error
+#![no_std = "foo"]
+//~^ ERROR malformed `no_std` attribute input
+#![no_std("bar")]
+//~^ ERROR malformed `no_std` attribute input
+#![no_std(foo = "bar")]
+//~^ ERROR malformed `no_std` attribute input
+#![no_core = "foo"]
+//~^ ERROR malformed `no_core` attribute input
+#![no_core("bar")]
+//~^ ERROR malformed `no_core` attribute input
+#![no_core(foo = "bar")]
+//~^ ERROR malformed `no_core` attribute input
+
+#[deny(unused_attributes)]
+#[no_std]
+//~^ ERROR crate-level attribute should be an inner attribute: add an exclamation mark:
+#[no_core]
+//~^ ERROR crate-level attribute should be an inner attribute: add an exclamation mark:
+// to fix compilation
+extern crate core;
+extern crate std;
+
+fn main() {}
diff --git a/tests/ui/attributes/malformed-no-std.stderr b/tests/ui/attributes/malformed-no-std.stderr
new file mode 100644
index 00000000000..322d5f03e41
--- /dev/null
+++ b/tests/ui/attributes/malformed-no-std.stderr
@@ -0,0 +1,86 @@
+error[E0565]: malformed `no_std` attribute input
+  --> $DIR/malformed-no-std.rs:3:1
+   |
+LL | #![no_std = "foo"]
+   | ^^^^^^^^^^-------^
+   | |         |
+   | |         didn't expect any arguments here
+   | help: must be of the form: `#![no_std]`
+
+error[E0565]: malformed `no_std` attribute input
+  --> $DIR/malformed-no-std.rs:5:1
+   |
+LL | #![no_std("bar")]
+   | ^^^^^^^^^-------^
+   | |        |
+   | |        didn't expect any arguments here
+   | help: must be of the form: `#![no_std]`
+
+error[E0565]: malformed `no_std` attribute input
+  --> $DIR/malformed-no-std.rs:7:1
+   |
+LL | #![no_std(foo = "bar")]
+   | ^^^^^^^^^-------------^
+   | |        |
+   | |        didn't expect any arguments here
+   | help: must be of the form: `#![no_std]`
+
+error[E0565]: malformed `no_core` attribute input
+  --> $DIR/malformed-no-std.rs:9:1
+   |
+LL | #![no_core = "foo"]
+   | ^^^^^^^^^^^-------^
+   | |          |
+   | |          didn't expect any arguments here
+   | help: must be of the form: `#![no_core]`
+
+error[E0565]: malformed `no_core` attribute input
+  --> $DIR/malformed-no-std.rs:11:1
+   |
+LL | #![no_core("bar")]
+   | ^^^^^^^^^^-------^
+   | |         |
+   | |         didn't expect any arguments here
+   | help: must be of the form: `#![no_core]`
+
+error[E0565]: malformed `no_core` attribute input
+  --> $DIR/malformed-no-std.rs:13:1
+   |
+LL | #![no_core(foo = "bar")]
+   | ^^^^^^^^^^-------------^
+   | |         |
+   | |         didn't expect any arguments here
+   | help: must be of the form: `#![no_core]`
+
+error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/malformed-no-std.rs:17:1
+   |
+LL | #[no_std]
+   | ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this extern crate
+  --> $DIR/malformed-no-std.rs:22:1
+   |
+LL | extern crate core;
+   | ^^^^^^^^^^^^^^^^^^
+note: the lint level is defined here
+  --> $DIR/malformed-no-std.rs:16:8
+   |
+LL | #[deny(unused_attributes)]
+   |        ^^^^^^^^^^^^^^^^^
+
+error: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_core]`
+  --> $DIR/malformed-no-std.rs:19:1
+   |
+LL | #[no_core]
+   | ^^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this extern crate
+  --> $DIR/malformed-no-std.rs:22:1
+   |
+LL | extern crate core;
+   | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0565`.
diff --git a/tests/ui/consts/const_cmp_type_id.rs b/tests/ui/consts/const_cmp_type_id.rs
index ff44876c5c4..dc0701d3b1d 100644
--- a/tests/ui/consts/const_cmp_type_id.rs
+++ b/tests/ui/consts/const_cmp_type_id.rs
@@ -9,8 +9,7 @@ fn main() {
         assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
         assert!(TypeId::of::<()>() != TypeId::of::<u8>());
         let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
-        //~^ ERROR: cannot call non-const operator in constants
-        // can't assert `_a` because it is not deterministic
-        // FIXME(const_trait_impl) make it pass
+        //~^ ERROR: the trait bound `TypeId: const PartialOrd` is not satisfied
+        // FIXME(const_trait_impl) make it pass; requires const comparison of pointers (#53020)
     }
 }
diff --git a/tests/ui/consts/const_cmp_type_id.stderr b/tests/ui/consts/const_cmp_type_id.stderr
index 05b94caef79..62a1677c0d9 100644
--- a/tests/ui/consts/const_cmp_type_id.stderr
+++ b/tests/ui/consts/const_cmp_type_id.stderr
@@ -1,13 +1,9 @@
-error[E0015]: cannot call non-const operator in constants
+error[E0277]: the trait bound `TypeId: const PartialOrd` is not satisfied
   --> $DIR/const_cmp_type_id.rs:11:18
    |
 LL |         let _a = TypeId::of::<u8>() < TypeId::of::<u16>();
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: impl defined here, but it is not `const`
-  --> $SRC_DIR/core/src/any.rs:LL:COL
-   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0015`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/fn_trait_refs.rs b/tests/ui/consts/fn_trait_refs.rs
index e475c0a1b6f..e4a62e18c7b 100644
--- a/tests/ui/consts/fn_trait_refs.rs
+++ b/tests/ui/consts/fn_trait_refs.rs
@@ -1,6 +1,5 @@
-//@ known-bug: #110395
+//@ check-pass
 
-#![feature(const_fn_trait_ref_impls)]
 #![feature(fn_traits)]
 #![feature(unboxed_closures)]
 #![feature(const_trait_impl)]
diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr
deleted file mode 100644
index bbe0714801c..00000000000
--- a/tests/ui/consts/fn_trait_refs.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0635]: unknown feature `const_fn_trait_ref_impls`
-  --> $DIR/fn_trait_refs.rs:3:12
-   |
-LL | #![feature(const_fn_trait_ref_impls)]
-   |            ^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0277]: the trait bound `(i32, i32, i32): const PartialEq` is not satisfied
-  --> $DIR/fn_trait_refs.rs:71:17
-   |
-LL |         assert!(test_one == (1, 1, 1));
-   |                 ^^^^^^^^^^^^^^^^^^^^^
-
-error[E0277]: the trait bound `(i32, i32): const PartialEq` is not satisfied
-  --> $DIR/fn_trait_refs.rs:74:17
-   |
-LL |         assert!(test_two == (2, 2));
-   |                 ^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0277, E0635.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/missing-larger-array-impl.stderr b/tests/ui/consts/missing-larger-array-impl.stderr
index ff4fa36d684..33d7a46339b 100644
--- a/tests/ui/consts/missing-larger-array-impl.stderr
+++ b/tests/ui/consts/missing-larger-array-impl.stderr
@@ -8,11 +8,11 @@ LL |     <[X; 35] as Default>::default();
              &[T]
              &mut [T]
              [T; 0]
-             [T; 10]
-             [T; 11]
-             [T; 12]
-             [T; 13]
-             [T; 14]
+             [T; 1]
+             [T; 2]
+             [T; 3]
+             [T; 4]
+             [T; 5]
            and 27 others
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
index c2653dd82a9..546aa4052d3 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.rs
@@ -539,26 +539,26 @@ mod macro_escape {
 
 #[no_std]
 //~^ WARN crate-level attribute should be an inner attribute
-//~| HELP add a `!`
 mod no_std {
+    //~^ NOTE This attribute does not have an `!`, which means it is applied to this module
     mod inner { #![no_std] }
-//~^ WARN crate-level attribute should be in the root module
+//~^ WARN the `#![no_std]` attribute can only be used at the crate root
 
     #[no_std] fn f() { }
     //~^ WARN crate-level attribute should be an inner attribute
-    //~| HELP add a `!`
+    //~| NOTE This attribute does not have an `!`, which means it is applied to this function
 
     #[no_std] struct S;
     //~^ WARN crate-level attribute should be an inner attribute
-    //~| HELP add a `!`
+    //~| NOTE This attribute does not have an `!`, which means it is applied to this struct
 
     #[no_std] type T = S;
     //~^ WARN crate-level attribute should be an inner attribute
-    //~| HELP add a `!`
+    //~| NOTE This attribute does not have an `!`, which means it is applied to this type alias
 
     #[no_std] impl S { }
     //~^ WARN crate-level attribute should be an inner attribute
-    //~| HELP add a `!`
+    //~| NOTE This attribute does not have an `!`, which means it is applied to this implementation block
 }
 
 // At time of authorship, #[proc_macro_derive = "2500"] signals error
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
index 4a3520972bf..3c835be5cff 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs.stderr
@@ -209,17 +209,6 @@ help: add a `!`
 LL | #![reexport_test_harness_main = "2900"]
    |  +
 
-warning: crate-level attribute should be an inner attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:1
-   |
-LL | #[no_std]
-   | ^^^^^^^^^
-   |
-help: add a `!`
-   |
-LL | #![no_std]
-   |  +
-
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:695:1
    |
@@ -387,56 +376,6 @@ help: add a `!`
 LL |     #![reexport_test_harness_main = "2900"] impl S { }
    |      +
 
-warning: crate-level attribute should be in the root module
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:17
-   |
-LL |     mod inner { #![no_std] }
-   |                 ^^^^^^^^^^
-
-warning: crate-level attribute should be an inner attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5
-   |
-LL |     #[no_std] fn f() { }
-   |     ^^^^^^^^^
-   |
-help: add a `!`
-   |
-LL |     #![no_std] fn f() { }
-   |      +
-
-warning: crate-level attribute should be an inner attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:5
-   |
-LL |     #[no_std] struct S;
-   |     ^^^^^^^^^
-   |
-help: add a `!`
-   |
-LL |     #![no_std] struct S;
-   |      +
-
-warning: crate-level attribute should be an inner attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:5
-   |
-LL |     #[no_std] type T = S;
-   |     ^^^^^^^^^
-   |
-help: add a `!`
-   |
-LL |     #![no_std] type T = S;
-   |      +
-
-warning: crate-level attribute should be an inner attribute
-  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:5
-   |
-LL |     #[no_std] impl S { }
-   |     ^^^^^^^^^
-   |
-help: add a `!`
-   |
-LL |     #![no_std] impl S { }
-   |      +
-
 warning: attribute should be applied to an `extern` block with non-Rust ABI
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:701:17
    |
@@ -1095,6 +1034,76 @@ LL |     #[macro_escape] impl S { }
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
    = help: `#[macro_escape]` can be applied to modules, extern crates, and crates
 
+warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:540:1
+   |
+LL | #[no_std]
+   | ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this module
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:542:1
+   |
+LL | / mod no_std {
+LL | |
+LL | |     mod inner { #![no_std] }
+...  |
+LL | | }
+   | |_^
+
+warning: the `#![no_std]` attribute can only be used at the crate root
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:544:17
+   |
+LL |     mod inner { #![no_std] }
+   |                 ^^^^^^^^^^
+
+warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:5
+   |
+LL |     #[no_std] fn f() { }
+   |     ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this function
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:547:15
+   |
+LL |     #[no_std] fn f() { }
+   |               ^^^^^^^^^^
+
+warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:5
+   |
+LL |     #[no_std] struct S;
+   |     ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this struct
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:551:15
+   |
+LL |     #[no_std] struct S;
+   |               ^^^^^^^^^
+
+warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:5
+   |
+LL |     #[no_std] type T = S;
+   |     ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this type alias
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:555:15
+   |
+LL |     #[no_std] type T = S;
+   |               ^^^^^^^^^^^
+
+warning: crate-level attribute should be an inner attribute: add an exclamation mark: `#![no_std]`
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:5
+   |
+LL |     #[no_std] impl S { }
+   |     ^^^^^^^^^
+   |
+note: This attribute does not have an `!`, which means it is applied to this implementation block
+  --> $DIR/issue-43106-gating-of-builtin-attrs.rs:559:15
+   |
+LL |     #[no_std] impl S { }
+   |               ^^^^^^^^^^
+
 warning: `#[cold]` attribute cannot be used on modules
   --> $DIR/issue-43106-gating-of-builtin-attrs.rs:581:1
    |
diff --git a/tests/ui/lint/unused/unused-attr-duplicate.stderr b/tests/ui/lint/unused/unused-attr-duplicate.stderr
index 076a08ac6f2..3a3b450f3c5 100644
--- a/tests/ui/lint/unused/unused-attr-duplicate.stderr
+++ b/tests/ui/lint/unused/unused-attr-duplicate.stderr
@@ -29,18 +29,6 @@ LL | #[no_link]
    | ^^^^^^^^^^
 
 error: unused attribute
-  --> $DIR/unused-attr-duplicate.rs:27:1
-   |
-LL | #![no_std]
-   | ^^^^^^^^^^ help: remove this attribute
-   |
-note: attribute also specified here
-  --> $DIR/unused-attr-duplicate.rs:26:1
-   |
-LL | #![no_std]
-   | ^^^^^^^^^^
-
-error: unused attribute
   --> $DIR/unused-attr-duplicate.rs:31:1
    |
 LL | #![windows_subsystem = "windows"]
@@ -305,6 +293,18 @@ LL | #![type_length_limit = "1048576"]
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
 
 error: unused attribute
+  --> $DIR/unused-attr-duplicate.rs:27:1
+   |
+LL | #![no_std]
+   | ^^^^^^^^^^ help: remove this attribute
+   |
+note: attribute also specified here
+  --> $DIR/unused-attr-duplicate.rs:26:1
+   |
+LL | #![no_std]
+   | ^^^^^^^^^^
+
+error: unused attribute
   --> $DIR/unused-attr-duplicate.rs:29:1
    |
 LL | #![no_implicit_prelude]
diff --git a/tests/ui/suggestions/issue-71394-no-from-impl.stderr b/tests/ui/suggestions/issue-71394-no-from-impl.stderr
index 31f8f1d455a..9e068c311ae 100644
--- a/tests/ui/suggestions/issue-71394-no-from-impl.stderr
+++ b/tests/ui/suggestions/issue-71394-no-from-impl.stderr
@@ -5,14 +5,14 @@ LL |     let _: &[i8] = data.into();
    |                         ^^^^ the trait `From<&[u8]>` is not implemented for `&[i8]`
    |
    = help: the following other types implement trait `From<T>`:
-             `[T; 10]` implements `From<(T, T, T, T, T, T, T, T, T, T)>`
-             `[T; 11]` implements `From<(T, T, T, T, T, T, T, T, T, T, T)>`
-             `[T; 12]` implements `From<(T, T, T, T, T, T, T, T, T, T, T, T)>`
              `[T; 1]` implements `From<(T,)>`
              `[T; 2]` implements `From<(T, T)>`
              `[T; 3]` implements `From<(T, T, T)>`
              `[T; 4]` implements `From<(T, T, T, T)>`
              `[T; 5]` implements `From<(T, T, T, T, T)>`
+             `[T; 6]` implements `From<(T, T, T, T, T, T)>`
+             `[T; 7]` implements `From<(T, T, T, T, T, T, T)>`
+             `[T; 8]` implements `From<(T, T, T, T, T, T, T, T)>`
            and 6 others
    = note: required for `&[u8]` to implement `Into<&[i8]>`
 
diff --git a/tests/ui/traits/const-traits/const-impl-trait.rs b/tests/ui/traits/const-traits/const-impl-trait.rs
index da28d9a47c3..c89aaa62d99 100644
--- a/tests/ui/traits/const-traits/const-impl-trait.rs
+++ b/tests/ui/traits/const-traits/const-impl-trait.rs
@@ -1,7 +1,5 @@
+//@ check-pass
 //@ compile-flags: -Znext-solver
-//@ known-bug: #110395
-
-// Broken until `(): const PartialEq`
 
 #![allow(incomplete_features)]
 #![feature(const_trait_impl, const_cmp, const_destruct)]
diff --git a/tests/ui/traits/const-traits/const-impl-trait.stderr b/tests/ui/traits/const-traits/const-impl-trait.stderr
deleted file mode 100644
index cbb68d8c983..00000000000
--- a/tests/ui/traits/const-traits/const-impl-trait.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0277]: the trait bound `(): const PartialEq` is not satisfied
-  --> $DIR/const-impl-trait.rs:34:17
-   |
-LL |     assert!(cmp(&()));
-   |             --- ^^^
-   |             |
-   |             required by a bound introduced by this call
-   |
-note: required by a bound in `cmp`
-  --> $DIR/const-impl-trait.rs:11:23
-   |
-LL | const fn cmp(a: &impl [const] PartialEq) -> bool {
-   |                       ^^^^^^^^^^^^^^^^^ required by this bound in `cmp`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-use.rs b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
index 1a3012de06f..78c25ccd6e5 100644
--- a/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
+++ b/tests/ui/traits/const-traits/const_derives/derive-const-use.rs
@@ -1,5 +1,4 @@
-//@ known-bug: #110395
-
+//@ check-pass
 #![feature(const_trait_impl, const_default, const_cmp, derive_const)]
 
 pub struct A;
diff --git a/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr b/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
deleted file mode 100644
index 4ea11a0c7ed..00000000000
--- a/tests/ui/traits/const-traits/const_derives/derive-const-use.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0277]: the trait bound `(): [const] PartialEq` is not satisfied
-  --> $DIR/derive-const-use.rs:16:14
-   |
-LL | #[derive_const(Default, PartialEq)]
-   |                         --------- in this derive macro expansion
-LL | pub struct S((), A);
-   |              ^^
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unpretty/exhaustive.hir.stdout b/tests/ui/unpretty/exhaustive.hir.stdout
index 924fb98ae18..96d85d1e7c1 100644
--- a/tests/ui/unpretty/exhaustive.hir.stdout
+++ b/tests/ui/unpretty/exhaustive.hir.stdout
@@ -55,7 +55,7 @@ use self::prelude::*;
      */
 #[doc = "inner doc attribute"]
 #[allow(dead_code, unused_variables)]
-#[no_std]
+#[attr = NoStd]
 mod attributes {
 
     /// outer single-line doc comment