about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2025-03-21 10:26:36 +0100
committerLukas Wirth <lukastw97@gmail.com>2025-03-21 12:14:39 +0100
commit3f7fc4dff24d0cb2af26f632f51d5702c508fad0 (patch)
tree9fa5f77439d2a4987b88b687c0f1412074e4e86e
parent7e1610e723f121a1bea229568d1aa2be42d62176 (diff)
downloadrust-3f7fc4dff24d0cb2af26f632f51d5702c508fad0.tar.gz
rust-3f7fc4dff24d0cb2af26f632f51d5702c508fad0.zip
refactor: Reduce codegen burden for `SyntaxKind`
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs59
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen.rs2
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen/grammar.rs37
-rw-r--r--src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs12
6 files changed, 76 insertions, 38 deletions
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
index fb25f001558..0d3d99994f6 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
@@ -852,7 +852,7 @@ fn highlight_name_ref_by_syntax(
             }
         }
         ASSOC_TYPE_ARG => SymbolKind::TypeAlias.into(),
-        USE_BOUND_GENERIC_ARG => SymbolKind::TypeParam.into(),
+        USE_BOUND_GENERIC_ARGS => SymbolKind::TypeParam.into(),
         _ => default.into(),
     }
 }
diff --git a/src/tools/rust-analyzer/crates/parser/src/lib.rs b/src/tools/rust-analyzer/crates/parser/src/lib.rs
index 398ad7cf66c..7963f00bb25 100644
--- a/src/tools/rust-analyzer/crates/parser/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/lib.rs
@@ -35,6 +35,8 @@ mod shortcuts;
 mod syntax_kind;
 mod token_set;
 
