mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
Auto merge of #12355 - ruabmbua:fix-inference-pattern-wildcards, r=flodiebold
Fix inference when pattern matching a tuple field with a wildcard This should fix the following issue: https://github.com/rust-lang/rust-analyzer/issues/12331 * Replaced the `err_ty` in `infer_pat()` with a new type variable. * Had to change the iterator code a bit, to get around multiple mutable borrows of `self` in `infer_pat()`. Also added a test * Also added a test
This commit is contained in:
commit
238253c22d
2 changed files with 41 additions and 8 deletions
|
@ -1,6 +1,6 @@
|
|||
//! Type inference for patterns.
|
||||
|
||||
use std::iter::repeat;
|
||||
use std::iter::repeat_with;
|
||||
|
||||
use chalk_ir::Mutability;
|
||||
use hir_def::{
|
||||
|
@ -140,15 +140,28 @@ impl<'a> InferenceContext<'a> {
|
|||
}
|
||||
None => ((&args[..], &[][..]), 0),
|
||||
};
|
||||
let err_ty = self.err_ty();
|
||||
let mut expectations_iter =
|
||||
expectations.iter().map(|a| a.assert_ty_ref(Interner)).chain(repeat(&err_ty));
|
||||
let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
|
||||
let mut expectations_iter = expectations
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|a| a.assert_ty_ref(Interner).clone())
|
||||
.chain(repeat_with(|| self.table.new_type_var()));
|
||||
|
||||
let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
|
||||
inner_tys.extend(pre.iter().zip(expectations_iter.by_ref()).map(&mut infer_pat));
|
||||
inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
|
||||
inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
|
||||
|
||||
inner_tys
|
||||
.extend(expectations_iter.by_ref().take(n_uncovered_patterns + args.len()));
|
||||
|
||||
// Process pre
|
||||
for (ty, pat) in inner_tys.iter_mut().zip(pre) {
|
||||
*ty = self.infer_pat(*pat, ty, default_bm);
|
||||
}
|
||||
|
||||
// Process post
|
||||
for (ty, pat) in
|
||||
inner_tys.iter_mut().skip(pre.len() + n_uncovered_patterns).zip(post)
|
||||
{
|
||||
*ty = self.infer_pat(*pat, ty, default_bm);
|
||||
}
|
||||
|
||||
TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
|
||||
.intern(Interner)
|
||||
|
|
|
@ -969,3 +969,23 @@ fn main() {
|
|||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tuple_wildcard() {
|
||||
check_types(
|
||||
r#"
|
||||
fn main() {
|
||||
enum Option<T> {Some(T), None}
|
||||
use Option::*;
|
||||
|
||||
let mut x = None;
|
||||
x;
|
||||
//^ Option<(i32, i32)>
|
||||
|
||||
if let Some((_, _a)) = x {}
|
||||
|
||||
x = Some((1, 2));
|
||||
}
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue