aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/infer
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/infer')
-rw-r--r--crates/ra_hir_ty/src/infer/pat.rs33
1 files changed, 20 insertions, 13 deletions
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs
index 4006f595d..23de2bd6b 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;
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use hir_def::{ 6use 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 {
@@ -227,3 +216,21 @@ impl<'a> InferenceContext<'a> {
227 ty 216 ty
228 } 217 }
229} 218}
219
220fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
221 match &body[pat] {
222 Pat::Tuple { .. }
223 | Pat::TupleStruct { .. }
224 | Pat::Record { .. }
225 | Pat::Range { .. }
226 | Pat::Slice { .. } => true,
227 Pat::Or(pats) => pats.iter().all(|p| is_non_ref_pat(body, *p)),
228 // FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented.
229 Pat::Path(..) => true,
230 Pat::Lit(expr) => match body[*expr] {
231 Expr::Literal(Literal::String(..)) => false,
232 _ => true,
233 },
234 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false,
235 }
236}