Unnamed repository; edit this file 'description' to name the repository.
Parse `try bikeshed T {}` syntax
| -rw-r--r-- | crates/parser/src/grammar/expressions/atom.rs | 6 | ||||
| -rw-r--r-- | crates/parser/src/syntax_kind/generated.rs | 8 | ||||
| -rw-r--r-- | crates/parser/test_data/parser/err/0042_weird_blocks.rast | 3 | ||||
| -rw-r--r-- | crates/parser/test_data/parser/inline/ok/try_block_expr.rast | 37 | ||||
| -rw-r--r-- | crates/parser/test_data/parser/inline/ok/try_block_expr.rs | 1 | ||||
| -rw-r--r-- | crates/syntax/rust.ungram | 5 | ||||
| -rw-r--r-- | crates/syntax/src/ast/generated/nodes.rs | 54 | ||||
| -rw-r--r-- | xtask/src/codegen/grammar/ast_src.rs | 2 |
8 files changed, 110 insertions, 6 deletions
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index d83e2eb2b4..b75474ee2b 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -976,11 +976,17 @@ fn break_expr(p: &mut Parser<'_>, r: Restrictions) -> CompletedMarker { // test try_block_expr // fn foo() { // let _ = try {}; +// let _ = try bikeshed T<U> {}; // } fn try_block_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker { assert!(p.at(T![try])); let m = m.unwrap_or_else(|| p.start()); + let try_modifier = p.start(); p.bump(T![try]); + if p.eat_contextual_kw(T![bikeshed]) { + type_(p); + } + try_modifier.complete(p, TRY_BLOCK_MODIFIER); if p.at(T!['{']) { stmt_list(p); } else { diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs index 5d22d966b2..a2295e4495 100644 --- a/crates/parser/src/syntax_kind/generated.rs +++ b/crates/parser/src/syntax_kind/generated.rs @@ -114,6 +114,7 @@ pub enum SyntaxKind { ATT_SYNTAX_KW, AUTO_KW, AWAIT_KW, + BIKESHED_KW, BUILTIN_KW, CLOBBER_ABI_KW, DEFAULT_KW, @@ -285,6 +286,7 @@ pub enum SyntaxKind { STRUCT, TOKEN_TREE, TRAIT, + TRY_BLOCK_MODIFIER, TRY_EXPR, TUPLE_EXPR, TUPLE_FIELD, @@ -458,6 +460,7 @@ impl SyntaxKind { | STRUCT | TOKEN_TREE | TRAIT + | TRY_BLOCK_MODIFIER | TRY_EXPR | TUPLE_EXPR | TUPLE_FIELD @@ -596,6 +599,7 @@ impl SyntaxKind { ASM_KW => "asm", ATT_SYNTAX_KW => "att_syntax", AUTO_KW => "auto", + BIKESHED_KW => "bikeshed", BUILTIN_KW => "builtin", CLOBBER_ABI_KW => "clobber_abi", DEFAULT_KW => "default", @@ -698,6 +702,7 @@ impl SyntaxKind { ASM_KW => true, ATT_SYNTAX_KW => true, AUTO_KW => true, + BIKESHED_KW => true, BUILTIN_KW => true, CLOBBER_ABI_KW => true, DEFAULT_KW => true, @@ -788,6 +793,7 @@ impl SyntaxKind { ASM_KW => true, ATT_SYNTAX_KW => true, AUTO_KW => true, + BIKESHED_KW => true, BUILTIN_KW => true, CLOBBER_ABI_KW => true, DEFAULT_KW => true, @@ -941,6 +947,7 @@ impl SyntaxKind { "asm" => ASM_KW, "att_syntax" => ATT_SYNTAX_KW, "auto" => AUTO_KW, + "bikeshed" => BIKESHED_KW, "builtin" => BUILTIN_KW, "clobber_abi" => CLOBBER_ABI_KW, "default" => DEFAULT_KW, @@ -1112,6 +1119,7 @@ macro_rules ! T_ { [asm] => { $ crate :: SyntaxKind :: ASM_KW }; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW }; [auto] => { $ crate :: SyntaxKind :: AUTO_KW }; + [bikeshed] => { $ crate :: SyntaxKind :: BIKESHED_KW }; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW }; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW }; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW }; diff --git a/crates/parser/test_data/parser/err/0042_weird_blocks.rast b/crates/parser/test_data/parser/err/0042_weird_blocks.rast index d6d2e75cca..9e4e9dbf9d 100644 --- a/crates/parser/test_data/parser/err/0042_weird_blocks.rast +++ b/crates/parser/test_data/parser/err/0042_weird_blocks.rast @@ -45,7 +45,8 @@ SOURCE_FILE WHITESPACE " " EXPR_STMT BLOCK_EXPR - TRY_KW "try" + TRY_BLOCK_MODIFIER + TRY_KW "try" WHITESPACE " " LITERAL INT_NUMBER "92" diff --git a/crates/parser/test_data/parser/inline/ok/try_block_expr.rast b/crates/parser/test_data/parser/inline/ok/try_block_expr.rast index aec8fbf477..472ce711c5 100644 --- a/crates/parser/test_data/parser/inline/ok/try_block_expr.rast +++ b/crates/parser/test_data/parser/inline/ok/try_block_expr.rast @@ -21,7 +21,42 @@ SOURCE_FILE EQ "=" WHITESPACE " " BLOCK_EXPR - TRY_KW "try" + TRY_BLOCK_MODIFIER + TRY_KW "try" + WHITESPACE " " + STMT_LIST + L_CURLY "{" + R_CURLY "}" + SEMICOLON ";" + WHITESPACE "\n " + LET_STMT + LET_KW "let" + WHITESPACE " " + WILDCARD_PAT + UNDERSCORE "_" + WHITESPACE " " + EQ "=" + WHITESPACE " " + BLOCK_EXPR + TRY_BLOCK_MODIFIER + TRY_KW "try" + WHITESPACE " " + BIKESHED_KW "bikeshed" + WHITESPACE " " + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "T" + GENERIC_ARG_LIST + L_ANGLE "<" + TYPE_ARG + PATH_TYPE + PATH + PATH_SEGMENT + NAME_REF + IDENT "U" + R_ANGLE ">" WHITESPACE " " STMT_LIST L_CURLY "{" diff --git a/crates/parser/test_data/parser/inline/ok/try_block_expr.rs b/crates/parser/test_data/parser/inline/ok/try_block_expr.rs index 0f1b41eb64..719980473c 100644 --- a/crates/parser/test_data/parser/inline/ok/try_block_expr.rs +++ b/crates/parser/test_data/parser/inline/ok/try_block_expr.rs @@ -1,3 +1,4 @@ fn foo() { let _ = try {}; + let _ = try bikeshed T<U> {}; } diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram index 991fe7d83a..544053408f 100644 --- a/crates/syntax/rust.ungram +++ b/crates/syntax/rust.ungram @@ -472,8 +472,11 @@ RefExpr = TryExpr = Attr* Expr '?' +TryBlockModifier = + 'try' ('bikeshed' Type)? + BlockExpr = - Attr* Label? ('try' | 'unsafe' | ('async' 'move'?) | ('gen' 'move'?) | 'const') StmtList + Attr* Label? (TryBlockModifier | 'unsafe' | ('async' 'move'?) | ('gen' 'move'?) | 'const') StmtList PrefixExpr = Attr* op:('-' | '!' | '*') Expr diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 7b9f5b9166..c4e72eafa7 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs @@ -323,6 +323,8 @@ impl BlockExpr { #[inline] pub fn stmt_list(&self) -> Option<StmtList> { support::child(&self.syntax) } #[inline] + pub fn try_block_modifier(&self) -> Option<TryBlockModifier> { support::child(&self.syntax) } + #[inline] pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) } #[inline] pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) } @@ -331,8 +333,6 @@ impl BlockExpr { #[inline] pub fn move_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![move]) } #[inline] - pub fn try_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![try]) } - #[inline] pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) } } pub struct BoxPat { @@ -1630,6 +1630,19 @@ impl Trait { #[inline] pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) } } +pub struct TryBlockModifier { + pub(crate) syntax: SyntaxNode, +} +impl TryBlockModifier { + #[inline] + pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) } + #[inline] + pub fn bikeshed_token(&self) -> Option<SyntaxToken> { + support::token(&self.syntax, T![bikeshed]) + } + #[inline] + pub fn try_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![try]) } +} pub struct TryExpr { pub(crate) syntax: SyntaxNode, } @@ -6320,6 +6333,38 @@ impl fmt::Debug for Trait { f.debug_struct("Trait").field("syntax", &self.syntax).finish() } } +impl AstNode for TryBlockModifier { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TRY_BLOCK_MODIFIER + } + #[inline] + fn can_cast(kind: SyntaxKind) -> bool { kind == TRY_BLOCK_MODIFIER } + #[inline] + fn cast(syntax: SyntaxNode) -> Option<Self> { + if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None } + } + #[inline] + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +impl hash::Hash for TryBlockModifier { + fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); } +} +impl Eq for TryBlockModifier {} +impl PartialEq for TryBlockModifier { + fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax } +} +impl Clone for TryBlockModifier { + fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } } +} +impl fmt::Debug for TryBlockModifier { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("TryBlockModifier").field("syntax", &self.syntax).finish() + } +} impl AstNode for TryExpr { #[inline] fn kind() -> SyntaxKind @@ -9979,6 +10024,11 @@ impl std::fmt::Display for Trait { std::fmt::Display::fmt(self.syntax(), f) } } +impl std::fmt::Display for TryBlockModifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self.syntax(), f) + } +} impl std::fmt::Display for TryExpr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { std::fmt::Display::fmt(self.syntax(), f) diff --git a/xtask/src/codegen/grammar/ast_src.rs b/xtask/src/codegen/grammar/ast_src.rs index b9f570fe0e..205072a6ce 100644 --- a/xtask/src/codegen/grammar/ast_src.rs +++ b/xtask/src/codegen/grammar/ast_src.rs @@ -112,7 +112,7 @@ const RESERVED: &[&str] = &[ // keywords that are keywords only in specific parse contexts #[doc(alias = "WEAK_KEYWORDS")] const CONTEXTUAL_KEYWORDS: &[&str] = - &["macro_rules", "union", "default", "raw", "dyn", "auto", "yeet", "safe"]; + &["macro_rules", "union", "default", "raw", "dyn", "auto", "yeet", "safe", "bikeshed"]; // keywords we use for special macro expansions const CONTEXTUAL_BUILTIN_KEYWORDS: &[&str] = &[ "asm", |