about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs67
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs6
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs1
-rw-r--r--compiler/rustc_resolve/messages.ftl9
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs6
-rw-r--r--compiler/rustc_resolve/src/errors.rs13
-rw-r--r--compiler/rustc_resolve/src/ident.rs42
-rw-r--r--compiler/rustc_resolve/src/late.rs49
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs1
-rw-r--r--compiler/rustc_resolve/src/lib.rs8
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs3
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr4
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr4
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr2
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr2
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/bad_inference.rs23
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/bad_inference.stderr14
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/evaluate_const_parameter_in_mir.rs19
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs11
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr15
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/inferred_from_arg.rs13
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.rs20
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.stderr23
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.rs15
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.stderr21
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.rs9
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr11
-rw-r--r--tests/ui/const-generics/generic_const_parameter_types/unrelated_inferred_arg.rs21
-rw-r--r--tests/ui/const-generics/issues/issue-56445-1.full.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-56445-1.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-62878.full.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-62878.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71169.full.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71169.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71381.full.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-71381.min.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-71611.full.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71611.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-88997.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-90364.stderr2
-rw-r--r--tests/ui/error-codes/E0771.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr21
-rw-r--r--tests/ui/feature-gates/feature-gate-generic-const-parameter-types.rs11
-rw-r--r--tests/ui/generic-const-items/wfcheck_err_leak_issue_118179.stderr2
-rw-r--r--tests/ui/lifetimes/unusual-rib-combinations.stderr2
-rw-r--r--tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs1
-rw-r--r--tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr26
56 files changed, 419 insertions, 154 deletions
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 66c26a541f1..0acd3b0f800 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -508,6 +508,8 @@ declare_features! (
     (incomplete, generic_const_exprs, "1.56.0", Some(76560)),
     /// Allows generic parameters and where-clauses on free & associated const items.
     (incomplete, generic_const_items, "1.73.0", Some(113521)),
+    /// Allows the type of const generics to depend on generic parameters
+    (incomplete, generic_const_parameter_types, "CURRENT_RUSTC_VERSION", Some(137626)),
     /// Allows any generic constants being used as pattern type range ends
     (incomplete, generic_pattern_types, "1.86.0", Some(136574)),
     /// Allows registering static items globally, possibly across crates, to iterate over at runtime.
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index e6ea6eddcaa..d72cf00293f 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -966,7 +966,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
             let ty = tcx.type_of(param.def_id).instantiate_identity();
 
             if tcx.features().unsized_const_params() {
-                enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
+                enter_wf_checking_ctxt(tcx, hir_ty.span, tcx.local_parent(param.def_id), |wfcx| {
                     wfcx.register_bound(
                         ObligationCause::new(
                             hir_ty.span,
@@ -980,7 +980,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(),
                     Ok(())
                 })
             } else if tcx.features().adt_const_params() {
-                enter_wf_checking_ctxt(tcx, hir_ty.span, param.def_id, |wfcx| {
+                enter_wf_checking_ctxt(tcx, hir_ty.span, tcx.local_parent(param.def_id), |wfcx| {
                     wfcx.register_bound(
                         ObligationCause::new(
                             hir_ty.span,
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 08d63f4349e..027aa5554a4 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1822,6 +1822,9 @@ fn const_param_default<'tcx>(
         ),
     };
     let icx = ItemCtxt::new(tcx, def_id);
-    let ct = icx.lowerer().lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id()));
+    let identity_args = ty::GenericArgs::identity_for_item(tcx, def_id);
+    let ct = icx
+        .lowerer()
+        .lower_const_arg(default_ct, FeedConstTy::Param(def_id.to_def_id(), identity_args));
     ty::EarlyBinder::bind(ct)
 }
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 5b511d27074..49549335363 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -223,10 +223,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
             }
             hir::GenericParamKind::Const { .. } => {
                 let param_def_id = param.def_id.to_def_id();
-                let ct_ty = tcx
-                    .type_of(param_def_id)
-                    .no_bound_vars()
-                    .expect("const parameters cannot be generic");
+                let ct_ty = tcx.type_of(param_def_id).instantiate_identity();
                 let ct = icx.lowerer().lower_const_param(param_def_id, param.hir_id);
                 predicates
                     .insert((ty::ClauseKind::ConstArgHasType(ct, ct_ty).upcast(tcx), param.span));
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
index 8d58a3bfbd3..fa58f12c553 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
@@ -273,7 +273,7 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
 
                             // We lower to an infer even when the feature gate is not enabled
                             // as it is useful for diagnostics to be able to see a `ConstKind::Infer`
-                            args.push(ctx.provided_kind(param, arg));
+                            args.push(ctx.provided_kind(&args, param, arg));
                             args_iter.next();
                             params.next();
                         }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index 750770178ee..a0f848f07c4 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -232,12 +232,15 @@ impl AssocItemQSelf {
 /// Use this enum with `<dyn HirTyLowerer>::lower_const_arg` to instruct it with the
 /// desired behavior.
 #[derive(Debug, Clone, Copy)]
-pub enum FeedConstTy {
+pub enum FeedConstTy<'a, 'tcx> {
     /// Feed the type.
     ///
     /// The `DefId` belongs to the const param that we are supplying
     /// this (anon) const arg to.
-    Param(DefId),
+    ///
+    /// The list of generic args is used to instantiate the parameters
+    /// used by the type of the const param specified by `DefId`.
+    Param(DefId, &'a [ty::GenericArg<'tcx>]),
     /// Don't feed the type.
     No,
 }
@@ -298,6 +301,7 @@ pub trait GenericArgsLowerer<'a, 'tcx> {
 
     fn provided_kind(
         &mut self,
+        preceding_args: &[ty::GenericArg<'tcx>],
         param: &ty::GenericParamDef,
         arg: &GenericArg<'tcx>,
     ) -> ty::GenericArg<'tcx>;
@@ -481,6 +485,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
             fn provided_kind(
                 &mut self,
+                preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 arg: &GenericArg<'tcx>,
             ) -> ty::GenericArg<'tcx> {
@@ -526,7 +531,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
                         .lowerer
                         // Ambig portions of `ConstArg` are handled in the match arm below
-                        .lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id))
+                        .lower_const_arg(
+                            ct.as_unambig_ct(),
+                            FeedConstTy::Param(param.def_id, preceding_args),
+                        )
                         .into(),
                     (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
                         self.lowerer.ct_infer(Some(param), inf.span).into()
@@ -582,8 +590,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         let ty = tcx
                             .at(self.span)
                             .type_of(param.def_id)
-                            .no_bound_vars()
-                            .expect("const parameter types cannot be generic");
+                            .instantiate(tcx, preceding_args);
                         if let Err(guar) = ty.error_reported() {
                             return ty::Const::new_error(tcx, guar).into();
                         }
@@ -2107,14 +2114,50 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     pub fn lower_const_arg(
         &self,
         const_arg: &hir::ConstArg<'tcx>,
-        feed: FeedConstTy,
+        feed: FeedConstTy<'_, 'tcx>,
     ) -> Const<'tcx> {
         let tcx = self.tcx();
 
-        if let FeedConstTy::Param(param_def_id) = feed
+        if let FeedConstTy::Param(param_def_id, args) = feed
             && let hir::ConstArgKind::Anon(anon) = &const_arg.kind
         {
-            tcx.feed_anon_const_type(anon.def_id, tcx.type_of(param_def_id));
+            let anon_const_type = tcx.type_of(param_def_id).instantiate(tcx, args);
+
+            // We must error if the instantiated type has any inference variables as we will
+            // use this type to feed the `type_of` and query results must not contain inference
+            // variables otherwise we will ICE.
+            //
+            // We also error if the type contains any regions as effectively any region will wind
+            // up as a region variable in mir borrowck. It would also be somewhat concerning if
+            // hir typeck was using equality but mir borrowck wound up using subtyping as that could
+            // result in a non-infer in hir typeck but a region variable in borrowck.
+            //
+            // FIXME(generic_const_parameter_types): Ideally we remove these errors one day when
+            // we have the ability to intermix typeck of anon const const args with the parent
+            // bodies typeck.
+            if tcx.features().generic_const_parameter_types()
+                && (anon_const_type.has_free_regions() || anon_const_type.has_erased_regions())
+            {
+                let e = tcx.dcx().span_err(
+                    const_arg.span(),
+                    "anonymous constants with lifetimes in their type are not yet supported",
+                );
+                tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
+                return ty::Const::new_error(tcx, e);
+            }
+            if anon_const_type.has_non_region_infer() {
+                let e = tcx.dcx().span_err(
+                    const_arg.span(),
+                    "anonymous constants with inferred types are not yet supported",
+                );
+                tcx.feed_anon_const_type(anon.def_id, ty::EarlyBinder::bind(Ty::new_error(tcx, e)));
+                return ty::Const::new_error(tcx, e);
+            }
+
+            tcx.feed_anon_const_type(
+                anon.def_id,
+                ty::EarlyBinder::bind(tcx.type_of(param_def_id).instantiate(tcx, args)),
+            );
         }
 
         let hir_id = const_arg.hir_id;
@@ -2230,10 +2273,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let expr = &tcx.hir_body(anon.body).value;
         debug!(?expr);
 
-        let ty = tcx
-            .type_of(anon.def_id)
-            .no_bound_vars()
-            .expect("const parameter types cannot be generic");
+        // FIXME(generic_const_parameter_types): We should use the proper generic args
+        // here. It's only used as a hint for literals so doesn't matter too much to use the right
+        // generic arguments, just weaker type inference.
+        let ty = tcx.type_of(anon.def_id).instantiate_identity();
 
         match self.try_lower_anon_const_lit(ty, expr) {
             Some(v) => v,
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index bdfbd540e40..cf18bab950a 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -260,7 +260,7 @@ pub fn lower_ty<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: &hir::Ty<'tcx>) -> Ty<'tcx> {
 pub fn lower_const_arg_for_rustdoc<'tcx>(
     tcx: TyCtxt<'tcx>,
     hir_ct: &hir::ConstArg<'tcx>,
-    feed: FeedConstTy,
+    feed: FeedConstTy<'_, 'tcx>,
 ) -> Const<'tcx> {
     let env_def_id = tcx.hir_get_parent_item(hir_ct.hir_id);
     collect::ItemCtxt::new(tcx, env_def_id.def_id).lowerer().lower_const_arg(hir_ct, feed)
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 2d7d80e39bc..7c01c26bed8 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -519,7 +519,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub(crate) fn lower_const_arg(
         &self,
         const_arg: &'tcx hir::ConstArg<'tcx>,
-        feed: FeedConstTy,
+        feed: FeedConstTy<'_, 'tcx>,
     ) -> ty::Const<'tcx> {
         let ct = self.lowerer().lower_const_arg(const_arg, feed);
         self.register_wf_obligation(
@@ -1135,7 +1135,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .last()
             .is_some_and(|GenericPathSegment(def_id, _)| tcx.generics_of(*def_id).has_self);
 
-        let (res, self_ctor_args) = if let Res::SelfCtor(impl_def_id) = res {
+        let (res, implicit_args) = if let Res::Def(DefKind::ConstParam, def) = res {
+            // types of const parameters are somewhat special as they are part of
+            // the same environment as the const parameter itself. this means that
+            // unlike most paths `type-of(N)` can return a type naming parameters
+            // introduced by the containing item, rather than provided through `N`.
+            //
+            // for example given `<T, const M: usize, const N: [T; M]>` and some
+            // `let a = N;` expression. The path to `N` would wind up with no args
+            // (as it has no args), but instantiating the early binder on `typeof(N)`
+            // requires providing generic arguments for `[T, M, N]`.
+            (res, Some(ty::GenericArgs::identity_for_item(tcx, tcx.parent(def))))
+        } else if let Res::SelfCtor(impl_def_id) = res {
             let ty = LoweredTy::from_raw(
                 self,
                 span,
@@ -1261,6 +1272,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             fn provided_kind(
                 &mut self,
+                preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 arg: &GenericArg<'tcx>,
             ) -> ty::GenericArg<'tcx> {
@@ -1280,7 +1292,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
                         .fcx
                         // Ambiguous parts of `ConstArg` are handled in the match arms below
-                        .lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id))
+                        .lower_const_arg(
+                            ct.as_unambig_ct(),
+                            FeedConstTy::Param(param.def_id, preceding_args),
+                        )
                         .into(),
                     (&GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
                         self.fcx.ct_infer(Some(param), inf.span).into()
@@ -1320,7 +1335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        let args_raw = self_ctor_args.unwrap_or_else(|| {
+        let args_raw = implicit_args.unwrap_or_else(|| {
             lower_generic_args(
                 self,
                 def_id,
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 3b107fbf173..0483164ca03 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -426,6 +426,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
 
             fn provided_kind(
                 &mut self,
+                preceding_args: &[ty::GenericArg<'tcx>],
                 param: &ty::GenericParamDef,
                 arg: &GenericArg<'tcx>,
             ) -> ty::GenericArg<'tcx> {
@@ -446,7 +447,10 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                     (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => self
                         .cfcx
                         // We handle the ambig portions of `ConstArg` in the match arms below
-                        .lower_const_arg(ct.as_unambig_ct(), FeedConstTy::Param(param.def_id))
+                        .lower_const_arg(
+                            ct.as_unambig_ct(),
+                            FeedConstTy::Param(param.def_id, preceding_args),
+                        )
                         .into(),
                     (GenericParamDefKind::Const { .. }, GenericArg::Infer(inf)) => {
                         self.cfcx.ct_infer(Some(param), inf.span).into()
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index d5617adf26b..e46ab302be2 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -342,6 +342,7 @@ impl ParamConst {
         ParamConst::new(def.index, def.name)
     }
 
+    #[instrument(level = "debug")]
     pub fn find_ty_from_env<'tcx>(self, env: ParamEnv<'tcx>) -> Ty<'tcx> {
         let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
             // `ConstArgHasType` are never desugared to be higher ranked.
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index b13de2875bc..9f062b3935f 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -125,9 +125,6 @@ resolve_const_param_in_enum_discriminant =
 resolve_const_param_in_non_trivial_anon_const =
     const parameters may only be used as standalone arguments, i.e. `{$name}`
 
-resolve_const_param_in_ty_of_const_param =
-    const parameters may not be used in the type of const parameters
-
 resolve_constructor_private_if_any_field_private =
     a constructor is private if any of the fields is private
 
@@ -250,9 +247,6 @@ resolve_lifetime_param_in_enum_discriminant =
 resolve_lifetime_param_in_non_trivial_anon_const =
     lifetime parameters may not be used in const expressions
 
-resolve_lifetime_param_in_ty_of_const_param =
-    lifetime parameters may not be used in the type of const parameters
-
 resolve_lowercase_self =
     attempt to use a non-constant value in a constant
     .suggestion = try using `Self`
@@ -437,9 +431,6 @@ resolve_type_param_in_enum_discriminant =
 resolve_type_param_in_non_trivial_anon_const =
     type parameters may not be used in const expressions
 
-resolve_type_param_in_ty_of_const_param =
-    type parameters may not be used in the type of const parameters
-
 resolve_undeclared_label =
     use of undeclared label `{$name}`
     .label = undeclared label `{$name}`
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 20af56e7ee4..e3405c89b79 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -890,9 +890,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             ResolutionError::ForwardDeclaredGenericParam => {
                 self.dcx().create_err(errs::ForwardDeclaredGenericParam { span })
             }
-            ResolutionError::ParamInTyOfConstParam { name, param_kind: is_type } => self
-                .dcx()
-                .create_err(errs::ParamInTyOfConstParam { span, name, param_kind: is_type }),
+            ResolutionError::ParamInTyOfConstParam { name } => {
+                self.dcx().create_err(errs::ParamInTyOfConstParam { span, name })
+            }
             ResolutionError::ParamInNonTrivialAnonConst { name, param_kind: is_type } => {
                 self.dcx().create_err(errs::ParamInNonTrivialAnonConst {
                     span,
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 7eb795034b0..b5d3e5ea776 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -347,19 +347,6 @@ pub(crate) struct ParamInTyOfConstParam {
     #[label]
     pub(crate) span: Span,
     pub(crate) name: Symbol,
-    #[subdiagnostic]
-    pub(crate) param_kind: Option<ParamKindInTyOfConstParam>,
-}
-
-#[derive(Debug)]
-#[derive(Subdiagnostic)]
-pub(crate) enum ParamKindInTyOfConstParam {
-    #[note(resolve_type_param_in_ty_of_const_param)]
-    Type,
-    #[note(resolve_const_param_in_ty_of_const_param)]
-    Const,
-    #[note(resolve_lifetime_param_in_ty_of_const_param)]
-    Lifetime,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 499b9bca4d2..d9776be4dd0 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -1131,6 +1131,17 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
             return Res::Err;
         }
 
+        if let RibKind::ConstParamTy = all_ribs[rib_index].kind {
+            if let Some(span) = finalize {
+                self.report_error(
+                    span,
+                    ResolutionError::ParamInTyOfConstParam { name: rib_ident.name },
+                );
+            }
+            assert_eq!(res, Res::Err);
+            return Res::Err;
+        }
+
         match res {
             Res::Local(_) => {
                 use ResolutionError::*;
@@ -1209,10 +1220,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                             if let Some(span) = finalize {
                                 self.report_error(
                                     span,
-                                    ParamInTyOfConstParam {
-                                        name: rib_ident.name,
-                                        param_kind: None,
-                                    },
+                                    ParamInTyOfConstParam { name: rib_ident.name },
                                 );
                             }
                             return Res::Err;
@@ -1239,6 +1247,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         | RibKind::MacroDefinition(..)
                         | RibKind::InlineAsmSym
                         | RibKind::AssocItem
+                        | RibKind::ConstParamTy
                         | RibKind::ForwardGenericParamBan => {
                             // Nothing to do. Continue.
                             continue;
@@ -1292,18 +1301,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         RibKind::Item(has_generic_params, def_kind) => {
                             (has_generic_params, def_kind)
                         }
-                        RibKind::ConstParamTy => {
-                            if let Some(span) = finalize {
-                                self.report_error(
-                                    span,
-                                    ResolutionError::ParamInTyOfConstParam {
-                                        name: rib_ident.name,
-                                        param_kind: Some(errors::ParamKindInTyOfConstParam::Type),
-                                    },
-                                );
-                            }
-                            return Res::Err;
-                        }
                     };
 
                     if let Some(span) = finalize {
@@ -1328,6 +1325,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         | RibKind::MacroDefinition(..)
                         | RibKind::InlineAsmSym
                         | RibKind::AssocItem
+                        | RibKind::ConstParamTy
                         | RibKind::ForwardGenericParamBan => continue,
 
                         RibKind::ConstantItem(trivial, _) => {
@@ -1361,18 +1359,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                         RibKind::Item(has_generic_params, def_kind) => {
                             (has_generic_params, def_kind)
                         }
-                        RibKind::ConstParamTy => {
-                            if let Some(span) = finalize {
-                                self.report_error(
-                                    span,
-                                    ResolutionError::ParamInTyOfConstParam {
-                                        name: rib_ident.name,
-                                        param_kind: Some(errors::ParamKindInTyOfConstParam::Const),
-                                    },
-                                );
-                            }
-                            return Res::Err;
-                        }
                     };
 
                     // This was an attempt to use a const parameter outside its scope.
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 32ef781631b..f119ed55e7d 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -227,9 +227,11 @@ impl RibKind<'_> {
             | RibKind::ConstantItem(..)
             | RibKind::Module(_)
             | RibKind::MacroDefinition(_)
-            | RibKind::ConstParamTy
             | RibKind::InlineAsmSym => false,
-            RibKind::AssocItem | RibKind::Item(..) | RibKind::ForwardGenericParamBan => true,
+            RibKind::ConstParamTy
+            | RibKind::AssocItem
+            | RibKind::Item(..)
+            | RibKind::ForwardGenericParamBan => true,
         }
     }
 
@@ -1570,6 +1572,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             forward_ty_ban_rib.bindings.insert(Ident::with_dummy_span(kw::SelfUpper), Res::Err);
         }
 
+        let mut forward_ty_ban_rib_const_param_ty = Rib {
+            bindings: forward_ty_ban_rib.bindings.clone(),
+            patterns_with_skipped_bindings: FxHashMap::default(),
+            kind: RibKind::ConstParamTy,
+        };
+        let mut forward_const_ban_rib_const_param_ty = Rib {
+            bindings: forward_const_ban_rib.bindings.clone(),
+            patterns_with_skipped_bindings: FxHashMap::default(),
+            kind: RibKind::ConstParamTy,
+        };
+
         self.with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| {
             for param in params {
                 match param.kind {
@@ -1592,21 +1605,27 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         }
 
                         // Allow all following defaults to refer to this type parameter.
-                        forward_ty_ban_rib
-                            .bindings
-                            .remove(&Ident::with_dummy_span(param.ident.name));
+                        let i = &Ident::with_dummy_span(param.ident.name);
+                        forward_ty_ban_rib.bindings.remove(i);
+                        if this.r.tcx.features().generic_const_parameter_types() {
+                            forward_ty_ban_rib_const_param_ty.bindings.remove(i);
+                        }
                     }
                     GenericParamKind::Const { ref ty, kw_span: _, ref default } => {
                         // Const parameters can't have param bounds.
                         assert!(param.bounds.is_empty());
 
-                        this.ribs[TypeNS].push(Rib::new(RibKind::ConstParamTy));
-                        this.ribs[ValueNS].push(Rib::new(RibKind::ConstParamTy));
-                        this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
+                        this.ribs[TypeNS].push(forward_ty_ban_rib_const_param_ty);
+                        this.ribs[ValueNS].push(forward_const_ban_rib_const_param_ty);
+                        if this.r.tcx.features().generic_const_parameter_types() {
                             this.visit_ty(ty)
-                        });
-                        this.ribs[TypeNS].pop().unwrap();
-                        this.ribs[ValueNS].pop().unwrap();
+                        } else {
+                            this.with_lifetime_rib(LifetimeRibKind::ConstParamTy, |this| {
+                                this.visit_ty(ty)
+                            });
+                        }
+                        forward_const_ban_rib_const_param_ty = this.ribs[ValueNS].pop().unwrap();
+                        forward_ty_ban_rib_const_param_ty = this.ribs[TypeNS].pop().unwrap();
 
                         if let Some(expr) = default {
                             this.ribs[TypeNS].push(forward_ty_ban_rib);
@@ -1620,9 +1639,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                         }
 
                         // Allow all following defaults to refer to this const parameter.
-                        forward_const_ban_rib
-                            .bindings
-                            .remove(&Ident::with_dummy_span(param.ident.name));
+                        let i = &Ident::with_dummy_span(param.ident.name);
+                        forward_const_ban_rib.bindings.remove(i);
+                        if this.r.tcx.features().generic_const_parameter_types() {
+                            forward_const_ban_rib_const_param_ty.bindings.remove(i);
+                        }
                     }
                 }
             }
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index fa9c42e3593..0e14e7671b1 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -3052,7 +3052,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
             .create_err(errors::ParamInTyOfConstParam {
                 span: lifetime_ref.ident.span,
                 name: lifetime_ref.ident.name,
-                param_kind: Some(errors::ParamKindInTyOfConstParam::Lifetime),
             })
             .emit();
     }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index ea48d0cad74..4c5d4041022 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -30,9 +30,7 @@ use std::sync::Arc;
 
 use diagnostics::{ImportSuggestion, LabelSuggestion, Suggestion};
 use effective_visibilities::EffectiveVisibilitiesVisitor;
-use errors::{
-    ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst, ParamKindInTyOfConstParam,
-};
+use errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
 use imports::{Import, ImportData, ImportKind, NameResolution};
 use late::{HasGenericParams, PathSource, PatternSource, UnnecessaryQualification};
 use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
@@ -276,8 +274,10 @@ enum ResolutionError<'ra> {
     },
     /// Error E0128: generic parameters with a default cannot use forward-declared identifiers.
     ForwardDeclaredGenericParam,
+    // FIXME(generic_const_parameter_types): This should give custom output specifying it's only
+    // problematic to use *forward declared* parameters when the feature is enabled.
     /// ERROR E0770: the type of const parameters must not depend on other generic parameters.
-    ParamInTyOfConstParam { name: Symbol, param_kind: Option<ParamKindInTyOfConstParam> },
+    ParamInTyOfConstParam { name: Symbol },
     /// generic parameters must not be used inside const evaluations.
     ///
     /// This error is only emitted when using `min_const_generics`.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 501c9039f2d..2a709b07255 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1037,6 +1037,7 @@ symbols! {
         generic_associated_types_extended,
         generic_const_exprs,
         generic_const_items,
+        generic_const_parameter_types,
         generic_param_attrs,
         generic_pattern_types,
         get_context,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
index 596f794568c..75616046a4d 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs
@@ -1189,9 +1189,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         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_code_err!(
                     self.dcx(),
diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr
index 539d840f0a8..f639e276f46 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.full.stderr
@@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
    |                                                    ^ the type must not depend on the parameter `N`
-   |
-   = note: const parameters may not be used in the type of const parameters
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
   --> $DIR/const-param-type-depends-on-const-param.rs:15:40
    |
 LL | pub struct SelfDependent<const N: [u8; N]>;
    |                                        ^ the type must not depend on the parameter `N`
-   |
-   = note: const parameters may not be used in the type of const parameters
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
index 18b89963267..44fcf9a13b1 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
@@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
    |                                                    ^ the type must not depend on the parameter `N`
-   |
-   = note: const parameters may not be used in the type of const parameters
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
   --> $DIR/const-param-type-depends-on-const-param.rs:15:40
    |
 LL | pub struct SelfDependent<const N: [u8; N]>;
    |                                        ^ the type must not depend on the parameter `N`
-   |
-   = note: const parameters may not be used in the type of const parameters
 
 error: `[u8; N]` is forbidden as the type of a const generic parameter
   --> $DIR/const-param-type-depends-on-const-param.rs:11:47
diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
index 55bced29aff..3075597895b 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-type-param-ungated.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | struct B<T, const N: T>(PhantomData<[T; N]>);
    |                      ^ the type must not depend on the parameter `T`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
index 49cf4281323..e8257ace692 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.full.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | pub struct Dependent<T, const X: T>([(); X]);
    |                                  ^ the type must not depend on the parameter `T`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error[E0392]: type parameter `T` is never used
   --> $DIR/const-param-type-depends-on-type-param.rs:11:22
diff --git a/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
index 49cf4281323..e8257ace692 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-type-param.min.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | pub struct Dependent<T, const X: T>([(); X]);
    |                                  ^ the type must not depend on the parameter `T`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error[E0392]: type parameter `T` is never used
   --> $DIR/const-param-type-depends-on-type-param.rs:11:22
diff --git a/tests/ui/const-generics/generic_const_parameter_types/bad_inference.rs b/tests/ui/const-generics/generic_const_parameter_types/bad_inference.rs
new file mode 100644
index 00000000000..de2e687e870
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/bad_inference.rs
@@ -0,0 +1,23 @@
+#![feature(
+    adt_const_params,
+    unsized_const_params,
+    generic_const_parameter_types,
+    generic_arg_infer
+)]
+#![allow(incomplete_features)]
+
+use std::marker::ConstParamTy_;
+
+fn foo<T: ConstParamTy_, const N: usize, const M: [T; N]>() -> [T; N] {
+    loop {}
+}
+
+fn main() {
+    // Requires inferring `T`/`N` from `12_u8` and `2` respectively.
+    let a = foo::<_, _, { [12_u8; 2] }>();
+    //~^ ERROR: anonymous constants with inferred types are not yet supported
+
+    // Requires inferring `T`/`N`/`12_?i`/`_` from `[u8; 2]`
+    let b: [u8; 2] = foo::<_, _, { [12; _] }>();
+    //~^ ERROR: anonymous constants with inferred types are not yet supported
+}
diff --git a/tests/ui/const-generics/generic_const_parameter_types/bad_inference.stderr b/tests/ui/const-generics/generic_const_parameter_types/bad_inference.stderr
new file mode 100644
index 00000000000..1ac67fe622b
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/bad_inference.stderr
@@ -0,0 +1,14 @@
+error: anonymous constants with inferred types are not yet supported
+  --> $DIR/bad_inference.rs:17:25
+   |
+LL |     let a = foo::<_, _, { [12_u8; 2] }>();
+   |                         ^^^^^^^^^^^^^^
+
+error: anonymous constants with inferred types are not yet supported
+  --> $DIR/bad_inference.rs:21:34
+   |
+LL |     let b: [u8; 2] = foo::<_, _, { [12; _] }>();
+   |                                  ^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/const-generics/generic_const_parameter_types/evaluate_const_parameter_in_mir.rs b/tests/ui/const-generics/generic_const_parameter_types/evaluate_const_parameter_in_mir.rs
new file mode 100644
index 00000000000..910deb6632d
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/evaluate_const_parameter_in_mir.rs
@@ -0,0 +1,19 @@
+//@ check-pass
+
+#![feature(
+    adt_const_params,
+    unsized_const_params,
+    generic_const_parameter_types,
+    generic_arg_infer
+)]
+#![allow(incomplete_features)]
+
+use std::marker::ConstParamTy_;
+
+fn foo<T: ConstParamTy_, const N: usize, const M: [T; N]>() -> [T; N] {
+    M
+}
+
+fn main() {
+    let a: [u8; 2] = foo::<u8, 2, { [12; _] }>();
+}
diff --git a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs
new file mode 100644
index 00000000000..91c1c80e07c
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.rs
@@ -0,0 +1,11 @@
+#![feature(adt_const_params, generic_const_parameter_types)]
+#![expect(incomplete_features)]
+
+use std::marker::PhantomData;
+
+struct UsesConst<const N: [u8; M], const M: usize>;
+//~^ ERROR: the type of const parameters must not depend on other generic parameters
+struct UsesType<const N: [T; 2], T>(PhantomData<T>);
+//~^ ERROR: the type of const parameters must not depend on other generic parameters
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr
new file mode 100644
index 00000000000..b0dbdff8413
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/forward_declared_type.stderr
@@ -0,0 +1,15 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/forward_declared_type.rs:6:32
+   |
+LL | struct UsesConst<const N: [u8; M], const M: usize>;
+   |                                ^ the type must not depend on the parameter `M`
+
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/forward_declared_type.rs:8:27
+   |
+LL | struct UsesType<const N: [T; 2], T>(PhantomData<T>);
+   |                           ^ the type must not depend on the parameter `T`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/const-generics/generic_const_parameter_types/inferred_from_arg.rs b/tests/ui/const-generics/generic_const_parameter_types/inferred_from_arg.rs
new file mode 100644
index 00000000000..d655fc174ee
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/inferred_from_arg.rs
@@ -0,0 +1,13 @@
+//@ check-pass
+
+#![feature(adt_const_params, generic_arg_infer, generic_const_parameter_types)]
+#![expect(incomplete_features)]
+
+struct Bar<const N: usize, const M: [u8; N]>;
+
+fn foo<const N: usize, const M: [u8; N]>(_: Bar<N, M>) {}
+
+fn main() {
+    foo(Bar::<2, { [1; 2] }>);
+    foo::<_, _>(Bar::<2, { [1; 2] }>);
+}
diff --git a/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.rs b/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.rs
new file mode 100644
index 00000000000..6b81ca743aa
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.rs
@@ -0,0 +1,20 @@
+#![feature(generic_const_parameter_types, adt_const_params, unsized_const_params)]
+#![expect(incomplete_features)]
+
+fn foo<'a, const N: &'a u32>() {}
+
+fn bar() {
+    foo::<'static, { &1_u32 }>();
+    //~^ ERROR: anonymous constants with lifetimes in their type are not yet supported
+    foo::<'_, { &1_u32 }>();
+    //~^ ERROR: anonymous constants with lifetimes in their type are not yet supported
+}
+
+fn borrowck<'a, const N: &'static u32, const M: &'a u32>() {
+    foo::<'a, M>();
+    foo::<'static, M>();
+    //~^ ERROR: lifetime may not live long enough
+    foo::<'static, N>();
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.stderr b/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.stderr
new file mode 100644
index 00000000000..be5f27bcbc0
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/lifetime_dependent_const_param.stderr
@@ -0,0 +1,23 @@
+error: anonymous constants with lifetimes in their type are not yet supported
+  --> $DIR/lifetime_dependent_const_param.rs:7:20
+   |
+LL |     foo::<'static, { &1_u32 }>();
+   |                    ^^^^^^^^^^
+
+error: anonymous constants with lifetimes in their type are not yet supported
+  --> $DIR/lifetime_dependent_const_param.rs:9:15
+   |
+LL |     foo::<'_, { &1_u32 }>();
+   |               ^^^^^^^^^^
+
+error: lifetime may not live long enough
+  --> $DIR/lifetime_dependent_const_param.rs:15:5
+   |
+LL | fn borrowck<'a, const N: &'static u32, const M: &'a u32>() {
+   |             -- lifetime `'a` defined here
+LL |     foo::<'a, M>();
+LL |     foo::<'static, M>();
+   |     ^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.rs b/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.rs
new file mode 100644
index 00000000000..df8a057b335
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.rs
@@ -0,0 +1,15 @@
+#![feature(adt_const_params, unsized_const_params, generic_const_parameter_types)]
+#![allow(incomplete_features)]
+
+use std::marker::ConstParamTy_;
+
+fn foo<const N: usize, const M: [u8; N]>() {}
+fn bar<T: ConstParamTy_, const M: [T; 2]>() {}
+
+fn main() {
+    foo::<3, { [1; 2] }>();
+    //~^ ERROR: mismatched type
+
+    bar::<u8, { [2_u16; 2] }>();
+    //~^ ERROR: mismatched type
+}
diff --git a/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.stderr b/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.stderr
new file mode 100644
index 00000000000..2411d31b980
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/mismatched_args_with_value.stderr
@@ -0,0 +1,21 @@
+error[E0308]: mismatched types
+  --> $DIR/mismatched_args_with_value.rs:10:16
+   |
+LL |     foo::<3, { [1; 2] }>();
+   |                ^^^^^^ expected an array with a size of 3, found one with a size of 2
+
+error[E0308]: mismatched types
+  --> $DIR/mismatched_args_with_value.rs:13:18
+   |
+LL |     bar::<u8, { [2_u16; 2] }>();
+   |                  ^^^^^ expected `u8`, found `u16`
+   |
+help: change the type of the numeric literal from `u16` to `u8`
+   |
+LL -     bar::<u8, { [2_u16; 2] }>();
+LL +     bar::<u8, { [2_u8; 2] }>();
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.rs b/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.rs
new file mode 100644
index 00000000000..1a5ab46cda1
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.rs
@@ -0,0 +1,9 @@
+#![feature(adt_const_params, unsized_const_params, generic_const_parameter_types)]
+#![expect(incomplete_features)]
+
+use std::marker::{ConstParamTy_, PhantomData};
+
+struct UsesType<T, const N: usize, const M: [T; N]>(PhantomData<T>);
+//~^ ERROR: `[T; N]` can't be used as a const parameter type
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr b/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr
new file mode 100644
index 00000000000..4ea323f4a5c
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/no_const_param_ty_bound.stderr
@@ -0,0 +1,11 @@
+error[E0741]: `[T; N]` can't be used as a const parameter type
+  --> $DIR/no_const_param_ty_bound.rs:6:45
+   |
+LL | struct UsesType<T, const N: usize, const M: [T; N]>(PhantomData<T>);
+   |                                             ^^^^^^
+   |
+   = note: `T` must implement `UnsizedConstParamTy`, but it does not
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0741`.
diff --git a/tests/ui/const-generics/generic_const_parameter_types/unrelated_inferred_arg.rs b/tests/ui/const-generics/generic_const_parameter_types/unrelated_inferred_arg.rs
new file mode 100644
index 00000000000..b389e12884e
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_parameter_types/unrelated_inferred_arg.rs
@@ -0,0 +1,21 @@
+//@ check-pass
+
+#![feature(
+    adt_const_params,
+    unsized_const_params,
+    generic_const_parameter_types,
+    generic_arg_infer
+)]
+#![allow(incomplete_features)]
+
+use std::marker::ConstParamTy_;
+
+fn foo<U, T: ConstParamTy_, const N: usize, const M: [T; N]>(_: U) -> [T; N] {
+    loop {}
+}
+
+fn main() {
+    // Check that `_` doesnt cause a "Type of const argument is uninferred" error
+    // as it is not actually used by the type of `M`.
+    let a = foo::<_, u8, 2, { [12; _] }>(true);
+}
diff --git a/tests/ui/const-generics/issues/issue-56445-1.full.stderr b/tests/ui/const-generics/issues/issue-56445-1.full.stderr
index 86eb57355bd..392a125de67 100644
--- a/tests/ui/const-generics/issues/issue-56445-1.full.stderr
+++ b/tests/ui/const-generics/issues/issue-56445-1.full.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
    |                          ^^ the type must not depend on the parameter `'a`
-   |
-   = note: lifetime parameters may not be used in the type of const parameters
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/issues/issue-56445-1.min.stderr b/tests/ui/const-generics/issues/issue-56445-1.min.stderr
index 86eb57355bd..392a125de67 100644
--- a/tests/ui/const-generics/issues/issue-56445-1.min.stderr
+++ b/tests/ui/const-generics/issues/issue-56445-1.min.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
    |                          ^^ the type must not depend on the parameter `'a`
-   |
-   = note: lifetime parameters may not be used in the type of const parameters
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/issues/issue-62878.full.stderr b/tests/ui/const-generics/issues/issue-62878.full.stderr
index 615bfeb65a5..5e6b3ad9f4c 100644
--- a/tests/ui/const-generics/issues/issue-62878.full.stderr
+++ b/tests/ui/const-generics/issues/issue-62878.full.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | fn foo<const N: usize, const A: [u8; N]>() {}
    |                                      ^ the type must not depend on the parameter `N`
-   |
-   = note: const parameters may not be used in the type of const parameters
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr
index 1bb111b188d..d3d4fa43871 100644
--- a/tests/ui/const-generics/issues/issue-62878.min.stderr
+++ b/tests/ui/const-generics/issues/issue-62878.min.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | fn foo<const N: usize, const A: [u8; N]>() {}
    |                                      ^ the type must not depend on the parameter `N`
-   |
-   = note: const parameters may not be used in the type of const parameters
 
 error: `[u8; N]` is forbidden as the type of a const generic parameter
   --> $DIR/issue-62878.rs:5:33
diff --git a/tests/ui/const-generics/issues/issue-71169.full.stderr b/tests/ui/const-generics/issues/issue-71169.full.stderr
index 9553be6fc07..f600ecdab74 100644
--- a/tests/ui/const-generics/issues/issue-71169.full.stderr
+++ b/tests/ui/const-generics/issues/issue-71169.full.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
    |                                           ^^^ the type must not depend on the parameter `LEN`
-   |
-   = note: const parameters may not be used in the type of const parameters
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/issues/issue-71169.min.stderr b/tests/ui/const-generics/issues/issue-71169.min.stderr
index 2ecbc337951..c04a710eee9 100644
--- a/tests/ui/const-generics/issues/issue-71169.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71169.min.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
    |                                           ^^^ the type must not depend on the parameter `LEN`
-   |
-   = note: const parameters may not be used in the type of const parameters
 
 error: `[u8; LEN]` is forbidden as the type of a const generic parameter
   --> $DIR/issue-71169.rs:5:38
diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr
index b6460e0017f..01bbe55415d 100644
--- a/tests/ui/const-generics/issues/issue-71381.full.stderr
+++ b/tests/ui/const-generics/issues/issue-71381.full.stderr
@@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
    |                                                                                  ^^^^ the type must not depend on the parameter `Args`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
   --> $DIR/issue-71381.rs:23:40
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                                        ^^^^ the type must not depend on the parameter `Args`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr
index 38d2cbe6368..2b0a671bc3f 100644
--- a/tests/ui/const-generics/issues/issue-71381.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71381.min.stderr
@@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
    |                                                                                  ^^^^ the type must not depend on the parameter `Args`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
   --> $DIR/issue-71381.rs:23:40
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                                        ^^^^ the type must not depend on the parameter `Args`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error: using function pointers as const generic parameters is forbidden
   --> $DIR/issue-71381.rs:14:61
diff --git a/tests/ui/const-generics/issues/issue-71611.full.stderr b/tests/ui/const-generics/issues/issue-71611.full.stderr
index 6f6a9fc21a6..e115630b64e 100644
--- a/tests/ui/const-generics/issues/issue-71611.full.stderr
+++ b/tests/ui/const-generics/issues/issue-71611.full.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |                               ^ the type must not depend on the parameter `A`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/const-generics/issues/issue-71611.min.stderr b/tests/ui/const-generics/issues/issue-71611.min.stderr
index 7252bfd1d6a..b2e2e5cb445 100644
--- a/tests/ui/const-generics/issues/issue-71611.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71611.min.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |                               ^ the type must not depend on the parameter `A`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error: using function pointers as const generic parameters is forbidden
   --> $DIR/issue-71611.rs:5:21
diff --git a/tests/ui/const-generics/issues/issue-88997.stderr b/tests/ui/const-generics/issues/issue-88997.stderr
index b49d52dd0ba..505ba0da232 100644
--- a/tests/ui/const-generics/issues/issue-88997.stderr
+++ b/tests/ui/const-generics/issues/issue-88997.stderr
@@ -3,16 +3,12 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T)
    |                                        ^ the type must not depend on the parameter `T`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error[E0770]: the type of const parameters must not depend on other generic parameters
   --> $DIR/issue-88997.rs:8:54
    |
 LL | struct Range<T: PartialOrd, const MIN: T, const MAX: T>(T)
    |                                                      ^ the type must not depend on the parameter `T`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-90364.stderr b/tests/ui/const-generics/issues/issue-90364.stderr
index 6c00a654cde..384ce5da3e2 100644
--- a/tests/ui/const-generics/issues/issue-90364.stderr
+++ b/tests/ui/const-generics/issues/issue-90364.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | pub struct Foo<T, const H: T>(T)
    |                            ^ the type must not depend on the parameter `T`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/error-codes/E0771.stderr b/tests/ui/error-codes/E0771.stderr
index 5e829e6f6d2..dfeaa347941 100644
--- a/tests/ui/error-codes/E0771.stderr
+++ b/tests/ui/error-codes/E0771.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | fn function_with_str<'a, const STRING: &'a str>() {}
    |                                         ^^ the type must not depend on the parameter `'a`
-   |
-   = note: lifetime parameters may not be used in the type of const parameters
 
 warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
   --> $DIR/E0771.rs:1:30
diff --git a/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr b/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr
new file mode 100644
index 00000000000..1377f845d16
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.normal.stderr
@@ -0,0 +1,21 @@
+error[E0770]: the type of const parameters must not depend on other generic parameters
+  --> $DIR/feature-gate-generic-const-parameter-types.rs:7:50
+   |
+LL | struct MyADT<const LEN: usize, const ARRAY: [u8; LEN]>;
+   |                                                  ^^^ the type must not depend on the parameter `LEN`
+
+error: `[u8; LEN]` is forbidden as the type of a const generic parameter
+  --> $DIR/feature-gate-generic-const-parameter-types.rs:7:45
+   |
+LL | struct MyADT<const LEN: usize, const ARRAY: [u8; LEN]>;
+   |                                             ^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool`, and `char`
+help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+   |
+LL + #![feature(adt_const_params)]
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0770`.
diff --git a/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.rs b/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.rs
new file mode 100644
index 00000000000..cc374ea3eb2
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-generic-const-parameter-types.rs
@@ -0,0 +1,11 @@
+//@ [feature] check-pass
+//@ revisions: normal feature
+
+#![cfg_attr(feature, feature(adt_const_params, generic_const_parameter_types))]
+#![cfg_attr(feature, expect(incomplete_features))]
+
+struct MyADT<const LEN: usize, const ARRAY: [u8; LEN]>;
+//[normal]~^ ERROR: the type of const parameters must not depend on other generic parameters
+//[normal]~| ERROR: `[u8; LEN]` is forbidden as the type of a const generic parameter
+
+fn main() {}
diff --git a/tests/ui/generic-const-items/wfcheck_err_leak_issue_118179.stderr b/tests/ui/generic-const-items/wfcheck_err_leak_issue_118179.stderr
index 654004571db..2b28e29421c 100644
--- a/tests/ui/generic-const-items/wfcheck_err_leak_issue_118179.stderr
+++ b/tests/ui/generic-const-items/wfcheck_err_leak_issue_118179.stderr
@@ -3,8 +3,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | struct G<T, const N: Vec<T>>(T);
    |                          ^ the type must not depend on the parameter `T`
-   |
-   = note: type parameters may not be used in the type of const parameters
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr
index b7effdc8d61..7373ca8cf84 100644
--- a/tests/ui/lifetimes/unusual-rib-combinations.stderr
+++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr
@@ -9,8 +9,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
    |
 LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
    |                      ^^ the type must not depend on the parameter `'a`
-   |
-   = note: lifetime parameters may not be used in the type of const parameters
 
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/unusual-rib-combinations.rs:11:15
diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs
index 997bee1e600..89e4b77b6cd 100644
--- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs
+++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs
@@ -3,6 +3,7 @@ trait Foo<const N: Bar<2>> {
     //~^ WARN trait objects without an explicit `dyn` are deprecated
     //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
     //~| ERROR cycle detected when computing type of `Foo::N`
+    //~| ERROR cycle detected when computing type of `Foo::N`
     fn func() {}
 }
 
diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr
index 733b729faf0..a381f2acdce 100644
--- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr
+++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr
@@ -13,7 +13,7 @@ LL | trait Foo<const N: dyn Bar<2>> {
    |                    +++
 
 warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:9:20
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:20
    |
 LL | trait Bar<const M: Foo<2>> {}
    |                    ^^^^^^
@@ -32,7 +32,7 @@ LL | trait Foo<const N: Bar<2>> {
    |           ^^^^^^^^^^^^^^^
    |
 note: ...which requires computing type of `Bar::M`...
-  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:9:11
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:11
    |
 LL | trait Bar<const M: Foo<2>> {}
    |           ^^^^^^^^^^^^^^^
@@ -44,6 +44,26 @@ LL | trait Foo<const N: Bar<2>> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error: aborting due to 1 previous error; 2 warnings emitted
+error[E0391]: cycle detected when computing type of `Foo::N`
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:11
+   |
+LL | trait Foo<const N: Bar<2>> {
+   |           ^^^^^^^^^^^^^^^
+   |
+note: ...which requires computing type of `Bar::M`...
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:10:11
+   |
+LL | trait Bar<const M: Foo<2>> {}
+   |           ^^^^^^^^^^^^^^^
+   = note: ...which again requires computing type of `Foo::N`, completing the cycle
+note: cycle used when computing explicit predicates of trait `Foo`
+  --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:1
+   |
+LL | trait Foo<const N: Bar<2>> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors; 2 warnings emitted
 
 For more information about this error, try `rustc --explain E0391`.