Skip to content

Commit ab432b3

Browse files
Merge #5990
5990: Implement box patterns r=jonas-schievink a=jonas-schievink Co-authored-by: Jonas Schievink <[email protected]>
2 parents c862346 + 07a704e commit ab432b3

File tree

4 files changed

+45
-2
lines changed

4 files changed

+45
-2
lines changed

crates/hir_def/src/body/lower.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,8 +835,12 @@ impl ExprCollector<'_> {
835835

836836
Pat::Missing
837837
}
838+
ast::Pat::BoxPat(boxpat) => {
839+
let inner = self.collect_pat_opt(boxpat.pat());
840+
Pat::Box { inner }
841+
}
838842
// FIXME: implement
839-
ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
843+
ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
840844
};
841845
let ptr = AstPtr::new(&pat);
842846
self.alloc_pat(pattern, Either::Left(ptr))

crates/hir_def/src/expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ pub enum Pat {
395395
Bind { mode: BindingAnnotation, name: Name, subpat: Option<PatId> },
396396
TupleStruct { path: Option<Path>, args: Vec<PatId>, ellipsis: Option<usize> },
397397
Ref { pat: PatId, mutability: Mutability },
398+
Box { inner: PatId },
398399
}
399400

400401
impl Pat {
@@ -415,6 +416,7 @@ impl Pat {
415416
Pat::Record { args, .. } => {
416417
args.iter().map(|f| f.pat).for_each(f);
417418
}
419+
Pat::Box { inner } => f(*inner),
418420
}
419421
}
420422
}

crates/hir_ty/src/infer/pat.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,18 @@ impl<'a> InferenceContext<'a> {
209209
end_ty
210210
}
211211
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+
},
212224
Pat::Missing => Ty::Unknown,
213225
};
214226
// 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 {
236248
Expr::Literal(Literal::String(..)) => false,
237249
_ => true,
238250
},
239-
Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Missing => false,
251+
Pat::Wild | Pat::Bind { .. } | Pat::Ref { .. } | Pat::Box { .. } | Pat::Missing => false,
240252
}
241253
}

crates/hir_ty/src/tests/patterns.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,3 +654,28 @@ fn slice_tail_pattern() {
654654
"#]],
655655
);
656656
}
657+
658+
#[test]
659+
fn 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+
}

0 commit comments

Comments
 (0)