+pub use T_ as T;
+
 #[cfg(test)]
 mod tests;
 
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 1ff0bbea8b1..8836bddc9bb 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
@@ -3,7 +3,7 @@
 #![allow(bad_style, missing_docs, unreachable_pub)]
 use crate::Edition;
 #[doc = r" The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT`."]
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+#[derive(Debug)]
 #[repr(u16)]
 pub enum SyntaxKind {
     #[doc(hidden)]
@@ -156,7 +156,6 @@ pub enum SyntaxKind {
     SHEBANG,
     WHITESPACE,
     ABI,
-    ADT,
     ARG_LIST,
     ARRAY_EXPR,
     ARRAY_TYPE,
@@ -165,16 +164,13 @@ pub enum SyntaxKind {
     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,
@@ -195,23 +191,18 @@ pub enum SyntaxKind {
     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,
@@ -219,7 +210,6 @@ pub enum SyntaxKind {
     IMPL_TRAIT_TYPE,
     INDEX_EXPR,
     INFER_TYPE,
-    ITEM,
     ITEM_LIST,
     LABEL,
     LET_ELSE,
@@ -257,7 +247,6 @@ pub enum SyntaxKind {
     PAREN_EXPR,
     PAREN_PAT,
     PAREN_TYPE,
-    PAT,
     PATH,
     PATH_EXPR,
     PATH_PAT,
@@ -288,7 +277,6 @@ pub enum SyntaxKind {
     SLICE_TYPE,
     SOURCE_FILE,
     STATIC,
-    STMT,
     STMT_LIST,
     STRUCT,
     TOKEN_TREE,
@@ -301,7 +289,6 @@ pub enum SyntaxKind {
     TUPLE_PAT,
     TUPLE_STRUCT_PAT,
     TUPLE_TYPE,
-    TYPE,
     TYPE_ALIAS,
     TYPE_ARG,
     TYPE_BOUND,
@@ -310,12 +297,10 @@ pub enum SyntaxKind {
     UNDERSCORE_EXPR,
     UNION,
     USE,
-    USE_BOUND_GENERIC_ARG,
     USE_BOUND_GENERIC_ARGS,
     USE_TREE,
     USE_TREE_LIST,
     VARIANT,
-    VARIANT_DEF,
     VARIANT_LIST,
     VISIBILITY,
     WHERE_CLAUSE,
@@ -343,7 +328,6 @@ impl SyntaxKind {
             | INT_NUMBER
             | STRING
             | ABI
-            | ADT
             | ARG_LIST
             | ARRAY_EXPR
             | ARRAY_TYPE
@@ -352,16 +336,13 @@ impl SyntaxKind {
             | 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
@@ -382,23 +363,18 @@ impl SyntaxKind {
             | 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
@@ -406,7 +382,6 @@ impl SyntaxKind {
             | IMPL_TRAIT_TYPE
             | INDEX_EXPR
             | INFER_TYPE
-            | ITEM
             | ITEM_LIST
             | LABEL
             | LET_ELSE
@@ -444,7 +419,6 @@ impl SyntaxKind {
             | PAREN_EXPR
             | PAREN_PAT
             | PAREN_TYPE
-            | PAT
             | PATH
             | PATH_EXPR
             | PATH_PAT
@@ -475,7 +449,6 @@ impl SyntaxKind {
             | SLICE_TYPE
             | SOURCE_FILE
             | STATIC
-            | STMT
             | STMT_LIST
             | STRUCT
             | TOKEN_TREE
@@ -488,7 +461,6 @@ impl SyntaxKind {
             | TUPLE_PAT
             | TUPLE_STRUCT_PAT
             | TUPLE_TYPE
-            | TYPE
             | TYPE_ALIAS
             | TYPE_ARG
             | TYPE_BOUND
@@ -497,12 +469,10 @@ impl SyntaxKind {
             | UNDERSCORE_EXPR
             | UNION
             | USE
-            | USE_BOUND_GENERIC_ARG
             | USE_BOUND_GENERIC_ARGS
             | USE_TREE
             | USE_TREE_LIST
             | VARIANT
-            | VARIANT_DEF
             | VARIANT_LIST
             | VISIBILITY
             | WHERE_CLAUSE
@@ -1024,4 +994,29 @@ impl SyntaxKind {
     }
 }
 #[macro_export]
-macro_rules ! T { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW } ; [inout] => { $ crate :: SyntaxKind :: INOUT_KW } ; [label] => { $ crate :: SyntaxKind :: LABEL_KW } ; [lateout] => { $ crate :: SyntaxKind :: LATEOUT_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [may_unwind] => { $ crate :: SyntaxKind :: MAY_UNWIND_KW } ; [nomem] => { $ crate :: SyntaxKind :: NOMEM_KW } ; [noreturn] => { $ crate :: SyntaxKind :: NORETURN_KW } ; [nostack] => { $ crate :: SyntaxKind :: NOSTACK_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [options] => { $ crate :: SyntaxKind :: OPTIONS_KW } ; [out] => { $ crate :: SyntaxKind :: OUT_KW } ; [preserves_flags] => { $ crate :: SyntaxKind :: PRESERVES_FLAGS_KW } ; [pure] => { $ crate :: SyntaxKind :: PURE_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [readonly] => { $ crate :: SyntaxKind :: READONLY_KW } ; [safe] => { $ crate :: SyntaxKind :: SAFE_KW } ; [sym] => { $ crate :: SyntaxKind :: SYM_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
+macro_rules ! T_ { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW } ; [inout] => { $ crate :: SyntaxKind :: INOUT_KW } ; [label] => { $ crate :: SyntaxKind :: LABEL_KW } ; [lateout] => { $ crate :: SyntaxKind :: LATEOUT_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [may_unwind] => { $ crate :: SyntaxKind :: MAY_UNWIND_KW } ; [nomem] => { $ crate :: SyntaxKind :: NOMEM_KW } ; [noreturn] => { $ crate :: SyntaxKind :: NORETURN_KW } ; [nostack] => { $ crate :: SyntaxKind :: NOSTACK_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [options] => { $ crate :: SyntaxKind :: OPTIONS_KW } ; [out] => { $ crate :: SyntaxKind :: OUT_KW } ; [preserves_flags] => { $ crate :: SyntaxKind :: PRESERVES_FLAGS_KW } ; [pure] => { $ crate :: SyntaxKind :: PURE_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [readonly] => { $ crate :: SyntaxKind :: READONLY_KW } ; [safe] => { $ crate :: SyntaxKind :: SAFE_KW } ; [sym] => { $ crate :: SyntaxKind :: SYM_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
+impl ::core::marker::Copy for SyntaxKind {}
+impl ::core::clone::Clone for SyntaxKind {
+    #[inline]
+    fn clone(&self) -> Self { *self }
+}
+impl ::core::cmp::PartialEq for SyntaxKind {
+    #[inline]
+    fn eq(&self, other: &Self) -> bool { (*self as u16) == (*other as u16) }
+}
+impl ::core::cmp::Eq for SyntaxKind {}
+impl ::core::cmp::PartialOrd for SyntaxKind {
+    #[inline]
+    fn partial_cmp(&self, other: &Self) -> core::option::Option<core::cmp::Ordering> {
+        (*self as u16).partial_cmp(&(*other as u16))
+    }
+}
+impl ::core::cmp::Ord for SyntaxKind {
+    #[inline]
+    fn cmp(&self, other: &Self) -> core::cmp::Ordering { (*self as u16).cmp(&(*other as u16)) }
+}
+impl ::core::hash::Hash for SyntaxKind {
+    fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
+        ::core::mem::discriminant(self).hash(state);
+    }
+}
diff --git a/src/tools/rust-analyzer/xtask/src/codegen.rs b/src/tools/rust-analyzer/xtask/src/codegen.rs
index 2aff97b6a4e..bba7ad73f38 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen.rs
@@ -21,7 +21,7 @@ impl flags::Codegen {
     pub(crate) fn run(self, _sh: &Shell) -> anyhow::Result<()> {
         match self.codegen_type.unwrap_or_default() {
             flags::CodegenType::All => {
-                diagnostics_docs::generate(self.check);
+                grammar::generate(self.check);
                 assists_doc_tests::generate(self.check);
                 parser_inline_tests::generate(self.check);
                 feature_docs::generate(self.check)
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs
index 839a6f20287..e9f38715852 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar.rs
@@ -476,7 +476,6 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
 
     let tokens = grammar.tokens.iter().map(|name| format_ident!("{}", name)).collect::<Vec<_>>();
 
-    // FIXME: This generates enum kinds?
     let nodes = grammar.nodes.iter().map(|name| format_ident!("{}", name)).collect::<Vec<_>>();
 
     let ast = quote! {
@@ -484,7 +483,7 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
         use crate::Edition;
 
         /// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT`.
-        #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
+        #[derive(Debug)]
         #[repr(u16)]
         pub enum SyntaxKind {
             // Technical SyntaxKinds: they appear temporally during parsing,
@@ -585,7 +584,7 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
         }
 
         #[macro_export]
-        macro_rules! T {
+        macro_rules! T_ {
             #([#punctuation_values] => { $crate::SyntaxKind::#punctuation };)*
             #([#strict_keywords_tokens] => { $crate::SyntaxKind::#strict_keywords_variants };)*
             #([#contextual_keywords_tokens] => { $crate::SyntaxKind::#contextual_keywords_variants };)*
@@ -596,6 +595,38 @@ fn generate_syntax_kinds(grammar: KindsSrc) -> String {
             [string] => { $crate::SyntaxKind::STRING };
             [shebang] => { $crate::SyntaxKind::SHEBANG };
         }
+
+        impl ::core::marker::Copy for SyntaxKind {}
+        impl ::core::clone::Clone for SyntaxKind {
+            #[inline]
+            fn clone(&self) -> Self {
+                *self
+            }
+        }
+        impl ::core::cmp::PartialEq for SyntaxKind {
+            #[inline]
+            fn eq(&self, other: &Self) -> bool {
+                (*self as u16) == (*other as u16)
+            }
+        }
+        impl ::core::cmp::Eq for SyntaxKind {}
+        impl ::core::cmp::PartialOrd for SyntaxKind {
+            #[inline]
+            fn partial_cmp(&self, other: &Self) -> core::option::Option<core::cmp::Ordering> {
+                (*self as u16).partial_cmp(&(*other as u16))
+            }
+        }
+        impl ::core::cmp::Ord for SyntaxKind {
+            #[inline]
+            fn cmp(&self, other: &Self) -> core::cmp::Ordering {
+                (*self as u16).cmp(&(*other as u16))
+            }
+        }
+        impl ::core::hash::Hash for SyntaxKind {
+            fn hash<H: ::core::hash::Hasher>(&self, state: &mut H) {
+                ::core::mem::discriminant(self).hash(state);
+            }
+        }
     };
 
     add_preamble(crate::flags::CodegenType::Grammar, reformat(ast.to_string()))
diff --git a/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs b/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs
index 9269d154235..d8cbf894520 100644
--- a/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs
+++ b/src/tools/rust-analyzer/xtask/src/codegen/grammar/ast_src.rs
@@ -12,6 +12,7 @@ pub(crate) struct KindsSrc {
     pub(crate) literals: &'static [&'static str],
     pub(crate) tokens: &'static [&'static str],
     pub(crate) nodes: &'static [&'static str],
+    pub(crate) _enums: &'static [&'static str],
     pub(crate) edition_dependent_keywords: &'static [(&'static str, Edition)],
 }
 
@@ -206,13 +207,21 @@ pub(crate) fn generate_kind_src(
     let nodes = nodes
         .iter()
         .map(|it| &it.name)
-        .chain(enums.iter().map(|it| &it.name))
         .map(|it| to_upper_snake_case(it))
         .map(String::leak)
         .map(|it| &*it)
         .collect();
     let nodes = Vec::leak(nodes);
     nodes.sort();
+    let enums = enums
+        .iter()
+        .map(|it| &it.name)
+        .map(|it| to_upper_snake_case(it))
+        .map(String::leak)
+        .map(|it| &*it)
+        .collect();
+    let enums = Vec::leak(enums);
+    enums.sort();
     let keywords = Vec::leak(keywords);
     let contextual_keywords = Vec::leak(contextual_keywords);
     let edition_dependent_keywords = Vec::leak(edition_dependent_keywords);
@@ -224,6 +233,7 @@ pub(crate) fn generate_kind_src(
     KindsSrc {
         punct: PUNCT,
         nodes,
+        _enums: enums,
         keywords,
         contextual_keywords,
         edition_dependent_keywords,