Skip to content

Commit 238253c

Browse files
committedMay 23, 2022
Auto merge of rust-lang#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: rust-lang/rust-analyzer#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
2 parents c626034 + 86bb27f commit 238253c

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed
 

‎crates/hir-ty/src/infer/pat.rs

+21-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Type inference for patterns.
22
3-
use std::iter::repeat;
3+
use std::iter::repeat_with;
44

55
use chalk_ir::Mutability;
66
use hir_def::{
@@ -140,15 +140,28 @@ impl<'a> InferenceContext<'a> {
140140
}
141141
None => ((&args[..], &[][..]), 0),
142142
};
143-
let err_ty = self.err_ty();
144-
let mut expectations_iter =
145-
expectations.iter().map(|a| a.assert_ty_ref(Interner)).chain(repeat(&err_ty));
146-
let mut infer_pat = |(&pat, ty)| self.infer_pat(pat, ty, default_bm);
143+
let mut expectations_iter = expectations
144+
.iter()
145+
.cloned()
146+
.map(|a| a.assert_ty_ref(Interner).clone())
147+
.chain(repeat_with(|| self.table.new_type_var()));
147148

148149
let mut inner_tys = Vec::with_capacity(n_uncovered_patterns + args.len());
149-
inner_tys.extend(pre.iter().zip(expectations_iter.by_ref()).map(&mut infer_pat));
150-
inner_tys.extend(expectations_iter.by_ref().take(n_uncovered_patterns).cloned());
151-
inner_tys.extend(post.iter().zip(expectations_iter).map(infer_pat));
150+
151+
inner_tys
152+
.extend(expectations_iter.by_ref().take(n_uncovered_patterns + args.len()));
153+
154+
// Process pre
155+
for (ty, pat) in inner_tys.iter_mut().zip(pre) {
156+
*ty = self.infer_pat(*pat, ty, default_bm);
157+
}
158+
159+
// Process post
160+
for (ty, pat) in
161+
inner_tys.iter_mut().skip(pre.len() + n_uncovered_patterns).zip(post)
162+
{
163+
*ty = self.infer_pat(*pat, ty, default_bm);
164+
}
152165

153166
TyKind::Tuple(inner_tys.len(), Substitution::from_iter(Interner, inner_tys))
154167
.intern(Interner)

‎crates/hir-ty/src/tests/patterns.rs

+20
Original file line numberDiff line numberDiff line change
@@ -969,3 +969,23 @@ fn main() {
969969
"#,
970970
);
971971
}
972+
973+
#[test]
974+
fn tuple_wildcard() {
975+
check_types(
976+
r#"
977+
fn main() {
978+
enum Option<T> {Some(T), None}
979+
use Option::*;
980+
981+
let mut x = None;
982+
x;
983+
//^ Option<(i32, i32)>
984+
985+
if let Some((_, _a)) = x {}
986+
987+
x = Some((1, 2));
988+
}
989+
"#,
990+
);
991+
}

0 commit comments

Comments
 (0)
Please sign in to comment.