Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir_ty/src/infer/pat.rs')
| -rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index 50fd2dd749..9821815ca3 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs @@ -6,6 +6,7 @@ use chalk_ir::Mutability; use hir_def::{ expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat}, path::Path, + type_ref::ConstScalar, }; use hir_expand::name::Name; @@ -14,7 +15,8 @@ use crate::{ Adjust, Adjustment, AutoBorrow, BindingMode, Expectation, InferenceContext, TypeMismatch, }, lower::lower_to_chalk_mutability, - static_lifetime, Interner, Substitution, Ty, TyBuilder, TyExt, TyKind, + static_lifetime, ConcreteConst, ConstValue, Interner, Substitution, Ty, TyBuilder, TyExt, + TyKind, }; impl<'a> InferenceContext<'a> { @@ -232,16 +234,28 @@ impl<'a> InferenceContext<'a> { self.infer_pat(pat_id, &elem_ty, default_bm); } - let pat_ty = match expected.kind(Interner) { - TyKind::Array(_, const_) => TyKind::Array(elem_ty, const_.clone()), - _ => TyKind::Slice(elem_ty), - } - .intern(Interner); if let &Some(slice_pat_id) = slice { - self.infer_pat(slice_pat_id, &pat_ty, default_bm); + let rest_pat_ty = match expected.kind(Interner) { + TyKind::Array(_, length) => { + let length = match length.data(Interner).value { + ConstValue::Concrete(ConcreteConst { + interned: ConstScalar::Usize(length), + }) => length.checked_sub((prefix.len() + suffix.len()) as u64), + _ => None, + }; + TyKind::Array(elem_ty.clone(), crate::consteval::usize_const(length)) + } + _ => TyKind::Slice(elem_ty.clone()), + } + .intern(Interner); + self.infer_pat(slice_pat_id, &rest_pat_ty, default_bm); } - pat_ty + match expected.kind(Interner) { + TyKind::Array(_, const_) => TyKind::Array(elem_ty, const_.clone()), + _ => TyKind::Slice(elem_ty), + } + .intern(Interner) } Pat::Wild => expected.clone(), Pat::Range { start, end } => { |