From fa2ea8f494d8434da705dc0e0f047f3bd7503af9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 18 Apr 2020 22:05:06 +0200 Subject: Fix goto definition for record patterns --- crates/ra_hir_ty/src/infer.rs | 4 ++++ crates/ra_hir_ty/src/infer/pat.rs | 6 ++++++ 2 files changed, 10 insertions(+) (limited to 'crates/ra_hir_ty') 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 { field_resolutions: FxHashMap, /// For each field in record literal, records the field it resolves to. record_field_resolutions: FxHashMap, + record_field_pat_resolutions: FxHashMap, /// For each struct literal, records the variant it resolves to. variant_resolutions: FxHashMap, /// For each associated item record what it resolves to @@ -147,6 +148,9 @@ impl InferenceResult { pub fn record_field_resolution(&self, expr: ExprId) -> Option { self.record_field_resolutions.get(&expr).copied() } + pub fn record_field_pat_resolution(&self, pat: PatId) -> Option { + self.record_field_pat_resolutions.get(&pat).copied() + } pub fn variant_resolution_for_expr(&self, id: ExprId) -> Option { self.variant_resolutions.get(&id.into()).copied() } 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::{ expr::{BindingAnnotation, Pat, PatId, RecordFieldPat}, path::Path, type_ref::Mutability, + StructFieldId, }; use hir_expand::name::Name; use test_utils::tested_by; @@ -67,6 +68,11 @@ impl<'a> InferenceContext<'a> { let field_tys = def.map(|it| self.db.field_types(it)).unwrap_or_default(); for subpat in subpats { let matching_field = var_data.as_ref().and_then(|it| it.field(&subpat.name)); + if let Some(local_id) = matching_field { + let field_def = StructFieldId { parent: def.unwrap(), local_id }; + self.result.record_field_pat_resolutions.insert(subpat.pat, field_def); + } + let expected_ty = matching_field.map_or(Ty::Unknown, |field| field_tys[field].clone().subst(&substs)); let expected_ty = self.normalize_associated_types_in(expected_ty); -- cgit v1.2.3 From b79fd82559642f4fe504c0c382b86d57c666be1d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 18 Apr 2020 22:16:04 +0200 Subject: Correctly infer types in guard expressions The root cause was that we forgot to add bindings from the arm to the guard expression closes #3980 --- crates/ra_hir_ty/src/tests/patterns.rs | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'crates/ra_hir_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() { "### ); } + +#[test] +fn infer_guard() { + assert_snapshot!( + infer(r#" +struct S; +impl S { fn foo(&self) -> bool { false } } + +fn main() { + match S { + s if s.foo() => (), + } +} + "#), @" + [28; 32) 'self': &S + [42; 51) '{ false }': bool + [44; 49) 'false': bool + [65; 116) '{ ... } }': () + [71; 114) 'match ... }': () + [77; 78) 'S': S + [89; 90) 's': S + [94; 95) 's': S + [94; 101) 's.foo()': bool + [105; 107) '()': () + ") +} -- cgit v1.2.3