Parse destructuring assignment

The only patterns we should parse are `..` in structs and `_`: the rest are either not supported or already valid expressions.
This commit is contained in:
Chayim Refael Friedman 2022-02-24 08:49:47 +00:00 committed by GitHub
parent ab2af50655
commit d9f0731bd2
18 changed files with 543 additions and 218 deletions

4
Cargo.lock generated
View file

@ -1832,9 +1832,9 @@ checksum = "0685c84d5d54d1c26f7d3eb96cd41550adb97baed141a761cf335d3d33bcd0ae"
[[package]]
name = "ungrammar"
version = "1.15.0"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed01567101450f7d600508e7680df6005ae4fe97119d79b0364cc5910ff39732"
checksum = "a62374cbbda72c1459ce5e7bfcdf1bd284c812a4faf2324aa083e5d9ea87880f"
[[package]]
name = "unicase"

View file

@ -518,6 +518,7 @@ impl ExprCollector<'_> {
self.alloc_expr(Expr::MacroStmts { tail }, syntax_ptr)
}
ast::Expr::UnderscoreExpr(_) => return None,
})
}

View file

@ -186,6 +186,7 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
| ast::Expr::TupleExpr(_)
| ast::Expr::WhileExpr(_)
| ast::Expr::LetExpr(_)
| ast::Expr::UnderscoreExpr(_)
| ast::Expr::YieldExpr(_) => cb(expr),
}
}

View file

