4012: fix panic on ellipsis in pattern r=flodiebold a=JoshMcguigan

fixes #3999

Co-authored-by: Josh Mcguigan <joshmcg88@gmail.com>
This commit is contained in:
bors[bot] 2020-04-17 12:39:20 +00:00 committed by GitHub
commit 179d983535
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 3 deletions

View file

@ -651,6 +651,7 @@ impl ExprCollector<'_> {
ast::Pat::SlicePat(p) => {
let SlicePatComponents { prefix, slice, suffix } = p.components();
// FIXME properly handle `DotDotPat`
Pat::Slice {
prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(),
slice: slice.map(|p| self.collect_pat(p)),
@ -667,9 +668,15 @@ impl ExprCollector<'_> {
Pat::Missing
}
}
ast::Pat::DotDotPat(_) => unreachable!(
"`DotDotPat` requires special handling and should not be mapped to a Pat."
),
ast::Pat::DotDotPat(_) => {
// `DotDotPat` requires special handling and should not be mapped
// to a Pat. Here we are using `Pat::Missing` as a fallback for
// when `DotDotPat` is mapped to `Pat`, which can easily happen
// when the source code being analyzed has a malformed pattern
// which includes `..` in a place where it isn't valid.
Pat::Missing
}
// FIXME: implement
ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
};

View file

@ -484,3 +484,52 @@ fn main() {
assert_eq!("()", super::type_at_pos(&db, pos));
}
#[test]
fn issue_3999_slice() {
assert_snapshot!(
infer(r#"
fn foo(params: &[usize]) {
match params {
[ps @ .., _] => {}
}
}
"#),
@r###"
[8; 14) 'params': &[usize]
[26; 81) '{ ... } }': ()
[32; 79) 'match ... }': ()
[38; 44) 'params': &[usize]
[55; 67) '[ps @ .., _]': [usize]
[65; 66) '_': usize
[71; 73) '{}': ()
"###
);
}
#[test]
fn issue_3999_struct() {
// rust-analyzer should not panic on seeing this malformed
// record pattern.
assert_snapshot!(
infer(r#"
struct Bar {
a: bool,
}
fn foo(b: Bar) {
match b {
Bar { a: .. } => {},
}
}
"#),
@r###"
[36; 37) 'b': Bar
[44; 96) '{ ... } }': ()
[50; 94) 'match ... }': ()
[56; 57) 'b': Bar
[68; 81) 'Bar { a: .. }': Bar
[77; 79) '..': bool
[85; 87) '{}': ()
"###
);
}