aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/hir_def/src/body/lower.rs6
-rw-r--r--crates/hir_def/src/expr.rs2
-rw-r--r--crates/hir_ty/src/infer/pat.rs14
-rw-r--r--crates/hir_ty/src/tests/patterns.rs25
4 files changed, 45 insertions, 2 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 30ac12a12..9ea3d5291 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -835,8 +835,12 @@ impl ExprCollector<'_> {
835 835
836 Pat::Missing 836 Pat::Missing
837 } 837 }
838 ast::Pat::BoxPat(boxpat) => {
839 let inner = self.collect_pat_opt(boxpat.pat());
840 Pat::Box { inner }
841 }
838 // FIXME: implement 842 // FIXME: implement
839 ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing, 843 ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
840 }; 844 };
841 let ptr = AstPtr::new(&pat); 845 let ptr = AstPtr::new(&pat);
842 self.alloc_pat(pattern, Either::Left(ptr)) 846 self.alloc_pat(pattern, Either::Left(ptr))
diff --git a/crates/hir_def/src/expr.rs b/crates/hir_def/src/expr.rs
index c94b3a36f..dc975d42f 100644
--- a/crates/hir_def/src/expr.rs
+++ b/crates/hir_def/src/expr.rs
@@ -395,6 +395,7 @@ pub enum Pat {
395 Bind { mode: BindingAnnotation, name: Name, subpat: Option<PatId> }, 395 Bind { mode: BindingAnnotation, name: Name, subpat: Option<PatId> },
396 TupleStruct { path: Option<Path>, args: Vec<PatId>, ellipsis: Option<usize> }, 396 TupleStruct { path: Option<Path>, args: Vec<PatId>, ellipsis: Option<usize> },
397 Ref { pat: PatId, mutability: Mutability }, 397 Ref { pat: PatId, mutability: Mutability },
398 Box { inner: PatId },
398} 399}
399 400
400impl Pat { 401impl Pat {
@@ -415,6 +416,7 @@ impl Pat {
415 Pat::Record { args, .. } => { 416 Pat::Record { args, .. } => {
416 args.iter().map(|f| f.pat).for_each(f); 417 args.iter().map(|f| f.pat).for_each(f);
417 } 418 }
419 Pat::Box { inner } => f(*inner),
418 } 420 }
419 } 421 }
420} 422}
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index dde38bc39..cde2ab82b 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -209,6 +209,18 @@ impl<'a> InferenceContext<'a> {
209 end_ty 209 end_ty
210 } 210 }
211 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())), 211 Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
212 Pat::Box { inner } => match self.resolve_boxed_box() {
213 Some(box_adt) => {
214 let inner_expected = match expected.as_adt() {
215 Some((adt, substs)) if adt == box_adt => substs.as_single(),
216 _ => &Ty::Unknown,
217 };
218
219 let inner_ty = self.infer_pat(*inner, inner_expected, default_bm);
220 Ty::apply_one(TypeCtor::Adt(box_adt), inner_ty)
221 }
222 None => Ty::Unknown,
223 },
212 Pat::Missing => Ty::Unknown, 224 Pat::Missing => Ty::Unknown,
213 }; 225 };
214 // use a new type variable if we got Ty::Unknown here 226 // use a new type variable if we got Ty::Unknown here
@@ -236,6 +248,6 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
236 Expr::Literal(Literal::String(..)) => false, 248 Expr::Literal(Literal::String(..)) => false,
237 _ => true, 249 _ => true,
238 }, 250 },
239 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false, 251 Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Box { .. } | Pat::Missing => false,
240 } 252 }
241} 253}
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index aeb191c79..6a965ac4f 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -654,3 +654,28 @@ fn slice_tail_pattern() {
654 "#]], 654 "#]],
655 ); 655 );
656} 656}
657
658#[test]
659fn box_pattern() {
660 check_infer(
661 r#"
662 #[lang = "owned_box"]
663 pub struct Box<T>(T);
664
665 fn foo(params: Box<i32>) {
666 match params {
667 box integer => {}
668 }
669 }
670 "#,
671 expect![[r#"
672 52..58 'params': Box<i32>
673 70..124 '{ ... } }': ()
674 76..122 'match ... }': ()
675 82..88 'params': Box<i32>
676 99..110 'box integer': Box<i32>
677 103..110 'integer': i32
678 114..116 '{}': ()
679 "#]],
680 );
681}