diff options
Diffstat (limited to 'crates/ra_hir_ty/src/infer/pat.rs')
-rw-r--r-- | crates/ra_hir_ty/src/infer/pat.rs | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index 4006f595d..4dd4f9802 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs | |||
@@ -4,7 +4,7 @@ use std::iter::repeat; | |||
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use hir_def::{ | 6 | use hir_def::{ |
7 | expr::{BindingAnnotation, Pat, PatId, RecordFieldPat}, | 7 | expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, |
8 | path::Path, | 8 | path::Path, |
9 | type_ref::Mutability, | 9 | type_ref::Mutability, |
10 | FieldId, | 10 | FieldId, |
@@ -90,18 +90,7 @@ impl<'a> InferenceContext<'a> { | |||
90 | ) -> Ty { | 90 | ) -> Ty { |
91 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 91 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
92 | 92 | ||
93 | let is_non_ref_pat = match &body[pat] { | 93 | if is_non_ref_pat(&body, pat) { |
94 | Pat::Tuple { .. } | ||
95 | | Pat::Or(..) | ||
96 | | Pat::TupleStruct { .. } | ||
97 | | Pat::Record { .. } | ||
98 | | Pat::Range { .. } | ||
99 | | Pat::Slice { .. } => true, | ||
100 | // FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented. | ||
101 | Pat::Path(..) | Pat::Lit(..) => true, | ||
102 | Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, | ||
103 | }; | ||
104 | if is_non_ref_pat { | ||
105 | while let Some((inner, mutability)) = expected.as_reference() { | 94 | while let Some((inner, mutability)) = expected.as_reference() { |
106 | expected = inner; | 95 | expected = inner; |
107 | default_bm = match default_bm { | 96 | default_bm = match default_bm { |
@@ -195,7 +184,7 @@ impl<'a> InferenceContext<'a> { | |||
195 | self.write_pat_ty(pat, bound_ty); | 184 | self.write_pat_ty(pat, bound_ty); |
196 | return inner_ty; | 185 | return inner_ty; |
197 | } | 186 | } |
198 | Pat::Slice { prefix, slice: _slice, suffix } => { | 187 | Pat::Slice { prefix, slice, suffix } => { |
199 | let (container_ty, elem_ty) = match &expected { | 188 | let (container_ty, elem_ty) = match &expected { |
200 | ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), | 189 | ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()), |
201 | ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), | 190 | ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()), |
@@ -206,7 +195,12 @@ impl<'a> InferenceContext<'a> { | |||
206 | self.infer_pat(*pat_id, &elem_ty, default_bm); | 195 | self.infer_pat(*pat_id, &elem_ty, default_bm); |
207 | } | 196 | } |
208 | 197 | ||
209 | Ty::apply_one(container_ty, elem_ty) | 198 | let pat_ty = Ty::apply_one(container_ty, elem_ty); |
199 | if let Some(slice_pat_id) = slice { | ||
200 | self.infer_pat(*slice_pat_id, &pat_ty, default_bm); | ||
201 | } | ||
202 | |||
203 | pat_ty | ||
210 | } | 204 | } |
211 | Pat::Wild => expected.clone(), | 205 | Pat::Wild => expected.clone(), |
212 | Pat::Range { start, end } => { | 206 | Pat::Range { start, end } => { |
@@ -227,3 +221,21 @@ impl<'a> InferenceContext<'a> { | |||
227 | ty | 221 | ty |
228 | } | 222 | } |
229 | } | 223 | } |
224 | |||
225 | fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool { | ||
226 | match &body[pat] { | ||
227 | Pat::Tuple { .. } | ||
228 | | Pat::TupleStruct { .. } | ||
229 | | Pat::Record { .. } | ||
230 | | Pat::Range { .. } | ||
231 | | Pat::Slice { .. } => true, | ||
232 | Pat::Or(pats) => pats.iter().all(|p| is_non_ref_pat(body, *p)), | ||
233 | // FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented. | ||
234 | Pat::Path(..) => true, | ||
235 | Pat::Lit(expr) => match body[*expr] { | ||
236 | Expr::Literal(Literal::String(..)) => false, | ||
237 | _ => true, | ||
238 | }, | ||
239 | Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, | ||
240 | } | ||
241 | } | ||