aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src')
-rw-r--r--crates/ra_hir_ty/src/infer.rs4
-rw-r--r--crates/ra_hir_ty/src/infer/pat.rs6
-rw-r--r--crates/ra_hir_ty/src/tests/patterns.rs26
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};
11use hir_expand::name::Name; 12use hir_expand::name::Name;
12use test_utils::tested_by; 13use 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]
460fn infer_guard() {
461 assert_snapshot!(
462 infer(r#"
463struct S;
464impl S { fn foo(&self) -> bool { false } }
465
466fn 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}