Skip to content

Commit 858ad55

Browse files
bors[bot]Veykril
andauthored
Merge #8137
8137: Fix box pattern inference panic r=flodiebold a=Veykril Fixes #6560 Co-authored-by: Lukas Wirth <[email protected]>
2 parents 31ed164 + af50e8d commit 858ad55

File tree

3 files changed

+51
-9
lines changed

3 files changed

+51
-9
lines changed

crates/hir_ty/src/infer/expr.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -513,10 +513,10 @@ impl<'a> InferenceContext<'a> {
513513
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
514514
if let Some(box_) = self.resolve_boxed_box() {
515515
let mut sb =
516-
Substitution::builder(generics(self.db.upcast(), box_.into()).len());
516+
Substitution::build_for_generics(&generics(self.db.upcast(), box_.into()));
517517
sb = sb.push(inner_ty);
518-
match self.db.generic_defaults(box_.into()).as_ref() {
519-
[_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
518+
match self.db.generic_defaults(box_.into()).get(1) {
519+
Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
520520
sb = sb.push(alloc_ty.value.clone());
521521
}
522522
_ => (),

crates/hir_ty/src/infer/pat.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use hir_expand::name::Name;
1313

1414
use super::{BindingMode, Expectation, InferenceContext};
1515
use crate::{
16-
lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyKind,
16+
lower::lower_to_chalk_mutability,
17+
utils::{generics, variant_data},
18+
Interner, Substitution, Ty, TyKind,
1719
};
1820

1921
impl<'a> InferenceContext<'a> {
@@ -233,13 +235,31 @@ impl<'a> InferenceContext<'a> {
233235
Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
234236
Pat::Box { inner } => match self.resolve_boxed_box() {
235237
Some(box_adt) => {
236-
let inner_expected = match expected.as_adt() {
237-
Some((adt, substs)) if adt == box_adt => substs.as_single().clone(),
238-
_ => self.result.standard_types.unknown.clone(),
238+
let (inner_ty, alloc_ty) = match expected.as_adt() {
239+
Some((adt, subst)) if adt == box_adt => {
240+
(subst[0].clone(), subst.get(1).cloned())
241+
}
242+
_ => (self.result.standard_types.unknown.clone(), None),
239243
};
240244

241-
let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm);
242-
Ty::adt_ty(box_adt, Substitution::single(inner_ty))
245+
let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
246+
let mut sb = Substitution::build_for_generics(&generics(
247+
self.db.upcast(),
248+
box_adt.into(),
249+
));
250+
sb = sb.push(inner_ty);
251+
if sb.remaining() == 1 {
252+
sb = sb.push(match alloc_ty {
253+
Some(alloc_ty) if !alloc_ty.is_unknown() => alloc_ty,
254+
_ => match self.db.generic_defaults(box_adt.into()).get(1) {
255+
Some(alloc_ty) if !alloc_ty.value.is_unknown() => {
256+
alloc_ty.value.clone()
257+
}
258+
_ => self.table.new_type_var(),
259+
},
260+
});
261+
}
262+
Ty::adt_ty(box_adt, sb.build())
243263
}
244264
None => self.err_ty(),
245265
},

crates/hir_ty/src/tests/patterns.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,28 @@ fn slice_tail_pattern() {
656656

657657
#[test]
658658
fn box_pattern() {
659+
check_infer(
660+
r#"
661+
pub struct Global;
662+
#[lang = "owned_box"]
663+
pub struct Box<T, A = Global>(T);
664+
665+
fn foo(params: Box<i32>) {
666+
match params {
667+
box integer => {}
668+
}
669+
}
670+
"#,
671+
expect![[r#"
672+
83..89 'params': Box<i32, Global>
673+
101..155 '{ ... } }': ()
674+
107..153 'match ... }': ()
675+
113..119 'params': Box<i32, Global>
676+
130..141 'box integer': Box<i32, Global>
677+
134..141 'integer': i32
678+
145..147 '{}': ()
679+
"#]],
680+
);
659681
check_infer(
660682
r#"
661683
#[lang = "owned_box"]

0 commit comments

Comments
 (0)