From f1afc933530a87bd0cc7b25726c9a7fff3f3e007 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 9 Feb 2019 19:07:35 +0100 Subject: Fix handling of literal patterns Wrap them in a LiteralPat node so they can be distinguished from literal expressions. --- crates/ra_hir/src/expr.rs | 1 + .../src/ty/snapshots/tests__infer_std_crash_3.snap | 13 +++++++ crates/ra_hir/src/ty/tests.rs | 15 ++++++++ crates/ra_syntax/src/ast/generated.rs | 37 ++++++++++++++++++- crates/ra_syntax/src/grammar.ron | 3 ++ crates/ra_syntax/src/grammar/patterns.rs | 41 ++++++++++++++-------- crates/ra_syntax/src/syntax_kinds/generated.rs | 2 ++ .../data/parser/inline/ok/0055_literal_pattern.txt | 22 +++++++----- .../tests/data/parser/inline/ok/0058_range_pat.txt | 30 +++++++++------- .../tests/data/parser/ok/0035_weird_exprs.txt | 10 +++--- 10 files changed, 133 insertions(+), 41 deletions(-) create mode 100644 crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_3.snap (limited to 'crates') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 4e61d87ff..bf423d3d8 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -850,6 +850,7 @@ impl ExprCollector { } // TODO: implement + ast::PatKind::LiteralPat(_) => Pat::Missing, ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, }; let syntax_ptr = SyntaxNodePtr::new(pat.syntax()); diff --git a/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_3.snap b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_3.snap new file mode 100644 index 000000000..d15b77e17 --- /dev/null +++ b/crates/ra_hir/src/ty/snapshots/tests__infer_std_crash_3.snap @@ -0,0 +1,13 @@ +--- +created: "2019-02-09T18:02:37.377591660Z" +creator: insta@0.6.1 +source: crates/ra_hir/src/ty/tests.rs +expression: "&result" +--- +[18; 102) '{ ... } }': () +[24; 100) 'match ... }': () +[42; 88) 'SizeSk...tail }': [unknown] +[76; 80) 'true': [unknown] +[82; 86) 'tail': [unknown] +[92; 94) '{}': () + diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 3139eba0b..e0b5a6471 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -663,6 +663,21 @@ fn test_line_buffer() { ); } +#[test] +fn infer_std_crash_3() { + // taken from rustc + check_inference( + "infer_std_crash_3", + r#" +pub fn compute() { + match _ { + SizeSkeleton::Pointer { non_zero: true, tail } => {} + } +} +"#, + ); +} + fn infer(content: &str) -> String { let (db, _, file_id) = MockDatabase::with_single_file(content); let source_file = db.parse(file_id); diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 60314d245..256277609 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1821,6 +1821,38 @@ impl LiteralExpr { impl LiteralExpr {} +// LiteralPat +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct LiteralPat { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for LiteralPat { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for LiteralPat { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + LITERAL_PAT => Some(LiteralPat::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl ToOwned for LiteralPat { + type Owned = TreeArc; + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } +} + + +impl LiteralPat { + pub fn literal(&self) -> Option<&Literal> { + super::child_opt(self) + } +} + // LoopExpr #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] @@ -2594,6 +2626,7 @@ pub enum PatKind<'a> { TuplePat(&'a TuplePat), SlicePat(&'a SlicePat), RangePat(&'a RangePat), + LiteralPat(&'a LiteralPat), } impl AstNode for Pat { @@ -2607,7 +2640,8 @@ impl AstNode for Pat { | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT - | RANGE_PAT => Some(Pat::from_repr(syntax.into_repr())), + | RANGE_PAT + | LITERAL_PAT => Some(Pat::from_repr(syntax.into_repr())), _ => None, } } @@ -2631,6 +2665,7 @@ impl Pat { TUPLE_PAT => PatKind::TuplePat(TuplePat::cast(&self.syntax).unwrap()), SLICE_PAT => PatKind::SlicePat(SlicePat::cast(&self.syntax).unwrap()), RANGE_PAT => PatKind::RangePat(RangePat::cast(&self.syntax).unwrap()), + LITERAL_PAT => PatKind::LiteralPat(LiteralPat::cast(&self.syntax).unwrap()), _ => unreachable!(), } } diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 046db5885..d428bc595 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -161,6 +161,7 @@ Grammar( "TUPLE_PAT", "SLICE_PAT", "RANGE_PAT", + "LITERAL_PAT", // atoms "TUPLE_EXPR", @@ -524,6 +525,7 @@ Grammar( "TuplePat": ( collections: [["args", "Pat"]] ), "SlicePat": (), "RangePat": (), + "LiteralPat": (options: ["Literal"]), "Pat": ( enum: [ @@ -536,6 +538,7 @@ Grammar( "TuplePat", "SlicePat", "RangePat", + "LiteralPat", ], ), diff --git a/crates/ra_syntax/src/grammar/patterns.rs b/crates/ra_syntax/src/grammar/patterns.rs index f3f400ae0..9d7da639d 100644 --- a/crates/ra_syntax/src/grammar/patterns.rs +++ b/crates/ra_syntax/src/grammar/patterns.rs @@ -43,21 +43,8 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option { return Some(path_pat(p)); } - // test literal_pattern - // fn main() { - // match () { - // -1 => (), - // 92 => (), - // 'c' => (), - // "hello" => (), - // } - // } - if p.at(MINUS) && (p.nth(1) == INT_NUMBER || p.nth(1) == FLOAT_NUMBER) { - p.bump(); - } - - if let Some(m) = expressions::literal(p) { - return Some(m); + if is_literal_pat_start(p) { + return Some(literal_pat(p)); } let m = match la0 { @@ -73,6 +60,30 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option { Some(m) } +fn is_literal_pat_start(p: &mut Parser) -> bool { + p.at(MINUS) && (p.nth(1) == INT_NUMBER || p.nth(1) == FLOAT_NUMBER) + || p.at_ts(expressions::LITERAL_FIRST) +} + +// test literal_pattern +// fn main() { +// match () { +// -1 => (), +// 92 => (), +// 'c' => (), +// "hello" => (), +// } +// } +fn literal_pat(p: &mut Parser) -> CompletedMarker { + assert!(is_literal_pat_start(p)); + let m = p.start(); + if p.at(MINUS) { + p.bump(); + } + expressions::literal(p); + m.complete(p, LITERAL_PAT) +} + // test path_part // fn foo() { // let foo::Bar = (); diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs b/crates/ra_syntax/src/syntax_kinds/generated.rs index fea513458..266b95bbb 100644 --- a/crates/ra_syntax/src/syntax_kinds/generated.rs +++ b/crates/ra_syntax/src/syntax_kinds/generated.rs @@ -157,6 +157,7 @@ pub enum SyntaxKind { TUPLE_PAT, SLICE_PAT, RANGE_PAT, + LITERAL_PAT, TUPLE_EXPR, ARRAY_EXPR, PAREN_EXPR, @@ -493,6 +494,7 @@ impl SyntaxKind { TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" }, SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" }, RANGE_PAT => &SyntaxInfo { name: "RANGE_PAT" }, + LITERAL_PAT => &SyntaxInfo { name: "LITERAL_PAT" }, TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" }, PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" }, diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.txt index 71d62eaba..51c5ab7f2 100644 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.txt +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0055_literal_pattern.txt @@ -22,9 +22,10 @@ SOURCE_FILE@[0; 113) L_CURLY@[25; 26) WHITESPACE@[26; 35) MATCH_ARM@[35; 43) - MINUS@[35; 36) - LITERAL@[36; 37) - INT_NUMBER@[36; 37) "1" + LITERAL_PAT@[35; 37) + MINUS@[35; 36) + LITERAL@[36; 37) + INT_NUMBER@[36; 37) "1" WHITESPACE@[37; 38) FAT_ARROW@[38; 40) WHITESPACE@[40; 41) @@ -34,8 +35,9 @@ SOURCE_FILE@[0; 113) COMMA@[43; 44) WHITESPACE@[44; 53) MATCH_ARM@[53; 61) - LITERAL@[53; 55) - INT_NUMBER@[53; 55) "92" + LITERAL_PAT@[53; 55) + LITERAL@[53; 55) + INT_NUMBER@[53; 55) "92" WHITESPACE@[55; 56) FAT_ARROW@[56; 58) WHITESPACE@[58; 59) @@ -45,8 +47,9 @@ SOURCE_FILE@[0; 113) COMMA@[61; 62) WHITESPACE@[62; 71) MATCH_ARM@[71; 80) - LITERAL@[71; 74) - CHAR@[71; 74) + LITERAL_PAT@[71; 74) + LITERAL@[71; 74) + CHAR@[71; 74) WHITESPACE@[74; 75) FAT_ARROW@[75; 77) WHITESPACE@[77; 78) @@ -56,8 +59,9 @@ SOURCE_FILE@[0; 113) COMMA@[80; 81) WHITESPACE@[81; 90) MATCH_ARM@[90; 103) - LITERAL@[90; 97) - STRING@[90; 97) + LITERAL_PAT@[90; 97) + LITERAL@[90; 97) + STRING@[90; 97) WHITESPACE@[97; 98) FAT_ARROW@[98; 100) WHITESPACE@[100; 101) diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0058_range_pat.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0058_range_pat.txt index d47f38903..de54c49e6 100644 --- a/crates/ra_syntax/tests/data/parser/inline/ok/0058_range_pat.txt +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0058_range_pat.txt @@ -22,13 +22,15 @@ SOURCE_FILE@[0; 112) WHITESPACE@[26; 35) MATCH_ARM@[35; 50) RANGE_PAT@[35; 44) - LITERAL@[35; 36) - INT_NUMBER@[35; 36) "0" + LITERAL_PAT@[35; 36) + LITERAL@[35; 36) + INT_NUMBER@[35; 36) "0" WHITESPACE@[36; 37) DOTDOTDOT@[37; 40) WHITESPACE@[40; 41) - LITERAL@[41; 44) - INT_NUMBER@[41; 44) "100" + LITERAL_PAT@[41; 44) + LITERAL@[41; 44) + INT_NUMBER@[41; 44) "100" WHITESPACE@[44; 45) FAT_ARROW@[45; 47) WHITESPACE@[47; 48) @@ -39,13 +41,15 @@ SOURCE_FILE@[0; 112) WHITESPACE@[51; 60) MATCH_ARM@[60; 77) RANGE_PAT@[60; 71) - LITERAL@[60; 63) - INT_NUMBER@[60; 63) "101" + LITERAL_PAT@[60; 63) + LITERAL@[60; 63) + INT_NUMBER@[60; 63) "101" WHITESPACE@[63; 64) DOTDOTEQ@[64; 67) WHITESPACE@[67; 68) - LITERAL@[68; 71) - INT_NUMBER@[68; 71) "200" + LITERAL_PAT@[68; 71) + LITERAL@[68; 71) + INT_NUMBER@[68; 71) "200" WHITESPACE@[71; 72) FAT_ARROW@[72; 74) WHITESPACE@[74; 75) @@ -56,13 +60,15 @@ SOURCE_FILE@[0; 112) WHITESPACE@[78; 87) MATCH_ARM@[87; 102) RANGE_PAT@[87; 97) - LITERAL@[87; 90) - INT_NUMBER@[87; 90) "200" + LITERAL_PAT@[87; 90) + LITERAL@[87; 90) + INT_NUMBER@[87; 90) "200" WHITESPACE@[90; 91) DOTDOT@[91; 93) WHITESPACE@[93; 94) - LITERAL@[94; 97) - INT_NUMBER@[94; 97) "301" + LITERAL_PAT@[94; 97) + LITERAL@[94; 97) + INT_NUMBER@[94; 97) "301" FAT_ARROW@[97; 99) WHITESPACE@[99; 100) TUPLE_EXPR@[100; 102) diff --git a/crates/ra_syntax/tests/data/parser/ok/0035_weird_exprs.txt b/crates/ra_syntax/tests/data/parser/ok/0035_weird_exprs.txt index 20932a837..f3987c3b7 100644 --- a/crates/ra_syntax/tests/data/parser/ok/0035_weird_exprs.txt +++ b/crates/ra_syntax/tests/data/parser/ok/0035_weird_exprs.txt @@ -456,8 +456,9 @@ SOURCE_FILE@[0; 3813) L_CURLY@[930; 931) WHITESPACE@[931; 952) MATCH_ARM@[952; 1147) - LITERAL@[952; 953) - INT_NUMBER@[952; 953) "1" + LITERAL_PAT@[952; 953) + LITERAL@[952; 953) + INT_NUMBER@[952; 953) "1" WHITESPACE@[953; 954) FAT_ARROW@[954; 956) WHITESPACE@[956; 957) @@ -1080,8 +1081,9 @@ SOURCE_FILE@[0; 3813) L_CURLY@[1853; 1854) WHITESPACE@[1854; 1855) MATCH_ARM@[1855; 1863) - LITERAL@[1855; 1856) - INT_NUMBER@[1855; 1856) "1" + LITERAL_PAT@[1855; 1856) + LITERAL@[1855; 1856) + INT_NUMBER@[1855; 1856) "1" WHITESPACE@[1856; 1857) FAT_ARROW@[1857; 1859) WHITESPACE@[1859; 1860) -- cgit v1.2.3