summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0741.md12
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs32
-rw-r--r--compiler/rustc_errors/src/lib.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs91
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs19
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs3
-rw-r--r--compiler/rustc_middle/src/ty/context.rs12
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs29
-rw-r--r--compiler/rustc_target/src/abi/call/x86_64.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_ios.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_tvos.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs110
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/misc.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_match.rs70
-rw-r--r--library/core/src/marker.rs26
-rw-r--r--library/core/src/mem/transmutability.rs5
-rw-r--r--library/core/src/tuple.rs25
-rw-r--r--src/librustdoc/html/render/print_item.rs23
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.rs4
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr24
-rw-r--r--tests/incremental/const-generics/hash-tyvid-regression-1.rs14
-rw-r--r--tests/incremental/const-generics/hash-tyvid-regression-2.rs16
-rw-r--r--tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-3.rs13
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr20
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_good.rs4
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs2
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr23
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs1
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr14
-rw-r--r--tests/ui/const-generics/const-param-with-additional-obligations.rs17
-rw-r--r--tests/ui/const-generics/const-param-with-additional-obligations.stderr11
-rw-r--r--tests/ui/const-generics/float-generic.adt_const_params.stderr2
-rw-r--r--tests/ui/const-generics/forbid-non-structural_match-types.rs6
-rw-r--r--tests/ui/const-generics/forbid-non-structural_match-types.stderr12
-rw-r--r--tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs4
-rw-r--r--tests/ui/const-generics/invalid-enum.rs4
-rw-r--r--tests/ui/const-generics/invalid-enum.stderr14
-rw-r--r--tests/ui/const-generics/issue-66451.rs6
-rw-r--r--tests/ui/const-generics/issue-66451.stderr2
-rw-r--r--tests/ui/const-generics/issue-80471.rs2
-rw-r--r--tests/ui/const-generics/issue-80471.stderr8
-rw-r--r--tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-63322-forbid-dyn.rs2
-rw-r--r--tests/ui/const-generics/issues/issue-71381.full.stderr17
-rw-r--r--tests/ui/const-generics/issues/issue-71381.rs10
-rw-r--r--tests/ui/const-generics/issues/issue-71611.full.stderr11
-rw-r--r--tests/ui/const-generics/issues/issue-71611.rs4
-rw-r--r--tests/ui/const-generics/issues/issue-74255.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-74255.rs4
-rw-r--r--tests/ui/const-generics/issues/issue-74950.min.stderr10
-rw-r--r--tests/ui/const-generics/issues/issue-74950.rs3
-rw-r--r--tests/ui/const-generics/issues/issue-87076.rs4
-rw-r--r--tests/ui/const-generics/issues/issue-97278.rs2
-rw-r--r--tests/ui/const-generics/issues/issue-97278.stderr8
-rw-r--r--tests/ui/const-generics/issues/issue-99641.rs4
-rw-r--r--tests/ui/const-generics/issues/issue-99641.stderr8
-rw-r--r--tests/ui/const-generics/overlapping_impls.rs5
-rw-r--r--tests/ui/const-generics/std/const-generics-range.full.stderr39
-rw-r--r--tests/ui/const-generics/std/const-generics-range.min.stderr12
-rw-r--r--tests/ui/const-generics/std/const-generics-range.rs3
-rw-r--r--tests/ui/consts/refs_check_const_eq-issue-88384.rs4
-rw-r--r--tests/ui/consts/refs_check_const_eq-issue-88384.stderr16
-rw-r--r--tests/ui/mir/thir-constparam-temp.rs4
-rw-r--r--tests/ui/mir/thir-constparam-temp.stderr6
-rw-r--r--tests/ui/offset-of/offset-of-dst-field.rs2
-rw-r--r--tests/ui/offset-of/offset-of-dst-field.stderr19
-rw-r--r--tests/ui/offset-of/offset-of-tuple.rs10
-rw-r--r--tests/ui/offset-of/offset-of-tuple.stderr37
-rw-r--r--tests/ui/offset-of/offset-of-unsized.rs3
-rw-r--r--tests/ui/sanitize/issue-111184-generator-witness.rs17
-rw-r--r--tests/ui/symbol-names/const-generics-structural-demangling.rs25
-rw-r--r--tests/ui/symbol-names/const-generics-structural-demangling.stderr62
78 files changed, 717 insertions, 349 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0741.md b/compiler/rustc_error_codes/src/error_codes/E0741.md
index 70d963cd41f..0c701052665 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0741.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0741.md
@@ -10,15 +10,19 @@ struct A;
 struct B<const X: A>; // error!
 ```
 
-Only structural-match types (that is, types that derive `PartialEq` and `Eq`)
-may be used as the types of const generic parameters.
+Only structural-match types, which are types that derive `PartialEq` and `Eq`
+and implement `ConstParamTy`, may be used as the types of const generic
+parameters.
 
-To fix the previous code example, we derive `PartialEq` and `Eq`:
+To fix the previous code example, we derive `PartialEq`, `Eq`, and
+`ConstParamTy`:
 
 ```
 #![feature(adt_const_params)]
 
-#[derive(PartialEq, Eq)] // We derive both traits here.
+use std::marker::ConstParamTy;
+
+#[derive(PartialEq, Eq, ConstParamTy)] // We derive both traits here.
 struct A;
 
 struct B<const X: A>; // ok!
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index 7d9d0c76450..08ff2cfba5c 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -115,36 +115,22 @@ pub trait EmissionGuarantee: Sized {
     ) -> DiagnosticBuilder<'_, Self>;
 }
 
-/// Private module for sealing the `IsError` helper trait.
-mod sealed_level_is_error {
-    use crate::Level;
-
-    /// Sealed helper trait for statically checking that a `Level` is an error.
-    pub(crate) trait IsError<const L: Level> {}
-
-    impl IsError<{ Level::Bug }> for () {}
-    impl IsError<{ Level::DelayedBug }> for () {}
-    impl IsError<{ Level::Fatal }> for () {}
-    // NOTE(eddyb) `Level::Error { lint: true }` is also an error, but lints
-    // don't need error guarantees, as their levels are always dynamic.
-    impl IsError<{ Level::Error { lint: false } }> for () {}
-}
-
 impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
     /// Convenience function for internal use, clients should use one of the
     /// `struct_*` methods on [`Handler`].
     #[track_caller]
-    pub(crate) fn new_guaranteeing_error<M: Into<DiagnosticMessage>, const L: Level>(
+    pub(crate) fn new_guaranteeing_error<M: Into<DiagnosticMessage>>(
         handler: &'a Handler,
         message: M,
-    ) -> Self
-    where
-        (): sealed_level_is_error::IsError<L>,
-    {
+    ) -> Self {
         Self {
             inner: DiagnosticBuilderInner {
                 state: DiagnosticBuilderState::Emittable(handler),
-                diagnostic: Box::new(Diagnostic::new_with_code(L, None, message)),
+                diagnostic: Box::new(Diagnostic::new_with_code(
+                    Level::Error { lint: false },
+                    None,
+                    message,
+                )),
             },
             _marker: PhantomData,
         }
@@ -203,9 +189,7 @@ impl EmissionGuarantee for ErrorGuaranteed {
         handler: &Handler,
         msg: impl Into<DiagnosticMessage>,
     ) -> DiagnosticBuilder<'_, Self> {
-        DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>(
-            handler, msg,
-        )
+        DiagnosticBuilder::new_guaranteeing_error(handler, msg)
     }
 }
 
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 6c5f3e62454..bf77ed81f9b 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -6,7 +6,6 @@
 #![feature(array_windows)]
 #![feature(drain_filter)]
 #![feature(if_let_guard)]
-#![feature(adt_const_params)]
 #![feature(let_chains)]
 #![feature(never_type)]
 #![feature(result_option_inspect)]
@@ -845,7 +844,7 @@ impl Handler {
         &self,
         msg: impl Into<DiagnosticMessage>,
     ) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
