diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-04-17 13:39:20 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-04-17 13:39:20 +0100 |
commit | 179d9835351f3abab03634b50bcee94723cce148 (patch) | |
tree | c8b87b685698ce45738662a2bf981a48055587b1 | |
parent | 48a9e2061826f9154ed497c306125c1ffd5e8fb3 (diff) | |
parent | 408f914bf4d6719ae68582ae43e2de9d3cb362b0 (diff) |
Merge #4012
4012: fix panic on ellipsis in pattern r=flodiebold a=JoshMcguigan
fixes #3999
Co-authored-by: Josh Mcguigan <[email protected]>
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/regression.rs | 49 |
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 10a1ba714..82a52804d 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -651,6 +651,7 @@ impl ExprCollector<'_> { | |||
651 | ast::Pat::SlicePat(p) => { | 651 | ast::Pat::SlicePat(p) => { |
652 | let SlicePatComponents { prefix, slice, suffix } = p.components(); | 652 | let SlicePatComponents { prefix, slice, suffix } = p.components(); |
653 | 653 | ||
654 | // FIXME properly handle `DotDotPat` | ||
654 | Pat::Slice { | 655 | Pat::Slice { |
655 | prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(), | 656 | prefix: prefix.into_iter().map(|p| self.collect_pat(p)).collect(), |
656 | slice: slice.map(|p| self.collect_pat(p)), | 657 | slice: slice.map(|p| self.collect_pat(p)), |
@@ -667,9 +668,15 @@ impl ExprCollector<'_> { | |||
667 | Pat::Missing | 668 | Pat::Missing |
668 | } | 669 | } |
669 | } | 670 | } |
670 | ast::Pat::DotDotPat(_) => unreachable!( | 671 | ast::Pat::DotDotPat(_) => { |
671 | "`DotDotPat` requires special handling and should not be mapped to a Pat." | 672 | // `DotDotPat` requires special handling and should not be mapped |
672 | ), | 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 | } | ||
673 | // FIXME: implement | 680 | // FIXME: implement |
674 | ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing, | 681 | ast::Pat::BoxPat(_) | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing, |
675 | }; | 682 | }; |
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] | ||
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 | } | ||