diff options
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r-- | crates/ra_hir_ty/src/infer.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/infer/pat.rs | 6 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/patterns.rs | 26 |
3 files changed, 36 insertions, 0 deletions
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs index b6d9b3438..dfb6a435f 100644 --- a/crates/ra_hir_ty/src/infer.rs +++ b/crates/ra_hir_ty/src/infer.rs | |||
@@ -127,6 +127,7 @@ pub struct InferenceResult { | |||
127 | field_resolutions: FxHashMap<ExprId, StructFieldId>, | 127 | field_resolutions: FxHashMap<ExprId, StructFieldId>, |
128 | /// For each field in record literal, records the field it resolves to. | 128 | /// For each field in record literal, records the field it resolves to. |
129 | record_field_resolutions: FxHashMap<ExprId, StructFieldId>, | 129 | record_field_resolutions: FxHashMap<ExprId, StructFieldId>, |
130 | record_field_pat_resolutions: FxHashMap<PatId, StructFieldId>, | ||
130 | /// For each struct literal, records the variant it resolves to. | 131 | /// For each struct literal, records the variant it resolves to. |
131 | variant_resolutions: FxHashMap<ExprOrPatId, VariantId>, | 132 | variant_resolutions: FxHashMap<ExprOrPatId, VariantId>, |
132 | /// For each associated item record what it resolves to | 133 | /// For each associated item record what it resolves to |
@@ -147,6 +148,9 @@ impl InferenceResult { | |||
147 | pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructFieldId> { | 148 | pub fn record_field_resolution(&self, expr: ExprId) -> Option<StructFieldId> { |
148 | self.record_field_resolutions.get(&expr).copied() | 149 | self.record_field_resolutions.get(&expr).copied() |
149 | } | 150 | } |
151 | pub fn record_field_pat_resolution(&self, pat: PatId) -> Option<StructFieldId> { | ||
152 | self.record_field_pat_resolutions.get(&pat).copied() | ||
153 | } | ||
150 | pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> { | 154 | pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option<VariantId> { |
151 | self.variant_resolutions.get(&id.into()).copied() | 155 | self.variant_resolutions.get(&id.into()).copied() |
152 | } | 156 | } |
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs index 8ec4d4ace..7c2ad4384 100644 --- a/crates/ra_hir_ty/src/infer/pat.rs +++ b/crates/ra_hir_ty/src/infer/pat.rs | |||
@@ -7,6 +7,7 @@ use hir_def::{ | |||
7 | expr::{BindingAnnotation, Pat, PatId, RecordFieldPat}, | 7 | expr::{BindingAnnotation, Pat, PatId, RecordFieldPat}, |
8 | path::Path, | 8 | path::Path, |
9 | type_ref::Mutability, | 9 | type_ref::Mutability, |
10 | StructFieldId, | ||
10 | }; | 11 | }; |
11 | use hir_expand::name::Name; | 12 | use hir_expand::name::Name; |
12 | use test_utils::tested_by; | 13 | use test_utils::tested_by; |
@@ -67,6 +68,11 @@ impl<'a> InferenceContext<'a> { | |||
67 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); | 68 | let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); |
68 | for subpat in subpats { | 69 | for subpat in subpats { |
69 | let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); | 70 | let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); |
71 | if let Some(local_id) = matching_field { | ||
72 | let field_def = StructFieldId { parent: def.unwrap(), local_id }; | ||
73 | self.result.record_field_pat_resolutions.insert(subpat.pat, field_def); | ||
74 | } | ||
75 | |||
70 | let expected_ty = | 76 | let expected_ty = |
71 | matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); | 77 | matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); |
72 | let expected_ty = self.normalize_associated_types_in(expected_ty); | 78 | let expected_ty = self.normalize_associated_types_in(expected_ty); |
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs index 07cbc521a..6ea51d5d3 100644 --- a/crates/ra_hir_ty/src/tests/patterns.rs +++ b/crates/ra_hir_ty/src/tests/patterns.rs | |||
@@ -455,3 +455,29 @@ fn test() { | |||
455 | "### | 455 | "### |
456 | ); | 456 | ); |
457 | } | 457 | } |
458 | |||
459 | #[test] | ||
460 | fn infer_guard() { | ||
461 | assert_snapshot!( | ||
462 | infer(r#" | ||
463 | struct S; | ||
464 | impl S { fn foo(&self) -> bool { false } } | ||
465 | |||
466 | fn main() { | ||
467 | match S { | ||
468 | s if s.foo() => (), | ||
469 | } | ||
470 | } | ||
471 | "#), @" | ||
472 | [28; 32) 'self': &S | ||
473 | [42; 51) '{ false }': bool | ||
474 | [44; 49) 'false': bool | ||
475 | [65; 116) '{ ... } }': () | ||
476 | [71; 114) 'match ... }': () | ||
477 | [77; 78) 'S': S | ||
478 | [89; 90) 's': S | ||
479 | [94; 95) 's': S | ||
480 | [94; 101) 's.foo()': bool | ||
481 | [105; 107) '()': () | ||
482 | ") | ||
483 | } | ||