Skip to content

Commit 408f914

Browse files
committed
fix panic on ellipsis in pattern
1 parent 8d296be commit 408f914

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
@@ -650,6 +650,7 @@ impl ExprCollector<'_> {
650650
ast::Pat::SlicePat(p) => {
651651
let SlicePatComponents { prefix, slice, suffix } = p.components();
652652

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

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)