check_match: unify some lowering code and fix some ICEs
diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs
index 8fcaa1e..20183fd 100644
--- a/src/librustc_mir_build/hair/pattern/_match.rs
+++ b/src/librustc_mir_build/hair/pattern/_match.rs
@@ -582,15 +582,12 @@
 }
 
 impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
-    crate fn create_and_enter<F, R>(
+    crate fn create_and_enter<R>(
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         module: DefId,
-        f: F,
-    ) -> R
-    where
-        F: for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R,
-    {
+        f: impl for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R,
+    ) -> R {
         let pattern_arena = TypedArena::default();
 
         f(MatchCheckCtxt { tcx, param_env, module, pattern_arena: &pattern_arena })
diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs
index ced0d5e..5462d08 100644
--- a/src/librustc_mir_build/hair/pattern/check_match.rs
+++ b/src/librustc_mir_build/hair/pattern/check_match.rs
@@ -121,6 +121,24 @@
         check_for_bindings_named_same_as_variants(self, pat);
     }
 
+    fn lower_pattern<'p>(
+        &self,
+        cx: &mut MatchCheckCtxt<'p, 'tcx>,
+        pat: &'tcx hir::Pat<'tcx>,
+        have_errors: &mut bool,
+    ) -> (&'p super::Pat<'tcx>, Ty<'tcx>) {
+        let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables);
+        patcx.include_lint_checks();
+        let pattern = patcx.lower_pattern(pat);
+        let pattern_ty = pattern.ty;
+        let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(cx, pattern));
+        if !patcx.errors.is_empty() {
+            *have_errors = true;
+            patcx.report_inlining_errors(pat.span);
+        }
+        (pattern, pattern_ty)
+    }
+
     fn check_match(
         &mut self,
         scrut: &hir::Expr<'_>,
@@ -139,14 +157,7 @@
             let inlined_arms: Vec<_> = arms
                 .iter()
                 .map(|arm| {
-                    let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables);
-                    patcx.include_lint_checks();
-                    let pattern = patcx.lower_pattern(&arm.pat);
-                    let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(cx, pattern));
-                    if !patcx.errors.is_empty() {
-                        patcx.report_inlining_errors(arm.pat.span);
-                        have_errors = true;
-                    }
+                    let (pattern, _) = self.lower_pattern(cx, &arm.pat, &mut have_errors);
                     (pattern, &*arm.pat, arm.guard.is_some())
                 })
                 .collect();
@@ -171,11 +182,7 @@
     fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>) {
         let module = self.tcx.hir().get_module_parent(pat.hir_id);
         MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
-            let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables);
-            patcx.include_lint_checks();
-            let pattern = patcx.lower_pattern(pat);
-            let pattern_ty = pattern.ty;
-            let pattern = cx.pattern_arena.alloc(expand_pattern(cx, pattern));
+            let (pattern, pattern_ty) = self.lower_pattern(cx, pat, &mut false);
             let pats: Matrix<'_, '_> = vec![PatStack::from_pattern(pattern)].into_iter().collect();
 
             let witnesses = match check_not_useful(cx, pattern_ty, &pats, pat.hir_id) {
diff --git a/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs
new file mode 100644
index 0000000..95ead6b
--- /dev/null
+++ b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs
@@ -0,0 +1,26 @@
+pub enum EFoo {
+    A,
+}
+
+pub trait Foo {
+    const X: EFoo;
+}
+
+struct Abc;
+
+impl Foo for Abc {
+    const X: EFoo = EFoo::A;
+}
+
+struct Def;
+impl Foo for Def {
+    const X: EFoo = EFoo::A;
+}
+
+pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
+    //~^ ERROR associated consts cannot be referenced in patterns
+    let A::X = arg;
+    //~^ ERROR associated consts cannot be referenced in patterns
+}
+
+fn main() {}
diff --git a/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.stderr b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.stderr
new file mode 100644
index 0000000..54ecc24
--- /dev/null
+++ b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.stderr
@@ -0,0 +1,15 @@
+error[E0158]: associated consts cannot be referenced in patterns
+  --> $DIR/issue-68393-let-pat-assoc-constant.rs:20:40
+   |
+LL | pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
+   |                                        ^^^^
+
+error[E0158]: associated consts cannot be referenced in patterns
+  --> $DIR/issue-68393-let-pat-assoc-constant.rs:22:9
+   |
+LL |     let A::X = arg;
+   |         ^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0158`.
diff --git a/src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs
new file mode 100644
index 0000000..f10a7f2
--- /dev/null
+++ b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let x = 255u8;
+    let 0u8..=x = 0;
+    //~^ ERROR runtime values cannot be referenced in patterns
+}
diff --git a/src/test/ui/pattern/issue-68394-let-pat-runtime-value.stderr b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.stderr
new file mode 100644
index 0000000..c1508bd
--- /dev/null
+++ b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.stderr
@@ -0,0 +1,9 @@
+error[E0080]: runtime values cannot be referenced in patterns
+  --> $DIR/issue-68394-let-pat-runtime-value.rs:3:15
+   |
+LL |     let 0u8..=x = 0;
+   |               ^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/pattern/issue-68396-let-float-bug.rs b/src/test/ui/pattern/issue-68396-let-float-bug.rs
new file mode 100644
index 0000000..afc599a
--- /dev/null
+++ b/src/test/ui/pattern/issue-68396-let-float-bug.rs
@@ -0,0 +1,7 @@
+fn main() {
+    let 1234567890123456789012345678901234567890e-340: f64 = 0.0;
+    //~^ ERROR could not evaluate float literal (see issue #31407)
+
+    fn param(1234567890123456789012345678901234567890e-340: f64) {}
+    //~^ ERROR could not evaluate float literal (see issue #31407)
+}
diff --git a/src/test/ui/pattern/issue-68396-let-float-bug.stderr b/src/test/ui/pattern/issue-68396-let-float-bug.stderr
new file mode 100644
index 0000000..618aa4b
--- /dev/null
+++ b/src/test/ui/pattern/issue-68396-let-float-bug.stderr
@@ -0,0 +1,15 @@
+error[E0080]: could not evaluate float literal (see issue #31407)
+  --> $DIR/issue-68396-let-float-bug.rs:2:9
+   |
+LL |     let 1234567890123456789012345678901234567890e-340: f64 = 0.0;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: could not evaluate float literal (see issue #31407)
+  --> $DIR/issue-68396-let-float-bug.rs:5:14
+   |
+LL |     fn param(1234567890123456789012345678901234567890e-340: f64) {}
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.