Skip to content

Commit

Permalink
Merge #8137
Browse files Browse the repository at this point in the history
8137: Fix box pattern inference panic r=flodiebold a=Veykril

Fixes #6560

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
  • Loading branch information
bors[bot] and Veykril committed Mar 21, 2021
2 parents 31ed164 + af50e8d commit 858ad55
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 9 deletions.
6 changes: 3 additions & 3 deletions crates/hir_ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,10 +513,10 @@ impl<'a> InferenceContext<'a> {
let inner_ty = self.infer_expr_inner(*expr, &Expectation::none());
if let Some(box_) = self.resolve_boxed_box() {
let mut sb =
Substitution::builder(generics(self.db.upcast(), box_.into()).len());
Substitution::build_for_generics(&generics(self.db.upcast(), box_.into()));
sb = sb.push(inner_ty);
match self.db.generic_defaults(box_.into()).as_ref() {
[_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => {
match self.db.generic_defaults(box_.into()).get(1) {
Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => {
sb = sb.push(alloc_ty.value.clone());
}
_ => (),
Expand Down
32 changes: 26 additions & 6 deletions crates/hir_ty/src/infer/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ use hir_expand::name::Name;

use super::{BindingMode, Expectation, InferenceContext};
use crate::{
lower::lower_to_chalk_mutability, utils::variant_data, Interner, Substitution, Ty, TyKind,
lower::lower_to_chalk_mutability,
utils::{generics, variant_data},
Interner, Substitution, Ty, TyKind,
};

impl<'a> InferenceContext<'a> {
Expand Down Expand Up @@ -233,13 +235,31 @@ impl<'a> InferenceContext<'a> {
Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
Pat::Box { inner } => match self.resolve_boxed_box() {
Some(box_adt) => {
let inner_expected = match expected.as_adt() {
Some((adt, substs)) if adt == box_adt => substs.as_single().clone(),
_ => self.result.standard_types.unknown.clone(),
let (inner_ty, alloc_ty) = match expected.as_adt() {
Some((adt, subst)) if adt == box_adt => {
(subst[0].clone(), subst.get(1).cloned())
}
_ => (self.result.standard_types.unknown.clone(), None),
};

let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm);
Ty::adt_ty(box_adt, Substitution::single(inner_ty))
let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm);
let mut sb = Substitution::build_for_generics(&generics(
self.db.upcast(),
box_adt.into(),
));
sb = sb.push(inner_ty);
if sb.remaining() == 1 {
sb = sb.push(match alloc_ty {
Some(alloc_ty) if !alloc_ty.is_unknown() => alloc_ty,
_ => match self.db.generic_defaults(box_adt.into()).get(1) {
Some(alloc_ty) if !alloc_ty.value.is_unknown() => {
alloc_ty.value.clone()
}
_ => self.table.new_type_var(),
},
});
}
Ty::adt_ty(box_adt, sb.build())
}
None => self.err_ty(),
},
Expand Down
22 changes: 22 additions & 0 deletions crates/hir_ty/src/tests/patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,28 @@ fn slice_tail_pattern() {

#[test]
fn box_pattern() {
check_infer(
r#"
pub struct Global;
#[lang = "owned_box"]
pub struct Box<T, A = Global>(T);
fn foo(params: Box<i32>) {
match params {
box integer => {}
}
}
"#,
expect![[r#"
83..89 'params': Box<i32, Global>
101..155 '{ ... } }': ()
107..153 'match ... }': ()
113..119 'params': Box<i32, Global>
130..141 'box integer': Box<i32, Global>
134..141 'integer': i32
145..147 '{}': ()
"#]],
);
check_infer(
r#"
#[lang = "owned_box"]
Expand Down

0 comments on commit 858ad55

Please sign in to comment.