diff options
-rw-r--r-- | crates/hir_ty/src/diagnostics/pattern.rs | 30 | ||||
-rw-r--r-- | crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs | 7 |
2 files changed, 28 insertions, 9 deletions
diff --git a/crates/hir_ty/src/diagnostics/pattern.rs b/crates/hir_ty/src/diagnostics/pattern.rs index 14dd736a6..99f32097f 100644 --- a/crates/hir_ty/src/diagnostics/pattern.rs +++ b/crates/hir_ty/src/diagnostics/pattern.rs | |||
@@ -11,7 +11,7 @@ use la_arena::Idx; | |||
11 | 11 | ||
12 | use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, Substitution, Ty, TyKind}; | 12 | use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, Substitution, Ty, TyKind}; |
13 | 13 | ||
14 | use self::{deconstruct_pat::ToDo, pat_util::EnumerateAndAdjustIterator}; | 14 | use self::pat_util::EnumerateAndAdjustIterator; |
15 | 15 | ||
16 | pub type PatId = Idx<Pat>; | 16 | pub type PatId = Idx<Pat>; |
17 | 17 | ||
@@ -45,7 +45,6 @@ pub enum PatKind { | |||
45 | /// `x`, `ref x`, `x @ P`, etc. | 45 | /// `x`, `ref x`, `x @ P`, etc. |
46 | Binding { | 46 | Binding { |
47 | subpattern: Option<Pat>, | 47 | subpattern: Option<Pat>, |
48 | // todo: ToDo, | ||
49 | }, | 48 | }, |
50 | 49 | ||
51 | /// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with | 50 | /// `Foo(...)` or `Foo{...}` or `Foo`, where `Foo` is a variant name from an ADT with |
@@ -119,6 +118,10 @@ impl<'a> PatCtxt<'a> { | |||
119 | PatKind::Leaf { subpatterns } | 118 | PatKind::Leaf { subpatterns } |
120 | } | 119 | } |
121 | 120 | ||
121 | hir_def::expr::Pat::Bind { subpat, .. } => { | ||
122 | PatKind::Binding { subpattern: self.lower_opt_pattern(subpat) } | ||
123 | } | ||
124 | |||
122 | hir_def::expr::Pat::TupleStruct { ref args, ellipsis, .. } => { | 125 | hir_def::expr::Pat::TupleStruct { ref args, ellipsis, .. } => { |
123 | let variant_data = match self.infer.variant_resolution_for_pat(pat) { | 126 | let variant_data = match self.infer.variant_resolution_for_pat(pat) { |
124 | Some(variant_id) => variant_id.variant_data(self.db.upcast()), | 127 | Some(variant_id) => variant_id.variant_data(self.db.upcast()), |
@@ -175,6 +178,10 @@ impl<'a> PatCtxt<'a> { | |||
175 | pats.iter().map(|&p| self.lower_pattern(p)).collect() | 178 | pats.iter().map(|&p| self.lower_pattern(p)).collect() |
176 | } | 179 | } |
177 | 180 | ||
181 | fn lower_opt_pattern(&mut self, pat: Option<hir_def::expr::PatId>) -> Option<Pat> { | ||
182 | pat.map(|p| self.lower_pattern(p)) | ||
183 | } | ||
184 | |||
178 | fn lower_variant_or_leaf( | 185 | fn lower_variant_or_leaf( |
179 | &mut self, | 186 | &mut self, |
180 | pat: hir_def::expr::PatId, | 187 | pat: hir_def::expr::PatId, |
@@ -383,7 +390,7 @@ fn main() { | |||
383 | struct S { a: char} | 390 | struct S { a: char} |
384 | fn main(v: S) { | 391 | fn main(v: S) { |
385 | match v { S{ a } => {} } | 392 | match v { S{ a } => {} } |
386 | match v { S{ a: x } => {} } | 393 | match v { S{ a: _x } => {} } |
387 | match v { S{ a: 'a' } => {} } | 394 | match v { S{ a: 'a' } => {} } |
388 | match v { S{..} => {} } | 395 | match v { S{..} => {} } |
389 | match v { _ => {} } | 396 | match v { _ => {} } |
@@ -393,4 +400,21 @@ fn main(v: S) { | |||
393 | "#, | 400 | "#, |
394 | ); | 401 | ); |
395 | } | 402 | } |
403 | |||
404 | #[test] | ||
405 | fn binding() { | ||
406 | check_diagnostics( | ||
407 | r#" | ||
408 | fn main() { | ||
409 | match true { | ||
410 | _x @ true => {} | ||
411 | false => {} | ||
412 | } | ||
413 | //FIXME: false negative. | ||
414 | // Binding patterns should be expanded in `usefulness::expand_pattern()` | ||
415 | match true { _x @ true => {} } | ||
416 | } | ||
417 | "#, | ||
418 | ); | ||
419 | } | ||
396 | } | 420 | } |
diff --git a/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs b/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs index 91b9c7184..1c86ed59b 100644 --- a/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs +++ b/crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs | |||
@@ -801,12 +801,7 @@ impl Fields { | |||
801 | cx: &MatchCheckCtx<'_>, | 801 | cx: &MatchCheckCtx<'_>, |
802 | pats: impl IntoIterator<Item = Pat>, | 802 | pats: impl IntoIterator<Item = Pat>, |
803 | ) -> Self { | 803 | ) -> Self { |
804 | let pats = { | 804 | let pats = pats.into_iter().map(|pat| cx.alloc_pat(pat)).collect(); |
805 | let tys: SmallVec<[Ty; 2]> = match self { | ||
806 | Fields::Vec(pats) => pats.iter().copied().map(|pat| cx.type_of(pat)).collect(), | ||
807 | }; | ||
808 | pats.into_iter().zip(tys.into_iter()).map(move |(pat, ty)| cx.alloc_pat(pat)).collect() | ||
809 | }; | ||
810 | 805 | ||
811 | match self { | 806 | match self { |
812 | Fields::Vec(_) => Fields::Vec(pats), | 807 | Fields::Vec(_) => Fields::Vec(pats), |