From 0ebc24043bb267cf77ddd6c1d8b7d5ad9f82444d Mon Sep 17 00:00:00 2001
From: adamrk <ark.email@gmail.com>
Date: Thu, 25 Jun 2020 23:05:55 +0200
Subject: [PATCH] Infer type for slice wildcard patterns

---
 crates/ra_hir_ty/src/infer/pat.rs        |  9 +++++++--
 crates/ra_hir_ty/src/tests/patterns.rs   | 25 ++++++++++++++++++++++++
 crates/ra_hir_ty/src/tests/regression.rs |  2 ++
 3 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs
index 23de2bd6b06..4dd4f9802d6 100644
--- a/crates/ra_hir_ty/src/infer/pat.rs
+++ b/crates/ra_hir_ty/src/infer/pat.rs
@@ -184,7 +184,7 @@ impl<'a> InferenceContext<'a> {
                 self.write_pat_ty(pat, bound_ty);
                 return inner_ty;
             }
-            Pat::Slice { prefix, slice: _slice, suffix } => {
+            Pat::Slice { prefix, slice, suffix } => {
                 let (container_ty, elem_ty) = match &expected {
                     ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()),
                     ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()),
@@ -195,7 +195,12 @@ impl<'a> InferenceContext<'a> {
                     self.infer_pat(*pat_id, &elem_ty, default_bm);
                 }
 
-                Ty::apply_one(container_ty, elem_ty)
+                let pat_ty = Ty::apply_one(container_ty, elem_ty);
+                if let Some(slice_pat_id) = slice {
+                    self.infer_pat(*slice_pat_id, &pat_ty, default_bm);
+                }
+
+                pat_ty
             }
             Pat::Wild => expected.clone(),
             Pat::Range { start, end } => {
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs
index e5ef241caef..f937426bdba 100644
--- a/crates/ra_hir_ty/src/tests/patterns.rs
+++ b/crates/ra_hir_ty/src/tests/patterns.rs
@@ -627,3 +627,28 @@ fn test() {
     "###
     );
 }
+
+#[test]
+fn slice_tail_pattern() {
+    assert_snapshot!(
+        infer(r#"
+fn foo(params: &[i32]) {
+    match params {
+        [head, tail @ ..] => {
+        }
+    }
+}
+"#),
+        @r###"
+    7..13 'params': &[i32]
+    23..92 '{     ...   } }': ()
+    29..90 'match ...     }': ()
+    35..41 'params': &[i32]
+    52..69 '[head,... @ ..]': [i32]
+    53..57 'head': &i32
+    59..68 'tail @ ..': &[i32]
+    66..68 '..': [i32]
+    73..84 '{         }': ()
+    "###
+    );
+}
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs
index eedaa27bad6..aa37326dffd 100644
--- a/crates/ra_hir_ty/src/tests/regression.rs
+++ b/crates/ra_hir_ty/src/tests/regression.rs
@@ -500,6 +500,8 @@ fn foo(params: &[usize]) {
     31..78 'match ...     }': ()
     37..43 'params': &[usize]
     54..66 '[ps @ .., _]': [usize]
+    55..62 'ps @ ..': &[usize]
+    60..62 '..': [usize]
     64..65 '_': usize
     70..72 '{}': ()
     "###