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`.