about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs15
-rw-r--r--tests/ui/consts/issue-116186.rs12
-rw-r--r--tests/ui/consts/issue-116186.stderr21
3 files changed, 47 insertions, 1 deletions
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 110ec052b35..e0ccf04ab63 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -12,6 +12,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator;
 use rustc_hir::{HirId, Pat, PatKind};
 use rustc_infer::infer;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::{self, Adt, BindingMode, Ty, TypeVisitableExt};
 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -2164,7 +2165,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         len: ty::Const<'tcx>,
         min_len: u64,
     ) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
-        let guar = if let Some(len) = len.try_eval_target_usize(self.tcx, self.param_env) {
+        let len = match len.eval(self.tcx, self.param_env, None) {
+            Ok(val) => val
+                .try_to_scalar()
+                .and_then(|scalar| scalar.try_to_int().ok())
+                .and_then(|int| int.try_to_target_usize(self.tcx).ok()),
+            Err(ErrorHandled::Reported(..)) => {
+                let guar = self.error_scrutinee_unfixed_length(span);
+                return (Some(Ty::new_error(self.tcx, guar)), arr_ty);
+            }
+            Err(ErrorHandled::TooGeneric(..)) => None,
+        };
+
+        let guar = if let Some(len) = len {
             // Now we know the length...
             if slice.is_none() {
                 // ...and since there is no variable-length pattern,
diff --git a/tests/ui/consts/issue-116186.rs b/tests/ui/consts/issue-116186.rs
new file mode 100644
index 00000000000..a77c38c64dc
--- /dev/null
+++ b/tests/ui/consts/issue-116186.rs
@@ -0,0 +1,12 @@
+#![allow(incomplete_features)]
+#![feature(generic_const_exprs)]
+
+fn something(path: [usize; N]) -> impl Clone {
+    //~^ ERROR cannot find value `N` in this scope
+    match path {
+        [] => 0, //~ ERROR cannot pattern-match on an array without a fixed length
+        _ => 1,
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/consts/issue-116186.stderr b/tests/ui/consts/issue-116186.stderr
new file mode 100644
index 00000000000..e6eae2d9f55
--- /dev/null
+++ b/tests/ui/consts/issue-116186.stderr
@@ -0,0 +1,21 @@
+error[E0425]: cannot find value `N` in this scope
+  --> $DIR/issue-116186.rs:4:28
+   |
+LL | fn something(path: [usize; N]) -> impl Clone {
+   |                            ^ not found in this scope
+   |
+help: you might be missing a const parameter
+   |
+LL | fn something<const N: /* Type */>(path: [usize; N]) -> impl Clone {
+   |             +++++++++++++++++++++
+
+error[E0730]: cannot pattern-match on an array without a fixed length
+  --> $DIR/issue-116186.rs:7:9
+   |
+LL |         [] => 0,
+   |         ^^
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0425, E0730.
+For more information about an error, try `rustc --explain E0425`.