diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-03-21 19:25:14 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2021-03-21 19:25:14 +0000 |
commit | 858ad554374a8b1ad67692558a0878391abfdd86 (patch) | |
tree | cae76f9d2a7ab4e10758ecf881e374f26f6bc803 /crates/hir_ty/src/infer | |
parent | 31ed1641615bd57d9f4897dbe93e97f185fc5273 (diff) | |
parent | af50e8d955caa0b689f3e5b02f0d8ff0302fd3e3 (diff) |
Merge #8137
8137: Fix box pattern inference panic r=flodiebold a=Veykril
Fixes #6560
Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/infer')
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 6 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 32 |
2 files changed, 29 insertions, 9 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 79bbc5dab..24deff707 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -513,10 +513,10 @@ impl<'a> InferenceContext<'a> { | |||
513 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); | 513 | let inner_ty = self.infer_expr_inner(*expr, &Expectation::none()); |
514 | if let Some(box_) = self.resolve_boxed_box() { | 514 | if let Some(box_) = self.resolve_boxed_box() { |
515 | let mut sb = | 515 | let mut sb = |
516 | Substitution::builder(generics(self.db.upcast(), box_.into()).len()); | 516 | Substitution::build_for_generics(&generics(self.db.upcast(), box_.into())); |
517 | sb = sb.push(inner_ty); | 517 | sb = sb.push(inner_ty); |
518 | match self.db.generic_defaults(box_.into()).as_ref() { | 518 | match self.db.generic_defaults(box_.into()).get(1) { |
519 | [_, alloc_ty, ..] if !alloc_ty.value.is_unknown() => { | 519 | Some(alloc_ty) if !alloc_ty.value.is_unknown() && sb.remaining() > 0 => { |
520 | sb = sb.push(alloc_ty.value.clone()); | 520 | sb = sb.push(alloc_ty.value.clone()); |
521 | } | 521 | } |
522 | _ => (), | 522 | _ => (), |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index ec491648f..474363709 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -13,7 +13,9 @@ use hir_expand::name::Name; | |||
13 | 13 | ||
14 | use super::{BindingMode, Expectation, InferenceContext}; | 14 | use super::{BindingMode, Expectation, InferenceContext}; |
15 | use crate::{ | 15 | 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, | ||
17 | }; | 19 | }; |
18 | 20 | ||
19 | impl<'a> InferenceContext<'a> { | 21 | impl<'a> InferenceContext<'a> { |
@@ -233,13 +235,31 @@ impl<'a> InferenceContext<'a> { | |||
233 | Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())), | 235 | Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())), |
234 | Pat::Box { inner } => match self.resolve_boxed_box() { | 236 | Pat::Box { inner } => match self.resolve_boxed_box() { |
235 | Some(box_adt) => { | 237 | Some(box_adt) => { |
236 | let inner_expected = match expected.as_adt() { | 238 | let (inner_ty, alloc_ty) = match expected.as_adt() { |
237 | Some((adt, substs)) if adt == box_adt => substs.as_single().clone(), | 239 | Some((adt, subst)) if adt == box_adt => { |
238 | _ => self.result.standard_types.unknown.clone(), | 240 | (subst[0].clone(), subst.get(1).cloned()) |
241 | } | ||
242 | _ => (self.result.standard_types.unknown.clone(), None), | ||
239 | }; | 243 | }; |
240 | 244 | ||
241 | let inner_ty = self.infer_pat(*inner, &inner_expected, default_bm); | 245 | let inner_ty = self.infer_pat(*inner, &inner_ty, default_bm); |
242 | Ty::adt_ty(box_adt, Substitution::single(inner_ty)) | 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()) | ||
243 | } | 263 | } |
244 | None => self.err_ty(), | 264 | None => self.err_ty(), |
245 | }, | 265 | }, |