Fix handling of literal patterns

Wrap them in a LiteralPat node so they can be distinguished from literal
expressions.
This commit is contained in:
Florian Diebold 2019-02-09 19:07:35 +01:00
parent 7ebde241c0
commit f1afc93353
10 changed files with 133 additions and 41 deletions

View file

@ -850,6 +850,7 @@ impl ExprCollector {
} }
// TODO: implement // TODO: implement
ast::PatKind::LiteralPat(_) => Pat::Missing,
ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing,
}; };
let syntax_ptr = SyntaxNodePtr::new(pat.syntax()); let syntax_ptr = SyntaxNodePtr::new(pat.syntax());

View file

@ -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) '{}': ()

View file

@ -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 { fn infer(content: &str) -> String {
let (db, _, file_id) = MockDatabase::with_single_file(content); let (db, _, file_id) = MockDatabase::with_single_file(content);
let source_file = db.parse(file_id); let source_file = db.parse(file_id);

View file

@ -1821,6 +1821,38 @@ impl LiteralExpr {
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<RaTypes>;
}
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<LiteralPat>;
fn to_owned(&self) -> TreeArc<LiteralPat> { TreeArc::cast(self.syntax.to_owned()) }
}
impl LiteralPat {
pub fn literal(&self) -> Option<&Literal> {
super::child_opt(self)
}
}
// LoopExpr // LoopExpr
#[derive(Debug, PartialEq, Eq, Hash)] #[derive(Debug, PartialEq, Eq, Hash)]
#[repr(transparent)] #[repr(transparent)]
@ -2594,6 +2626,7 @@ pub enum PatKind<'a> {
TuplePat(&'a TuplePat), TuplePat(&'a TuplePat),
SlicePat(&'a SlicePat), SlicePat(&'a SlicePat),
RangePat(&'a RangePat), RangePat(&'a RangePat),
LiteralPat(&'a LiteralPat),
} }
impl AstNode for Pat { impl AstNode for Pat {
@ -2607,7 +2640,8 @@ impl AstNode for Pat {
| TUPLE_STRUCT_PAT | TUPLE_STRUCT_PAT
| TUPLE_PAT | TUPLE_PAT
| SLICE_PAT | SLICE_PAT
| RANGE_PAT => Some(Pat::from_repr(syntax.into_repr())), | RANGE_PAT
| LITERAL_PAT => Some(Pat::from_repr(syntax.into_repr())),
_ => None, _ => None,
} }
} }
@ -2631,6 +2665,7 @@ impl Pat {
TUPLE_PAT => PatKind::TuplePat(TuplePat::cast(&self.syntax).unwrap()), TUPLE_PAT => PatKind::TuplePat(TuplePat::cast(&self.syntax).unwrap()),
SLICE_PAT => PatKind::SlicePat(SlicePat::cast(&self.syntax).unwrap()), SLICE_PAT => PatKind::SlicePat(SlicePat::cast(&self.syntax).unwrap()),
RANGE_PAT => PatKind::RangePat(RangePat::cast(&self.syntax).unwrap()), RANGE_PAT => PatKind::RangePat(RangePat::cast(&self.syntax).unwrap()),
LITERAL_PAT => PatKind::LiteralPat(LiteralPat::cast(&self.syntax).unwrap()),
_ => unreachable!(), _ => unreachable!(),
} }
} }

View file