-        DiagnosticBuilder::new_guaranteeing_error::<_, { Level::Error { lint: false } }>(self, msg)
+        DiagnosticBuilder::new_guaranteeing_error(self, msg)
     }
 
     /// This should only be used by `rustc_middle::lint::struct_lint_level`. Do not use it for hard errors.
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index fff417fcb29..69e32c35ed8 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -829,83 +829,20 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
             let ty = tcx.type_of(param.def_id).subst_identity();
 
             if tcx.features().adt_const_params {
-                if let Some(non_structural_match_ty) =
-                    traits::search_for_adt_const_param_violation(param.span, tcx, ty)
-                {
-                    // We use the same error code in both branches, because this is really the same
-                    // issue: we just special-case the message for type parameters to make it
-                    // clearer.
-                    match non_structural_match_ty.kind() {
-                        ty::Param(_) => {
-                            // Const parameters may not have type parameters as their types,
-                            // because we cannot be sure that the type parameter derives `PartialEq`
-                            // and `Eq` (just implementing them is not enough for `structural_match`).
-                            struct_span_err!(
-                                tcx.sess,
-                                hir_ty.span,
-                                E0741,
-                                "`{ty}` is not guaranteed to `#[derive(PartialEq, Eq)]`, so may not be \
-                                used as the type of a const parameter",
-                            )
-                            .span_label(
-                                hir_ty.span,
-                                format!("`{ty}` may not derive both `PartialEq` and `Eq`"),
-                            )
-                            .note(
-                                "it is not currently possible to use a type parameter as the type of a \
-                                const parameter",
-                            )
-                            .emit();
-                        }
-                        ty::Float(_) => {
-                            struct_span_err!(
-                                tcx.sess,
-                                hir_ty.span,
-                                E0741,
-                                "`{ty}` is forbidden as the type of a const generic parameter",
-                            )
-                            .note("floats do not derive `Eq` or `Ord`, which are required for const parameters")
-                            .emit();
-                        }
-                        ty::FnPtr(_) => {
-                            struct_span_err!(
-                                tcx.sess,
-                                hir_ty.span,
-                                E0741,
-                                "using function pointers as const generic parameters is forbidden",
-                            )
-                            .emit();
-                        }
-                        ty::RawPtr(_) => {
-                            struct_span_err!(
-                                tcx.sess,
-                                hir_ty.span,
-                                E0741,
-                                "using raw pointers as const generic parameters is forbidden",
-                            )
-                            .emit();
-                        }
-                        _ => {
-                            let mut diag = struct_span_err!(
-                                tcx.sess,
-                                hir_ty.span,
-                                E0741,
-                                "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \
-                                the type of a const parameter",
-                                non_structural_match_ty,
-                            );
-
-                            if ty == non_structural_match_ty {
-                                diag.span_label(
-                                    hir_ty.span,
-                                    format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),
-                                );
-                            }
-
-                            diag.emit();
-                        }
-                    }
-                }
+                enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
+                    let trait_def_id =
+                        tcx.require_lang_item(LangItem::ConstParamTy, Some(hir_ty.span));
+                    wfcx.register_bound(
+                        ObligationCause::new(
+                            hir_ty.span,
+                            param.def_id,
+                            ObligationCauseCode::ConstParam(ty),
+                        ),
+                        wfcx.param_env,
+                        ty,
+                        trait_def_id,
+                    );
+                });
             } else {
                 let err_ty_str;
                 let mut is_ptr = true;
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 19ff77d8349..5e10add013b 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -3117,16 +3117,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     }
                 }
                 ty::Tuple(tys) => {
-                    let fstr = field.as_str();
-
-                    if let Ok(index) = fstr.parse::<usize>() {
-                        if fstr == index.to_string() {
-                            if let Some(&field_ty) = tys.get(index) {
-                                field_indices.push(index.into());
-                                current_container = field_ty;
+                    if let Ok(index) = field.as_str().parse::<usize>()
+                        && field.name == sym::integer(index)
+                    {
+                        for ty in tys.iter().take(index + 1) {
+                            self.require_type_is_sized(ty, expr.span, traits::MiscObligation);
+                        }
+                        if let Some(&field_ty) = tys.get(index) {
+                            field_indices.push(index.into());
+                            current_container = field_ty;
 
-                                continue;
-                            }
+                            continue;
                         }
                     }
                 }
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 0a903a76974..bf3872e81d4 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -445,6 +445,9 @@ pub enum ObligationCauseCode<'tcx> {
     /// Obligations to prove that a `std::ops::Drop` impl is not stronger than
     /// the ADT it's being implemented for.
     DropImpl,
+
+    /// Requirement for a `const N: Ty` to implement `Ty: ConstParamTy`
+    ConstParam(Ty<'tcx>),
 }
 
 /// The 'location' at which we try to perform HIR-based wf checking.
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index b05e791211d..673d09cddf4 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -478,6 +478,17 @@ impl<'tcx> TyCtxtFeed<'tcx, LocalDefId> {
 /// [rustc dev guide] for more details.
 ///
 /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/ty.html
+///
+/// An implementation detail: `TyCtxt` is a wrapper type for [GlobalCtxt],
+/// which is the struct that actually holds all the data. `TyCtxt` derefs to
+/// `GlobalCtxt`, and in practice `TyCtxt` is passed around everywhere, and all
+/// operations are done via `TyCtxt`. A `TyCtxt` is obtained for a `GlobalCtxt`
+/// by calling `enter` with a closure `f`. That function creates both the
+/// `TyCtxt`, and an `ImplicitCtxt` around it that is put into TLS. Within `f`:
+/// - The `ImplicitCtxt` is available implicitly via TLS.
+/// - The `TyCtxt` is available explicitly via the `tcx` parameter, and also
+///   implicitly within the `ImplicitCtxt`. Explicit access is preferred when
+///   possible.
 #[derive(Copy, Clone)]
 #[rustc_diagnostic_item = "TyCtxt"]
 #[rustc_pass_by_value]
@@ -493,6 +504,7 @@ impl<'tcx> Deref for TyCtxt<'tcx> {
     }
 }
 
+/// See [TyCtxt] for details about this type.
 pub struct GlobalCtxt<'tcx> {
     pub arena: &'tcx WorkerLocal<Arena<'tcx>>,
     pub hir_arena: &'tcx WorkerLocal<hir::Arena<'tcx>>,
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index a1cb317c50e..81af071eefd 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -609,9 +609,7 @@ fn encode_ty<'tcx>(
         }
 
         // Function types
-        ty::FnDef(def_id, substs)
-        | ty::Closure(def_id, substs)
-        | ty::Generator(def_id, substs, ..) => {
+        ty::FnDef(def_id, substs) | ty::Closure(def_id, substs) => {
             // u<length><name>[I<element-type1..element-typeN>E], where <element-type> is <subst>,
             // as vendor extended type.
             let mut s = String::new();
@@ -622,6 +620,23 @@ fn encode_ty<'tcx>(
             typeid.push_str(&s);
         }
 
+        ty::Generator(def_id, substs, ..) => {
+            // u<length><name>[I<element-type1..element-typeN>E], where <element-type> is <subst>,
+            // as vendor extended type.
+            let mut s = String::new();
+            let name = encode_ty_name(tcx, *def_id);
+            let _ = write!(s, "u{}{}", name.len(), &name);
+            // Encode parent substs only
+            s.push_str(&encode_substs(
+                tcx,
+                tcx.mk_substs(substs.as_generator().parent_substs()),
+                dict,
+                options,
+            ));
+            compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
+            typeid.push_str(&s);
+        }
+
         // Pointer types
         ty::Ref(region, ty0, ..) => {
             // [U3mut]u3refI<element-type>E as vendor extended type qualifier and type
@@ -740,7 +755,12 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
     let mut ty = ty;
 
     match ty.kind() {
-        ty::Float(..) | ty::Char | ty::Str | ty::Never | ty::Foreign(..) => {}
+        ty::Float(..)
+        | ty::Char
+        | ty::Str
+        | ty::Never
+        | ty::Foreign(..)
+        | ty::GeneratorWitness(..) => {}
 
         ty::Bool => {
             if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
@@ -928,7 +948,6 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
 
         ty::Bound(..)
         | ty::Error(..)
-        | ty::GeneratorWitness(..)
         | ty::GeneratorWitnessMIR(..)
         | ty::Infer(..)
         | ty::Alias(..)
diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs
index 9427f27d1b7..74ef53915c9 100644
--- a/compiler/rustc_target/src/abi/call/x86_64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_64.rs
@@ -1,5 +1,5 @@
 // The classification code for the x86_64 ABI is taken from the clay language
-// https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp
+// https://github.com/jckarter/clay/blob/db0bd2702ab0b6e48965cd85f8859bbd5f60e48e/compiler/externals.cpp
 
 use crate::abi::call::{ArgAbi, CastTarget, FnAbi, Reg, RegKind};
 use crate::abi::{self, Abi, HasDataLayout, Size, TyAbiInterface, TyAndLayout};
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
index 1dcb47056a4..061b6a96fc8 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_ios.rs
@@ -13,7 +13,7 @@ pub fn target() -> Target {
             .into(),
         arch: arch.target_arch(),
         options: TargetOptions {
-            max_atomic_width: Some(64),
+            max_atomic_width: Some(128),
             stack_probes: StackProbeType::X86,
             ..base
         },
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
index 9f3b0fab697..50f359c357b 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
@@ -15,7 +15,7 @@ pub fn target() -> Target {
             .into(),
         arch: arch.target_arch(),
         options: TargetOptions {
-            max_atomic_width: Some(64),
+            max_atomic_width: Some(128),
             stack_probes: StackProbeType::X86,
             ..base
         },
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs
index 550ce0b9ce5..76de7d20c4c 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_tvos.rs
@@ -9,7 +9,7 @@ pub fn target() -> Target {
         data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".into(),
         arch: arch.target_arch(),
         options: TargetOptions {
-            max_atomic_width: Some(64),
+            max_atomic_width: Some(128),
             stack_probes: StackProbeType::X86,
             ..opts("tvos", arch)
         },
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs
index 75ce02cba1d..5fcc00a86ff 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs
@@ -10,7 +10,7 @@ pub fn target() -> Target {
             .into(),
         arch: arch.target_arch(),
         options: TargetOptions {
-            max_atomic_width: Some(64),
+            max_atomic_width: Some(128),
             stack_probes: StackProbeType::X86,
             forces_embed_bitcode: true,
             // Taken from a clang build on Xcode 11.4.1.
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index 1470dc452a1..01c74be7057 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -149,6 +149,12 @@ pub trait TypeErrCtxtExt<'tcx> {
         root_obligation: &PredicateObligation<'tcx>,
         error: &SelectionError<'tcx>,
     );
+
+    fn report_const_param_not_wf(
+        &self,
+        ty: Ty<'tcx>,
+        obligation: &PredicateObligation<'tcx>,
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed>;
 }
 
 impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
@@ -641,6 +647,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         span = obligation.cause.span;
                     }
                 }
+
                 if let ObligationCauseCode::CompareImplItemObligation {
                     impl_item_def_id,
                     trait_item_def_id,
@@ -657,6 +664,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     return;
                 }
 
+                // Report a const-param specific error
+                if let ObligationCauseCode::ConstParam(ty) = *obligation.cause.code().peel_derives()
+                {
+                    self.report_const_param_not_wf(ty, &obligation).emit();
+                    return;
+                }
+
                 let bound_predicate = obligation.predicate.kind();
                 match bound_predicate.skip_binder() {
                     ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
@@ -1163,6 +1177,102 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         self.point_at_returns_when_relevant(&mut err, &obligation);
         err.emit();
     }
+
+    fn report_const_param_not_wf(
+        &self,
+        ty: Ty<'tcx>,
+        obligation: &PredicateObligation<'tcx>,
+    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
+        let span = obligation.cause.span;
+
+        let mut diag = match ty.kind() {
+            _ if ty.has_param() => {
+                span_bug!(span, "const param tys cannot mention other generic parameters");
+            }
+            ty::Float(_) => {
+                struct_span_err!(
+                    self.tcx.sess,
+                    span,
+                    E0741,
+                    "`{ty}` is forbidden as the type of a const generic parameter",
+                )
+            }
+            ty::FnPtr(_) => {
+                struct_span_err!(
+                    self.tcx.sess,
+                    span,
+                    E0741,
+                    "using function pointers as const generic parameters is forbidden",
+                )
+            }
+            ty::RawPtr(_) => {
+                struct_span_err!(
+                    self.tcx.sess,
+                    span,
+                    E0741,
+                    "using raw pointers as const generic parameters is forbidden",
+                )
+            }
+            ty::Adt(def, _) => {
+                // We should probably see if we're *allowed* to derive `ConstParamTy` on the type...
+                let mut diag = struct_span_err!(
+                    self.tcx.sess,
+                    span,
+                    E0741,
+                    "`{ty}` must implement `ConstParamTy` to be used as the type of a const generic parameter",
+                );
+                // Only suggest derive if this isn't a derived obligation,
+                // and the struct is local.
+                if let Some(span) = self.tcx.hir().span_if_local(def.did())
+                    && obligation.cause.code().parent().is_none()
+                {
+                    if ty.is_structural_eq_shallow(self.tcx) {
+                        diag.span_suggestion(
+                            span,
+                            "add `#[derive(ConstParamTy)]` to the struct",
+                            "#[derive(ConstParamTy)]\n",
+                            Applicability::MachineApplicable,
+                        );
+                    } else {
+                        // FIXME(adt_const_params): We should check there's not already an
+                        // overlapping `Eq`/`PartialEq` impl.
+                        diag.span_suggestion(
+                            span,
+                            "add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct",
+                            "#[derive(ConstParamTy, PartialEq, Eq)]\n",
+                            Applicability::MachineApplicable,
+                        );
+                    }
+                }
+                diag
+            }
+            _ => {
+                struct_span_err!(
+                    self.tcx.sess,
+                    span,
+                    E0741,
+                    "`{ty}` can't be used as a const parameter type",
+                )
+            }
+        };
+
+        let mut code = obligation.cause.code();
+        let mut pred = obligation.predicate.to_opt_poly_trait_pred();
+        while let Some((next_code, next_pred)) = code.parent() {
+            if let Some(pred) = pred {
+                let pred = self.instantiate_binder_with_placeholders(pred);
+                diag.note(format!(
+                    "`{}` must implement `{}`, but it does not",
+                    pred.self_ty(),
+                    pred.print_modifiers_and_trait_path()
+                ));
+            }
+            code = next_code;
+            pred = next_pred;
+        }
+
+        diag
+    }
 }
 
 trait InferCtxtPrivExt<'tcx> {
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index b5b8c7fe3ac..204d6fd043b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2655,7 +2655,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             | ObligationCauseCode::BinOp { .. }
             | ObligationCauseCode::AscribeUserTypeProvePredicate(..)
             | ObligationCauseCode::RustCall
-            | ObligationCauseCode::DropImpl => {}
+            | ObligationCauseCode::DropImpl
+            | ObligationCauseCode::ConstParam(_) => {}
             ObligationCauseCode::SliceOrArrayElem => {
                 err.note("slice and array elements must have `Sized` type");
             }
diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs
index 2210ef975e6..e9cfd63e2ed 100644
--- a/compiler/rustc_trait_selection/src/traits/misc.rs
+++ b/compiler/rustc_trait_selection/src/traits/misc.rs
@@ -100,7 +100,8 @@ pub fn type_allowed_to_implement_const_param_ty<'tcx>(
         | ty::Str
         | ty::Array(..)
         | ty::Slice(_)
-        | ty::Ref(.., hir::Mutability::Not) => return Ok(()),
+        | ty::Ref(.., hir::Mutability::Not)
+        | ty::Tuple(_) => return Ok(()),
 
         &ty::Adt(adt, substs) => (adt, substs),
 
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index f7389bda159..c2f94cb6385 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -62,9 +62,7 @@ pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
 pub use self::specialize::{
     specialization_graph, translate_substs, translate_substs_with_cause, OverlapError,
 };
-pub use self::structural_match::{
-    search_for_adt_const_param_violation, search_for_structural_match_violation,
-};
+pub use self::structural_match::search_for_structural_match_violation;
 pub use self::structural_normalize::StructurallyNormalizeExt;
 pub use self::util::elaborate;
 pub use self::util::{expand_trait_aliases, TraitAliasExpander};
diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs
index e38ae9381c1..420f8c5dceb 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs
@@ -34,24 +34,7 @@ pub fn search_for_structural_match_violation<'tcx>(
     tcx: TyCtxt<'tcx>,
     ty: Ty<'tcx>,
 ) -> Option<Ty<'tcx>> {
-    ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), adt_const_param: false })
-        .break_value()
-}
-
-/// This method traverses the structure of `ty`, trying to find any
-/// types that are not allowed to be used in a const generic.
-///
-/// This is either because the type does not implement `StructuralEq`
-/// and `StructuralPartialEq`, or because the type is intentionally
-/// not supported in const generics (such as floats and raw pointers,
-/// which are allowed in match blocks).
-pub fn search_for_adt_const_param_violation<'tcx>(
-    span: Span,
-    tcx: TyCtxt<'tcx>,
-    ty: Ty<'tcx>,
-) -> Option<Ty<'tcx>> {
-    ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), adt_const_param: true })
-        .break_value()
+    ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default() }).break_value()
 }
 
 /// This implements the traversal over the structure of a given type to try to
