Skip to content

Commit 179d983

Browse files
Merge #4012
4012: fix panic on ellipsis in pattern r=flodiebold a=JoshMcguigan fixes #3999 Co-authored-by: Josh Mcguigan <[email protected]>
2 parents 48a9e20 + 408f914 commit 179d983

File tree

2 files changed

+59
-3
lines changed

2 files changed

+59
-3
lines changed

crates/ra_hir_def/src/body/lower.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,7 @@ impl ExprCollector<'_> {
651651
ast::Pat::SlicePat(p) => {
652652
let SlicePatComponents { prefix, slice, suffix } = p.components();
653653

654+
// FIXME properly handle `DotDotPat`
654655
Pat::Slice {
655656
prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(),
656657
slice: slice.map(|p| self.collect_pat(p)),
@@ -667,9 +668,15 @@ impl ExprCollector<'_> {
667668
Pat::Missing
668669
}
669670
}
670-
ast::Pat::DotDotPat(_) => unreachable!(
671-
"`DotDotPat` requires special handling and should not be mapped to a Pat."
672-
),
671+
ast::Pat::DotDotPat(_) => {
672+
// `DotDotPat` requires special handling and should not be mapped
673+
// to a Pat. Here we are using `Pat::Missing` as a fallback for
674+
// when `DotDotPat` is mapped to `Pat`, which can easily happen
675+
// when the source code being analyzed has a malformed pattern
676+
// which includes `..` in a place where it isn't valid.
677+
678+
Pat::Missing
679+
}
673680
// FIXME: implement
674681
ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
675682
};

crates/ra_hir_ty/src/tests/regression.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,3 +484,52 @@ fn main() {
484484

485485
assert_eq!("()", super::type_at_pos(&db, pos));
486486
}
487+
488+
#[test]
489+
fn issue_3999_slice() {
490+
assert_snapshot!(
491+
infer(r#"
492+
fn foo(params: &[usize]) {
493+
match params {
494+
[ps @ .., _] => {}
495+
}
496+
}
497+
"#),
498+
@r###"
499+
[8; 14) 'params': &[usize]
500+
[26; 81) '{ ... } }': ()
501+
[32; 79) 'match ... }': ()
502+
[38; 44) 'params': &[usize]
503+
[55; 67) '[ps @ .., _]': [usize]
504+
[65; 66) '_': usize
505+
[71; 73) '{}': ()
506+
"###
507+
);
508+
}
509+
510+
#[test]
511+
fn issue_3999_struct() {
512+
// rust-analyzer should not panic on seeing this malformed
513+
// record pattern.
514+
assert_snapshot!(
515+
infer(r#"
516+
struct Bar {
517+
a: bool,
518+
}
519+
fn foo(b: Bar) {
520+
match b {
521+
Bar { a: .. } => {},
522+
}
523+
}
524+
"#),
525+
@r###"
526+
[36; 37) 'b': Bar
527+
[44; 96) '{ ... } }': ()
528+
[50; 94) 'match ... }': ()
529+
[56; 57) 'b': Bar
530+
[68; 81) 'Bar { a: .. }': Bar
531+
[77; 79) '..': bool
532+
[85; 87) '{}': ()
533+
"###
534+
);
535+
}

0 commit comments

Comments
 (0)