mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Merge #11484
11484: Infer the array size for slice patterns r=flodiebold a=ChayimFriedman2 Fixes #11478 (feat or fix?), I don't know much about the type-checking in RA, so maybe I did some obvious mistake. Co-authored-by: Chayim Refael Friedman <chayimfr@gmail.com>
This commit is contained in:
commit
89faff7477
2 changed files with 48 additions and 8 deletions
|
@ -6,6 +6,7 @@ use chalk_ir::Mutability;
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat},
|
expr::{BindingAnnotation, Expr, Literal, Pat, PatId, RecordFieldPat},
|
||||||
path::Path,
|
path::Path,
|
||||||
|
type_ref::ConstScalar,
|
||||||
};
|
};
|
||||||
use hir_expand::name::Name;
|
use hir_expand::name::Name;
|
||||||
|
|
||||||
|
@ -14,7 +15,8 @@ use crate::{
|
||||||
Adjust, Adjustment, AutoBorrow, BindingMode, Expectation, InferenceContext, TypeMismatch,
|
Adjust, Adjustment, AutoBorrow, BindingMode, Expectation, InferenceContext, TypeMismatch,
|
||||||
},
|
},
|
||||||
lower::lower_to_chalk_mutability,
|
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> {
|
impl<'a> InferenceContext<'a> {
|
||||||
|
@ -232,16 +234,28 @@ impl<'a> InferenceContext<'a> {
|
||||||
self.infer_pat(pat_id, &elem_ty, default_bm);
|
self.infer_pat(pat_id, &elem_ty, default_bm);
|
||||||
}
|
}
|
||||||
|
|
||||||
let pat_ty = match expected.kind(Interner) {
|
if let &Some(slice_pat_id) = slice {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
match expected.kind(Interner) {
|
||||||
TyKind::Array(_, const_) => TyKind::Array(elem_ty, const_.clone()),
|
TyKind::Array(_, const_) => TyKind::Array(elem_ty, const_.clone()),
|
||||||
_ => TyKind::Slice(elem_ty),
|
_ => TyKind::Slice(elem_ty),
|
||||||
}
|
}
|
||||||
.intern(Interner);
|
.intern(Interner)
|
||||||
if let &Some(slice_pat_id) = slice {
|
|
||||||
self.infer_pat(slice_pat_id, &pat_ty, default_bm);
|
|
||||||
}
|
|
||||||
|
|
||||||
pat_ty
|
|
||||||
}
|
}
|
||||||
Pat::Wild => expected.clone(),
|
Pat::Wild => expected.clone(),
|
||||||
Pat::Range { start, end } => {
|
Pat::Range { start, end } => {
|
||||||
|
|
|
@ -890,6 +890,32 @@ fn main() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn slice_pattern_correctly_handles_array_length() {
|
||||||
|
check_infer(
|
||||||
|
r#"
|
||||||
|
fn main() {
|
||||||
|
let [head, middle @ .., tail, tail2] = [1, 2, 3, 4, 5];
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
10..73 '{ ... 5]; }': ()
|
||||||
|
20..52 '[head,...tail2]': [i32; 5]
|
||||||
|
21..25 'head': i32
|
||||||
|
27..38 'middle @ ..': [i32; 2]
|
||||||
|
36..38 '..': [i32; 2]
|
||||||
|
40..44 'tail': i32
|
||||||
|
46..51 'tail2': i32
|
||||||
|
55..70 '[1, 2, 3, 4, 5]': [i32; 5]
|
||||||
|
56..57 '1': i32
|
||||||
|
59..60 '2': i32
|
||||||
|
62..63 '3': i32
|
||||||
|
65..66 '4': i32
|
||||||
|
68..69 '5': i32
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn pattern_lookup_in_value_ns() {
|
fn pattern_lookup_in_value_ns() {
|
||||||
check_types(
|
check_types(
|
||||||
|
|
Loading…
Reference in a new issue