about summary refs log tree commit diff
diff options
context:
space:
mode:
authorb-naber <b_naber@gmx.de>2023-06-21 17:13:06 +0000
committerb-naber <b_naber@gmx.de>2023-07-17 22:00:43 +0000
commit2827aa975257d03f21c75fa27a594079a9da31ba (patch)
tree88d6c2fa9134252e907b57579eab2681b19f83c9
parent1787f312907eee9a4a9ac010985d725ad9a03ab6 (diff)
try to infer array type from slice pattern
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs26
1 files changed, 26 insertions, 0 deletions
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 8bf95d4bf9a..4785564d850 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -2024,6 +2024,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         Ty::new_ref(self.tcx, region, mt)
     }
 
+    fn try_resolve_slice_ty_to_array_ty(
+        &self,
+        before: &'tcx [Pat<'tcx>],
+        slice: Option<&'tcx Pat<'tcx>>,
+        span: Span,
+    ) -> Option<Ty<'tcx>> {
+        if !slice.is_none() {
+            return None;
+        }
+
+        let tcx = self.tcx;
+        let len = before.len();
+        let ty_var_origin =
+            TypeVariableOrigin { kind: TypeVariableOriginKind::TypeInference, span };
+        let inner_ty = self.next_ty_var(ty_var_origin);
+
+        Some(tcx.mk_array(inner_ty, len.try_into().unwrap()))
+    }
+
     /// Type check a slice pattern.
     ///
     /// Syntactically, these look like `[pat_0, ..., pat_n]`.
@@ -2044,6 +2063,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         def_bm: BindingMode,
         ti: TopInfo<'tcx>,
     ) -> Ty<'tcx> {
+        // If `expected` is an infer ty, we try to equate it to an array if the given pattern
+        // allows it. See issue #76342
+        if let Some(resolved_arr_ty) = self.try_resolve_slice_ty_to_array_ty(before, slice, span) && expected.is_ty_var() {
+            debug!(?resolved_arr_ty);
+            self.demand_eqtype(span, expected, resolved_arr_ty);
+        }
+
         let expected = self.structurally_resolve_type(span, expected);
         let (element_ty, opt_slice_ty, inferred) = match *expected.kind() {
             // An array, so we might have something like `let [a, b, c] = [0, 1, 2];`.