@@ -65,11 +48,6 @@ struct Search<'tcx> {
     /// Tracks ADTs previously encountered during search, so that
     /// we will not recur on them again.
     seen: FxHashSet<hir::def_id::DefId>,
-
-    // Additionally deny things that have been allowed in patterns,
-    // but are not allowed in adt const params, such as floats and
-    // fn ptrs.
-    adt_const_param: bool,
 }
 
 impl<'tcx> Search<'tcx> {
@@ -124,41 +102,29 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
             }
 
             ty::FnPtr(..) => {
-                if !self.adt_const_param {
-                    return ControlFlow::Continue(());
-                } else {
-                    return ControlFlow::Break(ty);
-                }
+                return ControlFlow::Continue(());
             }
 
             ty::RawPtr(..) => {
-                if !self.adt_const_param {
-                    // structural-match ignores substructure of
-                    // `*const _`/`*mut _`, so skip `super_visit_with`.
-                    //
-                    // For example, if you have:
-                    // ```
-                    // struct NonStructural;
-                    // #[derive(PartialEq, Eq)]
-                    // struct T(*const NonStructural);
-                    // const C: T = T(std::ptr::null());
-                    // ```
-                    //
-                    // Even though `NonStructural` does not implement `PartialEq`,
-                    // structural equality on `T` does not recur into the raw
-                    // pointer. Therefore, one can still use `C` in a pattern.
-                    return ControlFlow::Continue(());
-                } else {
-                    return ControlFlow::Break(ty);
-                }
+                // structural-match ignores substructure of
+                // `*const _`/`*mut _`, so skip `super_visit_with`.
+                //
+                // For example, if you have:
+                // ```
+                // struct NonStructural;
+                // #[derive(PartialEq, Eq)]
+                // struct T(*const NonStructural);
+                // const C: T = T(std::ptr::null());
+                // ```
+                //
+                // Even though `NonStructural` does not implement `PartialEq`,
+                // structural equality on `T` does not recur into the raw
+                // pointer. Therefore, one can still use `C` in a pattern.
+                return ControlFlow::Continue(());
             }
 
             ty::Float(_) => {
-                if !self.adt_const_param {
-                    return ControlFlow::Continue(());
-                } else {
-                    return ControlFlow::Break(ty);
-                }
+                return ControlFlow::Continue(());
             }
 
             ty::Array(..) | ty::Slice(_) | ty::Ref(..) | ty::Tuple(..) => {
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 2d2d5d49175..9a541ccaeac 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -205,6 +205,20 @@ pub trait StructuralPartialEq {
     // Empty.
 }
 
+marker_impls! {
+    #[unstable(feature = "structural_match", issue = "31434")]
+    StructuralPartialEq for
+        usize, u8, u16, u32, u64, u128,
+        isize, i8, i16, i32, i64, i128,
+        bool,
+        char,
+        str /* Technically requires `[u8]: StructuralEq` */,
+        (),
+        {T, const N: usize} [T; N],
+        {T} [T],
+        {T: ?Sized} &T,
+}
+
 /// Required trait for constants used in pattern matches.
 ///
 /// Any type that derives `Eq` automatically implements this trait, *regardless*
@@ -267,6 +281,7 @@ marker_impls! {
         bool,
         char,
         str /* Technically requires `[u8]: StructuralEq` */,
+        (),
         {T, const N: usize} [T; N],
         {T} [T],
         {T: ?Sized} &T,
@@ -974,7 +989,8 @@ pub trait PointerLike {}
 #[lang = "const_param_ty"]
 #[unstable(feature = "adt_const_params", issue = "95174")]
 #[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")]
-pub trait ConstParamTy: StructuralEq {}
+#[allow(multiple_supertrait_upcastable)]
+pub trait ConstParamTy: StructuralEq + StructuralPartialEq {}
 
 /// Derive macro generating an impl of the trait `ConstParamTy`.
 #[rustc_builtin_macro]
@@ -983,8 +999,7 @@ pub macro ConstParamTy($item:item) {
     /* compiler built-in */
 }
 
-// FIXME(generic_const_parameter_types): handle `ty::FnDef`/`ty::Closure`
-// FIXME(generic_const_parameter_types): handle `ty::Tuple`
+// FIXME(adt_const_params): handle `ty::FnDef`/`ty::Closure`
 marker_impls! {
     #[unstable(feature = "adt_const_params", issue = "95174")]
     ConstParamTy for
@@ -998,6 +1013,11 @@ marker_impls! {
         {T: ?Sized + ConstParamTy} &T,
 }
 
+// FIXME(adt_const_params): Add to marker_impls call above once not in bootstrap
+#[unstable(feature = "adt_const_params", issue = "95174")]
+#[cfg(not(bootstrap))]
+impl ConstParamTy for () {}
+
 /// A common trait implemented by all function pointers.
 #[unstable(
     feature = "fn_ptr_trait",
diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs
index 87ae30619c6..a6f792ed0e3 100644
--- a/library/core/src/mem/transmutability.rs
+++ b/library/core/src/mem/transmutability.rs
@@ -1,3 +1,5 @@
+use crate::marker::ConstParamTy;
+
 /// Are values of a type transmutable into values of another type?
 ///
 /// This trait is implemented on-the-fly by the compiler for types `Src` and `Self` when the bits of
@@ -33,6 +35,9 @@ pub struct Assume {
     pub validity: bool,
 }
 
+#[unstable(feature = "transmutability", issue = "99571")]
+impl ConstParamTy for Assume {}
+
 impl Assume {
     /// Do not assume that *you* have ensured any safety properties are met.
     #[unstable(feature = "transmutability", issue = "99571")]
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index a1388dfeee6..ac8d04a8286 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -1,6 +1,9 @@
 // See src/libstd/primitive_docs.rs for documentation.
 
 use crate::cmp::Ordering::{self, *};
+#[cfg(not(bootstrap))]
+use crate::marker::ConstParamTy;
+use crate::marker::{StructuralEq, StructuralPartialEq};
 
 // Recursive macro for implementing n-ary tuple functions and operations
 //
@@ -47,6 +50,28 @@ macro_rules! tuple_impls {
 
         maybe_tuple_doc! {
             $($T)+ @
+            #[unstable(feature = "structural_match", issue = "31434")]
+            #[cfg(not(bootstrap))]
+            impl<$($T: ConstParamTy),+> ConstParamTy for ($($T,)+)
+            {}
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[unstable(feature = "structural_match", issue = "31434")]
+            impl<$($T),+> StructuralPartialEq for ($($T,)+)
+            {}
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
+            #[unstable(feature = "structural_match", issue = "31434")]
+            impl<$($T),+> StructuralEq for ($($T,)+)
+            {}
+        }
+
+        maybe_tuple_doc! {
+            $($T)+ @
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
             where
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 21f61acb2c5..1d66805bd5c 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1101,7 +1101,12 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
     );
 }
 
-fn item_trait_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::TraitAlias) {
+fn item_trait_alias(
+    w: &mut impl fmt::Write,
+    cx: &mut Context<'_>,
+    it: &clean::Item,
+    t: &clean::TraitAlias,
+) {
     wrap_item(w, |w| {
         write!(
             w,
@@ -1111,16 +1116,17 @@ fn item_trait_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &
             print_where_clause(&t.generics, cx, 0, Ending::Newline),
             bounds(&t.bounds, true, cx),
             attrs = render_attributes_in_pre(it, "", cx.tcx()),
-        );
+        )
+        .unwrap();
     });
 
-    write!(w, "{}", document(cx, it, None, HeadingOffset::H2));
-
+    write!(w, "{}", document(cx, it, None, HeadingOffset::H2)).unwrap();
     // Render any items associated directly to this alias, as otherwise they
     // won't be visible anywhere in the docs. It would be nice to also show
     // associated items from the aliased type (see discussion in #32077), but
     // we need #14072 to make sense of the generics.
     write!(w, "{}", render_assoc_items(cx, it, it.item_id.expect_def_id(), AssocItemRender::All))
+        .unwrap();
 }
 
 fn item_opaque_ty(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) {
@@ -1673,13 +1679,14 @@ fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>)
     bounds
 }
 
-fn wrap_item<F>(w: &mut Buffer, f: F)
+fn wrap_item<W, F>(w: &mut W, f: F)
 where
-    F: FnOnce(&mut Buffer),
+    W: fmt::Write,
+    F: FnOnce(&mut W),
 {
-    w.write_str(r#"<pre class="rust item-decl"><code>"#);
+    write!(w, r#"<pre class="rust item-decl"><code>"#).unwrap();
     f(w);
-    w.write_str("</code></pre>");
+    write!(w, "</code></pre>").unwrap();
 }
 
 #[derive(PartialEq, Eq)]
diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
index aea1507cc5b..08916398cbb 100644
--- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
+++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
@@ -10,6 +10,8 @@
     clippy::uninlined_format_args
 )]
 
+use std::marker::ConstParamTy;
+
 fn function() -> bool {
     true
 }
@@ -96,7 +98,7 @@ fn main() {
     };
     println!("{}", os);
 
-    #[derive(PartialEq, Eq)]
+    #[derive(PartialEq, Eq, ConstParamTy)]
     enum E {
         A,
         B,
diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
index aade3b1fa45..6aacc73b90d 100644
--- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
+++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
@@ -1,11 +1,11 @@
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:37:15
+  --> $DIR/same_functions_in_if_condition.rs:39:15
    |
 LL |     } else if function() {
    |               ^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:36:8
+  --> $DIR/same_functions_in_if_condition.rs:38:8
    |
 LL |     if function() {
    |        ^^^^^^^^^^
@@ -16,61 +16,61 @@ LL | #![deny(clippy::same_functions_in_if_condition)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:42:15
+  --> $DIR/same_functions_in_if_condition.rs:44:15
    |
 LL |     } else if fn_arg(a) {
    |               ^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:41:8
+  --> $DIR/same_functions_in_if_condition.rs:43:8
    |
 LL |     if fn_arg(a) {
    |        ^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:47:15
+  --> $DIR/same_functions_in_if_condition.rs:49:15
    |
 LL |     } else if obj.method() {
    |               ^^^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:46:8
+  --> $DIR/same_functions_in_if_condition.rs:48:8
    |
 LL |     if obj.method() {
    |        ^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:52:15
+  --> $DIR/same_functions_in_if_condition.rs:54:15
    |
 LL |     } else if obj.method_arg(a) {
    |               ^^^^^^^^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:51:8
+  --> $DIR/same_functions_in_if_condition.rs:53:8
    |
 LL |     if obj.method_arg(a) {
    |        ^^^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:59:15
+  --> $DIR/same_functions_in_if_condition.rs:61:15
    |
 LL |     } else if v.pop().is_none() {
    |               ^^^^^^^^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:57:8
+  --> $DIR/same_functions_in_if_condition.rs:59:8
    |
 LL |     if v.pop().is_none() {
    |        ^^^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:64:15
+  --> $DIR/same_functions_in_if_condition.rs:66:15
    |
 LL |     } else if v.len() == 42 {
    |               ^^^^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:62:8
+  --> $DIR/same_functions_in_if_condition.rs:64:8
    |
 LL |     if v.len() == 42 {
    |        ^^^^^^^^^^^^^
diff --git a/tests/incremental/const-generics/hash-tyvid-regression-1.rs b/tests/incremental/const-generics/hash-tyvid-regression-1.rs
index 5ff7b19d894..06d67423451 100644
--- a/tests/incremental/const-generics/hash-tyvid-regression-1.rs
+++ b/tests/incremental/const-generics/hash-tyvid-regression-1.rs
@@ -1,8 +1,20 @@
 // revisions: cfail
 #![feature(generic_const_exprs, adt_const_params)]
 #![allow(incomplete_features)]
+
+use std::marker::ConstParamTy;
+
+#[derive(PartialEq, Eq, ConstParamTy)]
+struct NonZeroUsize(usize);
+
+impl NonZeroUsize {
+    const fn get(self) -> usize {
+        self.0
+    }
+}
+
 // regression test for #77650
-fn c<T, const N: std::num::NonZeroUsize>()
+fn c<T, const N: NonZeroUsize>()
 where
     [T; N.get()]: Sized,
 {
diff --git a/tests/incremental/const-generics/hash-tyvid-regression-2.rs b/tests/incremental/const-generics/hash-tyvid-regression-2.rs
index 5cdd43cd782..33f226ff611 100644
--- a/tests/incremental/const-generics/hash-tyvid-regression-2.rs
+++ b/tests/incremental/const-generics/hash-tyvid-regression-2.rs
@@ -1,11 +1,23 @@
 // revisions: cfail
 #![feature(generic_const_exprs, adt_const_params)]
 #![allow(incomplete_features)]
+
+use std::marker::ConstParamTy;
+
+#[derive(PartialEq, Eq, ConstParamTy)]
+struct NonZeroUsize(usize);
+
+impl NonZeroUsize {
+    const fn get(self) -> usize {
+        self.0
+    }
+}
+
 // regression test for #77650
-struct C<T, const N: core::num::NonZeroUsize>([T; N.get()])
+struct C<T, const N: NonZeroUsize>([T; N.get()])
 where
     [T; N.get()]: Sized;
-impl<'a, const N: core::num::NonZeroUsize, A, B: PartialEq<A>> PartialEq<&'a [A]> for C<B, N>
+impl<'a, const N: NonZeroUsize, A, B: PartialEq<A>> PartialEq<&'a [A]> for C<B, N>
 where
     [B; N.get()]: Sized,
 {
diff --git a/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-3.rs b/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-3.rs
index fc114f224a2..f1c108fed11 100644
--- a/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-3.rs
+++ b/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-3.rs
@@ -2,7 +2,18 @@
 #![feature(generic_const_exprs, adt_const_params)]
 #![allow(incomplete_features)]
 
-use std::{convert::TryFrom, num::NonZeroUsize};
+use std::{convert::TryFrom};
+
+use std::marker::ConstParamTy;
+
+#[derive(PartialEq, Eq, ConstParamTy)]
+struct NonZeroUsize(usize);
+
+impl NonZeroUsize {
+    const fn get(self) -> usize {
+        self.0
+    }
+}
 
 struct A<const N: NonZeroUsize>([u8; N.get()])
 where
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr
index de5704ee429..48910b82a10 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_bad.stderr
@@ -11,6 +11,10 @@ note: required by a bound in `check`
    |
 LL | fn check(_: impl std::marker::ConstParamTy) {}
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
+help: use parentheses to call this function
+   |
+LL |     check(main());
+   |               ++
 
 error[E0277]: `[closure@$DIR/const_param_ty_bad.rs:8:11: 8:13]` can't be used as a const parameter type
   --> $DIR/const_param_ty_bad.rs:8:11
@@ -25,6 +29,10 @@ note: required by a bound in `check`
    |
 LL | fn check(_: impl std::marker::ConstParamTy) {}
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
+help: use parentheses to call this closure
+   |
+LL |     check(|| {}());
+   |                ++
 
 error[E0277]: `fn()` can't be used as a const parameter type
   --> $DIR/const_param_ty_bad.rs:9:11
@@ -39,6 +47,10 @@ note: required by a bound in `check`
    |
 LL | fn check(_: impl std::marker::ConstParamTy) {}
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
+help: use parentheses to call this function pointer
+   |
+LL |     check(main as fn()());
+   |                       ++
 
 error[E0277]: `&mut ()` can't be used as a const parameter type
   --> $DIR/const_param_ty_bad.rs:10:11
@@ -48,11 +60,17 @@ LL |     check(&mut ());
    |     |
    |     required by a bound introduced by this call
    |
+   = note: `ConstParamTy` is implemented for `&()`, but not for `&mut ()`
 note: required by a bound in `check`
   --> $DIR/const_param_ty_bad.rs:4:18
    |
 LL | fn check(_: impl std::marker::ConstParamTy) {}
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
+help: consider removing the leading `&`-reference
+   |
+LL -     check(&mut ());
+LL +     check(());
+   |
 
 error[E0277]: `*mut ()` can't be used as a const parameter type
   --> $DIR/const_param_ty_bad.rs:11:11
@@ -62,6 +80,7 @@ LL |     check(&mut () as *mut ());
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `ConstParamTy` is implemented for `()`
 note: required by a bound in `check`
   --> $DIR/const_param_ty_bad.rs:4:18
    |
@@ -76,6 +95,7 @@ LL |     check(&() as *const ());
    |     |
    |     required by a bound introduced by this call
    |
+   = help: the trait `ConstParamTy` is implemented for `()`
 note: required by a bound in `check`
   --> $DIR/const_param_ty_bad.rs:4:18
    |
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs
index 87ae83dd966..100ab332a40 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_good.rs
@@ -49,5 +49,7 @@ fn main() {
     check::<D<u8>>();
     check::<D<[&[bool]; 8]>>();
 
-    // FIXME: test tuples
+    check::<()>();
+    check::<(i32,)>();
+    check::<(D<u8>, D<i32>)>();
 }
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
index 37986de481f..08f7c5cb542 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
@@ -9,9 +9,11 @@ struct CantParam(ImplementsConstParamTy);
 
 impl std::marker::ConstParamTy for CantParam {}
 //~^ error: the type `CantParam` does not `#[derive(Eq)]`
+//~| error: the type `CantParam` does not `#[derive(PartialEq)]`
 
 #[derive(std::marker::ConstParamTy)]
 //~^ error: the type `CantParamDerive` does not `#[derive(Eq)]`
+//~| error: the type `CantParamDerive` does not `#[derive(PartialEq)]`
 struct CantParamDerive(ImplementsConstParamTy);
 
 fn check<T: std::marker::ConstParamTy>() {}
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
index 52701d55914..43c5b96dc7c 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
@@ -1,3 +1,12 @@
+error[E0277]: the type `CantParam` does not `#[derive(PartialEq)]`
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36
+   |
+LL | impl std::marker::ConstParamTy for CantParam {}
+   |                                    ^^^^^^^^^ the trait `StructuralPartialEq` is not implemented for `CantParam`
+   |
+note: required by a bound in `ConstParamTy`
+  --> $SRC_DIR/core/src/marker.rs:LL:COL
+
 error[E0277]: the type `CantParam` does not `#[derive(Eq)]`
   --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36
    |
@@ -7,8 +16,18 @@ LL | impl std::marker::ConstParamTy for CantParam {}
 note: required by a bound in `ConstParamTy`
   --> $SRC_DIR/core/src/marker.rs:LL:COL
 
+error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]`
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10
+   |
+LL | #[derive(std::marker::ConstParamTy)]
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralPartialEq` is not implemented for `CantParamDerive`
+   |
+note: required by a bound in `ConstParamTy`
+  --> $SRC_DIR/core/src/marker.rs:LL:COL
+   = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
+
 error[E0277]: the type `CantParamDerive` does not `#[derive(Eq)]`
-  --> $DIR/const_param_ty_impl_no_structural_eq.rs:13:10
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10
    |
 LL | #[derive(std::marker::ConstParamTy)]
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParamDerive`
@@ -17,6 +36,6 @@ note: required by a bound in `ConstParamTy`
   --> $SRC_DIR/core/src/marker.rs:LL:COL
    = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs
index d70377a20c1..c04e96c569b 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.rs
@@ -14,6 +14,7 @@ impl Eq for Union {}
 impl std::marker::StructuralEq for Union {}
 
 impl std::marker::ConstParamTy for Union {}
+//~^ ERROR the type `Union` does not `#[derive(PartialEq)]`
 
 #[derive(std::marker::ConstParamTy)]
 //~^ ERROR this trait cannot be derived for unions
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr
index 29370304605..985b933c40c 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_union.stderr
@@ -1,8 +1,18 @@
 error: this trait cannot be derived for unions
-  --> $DIR/const_param_ty_impl_union.rs:18:10
+  --> $DIR/const_param_ty_impl_union.rs:19:10
    |
 LL | #[derive(std::marker::ConstParamTy)]
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to previous error
+error[E0277]: the type `Union` does not `#[derive(PartialEq)]`
+  --> $DIR/const_param_ty_impl_union.rs:16:36
+   |
+LL | impl std::marker::ConstParamTy for Union {}
+   |                                    ^^^^^ the trait `StructuralPartialEq` is not implemented for `Union`
+   |
+note: required by a bound in `ConstParamTy`
+  --> $SRC_DIR/core/src/marker.rs:LL:COL
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/const-param-with-additional-obligations.rs b/tests/ui/const-generics/const-param-with-additional-obligations.rs
new file mode 100644
index 00000000000..f53cf85cdd3
--- /dev/null
+++ b/tests/ui/const-generics/const-param-with-additional-obligations.rs
@@ -0,0 +1,17 @@
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
+
+use std::marker::ConstParamTy;
+
+#[derive(Eq, PartialEq)]
+struct Foo<T>(T);
+
+trait Other {}
+
+impl<T> ConstParamTy for Foo<T> where T: Other + ConstParamTy {}
+
+fn foo<const N: Foo<u8>>() {}
+//~^ ERROR `Foo<u8>` must implement `ConstParamTy` to be used as the type of a const generic parameter
+//~| NOTE `u8` must implement `Other`, but it does not
+
+fn main() {}
diff --git a/tests/ui/const-generics/const-param-with-additional-obligations.stderr b/tests/ui/const-generics/const-param-with-additional-obligations.stderr
new file mode 100644
index 00000000000..f7ec4d57401
--- /dev/null
+++ b/tests/ui/const-generics/const-param-with-additional-obligations.stderr
@@ -0,0 +1,11 @@
+error[E0741]: `Foo<u8>` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/const-param-with-additional-obligations.rs:13:17
+   |
+LL | fn foo<const N: Foo<u8>>() {}
+   |                 ^^^^^^^
+   |
+   = note: `u8` must implement `Other`, but it does not
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0741`.
diff --git a/tests/ui/const-generics/float-generic.adt_const_params.stderr b/tests/ui/const-generics/float-generic.adt_const_params.stderr
index fef5ef0d1fa..6fe5390471d 100644
--- a/tests/ui/const-generics/float-generic.adt_const_params.stderr
+++ b/tests/ui/const-generics/float-generic.adt_const_params.stderr
@@ -3,8 +3,6 @@ error[E0741]: `f32` is forbidden as the type of a const generic parameter
    |
 LL | fn foo<const F: f32>() {}
    |                 ^^^
-   |
-   = note: floats do not derive `Eq` or `Ord`, which are required for const parameters
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/forbid-non-structural_match-types.rs b/tests/ui/const-generics/forbid-non-structural_match-types.rs
index 6ae9d5cfbb5..4fec2a9f32f 100644
--- a/tests/ui/const-generics/forbid-non-structural_match-types.rs
+++ b/tests/ui/const-generics/forbid-non-structural_match-types.rs
@@ -1,13 +1,15 @@
 #![feature(adt_const_params)]
 #![allow(incomplete_features)]
 
-#[derive(PartialEq, Eq)]
+use std::marker::ConstParamTy;
+
+#[derive(PartialEq, Eq, ConstParamTy)]
 struct A;
 
 struct B<const X: A>; // ok
 
 struct C;
 
-struct D<const X: C>; //~ ERROR `C` must be annotated with `#[derive(PartialEq, Eq)]`
+struct D<const X: C>; //~ ERROR `C` must implement `ConstParamTy` to be used as the type of a const generic parameter
 
 fn main() {}
diff --git a/tests/ui/const-generics/forbid-non-structural_match-types.stderr b/tests/ui/const-generics/forbid-non-structural_match-types.stderr
index 81b9bdfbd60..0efb9e9d3c2 100644
--- a/tests/ui/const-generics/forbid-non-structural_match-types.stderr
+++ b/tests/ui/const-generics/forbid-non-structural_match-types.stderr
@@ -1,8 +1,14 @@
-error[E0741]: `C` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
-  --> $DIR/forbid-non-structural_match-types.rs:11:19
+error[E0741]: `C` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/forbid-non-structural_match-types.rs:13:19
    |
 LL | struct D<const X: C>;
-   |                   ^ `C` doesn't derive both `PartialEq` and `Eq`
+   |                   ^
+   |
+help: add `#[derive(ConstParamTy, PartialEq, Eq)]` to the struct
+   |
+LL + #[derive(ConstParamTy, PartialEq, Eq)]
+LL | struct C;
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr
index 1d10dfdf10c..c478718b4cc 100644
--- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.full.stderr
@@ -7,7 +7,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
    = help: try adding a `where` bound using this expression: `where [(); 0 + N]:`
 
 error: overly complex generic constant
-  --> $DIR/array-size-in-generic-struct-param.rs:19:15
+  --> $DIR/array-size-in-generic-struct-param.rs:23:15
    |
 LL |     arr: [u8; CFG.arr_size],
    |               ^^^^^^^^^^^^ field access is not supported in generic constants
diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
index 18e9135d072..956e9c9c988 100644
--- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
@@ -8,7 +8,7 @@ LL | struct ArithArrayLen<const N: usize>([u32; 0 + N]);
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: generic parameters may not be used in const operations
-  --> $DIR/array-size-in-generic-struct-param.rs:19:15
+  --> $DIR/array-size-in-generic-struct-param.rs:23:15
    |
 LL |     arr: [u8; CFG.arr_size],
    |               ^^^ cannot perform const operation using `CFG`
@@ -17,7 +17,7 @@ LL |     arr: [u8; CFG.arr_size],
    = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
 
 error: `Config` is forbidden as the type of a const generic parameter
-  --> $DIR/array-size-in-generic-struct-param.rs:17:21
+  --> $DIR/array-size-in-generic-struct-param.rs:21:21
    |
 LL | struct B<const CFG: Config> {
    |                     ^^^^^^
diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs
index 7d3fe413c17..33ca6dcb304 100644
--- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs
+++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.rs
@@ -9,7 +9,11 @@ struct ArithArrayLen<const N: usize>([u32; 0 + N]);
 //[full]~^ ERROR unconstrained generic constant
 //[min]~^^ ERROR generic parameters may not be used in const operations
 
+#[cfg(full)]
+use std::marker::ConstParamTy;
+
 #[derive(PartialEq, Eq)]
+#[cfg_attr(full, derive(ConstParamTy))]
 struct Config {
     arr_size: usize,
 }
diff --git a/tests/ui/const-generics/invalid-enum.rs b/tests/ui/const-generics/invalid-enum.rs
index cb6d05349db..fcfad300c44 100644
--- a/tests/ui/const-generics/invalid-enum.rs
+++ b/tests/ui/const-generics/invalid-enum.rs
@@ -1,7 +1,9 @@
 #![feature(adt_const_params)]
 #![allow(incomplete_features)]
 
-#[derive(PartialEq, Eq)]
+use std::marker::ConstParamTy;
+
+#[derive(PartialEq, Eq, ConstParamTy)]
 enum CompileFlag {
     A,
     B,
diff --git a/tests/ui/const-generics/invalid-enum.stderr b/tests/ui/const-generics/invalid-enum.stderr
index 0d3643f6f89..7e8a632b34f 100644
--- a/tests/ui/const-generics/invalid-enum.stderr
+++ b/tests/ui/const-generics/invalid-enum.stderr
@@ -1,5 +1,5 @@
 error[E0573]: expected type, found variant `CompileFlag::A`
-  --> $DIR/invalid-enum.rs:21:12
+  --> $DIR/invalid-enum.rs:23:12
    |
 LL |   test_1::<CompileFlag::A>();
    |            ^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |   test_1::<CompileFlag::A>();
    |            help: try using the variant's enum: `CompileFlag`
 
 error[E0573]: expected type, found variant `CompileFlag::A`
-  --> $DIR/invalid-enum.rs:25:15
+  --> $DIR/invalid-enum.rs:27:15
    |
 LL |   test_2::<_, CompileFlag::A>(0);
    |               ^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |   test_2::<_, CompileFlag::A>(0);
    |               help: try using the variant's enum: `CompileFlag`
 
 error[E0573]: expected type, found variant `CompileFlag::A`
-  --> $DIR/invalid-enum.rs:29:18
+  --> $DIR/invalid-enum.rs:31:18
    |
 LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
    |                  ^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
    |                  help: try using the variant's enum: `CompileFlag`
 
 error[E0747]: unresolved item provided when a constant was expected
-  --> $DIR/invalid-enum.rs:29:18
+  --> $DIR/invalid-enum.rs:31:18
    |
 LL |   let _: Example<CompileFlag::A, _> = Example { x: 0 };
    |                  ^^^^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL |   let _: Example<{ CompileFlag::A }, _> = Example { x: 0 };
    |                  +                +
 
 error[E0747]: type provided when a constant was expected
-  --> $DIR/invalid-enum.rs:33:18
+  --> $DIR/invalid-enum.rs:35:18
    |
 LL |   let _: Example<Example::ASSOC_FLAG, _> = Example { x: 0 };
    |                  ^^^^^^^^^^^^^^^^^^^
@@ -48,7 +48,7 @@ LL |   let _: Example<{ Example::ASSOC_FLAG }, _> = Example { x: 0 };
    |                  +                     +
 
 error[E0747]: unresolved item provided when a constant was expected
-  --> $DIR/invalid-enum.rs:21:12
+  --> $DIR/invalid-enum.rs:23:12
    |
 LL |   test_1::<CompileFlag::A>();
    |            ^^^^^^^^^^^^^^
@@ -59,7 +59,7 @@ LL |   test_1::<{ CompileFlag::A }>();
    |            +                +
 
 error[E0747]: unresolved item provided when a constant was expected
-  --> $DIR/invalid-enum.rs:25:15
+  --> $DIR/invalid-enum.rs:27:15
    |
 LL |   test_2::<_, CompileFlag::A>(0);
    |               ^^^^^^^^^^^^^^
diff --git a/tests/ui/const-generics/issue-66451.rs b/tests/ui/const-generics/issue-66451.rs
index 3335f7d5984..c8d5515e987 100644
--- a/tests/ui/const-generics/issue-66451.rs
+++ b/tests/ui/const-generics/issue-66451.rs
@@ -1,13 +1,15 @@
 #![feature(adt_const_params)]
 #![allow(incomplete_features)]
 
-#[derive(Debug, PartialEq, Eq)]
+use std::marker::ConstParamTy;
+
+#[derive(Debug, PartialEq, Eq, ConstParamTy)]
 struct Foo {
     value: i32,
     nested: &'static Bar<i32>,
 }
 
-#[derive(Debug, PartialEq, Eq)]
+#[derive(Debug, PartialEq, Eq, ConstParamTy)]
 struct Bar<T>(T);
 
 struct Test<const F: Foo>;
diff --git a/tests/ui/const-generics/issue-66451.stderr b/tests/ui/const-generics/issue-66451.stderr
index e0cb0b661ff..946d5148667 100644
--- a/tests/ui/const-generics/issue-66451.stderr
+++ b/tests/ui/const-generics/issue-66451.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-66451.rs:27:10
+  --> $DIR/issue-66451.rs:29:10
    |
 LL |       let y: Test<{
    |  ____________-
diff --git a/tests/ui/const-generics/issue-80471.rs b/tests/ui/const-generics/issue-80471.rs
index d0af8a5eaa8..fa6f1fde435 100644
--- a/tests/ui/const-generics/issue-80471.rs
+++ b/tests/ui/const-generics/issue-80471.rs
@@ -8,6 +8,6 @@ enum Nat {
 }
 
 fn foo<const N: Nat>() {}
-//~^ ERROR `Box<Nat>` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
+//~^ ERROR `Nat` must implement `ConstParamTy` to be used as the type of a const generic parameter
 
 fn main() {}
diff --git a/tests/ui/const-generics/issue-80471.stderr b/tests/ui/const-generics/issue-80471.stderr
index b89706710bc..3b7143de543 100644
--- a/tests/ui/const-generics/issue-80471.stderr
+++ b/tests/ui/const-generics/issue-80471.stderr
@@ -7,11 +7,17 @@ LL | #![feature(adt_const_params)]
    = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0741]: `Box<Nat>` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
+error[E0741]: `Nat` must implement `ConstParamTy` to be used as the type of a const generic parameter
   --> $DIR/issue-80471.rs:10:17
    |
 LL | fn foo<const N: Nat>() {}
    |                 ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | enum Nat {
+   |
 
 error: aborting due to previous error; 1 warning emitted
 
diff --git a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr
index 16fabd1e88f..e2d8c5ca0e1 100644
--- a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr
+++ b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.full.stderr
@@ -1,8 +1,10 @@
-error[E0741]: `(dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
+error[E0741]: `&'static (dyn A + 'static)` can't be used as a const parameter type
   --> $DIR/issue-63322-forbid-dyn.rs:9:18
    |
 LL | fn test<const T: &'static dyn A>() {
    |                  ^^^^^^^^^^^^^^
+   |
+   = note: `(dyn A + 'static)` must implement `ConstParamTy`, but it does not
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.rs b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.rs
index 116c3fcfb21..8bc35ab3d37 100644
--- a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.rs
+++ b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.rs
@@ -7,7 +7,7 @@ struct B;
 impl A for B {}
 
 fn test<const T: &'static dyn A>() {
-    //[full]~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used
+    //[full]~^ ERROR `&'static (dyn A + 'static)` can't be used as a const parameter type
     //[min]~^^ ERROR `&'static (dyn A + 'static)` is forbidden
     unimplemented!()
 }
diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr
index 962eaf75b98..b6460e0017f 100644
--- a/tests/ui/const-generics/issues/issue-71381.full.stderr
+++ b/tests/ui/const-generics/issues/issue-71381.full.stderr
@@ -14,19 +14,6 @@ LL |         const FN: unsafe extern "C" fn(Args),
    |
    = note: type parameters may not be used in the type of const parameters
 
-error[E0741]: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:14:61
-   |
-LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
-   |                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error[E0741]: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71381.rs:23:19
-   |
-LL |         const FN: unsafe extern "C" fn(Args),
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0741, E0770.
-For more information about an error, try `rustc --explain E0741`.
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/const-generics/issues/issue-71381.rs b/tests/ui/const-generics/issues/issue-71381.rs
index 66f819dbe06..8a878efb42a 100644
--- a/tests/ui/const-generics/issues/issue-71381.rs
+++ b/tests/ui/const-generics/issues/issue-71381.rs
@@ -12,8 +12,8 @@ unsafe extern "C" fn pass(args: PassArg) {
 
 impl Test {
     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
-        //~^ ERROR: using function pointers as const generic parameters is forbidden
-        //~| ERROR: the type of const parameters must not depend on other generic parameters
+        //[min]~^ ERROR: using function pointers as const generic parameters is forbidden
+        //~^^ ERROR: the type of const parameters must not depend on other generic parameters
         self.0 = Self::trampiline::<Args, IDX, FN> as _
     }
 
@@ -21,8 +21,8 @@ impl Test {
         Args: Sized,
         const IDX: usize,
         const FN: unsafe extern "C" fn(Args),
-        //~^ ERROR: using function pointers as const generic parameters is forbidden
-        //~| ERROR: the type of const parameters must not depend on other generic parameters
+        //[min]~^ ERROR: using function pointers as const generic parameters is forbidden
+        //~^^ ERROR: the type of const parameters must not depend on other generic parameters
     >(
         args: Args,
     ) {
@@ -31,6 +31,6 @@ impl Test {
 }
 
 fn main() {
-    let x = Test();
+    let x = Test(std::ptr::null());
     x.call_me::<PassArg, 30, pass>()
 }
diff --git a/tests/ui/const-generics/issues/issue-71611.full.stderr b/tests/ui/const-generics/issues/issue-71611.full.stderr
index e109459f2be..b55f410a023 100644
--- a/tests/ui/const-generics/issues/issue-71611.full.stderr
+++ b/tests/ui/const-generics/issues/issue-71611.full.stderr
@@ -6,13 +6,6 @@ LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |
    = note: type parameters may not be used in the type of const parameters
 
-error[E0741]: using function pointers as const generic parameters is forbidden
-  --> $DIR/issue-71611.rs:5:21
-   |
-LL | fn func<A, const F: fn(inner: A)>(outer: A) {
-   |                     ^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0741, E0770.
-For more information about an error, try `rustc --explain E0741`.
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/const-generics/issues/issue-71611.rs b/tests/ui/const-generics/issues/issue-71611.rs
index fbb91ca18aa..c917f66818b 100644
--- a/tests/ui/const-generics/issues/issue-71611.rs
+++ b/tests/ui/const-generics/issues/issue-71611.rs
@@ -3,8 +3,8 @@
 #![cfg_attr(full, allow(incomplete_features))]
 
 fn func<A, const F: fn(inner: A)>(outer: A) {
-    //~^ ERROR: using function pointers as const generic parameters is forbidden
-    //~| ERROR: the type of const parameters must not depend on other generic parameters
+    //[min]~^ ERROR: using function pointers as const generic parameters is forbidden
+    //~^^ ERROR: the type of const parameters must not depend on other generic parameters
     F(outer);
 }
 
diff --git a/tests/ui/const-generics/issues/issue-74255.min.stderr b/tests/ui/const-generics/issues/issue-74255.min.stderr
index b462d84487e..bbcf8682b71 100644
--- a/tests/ui/const-generics/issues/issue-74255.min.stderr
+++ b/tests/ui/const-generics/issues/issue-74255.min.stderr
@@ -1,5 +1,5 @@
 error: `IceEnum` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74255.rs:14:31
+  --> $DIR/issue-74255.rs:18:31
    |
 LL |     fn ice_struct_fn<const I: IceEnum>() {}
    |                               ^^^^^^^
diff --git a/tests/ui/const-generics/issues/issue-74255.rs b/tests/ui/const-generics/issues/issue-74255.rs
index 0e523926fb0..60b2fd37c44 100644
--- a/tests/ui/const-generics/issues/issue-74255.rs
+++ b/tests/ui/const-generics/issues/issue-74255.rs
@@ -3,7 +3,11 @@
 #![cfg_attr(full, feature(adt_const_params))]
 #![cfg_attr(full, allow(incomplete_features))]
 
+#[cfg(full)]
+use std::marker::ConstParamTy;
+
 #[derive(PartialEq, Eq)]
+#[cfg_attr(full, derive(ConstParamTy))]
 enum IceEnum {
     Variant
 }
diff --git a/tests/ui/const-generics/issues/issue-74950.min.stderr b/tests/ui/const-generics/issues/issue-74950.min.stderr
index 729ecc2022c..c37ee93d420 100644
--- a/tests/ui/const-generics/issues/issue-74950.min.stderr
+++ b/tests/ui/const-generics/issues/issue-74950.min.stderr
@@ -1,5 +1,5 @@
 error: `Inner` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74950.rs:17:23
+  --> $DIR/issue-74950.rs:20:23
    |
 LL | struct Outer<const I: Inner>;
    |                       ^^^^^
@@ -8,7 +8,7 @@ LL | struct Outer<const I: Inner>;
    = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: `Inner` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74950.rs:17:23
+  --> $DIR/issue-74950.rs:20:23
    |
 LL | struct Outer<const I: Inner>;
    |                       ^^^^^
@@ -17,7 +17,7 @@ LL | struct Outer<const I: Inner>;
    = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: `Inner` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74950.rs:17:23
+  --> $DIR/issue-74950.rs:20:23
    |
 LL | struct Outer<const I: Inner>;
    |                       ^^^^^
@@ -26,7 +26,7 @@ LL | struct Outer<const I: Inner>;
    = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: `Inner` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74950.rs:17:23
+  --> $DIR/issue-74950.rs:20:23
    |
 LL | struct Outer<const I: Inner>;
    |                       ^^^^^
@@ -35,7 +35,7 @@ LL | struct Outer<const I: Inner>;
    = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: `Inner` is forbidden as the type of a const generic parameter
-  --> $DIR/issue-74950.rs:17:23
+  --> $DIR/issue-74950.rs:20:23
    |
 LL | struct Outer<const I: Inner>;
    |                       ^^^^^
diff --git a/tests/ui/const-generics/issues/issue-74950.rs b/tests/ui/const-generics/issues/issue-74950.rs
index 3e1ca4735db..43bb322656b 100644
--- a/tests/ui/const-generics/issues/issue-74950.rs
+++ b/tests/ui/const-generics/issues/issue-74950.rs
@@ -3,8 +3,11 @@
 #![cfg_attr(full, feature(adt_const_params))]
 #![cfg_attr(full, allow(incomplete_features))]
 
+#[cfg(full)]
+use std::marker::ConstParamTy;
 
 #[derive(PartialEq, Eq)]
+#[cfg_attr(full, derive(ConstParamTy))]
 struct Inner;
 
 // Note: We emit the error 5 times if we don't deduplicate:
diff --git a/tests/ui/const-generics/issues/issue-87076.rs b/tests/ui/const-generics/issues/issue-87076.rs
index 8a567678b82..a32c1f965f8 100644
--- a/tests/ui/const-generics/issues/issue-87076.rs
+++ b/tests/ui/const-generics/issues/issue-87076.rs
@@ -3,7 +3,9 @@
 #![feature(adt_const_params)]
 #![allow(incomplete_features)]
 
-#[derive(PartialEq, Eq)]
+use std::marker::ConstParamTy;
+
+#[derive(PartialEq, Eq, ConstParamTy)]
 pub struct UnitDims {
     pub time: u8,
     pub length: u8,
diff --git a/tests/ui/const-generics/issues/issue-97278.rs b/tests/ui/const-generics/issues/issue-97278.rs
index da0a9776fd4..8e7a1fcd995 100644
--- a/tests/ui/const-generics/issues/issue-97278.rs
+++ b/tests/ui/const-generics/issues/issue-97278.rs
@@ -9,6 +9,6 @@ enum Bar {
 }
 
 fn test<const BAR: Bar>() {}
-//~^ ERROR `Arc<i32>` must be annotated with `#[derive(PartialEq, Eq)]`
+//~^ ERROR  `Bar` must implement `ConstParamTy` to be used as the type of a const generic parameter
 
 fn main() {}
diff --git a/tests/ui/const-generics/issues/issue-97278.stderr b/tests/ui/const-generics/issues/issue-97278.stderr
index ff13cb505ab..31e92f840e1 100644
--- a/tests/ui/const-generics/issues/issue-97278.stderr
+++ b/tests/ui/const-generics/issues/issue-97278.stderr
@@ -1,8 +1,14 @@
-error[E0741]: `Arc<i32>` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
+error[E0741]: `Bar` must implement `ConstParamTy` to be used as the type of a const generic parameter
   --> $DIR/issue-97278.rs:11:20
    |
 LL | fn test<const BAR: Bar>() {}
    |                    ^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | enum Bar {
+   |
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/issues/issue-99641.rs b/tests/ui/const-generics/issues/issue-99641.rs
index fae6d3fc41f..dd075a6ad05 100644
--- a/tests/ui/const-generics/issues/issue-99641.rs
+++ b/tests/ui/const-generics/issues/issue-99641.rs
@@ -3,10 +3,10 @@
 
 fn main() {
     pub struct Color<const WHITE: (fn(),)>;
-    //~^ ERROR using function pointers
+    //~^ ERROR `(fn(),)` can't be used as a const parameter type
 
     impl<const WHITE: (fn(),)> Color<WHITE> {
-        //~^ ERROR using function pointers
+        //~^ ERROR `(fn(),)` can't be used as a const parameter type
         pub fn new() -> Self {
             Color::<WHITE>
         }
diff --git a/tests/ui/const-generics/issues/issue-99641.stderr b/tests/ui/const-generics/issues/issue-99641.stderr
index 349ebba08d5..800aec3ef2c 100644
--- a/tests/ui/const-generics/issues/issue-99641.stderr
+++ b/tests/ui/const-generics/issues/issue-99641.stderr
@@ -1,14 +1,18 @@
-error[E0741]: using function pointers as const generic parameters is forbidden
+error[E0741]: `(fn(),)` can't be used as a const parameter type
   --> $DIR/issue-99641.rs:5:35
    |
 LL |     pub struct Color<const WHITE: (fn(),)>;
    |                                   ^^^^^^^
+   |
+   = note: `fn()` must implement `ConstParamTy`, but it does not
 
-error[E0741]: using function pointers as const generic parameters is forbidden
+error[E0741]: `(fn(),)` can't be used as a const parameter type
   --> $DIR/issue-99641.rs:8:23
    |
 LL |     impl<const WHITE: (fn(),)> Color<WHITE> {
    |                       ^^^^^^^
+   |
+   = note: `fn()` must implement `ConstParamTy`, but it does not
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/overlapping_impls.rs b/tests/ui/const-generics/overlapping_impls.rs
index e599eadd8cf..2ce6c4a823c 100644
--- a/tests/ui/const-generics/overlapping_impls.rs
+++ b/tests/ui/const-generics/overlapping_impls.rs
@@ -2,7 +2,8 @@
 #![allow(incomplete_features)]
 #![feature(adt_const_params)]
 #![feature(generic_const_exprs)]
-use std::marker::PhantomData;
+
+use std::marker::{ConstParamTy, PhantomData};
 
 struct Foo<const I: i32, const J: i32> {}
 
@@ -22,7 +23,7 @@ pub struct Foo2<const P: Protocol, T> {
     _marker: PhantomData<T>,
 }
 
-#[derive(PartialEq, Eq)]
+#[derive(PartialEq, Eq, ConstParamTy)]
 pub enum Protocol {
     Variant1,
     Variant2,
diff --git a/tests/ui/const-generics/std/const-generics-range.full.stderr b/tests/ui/const-generics/std/const-generics-range.full.stderr
new file mode 100644
index 00000000000..5bf48ad7385
--- /dev/null
+++ b/tests/ui/const-generics/std/const-generics-range.full.stderr
@@ -0,0 +1,39 @@
+error[E0741]: `std::ops::Range<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:8:24
+   |
+LL | struct _Range<const R: std::ops::Range<usize>>;
+   |                        ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0741]: `RangeFrom<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:13:28
+   |
+LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0741]: `RangeFull` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:18:28
+   |
+LL | struct _RangeFull<const R: std::ops::RangeFull>;
+   |                            ^^^^^^^^^^^^^^^^^^^
+
+error[E0741]: `RangeInclusive<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:24:33
+   |
+LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0741]: `RangeTo<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:29:26
+   |
+LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0741]: `RangeToInclusive<usize>` must implement `ConstParamTy` to be used as the type of a const generic parameter
+  --> $DIR/const-generics-range.rs:34:35
+   |
+LL | struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0741`.
diff --git a/tests/ui/const-generics/std/const-generics-range.min.stderr b/tests/ui/const-generics/std/const-generics-range.min.stderr
index d4b2ad6fd0c..53fca6e884a 100644
--- a/tests/ui/const-generics/std/const-generics-range.min.stderr
+++ b/tests/ui/const-generics/std/const-generics-range.min.stderr
@@ -1,5 +1,5 @@
 error: `std::ops::Range<usize>` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:7:24
+  --> $DIR/const-generics-range.rs:8:24
    |
 LL | struct _Range<const R: std::ops::Range<usize>>;
    |                        ^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | struct _Range<const R: std::ops::Range<usize>>;
    = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: `RangeFrom<usize>` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:12:28
+  --> $DIR/const-generics-range.rs:13:28
    |
 LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
    = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: `RangeFull` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:17:28
+  --> $DIR/const-generics-range.rs:18:28
    |
 LL | struct _RangeFull<const R: std::ops::RangeFull>;
    |                            ^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL | struct _RangeFull<const R: std::ops::RangeFull>;
    = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: `RangeInclusive<usize>` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:23:33
+  --> $DIR/const-generics-range.rs:24:33
    |
 LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -35,7 +35,7 @@ LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
    = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: `RangeTo<usize>` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:28:26
+  --> $DIR/const-generics-range.rs:29:26
    |
 LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
    = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: `RangeToInclusive<usize>` is forbidden as the type of a const generic parameter
-  --> $DIR/const-generics-range.rs:33:35
+  --> $DIR/const-generics-range.rs:34:35
    |
 LL | struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/const-generics/std/const-generics-range.rs b/tests/ui/const-generics/std/const-generics-range.rs
index 46c06f312b9..bda59f3ec45 100644
--- a/tests/ui/const-generics/std/const-generics-range.rs
+++ b/tests/ui/const-generics/std/const-generics-range.rs
@@ -1,4 +1,5 @@
-// [full] check-pass
+// [full] known-bug: unknown
+
 // revisions: full min
 #![cfg_attr(full, feature(adt_const_params))]
 #![cfg_attr(full, allow(incomplete_features))]
diff --git a/tests/ui/consts/refs_check_const_eq-issue-88384.rs b/tests/ui/consts/refs_check_const_eq-issue-88384.rs
index 1496b28bd3e..fb0405b651c 100644
--- a/tests/ui/consts/refs_check_const_eq-issue-88384.rs
+++ b/tests/ui/consts/refs_check_const_eq-issue-88384.rs
@@ -8,10 +8,10 @@ struct CompileTimeSettings{
 }
 
 struct Foo<const T: CompileTimeSettings>;
-//~^ ERROR using function pointers as const generic parameters is forbidden
+//~^ ERROR `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter
 
 impl<const T: CompileTimeSettings> Foo<T> {
-    //~^ ERROR using function pointers as const generic parameters is forbidden
+    //~^ ERROR `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter
     fn call_hooks(){
     }
 }
diff --git a/tests/ui/consts/refs_check_const_eq-issue-88384.stderr b/tests/ui/consts/refs_check_const_eq-issue-88384.stderr
index 3855b5f2a68..c490cd053e7 100644
--- a/tests/ui/consts/refs_check_const_eq-issue-88384.stderr
+++ b/tests/ui/consts/refs_check_const_eq-issue-88384.stderr
@@ -7,17 +7,29 @@ LL | #![feature(adt_const_params)]
    = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0741]: using function pointers as const generic parameters is forbidden
+error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter
   --> $DIR/refs_check_const_eq-issue-88384.rs:10:21
    |
 LL | struct Foo<const T: CompileTimeSettings>;
    |                     ^^^^^^^^^^^^^^^^^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct CompileTimeSettings{
+   |
 
-error[E0741]: using function pointers as const generic parameters is forbidden
+error[E0741]: `CompileTimeSettings` must implement `ConstParamTy` to be used as the type of a const generic parameter
   --> $DIR/refs_check_const_eq-issue-88384.rs:13:15
    |
 LL | impl<const T: CompileTimeSettings> Foo<T> {
    |               ^^^^^^^^^^^^^^^^^^^
+   |
+help: add `#[derive(ConstParamTy)]` to the struct
+   |
+LL + #[derive(ConstParamTy)]
+LL | struct CompileTimeSettings{
+   |
 
 error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/mir/thir-constparam-temp.rs b/tests/ui/mir/thir-constparam-temp.rs
index cdc5910b36c..7eedc325d60 100644
--- a/tests/ui/mir/thir-constparam-temp.rs
+++ b/tests/ui/mir/thir-constparam-temp.rs
@@ -3,7 +3,9 @@
 #![feature(adt_const_params)]
 #![allow(incomplete_features)]
 
-#[derive(PartialEq, Eq)]
+use std::marker::ConstParamTy;
+
+#[derive(PartialEq, Eq, ConstParamTy)]
 struct Yikes;
 
 impl Yikes {
diff --git a/tests/ui/mir/thir-constparam-temp.stderr b/tests/ui/mir/thir-constparam-temp.stderr
index b77d67e084f..d50747e5434 100644
--- a/tests/ui/mir/thir-constparam-temp.stderr
+++ b/tests/ui/mir/thir-constparam-temp.stderr
@@ -1,5 +1,5 @@
 warning: taking a mutable reference to a `const` item
-  --> $DIR/thir-constparam-temp.rs:14:5
+  --> $DIR/thir-constparam-temp.rs:16:5
    |
 LL |     YIKES.mut_self()
    |     ^^^^^^^^^^^^^^^^
@@ -7,12 +7,12 @@ LL |     YIKES.mut_self()
    = note: each usage of a `const` item creates a new temporary
    = note: the mutable reference will refer to this temporary, not the original `const` item
 note: mutable reference created due to call to this method
-  --> $DIR/thir-constparam-temp.rs:10:5
+  --> $DIR/thir-constparam-temp.rs:12:5
    |
 LL |     fn mut_self(&mut self) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^
 note: `const` item defined here
-  --> $DIR/thir-constparam-temp.rs:13:8
+  --> $DIR/thir-constparam-temp.rs:15:8
    |
 LL | fn foo<const YIKES: Yikes>() {
    |        ^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/offset-of/offset-of-dst-field.rs b/tests/ui/offset-of/offset-of-dst-field.rs
index 3b8dc0b84a4..e393b159e64 100644
--- a/tests/ui/offset-of/offset-of-dst-field.rs
+++ b/tests/ui/offset-of/offset-of-dst-field.rs
@@ -36,6 +36,8 @@ fn main() {
     offset_of!(Alpha, z); //~ ERROR the size for values of type
     offset_of!(Beta, z); //~ ERROR the size for values of type
     offset_of!(Gamma, z); //~ ERROR the size for values of type
+    offset_of!((u8, dyn Trait), 0); // ok
+    offset_of!((u8, dyn Trait), 1); //~ ERROR the size for values of type
 }
 
 fn delta() {
diff --git a/tests/ui/offset-of/offset-of-dst-field.stderr b/tests/ui/offset-of/offset-of-dst-field.stderr
index 128c783d5dd..4eaceaa9358 100644
--- a/tests/ui/offset-of/offset-of-dst-field.stderr
+++ b/tests/ui/offset-of/offset-of-dst-field.stderr
@@ -25,8 +25,17 @@ LL |     offset_of!(Gamma, z);
    = help: the trait `Sized` is not implemented for `Extern`
    = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
+error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
+  --> $DIR/offset-of-dst-field.rs:40:5
+   |
+LL |     offset_of!((u8, dyn Trait), 1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `dyn Trait`
+   = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
+
 error[E0277]: the size for values of type `Extern` cannot be known at compilation time
-  --> $DIR/offset-of-dst-field.rs:43:5
+  --> $DIR/offset-of-dst-field.rs:45:5
    |
 LL |     offset_of!(Delta<Extern>, z);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -35,7 +44,7 @@ LL |     offset_of!(Delta<Extern>, z);
    = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the size for values of type `dyn Trait` cannot be known at compilation time
-  --> $DIR/offset-of-dst-field.rs:44:5
+  --> $DIR/offset-of-dst-field.rs:46:5
    |
 LL |     offset_of!(Delta<dyn Trait>, z);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -44,7 +53,7 @@ LL |     offset_of!(Delta<dyn Trait>, z);
    = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/offset-of-dst-field.rs:42:5
+  --> $DIR/offset-of-dst-field.rs:44:5
    |
 LL |     offset_of!(Delta<Alpha>, z);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -58,7 +67,7 @@ LL | struct Alpha {
    = note: this error originates in the macro `offset_of` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the size for values of type `T` cannot be known at compilation time
-  --> $DIR/offset-of-dst-field.rs:48:5
+  --> $DIR/offset-of-dst-field.rs:50:5
    |
 LL | fn generic_with_maybe_sized<T: ?Sized>() -> usize {
    |                             - this type parameter needs to be `std::marker::Sized`
@@ -72,6 +81,6 @@ LL - fn generic_with_maybe_sized<T: ?Sized>() -> usize {
 LL + fn generic_with_maybe_sized<T>() -> usize {
    |
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/offset-of/offset-of-tuple.rs b/tests/ui/offset-of/offset-of-tuple.rs
new file mode 100644
index 00000000000..4077538b77f
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-tuple.rs
@@ -0,0 +1,10 @@
+#![feature(offset_of)]
+#![feature(builtin_syntax)]
+
+fn main() {
+    core::mem::offset_of!((u8, u8), _0); //~ ERROR no field `_0`
+    core::mem::offset_of!((u8, u8), +1); //~ ERROR no rules expected
+    core::mem::offset_of!((u8, u8), -1); //~ ERROR no rules expected
+    builtin # offset_of((u8, u8), _0); //~ ERROR no field `_0`
+    builtin # offset_of((u8, u8), +1); //~ ERROR expected identifier
+}
diff --git a/tests/ui/offset-of/offset-of-tuple.stderr b/tests/ui/offset-of/offset-of-tuple.stderr
new file mode 100644
index 00000000000..cc9ce0f3455
--- /dev/null
+++ b/tests/ui/offset-of/offset-of-tuple.stderr
@@ -0,0 +1,37 @@
+error: expected identifier, found `+`
+  --> $DIR/offset-of-tuple.rs:9:35
+   |
+LL |     builtin # offset_of((u8, u8), +1);
+   |                                   ^ expected identifier
+
+error: no rules expected the token `1`
+  --> $DIR/offset-of-tuple.rs:6:38
+   |
+LL |     core::mem::offset_of!((u8, u8), +1);
+   |                                      ^ no rules expected this token in macro call
+   |
+   = note: while trying to match sequence start
+
+error: no rules expected the token `1`
+  --> $DIR/offset-of-tuple.rs:7:38
+   |
+LL |     core::mem::offset_of!((u8, u8), -1);
+   |                                      ^ no rules expected this token in macro call
+   |
+   = note: while trying to match sequence start
+
+error[E0609]: no field `_0` on type `(u8, u8)`
+  --> $DIR/offset-of-tuple.rs:5:37
+   |
+LL |     core::mem::offset_of!((u8, u8), _0);
+   |                                     ^^
+
+error[E0609]: no field `_0` on type `(u8, u8)`
+  --> $DIR/offset-of-tuple.rs:8:35
+   |
+LL |     builtin # offset_of((u8, u8), _0);
+   |                                   ^^
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/tests/ui/offset-of/offset-of-unsized.rs b/tests/ui/offset-of/offset-of-unsized.rs
index 666387e615e..49c8328da5c 100644
--- a/tests/ui/offset-of/offset-of-unsized.rs
+++ b/tests/ui/offset-of/offset-of-unsized.rs
@@ -1,5 +1,6 @@
 // build-pass
-// regression test for #112051
+// regression test for #112051, not in `offset-of-dst` as the issue is in codegen,
+// and isn't triggered in the presence of typeck errors
 
 #![feature(offset_of)]
 
diff --git a/tests/ui/sanitize/issue-111184-generator-witness.rs b/tests/ui/sanitize/issue-111184-generator-witness.rs
new file mode 100644
index 00000000000..8f4118057ce
--- /dev/null
+++ b/tests/ui/sanitize/issue-111184-generator-witness.rs
@@ -0,0 +1,17 @@
+// Regression test for issue 111184, where ty::GeneratorWitness were not expected to occur in
+// encode_ty and caused the compiler to ICE.
+//
+// needs-sanitizer-cfi
+// compile-flags: -Clto -Ctarget-feature=-crt-static -Zsanitizer=cfi --edition=2021
+// no-prefer-dynamic
+// only-x86_64-unknown-linux-gnu
+// run-pass
+
+use std::future::Future;
+
+async fn foo() {}
+fn bar<T>(_: impl Future<Output = T>) {}
+
+fn main() {
+    bar(foo());
+}
diff --git a/tests/ui/symbol-names/const-generics-structural-demangling.rs b/tests/ui/symbol-names/const-generics-structural-demangling.rs
index df09ba494a7..947fddf3f31 100644
--- a/tests/ui/symbol-names/const-generics-structural-demangling.rs
+++ b/tests/ui/symbol-names/const-generics-structural-demangling.rs
@@ -1,14 +1,13 @@
 // build-fail
 // compile-flags: -C symbol-mangling-version=v0 --crate-name=c
 
-// NOTE(eddyb) we need `core` for `core::option::Option`, normalize away its
-// disambiguator hash, which can/should change (including between stage{1,2}).
-// normalize-stderr-test: "core\[[0-9a-f]+\]" -> "core[HASH]"
 // normalize-stderr-test: "c\[[0-9a-f]+\]" -> "c[HASH]"
 
 #![feature(adt_const_params, decl_macro, rustc_attrs)]
 #![allow(incomplete_features)]
 
+use std::marker::ConstParamTy;
+
 pub struct RefByte<const RB: &'static u8>;
 
 #[rustc_symbol_name]
@@ -43,25 +42,31 @@ pub struct TupleByteBool<const TBB: (u8, bool)>;
 //~| ERROR demangling-alt(<c::TupleByteBool<{(1, false)}>>)
 impl TupleByteBool<{(1, false)}> {}
 
-pub struct OptionUsize<const OU: Option<usize>>;
+#[derive(PartialEq, Eq, ConstParamTy)]
+pub enum MyOption<T> {
+    Some(T),
+    None,
+}
+
+pub struct OptionUsize<const OU: MyOption<usize>>;
 
 // HACK(eddyb) the full mangling is only in `.stderr` because we can normalize
 // the `core` disambiguator hash away there, but not here.
 #[rustc_symbol_name]
 //~^ ERROR symbol-name
 //~| ERROR demangling
-//~| ERROR demangling-alt(<c::OptionUsize<{core::option::Option::<usize>::None}>>)
-impl OptionUsize<{None}> {}
+//~| ERROR demangling-alt(<c::OptionUsize<{c::MyOption::<usize>::None}>>)
+impl OptionUsize<{MyOption::None}> {}
 
 // HACK(eddyb) the full mangling is only in `.stderr` because we can normalize
 // the `core` disambiguator hash away there, but not here.
 #[rustc_symbol_name]
 //~^ ERROR symbol-name
 //~| ERROR demangling
-//~| ERROR demangling-alt(<c::OptionUsize<{core::option::Option::<usize>::Some(0)}>>)
-impl OptionUsize<{Some(0)}> {}
+//~| ERROR demangling-alt(<c::OptionUsize<{c::MyOption::<usize>::Some(0)}>>)
+impl OptionUsize<{MyOption::Some(0)}> {}
 
-#[derive(PartialEq, Eq)]
+#[derive(PartialEq, Eq, ConstParamTy)]
 pub struct Foo {
     s: &'static str,
     ch: char,
@@ -78,7 +83,7 @@ impl Foo_<{Foo { s: "abc", ch: 'x', slice: &[1, 2, 3] }}> {}
 // NOTE(eddyb) this tests specifically the use of disambiguators in field names,
 // using macros 2.0 hygiene to create a `struct` with conflicting field names.
 macro duplicate_field_name_test($x:ident) {
-    #[derive(PartialEq, Eq)]
+    #[derive(PartialEq, Eq, ConstParamTy)]
     pub struct Bar {
         $x: u8,
         x: u16,
diff --git a/tests/ui/symbol-names/const-generics-structural-demangling.stderr b/tests/ui/symbol-names/const-generics-structural-demangling.stderr
index a4c997477ee..96dea154d05 100644
--- a/tests/ui/symbol-names/const-generics-structural-demangling.stderr
+++ b/tests/ui/symbol-names/const-generics-structural-demangling.stderr
@@ -1,131 +1,131 @@
 error: symbol-name(_RMCsCRATE_HASH_1cINtB<REF>_7RefByteKRh7b_E)
-  --> $DIR/const-generics-structural-demangling.rs:14:1
+  --> $DIR/const-generics-structural-demangling.rs:13:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling(<c[HASH]::RefByte<{&123u8}>>)
-  --> $DIR/const-generics-structural-demangling.rs:14:1
+  --> $DIR/const-generics-structural-demangling.rs:13:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling-alt(<c::RefByte<{&123}>>)
-  --> $DIR/const-generics-structural-demangling.rs:14:1
+  --> $DIR/const-generics-structural-demangling.rs:13:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: symbol-name(_RMs_CsCRATE_HASH_1cINtB<REF>_6RefZstKRAEE)
-  --> $DIR/const-generics-structural-demangling.rs:24:1
+  --> $DIR/const-generics-structural-demangling.rs:23:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling(<c[HASH]::RefZst<{&[]}>>)
-  --> $DIR/const-generics-structural-demangling.rs:24:1
+  --> $DIR/const-generics-structural-demangling.rs:23:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling-alt(<c::RefZst<{&[]}>>)
-  --> $DIR/const-generics-structural-demangling.rs:24:1
+  --> $DIR/const-generics-structural-demangling.rs:23:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: symbol-name(_RMs0_CsCRATE_HASH_1cINtB<REF>_11Array3BytesKAh1_h2_h3_EE)
-  --> $DIR/const-generics-structural-demangling.rs:32:1
+  --> $DIR/const-generics-structural-demangling.rs:31:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling(<c[HASH]::Array3Bytes<{[1u8, 2u8, 3u8]}>>)
-  --> $DIR/const-generics-structural-demangling.rs:32:1
+  --> $DIR/const-generics-structural-demangling.rs:31:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling-alt(<c::Array3Bytes<{[1, 2, 3]}>>)
-  --> $DIR/const-generics-structural-demangling.rs:32:1
+  --> $DIR/const-generics-structural-demangling.rs:31:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: symbol-name(_RMs1_CsCRATE_HASH_1cINtB<REF>_13TupleByteBoolKTh1_b0_EE)
-  --> $DIR/const-generics-structural-demangling.rs:40:1
+  --> $DIR/const-generics-structural-demangling.rs:39:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling(<c[HASH]::TupleByteBool<{(1u8, false)}>>)
-  --> $DIR/const-generics-structural-demangling.rs:40:1
+  --> $DIR/const-generics-structural-demangling.rs:39:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling-alt(<c::TupleByteBool<{(1, false)}>>)
-  --> $DIR/const-generics-structural-demangling.rs:40:1
+  --> $DIR/const-generics-structural-demangling.rs:39:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: symbol-name(_RMs2_CsCRATE_HASH_1cINtB<REF>_11OptionUsizeKVNtINtNtCsCRATE_HASH_4core6option6OptionjE4NoneUE)
-  --> $DIR/const-generics-structural-demangling.rs:50:1
+error: symbol-name(_RMs2_CsCRATE_HASH_1cINtB<REF>_11OptionUsizeKVNtINtB<REF>_8MyOptionjE4NoneUE)
+  --> $DIR/const-generics-structural-demangling.rs:55:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(<c[HASH]::OptionUsize<{core[HASH]::option::Option::<usize>::None}>>)
-  --> $DIR/const-generics-structural-demangling.rs:50:1
+error: demangling(<c[HASH]::OptionUsize<{c[HASH]::MyOption::<usize>::None}>>)
+  --> $DIR/const-generics-structural-demangling.rs:55:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling-alt(<c::OptionUsize<{core::option::Option::<usize>::None}>>)
-  --> $DIR/const-generics-structural-demangling.rs:50:1
+error: demangling-alt(<c::OptionUsize<{c::MyOption::<usize>::None}>>)
+  --> $DIR/const-generics-structural-demangling.rs:55:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: symbol-name(_RMs3_CsCRATE_HASH_1cINtB<REF>_11OptionUsizeKVNtINtNtCsCRATE_HASH_4core6option6OptionjE4SomeTj0_EE)
-  --> $DIR/const-generics-structural-demangling.rs:58:1
+error: symbol-name(_RMs3_CsCRATE_HASH_1cINtB<REF>_11OptionUsizeKVNtINtB<REF>_8MyOptionjE4SomeTj0_EE)
+  --> $DIR/const-generics-structural-demangling.rs:63:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(<c[HASH]::OptionUsize<{core[HASH]::option::Option::<usize>::Some(0usize)}>>)
-  --> $DIR/const-generics-structural-demangling.rs:58:1
+error: demangling(<c[HASH]::OptionUsize<{c[HASH]::MyOption::<usize>::Some(0usize)}>>)
+  --> $DIR/const-generics-structural-demangling.rs:63:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling-alt(<c::OptionUsize<{core::option::Option::<usize>::Some(0)}>>)
-  --> $DIR/const-generics-structural-demangling.rs:58:1
+error: demangling-alt(<c::OptionUsize<{c::MyOption::<usize>::Some(0)}>>)
+  --> $DIR/const-generics-structural-demangling.rs:63:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: symbol-name(_RMs4_CsCRATE_HASH_1cINtB<REF>_4Foo_KVNtB<REF>_3FooS1sRe616263_2chc78_5sliceRAh1_h2_h3_EEE)
-  --> $DIR/const-generics-structural-demangling.rs:72:1
+  --> $DIR/const-generics-structural-demangling.rs:77:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling(<c[HASH]::Foo_<{c[HASH]::Foo { s: "abc", ch: 'x', slice: &[1u8, 2u8, 3u8] }}>>)
-  --> $DIR/const-generics-structural-demangling.rs:72:1
+  --> $DIR/const-generics-structural-demangling.rs:77:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
 error: demangling-alt(<c::Foo_<{c::Foo { s: "abc", ch: 'x', slice: &[1, 2, 3] }}>>)
-  --> $DIR/const-generics-structural-demangling.rs:72:1
+  --> $DIR/const-generics-structural-demangling.rs:77:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: symbol-name(_RMs9_CsCRATE_HASH_1cINtB<REF>_4Bar_KVNtB<REF>_3BarS1xh7b_s_1xt1000_EE)
-  --> $DIR/const-generics-structural-demangling.rs:88:5
+error: symbol-name(_RMsf_CsCRATE_HASH_1cINtB<REF>_4Bar_KVNtB<REF>_3BarS1xh7b_s_1xt1000_EE)
+  --> $DIR/const-generics-structural-demangling.rs:93:5
    |
 LL |     #[rustc_symbol_name]
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -136,7 +136,7 @@ LL | duplicate_field_name_test!(x);
    = note: this error originates in the macro `duplicate_field_name_test` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: demangling(<c[HASH]::Bar_<{c[HASH]::Bar { x: 123u8, x: 4096u16 }}>>)
-  --> $DIR/const-generics-structural-demangling.rs:88:5
+  --> $DIR/const-generics-structural-demangling.rs:93:5
    |
 LL |     #[rustc_symbol_name]
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -147,7 +147,7 @@ LL | duplicate_field_name_test!(x);
    = note: this error originates in the macro `duplicate_field_name_test` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: demangling-alt(<c::Bar_<{c::Bar { x: 123, x: 4096 }}>>)
-  --> $DIR/const-generics-structural-demangling.rs:88:5
+  --> $DIR/const-generics-structural-demangling.rs:93:5
    |
 LL |     #[rustc_symbol_name]
    |     ^^^^^^^^^^^^^^^^^^^^