diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index bb6fdd2ffc2c9..4503af03ca341 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -189,10 +189,19 @@ impl<'tcx> InferCtxt<'tcx> {
         // the expected const's type. Specifically, we don't want const infer vars
         // to do any type shapeshifting before and after resolution.
         if let Err(guar) = compatible_types {
-            return Ok(self.tcx.const_error_with_guaranteed(
-                if relation.a_is_expected() { a.ty() } else { b.ty() },
-                guar,
-            ));
+            // HACK: equating both sides with `[const error]` eagerly prevents us
+            // from leaving unconstrained inference vars during things like impl
+            // matching in the solver.
+            let a_error = self.tcx.const_error_with_guaranteed(a.ty(), guar);
+            if let ty::ConstKind::Infer(InferConst::Var(vid)) = a.kind() {
+                return self.unify_const_variable(vid, a_error);
+            }
+            let b_error = self.tcx.const_error_with_guaranteed(b.ty(), guar);
+            if let ty::ConstKind::Infer(InferConst::Var(vid)) = b.kind() {
+                return self.unify_const_variable(vid, b_error);
+            }
+
+            return Ok(if relation.a_is_expected() { a_error } else { b_error });
         }
 
         match (a.kind(), b.kind()) {
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 8e229dd8d6b98..8546bbe52dcc3 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -22,7 +22,7 @@ use crate::traits::{
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{error_code, DelayDm, Diagnostic};
 use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt};
+use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{InternalSubsts, SubstsRef};
 use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
 use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
@@ -350,6 +350,10 @@ fn report_conflicting_impls<'tcx>(
         impl_span: Span,
         err: &mut Diagnostic,
     ) {
+        if (overlap.trait_ref, overlap.self_ty).references_error() {
+            err.downgrade_to_delayed_bug();
+        }
+
         match tcx.span_of_impl(overlap.with_impl) {
             Ok(span) => {
                 err.span_label(span, "first implementation here");
diff --git a/tests/ui/const-generics/bad-subst-const-kind.rs b/tests/ui/const-generics/bad-subst-const-kind.rs
new file mode 100644
index 0000000000000..e13dfbacd2422
--- /dev/null
+++ b/tests/ui/const-generics/bad-subst-const-kind.rs
@@ -0,0 +1,13 @@
+// incremental
+#![crate_type = "lib"]
+
+trait Q {
+    const ASSOC: usize;
+}
+
+impl<const N: u64> Q for [u8; N] {
+    //~^ ERROR mismatched types
+    const ASSOC: usize = 1;
+}
+
+pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] { todo!() }
diff --git a/tests/ui/const-generics/bad-subst-const-kind.stderr b/tests/ui/const-generics/bad-subst-const-kind.stderr
new file mode 100644
index 0000000000000..bd24f9140e4ea
--- /dev/null
+++ b/tests/ui/const-generics/bad-subst-const-kind.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/bad-subst-const-kind.rs:8:31
+   |
+LL | impl<const N: u64> Q for [u8; N] {
+   |                               ^ expected `usize`, found `u64`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
index 582b480aa25be..5fd7c647c2531 100644
--- a/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
+++ b/tests/ui/specialization/min_specialization/bad-const-wf-doesnt-specialize.rs
@@ -2,11 +2,11 @@
 
 // An impl that has an erroneous const substitution should not specialize one
 // that is well-formed.
-
+#[derive(Clone)]
 struct S<const L: usize>;
 
 impl<const N: i32> Copy for S<N> {}
+//~^ ERROR the constant `N` is not of type `usize`
 impl<const M: usize> Copy for S<M> {}
-//~^ ERROR conflicting implementations of trait `Copy` for type `S<_>`
 
 fn main() {}
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 a3906a9a22fec..6d7028c5e7088 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
@@ -1,11 +1,14 @@
-error[E0119]: conflicting implementations of trait `Copy` for type `S<_>`
-  --> $DIR/bad-const-wf-doesnt-specialize.rs:9:1
+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> {}
-   | -------------------------------- first implementation here
-LL | impl<const M: usize> Copy for S<M> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `S<_>`
+   |                             ^^^^
+   |
+note: required by a bound in `S`
+  --> $DIR/bad-const-wf-doesnt-specialize.rs:6:10
+   |
+LL | struct S<const L: usize>;
+   |          ^^^^^^^^^^^^^^ required by this bound in `S`
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0119`.