From ca0c8da517ccc352e080ac3dcd53c263a3a79b4f Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 30 Dec 2024 03:13:17 +0200 Subject: [PATCH 1/4] Generate a method for static retrieval of the SyntaxKind of a node, where possible This will help for the quote macro for `ast::make`. --- .../rust-analyzer/crates/syntax/src/ast.rs | 8 + .../crates/syntax/src/ast/generated/nodes.rs | 1078 +++++++++++++++++ .../xtask/src/codegen/grammar.rs | 7 + 3 files changed, 1093 insertions(+) diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast.rs b/src/tools/rust-analyzer/crates/syntax/src/ast.rs index 32b1f5f75448..72a46f2f9f00 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast.rs @@ -42,6 +42,14 @@ pub use self::{ /// the same representation: a pointer to the tree root and a pointer to the /// node itself. pub trait AstNode { + /// This panics if the `SyntaxKind` is not statically known. + fn kind() -> SyntaxKind + where + Self: Sized, + { + panic!("dynamic `SyntaxKind` for `AstNode::kind()`") + } + fn can_cast(kind: SyntaxKind) -> bool where Self: Sized; diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs index 3876ef71a077..69e2a9f9c1b2 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/generated/nodes.rs @@ -2502,6 +2502,13 @@ pub struct AnyHasVisibility { } impl ast::HasVisibility for AnyHasVisibility {} impl AstNode for Abi { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ABI + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ABI } #[inline] @@ -2516,6 +2523,13 @@ impl AstNode for Abi { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ArgList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ARG_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ARG_LIST } #[inline] @@ -2530,6 +2544,13 @@ impl AstNode for ArgList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ArrayExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ARRAY_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ARRAY_EXPR } #[inline] @@ -2544,6 +2565,13 @@ impl AstNode for ArrayExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ArrayType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ARRAY_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ARRAY_TYPE } #[inline] @@ -2558,6 +2586,13 @@ impl AstNode for ArrayType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmClobberAbi { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_CLOBBER_ABI + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_CLOBBER_ABI } #[inline] @@ -2572,6 +2607,13 @@ impl AstNode for AsmClobberAbi { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmConst { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_CONST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_CONST } #[inline] @@ -2586,6 +2628,13 @@ impl AstNode for AsmConst { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmDirSpec { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_DIR_SPEC + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_DIR_SPEC } #[inline] @@ -2600,6 +2649,13 @@ impl AstNode for AsmDirSpec { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_EXPR } #[inline] @@ -2614,6 +2670,13 @@ impl AstNode for AsmExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmLabel { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_LABEL + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_LABEL } #[inline] @@ -2628,6 +2691,13 @@ impl AstNode for AsmLabel { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmOperandExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_OPERAND_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_OPERAND_EXPR } #[inline] @@ -2642,6 +2712,13 @@ impl AstNode for AsmOperandExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmOperandNamed { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_OPERAND_NAMED + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_OPERAND_NAMED } #[inline] @@ -2656,6 +2733,13 @@ impl AstNode for AsmOperandNamed { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmOption { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_OPTION + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_OPTION } #[inline] @@ -2670,6 +2754,13 @@ impl AstNode for AsmOption { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmOptions { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_OPTIONS + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_OPTIONS } #[inline] @@ -2684,6 +2775,13 @@ impl AstNode for AsmOptions { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmRegOperand { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_REG_OPERAND + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_REG_OPERAND } #[inline] @@ -2698,6 +2796,13 @@ impl AstNode for AsmRegOperand { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmRegSpec { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_REG_SPEC + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_REG_SPEC } #[inline] @@ -2712,6 +2817,13 @@ impl AstNode for AsmRegSpec { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AsmSym { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASM_SYM + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_SYM } #[inline] @@ -2726,6 +2838,13 @@ impl AstNode for AsmSym { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AssocItemList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASSOC_ITEM_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_ITEM_LIST } #[inline] @@ -2740,6 +2859,13 @@ impl AstNode for AssocItemList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AssocTypeArg { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ASSOC_TYPE_ARG + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_TYPE_ARG } #[inline] @@ -2754,6 +2880,13 @@ impl AstNode for AssocTypeArg { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Attr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ATTR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ATTR } #[inline] @@ -2768,6 +2901,13 @@ impl AstNode for Attr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for AwaitExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + AWAIT_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == AWAIT_EXPR } #[inline] @@ -2782,6 +2922,13 @@ impl AstNode for AwaitExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for BecomeExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + BECOME_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == BECOME_EXPR } #[inline] @@ -2796,6 +2943,13 @@ impl AstNode for BecomeExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for BinExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + BIN_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == BIN_EXPR } #[inline] @@ -2810,6 +2964,13 @@ impl AstNode for BinExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for BlockExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + BLOCK_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == BLOCK_EXPR } #[inline] @@ -2824,6 +2985,13 @@ impl AstNode for BlockExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for BoxPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + BOX_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == BOX_PAT } #[inline] @@ -2838,6 +3006,13 @@ impl AstNode for BoxPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for BreakExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + BREAK_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == BREAK_EXPR } #[inline] @@ -2852,6 +3027,13 @@ impl AstNode for BreakExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for CallExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CALL_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == CALL_EXPR } #[inline] @@ -2866,6 +3048,13 @@ impl AstNode for CallExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for CastExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CAST_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == CAST_EXPR } #[inline] @@ -2880,6 +3069,13 @@ impl AstNode for CastExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ClosureBinder { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CLOSURE_BINDER + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == CLOSURE_BINDER } #[inline] @@ -2894,6 +3090,13 @@ impl AstNode for ClosureBinder { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ClosureExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CLOSURE_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == CLOSURE_EXPR } #[inline] @@ -2908,6 +3111,13 @@ impl AstNode for ClosureExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Const { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CONST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == CONST } #[inline] @@ -2922,6 +3132,13 @@ impl AstNode for Const { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ConstArg { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CONST_ARG + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_ARG } #[inline] @@ -2936,6 +3153,13 @@ impl AstNode for ConstArg { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ConstBlockPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CONST_BLOCK_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_BLOCK_PAT } #[inline] @@ -2950,6 +3174,13 @@ impl AstNode for ConstBlockPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ConstParam { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CONST_PARAM + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_PARAM } #[inline] @@ -2964,6 +3195,13 @@ impl AstNode for ConstParam { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ContinueExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + CONTINUE_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == CONTINUE_EXPR } #[inline] @@ -2978,6 +3216,13 @@ impl AstNode for ContinueExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for DynTraitType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + DYN_TRAIT_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == DYN_TRAIT_TYPE } #[inline] @@ -2992,6 +3237,13 @@ impl AstNode for DynTraitType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Enum { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ENUM + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ENUM } #[inline] @@ -3006,6 +3258,13 @@ impl AstNode for Enum { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ExprStmt { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + EXPR_STMT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_STMT } #[inline] @@ -3020,6 +3279,13 @@ impl AstNode for ExprStmt { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ExternBlock { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + EXTERN_BLOCK + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == EXTERN_BLOCK } #[inline] @@ -3034,6 +3300,13 @@ impl AstNode for ExternBlock { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ExternCrate { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + EXTERN_CRATE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == EXTERN_CRATE } #[inline] @@ -3048,6 +3321,13 @@ impl AstNode for ExternCrate { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ExternItemList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + EXTERN_ITEM_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == EXTERN_ITEM_LIST } #[inline] @@ -3062,6 +3342,13 @@ impl AstNode for ExternItemList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for FieldExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + FIELD_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == FIELD_EXPR } #[inline] @@ -3076,6 +3363,13 @@ impl AstNode for FieldExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Fn { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + FN + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == FN } #[inline] @@ -3090,6 +3384,13 @@ impl AstNode for Fn { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for FnPtrType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + FN_PTR_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == FN_PTR_TYPE } #[inline] @@ -3104,6 +3405,13 @@ impl AstNode for FnPtrType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ForExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + FOR_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_EXPR } #[inline] @@ -3118,6 +3426,13 @@ impl AstNode for ForExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ForType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + FOR_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_TYPE } #[inline] @@ -3132,6 +3447,13 @@ impl AstNode for ForType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for FormatArgsArg { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + FORMAT_ARGS_ARG + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == FORMAT_ARGS_ARG } #[inline] @@ -3146,6 +3468,13 @@ impl AstNode for FormatArgsArg { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for FormatArgsExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + FORMAT_ARGS_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == FORMAT_ARGS_EXPR } #[inline] @@ -3160,6 +3489,13 @@ impl AstNode for FormatArgsExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for GenericArgList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + GENERIC_ARG_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_ARG_LIST } #[inline] @@ -3174,6 +3510,13 @@ impl AstNode for GenericArgList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for GenericParamList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + GENERIC_PARAM_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_PARAM_LIST } #[inline] @@ -3188,6 +3531,13 @@ impl AstNode for GenericParamList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for IdentPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + IDENT_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == IDENT_PAT } #[inline] @@ -3202,6 +3552,13 @@ impl AstNode for IdentPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for IfExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + IF_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == IF_EXPR } #[inline] @@ -3216,6 +3573,13 @@ impl AstNode for IfExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Impl { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + IMPL + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == IMPL } #[inline] @@ -3230,6 +3594,13 @@ impl AstNode for Impl { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ImplTraitType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + IMPL_TRAIT_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == IMPL_TRAIT_TYPE } #[inline] @@ -3244,6 +3615,13 @@ impl AstNode for ImplTraitType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for IndexExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + INDEX_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == INDEX_EXPR } #[inline] @@ -3258,6 +3636,13 @@ impl AstNode for IndexExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for InferType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + INFER_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == INFER_TYPE } #[inline] @@ -3272,6 +3657,13 @@ impl AstNode for InferType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ItemList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + ITEM_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == ITEM_LIST } #[inline] @@ -3286,6 +3678,13 @@ impl AstNode for ItemList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Label { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + LABEL + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == LABEL } #[inline] @@ -3300,6 +3699,13 @@ impl AstNode for Label { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for LetElse { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + LET_ELSE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == LET_ELSE } #[inline] @@ -3314,6 +3720,13 @@ impl AstNode for LetElse { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for LetExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + LET_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == LET_EXPR } #[inline] @@ -3328,6 +3741,13 @@ impl AstNode for LetExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for LetStmt { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + LET_STMT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == LET_STMT } #[inline] @@ -3342,6 +3762,13 @@ impl AstNode for LetStmt { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Lifetime { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + LIFETIME + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME } #[inline] @@ -3356,6 +3783,13 @@ impl AstNode for Lifetime { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for LifetimeArg { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + LIFETIME_ARG + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME_ARG } #[inline] @@ -3370,6 +3804,13 @@ impl AstNode for LifetimeArg { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for LifetimeParam { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + LIFETIME_PARAM + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME_PARAM } #[inline] @@ -3384,6 +3825,13 @@ impl AstNode for LifetimeParam { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Literal { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + LITERAL + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == LITERAL } #[inline] @@ -3398,6 +3846,13 @@ impl AstNode for Literal { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for LiteralPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + LITERAL_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == LITERAL_PAT } #[inline] @@ -3412,6 +3867,13 @@ impl AstNode for LiteralPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for LoopExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + LOOP_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == LOOP_EXPR } #[inline] @@ -3426,6 +3888,13 @@ impl AstNode for LoopExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MacroCall { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MACRO_CALL + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_CALL } #[inline] @@ -3440,6 +3909,13 @@ impl AstNode for MacroCall { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MacroDef { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MACRO_DEF + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_DEF } #[inline] @@ -3454,6 +3930,13 @@ impl AstNode for MacroDef { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MacroExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MACRO_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_EXPR } #[inline] @@ -3468,6 +3951,13 @@ impl AstNode for MacroExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MacroItems { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MACRO_ITEMS + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_ITEMS } #[inline] @@ -3482,6 +3972,13 @@ impl AstNode for MacroItems { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MacroPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MACRO_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_PAT } #[inline] @@ -3496,6 +3993,13 @@ impl AstNode for MacroPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MacroRules { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MACRO_RULES + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_RULES } #[inline] @@ -3510,6 +4014,13 @@ impl AstNode for MacroRules { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MacroStmts { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MACRO_STMTS + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_STMTS } #[inline] @@ -3524,6 +4035,13 @@ impl AstNode for MacroStmts { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MacroType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MACRO_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_TYPE } #[inline] @@ -3538,6 +4056,13 @@ impl AstNode for MacroType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MatchArm { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MATCH_ARM + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MATCH_ARM } #[inline] @@ -3552,6 +4077,13 @@ impl AstNode for MatchArm { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MatchArmList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MATCH_ARM_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MATCH_ARM_LIST } #[inline] @@ -3566,6 +4098,13 @@ impl AstNode for MatchArmList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MatchExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MATCH_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MATCH_EXPR } #[inline] @@ -3580,6 +4119,13 @@ impl AstNode for MatchExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MatchGuard { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MATCH_GUARD + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MATCH_GUARD } #[inline] @@ -3594,6 +4140,13 @@ impl AstNode for MatchGuard { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Meta { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + META + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == META } #[inline] @@ -3608,6 +4161,13 @@ impl AstNode for Meta { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for MethodCallExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + METHOD_CALL_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == METHOD_CALL_EXPR } #[inline] @@ -3622,6 +4182,13 @@ impl AstNode for MethodCallExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Module { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + MODULE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE } #[inline] @@ -3636,6 +4203,13 @@ impl AstNode for Module { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Name { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + NAME + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == NAME } #[inline] @@ -3650,6 +4224,13 @@ impl AstNode for Name { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for NameRef { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + NAME_REF + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == NAME_REF } #[inline] @@ -3664,6 +4245,13 @@ impl AstNode for NameRef { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for NeverType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + NEVER_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == NEVER_TYPE } #[inline] @@ -3678,6 +4266,13 @@ impl AstNode for NeverType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for OffsetOfExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + OFFSET_OF_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == OFFSET_OF_EXPR } #[inline] @@ -3692,6 +4287,13 @@ impl AstNode for OffsetOfExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for OrPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + OR_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == OR_PAT } #[inline] @@ -3706,6 +4308,13 @@ impl AstNode for OrPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Param { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PARAM + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PARAM } #[inline] @@ -3720,6 +4329,13 @@ impl AstNode for Param { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ParamList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PARAM_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PARAM_LIST } #[inline] @@ -3734,6 +4350,13 @@ impl AstNode for ParamList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ParenExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PAREN_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PAREN_EXPR } #[inline] @@ -3748,6 +4371,13 @@ impl AstNode for ParenExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ParenPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PAREN_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PAREN_PAT } #[inline] @@ -3762,6 +4392,13 @@ impl AstNode for ParenPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ParenType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PAREN_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PAREN_TYPE } #[inline] @@ -3776,6 +4413,13 @@ impl AstNode for ParenType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ParenthesizedArgList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PARENTHESIZED_ARG_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PARENTHESIZED_ARG_LIST } #[inline] @@ -3790,6 +4434,13 @@ impl AstNode for ParenthesizedArgList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Path { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PATH + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PATH } #[inline] @@ -3804,6 +4455,13 @@ impl AstNode for Path { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for PathExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PATH_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_EXPR } #[inline] @@ -3818,6 +4476,13 @@ impl AstNode for PathExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for PathPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PATH_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_PAT } #[inline] @@ -3832,6 +4497,13 @@ impl AstNode for PathPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for PathSegment { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PATH_SEGMENT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_SEGMENT } #[inline] @@ -3846,6 +4518,13 @@ impl AstNode for PathSegment { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for PathType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PATH_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_TYPE } #[inline] @@ -3860,6 +4539,13 @@ impl AstNode for PathType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for PrefixExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PREFIX_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PREFIX_EXPR } #[inline] @@ -3874,6 +4560,13 @@ impl AstNode for PrefixExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for PtrType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + PTR_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == PTR_TYPE } #[inline] @@ -3888,6 +4581,13 @@ impl AstNode for PtrType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RangeExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RANGE_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RANGE_EXPR } #[inline] @@ -3902,6 +4602,13 @@ impl AstNode for RangeExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RangePat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RANGE_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RANGE_PAT } #[inline] @@ -3916,6 +4623,13 @@ impl AstNode for RangePat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RecordExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RECORD_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_EXPR } #[inline] @@ -3930,6 +4644,13 @@ impl AstNode for RecordExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RecordExprField { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RECORD_EXPR_FIELD + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_EXPR_FIELD } #[inline] @@ -3944,6 +4665,13 @@ impl AstNode for RecordExprField { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RecordExprFieldList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RECORD_EXPR_FIELD_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_EXPR_FIELD_LIST } #[inline] @@ -3958,6 +4686,13 @@ impl AstNode for RecordExprFieldList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RecordField { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RECORD_FIELD + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD } #[inline] @@ -3972,6 +4707,13 @@ impl AstNode for RecordField { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RecordFieldList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RECORD_FIELD_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD_LIST } #[inline] @@ -3986,6 +4728,13 @@ impl AstNode for RecordFieldList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RecordPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RECORD_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_PAT } #[inline] @@ -4000,6 +4749,13 @@ impl AstNode for RecordPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RecordPatField { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RECORD_PAT_FIELD + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_PAT_FIELD } #[inline] @@ -4014,6 +4770,13 @@ impl AstNode for RecordPatField { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RecordPatFieldList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RECORD_PAT_FIELD_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_PAT_FIELD_LIST } #[inline] @@ -4028,6 +4791,13 @@ impl AstNode for RecordPatFieldList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RefExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + REF_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == REF_EXPR } #[inline] @@ -4042,6 +4812,13 @@ impl AstNode for RefExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RefPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + REF_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == REF_PAT } #[inline] @@ -4056,6 +4833,13 @@ impl AstNode for RefPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RefType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + REF_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == REF_TYPE } #[inline] @@ -4070,6 +4854,13 @@ impl AstNode for RefType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Rename { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RENAME + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RENAME } #[inline] @@ -4084,6 +4875,13 @@ impl AstNode for Rename { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RestPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + REST_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == REST_PAT } #[inline] @@ -4098,6 +4896,13 @@ impl AstNode for RestPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for RetType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RET_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RET_TYPE } #[inline] @@ -4112,6 +4917,13 @@ impl AstNode for RetType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ReturnExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RETURN_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RETURN_EXPR } #[inline] @@ -4126,6 +4938,13 @@ impl AstNode for ReturnExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for ReturnTypeSyntax { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + RETURN_TYPE_SYNTAX + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == RETURN_TYPE_SYNTAX } #[inline] @@ -4140,6 +4959,13 @@ impl AstNode for ReturnTypeSyntax { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for SelfParam { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + SELF_PARAM + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == SELF_PARAM } #[inline] @@ -4154,6 +4980,13 @@ impl AstNode for SelfParam { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for SlicePat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + SLICE_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == SLICE_PAT } #[inline] @@ -4168,6 +5001,13 @@ impl AstNode for SlicePat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for SliceType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + SLICE_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == SLICE_TYPE } #[inline] @@ -4182,6 +5022,13 @@ impl AstNode for SliceType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for SourceFile { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + SOURCE_FILE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == SOURCE_FILE } #[inline] @@ -4196,6 +5043,13 @@ impl AstNode for SourceFile { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Static { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + STATIC + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == STATIC } #[inline] @@ -4210,6 +5064,13 @@ impl AstNode for Static { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for StmtList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + STMT_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == STMT_LIST } #[inline] @@ -4224,6 +5085,13 @@ impl AstNode for StmtList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Struct { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + STRUCT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == STRUCT } #[inline] @@ -4238,6 +5106,13 @@ impl AstNode for Struct { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TokenTree { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TOKEN_TREE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TOKEN_TREE } #[inline] @@ -4252,6 +5127,13 @@ impl AstNode for TokenTree { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Trait { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TRAIT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TRAIT } #[inline] @@ -4266,6 +5148,13 @@ impl AstNode for Trait { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TraitAlias { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TRAIT_ALIAS + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TRAIT_ALIAS } #[inline] @@ -4280,6 +5169,13 @@ impl AstNode for TraitAlias { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TryExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TRY_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TRY_EXPR } #[inline] @@ -4294,6 +5190,13 @@ impl AstNode for TryExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TupleExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TUPLE_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_EXPR } #[inline] @@ -4308,6 +5211,13 @@ impl AstNode for TupleExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TupleField { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TUPLE_FIELD + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_FIELD } #[inline] @@ -4322,6 +5232,13 @@ impl AstNode for TupleField { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TupleFieldList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TUPLE_FIELD_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_FIELD_LIST } #[inline] @@ -4336,6 +5253,13 @@ impl AstNode for TupleFieldList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TuplePat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TUPLE_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_PAT } #[inline] @@ -4350,6 +5274,13 @@ impl AstNode for TuplePat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TupleStructPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TUPLE_STRUCT_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_STRUCT_PAT } #[inline] @@ -4364,6 +5295,13 @@ impl AstNode for TupleStructPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TupleType { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TUPLE_TYPE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_TYPE } #[inline] @@ -4378,6 +5316,13 @@ impl AstNode for TupleType { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TypeAlias { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TYPE_ALIAS + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ALIAS } #[inline] @@ -4392,6 +5337,13 @@ impl AstNode for TypeAlias { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TypeArg { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TYPE_ARG + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ARG } #[inline] @@ -4406,6 +5358,13 @@ impl AstNode for TypeArg { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TypeBound { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TYPE_BOUND + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND } #[inline] @@ -4420,6 +5379,13 @@ impl AstNode for TypeBound { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TypeBoundList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TYPE_BOUND_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND_LIST } #[inline] @@ -4434,6 +5400,13 @@ impl AstNode for TypeBoundList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for TypeParam { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + TYPE_PARAM + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_PARAM } #[inline] @@ -4448,6 +5421,13 @@ impl AstNode for TypeParam { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for UnderscoreExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + UNDERSCORE_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == UNDERSCORE_EXPR } #[inline] @@ -4462,6 +5442,13 @@ impl AstNode for UnderscoreExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Union { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + UNION + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == UNION } #[inline] @@ -4476,6 +5463,13 @@ impl AstNode for Union { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Use { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + USE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == USE } #[inline] @@ -4490,6 +5484,13 @@ impl AstNode for Use { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for UseBoundGenericArgs { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + USE_BOUND_GENERIC_ARGS + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == USE_BOUND_GENERIC_ARGS } #[inline] @@ -4504,6 +5505,13 @@ impl AstNode for UseBoundGenericArgs { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for UseTree { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + USE_TREE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE } #[inline] @@ -4518,6 +5526,13 @@ impl AstNode for UseTree { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for UseTreeList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + USE_TREE_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE_LIST } #[inline] @@ -4532,6 +5547,13 @@ impl AstNode for UseTreeList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Variant { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + VARIANT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == VARIANT } #[inline] @@ -4546,6 +5568,13 @@ impl AstNode for Variant { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for VariantList { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + VARIANT_LIST + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == VARIANT_LIST } #[inline] @@ -4560,6 +5589,13 @@ impl AstNode for VariantList { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for Visibility { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + VISIBILITY + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == VISIBILITY } #[inline] @@ -4574,6 +5610,13 @@ impl AstNode for Visibility { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for WhereClause { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + WHERE_CLAUSE + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == WHERE_CLAUSE } #[inline] @@ -4588,6 +5631,13 @@ impl AstNode for WhereClause { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for WherePred { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + WHERE_PRED + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == WHERE_PRED } #[inline] @@ -4602,6 +5652,13 @@ impl AstNode for WherePred { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for WhileExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + WHILE_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == WHILE_EXPR } #[inline] @@ -4616,6 +5673,13 @@ impl AstNode for WhileExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for WildcardPat { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + WILDCARD_PAT + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == WILDCARD_PAT } #[inline] @@ -4630,6 +5694,13 @@ impl AstNode for WildcardPat { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for YeetExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + YEET_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == YEET_EXPR } #[inline] @@ -4644,6 +5715,13 @@ impl AstNode for YeetExpr { fn syntax(&self) -> &SyntaxNode { &self.syntax } } impl AstNode for YieldExpr { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized, + { + YIELD_EXPR + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == YIELD_EXPR } #[inline] diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs index e7534582f2b4..d39231f1c28d 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs @@ -162,6 +162,13 @@ fn generate_nodes(kinds: KindsSrc, grammar: &AstSrc) -> String { }, quote! { impl AstNode for #name { + #[inline] + fn kind() -> SyntaxKind + where + Self: Sized + { + #kind + } #[inline] fn can_cast(kind: SyntaxKind) -> bool { kind == #kind From be12c80d23404c59cfbe80529f6f466637619140 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 30 Dec 2024 03:54:53 +0200 Subject: [PATCH 2/4] Add a function to convert a SyntaxKind to its text, where possible This will also help for the make's quote macro. --- .../parser/src/syntax_kind/generated.rs | 325 ++++++++++++++++++ .../xtask/src/codegen/grammar.rs | 16 + 2 files changed, 341 insertions(+) diff --git a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs index 0c9c6ffd715e..318f71a2d4df 100644 --- a/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs +++ b/src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs @@ -331,6 +331,331 @@ pub enum SyntaxKind { } use self::SyntaxKind::*; impl SyntaxKind { + #[allow(unreachable_patterns)] + pub const fn text(self) -> &'static str { + match self { + TOMBSTONE + | EOF + | __LAST + | BYTE + | BYTE_STRING + | CHAR + | C_STRING + | FLOAT_NUMBER + | INT_NUMBER + | RAW_BYTE_STRING + | RAW_C_STRING + | RAW_STRING + | STRING + | ABI + | ADT + | ARG_LIST + | ARRAY_EXPR + | ARRAY_TYPE + | ASM_CLOBBER_ABI + | ASM_CONST + | ASM_DIR_SPEC + | ASM_EXPR + | ASM_LABEL + | ASM_OPERAND + | ASM_OPERAND_EXPR + | ASM_OPERAND_NAMED + | ASM_OPTION + | ASM_OPTIONS + | ASM_PIECE + | ASM_REG_OPERAND + | ASM_REG_SPEC + | ASM_SYM + | ASSOC_ITEM + | ASSOC_ITEM_LIST + | ASSOC_TYPE_ARG + | ATTR + | AWAIT_EXPR + | BECOME_EXPR + | BIN_EXPR + | BLOCK_EXPR + | BOX_PAT + | BREAK_EXPR + | CALL_EXPR + | CAST_EXPR + | CLOSURE_BINDER + | CLOSURE_EXPR + | CONST + | CONST_ARG + | CONST_BLOCK_PAT + | CONST_PARAM + | CONTINUE_EXPR + | DYN_TRAIT_TYPE + | ENUM + | EXPR + | EXPR_STMT + | EXTERN_BLOCK + | EXTERN_CRATE + | EXTERN_ITEM + | EXTERN_ITEM_LIST + | FIELD_EXPR + | FIELD_LIST + | FN + | FN_PTR_TYPE + | FORMAT_ARGS_ARG + | FORMAT_ARGS_EXPR + | FOR_EXPR + | FOR_TYPE + | GENERIC_ARG + | GENERIC_ARG_LIST + | GENERIC_PARAM + | GENERIC_PARAM_LIST + | IDENT_PAT + | IF_EXPR + | IMPL + | IMPL_TRAIT_TYPE + | INDEX_EXPR + | INFER_TYPE + | ITEM + | ITEM_LIST + | LABEL + | LET_ELSE + | LET_EXPR + | LET_STMT + | LIFETIME + | LIFETIME_ARG + | LIFETIME_PARAM + | LITERAL + | LITERAL_PAT + | LOOP_EXPR + | MACRO_CALL + | MACRO_DEF + | MACRO_EXPR + | MACRO_ITEMS + | MACRO_PAT + | MACRO_RULES + | MACRO_STMTS + | MACRO_TYPE + | MATCH_ARM + | MATCH_ARM_LIST + | MATCH_EXPR + | MATCH_GUARD + | META + | METHOD_CALL_EXPR + | MODULE + | NAME + | NAME_REF + | NEVER_TYPE + | OFFSET_OF_EXPR + | OR_PAT + | PARAM + | PARAM_LIST + | PARENTHESIZED_ARG_LIST + | PAREN_EXPR + | PAREN_PAT + | PAREN_TYPE + | PAT + | PATH + | PATH_EXPR + | PATH_PAT + | PATH_SEGMENT + | PATH_TYPE + | PREFIX_EXPR + | PTR_TYPE + | RANGE_EXPR + | RANGE_PAT + | RECORD_EXPR + | RECORD_EXPR_FIELD + | RECORD_EXPR_FIELD_LIST + | RECORD_FIELD + | RECORD_FIELD_LIST + | RECORD_PAT + | RECORD_PAT_FIELD + | RECORD_PAT_FIELD_LIST + | REF_EXPR + | REF_PAT + | REF_TYPE + | RENAME + | REST_PAT + | RETURN_EXPR + | RETURN_TYPE_SYNTAX + | RET_TYPE + | SELF_PARAM + | SLICE_PAT + | SLICE_TYPE + | SOURCE_FILE + | STATIC + | STMT + | STMT_LIST + | STRUCT + | TOKEN_TREE + | TRAIT + | TRAIT_ALIAS + | TRY_EXPR + | TUPLE_EXPR + | TUPLE_FIELD + | TUPLE_FIELD_LIST + | TUPLE_PAT + | TUPLE_STRUCT_PAT + | TUPLE_TYPE + | TYPE + | TYPE_ALIAS + | TYPE_ARG + | TYPE_BOUND + | TYPE_BOUND_LIST + | TYPE_PARAM + | UNDERSCORE_EXPR + | UNION + | USE + | USE_BOUND_GENERIC_ARG + | USE_BOUND_GENERIC_ARGS + | USE_TREE + | USE_TREE_LIST + | VARIANT + | VARIANT_LIST + | VISIBILITY + | WHERE_CLAUSE + | WHERE_PRED + | WHILE_EXPR + | WILDCARD_PAT + | YEET_EXPR + | YIELD_EXPR + | COMMENT + | ERROR + | IDENT + | LIFETIME_IDENT + | NEWLINE + | SHEBANG + | WHITESPACE => panic!("no text for these `SyntaxKind`s"), + DOLLAR => "$", + SEMICOLON => ";", + COMMA => ",", + L_PAREN => "(", + R_PAREN => ")", + L_CURLY => "{", + R_CURLY => "}", + L_BRACK => "[", + R_BRACK => "]", + L_ANGLE => "<", + R_ANGLE => ">", + AT => "@", + POUND => "#", + TILDE => "~", + QUESTION => "?", + AMP => "&", + PIPE => "|", + PLUS => "+", + STAR => "*", + SLASH => "/", + CARET => "^", + PERCENT => "%", + UNDERSCORE => "_", + DOT => ".", + DOT2 => "..", + DOT3 => "...", + DOT2EQ => "..=", + COLON => ":", + COLON2 => "::", + EQ => "=", + EQ2 => "==", + FAT_ARROW => "=>", + BANG => "!", + NEQ => "!=", + MINUS => "-", + THIN_ARROW => "->", + LTEQ => "<=", + GTEQ => ">=", + PLUSEQ => "+=", + MINUSEQ => "-=", + PIPEEQ => "|=", + AMPEQ => "&=", + CARETEQ => "^=", + SLASHEQ => "/=", + STAREQ => "*=", + PERCENTEQ => "%=", + AMP2 => "&&", + PIPE2 => "||", + SHL => "<<", + SHR => ">>", + SHLEQ => "<<=", + SHREQ => ">>=", + SELF_TYPE_KW => "Self", + ABSTRACT_KW => "abstract", + AS_KW => "as", + BECOME_KW => "become", + BOX_KW => "box", + BREAK_KW => "break", + CONST_KW => "const", + CONTINUE_KW => "continue", + CRATE_KW => "crate", + DO_KW => "do", + ELSE_KW => "else", + ENUM_KW => "enum", + EXTERN_KW => "extern", + FALSE_KW => "false", + FINAL_KW => "final", + FN_KW => "fn", + FOR_KW => "for", + IF_KW => "if", + IMPL_KW => "impl", + IN_KW => "in", + LET_KW => "let", + LOOP_KW => "loop", + MACRO_KW => "macro", + MATCH_KW => "match", + MOD_KW => "mod", + MOVE_KW => "move", + MUT_KW => "mut", + OVERRIDE_KW => "override", + PRIV_KW => "priv", + PUB_KW => "pub", + REF_KW => "ref", + RETURN_KW => "return", + SELF_KW => "self", + STATIC_KW => "static", + STRUCT_KW => "struct", + SUPER_KW => "super", + TRAIT_KW => "trait", + TRUE_KW => "true", + TYPE_KW => "type", + TYPEOF_KW => "typeof", + UNSAFE_KW => "unsafe", + UNSIZED_KW => "unsized", + USE_KW => "use", + VIRTUAL_KW => "virtual", + WHERE_KW => "where", + WHILE_KW => "while", + YIELD_KW => "yield", + ASM_KW => "asm", + ATT_SYNTAX_KW => "att_syntax", + AUTO_KW => "auto", + BUILTIN_KW => "builtin", + CLOBBER_ABI_KW => "clobber_abi", + DEFAULT_KW => "default", + DYN_KW => "dyn", + FORMAT_ARGS_KW => "format_args", + INLATEOUT_KW => "inlateout", + INOUT_KW => "inout", + LABEL_KW => "label", + LATEOUT_KW => "lateout", + MACRO_RULES_KW => "macro_rules", + MAY_UNWIND_KW => "may_unwind", + NOMEM_KW => "nomem", + NORETURN_KW => "noreturn", + NOSTACK_KW => "nostack", + OFFSET_OF_KW => "offset_of", + OPTIONS_KW => "options", + OUT_KW => "out", + PRESERVES_FLAGS_KW => "preserves_flags", + PURE_KW => "pure", + RAW_KW => "raw", + READONLY_KW => "readonly", + SAFE_KW => "safe", + SYM_KW => "sym", + UNION_KW => "union", + YEET_KW => "yeet", + ASYNC_KW => "async", + AWAIT_KW => "await", + DYN_KW => "dyn", + GEN_KW => "gen", + TRY_KW => "try", + } + } #[doc = r" Checks whether this syntax kind is a strict keyword for the given edition."] #[doc = r" Strict keywords are identifiers that are always considered keywords."] pub fn is_strict_keyword(self, edition: Edition) -> bool { diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs index d39231f1c28d..035891dcbeef 100644 --- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs +++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs @@ -404,6 +404,7 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String { }); let punctuation = grammar.punct.iter().map(|(_token, name)| format_ident!("{}", name)).collect::>(); + let punctuation_texts = grammar.punct.iter().map(|&(text, _name)| text); let fmt_kw_as_variant = |&name| match name { "Self" => format_ident!("SELF_TYPE_KW"), @@ -429,6 +430,7 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String { quote! { #kw if #ed <= edition } }) .collect::>(); + let edition_dependent_keywords = grammar.edition_dependent_keywords.iter().map(|&(it, _)| it); let edition_dependent_keywords_variants = grammar .edition_dependent_keywords .iter() @@ -502,6 +504,20 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String { use self::SyntaxKind::*; impl SyntaxKind { + #[allow(unreachable_patterns)] + pub const fn text(self) -> &'static str { + match self { + TOMBSTONE | EOF | __LAST + #( | #literals )* + #( | #nodes )* + #( | #tokens )* => panic!("no text for these `SyntaxKind`s"), + #( #punctuation => #punctuation_texts ,)* + #( #strict_keywords_variants => #strict_keywords ,)* + #( #contextual_keywords_variants => #contextual_keywords ,)* + #( #edition_dependent_keywords_variants => #edition_dependent_keywords ,)* + } + } + /// Checks whether this syntax kind is a strict keyword for the given edition. /// Strict keywords are identifiers that are always considered keywords. pub fn is_strict_keyword(self, edition: Edition) -> bool { From a0c052fa57083031234f35462fbee5026413fd8d Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 30 Dec 2024 04:54:39 +0200 Subject: [PATCH 3/4] Create a `quote!`-like API for crafting AST nodes Instead of messing with textual `make`. And port one `make` helper to it, for the sake of testing. --- .../crates/syntax/src/ast/make.rs | 21 ++- .../crates/syntax/src/ast/make/quote.rs | 170 ++++++++++++++++++ 2 files changed, 182 insertions(+), 9 deletions(-) create mode 100644 src/tools/rust-analyzer/crates/syntax/src/ast/make/quote.rs diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index eb96ab6ef590..059028bea823 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -10,13 +10,15 @@ //! `parse(format!())` we use internally is an implementation detail -- long //! term, it will be replaced with direct tree manipulation. +mod quote; + use itertools::Itertools; use parser::{Edition, T}; use rowan::NodeOrToken; use stdx::{format_to, format_to_acc, never}; use crate::{ - ast::{self, Param}, + ast::{self, make::quote::quote, Param}, utils::is_raw_identifier, AstNode, SourceFile, SyntaxKind, SyntaxToken, }; @@ -480,15 +482,16 @@ pub fn block_expr( stmts: impl IntoIterator, tail_expr: Option, ) -> ast::BlockExpr { - let mut buf = "{\n".to_owned(); - for stmt in stmts.into_iter() { - format_to!(buf, " {stmt}\n"); + quote! { + BlockExpr { + StmtList { + ['{'] "\n" + #(" " #stmts "\n")* + #(" " #tail_expr "\n")* + ['}'] + } + } } - if let Some(tail_expr) = tail_expr { - format_to!(buf, " {tail_expr}\n"); - } - buf += "}"; - ast_from_text(&format!("fn f() {buf}")) } pub fn async_move_block_expr( diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make/quote.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make/quote.rs new file mode 100644 index 000000000000..1c66a413f87a --- /dev/null +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make/quote.rs @@ -0,0 +1,170 @@ +//! A `quote!`-like API for crafting AST nodes. + +pub(crate) use rowan::{GreenNode, GreenToken, NodeOrToken, SyntaxKind as RSyntaxKind}; + +macro_rules! quote_impl_ { + ( @append $children:ident ) => {}; // Base case. + + ( @append $children:ident + $node:ident { + $($tree:tt)* + } + $($rest:tt)* + ) => { + { + #[allow(unused_mut)] + let mut inner_children = ::std::vec::Vec::<$crate::ast::make::quote::NodeOrToken< + $crate::ast::make::quote::GreenNode, + $crate::ast::make::quote::GreenToken, + >>::new(); + $crate::ast::make::quote::quote_impl!( @append inner_children + $($tree)* + ); + let kind = <$crate::ast::$node as $crate::ast::AstNode>::kind(); + let node = $crate::ast::make::quote::GreenNode::new($crate::ast::make::quote::RSyntaxKind(kind as u16), inner_children); + $children.push($crate::ast::make::quote::NodeOrToken::Node(node)); + } + $crate::ast::make::quote::quote_impl!( @append $children $($rest)* ); + }; + + ( @append $children:ident + [$($token:tt)+] + $($rest:tt)* + ) => { + $children.push($crate::ast::make::quote::NodeOrToken::Token( + $crate::ast::make::quote::GreenToken::new( + $crate::ast::make::quote::RSyntaxKind($crate::T![ $($token)+ ] as u16), + const { $crate::T![ $($token)+ ].text() }, + ), + )); + $crate::ast::make::quote::quote_impl!( @append $children $($rest)* ); + }; + + ( @append $children:ident + $whitespace:literal + $($rest:tt)* + ) => { + const { $crate::ast::make::quote::verify_only_whitespaces($whitespace) }; + $children.push($crate::ast::make::quote::NodeOrToken::Token( + $crate::ast::make::quote::GreenToken::new( + $crate::ast::make::quote::RSyntaxKind($crate::SyntaxKind::WHITESPACE as u16), + $whitespace, + ), + )); + $crate::ast::make::quote::quote_impl!( @append $children $($rest)* ); + }; + + ( @append $children:ident + # $var:ident + $($rest:tt)* + ) => { + $crate::ast::make::quote::ToNodeChild::append_node_child($var, &mut $children); + $crate::ast::make::quote::quote_impl!( @append $children $($rest)* ); + }; + + ( @append $children:ident + #( $($repetition:tt)+ )* + $($rest:tt)* + ) => { + $crate::ast::make::quote::quote_impl!( @extract_pounded_in_repetition $children + [] [] $($repetition)* + ); + $crate::ast::make::quote::quote_impl!( @append $children $($rest)* ); + }; + + // Base case - no repetition var. + ( @extract_pounded_in_repetition $children:ident + [ $($repetition:tt)* ] [ ] + ) => { + ::std::compile_error!("repetition in `ast::make::quote!()` without variable"); + }; + + // Base case - repetition var found. + ( @extract_pounded_in_repetition $children:ident + [ $($repetition:tt)* ] [ $repetition_var:ident ] + ) => { + ::std::iter::IntoIterator::into_iter($repetition_var).for_each(|$repetition_var| { + $crate::ast::make::quote::quote_impl!( @append $children $($repetition)* ); + }); + }; + + ( @extract_pounded_in_repetition $children:ident + [ $($repetition:tt)* ] [ $repetition_var1:ident ] # $repetition_var2:ident $($rest:tt)* + ) => { + ::std::compile_error!("repetition in `ast::make::quote!()` with more than one variable"); + }; + + ( @extract_pounded_in_repetition $children:ident + [ $($repetition:tt)* ] [ ] # $repetition_var:ident $($rest:tt)* + ) => { + $crate::ast::make::quote::quote_impl!( @extract_pounded_in_repetition $children + [ $($repetition)* # $repetition_var ] [ $repetition_var ] $($rest)* + ); + }; + + ( @extract_pounded_in_repetition $children:ident + [ $($repetition:tt)* ] [ $($repetition_var:tt)* ] $non_repetition_var:tt $($rest:tt)* + ) => { + $crate::ast::make::quote::quote_impl!( @extract_pounded_in_repetition $children + [ $($repetition)* $non_repetition_var ] [ $($repetition_var)* ] $($rest)* + ); + }; +} +pub(crate) use quote_impl_ as quote_impl; + +/// A `quote!`-like API for crafting AST nodes. +/// +/// Syntax: AST nodes are created with `Node { children }`, where `Node` is the node name in `ast` (`ast::Node`). +/// Tokens are creates with their syntax enclosed by brackets, e.g. `[::]` or `['{']`. Whitespaces can be added +/// as string literals (i.e. `"\n "` is a whitespace token). Interpolation is allowed with `#` (`#variable`), +/// from `AstNode`s and `Option`s of them. Repetition is also supported, with only one repeating variable +/// and no separator (`#("\n" #variable [>])*`), for any `IntoIterator`. Note that `Option`s are also `IntoIterator`, +/// which can help when you want to conditionally include something along with an optional node. +/// +/// There needs to be one root node, and its type is returned. +/// +/// Be careful to closely match the Ungrammar AST, there is no validation for this! +macro_rules! quote_ { + ( $root:ident { $($tree:tt)* } ) => {{ + let mut root = ::std::vec::Vec::<$crate::ast::make::quote::NodeOrToken< + $crate::ast::make::quote::GreenNode, + $crate::ast::make::quote::GreenToken, + >>::with_capacity(1); + $crate::ast::make::quote::quote_impl!( @append root $root { $($tree)* } ); + let root = root.into_iter().next().unwrap(); + let root = $crate::SyntaxNode::new_root(root.into_node().unwrap()); + <$crate::ast::$root as $crate::ast::AstNode>::cast(root).unwrap() + }}; +} +pub(crate) use quote_ as quote; + +use crate::AstNode; + +pub(crate) trait ToNodeChild { + fn append_node_child(self, children: &mut Vec>); +} + +impl ToNodeChild for N { + fn append_node_child(self, children: &mut Vec>) { + children.push(self.syntax().clone_subtree().green().to_owned().into()); + } +} + +impl ToNodeChild for Option { + fn append_node_child(self, children: &mut Vec>) { + if let Some(child) = self { + child.append_node_child(children); + } + } +} + +pub(crate) const fn verify_only_whitespaces(text: &str) { + let text = text.as_bytes(); + let mut i = 0; + while i < text.len() { + if !text[i].is_ascii_whitespace() { + panic!("non-whitespace found in whitespace token"); + } + i += 1; + } +} From 33f1f1d787f9f3a41a1983219d27d24f741c9fb1 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Mon, 30 Dec 2024 05:46:06 +0200 Subject: [PATCH 4/4] Move some more AST makers to the quote macro And implement addons as necessary. There are many more makers to be moved, and I'm not completely satisfied with this (due to the ease of making a mistake in the AST structure, and slightly less but also because of the need to remember whitespaces), but this is already enough to see how this will look like. --- src/tools/rust-analyzer/Cargo.toml | 2 + .../src/handlers/generate_fn_type_alias.rs | 1 - .../crates/syntax/src/ast/make.rs | 83 ++++++++----------- .../crates/syntax/src/ast/make/quote.rs | 25 +++++- 4 files changed, 58 insertions(+), 53 deletions(-) diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index 7f3abcccc472..e303b3c11092 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -203,6 +203,8 @@ new_ret_no_self = "allow" useless_asref = "allow" # Has false positives assigning_clones = "allow" +# Does not work with macros +vec_init_then_push = "allow" ## Following lints should be tackled at some point too_many_arguments = "allow" diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs index f4b4c22d98d4..9d01ec00f836 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_fn_type_alias.rs @@ -85,7 +85,6 @@ pub(crate) fn generate_fn_type_alias(acc: &mut Assists, ctx: &AssistContext<'_>) let is_unsafe = func_node.unsafe_token().is_some(); let ty = make::ty_fn_ptr( - None, is_unsafe, func_node.abi(), fn_params_vec.into_iter(), diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs index 059028bea823..76b39c3b73f3 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs @@ -8,7 +8,8 @@ //! Keep in mind that `from_text` functions should be kept private. The public //! API should require to assemble every node piecewise. The trick of //! `parse(format!())` we use internally is an implementation detail -- long -//! term, it will be replaced with direct tree manipulation. +//! term, it will be replaced with `quote!`. Do not add more usages to `from_text` - +//! use `quote!` instead. mod quote; @@ -120,7 +121,11 @@ pub fn name(name: &str) -> ast::Name { } pub fn name_ref(name_ref: &str) -> ast::NameRef { let raw_escape = raw_ident_esc(name_ref); - ast_from_text(&format!("fn f() {{ {raw_escape}{name_ref}; }}")) + quote! { + NameRef { + [IDENT format!("{raw_escape}{name_ref}")] + } + } } fn raw_ident_esc(ident: &str) -> &'static str { if is_raw_identifier(ident, Edition::CURRENT) { @@ -137,7 +142,11 @@ pub fn lifetime(text: &str) -> ast::Lifetime { tmp = format!("'{text}"); text = &tmp; } - ast_from_text(&format!("fn f<{text}>() {{ }}")) + quote! { + Lifetime { + [LIFETIME_IDENT text] + } + } } // FIXME: replace stringly-typed constructor with a family of typed ctors, a-la @@ -177,63 +186,37 @@ pub fn ty_alias( where_clause: Option, assignment: Option<(ast::Type, Option)>, ) -> ast::TypeAlias { - let mut s = String::new(); - s.push_str(&format!("type {ident}")); - - if let Some(list) = generic_param_list { - s.push_str(&list.to_string()); - } - - if let Some(list) = type_param_bounds { - s.push_str(&format!(" : {list}")); - } - - if let Some(cl) = where_clause { - s.push_str(&format!(" {cl}")); - } - - if let Some(exp) = assignment { - if let Some(cl) = exp.1 { - s.push_str(&format!(" = {} {cl}", exp.0)); - } else { - s.push_str(&format!(" = {}", exp.0)); + let (assignment_ty, assignment_where) = assignment.unzip(); + let assignment_where = assignment_where.flatten(); + quote! { + TypeAlias { + [type] " " + Name { [IDENT ident] } + #generic_param_list + #(" " [:] " " #type_param_bounds)* + #(" " #where_clause)* + #(" " [=] " " #assignment_ty)* + #(" " #assignment_where)* + [;] } } - - s.push(';'); - ast_from_text(&s) } pub fn ty_fn_ptr>( - for_lifetime_list: Option, is_unsafe: bool, abi: Option, - params: I, + mut params: I, ret_type: Option, ) -> ast::FnPtrType { - let mut s = String::from("type __ = "); - - if let Some(list) = for_lifetime_list { - format_to!(s, "for{} ", list); + let is_unsafe = is_unsafe.then_some(()); + let first_param = params.next(); + quote! { + FnPtrType { + #(#is_unsafe [unsafe] " ")* #(#abi " ")* [fn] + ['('] #first_param #([,] " " #params)* [')'] + #(" " #ret_type)* + } } - - if is_unsafe { - s.push_str("unsafe "); - } - - if let Some(abi) = abi { - format_to!(s, "{} ", abi) - } - - s.push_str("fn"); - - format_to!(s, "({})", params.map(|p| p.to_string()).join(", ")); - - if let Some(ret_type) = ret_type { - format_to!(s, " {}", ret_type); - } - - ast_from_text(&s) } pub fn assoc_item_list() -> ast::AssocItemList { diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make/quote.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make/quote.rs index 1c66a413f87a..300ef25c137c 100644 --- a/src/tools/rust-analyzer/crates/syntax/src/ast/make/quote.rs +++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make/quote.rs @@ -27,6 +27,19 @@ macro_rules! quote_impl_ { $crate::ast::make::quote::quote_impl!( @append $children $($rest)* ); }; + ( @append $children:ident + [ $token_kind:ident $token_text:expr ] + $($rest:tt)* + ) => { + $children.push($crate::ast::make::quote::NodeOrToken::Token( + $crate::ast::make::quote::GreenToken::new( + $crate::ast::make::quote::RSyntaxKind($crate::SyntaxKind::$token_kind as u16), + &$token_text, + ), + )); + $crate::ast::make::quote::quote_impl!( @append $children $($rest)* ); + }; + ( @append $children:ident [$($token:tt)+] $($rest:tt)* @@ -115,7 +128,9 @@ pub(crate) use quote_impl_ as quote_impl; /// A `quote!`-like API for crafting AST nodes. /// /// Syntax: AST nodes are created with `Node { children }`, where `Node` is the node name in `ast` (`ast::Node`). -/// Tokens are creates with their syntax enclosed by brackets, e.g. `[::]` or `['{']`. Whitespaces can be added +/// Tokens are creates with their syntax enclosed by brackets, e.g. `[::]` or `['{']`. Alternatively, tokens can +/// be created with the syntax `[token_kind token_text]`, where `token_kind` is a variant of `SyntaxKind` (e.g. +/// `IDENT`) and `token_text` is an expression producing `String` or `&str`. Whitespaces can be added /// as string literals (i.e. `"\n "` is a whitespace token). Interpolation is allowed with `#` (`#variable`), /// from `AstNode`s and `Option`s of them. Repetition is also supported, with only one repeating variable /// and no separator (`#("\n" #variable [>])*`), for any `IntoIterator`. Note that `Option`s are also `IntoIterator`, @@ -126,6 +141,7 @@ pub(crate) use quote_impl_ as quote_impl; /// Be careful to closely match the Ungrammar AST, there is no validation for this! macro_rules! quote_ { ( $root:ident { $($tree:tt)* } ) => {{ + #[allow(unused_mut)] let mut root = ::std::vec::Vec::<$crate::ast::make::quote::NodeOrToken< $crate::ast::make::quote::GreenNode, $crate::ast::make::quote::GreenToken, @@ -146,7 +162,7 @@ pub(crate) trait ToNodeChild { impl ToNodeChild for N { fn append_node_child(self, children: &mut Vec>) { - children.push(self.syntax().clone_subtree().green().to_owned().into()); + children.push((*self.syntax().clone_subtree().green()).to_owned().into()); } } @@ -158,6 +174,11 @@ impl ToNodeChild for Option { } } +// This is useful when you want conditionally, based on some `bool`, to emit some code. +impl ToNodeChild for () { + fn append_node_child(self, _children: &mut Vec>) {} +} + pub(crate) const fn verify_only_whitespaces(text: &str) { let text = text.as_bytes(); let mut i = 0;