diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index bf8ea192b7ac..623e52599396 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs @@ -185,6 +185,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.write_pat_ty(pat, bound_ty); return inner_ty; } + Pat::Slice { prefix, slice: _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()) + }, + _ => (TypeCtor::Slice, Ty::Unknown), + }; + + for pat_id in prefix.iter().chain(suffix) { + self.infer_pat(*pat_id, &elem_ty, default_bm); + } + + Ty::apply_one(container_ty, elem_ty) + } _ => Ty::Unknown, }; // use a new type variable if we got Ty::Unknown here diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs index 81d00c2afb8b..76aa320246f2 100644 --- a/crates/ra_hir_ty/src/tests/patterns.rs +++ b/crates/ra_hir_ty/src/tests/patterns.rs @@ -53,8 +53,9 @@ fn test(x: &i32) { [140; 141) 'g': {unknown} [144; 145) 'e': {unknown} [158; 205) 'if let... }': () - [165; 170) '[val]': {unknown} - [173; 176) 'opt': {unknown} + [165; 170) '[val]': [{unknown}] + [166; 169) 'val': {unknown} + [173; 176) 'opt': [{unknown}] [177; 205) '{ ... }': () [191; 192) 'h': {unknown} [195; 198) 'val': {unknown} @@ -136,6 +137,94 @@ fn test() { ); } +#[test] +fn infer_pattern_match_slice() { + assert_snapshot!( + infer(r#" +fn test() { + let slice: &[f64] = &[0.0]; + match slice { + &[] => {}, + &[a] => { + a; + }, + &[b, c] => { + b; + c; + } + _ => {} + } +} +"#), + @r###" + [11; 210) '{ ... } }': () + [21; 26) 'slice': &[f64] + [37; 43) '&[0.0]': &[f64; _] + [38; 43) '[0.0]': [f64; _] + [39; 42) '0.0': f64 + [49; 208) 'match ... }': () + [55; 60) 'slice': &[f64] + [71; 74) '&[]': &[f64] + [72; 74) '[]': [f64] + [78; 80) '{}': () + [90; 94) '&[a]': &[f64] + [91; 94) '[a]': [f64] + [92; 93) 'a': f64 + [98; 124) '{ ... }': () + [112; 113) 'a': f64 + [134; 141) '&[b, c]': &[f64] + [135; 141) '[b, c]': [f64] + [136; 137) 'b': f64 + [139; 140) 'c': f64 + [145; 186) '{ ... }': () + [159; 160) 'b': f64 + [174; 175) 'c': f64 + [195; 196) '_': &[f64] + [200; 202) '{}': () + "### + ); +} + +#[test] +fn infer_pattern_match_arr() { + assert_snapshot!( + infer(r#" +fn test() { + let arr: [f64; 2] = [0.0, 1.0]; + match arr { + [1.0, a] => { + a; + }, + [b, c] => { + b; + c; + } + } +} +"#), + @r###" + [11; 180) '{ ... } }': () + [21; 24) 'arr': [f64; _] + [37; 47) '[0.0, 1.0]': [f64; _] + [38; 41) '0.0': f64 + [43; 46) '1.0': f64 + [53; 178) 'match ... }': () + [59; 62) 'arr': [f64; _] + [73; 81) '[1.0, a]': [f64; _] + [74; 77) '1.0': f64 + [79; 80) 'a': f64 + [85; 111) '{ ... }': () + [99; 100) 'a': f64 + [121; 127) '[b, c]': [f64; _] + [122; 123) 'b': f64 + [125; 126) 'c': f64 + [131; 172) '{ ... }': () + [145; 146) 'b': f64 + [160; 161) 'c': f64 + "### + ); +} + #[test] fn infer_adt_pattern() { assert_snapshot!(