aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDawer <[email protected]>2021-05-07 06:38:51 +0100
committerDawer <[email protected]>2021-05-31 20:03:47 +0100
commita236bfa57a1a860e834498d6ca1e1fc1f857a3a4 (patch)
treed578bec5f26628347b14b3245565784669654834
parentcf6f989a8d638b76ec7e14d00f7ed095b20ffed6 (diff)
Lower binding pattern
-rw-r--r--crates/hir_ty/src/diagnostics/pattern.rs30
-rw-r--r--crates/hir_ty/src/diagnostics/pattern/deconstruct_pat.rs7
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
12use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, Substitution, Ty, TyKind}; 12use crate::{db::HirDatabase, AdtId, InferenceResult, Interner, Substitution, Ty, TyKind};
13 13
14use self::{deconstruct_pat::ToDo, pat_util::EnumerateAndAdjustIterator}; 14use self::pat_util::EnumerateAndAdjustIterator;
15 15
16pub type PatId = Idx<Pat>; 16pub 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() {
383struct S { a: char} 390struct S { a: char}
384fn main(v: S) { 391fn 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#"
408fn 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),