diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
index ec14bd3c6f43e..e0ddb90c33b99 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs
@@ -4,7 +4,7 @@ use rustc_hir::def::Res;
 use rustc_hir::def_id::DefId;
 use rustc_infer::traits::ObligationCauseCode;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
-use rustc_span::{self, Span};
+use rustc_span::{self, symbol::kw, Span};
 use rustc_trait_selection::traits;
 
 use std::ops::ControlFlow;
@@ -25,17 +25,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let generics = self.tcx.generics_of(def_id);
         let predicate_substs = match unsubstituted_pred.kind().skip_binder() {
-            ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => pred.trait_ref.substs,
-            ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => pred.projection_ty.substs,
-            _ => ty::List::empty(),
+            ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => pred.trait_ref.substs.to_vec(),
+            ty::PredicateKind::Clause(ty::Clause::Projection(pred)) => {
+                pred.projection_ty.substs.to_vec()
+            }
+            ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(arg, ty)) => {
+                vec![ty.into(), arg.into()]
+            }
+            ty::PredicateKind::ConstEvaluatable(e) => vec![e.into()],
+            _ => return false,
         };
 
-        let find_param_matching = |matches: &dyn Fn(&ty::ParamTy) -> bool| {
-            predicate_substs.types().find_map(|ty| {
-                ty.walk().find_map(|arg| {
+        let find_param_matching = |matches: &dyn Fn(ty::ParamTerm) -> bool| {
+            predicate_substs.iter().find_map(|arg| {
+                arg.walk().find_map(|arg| {
                     if let ty::GenericArgKind::Type(ty) = arg.unpack()
-                        && let ty::Param(param_ty) = ty.kind()
-                        && matches(param_ty)
+                        && let ty::Param(param_ty) = *ty.kind()
+                        && matches(ty::ParamTerm::Ty(param_ty))
+                    {
+                        Some(arg)
+                    } else if let ty::GenericArgKind::Const(ct) = arg.unpack()
+                        && let ty::ConstKind::Param(param_ct) = ct.kind()
+                        && matches(ty::ParamTerm::Const(param_ct))
                     {
                         Some(arg)
                     } else {
@@ -47,21 +58,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         // Prefer generics that are local to the fn item, since these are likely
         // to be the cause of the unsatisfied predicate.
-        let mut param_to_point_at = find_param_matching(&|param_ty| {
-            self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) == def_id
+        let mut param_to_point_at = find_param_matching(&|param_term| {
+            self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) == def_id
         });
         // Fall back to generic that isn't local to the fn item. This will come
         // from a trait or impl, for example.
-        let mut fallback_param_to_point_at = find_param_matching(&|param_ty| {
-            self.tcx.parent(generics.type_param(param_ty, self.tcx).def_id) != def_id
-                && param_ty.name != rustc_span::symbol::kw::SelfUpper
+        let mut fallback_param_to_point_at = find_param_matching(&|param_term| {
+            self.tcx.parent(generics.param_at(param_term.index(), self.tcx).def_id) != def_id
+                && !matches!(param_term, ty::ParamTerm::Ty(ty) if ty.name == kw::SelfUpper)
         });
         // Finally, the `Self` parameter is possibly the reason that the predicate
         // is unsatisfied. This is less likely to be true for methods, because
         // method probe means that we already kinda check that the predicates due
         // to the `Self` type are true.
-        let mut self_param_to_point_at =
-            find_param_matching(&|param_ty| param_ty.name == rustc_span::symbol::kw::SelfUpper);
+        let mut self_param_to_point_at = find_param_matching(
+            &|param_term| matches!(param_term, ty::ParamTerm::Ty(ty) if ty.name == kw::SelfUpper),
+        );
 
         // Finally, for ambiguity-related errors, we actually want to look
         // for a parameter that is the source of the inference type left
@@ -225,14 +237,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .own_substs(ty::InternalSubsts::identity_for_item(self.tcx, def_id));
         let Some((index, _)) = own_substs
             .iter()
-            .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
             .enumerate()
             .find(|(_, arg)| **arg == param_to_point_at) else { return false };
         let Some(arg) = segment
             .args()
             .args
             .iter()
-            .filter(|arg| matches!(arg, hir::GenericArg::Type(_)))
             .nth(index) else { return false; };
         error.obligation.cause.span = arg
             .span()
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index b17749c1ebafa..e3cd5cca785aa 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1051,6 +1051,21 @@ impl<'tcx> TermKind<'tcx> {
     }
 }
 
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum ParamTerm {
+    Ty(ParamTy),
+    Const(ParamConst),
+}
+
+impl ParamTerm {
+    pub fn index(self) -> usize {
+        match self {
+            ParamTerm::Ty(ty) => ty.index as usize,
+            ParamTerm::Const(ct) => ct.index as usize,
+        }
+    }
+}
+
 /// This kind of predicate has no *direct* correspondent in the
 /// syntax, but it roughly corresponds to the syntactic forms:
 ///
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 617d53b609dbc..296fd1ed5248f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1282,10 +1282,20 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     ),
 
                     ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(ct, ty)) => {
-                        self.tcx.sess.struct_span_err(
+                        let mut diag = self.tcx.sess.struct_span_err(
                             span,
                             &format!("the constant `{}` is not of type `{}`", ct, ty),
-                        )
+                        );
+                        self.note_type_err(
+                            &mut diag,
+                            &obligation.cause,
+                            None,
+                            None,
+                            TypeError::Sorts(ty::error::ExpectedFound::new(true, ty, ct.ty())),
+                            false,
+                            false,
+                        );
+                        diag
                     }
                 }
             }
diff --git a/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
index 7b4d46b820976..6b3396a25cf97 100644
--- a/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/cross_crate_predicate.stderr
@@ -1,8 +1,8 @@
 error: unconstrained generic constant
-  --> $DIR/cross_crate_predicate.rs:7:13
+  --> $DIR/cross_crate_predicate.rs:7:44
    |
 LL |     let _ = const_evaluatable_lib::test1::<T>();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                            ^
    |
    = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
 note: required by a bound in `test1`
@@ -12,10 +12,10 @@ LL |     [u8; std::mem::size_of::<T>() - 1]: Sized,
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test1`
 
 error: unconstrained generic constant
-  --> $DIR/cross_crate_predicate.rs:7:13
+  --> $DIR/cross_crate_predicate.rs:7:44
    |
 LL |     let _ = const_evaluatable_lib::test1::<T>();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                            ^
    |
    = help: try adding a `where` bound using this expression: `where [(); std::mem::size_of::<T>() - 1]:`
 note: required by a bound in `test1`
diff --git a/tests/ui/const-generics/type_mismatch.stderr b/tests/ui/const-generics/type_mismatch.stderr
index 6d8955e411ec3..394dd44d40d33 100644
--- a/tests/ui/const-generics/type_mismatch.stderr
+++ b/tests/ui/const-generics/type_mismatch.stderr
@@ -1,8 +1,8 @@
 error: the constant `N` is not of type `u8`
-  --> $DIR/type_mismatch.rs:2:5
+  --> $DIR/type_mismatch.rs:2:11
    |
 LL |     bar::<N>()
-   |     ^^^^^^^^
+   |           ^ expected `u8`, found `usize`
    |
 note: required by a bound in `bar`
   --> $DIR/type_mismatch.rs:6:8
diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
index 6d7028c5e7088..83f311efd39d7 100644
--- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
+++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.stderr
@@ -2,7 +2,7 @@ error: the constant `N` is not of type `usize`
   --> $DIR/bad-const-wf-doesnt-specialize.rs:8:29
    |
 LL | impl<const N: i32> Copy for S<N> {}
-   |                             ^^^^
+   |                             ^^^^ expected `usize`, found `i32`
    |
 note: required by a bound in `S`
   --> $DIR/bad-const-wf-doesnt-specialize.rs:6:10
diff --git a/tests/ui/transmutability/issue-101739-1.stderr b/tests/ui/transmutability/issue-101739-1.stderr
index f0fa93722b89b..bf947d0ea4a6c 100644
--- a/tests/ui/transmutability/issue-101739-1.stderr
+++ b/tests/ui/transmutability/issue-101739-1.stderr
@@ -8,7 +8,7 @@ error: the constant `ASSUME_ALIGNMENT` is not of type `Assume`
   --> $DIR/issue-101739-1.rs:8:14
    |
 LL |         Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME_ALIGNMENT>,
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `bool`
    |
 note: required by a bound in `BikeshedIntrinsicFrom`
   --> $SRC_DIR/core/src/mem/transmutability.rs:LL:COL