aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Mcguigan <[email protected]>2020-04-17 13:36:44 +0100
committerJosh Mcguigan <[email protected]>2020-04-17 13:36:44 +0100
commit408f914bf4d6719ae68582ae43e2de9d3cb362b0 (patch)
treeecd8eef9e5e7b9027c143930840e05a764e40690
parent8d296be1090b21b60e509c831864ae85feec2490 (diff)
fix panic on ellipsis in pattern
-rw-r--r--crates/ra_hir_def/src/body/lower.rs13
-rw-r--r--crates/ra_hir_ty/src/tests/regression.rs49
2 files changed, 59 insertions, 3 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 79abe55ce..0679ffa1e 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -650,6 +650,7 @@ impl ExprCollector<'_> {
650 ast::Pat::SlicePat(p) => { 650 ast::Pat::SlicePat(p) => {
651 let SlicePatComponents { prefix, slice, suffix } = p.components(); 651 let SlicePatComponents { prefix, slice, suffix } = p.components();
652 652
653 // FIXME properly handle `DotDotPat`
653 Pat::Slice { 654 Pat::Slice {
654 prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(), 655 prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(),
655 slice: slice.map(|p| self.collect_pat(p)), 656 slice: slice.map(|p| self.collect_pat(p)),
@@ -666,9 +667,15 @@ impl ExprCollector<'_> {
666 Pat::Missing 667 Pat::Missing
667 } 668 }
668 } 669 }
669 ast::Pat::DotDotPat(_) => unreachable!( 670 ast::Pat::DotDotPat(_) => {
670 "`DotDotPat` requires special handling and should not be mapped to a Pat." 671 // `DotDotPat` requires special handling and should not be mapped
671 ), 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 }
672 // FIXME: implement 679 // FIXME: implement
673 ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing, 680 ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
674 }; 681 };
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs
index d69115a2f..61284d672 100644
--- a/crates/ra_hir_ty/src/tests/regression.rs
+++ b/crates/ra_hir_ty/src/tests/regression.rs
@@ -484,3 +484,52 @@ fn main() {
484 484
485 assert_eq!("()", super::type_at_pos(&db, pos)); 485 assert_eq!("()", super::type_at_pos(&db, pos));
486} 486}
487
488#[test]
489fn issue_3999_slice() {
490 assert_snapshot!(
491 infer(r#"
492fn 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]
511fn issue_3999_struct() {
512 // rust-analyzer should not panic on seeing this malformed
513 // record pattern.
514 assert_snapshot!(
515 infer(r#"
516struct Bar {
517 a: bool,
518}
519fn 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}