Fix handling of literal patterns
Wrap them in a LiteralPat node so they can be distinguished from literal expressions.
This commit is contained in:
@@ -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<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
|
||||
#[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!(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
],
|
||||
),
|
||||
|
||||
|
||||
@@ -43,21 +43,8 @@ fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
|
||||
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<CompletedMarker> {
|
||||
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 = ();
|
||||
|
||||
@@ -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" },
|
||||
|
||||
Reference in New Issue
Block a user