@ -161,6 +161,7 @@ Grammar(
"TUPLE_PAT", "TUPLE_PAT",
"SLICE_PAT", "SLICE_PAT",
"RANGE_PAT", "RANGE_PAT",
"LITERAL_PAT",
// atoms // atoms
"TUPLE_EXPR", "TUPLE_EXPR",
@ -524,6 +525,7 @@ Grammar(
"TuplePat": ( collections: [["args", "Pat"]] ), "TuplePat": ( collections: [["args", "Pat"]] ),
"SlicePat": (), "SlicePat": (),
"RangePat": (), "RangePat": (),
"LiteralPat": (options: ["Literal"]),
"Pat": ( "Pat": (
enum: [ enum: [
@ -536,6 +538,7 @@ Grammar(
"TuplePat", "TuplePat",
"SlicePat", "SlicePat",
"RangePat", "RangePat",
"LiteralPat",
], ],
), ),

View file

@ -43,21 +43,8 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
return Some(path_pat(p)); return Some(path_pat(p));
} }
// test literal_pattern if is_literal_pat_start(p) {
// fn main() { return Some(literal_pat(p));
// 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);
} }
let m = match la0 { let m = match la0 {
@ -73,6 +60,30 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
Some(m) 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 // test path_part
// fn foo() { // fn foo() {
// let foo::Bar = (); // let foo::Bar = ();

View file

@ -157,6 +157,7 @@ pub enum SyntaxKind {
TUPLE_PAT, TUPLE_PAT,
SLICE_PAT, SLICE_PAT,
RANGE_PAT, RANGE_PAT,
LITERAL_PAT,
TUPLE_EXPR, TUPLE_EXPR,
ARRAY_EXPR, ARRAY_EXPR,
PAREN_EXPR, PAREN_EXPR,
@ -493,6 +494,7 @@ impl SyntaxKind {
TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" }, TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" }, SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" },
RANGE_PAT => &SyntaxInfo { name: "RANGE_PAT" }, RANGE_PAT => &SyntaxInfo { name: "RANGE_PAT" },
LITERAL_PAT => &SyntaxInfo { name: "LITERAL_PAT" },
TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" }, ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" },
PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" }, PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" },

View file

@ -22,9 +22,10 @@ SOURCE_FILE@[0; 113)
L_CURLY@[25; 26) L_CURLY@[25; 26)
WHITESPACE@[26; 35) WHITESPACE@[26; 35)
MATCH_ARM@[35; 43) MATCH_ARM@[35; 43)
MINUS@[35; 36) LITERAL_PAT@[35; 37)
LITERAL@[36; 37) MINUS@[35; 36)
INT_NUMBER@[36; 37) "1" LITERAL@[36; 37)
INT_NUMBER@[36; 37) "1"
WHITESPACE@[37; 38) WHITESPACE@[37; 38)
FAT_ARROW@[38; 40) FAT_ARROW@[38; 40)
WHITESPACE@[40; 41) WHITESPACE@[40; 41)
@ -34,8 +35,9 @@ SOURCE_FILE@[0; 113)
COMMA@[43; 44) COMMA@[43; 44)
WHITESPACE@[44; 53) WHITESPACE@[44; 53)
MATCH_ARM@[53; 61) MATCH_ARM@[53; 61)
LITERAL@[53; 55) LITERAL_PAT@[53; 55)
INT_NUMBER@[53; 55) "92" LITERAL@[53; 55)
INT_NUMBER@[53; 55) "92"
WHITESPACE@[55; 56) WHITESPACE@[55; 56)
FAT_ARROW@[56; 58) FAT_ARROW@[56; 58)
WHITESPACE@[58; 59) WHITESPACE@[58; 59)
@ -45,8 +47,9 @@ SOURCE_FILE@[0; 113)
COMMA@[61; 62) COMMA@[61; 62)
WHITESPACE@[62; 71) WHITESPACE@[62; 71)
MATCH_ARM@[71; 80) MATCH_ARM@[71; 80)
LITERAL@[71; 74) LITERAL_PAT@[71; 74)
CHAR@[71; 74) LITERAL@[71; 74)
CHAR@[71; 74)
WHITESPACE@[74; 75) WHITESPACE@[74; 75)
FAT_ARROW@[75; 77) FAT_ARROW@[75; 77)
WHITESPACE@[77; 78) WHITESPACE@[77; 78)
@ -56,8 +59,9 @@ SOURCE_FILE@[0; 113)
COMMA@[80; 81) COMMA@[80; 81)
WHITESPACE@[81; 90) WHITESPACE@[81; 90)
MATCH_ARM@[90; 103) MATCH_ARM@[90; 103)
LITERAL@[90; 97) LITERAL_PAT@[90; 97)
STRING@[90; 97) LITERAL@[90; 97)
STRING@[90; 97)
WHITESPACE@[97; 98) WHITESPACE@[97; 98)
FAT_ARROW@[98; 100) FAT_ARROW@[98; 100)
WHITESPACE@[100; 101) WHITESPACE@[100; 101)

View file

@ -22,13 +22,15 @@ SOURCE_FILE@[0; 112)
WHITESPACE@[26; 35) WHITESPACE@[26; 35)
MATCH_ARM@[35; 50) MATCH_ARM@[35; 50)
RANGE_PAT@[35; 44) RANGE_PAT@[35; 44)
LITERAL@[35; 36) LITERAL_PAT@[35; 36)
INT_NUMBER@[35; 36) "0" LITERAL@[35; 36)
INT_NUMBER@[35; 36) "0"
WHITESPACE@[36; 37) WHITESPACE@[36; 37)
DOTDOTDOT@[37; 40) DOTDOTDOT@[37; 40)
WHITESPACE@[40; 41) WHITESPACE@[40; 41)
LITERAL@[41; 44) LITERAL_PAT@[41; 44)
INT_NUMBER@[41; 44) "100" LITERAL@[41; 44)
INT_NUMBER@[41; 44) "100"
WHITESPACE@[44; 45) WHITESPACE@[44; 45)
FAT_ARROW@[45; 47) FAT_ARROW@[45; 47)
WHITESPACE@[47; 48) WHITESPACE@[47; 48)
@ -39,13 +41,15 @@ SOURCE_FILE@[0; 112)
WHITESPACE@[51; 60) WHITESPACE@[51; 60)
MATCH_ARM@[60; 77) MATCH_ARM@[60; 77)
RANGE_PAT@[60; 71) RANGE_PAT@[60; 71)
LITERAL@[60; 63) LITERAL_PAT@[60; 63)
INT_NUMBER@[60; 63) "101" LITERAL@[60; 63)
INT_NUMBER@[60; 63) "101"
WHITESPACE@[63; 64) WHITESPACE@[63; 64)
DOTDOTEQ@[64; 67) DOTDOTEQ@[64; 67)
WHITESPACE@[67; 68) WHITESPACE@[67; 68)
LITERAL@[68; 71) LITERAL_PAT@[68; 71)
INT_NUMBER@[68; 71) "200" LITERAL@[68; 71)
INT_NUMBER@[68; 71) "200"
WHITESPACE@[71; 72) WHITESPACE@[71; 72)
FAT_ARROW@[72; 74) FAT_ARROW@[72; 74)
WHITESPACE@[74; 75) WHITESPACE@[74; 75)
@ -56,13 +60,15 @@ SOURCE_FILE@[0; 112)
WHITESPACE@[78; 87) WHITESPACE@[78; 87)
MATCH_ARM@[87; 102) MATCH_ARM@[87; 102)
RANGE_PAT@[87; 97) RANGE_PAT@[87; 97)
LITERAL@[87; 90) LITERAL_PAT@[87; 90)
INT_NUMBER@[87; 90) "200" LITERAL@[87; 90)
INT_NUMBER@[87; 90) "200"
WHITESPACE@[90; 91) WHITESPACE@[90; 91)
DOTDOT@[91; 93) DOTDOT@[91; 93)
WHITESPACE@[93; 94) WHITESPACE@[93; 94)
LITERAL@[94; 97) LITERAL_PAT@[94; 97)
INT_NUMBER@[94; 97) "301" LITERAL@[94; 97)
INT_NUMBER@[94; 97) "301"
FAT_ARROW@[97; 99) FAT_ARROW@[97; 99)
WHITESPACE@[99; 100) WHITESPACE@[99; 100)
TUPLE_EXPR@[100; 102) TUPLE_EXPR@[100; 102)

View file

@ -456,8 +456,9 @@ SOURCE_FILE@[0; 3813)
L_CURLY@[930; 931) L_CURLY@[930; 931)
WHITESPACE@[931; 952) WHITESPACE@[931; 952)
MATCH_ARM@[952; 1147) MATCH_ARM@[952; 1147)
LITERAL@[952; 953) LITERAL_PAT@[952; 953)
INT_NUMBER@[952; 953) "1" LITERAL@[952; 953)
INT_NUMBER@[952; 953) "1"
WHITESPACE@[953; 954) WHITESPACE@[953; 954)
FAT_ARROW@[954; 956) FAT_ARROW@[954; 956)
WHITESPACE@[956; 957) WHITESPACE@[956; 957)
@ -1080,8 +1081,9 @@ SOURCE_FILE@[0; 3813)
L_CURLY@[1853; 1854) L_CURLY@[1853; 1854)
WHITESPACE@[1854; 1855) WHITESPACE@[1854; 1855)
MATCH_ARM@[1855; 1863) MATCH_ARM@[1855; 1863)
LITERAL@[1855; 1856) LITERAL_PAT@[1855; 1856)
INT_NUMBER@[1855; 1856) "1" LITERAL@[1855; 1856)
INT_NUMBER@[1855; 1856) "1"
WHITESPACE@[1856; 1857) WHITESPACE@[1856; 1857)
FAT_ARROW@[1857; 1859) FAT_ARROW@[1857; 1859)
WHITESPACE@[1859; 1860) WHITESPACE@[1859; 1860)