@ -593,8 +593,17 @@ pub(crate) fn record_expr_field_list(p: &mut Parser) {
T![.] if p.at(T![..]) => {
m.abandon(p);
p.bump(T![..]);
// test destructuring_assignment_struct_rest_pattern
// fn foo() {
// S { .. } = S {};
// }
// We permit `.. }` on the left-hand side of a destructuring assignment.
if !p.at(T!['}']) {
expr(p);
}
}
T!['{'] => {
error_block(p, "expected a field");
m.abandon(p);

View file

@ -81,6 +81,17 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
T![if] => if_expr(p),
T![let] => let_expr(p),
T![_] => {
// test destructuring_assignment_wildcard_pat
// fn foo() {
// _ = 1;
// Some(_) = None;
// }
let m = p.start();
p.bump(T![_]);
m.complete(p, UNDERSCORE_EXPR)
}
T![loop] => loop_expr(p, None),
T![box] => box_expr(p, None),
T![for] => for_expr(p, None),

View file

@ -188,6 +188,7 @@ pub enum SyntaxKind {
RETURN_EXPR,
YIELD_EXPR,
LET_EXPR,
UNDERSCORE_EXPR,
MATCH_EXPR,
MATCH_ARM_LIST,
MATCH_ARM,

View file

@ -1,204 +0,0 @@
SOURCE_FILE@0..575
FN@0..574
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..7
IDENT@3..7 "main"
PARAM_LIST@7..9
L_PAREN@7..8 "("
R_PAREN@8..9 ")"
WHITESPACE@9..10 " "
BLOCK_EXPR@10..574
STMT_LIST@10..574
L_CURLY@10..11 "{"
WHITESPACE@11..16 "\n "
ENUM@16..152
ENUM_KW@16..20 "enum"
WHITESPACE@20..21 " "
NAME@21..25
IDENT@21..25 "Test"
WHITESPACE@25..26 " "
VARIANT_LIST@26..152
L_CURLY@26..27 "{"
WHITESPACE@27..36 "\n "
VARIANT@36..40
NAME@36..40
IDENT@36..40 "Var1"
COMMA@40..41 ","
WHITESPACE@41..50 "\n "
VARIANT@50..62
NAME@50..54
IDENT@50..54 "Var2"
TUPLE_FIELD_LIST@54..62
L_PAREN@54..55 "("
TUPLE_FIELD@55..61
PATH_TYPE@55..61
PATH@55..61
PATH_SEGMENT@55..61
NAME_REF@55..61
IDENT@55..61 "String"
R_PAREN@61..62 ")"
COMMA@62..63 ","
WHITESPACE@63..72 "\n "
VARIANT@72..145
NAME@72..76
IDENT@72..76 "Var3"
WHITESPACE@76..77 " "
RECORD_FIELD_LIST@77..145
L_CURLY@77..78 "{"
WHITESPACE@78..91 "\n "
RECORD_FIELD@91..95
NAME@91..94
IDENT@91..94 "abc"
COLON@94..95 ":"
WHITESPACE@95..96 " "
ERROR@96..98
L_CURLY@96..97 "{"
R_CURLY@97..98 "}"
ERROR@98..99
COMMA@98..99 ","
WHITESPACE@99..100 " "
COMMENT@100..135 "//~ ERROR: expected t ..."
WHITESPACE@135..144 "\n "
R_CURLY@144..145 "}"
COMMA@145..146 ","
WHITESPACE@146..151 "\n "
R_CURLY@151..152 "}"
WHITESPACE@152..158 "\n\n "
COMMENT@158..171 "// recover..."
WHITESPACE@171..176 "\n "
LET_STMT@176..186
LET_KW@176..179 "let"
WHITESPACE@179..180 " "
IDENT_PAT@180..181
NAME@180..181
IDENT@180..181 "a"
WHITESPACE@181..182 " "
EQ@182..183 "="
WHITESPACE@183..184 " "
LITERAL@184..185
INT_NUMBER@184..185 "1"
SEMICOLON@185..186 ";"
WHITESPACE@186..191 "\n "
ENUM@191..223
ENUM_KW@191..195 "enum"
WHITESPACE@195..196 " "
NAME@196..201
IDENT@196..201 "Test2"
WHITESPACE@201..202 " "
VARIANT_LIST@202..223
L_CURLY@202..203 "{"
WHITESPACE@203..212 "\n "
VARIANT@212..216
NAME@212..216
IDENT@212..216 "Fine"
COMMA@216..217 ","
WHITESPACE@217..222 "\n "
R_CURLY@222..223 "}"
WHITESPACE@223..229 "\n\n "
ENUM@229..300
ENUM_KW@229..233 "enum"
WHITESPACE@233..234 " "
NAME@234..239
IDENT@234..239 "Test3"
WHITESPACE@239..240 " "
VARIANT_LIST@240..300
L_CURLY@240..241 "{"
WHITESPACE@241..250 "\n "
VARIANT@250..293
NAME@250..259
IDENT@250..259 "StillFine"
WHITESPACE@259..260 " "
RECORD_FIELD_LIST@260..293
L_CURLY@260..261 "{"
WHITESPACE@261..274 "\n "
RECORD_FIELD@274..282
NAME@274..277
IDENT@274..277 "def"
COLON@277..278 ":"
WHITESPACE@278..279 " "
PATH_TYPE@279..282
PATH@279..282
PATH_SEGMENT@279..282
NAME_REF@279..282
IDENT@279..282 "i32"
COMMA@282..283 ","
WHITESPACE@283..292 "\n "
R_CURLY@292..293 "}"
COMMA@293..294 ","
WHITESPACE@294..299 "\n "
R_CURLY@299..300 "}"
WHITESPACE@300..306 "\n\n "
EXPR_STMT@306..459
BLOCK_EXPR@306..459
STMT_LIST@306..459
L_CURLY@306..307 "{"
WHITESPACE@307..316 "\n "
ENUM@316..453
COMMENT@316..329 "// fail again"
WHITESPACE@329..338 "\n "
ENUM_KW@338..342 "enum"
WHITESPACE@342..343 " "
NAME@343..348
IDENT@343..348 "Test4"
WHITESPACE@348..349 " "
VARIANT_LIST@349..453
L_CURLY@349..350 "{"
WHITESPACE@350..363 "\n "
VARIANT@363..372
NAME@363..367
IDENT@363..367 "Nope"
TUPLE_FIELD_LIST@367..372
L_PAREN@367..368 "("
TUPLE_FIELD@368..371
PATH_TYPE@368..371
PATH@368..371
PATH_SEGMENT@368..371
NAME_REF@368..371
IDENT@368..371 "i32"
WHITESPACE@371..372 " "
ERROR@372..372
ERROR@372..374
L_CURLY@372..373 "{"
R_CURLY@373..374 "}"
ERROR@374..375
R_PAREN@374..375 ")"
WHITESPACE@375..376 " "
COMMENT@376..396 "//~ ERROR: found `{`"
WHITESPACE@396..422 "\n ..."
COMMENT@422..443 "//~^ ERROR: found `{`"
WHITESPACE@443..452 "\n "
R_CURLY@452..453 "}"
WHITESPACE@453..458 "\n "
R_CURLY@458..459 "}"
WHITESPACE@459..464 "\n "
COMMENT@464..486 "// still recover later"
WHITESPACE@486..491 "\n "
LET_STMT@491..510
LET_KW@491..494 "let"
WHITESPACE@494..495 " "
IDENT_PAT@495..505
NAME@495..505
IDENT@495..505 "bad_syntax"
WHITESPACE@505..506 " "
EQ@506..507 "="
WHITESPACE@507..508 " "
ERROR@508..509
UNDERSCORE@508..509 "_"
SEMICOLON@509..510 ";"
WHITESPACE@510..511 " "
COMMENT@511..572 "//~ ERROR: expected e ..."
WHITESPACE@572..573 "\n"
R_CURLY@573..574 "}"
WHITESPACE@574..575 "\n"
error 95..95: expected type
error 95..95: expected COMMA
error 96..96: expected field
error 98..98: expected field declaration
error 371..371: expected COMMA
error 372..372: expected a type
error 372..372: expected R_PAREN
error 372..372: expected COMMA
error 372..372: expected enum variant
error 374..374: expected enum variant
error 508..508: expected expression

View file

@ -27,5 +27,6 @@ fn main() {
}
}
// still recover later
let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_`
let; //~ ERROR: expected pattern
let _ = 0;
}

View file

@ -176,18 +176,22 @@ SOURCE_FILE
WHITESPACE "\n "
LET_STMT
LET_KW "let"
ERROR
SEMICOLON ";"
WHITESPACE " "
IDENT_PAT
NAME
IDENT "bad_syntax"
COMMENT "//~ ERROR: expected pattern"
WHITESPACE "\n "
LET_STMT
LET_KW "let"
WHITESPACE " "
WILDCARD_PAT
UNDERSCORE "_"
WHITESPACE " "
EQ "="
WHITESPACE " "
ERROR
UNDERSCORE "_"
LITERAL
INT_NUMBER "0"
SEMICOLON ";"
WHITESPACE " "
COMMENT "//~ ERROR: expected expression, found reserved identifier `_`"
WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"
@ -201,4 +205,5 @@ error 372: expected R_PAREN
error 372: expected COMMA
error 372: expected enum variant
error 374: expected enum variant
error 508: expected expression
error 494: expected pattern
error 495: expected SEMICOLON

View file

@ -0,0 +1,3 @@
fn foo() {
S { .. } = S {};
}

View file

@ -0,0 +1,44 @@
SOURCE_FILE
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "foo"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
RECORD_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "S"
WHITESPACE " "
RECORD_EXPR_FIELD_LIST
L_CURLY "{"
WHITESPACE " "
DOT2 ".."
WHITESPACE " "
R_CURLY "}"
WHITESPACE " "
EQ "="
WHITESPACE " "
RECORD_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "S"
WHITESPACE " "
RECORD_EXPR_FIELD_LIST
L_CURLY "{"
R_CURLY "}"
SEMICOLON ";"
WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"

View file

@ -0,0 +1,4 @@
fn foo() {
_ = 1;
Some(_) = None;
}

View file

@ -0,0 +1,50 @@
SOURCE_FILE
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "foo"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
UNDERSCORE_EXPR
UNDERSCORE "_"
WHITESPACE " "
EQ "="
WHITESPACE " "
LITERAL
INT_NUMBER "1"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
CALL_EXPR
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "Some"
ARG_LIST
L_PAREN "("
UNDERSCORE_EXPR
UNDERSCORE "_"
R_PAREN ")"
WHITESPACE " "
EQ "="
WHITESPACE " "
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "None"
SEMICOLON ";"
WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"

View file

@ -0,0 +1,14 @@
fn foo() {
let (mut a, mut b) = (0, 1);
(b, a, ..) = (a, b);
(_) = ..;
struct S { a: i32 }
S { .. } = S { ..S::default() };
Some(..) = Some(0).
Ok(_) = 0;
let (a, b);
[a, .., b] = [1, .., 2];
(_, _) = (a, b);
(_) = (a, b);
_ = (a, b);
}

View file

@ -0,0 +1,352 @@
SOURCE_FILE
FN
FN_KW "fn"
WHITESPACE " "
NAME
IDENT "foo"
PARAM_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
BLOCK_EXPR
STMT_LIST
L_CURLY "{"
WHITESPACE "\n "
LET_STMT
LET_KW "let"
WHITESPACE " "
TUPLE_PAT
L_PAREN "("
IDENT_PAT
MUT_KW "mut"
WHITESPACE " "
NAME
IDENT "a"
COMMA ","
WHITESPACE " "
IDENT_PAT
MUT_KW "mut"
WHITESPACE " "
NAME
IDENT "b"
R_PAREN ")"
WHITESPACE " "
EQ "="
WHITESPACE " "
TUPLE_EXPR
L_PAREN "("
LITERAL
INT_NUMBER "0"
COMMA ","
WHITESPACE " "
LITERAL
INT_NUMBER "1"
R_PAREN ")"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
TUPLE_EXPR
L_PAREN "("
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "b"
COMMA ","
WHITESPACE " "
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "a"
COMMA ","
WHITESPACE " "
RANGE_EXPR
DOT2 ".."
R_PAREN ")"
WHITESPACE " "
EQ "="
WHITESPACE " "
TUPLE_EXPR
L_PAREN "("
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "a"
COMMA ","
WHITESPACE " "
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "b"
R_PAREN ")"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
PAREN_EXPR
L_PAREN "("
UNDERSCORE_EXPR
UNDERSCORE "_"
R_PAREN ")"
WHITESPACE " "
EQ "="
WHITESPACE " "
RANGE_EXPR
DOT2 ".."
SEMICOLON ";"
WHITESPACE "\n "
STRUCT
STRUCT_KW "struct"
WHITESPACE " "
NAME
IDENT "S"
WHITESPACE " "
RECORD_FIELD_LIST
L_CURLY "{"
WHITESPACE " "
RECORD_FIELD
NAME
IDENT "a"
COLON ":"
WHITESPACE " "
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
IDENT "i32"
WHITESPACE " "
R_CURLY "}"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
RECORD_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "S"
WHITESPACE " "
RECORD_EXPR_FIELD_LIST
L_CURLY "{"
WHITESPACE " "
DOT2 ".."
WHITESPACE " "
R_CURLY "}"
WHITESPACE " "
EQ "="
WHITESPACE " "
RECORD_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "S"
WHITESPACE " "
RECORD_EXPR_FIELD_LIST
L_CURLY "{"
WHITESPACE " "
DOT2 ".."
CALL_EXPR
PATH_EXPR
PATH
PATH
PATH_SEGMENT
NAME_REF
IDENT "S"
COLON2 "::"
PATH_SEGMENT
NAME_REF
IDENT "default"
ARG_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
R_CURLY "}"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
BIN_EXPR
CALL_EXPR
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "Some"
ARG_LIST
L_PAREN "("
RANGE_EXPR
DOT2 ".."
R_PAREN ")"
WHITESPACE " "
EQ "="
WHITESPACE " "
METHOD_CALL_EXPR
CALL_EXPR
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "Some"
ARG_LIST
L_PAREN "("
LITERAL
INT_NUMBER "0"
R_PAREN ")"
DOT "."
WHITESPACE "\n "
NAME_REF
IDENT "Ok"
ARG_LIST
L_PAREN "("
UNDERSCORE_EXPR
UNDERSCORE "_"
R_PAREN ")"
WHITESPACE " "
EQ "="
WHITESPACE " "
LITERAL
INT_NUMBER "0"
SEMICOLON ";"
WHITESPACE "\n "
LET_STMT
LET_KW "let"
WHITESPACE " "
TUPLE_PAT
L_PAREN "("
IDENT_PAT
NAME
IDENT "a"
COMMA ","
WHITESPACE " "
IDENT_PAT
NAME
IDENT "b"
R_PAREN ")"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
ARRAY_EXPR
L_BRACK "["
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "a"
COMMA ","
WHITESPACE " "
RANGE_EXPR
DOT2 ".."
COMMA ","
WHITESPACE " "
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "b"
R_BRACK "]"
WHITESPACE " "
EQ "="
WHITESPACE " "
ARRAY_EXPR
L_BRACK "["
LITERAL
INT_NUMBER "1"
COMMA ","
WHITESPACE " "
RANGE_EXPR
DOT2 ".."
COMMA ","
WHITESPACE " "
LITERAL
INT_NUMBER "2"
R_BRACK "]"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
TUPLE_EXPR
L_PAREN "("
UNDERSCORE_EXPR
UNDERSCORE "_"
COMMA ","
WHITESPACE " "
UNDERSCORE_EXPR
UNDERSCORE "_"
R_PAREN ")"
WHITESPACE " "
EQ "="
WHITESPACE " "
TUPLE_EXPR
L_PAREN "("
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "a"
COMMA ","
WHITESPACE " "
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "b"
R_PAREN ")"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
PAREN_EXPR
L_PAREN "("
UNDERSCORE_EXPR
UNDERSCORE "_"
R_PAREN ")"
WHITESPACE " "
EQ "="
WHITESPACE " "
TUPLE_EXPR
L_PAREN "("
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "a"
COMMA ","
WHITESPACE " "
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "b"
R_PAREN ")"
SEMICOLON ";"
WHITESPACE "\n "
EXPR_STMT
BIN_EXPR
UNDERSCORE_EXPR
UNDERSCORE "_"
WHITESPACE " "
EQ "="
WHITESPACE " "
TUPLE_EXPR
L_PAREN "("
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "a"
COMMA ","
WHITESPACE " "
PATH_EXPR
PATH
PATH_SEGMENT
NAME_REF
IDENT "b"
R_PAREN ")"
SEMICOLON ";"
WHITESPACE "\n"
R_CURLY "}"
WHITESPACE "\n"

View file

@ -30,7 +30,7 @@ rayon = "1"
expect-test = "1.2.0-pre.1"
proc-macro2 = "1.0.8"
quote = "1.0.2"
ungrammar = "=1.15.0"
ungrammar = "=1.16.0"
test_utils = { path = "../test_utils" }
sourcegen = { path = "../sourcegen" }

View file

@ -1064,6 +1064,15 @@ impl LetExpr {
pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct UnderscoreExpr {
pub(crate) syntax: SyntaxNode,
}
impl ast::HasAttrs for UnderscoreExpr {}
impl UnderscoreExpr {
pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct StmtList {
pub(crate) syntax: SyntaxNode,
@ -1524,6 +1533,7 @@ pub enum Expr {
WhileExpr(WhileExpr),
YieldExpr(YieldExpr),
LetExpr(LetExpr),
UnderscoreExpr(UnderscoreExpr),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@ -2675,6 +2685,17 @@ impl AstNode for LetExpr {
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl AstNode for UnderscoreExpr {
fn can_cast(kind: SyntaxKind) -> bool { kind == UNDERSCORE_EXPR }
fn cast(syntax: SyntaxNode) -> Option<Self> {
if Self::can_cast(syntax.kind()) {
Some(Self { syntax })
} else {
None
}
}
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
impl AstNode for StmtList {
fn can_cast(kind: SyntaxKind) -> bool { kind == STMT_LIST }
fn cast(syntax: SyntaxNode) -> Option<Self> {
@ -3339,6 +3360,9 @@ impl From<YieldExpr> for Expr {
impl From<LetExpr> for Expr {
fn from(node: LetExpr) -> Expr { Expr::LetExpr(node) }
}
impl From<UnderscoreExpr> for Expr {
fn from(node: UnderscoreExpr) -> Expr { Expr::UnderscoreExpr(node) }
}
impl AstNode for Expr {
fn can_cast(kind: SyntaxKind) -> bool {
match kind {
@ -3347,7 +3371,7 @@ impl AstNode for Expr {
| INDEX_EXPR | LITERAL | LOOP_EXPR | MACRO_CALL | MACRO_STMTS | MATCH_EXPR
| METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR | RANGE_EXPR
| RECORD_EXPR | REF_EXPR | RETURN_EXPR | TRY_EXPR | TUPLE_EXPR | WHILE_EXPR
| YIELD_EXPR | LET_EXPR => true,
| YIELD_EXPR | LET_EXPR | UNDERSCORE_EXPR => true,
_ => false,
}
}
@ -3385,6 +3409,7 @@ impl AstNode for Expr {
WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }),
YIELD_EXPR => Expr::YieldExpr(YieldExpr { syntax }),
LET_EXPR => Expr::LetExpr(LetExpr { syntax }),
UNDERSCORE_EXPR => Expr::UnderscoreExpr(UnderscoreExpr { syntax }),
_ => return None,
};
Some(res)
@ -3423,6 +3448,7 @@ impl AstNode for Expr {
Expr::WhileExpr(it) => &it.syntax,
Expr::YieldExpr(it) => &it.syntax,
Expr::LetExpr(it) => &it.syntax,
Expr::UnderscoreExpr(it) => &it.syntax,
}
}
}
@ -3889,6 +3915,7 @@ impl AstNode for AnyHasAttrs {
| WHILE_EXPR
| YIELD_EXPR
| LET_EXPR
| UNDERSCORE_EXPR
| STMT_LIST
| RECORD_EXPR_FIELD_LIST
| RECORD_EXPR_FIELD
@ -4548,6 +4575,11 @@ impl std::fmt::Display for LetExpr {
std::fmt::Display::fmt(self.syntax(), f)
}
}
impl std::fmt::Display for UnderscoreExpr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)
}
}
impl std::fmt::Display for StmtList {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)

View file

@ -143,6 +143,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
"RETURN_EXPR",
"YIELD_EXPR",
"LET_EXPR",
"UNDERSCORE_EXPR",
"MATCH_EXPR",
"MATCH_ARM_LIST",
"MATCH_ARM",