about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock22
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs270
-rw-r--r--crates/ra_syntax/src/ast/generated.rs2960
-rw-r--r--crates/ra_syntax/src/grammar.ron730
-rw-r--r--xtask/Cargo.toml2
-rw-r--r--xtask/src/ast_src.rs618
-rw-r--r--xtask/src/codegen.rs1
-rw-r--r--xtask/src/codegen/gen_syntax.rs234
-rw-r--r--xtask/src/lib.rs1
9 files changed, 2328 insertions, 2510 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 65120c362dc..2d1856d99c4 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -59,14 +59,6 @@ dependencies = [
 
 [[package]]
 name = "base64"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "base64"
 version = "0.11.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -1399,16 +1391,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "ron"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
 name = "rowan"
 version = "0.8.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1772,8 +1754,6 @@ dependencies = [
  "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1794,7 +1774,6 @@ dependencies = [
 "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
 "checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
 "checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
-"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
 "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
 "checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
 "checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
@@ -1915,7 +1894,6 @@ dependencies = [
 "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
 "checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954"
 "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
-"checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5"
 "checksum rowan 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3eb10a10a48f0f809a217bcf074b85a03dcf79831bae80e7f1a043d0897463e2"
 "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
 "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index af2945f571e..262c545e4c8 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -61,46 +61,46 @@ pub enum SyntaxKind {
     SHR,
     SHLEQ,
     SHREQ,
+    AS_KW,
     ASYNC_KW,
-    USE_KW,
-    FN_KW,
-    STRUCT_KW,
-    ENUM_KW,
-    TRAIT_KW,
-    IMPL_KW,
+    AWAIT_KW,
+    BOX_KW,
+    BREAK_KW,
+    CONST_KW,
+    CONTINUE_KW,
+    CRATE_KW,
     DYN_KW,
-    TRUE_KW,
-    FALSE_KW,
-    AS_KW,
+    ELSE_KW,
+    ENUM_KW,
     EXTERN_KW,
-    CRATE_KW,
-    MOD_KW,
-    PUB_KW,
-    SELF_KW,
-    SUPER_KW,
-    IN_KW,
-    WHERE_KW,
+    FALSE_KW,
+    FN_KW,
     FOR_KW,
-    LOOP_KW,
-    WHILE_KW,
-    CONTINUE_KW,
-    BREAK_KW,
     IF_KW,
-    ELSE_KW,
+    IMPL_KW,
+    IN_KW,
+    LET_KW,
+    LOOP_KW,
+    MACRO_KW,
     MATCH_KW,
-    CONST_KW,
-    STATIC_KW,
+    MOD_KW,
+    MOVE_KW,
     MUT_KW,
-    UNSAFE_KW,
-    TYPE_KW,
+    PUB_KW,
     REF_KW,
-    LET_KW,
-    MOVE_KW,
     RETURN_KW,
+    SELF_KW,
+    STATIC_KW,
+    STRUCT_KW,
+    SUPER_KW,
+    TRAIT_KW,
+    TRUE_KW,
     TRY_KW,
-    BOX_KW,
-    AWAIT_KW,
-    MACRO_KW,
+    TYPE_KW,
+    UNSAFE_KW,
+    USE_KW,
+    WHERE_KW,
+    WHILE_KW,
     AUTO_KW,
     DEFAULT_KW,
     EXISTENTIAL_KW,
@@ -249,12 +249,12 @@ use self::SyntaxKind::*;
 impl SyntaxKind {
     pub fn is_keyword(self) -> bool {
         match self {
-            ASYNC_KW | USE_KW | FN_KW | STRUCT_KW | ENUM_KW | TRAIT_KW | IMPL_KW | DYN_KW
-            | TRUE_KW | FALSE_KW | AS_KW | EXTERN_KW | CRATE_KW | MOD_KW | PUB_KW | SELF_KW
-            | SUPER_KW | IN_KW | WHERE_KW | FOR_KW | LOOP_KW | WHILE_KW | CONTINUE_KW
-            | BREAK_KW | IF_KW | ELSE_KW | MATCH_KW | CONST_KW | STATIC_KW | MUT_KW | UNSAFE_KW
-            | TYPE_KW | REF_KW | LET_KW | MOVE_KW | RETURN_KW | TRY_KW | BOX_KW | AWAIT_KW
-            | MACRO_KW | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW => true,
+            AS_KW | ASYNC_KW | AWAIT_KW | BOX_KW | BREAK_KW | CONST_KW | CONTINUE_KW | CRATE_KW
+            | DYN_KW | ELSE_KW | ENUM_KW | EXTERN_KW | FALSE_KW | FN_KW | FOR_KW | IF_KW
+            | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW
+            | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | STATIC_KW | STRUCT_KW | SUPER_KW
+            | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW | WHERE_KW | WHILE_KW
+            | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW => true,
             _ => false,
         }
     }
@@ -278,46 +278,46 @@ impl SyntaxKind {
     }
     pub fn from_keyword(ident: &str) -> Option<SyntaxKind> {
         let kw = match ident {
+            "as" => AS_KW,
             "async" => ASYNC_KW,
-            "use" => USE_KW,
-            "fn" => FN_KW,
-            "struct" => STRUCT_KW,
-            "enum" => ENUM_KW,
-            "trait" => TRAIT_KW,
-            "impl" => IMPL_KW,
+            "await" => AWAIT_KW,
+            "box" => BOX_KW,
+            "break" => BREAK_KW,
+            "const" => CONST_KW,
+            "continue" => CONTINUE_KW,
+            "crate" => CRATE_KW,
             "dyn" => DYN_KW,
-            "true" => TRUE_KW,
-            "false" => FALSE_KW,
-            "as" => AS_KW,
+            "else" => ELSE_KW,
+            "enum" => ENUM_KW,
             "extern" => EXTERN_KW,
-            "crate" => CRATE_KW,
-            "mod" => MOD_KW,
-            "pub" => PUB_KW,
-            "self" => SELF_KW,
-            "super" => SUPER_KW,
-            "in" => IN_KW,
-            "where" => WHERE_KW,
+            "false" => FALSE_KW,
+            "fn" => FN_KW,
             "for" => FOR_KW,
-            "loop" => LOOP_KW,
-            "while" => WHILE_KW,
-            "continue" => CONTINUE_KW,
-            "break" => BREAK_KW,
             "if" => IF_KW,
-            "else" => ELSE_KW,
+            "impl" => IMPL_KW,
+            "in" => IN_KW,
+            "let" => LET_KW,
+            "loop" => LOOP_KW,
+            "macro" => MACRO_KW,
             "match" => MATCH_KW,
-            "const" => CONST_KW,
-            "static" => STATIC_KW,
+            "mod" => MOD_KW,
+            "move" => MOVE_KW,
             "mut" => MUT_KW,
-            "unsafe" => UNSAFE_KW,
-            "type" => TYPE_KW,
+            "pub" => PUB_KW,
             "ref" => REF_KW,
-            "let" => LET_KW,
-            "move" => MOVE_KW,
             "return" => RETURN_KW,
+            "self" => SELF_KW,
+            "static" => STATIC_KW,
+            "struct" => STRUCT_KW,
+            "super" => SUPER_KW,
+            "trait" => TRAIT_KW,
+            "true" => TRUE_KW,
             "try" => TRY_KW,
-            "box" => BOX_KW,
-            "await" => AWAIT_KW,
-            "macro" => MACRO_KW,
+            "type" => TYPE_KW,
+            "unsafe" => UNSAFE_KW,
+            "use" => USE_KW,
+            "where" => WHERE_KW,
+            "while" => WHILE_KW,
             _ => return None,
         };
         Some(kw)
@@ -515,125 +515,125 @@ macro_rules! T {
     ( >>= ) => {
         $crate::SyntaxKind::SHREQ
     };
+    ( as ) => {
+        $crate::SyntaxKind::AS_KW
+    };
     ( async ) => {
         $crate::SyntaxKind::ASYNC_KW
     };
-    ( use ) => {
-        $crate::SyntaxKind::USE_KW
+    ( await ) => {
+        $crate::SyntaxKind::AWAIT_KW
     };
-    ( fn ) => {
-        $crate::SyntaxKind::FN_KW
+    ( box ) => {
+        $crate::SyntaxKind::BOX_KW
     };
-    ( struct ) => {
-        $crate::SyntaxKind::STRUCT_KW
+    ( break ) => {
+        $crate::SyntaxKind::BREAK_KW
     };
-    ( enum ) => {
-        $crate::SyntaxKind::ENUM_KW
+    ( const ) => {
+        $crate::SyntaxKind::CONST_KW
     };
-    ( trait ) => {
-        $crate::SyntaxKind::TRAIT_KW
+    ( continue ) => {
+        $crate::SyntaxKind::CONTINUE_KW
     };
-    ( impl ) => {
-        $crate::SyntaxKind::IMPL_KW
+    ( crate ) => {
+        $crate::SyntaxKind::CRATE_KW
     };
     ( dyn ) => {
         $crate::SyntaxKind::DYN_KW
     };
-    ( true ) => {
-        $crate::SyntaxKind::TRUE_KW
-    };
-    ( false ) => {
-        $crate::SyntaxKind::FALSE_KW
+    ( else ) => {
+        $crate::SyntaxKind::ELSE_KW
     };
-    ( as ) => {
-        $crate::SyntaxKind::AS_KW
+    ( enum ) => {
+        $crate::SyntaxKind::ENUM_KW
     };
     ( extern ) => {
         $crate::SyntaxKind::EXTERN_KW
     };
-    ( crate ) => {
-        $crate::SyntaxKind::CRATE_KW
+    ( false ) => {
+        $crate::SyntaxKind::FALSE_KW
     };
-    ( mod ) => {
-        $crate::SyntaxKind::MOD_KW
+    ( fn ) => {
+        $crate::SyntaxKind::FN_KW
     };
-    ( pub ) => {
-        $crate::SyntaxKind::PUB_KW
+    ( for ) => {
+        $crate::SyntaxKind::FOR_KW
     };
-    ( self ) => {
-        $crate::SyntaxKind::SELF_KW
+    ( if ) => {
+        $crate::SyntaxKind::IF_KW
     };
-    ( super ) => {
-        $crate::SyntaxKind::SUPER_KW
+    ( impl ) => {
+        $crate::SyntaxKind::IMPL_KW
     };
     ( in ) => {
         $crate::SyntaxKind::IN_KW
     };
-    ( where ) => {
-        $crate::SyntaxKind::WHERE_KW
-    };
-    ( for ) => {
-        $crate::SyntaxKind::FOR_KW
+    ( let ) => {
+        $crate::SyntaxKind::LET_KW
     };
     ( loop ) => {
         $crate::SyntaxKind::LOOP_KW
     };
-    ( while ) => {
-        $crate::SyntaxKind::WHILE_KW
-    };
-    ( continue ) => {
-        $crate::SyntaxKind::CONTINUE_KW
-    };
-    ( break ) => {
-        $crate::SyntaxKind::BREAK_KW
-    };
-    ( if ) => {
-        $crate::SyntaxKind::IF_KW
-    };
-    ( else ) => {
-        $crate::SyntaxKind::ELSE_KW
+    ( macro ) => {
+        $crate::SyntaxKind::MACRO_KW
     };
     ( match ) => {
         $crate::SyntaxKind::MATCH_KW
     };
-    ( const ) => {
-        $crate::SyntaxKind::CONST_KW
+    ( mod ) => {
+        $crate::SyntaxKind::MOD_KW
     };
-    ( static ) => {
-        $crate::SyntaxKind::STATIC_KW
+    ( move ) => {
+        $crate::SyntaxKind::MOVE_KW
     };
     ( mut ) => {
         $crate::SyntaxKind::MUT_KW
     };
-    ( unsafe ) => {
-        $crate::SyntaxKind::UNSAFE_KW
-    };
-    ( type ) => {
-        $crate::SyntaxKind::TYPE_KW
+    ( pub ) => {
+        $crate::SyntaxKind::PUB_KW
     };
     ( ref ) => {
         $crate::SyntaxKind::REF_KW
     };
-    ( let ) => {
-        $crate::SyntaxKind::LET_KW
-    };
-    ( move ) => {
-        $crate::SyntaxKind::MOVE_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
+    };
     ( try ) => {
         $crate::SyntaxKind::TRY_KW
     };
-    ( box ) => {
-        $crate::SyntaxKind::BOX_KW
+    ( type ) => {
+        $crate::SyntaxKind::TYPE_KW
     };
-    ( await ) => {
-        $crate::SyntaxKind::AWAIT_KW
+    ( unsafe ) => {
+        $crate::SyntaxKind::UNSAFE_KW
     };
-    ( macro ) => {
-        $crate::SyntaxKind::MACRO_KW
+    ( use ) => {
+        $crate::SyntaxKind::USE_KW
+    };
+    ( where ) => {
+        $crate::SyntaxKind::WHERE_KW
+    };
+    ( while ) => {
+        $crate::SyntaxKind::WHILE_KW
     };
     ( auto ) => {
         $crate::SyntaxKind::AUTO_KW
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index e64c83d3352..2eb4b14d20b 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -6,13 +6,13 @@ use crate::{
     SyntaxNode,
 };
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Alias {
+pub struct SourceFile {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Alias {
+impl AstNode for SourceFile {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            ALIAS => true,
+            SOURCE_FILE => true,
             _ => false,
         }
     }
@@ -27,16 +27,21 @@ impl AstNode for Alias {
         &self.syntax
     }
 }
-impl ast::NameOwner for Alias {}
-impl Alias {}
+impl ast::ModuleItemOwner for SourceFile {}
+impl ast::FnDefOwner for SourceFile {}
+impl SourceFile {
+    pub fn modules(&self) -> AstChildren<Module> {
+        AstChildren::new(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ArgList {
+pub struct FnDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ArgList {
+impl AstNode for FnDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            ARG_LIST => true,
+            FN_DEF => true,
             _ => false,
         }
     }
@@ -51,19 +56,30 @@ impl AstNode for ArgList {
         &self.syntax
     }
 }
-impl ArgList {
-    pub fn args(&self) -> AstChildren<Expr> {
-        AstChildren::new(&self.syntax)
+impl ast::VisibilityOwner for FnDef {}
+impl ast::NameOwner for FnDef {}
+impl ast::TypeParamsOwner for FnDef {}
+impl ast::DocCommentsOwner for FnDef {}
+impl ast::AttrsOwner for FnDef {}
+impl FnDef {
+    pub fn param_list(&self) -> Option<ParamList> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn ret_type(&self) -> Option<RetType> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn body(&self) -> Option<BlockExpr> {
+        AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ArrayExpr {
+pub struct RetType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ArrayExpr {
+impl AstNode for RetType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            ARRAY_EXPR => true,
+            RET_TYPE => true,
             _ => false,
         }
     }
@@ -78,19 +94,19 @@ impl AstNode for ArrayExpr {
         &self.syntax
     }
 }
-impl ArrayExpr {
-    pub fn exprs(&self) -> AstChildren<Expr> {
-        AstChildren::new(&self.syntax)
+impl RetType {
+    pub fn type_ref(&self) -> Option<TypeRef> {
+        AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ArrayType {
+pub struct StructDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ArrayType {
+impl AstNode for StructDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            ARRAY_TYPE => true,
+            STRUCT_DEF => true,
             _ => false,
         }
     }
@@ -105,22 +121,20 @@ impl AstNode for ArrayType {
         &self.syntax
     }
 }
-impl ArrayType {
-    pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
-    }
-}
+impl ast::VisibilityOwner for StructDef {}
+impl ast::NameOwner for StructDef {}
+impl ast::TypeParamsOwner for StructDef {}
+impl ast::AttrsOwner for StructDef {}
+impl ast::DocCommentsOwner for StructDef {}
+impl StructDef {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct AssocTypeArg {
+pub struct UnionDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for AssocTypeArg {
+impl AstNode for UnionDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            ASSOC_TYPE_ARG => true,
+            UNION_DEF => true,
             _ => false,
         }
     }
@@ -135,22 +149,24 @@ impl AstNode for AssocTypeArg {
         &self.syntax
     }
 }
-impl AssocTypeArg {
-    pub fn name_ref(&self) -> Option<NameRef> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn type_ref(&self) -> Option<TypeRef> {
+impl ast::VisibilityOwner for UnionDef {}
+impl ast::NameOwner for UnionDef {}
+impl ast::TypeParamsOwner for UnionDef {}
+impl ast::AttrsOwner for UnionDef {}
+impl ast::DocCommentsOwner for UnionDef {}
+impl UnionDef {
+    pub fn record_field_def_list(&self) -> Option<RecordFieldDefList> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Attr {
+pub struct RecordFieldDefList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Attr {
+impl AstNode for RecordFieldDefList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            ATTR => true,
+            RECORD_FIELD_DEF_LIST => true,
             _ => false,
         }
     }
@@ -165,60 +181,47 @@ impl AstNode for Attr {
         &self.syntax
     }
 }
-impl Attr {
-    pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn input(&self) -> Option<AttrInput> {
-        AstChildren::new(&self.syntax).next()
+impl RecordFieldDefList {
+    pub fn fields(&self) -> AstChildren<RecordFieldDef> {
+        AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum AttrInput {
-    Literal(Literal),
-    TokenTree(TokenTree),
-}
-impl From<Literal> for AttrInput {
-    fn from(node: Literal) -> AttrInput {
-        AttrInput::Literal(node)
-    }
-}
-impl From<TokenTree> for AttrInput {
-    fn from(node: TokenTree) -> AttrInput {
-        AttrInput::TokenTree(node)
-    }
+pub struct RecordFieldDef {
+    pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for AttrInput {
+impl AstNode for RecordFieldDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LITERAL | TOKEN_TREE => true,
+            RECORD_FIELD_DEF => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        let res = match syntax.kind() {
-            LITERAL => AttrInput::Literal(Literal { syntax }),
-            TOKEN_TREE => AttrInput::TokenTree(TokenTree { syntax }),
-            _ => return None,
-        };
-        Some(res)
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
     }
     fn syntax(&self) -> &SyntaxNode {
-        match self {
-            AttrInput::Literal(it) => &it.syntax,
-            AttrInput::TokenTree(it) => &it.syntax,
-        }
+        &self.syntax
     }
 }
-impl AttrInput {}
+impl ast::VisibilityOwner for RecordFieldDef {}
+impl ast::NameOwner for RecordFieldDef {}
+impl ast::AttrsOwner for RecordFieldDef {}
+impl ast::DocCommentsOwner for RecordFieldDef {}
+impl ast::TypeAscriptionOwner for RecordFieldDef {}
+impl RecordFieldDef {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct AwaitExpr {
+pub struct TupleFieldDefList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for AwaitExpr {
+impl AstNode for TupleFieldDefList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            AWAIT_EXPR => true,
+            TUPLE_FIELD_DEF_LIST => true,
             _ => false,
         }
     }
@@ -233,19 +236,19 @@ impl AstNode for AwaitExpr {
         &self.syntax
     }
 }
-impl AwaitExpr {
-    pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+impl TupleFieldDefList {
+    pub fn fields(&self) -> AstChildren<TupleFieldDef> {
+        AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct BinExpr {
+pub struct TupleFieldDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for BinExpr {
+impl AstNode for TupleFieldDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            BIN_EXPR => true,
+            TUPLE_FIELD_DEF => true,
             _ => false,
         }
     }
@@ -260,15 +263,21 @@ impl AstNode for BinExpr {
         &self.syntax
     }
 }
-impl BinExpr {}
+impl ast::VisibilityOwner for TupleFieldDef {}
+impl ast::AttrsOwner for TupleFieldDef {}
+impl TupleFieldDef {
+    pub fn type_ref(&self) -> Option<TypeRef> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct BindPat {
+pub struct EnumDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for BindPat {
+impl AstNode for EnumDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            BIND_PAT => true,
+            ENUM_DEF => true,
             _ => false,
         }
     }
@@ -283,20 +292,24 @@ impl AstNode for BindPat {
         &self.syntax
     }
 }
-impl ast::NameOwner for BindPat {}
-impl BindPat {
-    pub fn pat(&self) -> Option<Pat> {
+impl ast::VisibilityOwner for EnumDef {}
+impl ast::NameOwner for EnumDef {}
+impl ast::TypeParamsOwner for EnumDef {}
+impl ast::AttrsOwner for EnumDef {}
+impl ast::DocCommentsOwner for EnumDef {}
+impl EnumDef {
+    pub fn variant_list(&self) -> Option<EnumVariantList> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Block {
+pub struct EnumVariantList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Block {
+impl AstNode for EnumVariantList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            BLOCK => true,
+            ENUM_VARIANT_LIST => true,
             _ => false,
         }
     }
@@ -311,24 +324,19 @@ impl AstNode for Block {
         &self.syntax
     }
 }
-impl ast::AttrsOwner for Block {}
-impl ast::ModuleItemOwner for Block {}
-impl Block {
-    pub fn statements(&self) -> AstChildren<Stmt> {
+impl EnumVariantList {
+    pub fn variants(&self) -> AstChildren<EnumVariant> {
         AstChildren::new(&self.syntax)
     }
-    pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
-    }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct BlockExpr {
+pub struct EnumVariant {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for BlockExpr {
+impl AstNode for EnumVariant {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            BLOCK_EXPR => true,
+            ENUM_VARIANT => true,
             _ => false,
         }
     }
@@ -343,19 +351,22 @@ impl AstNode for BlockExpr {
         &self.syntax
     }
 }
-impl BlockExpr {
-    pub fn block(&self) -> Option<Block> {
+impl ast::NameOwner for EnumVariant {}
+impl ast::DocCommentsOwner for EnumVariant {}
+impl ast::AttrsOwner for EnumVariant {}
+impl EnumVariant {
+    pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct BoxExpr {
+pub struct TraitDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for BoxExpr {
+impl AstNode for TraitDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            BOX_EXPR => true,
+            TRAIT_DEF => true,
             _ => false,
         }
     }
@@ -370,19 +381,25 @@ impl AstNode for BoxExpr {
         &self.syntax
     }
 }
-impl BoxExpr {
-    pub fn expr(&self) -> Option<Expr> {
+impl ast::VisibilityOwner for TraitDef {}
+impl ast::NameOwner for TraitDef {}
+impl ast::AttrsOwner for TraitDef {}
+impl ast::DocCommentsOwner for TraitDef {}
+impl ast::TypeParamsOwner for TraitDef {}
+impl ast::TypeBoundsOwner for TraitDef {}
+impl TraitDef {
+    pub fn item_list(&self) -> Option<ItemList> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct BoxPat {
+pub struct Module {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for BoxPat {
+impl AstNode for Module {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            BOX_PAT => true,
+            MODULE => true,
             _ => false,
         }
     }
@@ -397,19 +414,23 @@ impl AstNode for BoxPat {
         &self.syntax
     }
 }
-impl BoxPat {
-    pub fn pat(&self) -> Option<Pat> {
+impl ast::VisibilityOwner for Module {}
+impl ast::NameOwner for Module {}
+impl ast::AttrsOwner for Module {}
+impl ast::DocCommentsOwner for Module {}
+impl Module {
+    pub fn item_list(&self) -> Option<ItemList> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct BreakExpr {
+pub struct ItemList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for BreakExpr {
+impl AstNode for ItemList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            BREAK_EXPR => true,
+            ITEM_LIST => true,
             _ => false,
         }
     }
@@ -424,19 +445,21 @@ impl AstNode for BreakExpr {
         &self.syntax
     }
 }
-impl BreakExpr {
-    pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+impl ast::FnDefOwner for ItemList {}
+impl ast::ModuleItemOwner for ItemList {}
+impl ItemList {
+    pub fn impl_items(&self) -> AstChildren<ImplItem> {
+        AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct CallExpr {
+pub struct ConstDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for CallExpr {
+impl AstNode for ConstDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            CALL_EXPR => true,
+            CONST_DEF => true,
             _ => false,
         }
     }
@@ -451,20 +474,25 @@ impl AstNode for CallExpr {
         &self.syntax
     }
 }
-impl ast::ArgListOwner for CallExpr {}
-impl CallExpr {
-    pub fn expr(&self) -> Option<Expr> {
+impl ast::VisibilityOwner for ConstDef {}
+impl ast::NameOwner for ConstDef {}
+impl ast::TypeParamsOwner for ConstDef {}
+impl ast::AttrsOwner for ConstDef {}
+impl ast::DocCommentsOwner for ConstDef {}
+impl ast::TypeAscriptionOwner for ConstDef {}
+impl ConstDef {
+    pub fn body(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct CastExpr {
+pub struct StaticDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for CastExpr {
+impl AstNode for StaticDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            CAST_EXPR => true,
+            STATIC_DEF => true,
             _ => false,
         }
     }
@@ -479,22 +507,25 @@ impl AstNode for CastExpr {
         &self.syntax
     }
 }
-impl CastExpr {
-    pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn type_ref(&self) -> Option<TypeRef> {
+impl ast::VisibilityOwner for StaticDef {}
+impl ast::NameOwner for StaticDef {}
+impl ast::TypeParamsOwner for StaticDef {}
+impl ast::AttrsOwner for StaticDef {}
+impl ast::DocCommentsOwner for StaticDef {}
+impl ast::TypeAscriptionOwner for StaticDef {}
+impl StaticDef {
+    pub fn body(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Condition {
+pub struct TypeAliasDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Condition {
+impl AstNode for TypeAliasDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            CONDITION => true,
+            TYPE_ALIAS_DEF => true,
             _ => false,
         }
     }
@@ -509,22 +540,25 @@ impl AstNode for Condition {
         &self.syntax
     }
 }
-impl Condition {
-    pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn expr(&self) -> Option<Expr> {
+impl ast::VisibilityOwner for TypeAliasDef {}
+impl ast::NameOwner for TypeAliasDef {}
+impl ast::TypeParamsOwner for TypeAliasDef {}
+impl ast::AttrsOwner for TypeAliasDef {}
+impl ast::DocCommentsOwner for TypeAliasDef {}
+impl ast::TypeBoundsOwner for TypeAliasDef {}
+impl TypeAliasDef {
+    pub fn type_ref(&self) -> Option<TypeRef> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ConstDef {
+pub struct ImplBlock {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ConstDef {
+impl AstNode for ImplBlock {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            CONST_DEF => true,
+            IMPL_BLOCK => true,
             _ => false,
         }
     }
@@ -539,25 +573,21 @@ impl AstNode for ConstDef {
         &self.syntax
     }
 }
-impl ast::VisibilityOwner for ConstDef {}
-impl ast::NameOwner for ConstDef {}
-impl ast::TypeParamsOwner for ConstDef {}
-impl ast::AttrsOwner for ConstDef {}
-impl ast::DocCommentsOwner for ConstDef {}
-impl ast::TypeAscriptionOwner for ConstDef {}
-impl ConstDef {
-    pub fn body(&self) -> Option<Expr> {
+impl ast::TypeParamsOwner for ImplBlock {}
+impl ast::AttrsOwner for ImplBlock {}
+impl ImplBlock {
+    pub fn item_list(&self) -> Option<ItemList> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ConstParam {
+pub struct ParenType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ConstParam {
+impl AstNode for ParenType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            CONST_PARAM => true,
+            PAREN_TYPE => true,
             _ => false,
         }
     }
@@ -572,22 +602,19 @@ impl AstNode for ConstParam {
         &self.syntax
     }
 }
-impl ast::NameOwner for ConstParam {}
-impl ast::AttrsOwner for ConstParam {}
-impl ast::TypeAscriptionOwner for ConstParam {}
-impl ConstParam {
-    pub fn default_val(&self) -> Option<Expr> {
+impl ParenType {
+    pub fn type_ref(&self) -> Option<TypeRef> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ContinueExpr {
+pub struct TupleType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ContinueExpr {
+impl AstNode for TupleType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            CONTINUE_EXPR => true,
+            TUPLE_TYPE => true,
             _ => false,
         }
     }
@@ -602,15 +629,19 @@ impl AstNode for ContinueExpr {
         &self.syntax
     }
 }
-impl ContinueExpr {}
+impl TupleType {
+    pub fn fields(&self) -> AstChildren<TypeRef> {
+        AstChildren::new(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct DotDotPat {
+pub struct NeverType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for DotDotPat {
+impl AstNode for NeverType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            DOT_DOT_PAT => true,
+            NEVER_TYPE => true,
             _ => false,
         }
     }
@@ -625,15 +656,15 @@ impl AstNode for DotDotPat {
         &self.syntax
     }
 }
-impl DotDotPat {}
+impl NeverType {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct DynTraitType {
+pub struct PathType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for DynTraitType {
+impl AstNode for PathType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            DYN_TRAIT_TYPE => true,
+            PATH_TYPE => true,
             _ => false,
         }
     }
@@ -648,16 +679,19 @@ impl AstNode for DynTraitType {
         &self.syntax
     }
 }
-impl ast::TypeBoundsOwner for DynTraitType {}
-impl DynTraitType {}
+impl PathType {
+    pub fn path(&self) -> Option<Path> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct EnumDef {
+pub struct PointerType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for EnumDef {
+impl AstNode for PointerType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            ENUM_DEF => true,
+            POINTER_TYPE => true,
             _ => false,
         }
     }
@@ -672,24 +706,19 @@ impl AstNode for EnumDef {
         &self.syntax
     }
 }
-impl ast::VisibilityOwner for EnumDef {}
-impl ast::NameOwner for EnumDef {}
-impl ast::TypeParamsOwner for EnumDef {}
-impl ast::AttrsOwner for EnumDef {}
-impl ast::DocCommentsOwner for EnumDef {}
-impl EnumDef {
-    pub fn variant_list(&self) -> Option<EnumVariantList> {
+impl PointerType {
+    pub fn type_ref(&self) -> Option<TypeRef> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct EnumVariant {
+pub struct ArrayType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for EnumVariant {
+impl AstNode for ArrayType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            ENUM_VARIANT => true,
+            ARRAY_TYPE => true,
             _ => false,
         }
     }
@@ -704,22 +733,22 @@ impl AstNode for EnumVariant {
         &self.syntax
     }
 }
-impl ast::NameOwner for EnumVariant {}
-impl ast::DocCommentsOwner for EnumVariant {}
-impl ast::AttrsOwner for EnumVariant {}
-impl EnumVariant {
+impl ArrayType {
+    pub fn type_ref(&self) -> Option<TypeRef> {
+        AstChildren::new(&self.syntax).next()
+    }
     pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct EnumVariantList {
+pub struct SliceType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for EnumVariantList {
+impl AstNode for SliceType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            ENUM_VARIANT_LIST => true,
+            SLICE_TYPE => true,
             _ => false,
         }
     }
@@ -734,294 +763,46 @@ impl AstNode for EnumVariantList {
         &self.syntax
     }
 }
-impl EnumVariantList {
-    pub fn variants(&self) -> AstChildren<EnumVariant> {
-        AstChildren::new(&self.syntax)
+impl SliceType {
+    pub fn type_ref(&self) -> Option<TypeRef> {
+        AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum Expr {
-    TupleExpr(TupleExpr),
-    ArrayExpr(ArrayExpr),
-    ParenExpr(ParenExpr),
-    PathExpr(PathExpr),
-    LambdaExpr(LambdaExpr),
-    IfExpr(IfExpr),
-    LoopExpr(LoopExpr),
-    ForExpr(ForExpr),
-    WhileExpr(WhileExpr),
-    ContinueExpr(ContinueExpr),
-    BreakExpr(BreakExpr),
-    Label(Label),
-    BlockExpr(BlockExpr),
-    ReturnExpr(ReturnExpr),
-    MatchExpr(MatchExpr),
-    RecordLit(RecordLit),
-    CallExpr(CallExpr),
-    IndexExpr(IndexExpr),
-    MethodCallExpr(MethodCallExpr),
-    FieldExpr(FieldExpr),
-    AwaitExpr(AwaitExpr),
-    TryExpr(TryExpr),
-    TryBlockExpr(TryBlockExpr),
-    CastExpr(CastExpr),
-    RefExpr(RefExpr),
-    PrefixExpr(PrefixExpr),
-    RangeExpr(RangeExpr),
-    BinExpr(BinExpr),
-    Literal(Literal),
-    MacroCall(MacroCall),
-    BoxExpr(BoxExpr),
-}
-impl From<TupleExpr> for Expr {
-    fn from(node: TupleExpr) -> Expr {
-        Expr::TupleExpr(node)
-    }
-}
-impl From<ArrayExpr> for Expr {
-    fn from(node: ArrayExpr) -> Expr {
-        Expr::ArrayExpr(node)
-    }
-}
-impl From<ParenExpr> for Expr {
-    fn from(node: ParenExpr) -> Expr {
-        Expr::ParenExpr(node)
-    }
-}
-impl From<PathExpr> for Expr {
-    fn from(node: PathExpr) -> Expr {
-        Expr::PathExpr(node)
-    }
-}
-impl From<LambdaExpr> for Expr {
-    fn from(node: LambdaExpr) -> Expr {
-        Expr::LambdaExpr(node)
-    }
-}
-impl From<IfExpr> for Expr {
-    fn from(node: IfExpr) -> Expr {
-        Expr::IfExpr(node)
-    }
-}
-impl From<LoopExpr> for Expr {
-    fn from(node: LoopExpr) -> Expr {
-        Expr::LoopExpr(node)
-    }
-}
-impl From<ForExpr> for Expr {
-    fn from(node: ForExpr) -> Expr {
-        Expr::ForExpr(node)
-    }
-}
-impl From<WhileExpr> for Expr {
-    fn from(node: WhileExpr) -> Expr {
-        Expr::WhileExpr(node)
-    }
-}
-impl From<ContinueExpr> for Expr {
-    fn from(node: ContinueExpr) -> Expr {
-        Expr::ContinueExpr(node)
-    }
-}
-impl From<BreakExpr> for Expr {
-    fn from(node: BreakExpr) -> Expr {
-        Expr::BreakExpr(node)
-    }
-}
-impl From<Label> for Expr {
-    fn from(node: Label) -> Expr {
-        Expr::Label(node)
-    }
-}
-impl From<BlockExpr> for Expr {
-    fn from(node: BlockExpr) -> Expr {
-        Expr::BlockExpr(node)
-    }
-}
-impl From<ReturnExpr> for Expr {
-    fn from(node: ReturnExpr) -> Expr {
-        Expr::ReturnExpr(node)
-    }
-}
-impl From<MatchExpr> for Expr {
-    fn from(node: MatchExpr) -> Expr {
-        Expr::MatchExpr(node)
-    }
-}
-impl From<RecordLit> for Expr {
-    fn from(node: RecordLit) -> Expr {
-        Expr::RecordLit(node)
-    }
-}
-impl From<CallExpr> for Expr {
-    fn from(node: CallExpr) -> Expr {
-        Expr::CallExpr(node)
-    }
-}
-impl From<IndexExpr> for Expr {
-    fn from(node: IndexExpr) -> Expr {
-        Expr::IndexExpr(node)
-    }
-}
-impl From<MethodCallExpr> for Expr {
-    fn from(node: MethodCallExpr) -> Expr {
-        Expr::MethodCallExpr(node)
-    }
-}
-impl From<FieldExpr> for Expr {
-    fn from(node: FieldExpr) -> Expr {
-        Expr::FieldExpr(node)
-    }
-}
-impl From<AwaitExpr> for Expr {
-    fn from(node: AwaitExpr) -> Expr {
-        Expr::AwaitExpr(node)
-    }
-}
-impl From<TryExpr> for Expr {
-    fn from(node: TryExpr) -> Expr {
-        Expr::TryExpr(node)
-    }
-}
-impl From<TryBlockExpr> for Expr {
-    fn from(node: TryBlockExpr) -> Expr {
-        Expr::TryBlockExpr(node)
-    }
-}
-impl From<CastExpr> for Expr {
-    fn from(node: CastExpr) -> Expr {
-        Expr::CastExpr(node)
-    }
-}
-impl From<RefExpr> for Expr {
-    fn from(node: RefExpr) -> Expr {
-        Expr::RefExpr(node)
-    }
-}
-impl From<PrefixExpr> for Expr {
-    fn from(node: PrefixExpr) -> Expr {
-        Expr::PrefixExpr(node)
-    }
-}
-impl From<RangeExpr> for Expr {
-    fn from(node: RangeExpr) -> Expr {
-        Expr::RangeExpr(node)
-    }
-}
-impl From<BinExpr> for Expr {
-    fn from(node: BinExpr) -> Expr {
-        Expr::BinExpr(node)
-    }
-}
-impl From<Literal> for Expr {
-    fn from(node: Literal) -> Expr {
-        Expr::Literal(node)
-    }
-}
-impl From<MacroCall> for Expr {
-    fn from(node: MacroCall) -> Expr {
-        Expr::MacroCall(node)
-    }
-}
-impl From<BoxExpr> for Expr {
-    fn from(node: BoxExpr) -> Expr {
-        Expr::BoxExpr(node)
-    }
+pub struct ReferenceType {
+    pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Expr {
+impl AstNode for ReferenceType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR
-            | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL
-            | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR
-            | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR
-            | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL
-            | BOX_EXPR => true,
+            REFERENCE_TYPE => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        let res = match syntax.kind() {
-            TUPLE_EXPR => Expr::TupleExpr(TupleExpr { syntax }),
-            ARRAY_EXPR => Expr::ArrayExpr(ArrayExpr { syntax }),
-            PAREN_EXPR => Expr::ParenExpr(ParenExpr { syntax }),
-            PATH_EXPR => Expr::PathExpr(PathExpr { syntax }),
-            LAMBDA_EXPR => Expr::LambdaExpr(LambdaExpr { syntax }),
-            IF_EXPR => Expr::IfExpr(IfExpr { syntax }),
-            LOOP_EXPR => Expr::LoopExpr(LoopExpr { syntax }),
-            FOR_EXPR => Expr::ForExpr(ForExpr { syntax }),
-            WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }),
-            CONTINUE_EXPR => Expr::ContinueExpr(ContinueExpr { syntax }),
-            BREAK_EXPR => Expr::BreakExpr(BreakExpr { syntax }),
-            LABEL => Expr::Label(Label { syntax }),
-            BLOCK_EXPR => Expr::BlockExpr(BlockExpr { syntax }),
-            RETURN_EXPR => Expr::ReturnExpr(ReturnExpr { syntax }),
-            MATCH_EXPR => Expr::MatchExpr(MatchExpr { syntax }),
-            RECORD_LIT => Expr::RecordLit(RecordLit { syntax }),
-            CALL_EXPR => Expr::CallExpr(CallExpr { syntax }),
-            INDEX_EXPR => Expr::IndexExpr(IndexExpr { syntax }),
-            METHOD_CALL_EXPR => Expr::MethodCallExpr(MethodCallExpr { syntax }),
-            FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }),
-            AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }),
-            TRY_EXPR => Expr::TryExpr(TryExpr { syntax }),
-            TRY_BLOCK_EXPR => Expr::TryBlockExpr(TryBlockExpr { syntax }),
-            CAST_EXPR => Expr::CastExpr(CastExpr { syntax }),
-            REF_EXPR => Expr::RefExpr(RefExpr { syntax }),
-            PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }),
-            RANGE_EXPR => Expr::RangeExpr(RangeExpr { syntax }),
-            BIN_EXPR => Expr::BinExpr(BinExpr { syntax }),
-            LITERAL => Expr::Literal(Literal { syntax }),
-            MACRO_CALL => Expr::MacroCall(MacroCall { syntax }),
-            BOX_EXPR => Expr::BoxExpr(BoxExpr { syntax }),
-            _ => return None,
-        };
-        Some(res)
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
     }
     fn syntax(&self) -> &SyntaxNode {
-        match self {
-            Expr::TupleExpr(it) => &it.syntax,
-            Expr::ArrayExpr(it) => &it.syntax,
-            Expr::ParenExpr(it) => &it.syntax,
-            Expr::PathExpr(it) => &it.syntax,
-            Expr::LambdaExpr(it) => &it.syntax,
-            Expr::IfExpr(it) => &it.syntax,
-            Expr::LoopExpr(it) => &it.syntax,
-            Expr::ForExpr(it) => &it.syntax,
-            Expr::WhileExpr(it) => &it.syntax,
-            Expr::ContinueExpr(it) => &it.syntax,
-            Expr::BreakExpr(it) => &it.syntax,
-            Expr::Label(it) => &it.syntax,
-            Expr::BlockExpr(it) => &it.syntax,
-            Expr::ReturnExpr(it) => &it.syntax,
-            Expr::MatchExpr(it) => &it.syntax,
-            Expr::RecordLit(it) => &it.syntax,
-            Expr::CallExpr(it) => &it.syntax,
-            Expr::IndexExpr(it) => &it.syntax,
-            Expr::MethodCallExpr(it) => &it.syntax,
-            Expr::FieldExpr(it) => &it.syntax,
-            Expr::AwaitExpr(it) => &it.syntax,
-            Expr::TryExpr(it) => &it.syntax,
-            Expr::TryBlockExpr(it) => &it.syntax,
-            Expr::CastExpr(it) => &it.syntax,
-            Expr::RefExpr(it) => &it.syntax,
-            Expr::PrefixExpr(it) => &it.syntax,
-            Expr::RangeExpr(it) => &it.syntax,
-            Expr::BinExpr(it) => &it.syntax,
-            Expr::Literal(it) => &it.syntax,
-            Expr::MacroCall(it) => &it.syntax,
-            Expr::BoxExpr(it) => &it.syntax,
-        }
+        &self.syntax
+    }
+}
+impl ReferenceType {
+    pub fn type_ref(&self) -> Option<TypeRef> {
+        AstChildren::new(&self.syntax).next()
     }
 }
-impl Expr {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ExprStmt {
+pub struct PlaceholderType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ExprStmt {
+impl AstNode for PlaceholderType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            EXPR_STMT => true,
+            PLACEHOLDER_TYPE => true,
             _ => false,
         }
     }
@@ -1036,19 +817,15 @@ impl AstNode for ExprStmt {
         &self.syntax
     }
 }
-impl ExprStmt {
-    pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
-    }
-}
+impl PlaceholderType {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ExternCrateItem {
+pub struct FnPointerType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ExternCrateItem {
+impl AstNode for FnPointerType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            EXTERN_CRATE_ITEM => true,
+            FN_POINTER_TYPE => true,
             _ => false,
         }
     }
@@ -1063,24 +840,22 @@ impl AstNode for ExternCrateItem {
         &self.syntax
     }
 }
-impl ast::AttrsOwner for ExternCrateItem {}
-impl ast::VisibilityOwner for ExternCrateItem {}
-impl ExternCrateItem {
-    pub fn name_ref(&self) -> Option<NameRef> {
+impl FnPointerType {
+    pub fn param_list(&self) -> Option<ParamList> {
         AstChildren::new(&self.syntax).next()
     }
-    pub fn alias(&self) -> Option<Alias> {
+    pub fn ret_type(&self) -> Option<RetType> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct FieldExpr {
+pub struct ForType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for FieldExpr {
+impl AstNode for ForType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            FIELD_EXPR => true,
+            FOR_TYPE => true,
             _ => false,
         }
     }
@@ -1095,22 +870,19 @@ impl AstNode for FieldExpr {
         &self.syntax
     }
 }
-impl FieldExpr {
-    pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn name_ref(&self) -> Option<NameRef> {
+impl ForType {
+    pub fn type_ref(&self) -> Option<TypeRef> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct FnDef {
+pub struct ImplTraitType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for FnDef {
+impl AstNode for ImplTraitType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            FN_DEF => true,
+            IMPL_TRAIT_TYPE => true,
             _ => false,
         }
     }
@@ -1125,30 +897,16 @@ impl AstNode for FnDef {
         &self.syntax
     }
 }
-impl ast::VisibilityOwner for FnDef {}
-impl ast::NameOwner for FnDef {}
-impl ast::TypeParamsOwner for FnDef {}
-impl ast::AttrsOwner for FnDef {}
-impl ast::DocCommentsOwner for FnDef {}
-impl FnDef {
-    pub fn param_list(&self) -> Option<ParamList> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn body(&self) -> Option<BlockExpr> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn ret_type(&self) -> Option<RetType> {
-        AstChildren::new(&self.syntax).next()
-    }
-}
+impl ast::TypeBoundsOwner for ImplTraitType {}
+impl ImplTraitType {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct FnPointerType {
+pub struct DynTraitType {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for FnPointerType {
+impl AstNode for DynTraitType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            FN_POINTER_TYPE => true,
+            DYN_TRAIT_TYPE => true,
             _ => false,
         }
     }
@@ -1163,22 +921,16 @@ impl AstNode for FnPointerType {
         &self.syntax
     }
 }
-impl FnPointerType {
-    pub fn param_list(&self) -> Option<ParamList> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn ret_type(&self) -> Option<RetType> {
-        AstChildren::new(&self.syntax).next()
-    }
-}
+impl ast::TypeBoundsOwner for DynTraitType {}
+impl DynTraitType {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ForExpr {
+pub struct TupleExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ForExpr {
+impl AstNode for TupleExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            FOR_EXPR => true,
+            TUPLE_EXPR => true,
             _ => false,
         }
     }
@@ -1193,23 +945,19 @@ impl AstNode for ForExpr {
         &self.syntax
     }
 }
-impl ast::LoopBodyOwner for ForExpr {}
-impl ForExpr {
-    pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn iterable(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+impl TupleExpr {
+    pub fn exprs(&self) -> AstChildren<Expr> {
+        AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ForType {
+pub struct ArrayExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ForType {
+impl AstNode for ArrayExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            FOR_TYPE => true,
+            ARRAY_EXPR => true,
             _ => false,
         }
     }
@@ -1224,19 +972,19 @@ impl AstNode for ForType {
         &self.syntax
     }
 }
-impl ForType {
-    pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+impl ArrayExpr {
+    pub fn exprs(&self) -> AstChildren<Expr> {
+        AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct IfExpr {
+pub struct ParenExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for IfExpr {
+impl AstNode for ParenExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            IF_EXPR => true,
+            PAREN_EXPR => true,
             _ => false,
         }
     }
@@ -1251,19 +999,19 @@ impl AstNode for IfExpr {
         &self.syntax
     }
 }
-impl IfExpr {
-    pub fn condition(&self) -> Option<Condition> {
+impl ParenExpr {
+    pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ImplBlock {
+pub struct PathExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ImplBlock {
+impl AstNode for PathExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            IMPL_BLOCK => true,
+            PATH_EXPR => true,
             _ => false,
         }
     }
@@ -1278,68 +1026,52 @@ impl AstNode for ImplBlock {
         &self.syntax
     }
 }
-impl ast::TypeParamsOwner for ImplBlock {}
-impl ast::AttrsOwner for ImplBlock {}
-impl ImplBlock {
-    pub fn item_list(&self) -> Option<ItemList> {
+impl PathExpr {
+    pub fn path(&self) -> Option<Path> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum ImplItem {
-    FnDef(FnDef),
-    TypeAliasDef(TypeAliasDef),
-    ConstDef(ConstDef),
-}
-impl From<FnDef> for ImplItem {
-    fn from(node: FnDef) -> ImplItem {
-        ImplItem::FnDef(node)
-    }
-}
-impl From<TypeAliasDef> for ImplItem {
-    fn from(node: TypeAliasDef) -> ImplItem {
-        ImplItem::TypeAliasDef(node)
-    }
-}
-impl From<ConstDef> for ImplItem {
-    fn from(node: ConstDef) -> ImplItem {
-        ImplItem::ConstDef(node)
-    }
+pub struct LambdaExpr {
+    pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ImplItem {
+impl AstNode for LambdaExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            FN_DEF | TYPE_ALIAS_DEF | CONST_DEF => true,
+            LAMBDA_EXPR => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        let res = match syntax.kind() {
-            FN_DEF => ImplItem::FnDef(FnDef { syntax }),
-            TYPE_ALIAS_DEF => ImplItem::TypeAliasDef(TypeAliasDef { syntax }),
-            CONST_DEF => ImplItem::ConstDef(ConstDef { syntax }),
-            _ => return None,
-        };
-        Some(res)
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
     }
     fn syntax(&self) -> &SyntaxNode {
-        match self {
-            ImplItem::FnDef(it) => &it.syntax,
-            ImplItem::TypeAliasDef(it) => &it.syntax,
-            ImplItem::ConstDef(it) => &it.syntax,
-        }
+        &self.syntax
+    }
+}
+impl LambdaExpr {
+    pub fn param_list(&self) -> Option<ParamList> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn ret_type(&self) -> Option<RetType> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn body(&self) -> Option<Expr> {
+        AstChildren::new(&self.syntax).next()
     }
 }
-impl ast::AttrsOwner for ImplItem {}
-impl ImplItem {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ImplTraitType {
+pub struct IfExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ImplTraitType {
+impl AstNode for IfExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            IMPL_TRAIT_TYPE => true,
+            IF_EXPR => true,
             _ => false,
         }
     }
@@ -1354,16 +1086,19 @@ impl AstNode for ImplTraitType {
         &self.syntax
     }
 }
-impl ast::TypeBoundsOwner for ImplTraitType {}
-impl ImplTraitType {}
+impl IfExpr {
+    pub fn condition(&self) -> Option<Condition> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct IndexExpr {
+pub struct LoopExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for IndexExpr {
+impl AstNode for LoopExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            INDEX_EXPR => true,
+            LOOP_EXPR => true,
             _ => false,
         }
     }
@@ -1378,15 +1113,16 @@ impl AstNode for IndexExpr {
         &self.syntax
     }
 }
-impl IndexExpr {}
+impl ast::LoopBodyOwner for LoopExpr {}
+impl LoopExpr {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ItemList {
+pub struct TryBlockExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ItemList {
+impl AstNode for TryBlockExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            ITEM_LIST => true,
+            TRY_BLOCK_EXPR => true,
             _ => false,
         }
     }
@@ -1401,21 +1137,19 @@ impl AstNode for ItemList {
         &self.syntax
     }
 }
-impl ast::FnDefOwner for ItemList {}
-impl ast::ModuleItemOwner for ItemList {}
-impl ItemList {
-    pub fn impl_items(&self) -> AstChildren<ImplItem> {
-        AstChildren::new(&self.syntax)
+impl TryBlockExpr {
+    pub fn body(&self) -> Option<BlockExpr> {
+        AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Label {
+pub struct ForExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Label {
+impl AstNode for ForExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LABEL => true,
+            FOR_EXPR => true,
             _ => false,
         }
     }
@@ -1430,15 +1164,23 @@ impl AstNode for Label {
         &self.syntax
     }
 }
-impl Label {}
+impl ast::LoopBodyOwner for ForExpr {}
+impl ForExpr {
+    pub fn pat(&self) -> Option<Pat> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn iterable(&self) -> Option<Expr> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LambdaExpr {
+pub struct WhileExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for LambdaExpr {
+impl AstNode for WhileExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LAMBDA_EXPR => true,
+            WHILE_EXPR => true,
             _ => false,
         }
     }
@@ -1453,25 +1195,20 @@ impl AstNode for LambdaExpr {
         &self.syntax
     }
 }
-impl LambdaExpr {
-    pub fn param_list(&self) -> Option<ParamList> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn ret_type(&self) -> Option<RetType> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn body(&self) -> Option<Expr> {
+impl ast::LoopBodyOwner for WhileExpr {}
+impl WhileExpr {
+    pub fn condition(&self) -> Option<Condition> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LetStmt {
+pub struct ContinueExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for LetStmt {
+impl AstNode for ContinueExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LET_STMT => true,
+            CONTINUE_EXPR => true,
             _ => false,
         }
     }
@@ -1486,23 +1223,15 @@ impl AstNode for LetStmt {
         &self.syntax
     }
 }
-impl ast::TypeAscriptionOwner for LetStmt {}
-impl LetStmt {
-    pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn initializer(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
-    }
-}
+impl ContinueExpr {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LifetimeArg {
+pub struct BreakExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for LifetimeArg {
+impl AstNode for BreakExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LIFETIME_ARG => true,
+            BREAK_EXPR => true,
             _ => false,
         }
     }
@@ -1517,15 +1246,19 @@ impl AstNode for LifetimeArg {
         &self.syntax
     }
 }
-impl LifetimeArg {}
+impl BreakExpr {
+    pub fn expr(&self) -> Option<Expr> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LifetimeParam {
+pub struct Label {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for LifetimeParam {
+impl AstNode for Label {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LIFETIME_PARAM => true,
+            LABEL => true,
             _ => false,
         }
     }
@@ -1540,16 +1273,15 @@ impl AstNode for LifetimeParam {
         &self.syntax
     }
 }
-impl ast::AttrsOwner for LifetimeParam {}
-impl LifetimeParam {}
+impl Label {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Literal {
+pub struct BlockExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Literal {
+impl AstNode for BlockExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LITERAL => true,
+            BLOCK_EXPR => true,
             _ => false,
         }
     }
@@ -1564,15 +1296,19 @@ impl AstNode for Literal {
         &self.syntax
     }
 }
-impl Literal {}
+impl BlockExpr {
+    pub fn block(&self) -> Option<Block> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LiteralPat {
+pub struct ReturnExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for LiteralPat {
+impl AstNode for ReturnExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LITERAL_PAT => true,
+            RETURN_EXPR => true,
             _ => false,
         }
     }
@@ -1587,19 +1323,19 @@ impl AstNode for LiteralPat {
         &self.syntax
     }
 }
-impl LiteralPat {
-    pub fn literal(&self) -> Option<Literal> {
+impl ReturnExpr {
+    pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LoopExpr {
+pub struct CallExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for LoopExpr {
+impl AstNode for CallExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LOOP_EXPR => true,
+            CALL_EXPR => true,
             _ => false,
         }
     }
@@ -1614,16 +1350,20 @@ impl AstNode for LoopExpr {
         &self.syntax
     }
 }
-impl ast::LoopBodyOwner for LoopExpr {}
-impl LoopExpr {}
+impl ast::ArgListOwner for CallExpr {}
+impl CallExpr {
+    pub fn expr(&self) -> Option<Expr> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MacroCall {
+pub struct MethodCallExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for MacroCall {
+impl AstNode for MethodCallExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            MACRO_CALL => true,
+            METHOD_CALL_EXPR => true,
             _ => false,
         }
     }
@@ -1638,25 +1378,26 @@ impl AstNode for MacroCall {
         &self.syntax
     }
 }
-impl ast::NameOwner for MacroCall {}
-impl ast::AttrsOwner for MacroCall {}
-impl ast::DocCommentsOwner for MacroCall {}
-impl MacroCall {
-    pub fn token_tree(&self) -> Option<TokenTree> {
+impl ast::ArgListOwner for MethodCallExpr {}
+impl MethodCallExpr {
+    pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
-    pub fn path(&self) -> Option<Path> {
+    pub fn name_ref(&self) -> Option<NameRef> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn type_arg_list(&self) -> Option<TypeArgList> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MacroItems {
+pub struct IndexExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for MacroItems {
+impl AstNode for IndexExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            MACRO_ITEMS => true,
+            INDEX_EXPR => true,
             _ => false,
         }
     }
@@ -1671,17 +1412,15 @@ impl AstNode for MacroItems {
         &self.syntax
     }
 }
-impl ast::ModuleItemOwner for MacroItems {}
-impl ast::FnDefOwner for MacroItems {}
-impl MacroItems {}
+impl IndexExpr {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MacroStmts {
+pub struct FieldExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for MacroStmts {
+impl AstNode for FieldExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            MACRO_STMTS => true,
+            FIELD_EXPR => true,
             _ => false,
         }
     }
@@ -1696,22 +1435,22 @@ impl AstNode for MacroStmts {
         &self.syntax
     }
 }
-impl MacroStmts {
-    pub fn statements(&self) -> AstChildren<Stmt> {
-        AstChildren::new(&self.syntax)
-    }
+impl FieldExpr {
     pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
+    pub fn name_ref(&self) -> Option<NameRef> {
+        AstChildren::new(&self.syntax).next()
+    }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MatchArm {
+pub struct AwaitExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for MatchArm {
+impl AstNode for AwaitExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            MATCH_ARM => true,
+            AWAIT_EXPR => true,
             _ => false,
         }
     }
@@ -1726,26 +1465,19 @@ impl AstNode for MatchArm {
         &self.syntax
     }
 }
-impl ast::AttrsOwner for MatchArm {}
-impl MatchArm {
-    pub fn pats(&self) -> AstChildren<Pat> {
-        AstChildren::new(&self.syntax)
-    }
-    pub fn guard(&self) -> Option<MatchGuard> {
-        AstChildren::new(&self.syntax).next()
-    }
+impl AwaitExpr {
     pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MatchArmList {
+pub struct TryExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for MatchArmList {
+impl AstNode for TryExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            MATCH_ARM_LIST => true,
+            TRY_EXPR => true,
             _ => false,
         }
     }
@@ -1760,20 +1492,19 @@ impl AstNode for MatchArmList {
         &self.syntax
     }
 }
-impl ast::AttrsOwner for MatchArmList {}
-impl MatchArmList {
-    pub fn arms(&self) -> AstChildren<MatchArm> {
-        AstChildren::new(&self.syntax)
+impl TryExpr {
+    pub fn expr(&self) -> Option<Expr> {
+        AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MatchExpr {
+pub struct CastExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for MatchExpr {
+impl AstNode for CastExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            MATCH_EXPR => true,
+            CAST_EXPR => true,
             _ => false,
         }
     }
@@ -1788,22 +1519,22 @@ impl AstNode for MatchExpr {
         &self.syntax
     }
 }
-impl MatchExpr {
+impl CastExpr {
     pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
-    pub fn match_arm_list(&self) -> Option<MatchArmList> {
+    pub fn type_ref(&self) -> Option<TypeRef> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MatchGuard {
+pub struct RefExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for MatchGuard {
+impl AstNode for RefExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            MATCH_GUARD => true,
+            REF_EXPR => true,
             _ => false,
         }
     }
@@ -1818,19 +1549,19 @@ impl AstNode for MatchGuard {
         &self.syntax
     }
 }
-impl MatchGuard {
+impl RefExpr {
     pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MethodCallExpr {
+pub struct PrefixExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for MethodCallExpr {
+impl AstNode for PrefixExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            METHOD_CALL_EXPR => true,
+            PREFIX_EXPR => true,
             _ => false,
         }
     }
@@ -1845,26 +1576,19 @@ impl AstNode for MethodCallExpr {
         &self.syntax
     }
 }
-impl ast::ArgListOwner for MethodCallExpr {}
-impl MethodCallExpr {
+impl PrefixExpr {
     pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
-    pub fn name_ref(&self) -> Option<NameRef> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn type_arg_list(&self) -> Option<TypeArgList> {
-        AstChildren::new(&self.syntax).next()
-    }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Module {
+pub struct BoxExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Module {
+impl AstNode for BoxExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            MODULE => true,
+            BOX_EXPR => true,
             _ => false,
         }
     }
@@ -1879,144 +1603,42 @@ impl AstNode for Module {
         &self.syntax
     }
 }
-impl ast::VisibilityOwner for Module {}
-impl ast::NameOwner for Module {}
-impl ast::AttrsOwner for Module {}
-impl ast::DocCommentsOwner for Module {}
-impl Module {
-    pub fn item_list(&self) -> Option<ItemList> {
+impl BoxExpr {
+    pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum ModuleItem {
-    StructDef(StructDef),
-    UnionDef(UnionDef),
-    EnumDef(EnumDef),
-    FnDef(FnDef),
-    TraitDef(TraitDef),
-    TypeAliasDef(TypeAliasDef),
-    ImplBlock(ImplBlock),
-    UseItem(UseItem),
-    ExternCrateItem(ExternCrateItem),
-    ConstDef(ConstDef),
-    StaticDef(StaticDef),
-    Module(Module),
-}
-impl From<StructDef> for ModuleItem {
-    fn from(node: StructDef) -> ModuleItem {
-        ModuleItem::StructDef(node)
-    }
-}
-impl From<UnionDef> for ModuleItem {
-    fn from(node: UnionDef) -> ModuleItem {
-        ModuleItem::UnionDef(node)
-    }
-}
-impl From<EnumDef> for ModuleItem {
-    fn from(node: EnumDef) -> ModuleItem {
-        ModuleItem::EnumDef(node)
-    }
-}
-impl From<FnDef> for ModuleItem {
-    fn from(node: FnDef) -> ModuleItem {
-        ModuleItem::FnDef(node)
-    }
-}
-impl From<TraitDef> for ModuleItem {
-    fn from(node: TraitDef) -> ModuleItem {
-        ModuleItem::TraitDef(node)
-    }
-}
-impl From<TypeAliasDef> for ModuleItem {
-    fn from(node: TypeAliasDef) -> ModuleItem {
-        ModuleItem::TypeAliasDef(node)
-    }
-}
-impl From<ImplBlock> for ModuleItem {
-    fn from(node: ImplBlock) -> ModuleItem {
-        ModuleItem::ImplBlock(node)
-    }
-}
-impl From<UseItem> for ModuleItem {
-    fn from(node: UseItem) -> ModuleItem {
-        ModuleItem::UseItem(node)
-    }
-}
-impl From<ExternCrateItem> for ModuleItem {
-    fn from(node: ExternCrateItem) -> ModuleItem {
-        ModuleItem::ExternCrateItem(node)
-    }
-}
-impl From<ConstDef> for ModuleItem {
-    fn from(node: ConstDef) -> ModuleItem {
-        ModuleItem::ConstDef(node)
-    }
-}
-impl From<StaticDef> for ModuleItem {
-    fn from(node: StaticDef) -> ModuleItem {
-        ModuleItem::StaticDef(node)
-    }
-}
-impl From<Module> for ModuleItem {
-    fn from(node: Module) -> ModuleItem {
-        ModuleItem::Module(node)
-    }
+pub struct RangeExpr {
+    pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ModuleItem {
+impl AstNode for RangeExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF
-            | IMPL_BLOCK | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true,
+            RANGE_EXPR => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        let res = match syntax.kind() {
-            STRUCT_DEF => ModuleItem::StructDef(StructDef { syntax }),
-            UNION_DEF => ModuleItem::UnionDef(UnionDef { syntax }),
-            ENUM_DEF => ModuleItem::EnumDef(EnumDef { syntax }),
-            FN_DEF => ModuleItem::FnDef(FnDef { syntax }),
-            TRAIT_DEF => ModuleItem::TraitDef(TraitDef { syntax }),
-            TYPE_ALIAS_DEF => ModuleItem::TypeAliasDef(TypeAliasDef { syntax }),
-            IMPL_BLOCK => ModuleItem::ImplBlock(ImplBlock { syntax }),
-            USE_ITEM => ModuleItem::UseItem(UseItem { syntax }),
-            EXTERN_CRATE_ITEM => ModuleItem::ExternCrateItem(ExternCrateItem { syntax }),
-            CONST_DEF => ModuleItem::ConstDef(ConstDef { syntax }),
-            STATIC_DEF => ModuleItem::StaticDef(StaticDef { syntax }),
-            MODULE => ModuleItem::Module(Module { syntax }),
-            _ => return None,
-        };
-        Some(res)
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
     }
     fn syntax(&self) -> &SyntaxNode {
-        match self {
-            ModuleItem::StructDef(it) => &it.syntax,
-            ModuleItem::UnionDef(it) => &it.syntax,
-            ModuleItem::EnumDef(it) => &it.syntax,
-            ModuleItem::FnDef(it) => &it.syntax,
-            ModuleItem::TraitDef(it) => &it.syntax,
-            ModuleItem::TypeAliasDef(it) => &it.syntax,
-            ModuleItem::ImplBlock(it) => &it.syntax,
-            ModuleItem::UseItem(it) => &it.syntax,
-            ModuleItem::ExternCrateItem(it) => &it.syntax,
-            ModuleItem::ConstDef(it) => &it.syntax,
-            ModuleItem::StaticDef(it) => &it.syntax,
-            ModuleItem::Module(it) => &it.syntax,
-        }
+        &self.syntax
     }
 }
-impl ast::AttrsOwner for ModuleItem {}
-impl ast::VisibilityOwner for ModuleItem {}
-impl ModuleItem {}
+impl RangeExpr {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Name {
+pub struct BinExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Name {
+impl AstNode for BinExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            NAME => true,
+            BIN_EXPR => true,
             _ => false,
         }
     }
@@ -2031,15 +1653,15 @@ impl AstNode for Name {
         &self.syntax
     }
 }
-impl Name {}
+impl BinExpr {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct NameRef {
+pub struct Literal {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for NameRef {
+impl AstNode for Literal {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            NAME_REF => true,
+            LITERAL => true,
             _ => false,
         }
     }
@@ -2054,15 +1676,15 @@ impl AstNode for NameRef {
         &self.syntax
     }
 }
-impl NameRef {}
+impl Literal {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct NeverType {
+pub struct MatchExpr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for NeverType {
+impl AstNode for MatchExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            NEVER_TYPE => true,
+            MATCH_EXPR => true,
             _ => false,
         }
     }
@@ -2077,64 +1699,22 @@ impl AstNode for NeverType {
         &self.syntax
     }
 }
-impl NeverType {}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum NominalDef {
-    StructDef(StructDef),
-    EnumDef(EnumDef),
-    UnionDef(UnionDef),
-}
-impl From<StructDef> for NominalDef {
-    fn from(node: StructDef) -> NominalDef {
-        NominalDef::StructDef(node)
-    }
-}
-impl From<EnumDef> for NominalDef {
-    fn from(node: EnumDef) -> NominalDef {
-        NominalDef::EnumDef(node)
-    }
-}
-impl From<UnionDef> for NominalDef {
-    fn from(node: UnionDef) -> NominalDef {
-        NominalDef::UnionDef(node)
-    }
-}
-impl AstNode for NominalDef {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            STRUCT_DEF | ENUM_DEF | UNION_DEF => true,
-            _ => false,
-        }
-    }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        let res = match syntax.kind() {
-            STRUCT_DEF => NominalDef::StructDef(StructDef { syntax }),
-            ENUM_DEF => NominalDef::EnumDef(EnumDef { syntax }),
-            UNION_DEF => NominalDef::UnionDef(UnionDef { syntax }),
-            _ => return None,
-        };
-        Some(res)
+impl MatchExpr {
+    pub fn expr(&self) -> Option<Expr> {
+        AstChildren::new(&self.syntax).next()
     }
-    fn syntax(&self) -> &SyntaxNode {
-        match self {
-            NominalDef::StructDef(it) => &it.syntax,
-            NominalDef::EnumDef(it) => &it.syntax,
-            NominalDef::UnionDef(it) => &it.syntax,
-        }
+    pub fn match_arm_list(&self) -> Option<MatchArmList> {
+        AstChildren::new(&self.syntax).next()
     }
 }
-impl ast::NameOwner for NominalDef {}
-impl ast::TypeParamsOwner for NominalDef {}
-impl ast::AttrsOwner for NominalDef {}
-impl NominalDef {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Param {
+pub struct MatchArmList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Param {
+impl AstNode for MatchArmList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PARAM => true,
+            MATCH_ARM_LIST => true,
             _ => false,
         }
     }
@@ -2149,21 +1729,20 @@ impl AstNode for Param {
         &self.syntax
     }
 }
-impl ast::TypeAscriptionOwner for Param {}
-impl ast::AttrsOwner for Param {}
-impl Param {
-    pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+impl ast::AttrsOwner for MatchArmList {}
+impl MatchArmList {
+    pub fn arms(&self) -> AstChildren<MatchArm> {
+        AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ParamList {
+pub struct MatchArm {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ParamList {
+impl AstNode for MatchArm {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PARAM_LIST => true,
+            MATCH_ARM => true,
             _ => false,
         }
     }
@@ -2178,22 +1757,26 @@ impl AstNode for ParamList {
         &self.syntax
     }
 }
-impl ParamList {
-    pub fn params(&self) -> AstChildren<Param> {
+impl ast::AttrsOwner for MatchArm {}
+impl MatchArm {
+    pub fn pats(&self) -> AstChildren<Pat> {
         AstChildren::new(&self.syntax)
     }
-    pub fn self_param(&self) -> Option<SelfParam> {
+    pub fn guard(&self) -> Option<MatchGuard> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ParenExpr {
+pub struct MatchGuard {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ParenExpr {
+impl AstNode for MatchGuard {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PAREN_EXPR => true,
+            MATCH_GUARD => true,
             _ => false,
         }
     }
@@ -2208,19 +1791,19 @@ impl AstNode for ParenExpr {
         &self.syntax
     }
 }
-impl ParenExpr {
+impl MatchGuard {
     pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ParenType {
+pub struct RecordLit {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ParenType {
+impl AstNode for RecordLit {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PAREN_TYPE => true,
+            RECORD_LIT => true,
             _ => false,
         }
     }
@@ -2235,140 +1818,22 @@ impl AstNode for ParenType {
         &self.syntax
     }
 }
-impl ParenType {
-    pub fn type_ref(&self) -> Option<TypeRef> {
+impl RecordLit {
+    pub fn path(&self) -> Option<Path> {
         AstChildren::new(&self.syntax).next()
     }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum Pat {
-    RefPat(RefPat),
-    BoxPat(BoxPat),
-    BindPat(BindPat),
-    PlaceholderPat(PlaceholderPat),
-    DotDotPat(DotDotPat),
-    PathPat(PathPat),
-    RecordPat(RecordPat),
-    TupleStructPat(TupleStructPat),
-    TuplePat(TuplePat),
-    SlicePat(SlicePat),
-    RangePat(RangePat),
-    LiteralPat(LiteralPat),
-}
-impl From<RefPat> for Pat {
-    fn from(node: RefPat) -> Pat {
-        Pat::RefPat(node)
-    }
-}
-impl From<BoxPat> for Pat {
-    fn from(node: BoxPat) -> Pat {
-        Pat::BoxPat(node)
-    }
-}
-impl From<BindPat> for Pat {
-    fn from(node: BindPat) -> Pat {
-        Pat::BindPat(node)
-    }
-}
-impl From<PlaceholderPat> for Pat {
-    fn from(node: PlaceholderPat) -> Pat {
-        Pat::PlaceholderPat(node)
-    }
-}
-impl From<DotDotPat> for Pat {
-    fn from(node: DotDotPat) -> Pat {
-        Pat::DotDotPat(node)
-    }
-}
-impl From<PathPat> for Pat {
-    fn from(node: PathPat) -> Pat {
-        Pat::PathPat(node)
-    }
-}
-impl From<RecordPat> for Pat {
-    fn from(node: RecordPat) -> Pat {
-        Pat::RecordPat(node)
-    }
-}
-impl From<TupleStructPat> for Pat {
-    fn from(node: TupleStructPat) -> Pat {
-        Pat::TupleStructPat(node)
-    }
-}
-impl From<TuplePat> for Pat {
-    fn from(node: TuplePat) -> Pat {
-        Pat::TuplePat(node)
-    }
-}
-impl From<SlicePat> for Pat {
-    fn from(node: SlicePat) -> Pat {
-        Pat::SlicePat(node)
-    }
-}
-impl From<RangePat> for Pat {
-    fn from(node: RangePat) -> Pat {
-        Pat::RangePat(node)
-    }
-}
-impl From<LiteralPat> for Pat {
-    fn from(node: LiteralPat) -> Pat {
-        Pat::LiteralPat(node)
-    }
-}
-impl AstNode for Pat {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT | PATH_PAT
-            | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT | LITERAL_PAT => {
-                true
-            }
-            _ => false,
-        }
-    }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        let res = match syntax.kind() {
-            REF_PAT => Pat::RefPat(RefPat { syntax }),
-            BOX_PAT => Pat::BoxPat(BoxPat { syntax }),
-            BIND_PAT => Pat::BindPat(BindPat { syntax }),
-            PLACEHOLDER_PAT => Pat::PlaceholderPat(PlaceholderPat { syntax }),
-            DOT_DOT_PAT => Pat::DotDotPat(DotDotPat { syntax }),
-            PATH_PAT => Pat::PathPat(PathPat { syntax }),
-            RECORD_PAT => Pat::RecordPat(RecordPat { syntax }),
-            TUPLE_STRUCT_PAT => Pat::TupleStructPat(TupleStructPat { syntax }),
-            TUPLE_PAT => Pat::TuplePat(TuplePat { syntax }),
-            SLICE_PAT => Pat::SlicePat(SlicePat { syntax }),
-            RANGE_PAT => Pat::RangePat(RangePat { syntax }),
-            LITERAL_PAT => Pat::LiteralPat(LiteralPat { syntax }),
-            _ => return None,
-        };
-        Some(res)
-    }
-    fn syntax(&self) -> &SyntaxNode {
-        match self {
-            Pat::RefPat(it) => &it.syntax,
-            Pat::BoxPat(it) => &it.syntax,
-            Pat::BindPat(it) => &it.syntax,
-            Pat::PlaceholderPat(it) => &it.syntax,
-            Pat::DotDotPat(it) => &it.syntax,
-            Pat::PathPat(it) => &it.syntax,
-            Pat::RecordPat(it) => &it.syntax,
-            Pat::TupleStructPat(it) => &it.syntax,
-            Pat::TuplePat(it) => &it.syntax,
-            Pat::SlicePat(it) => &it.syntax,
-            Pat::RangePat(it) => &it.syntax,
-            Pat::LiteralPat(it) => &it.syntax,
-        }
+    pub fn record_field_list(&self) -> Option<RecordFieldList> {
+        AstChildren::new(&self.syntax).next()
     }
 }
-impl Pat {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Path {
+pub struct RecordFieldList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Path {
+impl AstNode for RecordFieldList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PATH => true,
+            RECORD_FIELD_LIST => true,
             _ => false,
         }
     }
@@ -2383,22 +1848,22 @@ impl AstNode for Path {
         &self.syntax
     }
 }
-impl Path {
-    pub fn segment(&self) -> Option<PathSegment> {
-        AstChildren::new(&self.syntax).next()
+impl RecordFieldList {
+    pub fn fields(&self) -> AstChildren<RecordField> {
+        AstChildren::new(&self.syntax)
     }
-    pub fn qualifier(&self) -> Option<Path> {
+    pub fn spread(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct PathExpr {
+pub struct RecordField {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for PathExpr {
+impl AstNode for RecordField {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PATH_EXPR => true,
+            RECORD_FIELD => true,
             _ => false,
         }
     }
@@ -2413,19 +1878,22 @@ impl AstNode for PathExpr {
         &self.syntax
     }
 }
-impl PathExpr {
-    pub fn path(&self) -> Option<Path> {
+impl RecordField {
+    pub fn name_ref(&self) -> Option<NameRef> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct PathPat {
+pub struct RefPat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for PathPat {
+impl AstNode for RefPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PATH_PAT => true,
+            REF_PAT => true,
             _ => false,
         }
     }
@@ -2440,19 +1908,19 @@ impl AstNode for PathPat {
         &self.syntax
     }
 }
-impl PathPat {
-    pub fn path(&self) -> Option<Path> {
+impl RefPat {
+    pub fn pat(&self) -> Option<Pat> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct PathSegment {
+pub struct BoxPat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for PathSegment {
+impl AstNode for BoxPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PATH_SEGMENT => true,
+            BOX_PAT => true,
             _ => false,
         }
     }
@@ -2467,31 +1935,19 @@ impl AstNode for PathSegment {
         &self.syntax
     }
 }
-impl PathSegment {
-    pub fn name_ref(&self) -> Option<NameRef> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn type_arg_list(&self) -> Option<TypeArgList> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn param_list(&self) -> Option<ParamList> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn ret_type(&self) -> Option<RetType> {
-        AstChildren::new(&self.syntax).next()
-    }
-    pub fn path_type(&self) -> Option<PathType> {
+impl BoxPat {
+    pub fn pat(&self) -> Option<Pat> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct PathType {
+pub struct BindPat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for PathType {
+impl AstNode for BindPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PATH_TYPE => true,
+            BIND_PAT => true,
             _ => false,
         }
     }
@@ -2506,8 +1962,9 @@ impl AstNode for PathType {
         &self.syntax
     }
 }
-impl PathType {
-    pub fn path(&self) -> Option<Path> {
+impl ast::NameOwner for BindPat {}
+impl BindPat {
+    pub fn pat(&self) -> Option<Pat> {
         AstChildren::new(&self.syntax).next()
     }
 }
@@ -2535,13 +1992,13 @@ impl AstNode for PlaceholderPat {
 }
 impl PlaceholderPat {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct PlaceholderType {
+pub struct DotDotPat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for PlaceholderType {
+impl AstNode for DotDotPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PLACEHOLDER_TYPE => true,
+            DOT_DOT_PAT => true,
             _ => false,
         }
     }
@@ -2556,15 +2013,15 @@ impl AstNode for PlaceholderType {
         &self.syntax
     }
 }
-impl PlaceholderType {}
+impl DotDotPat {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct PointerType {
+pub struct PathPat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for PointerType {
+impl AstNode for PathPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            POINTER_TYPE => true,
+            PATH_PAT => true,
             _ => false,
         }
     }
@@ -2579,19 +2036,19 @@ impl AstNode for PointerType {
         &self.syntax
     }
 }
-impl PointerType {
-    pub fn type_ref(&self) -> Option<TypeRef> {
+impl PathPat {
+    pub fn path(&self) -> Option<Path> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct PrefixExpr {
+pub struct SlicePat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for PrefixExpr {
+impl AstNode for SlicePat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            PREFIX_EXPR => true,
+            SLICE_PAT => true,
             _ => false,
         }
     }
@@ -2606,19 +2063,15 @@ impl AstNode for PrefixExpr {
         &self.syntax
     }
 }
-impl PrefixExpr {
-    pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
-    }
-}
+impl SlicePat {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RangeExpr {
+pub struct RangePat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RangeExpr {
+impl AstNode for RangePat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RANGE_EXPR => true,
+            RANGE_PAT => true,
             _ => false,
         }
     }
@@ -2633,15 +2086,15 @@ impl AstNode for RangeExpr {
         &self.syntax
     }
 }
-impl RangeExpr {}
+impl RangePat {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RangePat {
+pub struct LiteralPat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RangePat {
+impl AstNode for LiteralPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RANGE_PAT => true,
+            LITERAL_PAT => true,
             _ => false,
         }
     }
@@ -2656,15 +2109,19 @@ impl AstNode for RangePat {
         &self.syntax
     }
 }
-impl RangePat {}
+impl LiteralPat {
+    pub fn literal(&self) -> Option<Literal> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RecordField {
+pub struct RecordPat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RecordField {
+impl AstNode for RecordPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RECORD_FIELD => true,
+            RECORD_PAT => true,
             _ => false,
         }
     }
@@ -2679,22 +2136,22 @@ impl AstNode for RecordField {
         &self.syntax
     }
 }
-impl RecordField {
-    pub fn name_ref(&self) -> Option<NameRef> {
+impl RecordPat {
+    pub fn record_field_pat_list(&self) -> Option<RecordFieldPatList> {
         AstChildren::new(&self.syntax).next()
     }
-    pub fn expr(&self) -> Option<Expr> {
+    pub fn path(&self) -> Option<Path> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RecordFieldDef {
+pub struct RecordFieldPatList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RecordFieldDef {
+impl AstNode for RecordFieldPatList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RECORD_FIELD_DEF => true,
+            RECORD_FIELD_PAT_LIST => true,
             _ => false,
         }
     }
@@ -2709,20 +2166,22 @@ impl AstNode for RecordFieldDef {
         &self.syntax
     }
 }
-impl ast::VisibilityOwner for RecordFieldDef {}
-impl ast::NameOwner for RecordFieldDef {}
-impl ast::AttrsOwner for RecordFieldDef {}
-impl ast::DocCommentsOwner for RecordFieldDef {}
-impl ast::TypeAscriptionOwner for RecordFieldDef {}
-impl RecordFieldDef {}
+impl RecordFieldPatList {
+    pub fn record_field_pats(&self) -> AstChildren<RecordFieldPat> {
+        AstChildren::new(&self.syntax)
+    }
+    pub fn bind_pats(&self) -> AstChildren<BindPat> {
+        AstChildren::new(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RecordFieldDefList {
+pub struct RecordFieldPat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RecordFieldDefList {
+impl AstNode for RecordFieldPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RECORD_FIELD_DEF_LIST => true,
+            RECORD_FIELD_PAT => true,
             _ => false,
         }
     }
@@ -2737,19 +2196,20 @@ impl AstNode for RecordFieldDefList {
         &self.syntax
     }
 }
-impl RecordFieldDefList {
-    pub fn fields(&self) -> AstChildren<RecordFieldDef> {
-        AstChildren::new(&self.syntax)
+impl ast::NameOwner for RecordFieldPat {}
+impl RecordFieldPat {
+    pub fn pat(&self) -> Option<Pat> {
+        AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RecordFieldList {
+pub struct TupleStructPat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RecordFieldList {
+impl AstNode for TupleStructPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RECORD_FIELD_LIST => true,
+            TUPLE_STRUCT_PAT => true,
             _ => false,
         }
     }
@@ -2764,22 +2224,22 @@ impl AstNode for RecordFieldList {
         &self.syntax
     }
 }
-impl RecordFieldList {
-    pub fn fields(&self) -> AstChildren<RecordField> {
-        AstChildren::new(&self.syntax)
-    }
-    pub fn spread(&self) -> Option<Expr> {
+impl TupleStructPat {
+    pub fn path(&self) -> Option<Path> {
         AstChildren::new(&self.syntax).next()
     }
+    pub fn args(&self) -> AstChildren<Pat> {
+        AstChildren::new(&self.syntax)
+    }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RecordFieldPat {
+pub struct TuplePat {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RecordFieldPat {
+impl AstNode for TuplePat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RECORD_FIELD_PAT => true,
+            TUPLE_PAT => true,
             _ => false,
         }
     }
@@ -2794,20 +2254,19 @@ impl AstNode for RecordFieldPat {
         &self.syntax
     }
 }
-impl ast::NameOwner for RecordFieldPat {}
-impl RecordFieldPat {
-    pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+impl TuplePat {
+    pub fn args(&self) -> AstChildren<Pat> {
+        AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RecordFieldPatList {
+pub struct Visibility {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RecordFieldPatList {
+impl AstNode for Visibility {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RECORD_FIELD_PAT_LIST => true,
+            VISIBILITY => true,
             _ => false,
         }
     }
@@ -2822,22 +2281,38 @@ impl AstNode for RecordFieldPatList {
         &self.syntax
     }
 }
-impl RecordFieldPatList {
-    pub fn record_field_pats(&self) -> AstChildren<RecordFieldPat> {
-        AstChildren::new(&self.syntax)
+impl Visibility {}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Name {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AstNode for Name {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            NAME => true,
+            _ => false,
+        }
     }
-    pub fn bind_pats(&self) -> AstChildren<BindPat> {
-        AstChildren::new(&self.syntax)
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
 }
+impl Name {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RecordLit {
+pub struct NameRef {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RecordLit {
+impl AstNode for NameRef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RECORD_LIT => true,
+            NAME_REF => true,
             _ => false,
         }
     }
@@ -2852,22 +2327,48 @@ impl AstNode for RecordLit {
         &self.syntax
     }
 }
-impl RecordLit {
-    pub fn path(&self) -> Option<Path> {
+impl NameRef {}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct MacroCall {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AstNode for MacroCall {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            MACRO_CALL => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
+    }
+}
+impl ast::NameOwner for MacroCall {}
+impl ast::AttrsOwner for MacroCall {}
+impl ast::DocCommentsOwner for MacroCall {}
+impl MacroCall {
+    pub fn token_tree(&self) -> Option<TokenTree> {
         AstChildren::new(&self.syntax).next()
     }
-    pub fn record_field_list(&self) -> Option<RecordFieldList> {
+    pub fn path(&self) -> Option<Path> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RecordPat {
+pub struct Attr {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RecordPat {
+impl AstNode for Attr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RECORD_PAT => true,
+            ATTR => true,
             _ => false,
         }
     }
@@ -2882,22 +2383,22 @@ impl AstNode for RecordPat {
         &self.syntax
     }
 }
-impl RecordPat {
-    pub fn record_field_pat_list(&self) -> Option<RecordFieldPatList> {
+impl Attr {
+    pub fn path(&self) -> Option<Path> {
         AstChildren::new(&self.syntax).next()
     }
-    pub fn path(&self) -> Option<Path> {
+    pub fn input(&self) -> Option<AttrInput> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RefExpr {
+pub struct TokenTree {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RefExpr {
+impl AstNode for TokenTree {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            REF_EXPR => true,
+            TOKEN_TREE => true,
             _ => false,
         }
     }
@@ -2912,19 +2413,15 @@ impl AstNode for RefExpr {
         &self.syntax
     }
 }
-impl RefExpr {
-    pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
-    }
-}
+impl TokenTree {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RefPat {
+pub struct TypeParamList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RefPat {
+impl AstNode for TypeParamList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            REF_PAT => true,
+            TYPE_PARAM_LIST => true,
             _ => false,
         }
     }
@@ -2939,19 +2436,22 @@ impl AstNode for RefPat {
         &self.syntax
     }
 }
-impl RefPat {
-    pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+impl TypeParamList {
+    pub fn type_params(&self) -> AstChildren<TypeParam> {
+        AstChildren::new(&self.syntax)
+    }
+    pub fn lifetime_params(&self) -> AstChildren<LifetimeParam> {
+        AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ReferenceType {
+pub struct TypeParam {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ReferenceType {
+impl AstNode for TypeParam {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            REFERENCE_TYPE => true,
+            TYPE_PARAM => true,
             _ => false,
         }
     }
@@ -2966,19 +2466,22 @@ impl AstNode for ReferenceType {
         &self.syntax
     }
 }
-impl ReferenceType {
-    pub fn type_ref(&self) -> Option<TypeRef> {
+impl ast::NameOwner for TypeParam {}
+impl ast::AttrsOwner for TypeParam {}
+impl ast::TypeBoundsOwner for TypeParam {}
+impl TypeParam {
+    pub fn default_type(&self) -> Option<TypeRef> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RetType {
+pub struct ConstParam {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for RetType {
+impl AstNode for ConstParam {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RET_TYPE => true,
+            CONST_PARAM => true,
             _ => false,
         }
     }
@@ -2993,19 +2496,22 @@ impl AstNode for RetType {
         &self.syntax
     }
 }
-impl RetType {
-    pub fn type_ref(&self) -> Option<TypeRef> {
+impl ast::NameOwner for ConstParam {}
+impl ast::AttrsOwner for ConstParam {}
+impl ast::TypeAscriptionOwner for ConstParam {}
+impl ConstParam {
+    pub fn default_val(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ReturnExpr {
+pub struct LifetimeParam {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for ReturnExpr {
+impl AstNode for LifetimeParam {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            RETURN_EXPR => true,
+            LIFETIME_PARAM => true,
             _ => false,
         }
     }
@@ -3020,19 +2526,16 @@ impl AstNode for ReturnExpr {
         &self.syntax
     }
 }
-impl ReturnExpr {
-    pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
-    }
-}
+impl ast::AttrsOwner for LifetimeParam {}
+impl LifetimeParam {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct SelfParam {
+pub struct TypeBound {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for SelfParam {
+impl AstNode for TypeBound {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            SELF_PARAM => true,
+            TYPE_BOUND => true,
             _ => false,
         }
     }
@@ -3047,17 +2550,19 @@ impl AstNode for SelfParam {
         &self.syntax
     }
 }
-impl ast::TypeAscriptionOwner for SelfParam {}
-impl ast::AttrsOwner for SelfParam {}
-impl SelfParam {}
+impl TypeBound {
+    pub fn type_ref(&self) -> Option<TypeRef> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct SlicePat {
+pub struct TypeBoundList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for SlicePat {
+impl AstNode for TypeBoundList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            SLICE_PAT => true,
+            TYPE_BOUND_LIST => true,
             _ => false,
         }
     }
@@ -3072,15 +2577,19 @@ impl AstNode for SlicePat {
         &self.syntax
     }
 }
-impl SlicePat {}
+impl TypeBoundList {
+    pub fn bounds(&self) -> AstChildren<TypeBound> {
+        AstChildren::new(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct SliceType {
+pub struct WherePred {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for SliceType {
+impl AstNode for WherePred {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            SLICE_TYPE => true,
+            WHERE_PRED => true,
             _ => false,
         }
     }
@@ -3095,19 +2604,20 @@ impl AstNode for SliceType {
         &self.syntax
     }
 }
-impl SliceType {
+impl ast::TypeBoundsOwner for WherePred {}
+impl WherePred {
     pub fn type_ref(&self) -> Option<TypeRef> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct SourceFile {
+pub struct WhereClause {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for SourceFile {
+impl AstNode for WhereClause {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            SOURCE_FILE => true,
+            WHERE_CLAUSE => true,
             _ => false,
         }
     }
@@ -3122,21 +2632,19 @@ impl AstNode for SourceFile {
         &self.syntax
     }
 }
-impl ast::ModuleItemOwner for SourceFile {}
-impl ast::FnDefOwner for SourceFile {}
-impl SourceFile {
-    pub fn modules(&self) -> AstChildren<Module> {
+impl WhereClause {
+    pub fn predicates(&self) -> AstChildren<WherePred> {
         AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct StaticDef {
+pub struct ExprStmt {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for StaticDef {
+impl AstNode for ExprStmt {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            STATIC_DEF => true,
+            EXPR_STMT => true,
             _ => false,
         }
     }
@@ -3151,63 +2659,50 @@ impl AstNode for StaticDef {
         &self.syntax
     }
 }
-impl ast::VisibilityOwner for StaticDef {}
-impl ast::NameOwner for StaticDef {}
-impl ast::TypeParamsOwner for StaticDef {}
-impl ast::AttrsOwner for StaticDef {}
-impl ast::DocCommentsOwner for StaticDef {}
-impl ast::TypeAscriptionOwner for StaticDef {}
-impl StaticDef {
-    pub fn body(&self) -> Option<Expr> {
+impl ExprStmt {
+    pub fn expr(&self) -> Option<Expr> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum Stmt {
-    ExprStmt(ExprStmt),
-    LetStmt(LetStmt),
-}
-impl From<ExprStmt> for Stmt {
-    fn from(node: ExprStmt) -> Stmt {
-        Stmt::ExprStmt(node)
-    }
-}
-impl From<LetStmt> for Stmt {
-    fn from(node: LetStmt) -> Stmt {
-        Stmt::LetStmt(node)
-    }
+pub struct LetStmt {
+    pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for Stmt {
+impl AstNode for LetStmt {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            EXPR_STMT | LET_STMT => true,
+            LET_STMT => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        let res = match syntax.kind() {
-            EXPR_STMT => Stmt::ExprStmt(ExprStmt { syntax }),
-            LET_STMT => Stmt::LetStmt(LetStmt { syntax }),
-            _ => return None,
-        };
-        Some(res)
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
     }
     fn syntax(&self) -> &SyntaxNode {
-        match self {
-            Stmt::ExprStmt(it) => &it.syntax,
-            Stmt::LetStmt(it) => &it.syntax,
-        }
+        &self.syntax
+    }
+}
+impl ast::TypeAscriptionOwner for LetStmt {}
+impl LetStmt {
+    pub fn pat(&self) -> Option<Pat> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn initializer(&self) -> Option<Expr> {
+        AstChildren::new(&self.syntax).next()
     }
 }
-impl Stmt {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct StructDef {
+pub struct Condition {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for StructDef {
+impl AstNode for Condition {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            STRUCT_DEF => true,
+            CONDITION => true,
             _ => false,
         }
     }
@@ -3222,20 +2717,22 @@ impl AstNode for StructDef {
         &self.syntax
     }
 }
-impl ast::VisibilityOwner for StructDef {}
-impl ast::NameOwner for StructDef {}
-impl ast::TypeParamsOwner for StructDef {}
-impl ast::AttrsOwner for StructDef {}
-impl ast::DocCommentsOwner for StructDef {}
-impl StructDef {}
+impl Condition {
+    pub fn pat(&self) -> Option<Pat> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn expr(&self) -> Option<Expr> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TokenTree {
+pub struct Block {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TokenTree {
+impl AstNode for Block {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TOKEN_TREE => true,
+            BLOCK => true,
             _ => false,
         }
     }
@@ -3250,15 +2747,24 @@ impl AstNode for TokenTree {
         &self.syntax
     }
 }
-impl TokenTree {}
+impl ast::AttrsOwner for Block {}
+impl ast::ModuleItemOwner for Block {}
+impl Block {
+    pub fn statements(&self) -> AstChildren<Stmt> {
+        AstChildren::new(&self.syntax)
+    }
+    pub fn expr(&self) -> Option<Expr> {
+        AstChildren::new(&self.syntax).next()
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TraitDef {
+pub struct ParamList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TraitDef {
+impl AstNode for ParamList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TRAIT_DEF => true,
+            PARAM_LIST => true,
             _ => false,
         }
     }
@@ -3273,25 +2779,22 @@ impl AstNode for TraitDef {
         &self.syntax
     }
 }
-impl ast::VisibilityOwner for TraitDef {}
-impl ast::NameOwner for TraitDef {}
-impl ast::AttrsOwner for TraitDef {}
-impl ast::DocCommentsOwner for TraitDef {}
-impl ast::TypeParamsOwner for TraitDef {}
-impl ast::TypeBoundsOwner for TraitDef {}
-impl TraitDef {
-    pub fn item_list(&self) -> Option<ItemList> {
+impl ParamList {
+    pub fn self_param(&self) -> Option<SelfParam> {
         AstChildren::new(&self.syntax).next()
     }
+    pub fn params(&self) -> AstChildren<Param> {
+        AstChildren::new(&self.syntax)
+    }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TryBlockExpr {
+pub struct SelfParam {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TryBlockExpr {
+impl AstNode for SelfParam {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TRY_BLOCK_EXPR => true,
+            SELF_PARAM => true,
             _ => false,
         }
     }
@@ -3306,19 +2809,17 @@ impl AstNode for TryBlockExpr {
         &self.syntax
     }
 }
-impl TryBlockExpr {
-    pub fn body(&self) -> Option<BlockExpr> {
-        AstChildren::new(&self.syntax).next()
-    }
-}
+impl ast::TypeAscriptionOwner for SelfParam {}
+impl ast::AttrsOwner for SelfParam {}
+impl SelfParam {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TryExpr {
+pub struct Param {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TryExpr {
+impl AstNode for Param {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TRY_EXPR => true,
+            PARAM => true,
             _ => false,
         }
     }
@@ -3333,19 +2834,21 @@ impl AstNode for TryExpr {
         &self.syntax
     }
 }
-impl TryExpr {
-    pub fn expr(&self) -> Option<Expr> {
+impl ast::TypeAscriptionOwner for Param {}
+impl ast::AttrsOwner for Param {}
+impl Param {
+    pub fn pat(&self) -> Option<Pat> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TupleExpr {
+pub struct UseItem {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TupleExpr {
+impl AstNode for UseItem {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TUPLE_EXPR => true,
+            USE_ITEM => true,
             _ => false,
         }
     }
@@ -3360,19 +2863,21 @@ impl AstNode for TupleExpr {
         &self.syntax
     }
 }
-impl TupleExpr {
-    pub fn exprs(&self) -> AstChildren<Expr> {
-        AstChildren::new(&self.syntax)
+impl ast::AttrsOwner for UseItem {}
+impl ast::VisibilityOwner for UseItem {}
+impl UseItem {
+    pub fn use_tree(&self) -> Option<UseTree> {
+        AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TupleFieldDef {
+pub struct UseTree {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TupleFieldDef {
+impl AstNode for UseTree {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TUPLE_FIELD_DEF => true,
+            USE_TREE => true,
             _ => false,
         }
     }
@@ -3387,21 +2892,25 @@ impl AstNode for TupleFieldDef {
         &self.syntax
     }
 }
-impl ast::VisibilityOwner for TupleFieldDef {}
-impl ast::AttrsOwner for TupleFieldDef {}
-impl TupleFieldDef {
-    pub fn type_ref(&self) -> Option<TypeRef> {
+impl UseTree {
+    pub fn path(&self) -> Option<Path> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn use_tree_list(&self) -> Option<UseTreeList> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn alias(&self) -> Option<Alias> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TupleFieldDefList {
+pub struct Alias {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TupleFieldDefList {
+impl AstNode for Alias {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TUPLE_FIELD_DEF_LIST => true,
+            ALIAS => true,
             _ => false,
         }
     }
@@ -3416,19 +2925,16 @@ impl AstNode for TupleFieldDefList {
         &self.syntax
     }
 }
-impl TupleFieldDefList {
-    pub fn fields(&self) -> AstChildren<TupleFieldDef> {
-        AstChildren::new(&self.syntax)
-    }
-}
+impl ast::NameOwner for Alias {}
+impl Alias {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TuplePat {
+pub struct UseTreeList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TuplePat {
+impl AstNode for UseTreeList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TUPLE_PAT => true,
+            USE_TREE_LIST => true,
             _ => false,
         }
     }
@@ -3443,19 +2949,19 @@ impl AstNode for TuplePat {
         &self.syntax
     }
 }
-impl TuplePat {
-    pub fn args(&self) -> AstChildren<Pat> {
+impl UseTreeList {
+    pub fn use_trees(&self) -> AstChildren<UseTree> {
         AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TupleStructPat {
+pub struct ExternCrateItem {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TupleStructPat {
+impl AstNode for ExternCrateItem {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TUPLE_STRUCT_PAT => true,
+            EXTERN_CRATE_ITEM => true,
             _ => false,
         }
     }
@@ -3470,22 +2976,24 @@ impl AstNode for TupleStructPat {
         &self.syntax
     }
 }
-impl TupleStructPat {
-    pub fn args(&self) -> AstChildren<Pat> {
-        AstChildren::new(&self.syntax)
+impl ast::AttrsOwner for ExternCrateItem {}
+impl ast::VisibilityOwner for ExternCrateItem {}
+impl ExternCrateItem {
+    pub fn name_ref(&self) -> Option<NameRef> {
+        AstChildren::new(&self.syntax).next()
     }
-    pub fn path(&self) -> Option<Path> {
+    pub fn alias(&self) -> Option<Alias> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TupleType {
+pub struct ArgList {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TupleType {
+impl AstNode for ArgList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TUPLE_TYPE => true,
+            ARG_LIST => true,
             _ => false,
         }
     }
@@ -3500,19 +3008,19 @@ impl AstNode for TupleType {
         &self.syntax
     }
 }
-impl TupleType {
-    pub fn fields(&self) -> AstChildren<TypeRef> {
+impl ArgList {
+    pub fn args(&self) -> AstChildren<Expr> {
         AstChildren::new(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TypeAliasDef {
+pub struct Path {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TypeAliasDef {
+impl AstNode for Path {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TYPE_ALIAS_DEF => true,
+            PATH => true,
             _ => false,
         }
     }
@@ -3527,25 +3035,22 @@ impl AstNode for TypeAliasDef {
         &self.syntax
     }
 }
-impl ast::VisibilityOwner for TypeAliasDef {}
-impl ast::NameOwner for TypeAliasDef {}
-impl ast::TypeParamsOwner for TypeAliasDef {}
-impl ast::AttrsOwner for TypeAliasDef {}
-impl ast::DocCommentsOwner for TypeAliasDef {}
-impl ast::TypeBoundsOwner for TypeAliasDef {}
-impl TypeAliasDef {
-    pub fn type_ref(&self) -> Option<TypeRef> {
+impl Path {
+    pub fn segment(&self) -> Option<PathSegment> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn qualifier(&self) -> Option<Path> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TypeArg {
+pub struct PathSegment {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TypeArg {
+impl AstNode for PathSegment {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TYPE_ARG => true,
+            PATH_SEGMENT => true,
             _ => false,
         }
     }
@@ -3560,8 +3065,20 @@ impl AstNode for TypeArg {
         &self.syntax
     }
 }
-impl TypeArg {
-    pub fn type_ref(&self) -> Option<TypeRef> {
+impl PathSegment {
+    pub fn name_ref(&self) -> Option<NameRef> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn type_arg_list(&self) -> Option<TypeArgList> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn param_list(&self) -> Option<ParamList> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn ret_type(&self) -> Option<RetType> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn path_type(&self) -> Option<PathType> {
         AstChildren::new(&self.syntax).next()
     }
 }
@@ -3599,13 +3116,13 @@ impl TypeArgList {
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TypeBound {
+pub struct TypeArg {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TypeBound {
+impl AstNode for TypeArg {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TYPE_BOUND => true,
+            TYPE_ARG => true,
             _ => false,
         }
     }
@@ -3620,19 +3137,19 @@ impl AstNode for TypeBound {
         &self.syntax
     }
 }
-impl TypeBound {
+impl TypeArg {
     pub fn type_ref(&self) -> Option<TypeRef> {
         AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TypeBoundList {
+pub struct AssocTypeArg {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TypeBoundList {
+impl AstNode for AssocTypeArg {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TYPE_BOUND_LIST => true,
+            ASSOC_TYPE_ARG => true,
             _ => false,
         }
     }
@@ -3647,19 +3164,22 @@ impl AstNode for TypeBoundList {
         &self.syntax
     }
 }
-impl TypeBoundList {
-    pub fn bounds(&self) -> AstChildren<TypeBound> {
-        AstChildren::new(&self.syntax)
+impl AssocTypeArg {
+    pub fn name_ref(&self) -> Option<NameRef> {
+        AstChildren::new(&self.syntax).next()
+    }
+    pub fn type_ref(&self) -> Option<TypeRef> {
+        AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TypeParam {
+pub struct LifetimeArg {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TypeParam {
+impl AstNode for LifetimeArg {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TYPE_PARAM => true,
+            LIFETIME_ARG => true,
             _ => false,
         }
     }
@@ -3674,22 +3194,40 @@ impl AstNode for TypeParam {
         &self.syntax
     }
 }
-impl ast::NameOwner for TypeParam {}
-impl ast::AttrsOwner for TypeParam {}
-impl ast::TypeBoundsOwner for TypeParam {}
-impl TypeParam {
-    pub fn default_type(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+impl LifetimeArg {}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct MacroItems {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AstNode for MacroItems {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            MACRO_ITEMS => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
 }
+impl ast::ModuleItemOwner for MacroItems {}
+impl ast::FnDefOwner for MacroItems {}
+impl MacroItems {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TypeParamList {
+pub struct MacroStmts {
     pub(crate) syntax: SyntaxNode,
 }
-impl AstNode for TypeParamList {
+impl AstNode for MacroStmts {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            TYPE_PARAM_LIST => true,
+            MACRO_STMTS => true,
             _ => false,
         }
     }
@@ -3704,15 +3242,63 @@ impl AstNode for TypeParamList {
         &self.syntax
     }
 }
-impl TypeParamList {
-    pub fn type_params(&self) -> AstChildren<TypeParam> {
+impl MacroStmts {
+    pub fn statements(&self) -> AstChildren<Stmt> {
         AstChildren::new(&self.syntax)
     }
-    pub fn lifetime_params(&self) -> AstChildren<LifetimeParam> {
-        AstChildren::new(&self.syntax)
+    pub fn expr(&self) -> Option<Expr> {
+        AstChildren::new(&self.syntax).next()
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum NominalDef {
+    StructDef(StructDef),
+    EnumDef(EnumDef),
+    UnionDef(UnionDef),
+}
+impl From<StructDef> for NominalDef {
+    fn from(node: StructDef) -> NominalDef {
+        NominalDef::StructDef(node)
+    }
+}
+impl From<EnumDef> for NominalDef {
+    fn from(node: EnumDef) -> NominalDef {
+        NominalDef::EnumDef(node)
+    }
+}
+impl From<UnionDef> for NominalDef {
+    fn from(node: UnionDef) -> NominalDef {
+        NominalDef::UnionDef(node)
+    }
+}
+impl AstNode for NominalDef {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            STRUCT_DEF | ENUM_DEF | UNION_DEF => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        let res = match syntax.kind() {
+            STRUCT_DEF => NominalDef::StructDef(StructDef { syntax }),
+            ENUM_DEF => NominalDef::EnumDef(EnumDef { syntax }),
+            UNION_DEF => NominalDef::UnionDef(UnionDef { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            NominalDef::StructDef(it) => &it.syntax,
+            NominalDef::EnumDef(it) => &it.syntax,
+            NominalDef::UnionDef(it) => &it.syntax,
+        }
+    }
+}
+impl ast::NameOwner for NominalDef {}
+impl ast::TypeParamsOwner for NominalDef {}
+impl ast::AttrsOwner for NominalDef {}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum TypeRef {
     ParenType(ParenType),
     TupleType(TupleType),
@@ -3839,231 +3425,637 @@ impl AstNode for TypeRef {
         }
     }
 }
-impl TypeRef {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct UnionDef {
-    pub(crate) syntax: SyntaxNode,
+pub enum ModuleItem {
+    StructDef(StructDef),
+    UnionDef(UnionDef),
+    EnumDef(EnumDef),
+    FnDef(FnDef),
+    TraitDef(TraitDef),
+    TypeAliasDef(TypeAliasDef),
+    ImplBlock(ImplBlock),
+    UseItem(UseItem),
+    ExternCrateItem(ExternCrateItem),
+    ConstDef(ConstDef),
+    StaticDef(StaticDef),
+    Module(Module),
 }
-impl AstNode for UnionDef {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            UNION_DEF => true,
-            _ => false,
-        }
+impl From<StructDef> for ModuleItem {
+    fn from(node: StructDef) -> ModuleItem {
+        ModuleItem::StructDef(node)
     }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
+}
+impl From<UnionDef> for ModuleItem {
+    fn from(node: UnionDef) -> ModuleItem {
+        ModuleItem::UnionDef(node)
     }
-    fn syntax(&self) -> &SyntaxNode {
-        &self.syntax
+}
+impl From<EnumDef> for ModuleItem {
+    fn from(node: EnumDef) -> ModuleItem {
+        ModuleItem::EnumDef(node)
     }
 }
-impl ast::VisibilityOwner for UnionDef {}
-impl ast::NameOwner for UnionDef {}
-impl ast::TypeParamsOwner for UnionDef {}
-impl ast::AttrsOwner for UnionDef {}
-impl ast::DocCommentsOwner for UnionDef {}
-impl UnionDef {
-    pub fn record_field_def_list(&self) -> Option<RecordFieldDefList> {
-        AstChildren::new(&self.syntax).next()
+impl From<FnDef> for ModuleItem {
+    fn from(node: FnDef) -> ModuleItem {
+        ModuleItem::FnDef(node)
     }
 }
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct UseItem {
-    pub(crate) syntax: SyntaxNode,
+impl From<TraitDef> for ModuleItem {
+    fn from(node: TraitDef) -> ModuleItem {
+        ModuleItem::TraitDef(node)
+    }
 }
-impl AstNode for UseItem {
+impl From<TypeAliasDef> for ModuleItem {
+    fn from(node: TypeAliasDef) -> ModuleItem {
+        ModuleItem::TypeAliasDef(node)
+    }
+}
+impl From<ImplBlock> for ModuleItem {
+    fn from(node: ImplBlock) -> ModuleItem {
+        ModuleItem::ImplBlock(node)
+    }
+}
+impl From<UseItem> for ModuleItem {
+    fn from(node: UseItem) -> ModuleItem {
+        ModuleItem::UseItem(node)
+    }
+}
+impl From<ExternCrateItem> for ModuleItem {
+    fn from(node: ExternCrateItem) -> ModuleItem {
+        ModuleItem::ExternCrateItem(node)
+    }
+}
+impl From<ConstDef> for ModuleItem {
+    fn from(node: ConstDef) -> ModuleItem {
+        ModuleItem::ConstDef(node)
+    }
+}
+impl From<StaticDef> for ModuleItem {
+    fn from(node: StaticDef) -> ModuleItem {
+        ModuleItem::StaticDef(node)
+    }
+}
+impl From<Module> for ModuleItem {
+    fn from(node: Module) -> ModuleItem {
+        ModuleItem::Module(node)
+    }
+}
+impl AstNode for ModuleItem {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            USE_ITEM => true,
+            STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF
+            | IMPL_BLOCK | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
+        let res = match syntax.kind() {
+            STRUCT_DEF => ModuleItem::StructDef(StructDef { syntax }),
+            UNION_DEF => ModuleItem::UnionDef(UnionDef { syntax }),
+            ENUM_DEF => ModuleItem::EnumDef(EnumDef { syntax }),
+            FN_DEF => ModuleItem::FnDef(FnDef { syntax }),
+            TRAIT_DEF => ModuleItem::TraitDef(TraitDef { syntax }),
+            TYPE_ALIAS_DEF => ModuleItem::TypeAliasDef(TypeAliasDef { syntax }),
+            IMPL_BLOCK => ModuleItem::ImplBlock(ImplBlock { syntax }),
+            USE_ITEM => ModuleItem::UseItem(UseItem { syntax }),
+            EXTERN_CRATE_ITEM => ModuleItem::ExternCrateItem(ExternCrateItem { syntax }),
+            CONST_DEF => ModuleItem::ConstDef(ConstDef { syntax }),
+            STATIC_DEF => ModuleItem::StaticDef(StaticDef { syntax }),
+            MODULE => ModuleItem::Module(Module { syntax }),
+            _ => return None,
+        };
+        Some(res)
     }
     fn syntax(&self) -> &SyntaxNode {
-        &self.syntax
+        match self {
+            ModuleItem::StructDef(it) => &it.syntax,
+            ModuleItem::UnionDef(it) => &it.syntax,
+            ModuleItem::EnumDef(it) => &it.syntax,
+            ModuleItem::FnDef(it) => &it.syntax,
+            ModuleItem::TraitDef(it) => &it.syntax,
+            ModuleItem::TypeAliasDef(it) => &it.syntax,
+            ModuleItem::ImplBlock(it) => &it.syntax,
+            ModuleItem::UseItem(it) => &it.syntax,
+            ModuleItem::ExternCrateItem(it) => &it.syntax,
+            ModuleItem::ConstDef(it) => &it.syntax,
+            ModuleItem::StaticDef(it) => &it.syntax,
+            ModuleItem::Module(it) => &it.syntax,
+        }
     }
 }
-impl ast::AttrsOwner for UseItem {}
-impl ast::VisibilityOwner for UseItem {}
-impl UseItem {
-    pub fn use_tree(&self) -> Option<UseTree> {
-        AstChildren::new(&self.syntax).next()
+impl ast::AttrsOwner for ModuleItem {}
+impl ast::VisibilityOwner for ModuleItem {}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum ImplItem {
+    FnDef(FnDef),
+    TypeAliasDef(TypeAliasDef),
+    ConstDef(ConstDef),
+}
+impl From<FnDef> for ImplItem {
+    fn from(node: FnDef) -> ImplItem {
+        ImplItem::FnDef(node)
     }
 }
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct UseTree {
-    pub(crate) syntax: SyntaxNode,
+impl From<TypeAliasDef> for ImplItem {
+    fn from(node: TypeAliasDef) -> ImplItem {
+        ImplItem::TypeAliasDef(node)
+    }
 }
-impl AstNode for UseTree {
+impl From<ConstDef> for ImplItem {
+    fn from(node: ConstDef) -> ImplItem {
+        ImplItem::ConstDef(node)
+    }
+}
+impl AstNode for ImplItem {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            USE_TREE => true,
+            FN_DEF | TYPE_ALIAS_DEF | CONST_DEF => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
+        let res = match syntax.kind() {
+            FN_DEF => ImplItem::FnDef(FnDef { syntax }),
+            TYPE_ALIAS_DEF => ImplItem::TypeAliasDef(TypeAliasDef { syntax }),
+            CONST_DEF => ImplItem::ConstDef(ConstDef { syntax }),
+            _ => return None,
+        };
+        Some(res)
     }
     fn syntax(&self) -> &SyntaxNode {
-        &self.syntax
+        match self {
+            ImplItem::FnDef(it) => &it.syntax,
+            ImplItem::TypeAliasDef(it) => &it.syntax,
+            ImplItem::ConstDef(it) => &it.syntax,
+        }
     }
 }
-impl UseTree {
-    pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+impl ast::AttrsOwner for ImplItem {}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum Expr {
+    TupleExpr(TupleExpr),
+    ArrayExpr(ArrayExpr),
+    ParenExpr(ParenExpr),
+    PathExpr(PathExpr),
+    LambdaExpr(LambdaExpr),
+    IfExpr(IfExpr),
+    LoopExpr(LoopExpr),
+    ForExpr(ForExpr),
+    WhileExpr(WhileExpr),
+    ContinueExpr(ContinueExpr),
+    BreakExpr(BreakExpr),
+    Label(Label),
+    BlockExpr(BlockExpr),
+    ReturnExpr(ReturnExpr),
+    MatchExpr(MatchExpr),
+    RecordLit(RecordLit),
+    CallExpr(CallExpr),
+    IndexExpr(IndexExpr),
+    MethodCallExpr(MethodCallExpr),
+    FieldExpr(FieldExpr),
+    AwaitExpr(AwaitExpr),
+    TryExpr(TryExpr),
+    TryBlockExpr(TryBlockExpr),
+    CastExpr(CastExpr),
+    RefExpr(RefExpr),
+    PrefixExpr(PrefixExpr),
+    RangeExpr(RangeExpr),
+    BinExpr(BinExpr),
+    Literal(Literal),
+    MacroCall(MacroCall),
+    BoxExpr(BoxExpr),
+}
+impl From<TupleExpr> for Expr {
+    fn from(node: TupleExpr) -> Expr {
+        Expr::TupleExpr(node)
     }
-    pub fn use_tree_list(&self) -> Option<UseTreeList> {
-        AstChildren::new(&self.syntax).next()
+}
+impl From<ArrayExpr> for Expr {
+    fn from(node: ArrayExpr) -> Expr {
+        Expr::ArrayExpr(node)
     }
-    pub fn alias(&self) -> Option<Alias> {
-        AstChildren::new(&self.syntax).next()
+}
+impl From<ParenExpr> for Expr {
+    fn from(node: ParenExpr) -> Expr {
+        Expr::ParenExpr(node)
     }
 }
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct UseTreeList {
-    pub(crate) syntax: SyntaxNode,
+impl From<PathExpr> for Expr {
+    fn from(node: PathExpr) -> Expr {
+        Expr::PathExpr(node)
+    }
 }
-impl AstNode for UseTreeList {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            USE_TREE_LIST => true,
-            _ => false,
-        }
+impl From<LambdaExpr> for Expr {
+    fn from(node: LambdaExpr) -> Expr {
+        Expr::LambdaExpr(node)
     }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
+}
+impl From<IfExpr> for Expr {
+    fn from(node: IfExpr) -> Expr {
+        Expr::IfExpr(node)
     }
-    fn syntax(&self) -> &SyntaxNode {
-        &self.syntax
+}
+impl From<LoopExpr> for Expr {
+    fn from(node: LoopExpr) -> Expr {
+        Expr::LoopExpr(node)
     }
 }
-impl UseTreeList {
-    pub fn use_trees(&self) -> AstChildren<UseTree> {
-        AstChildren::new(&self.syntax)
+impl From<ForExpr> for Expr {
+    fn from(node: ForExpr) -> Expr {
+        Expr::ForExpr(node)
     }
 }
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Visibility {
-    pub(crate) syntax: SyntaxNode,
+impl From<WhileExpr> for Expr {
+    fn from(node: WhileExpr) -> Expr {
+        Expr::WhileExpr(node)
+    }
 }
-impl AstNode for Visibility {
+impl From<ContinueExpr> for Expr {
+    fn from(node: ContinueExpr) -> Expr {
+        Expr::ContinueExpr(node)
+    }
+}
+impl From<BreakExpr> for Expr {
+    fn from(node: BreakExpr) -> Expr {
+        Expr::BreakExpr(node)
+    }
+}
+impl From<Label> for Expr {
+    fn from(node: Label) -> Expr {
+        Expr::Label(node)
+    }
+}
+impl From<BlockExpr> for Expr {
+    fn from(node: BlockExpr) -> Expr {
+        Expr::BlockExpr(node)
+    }
+}
+impl From<ReturnExpr> for Expr {
+    fn from(node: ReturnExpr) -> Expr {
+        Expr::ReturnExpr(node)
+    }
+}
+impl From<MatchExpr> for Expr {
+    fn from(node: MatchExpr) -> Expr {
+        Expr::MatchExpr(node)
+    }
+}
+impl From<RecordLit> for Expr {
+    fn from(node: RecordLit) -> Expr {
+        Expr::RecordLit(node)
+    }
+}
+impl From<CallExpr> for Expr {
+    fn from(node: CallExpr) -> Expr {
+        Expr::CallExpr(node)
+    }
+}
+impl From<IndexExpr> for Expr {
+    fn from(node: IndexExpr) -> Expr {
+        Expr::IndexExpr(node)
+    }
+}
+impl From<MethodCallExpr> for Expr {
+    fn from(node: MethodCallExpr) -> Expr {
+        Expr::MethodCallExpr(node)
+    }
+}
+impl From<FieldExpr> for Expr {
+    fn from(node: FieldExpr) -> Expr {
+        Expr::FieldExpr(node)
+    }
+}
+impl From<AwaitExpr> for Expr {
+    fn from(node: AwaitExpr) -> Expr {
+        Expr::AwaitExpr(node)
+    }
+}
+impl From<TryExpr> for Expr {
+    fn from(node: TryExpr) -> Expr {
+        Expr::TryExpr(node)
+    }
+}
+impl From<TryBlockExpr> for Expr {
+    fn from(node: TryBlockExpr) -> Expr {
+        Expr::TryBlockExpr(node)
+    }
+}
+impl From<CastExpr> for Expr {
+    fn from(node: CastExpr) -> Expr {
+        Expr::CastExpr(node)
+    }
+}
+impl From<RefExpr> for Expr {
+    fn from(node: RefExpr) -> Expr {
+        Expr::RefExpr(node)
+    }
+}
+impl From<PrefixExpr> for Expr {
+    fn from(node: PrefixExpr) -> Expr {
+        Expr::PrefixExpr(node)
+    }
+}
+impl From<RangeExpr> for Expr {
+    fn from(node: RangeExpr) -> Expr {
+        Expr::RangeExpr(node)
+    }
+}
+impl From<BinExpr> for Expr {
+    fn from(node: BinExpr) -> Expr {
+        Expr::BinExpr(node)
+    }
+}
+impl From<Literal> for Expr {
+    fn from(node: Literal) -> Expr {
+        Expr::Literal(node)
+    }
+}
+impl From<MacroCall> for Expr {
+    fn from(node: MacroCall) -> Expr {
+        Expr::MacroCall(node)
+    }
+}
+impl From<BoxExpr> for Expr {
+    fn from(node: BoxExpr) -> Expr {
+        Expr::BoxExpr(node)
+    }
+}
+impl AstNode for Expr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            VISIBILITY => true,
+            TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR
+            | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL
+            | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR
+            | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR
+            | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL
+            | BOX_EXPR => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
+        let res = match syntax.kind() {
+            TUPLE_EXPR => Expr::TupleExpr(TupleExpr { syntax }),
+            ARRAY_EXPR => Expr::ArrayExpr(ArrayExpr { syntax }),
+            PAREN_EXPR => Expr::ParenExpr(ParenExpr { syntax }),
+            PATH_EXPR => Expr::PathExpr(PathExpr { syntax }),
+            LAMBDA_EXPR => Expr::LambdaExpr(LambdaExpr { syntax }),
+            IF_EXPR => Expr::IfExpr(IfExpr { syntax }),
+            LOOP_EXPR => Expr::LoopExpr(LoopExpr { syntax }),
+            FOR_EXPR => Expr::ForExpr(ForExpr { syntax }),
+            WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }),
+            CONTINUE_EXPR => Expr::ContinueExpr(ContinueExpr { syntax }),
+            BREAK_EXPR => Expr::BreakExpr(BreakExpr { syntax }),
+            LABEL => Expr::Label(Label { syntax }),
+            BLOCK_EXPR => Expr::BlockExpr(BlockExpr { syntax }),
+            RETURN_EXPR => Expr::ReturnExpr(ReturnExpr { syntax }),
+            MATCH_EXPR => Expr::MatchExpr(MatchExpr { syntax }),
+            RECORD_LIT => Expr::RecordLit(RecordLit { syntax }),
+            CALL_EXPR => Expr::CallExpr(CallExpr { syntax }),
+            INDEX_EXPR => Expr::IndexExpr(IndexExpr { syntax }),
+            METHOD_CALL_EXPR => Expr::MethodCallExpr(MethodCallExpr { syntax }),
+            FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }),
+            AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }),
+            TRY_EXPR => Expr::TryExpr(TryExpr { syntax }),
+            TRY_BLOCK_EXPR => Expr::TryBlockExpr(TryBlockExpr { syntax }),
+            CAST_EXPR => Expr::CastExpr(CastExpr { syntax }),
+            REF_EXPR => Expr::RefExpr(RefExpr { syntax }),
+            PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }),
+            RANGE_EXPR => Expr::RangeExpr(RangeExpr { syntax }),
+            BIN_EXPR => Expr::BinExpr(BinExpr { syntax }),
+            LITERAL => Expr::Literal(Literal { syntax }),
+            MACRO_CALL => Expr::MacroCall(MacroCall { syntax }),
+            BOX_EXPR => Expr::BoxExpr(BoxExpr { syntax }),
+            _ => return None,
+        };
+        Some(res)
     }
     fn syntax(&self) -> &SyntaxNode {
-        &self.syntax
+        match self {
+            Expr::TupleExpr(it) => &it.syntax,
+            Expr::ArrayExpr(it) => &it.syntax,
+            Expr::ParenExpr(it) => &it.syntax,
+            Expr::PathExpr(it) => &it.syntax,
+            Expr::LambdaExpr(it) => &it.syntax,
+            Expr::IfExpr(it) => &it.syntax,
+            Expr::LoopExpr(it) => &it.syntax,
+            Expr::ForExpr(it) => &it.syntax,
+            Expr::WhileExpr(it) => &it.syntax,
+            Expr::ContinueExpr(it) => &it.syntax,
+            Expr::BreakExpr(it) => &it.syntax,
+            Expr::Label(it) => &it.syntax,
+            Expr::BlockExpr(it) => &it.syntax,
+            Expr::ReturnExpr(it) => &it.syntax,
+            Expr::MatchExpr(it) => &it.syntax,
+            Expr::RecordLit(it) => &it.syntax,
+            Expr::CallExpr(it) => &it.syntax,
+            Expr::IndexExpr(it) => &it.syntax,
+            Expr::MethodCallExpr(it) => &it.syntax,
+            Expr::FieldExpr(it) => &it.syntax,
+            Expr::AwaitExpr(it) => &it.syntax,
+            Expr::TryExpr(it) => &it.syntax,
+            Expr::TryBlockExpr(it) => &it.syntax,
+            Expr::CastExpr(it) => &it.syntax,
+            Expr::RefExpr(it) => &it.syntax,
+            Expr::PrefixExpr(it) => &it.syntax,
+            Expr::RangeExpr(it) => &it.syntax,
+            Expr::BinExpr(it) => &it.syntax,
+            Expr::Literal(it) => &it.syntax,
+            Expr::MacroCall(it) => &it.syntax,
+            Expr::BoxExpr(it) => &it.syntax,
+        }
     }
 }
-impl Visibility {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct WhereClause {
-    pub(crate) syntax: SyntaxNode,
+pub enum Pat {
+    RefPat(RefPat),
+    BoxPat(BoxPat),
+    BindPat(BindPat),
+    PlaceholderPat(PlaceholderPat),
+    DotDotPat(DotDotPat),
+    PathPat(PathPat),
+    RecordPat(RecordPat),
+    TupleStructPat(TupleStructPat),
+    TuplePat(TuplePat),
+    SlicePat(SlicePat),
+    RangePat(RangePat),
+    LiteralPat(LiteralPat),
 }
-impl AstNode for WhereClause {
+impl From<RefPat> for Pat {
+    fn from(node: RefPat) -> Pat {
+        Pat::RefPat(node)
+    }
+}
+impl From<BoxPat> for Pat {
+    fn from(node: BoxPat) -> Pat {
+        Pat::BoxPat(node)
+    }
+}
+impl From<BindPat> for Pat {
+    fn from(node: BindPat) -> Pat {
+        Pat::BindPat(node)
+    }
+}
+impl From<PlaceholderPat> for Pat {
+    fn from(node: PlaceholderPat) -> Pat {
+        Pat::PlaceholderPat(node)
+    }
+}
+impl From<DotDotPat> for Pat {
+    fn from(node: DotDotPat) -> Pat {
+        Pat::DotDotPat(node)
+    }
+}
+impl From<PathPat> for Pat {
+    fn from(node: PathPat) -> Pat {
+        Pat::PathPat(node)
+    }
+}
+impl From<RecordPat> for Pat {
+    fn from(node: RecordPat) -> Pat {
+        Pat::RecordPat(node)
+    }
+}
+impl From<TupleStructPat> for Pat {
+    fn from(node: TupleStructPat) -> Pat {
+        Pat::TupleStructPat(node)
+    }
+}
+impl From<TuplePat> for Pat {
+    fn from(node: TuplePat) -> Pat {
+        Pat::TuplePat(node)
+    }
+}
+impl From<SlicePat> for Pat {
+    fn from(node: SlicePat) -> Pat {
+        Pat::SlicePat(node)
+    }
+}
+impl From<RangePat> for Pat {
+    fn from(node: RangePat) -> Pat {
+        Pat::RangePat(node)
+    }
+}
+impl From<LiteralPat> for Pat {
+    fn from(node: LiteralPat) -> Pat {
+        Pat::LiteralPat(node)
+    }
+}
+impl AstNode for Pat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            WHERE_CLAUSE => true,
+            REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT | PATH_PAT
+            | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT | LITERAL_PAT => {
+                true
+            }
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
+        let res = match syntax.kind() {
+            REF_PAT => Pat::RefPat(RefPat { syntax }),
+            BOX_PAT => Pat::BoxPat(BoxPat { syntax }),
+            BIND_PAT => Pat::BindPat(BindPat { syntax }),
+            PLACEHOLDER_PAT => Pat::PlaceholderPat(PlaceholderPat { syntax }),
+            DOT_DOT_PAT => Pat::DotDotPat(DotDotPat { syntax }),
+            PATH_PAT => Pat::PathPat(PathPat { syntax }),
+            RECORD_PAT => Pat::RecordPat(RecordPat { syntax }),
+            TUPLE_STRUCT_PAT => Pat::TupleStructPat(TupleStructPat { syntax }),
+            TUPLE_PAT => Pat::TuplePat(TuplePat { syntax }),
+            SLICE_PAT => Pat::SlicePat(SlicePat { syntax }),
+            RANGE_PAT => Pat::RangePat(RangePat { syntax }),
+            LITERAL_PAT => Pat::LiteralPat(LiteralPat { syntax }),
+            _ => return None,
+        };
+        Some(res)
     }
     fn syntax(&self) -> &SyntaxNode {
-        &self.syntax
+        match self {
+            Pat::RefPat(it) => &it.syntax,
+            Pat::BoxPat(it) => &it.syntax,
+            Pat::BindPat(it) => &it.syntax,
+            Pat::PlaceholderPat(it) => &it.syntax,
+            Pat::DotDotPat(it) => &it.syntax,
+            Pat::PathPat(it) => &it.syntax,
+            Pat::RecordPat(it) => &it.syntax,
+            Pat::TupleStructPat(it) => &it.syntax,
+            Pat::TuplePat(it) => &it.syntax,
+            Pat::SlicePat(it) => &it.syntax,
+            Pat::RangePat(it) => &it.syntax,
+            Pat::LiteralPat(it) => &it.syntax,
+        }
     }
 }
-impl WhereClause {
-    pub fn predicates(&self) -> AstChildren<WherePred> {
-        AstChildren::new(&self.syntax)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum AttrInput {
+    Literal(Literal),
+    TokenTree(TokenTree),
+}
+impl From<Literal> for AttrInput {
+    fn from(node: Literal) -> AttrInput {
+        AttrInput::Literal(node)
     }
 }
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct WherePred {
-    pub(crate) syntax: SyntaxNode,
+impl From<TokenTree> for AttrInput {
+    fn from(node: TokenTree) -> AttrInput {
+        AttrInput::TokenTree(node)
+    }
 }
-impl AstNode for WherePred {
+impl AstNode for AttrInput {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            WHERE_PRED => true,
+            LITERAL | TOKEN_TREE => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
+        let res = match syntax.kind() {
+            LITERAL => AttrInput::Literal(Literal { syntax }),
+            TOKEN_TREE => AttrInput::TokenTree(TokenTree { syntax }),
+            _ => return None,
+        };
+        Some(res)
     }
     fn syntax(&self) -> &SyntaxNode {
-        &self.syntax
+        match self {
+            AttrInput::Literal(it) => &it.syntax,
+            AttrInput::TokenTree(it) => &it.syntax,
+        }
     }
 }
-impl ast::TypeBoundsOwner for WherePred {}
-impl WherePred {
-    pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum Stmt {
+    ExprStmt(ExprStmt),
+    LetStmt(LetStmt),
+}
+impl From<ExprStmt> for Stmt {
+    fn from(node: ExprStmt) -> Stmt {
+        Stmt::ExprStmt(node)
     }
 }
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct WhileExpr {
-    pub(crate) syntax: SyntaxNode,
+impl From<LetStmt> for Stmt {
+    fn from(node: LetStmt) -> Stmt {
+        Stmt::LetStmt(node)
+    }
 }
-impl AstNode for WhileExpr {
+impl AstNode for Stmt {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            WHILE_EXPR => true,
+            EXPR_STMT | LET_STMT => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
+        let res = match syntax.kind() {
+            EXPR_STMT => Stmt::ExprStmt(ExprStmt { syntax }),
+            LET_STMT => Stmt::LetStmt(LetStmt { syntax }),
+            _ => return None,
+        };
+        Some(res)
     }
     fn syntax(&self) -> &SyntaxNode {
-        &self.syntax
-    }
-}
-impl ast::LoopBodyOwner for WhileExpr {}
-impl WhileExpr {
-    pub fn condition(&self) -> Option<Condition> {
-        AstChildren::new(&self.syntax).next()
+        match self {
+            Stmt::ExprStmt(it) => &it.syntax,
+            Stmt::LetStmt(it) => &it.syntax,
+        }
     }
 }
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index e43a724f0bc..47446a878c2 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -1,736 +1,6 @@
 // Stores definitions which must be used in multiple places
 // See `cargo xtask codegen` (defined in xtasks/src/main.rs)
 Grammar(
-    punct: [
-        (";", "SEMI"),
-        (",", "COMMA"),
-        ("(", "L_PAREN"),
-        (")", "R_PAREN"),
-        ("{", "L_CURLY"),
-        ("}", "R_CURLY"),
-        ("[", "L_BRACK"),
-        ("]", "R_BRACK"),
-        ("<", "L_ANGLE"),
-        (">", "R_ANGLE"),
-        ("@", "AT"),
-        ("#", "POUND"),
-        ("~", "TILDE"),
-        ("?", "QUESTION"),
-        ("$", "DOLLAR"),
-        ("&", "AMP"),
-        ("|", "PIPE"),
-        ("+", "PLUS"),
-        ("*", "STAR"),
-        ("/", "SLASH"),
-        ("^", "CARET"),
-        ("%", "PERCENT"),
-        ("_", "UNDERSCORE"),
-        (".", "DOT"),
-        ("..", "DOTDOT"),
-        ("...", "DOTDOTDOT"),
-        ("..=", "DOTDOTEQ"),
-        (":", "COLON"),
-        ("::", "COLONCOLON"),
-        ("=", "EQ"),
-        ("==", "EQEQ"),
-        ("=>", "FAT_ARROW"),
-        ("!", "EXCL"),
-        ("!=", "NEQ"),
-        ("-", "MINUS"),
-        ("->", "THIN_ARROW"),
-        ("<=", "LTEQ"),
-        (">=", "GTEQ"),
-        ("+=", "PLUSEQ"),
-        ("-=", "MINUSEQ"),
-        ("|=", "PIPEEQ"),
-        ("&=", "AMPEQ"),
-        ("^=", "CARETEQ"),
-        ("/=", "SLASHEQ"),
-        ("*=", "STAREQ"),
-        ("%=", "PERCENTEQ"),
-        ("&&", "AMPAMP"),
-        ("||", "PIPEPIPE"),
-        ("<<", "SHL"),
-        (">>", "SHR"),
-        ("<<=", "SHLEQ"),
-        (">>=", "SHREQ"),
-    ],
-    keywords: [
-        "async",
-        "use",
-        "fn",
-        "struct",
-        "enum",
-        "trait",
-        "impl",
-        "dyn",
-        "true",
-        "false",
-        "as",
-        "extern",
-        "crate",
-        "mod",
-        "pub",
-        "self",
-        "super",
-        "in",
-        "where",
-        "for",
-        "loop",
-        "while",
-        "continue",
-        "break",
-        "if",
-        "else",
-        "match",
-        "const",
-        "static",
-        "mut",
-        "unsafe",
-        "type",
-        "ref",
-        "let",
-        "move",
-        "return",
-        "try",
-        "box",
-        "await",
-        "macro"
-    ],
-    contextual_keywords: [
-        "auto",
-        "default",
-        "existential",
-        "union",
-    ],
-    literals: [
-        "INT_NUMBER",
-        "FLOAT_NUMBER",
-        "CHAR",
-        "BYTE",
-        "STRING",
-        "RAW_STRING",
-        "BYTE_STRING",
-        "RAW_BYTE_STRING",
-    ],
-    tokens: [
-        "ERROR",
-        "IDENT",
-        "WHITESPACE",
-        "LIFETIME",
-        "COMMENT",
-        "SHEBANG",
-        "L_DOLLAR",
-        "R_DOLLAR",
-    ],
-    nodes: [
-        "SOURCE_FILE",
-
-        "STRUCT_DEF",
-        "UNION_DEF",
-        "ENUM_DEF",
-        "FN_DEF",
-        "RET_TYPE",
-        "EXTERN_CRATE_ITEM",
-        "MODULE",
-        "USE_ITEM",
-        "STATIC_DEF",
-        "CONST_DEF",
-        "TRAIT_DEF",
-        "IMPL_BLOCK",
-        "TYPE_ALIAS_DEF",
-        "MACRO_CALL",
-        "TOKEN_TREE",
-        "MACRO_DEF",
-
-        "PAREN_TYPE",
-        "TUPLE_TYPE",
-        "NEVER_TYPE",
-        "PATH_TYPE",
-        "POINTER_TYPE",
-        "ARRAY_TYPE",
-        "SLICE_TYPE",
-        "REFERENCE_TYPE",
-        "PLACEHOLDER_TYPE",
-        "FN_POINTER_TYPE",
-        "FOR_TYPE",
-        "IMPL_TRAIT_TYPE",
-        "DYN_TRAIT_TYPE",
-
-        "REF_PAT",
-        "BOX_PAT",
-        "BIND_PAT",
-        "PLACEHOLDER_PAT",
-        "DOT_DOT_PAT",
-        "PATH_PAT",
-        "RECORD_PAT",
-        "RECORD_FIELD_PAT_LIST",
-        "RECORD_FIELD_PAT",
-        "TUPLE_STRUCT_PAT",
-        "TUPLE_PAT",
-        "SLICE_PAT",
-        "RANGE_PAT",
-        "LITERAL_PAT",
-
-        // atoms
-        "TUPLE_EXPR",
-        "ARRAY_EXPR",
-        "PAREN_EXPR",
-        "PATH_EXPR",
-        "LAMBDA_EXPR",
-        "IF_EXPR",
-        "WHILE_EXPR",
-        "CONDITION",
-        "LOOP_EXPR",
-        "FOR_EXPR",
-        "CONTINUE_EXPR",
-        "BREAK_EXPR",
-        "LABEL",
-        "BLOCK_EXPR",
-        "RETURN_EXPR",
-        "MATCH_EXPR",
-        "MATCH_ARM_LIST",
-        "MATCH_ARM",
-        "MATCH_GUARD",
-        "RECORD_LIT",
-        "RECORD_FIELD_LIST",
-        "RECORD_FIELD",
-        "TRY_BLOCK_EXPR",
-        "BOX_EXPR",
-
-        // postfix
-        "CALL_EXPR",
-        "INDEX_EXPR",
-        "METHOD_CALL_EXPR",
-        "FIELD_EXPR",
-        "AWAIT_EXPR",
-        "TRY_EXPR",
-        "CAST_EXPR",
-
-        // unary
-        "REF_EXPR",
-        "PREFIX_EXPR",
-
-        "RANGE_EXPR", // just weird
-        "BIN_EXPR",
-
-        "BLOCK",
-        "EXTERN_BLOCK",
-        "EXTERN_ITEM_LIST",
-        "ENUM_VARIANT",
-        "RECORD_FIELD_DEF_LIST",
-        "RECORD_FIELD_DEF",
-        "TUPLE_FIELD_DEF_LIST",
-        "TUPLE_FIELD_DEF",
-        "ENUM_VARIANT_LIST",
-        "ITEM_LIST",
-        "ATTR",
-        "META_ITEM", // not an item actually
-        "USE_TREE",
-        "USE_TREE_LIST",
-        "PATH",
-        "PATH_SEGMENT",
-        "LITERAL",
-        "ALIAS",
-        "VISIBILITY",
-        "WHERE_CLAUSE",
-        "WHERE_PRED",
-        "ABI",
-        "NAME",
-        "NAME_REF",
-
-        "LET_STMT",
-        "EXPR_STMT",
-
-        "TYPE_PARAM_LIST",
-        "LIFETIME_PARAM",
-        "TYPE_PARAM",
-        "CONST_PARAM",
-        "TYPE_ARG_LIST",
-        "LIFETIME_ARG",
-        "TYPE_ARG",
-        "ASSOC_TYPE_ARG",
-
-        "PARAM_LIST",
-        "PARAM",
-        "SELF_PARAM",
-        "ARG_LIST",
-        "TYPE_BOUND",
-        "TYPE_BOUND_LIST",
-
-        // macro related
-        "MACRO_ITEMS",
-        "MACRO_STMTS",
-    ],
     ast: {
-        "SourceFile": (
-            traits: [ "ModuleItemOwner", "FnDefOwner" ],
-            collections: [
-                ("modules", "Module"),
-            ]
-        ),
-        "FnDef": (
-            traits: [
-                "VisibilityOwner",
-                "NameOwner",
-                "TypeParamsOwner",
-                "AttrsOwner",
-                "DocCommentsOwner"
-            ],
-            options: [ "ParamList", ["body", "BlockExpr"], "RetType" ],
-        ),
-        "RetType": (options: ["TypeRef"]),
-        "StructDef": (
-            traits: [
-                "VisibilityOwner",
-                "NameOwner",
-                "TypeParamsOwner",
-                "AttrsOwner",
-                "DocCommentsOwner"
-            ]
-        ),
-        "UnionDef": (
-            traits: [
-                "VisibilityOwner",
-                "NameOwner",
-                "TypeParamsOwner",
-                "AttrsOwner",
-                "DocCommentsOwner"
-            ],
-            options: ["RecordFieldDefList"],
-        ),
-        "RecordFieldDefList": (collections: [("fields", "RecordFieldDef")]),
-        "RecordFieldDef": (
-            traits: [
-                "VisibilityOwner",
-                "NameOwner",
-                "AttrsOwner",
-                "DocCommentsOwner",
-                "TypeAscriptionOwner"
-            ]
-        ),
-        "TupleFieldDefList": (collections: [("fields", "TupleFieldDef")]),
-        "TupleFieldDef": ( traits: ["VisibilityOwner", "AttrsOwner"], options: ["TypeRef"]),
-        "EnumDef": ( traits: [
-            "VisibilityOwner",
-            "NameOwner",
-            "TypeParamsOwner",
-            "AttrsOwner",
-            "DocCommentsOwner"
-        ], options: [["variant_list", "EnumVariantList"]] ),
-        "EnumVariantList": ( collections: [("variants", "EnumVariant")] ),
-        "EnumVariant": ( traits: ["NameOwner", "DocCommentsOwner", "AttrsOwner"], options: ["Expr"] ),
-        "TraitDef": (
-            traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner", "TypeParamsOwner", "TypeBoundsOwner"],
-            options: ["ItemList"]
-        ),
-        "Module": (
-            traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner" ],
-            options: [ "ItemList" ]
-        ),
-        "ItemList": (
-            collections: [("impl_items", "ImplItem")],
-            traits: [ "FnDefOwner", "ModuleItemOwner" ],
-        ),
-        "ConstDef": (
-            traits: [
-                "VisibilityOwner",
-                "NameOwner",
-                "TypeParamsOwner",
-                "AttrsOwner",
-                "DocCommentsOwner",
-                "TypeAscriptionOwner",
-            ],
-            options: [ ["body","Expr"]],
-        ),
-        "StaticDef": (
-            traits: [
-                "VisibilityOwner",
-                "NameOwner",
-                "TypeParamsOwner",
-                "AttrsOwner",
-                "DocCommentsOwner",
-                "TypeAscriptionOwner",
-            ],
-            options: [ ["body","Expr"]],
-        ),
-        "TypeAliasDef": (
-            traits: [
-                "VisibilityOwner",
-                "NameOwner",
-                "TypeParamsOwner",
-                "AttrsOwner",
-                "DocCommentsOwner",
-                "TypeBoundsOwner",
-            ],
-            options: ["TypeRef"]
-        ),
-        "ImplBlock": (options: ["ItemList"], traits: ["TypeParamsOwner", "AttrsOwner"]),
-
-        "ParenType": (options: ["TypeRef"]),
-        "TupleType": ( collections: [("fields", "TypeRef")] ),
-        "NeverType": (),
-        "PathType": (options: ["Path"]),
-        "PointerType": (options: ["TypeRef"]),
-        "ArrayType": ( options: ["TypeRef", "Expr"] ),
-        "SliceType": ( options: ["TypeRef"] ),
-        "ReferenceType": (options: ["TypeRef"]),
-        "PlaceholderType": (),
-        "FnPointerType": (options: ["ParamList", "RetType"]),
-        "ForType": (options: ["TypeRef"]),
-        "ImplTraitType": (
-            traits: ["TypeBoundsOwner"],
-        ),
-        "DynTraitType": (
-            traits: ["TypeBoundsOwner"],
-        ),
-
-        "TypeRef": ( enum: [
-            "ParenType",
-            "TupleType",
-            "NeverType",
-            "PathType",
-            "PointerType",
-            "ArrayType",
-            "SliceType",
-            "ReferenceType",
-            "PlaceholderType",
-            "FnPointerType",
-            "ForType",
-            "ImplTraitType",
-            "DynTraitType",
-        ]),
-
-        "NominalDef": (
-            enum: ["StructDef", "EnumDef", "UnionDef"],
-            traits: [
-                "NameOwner",
-                "TypeParamsOwner",
-                "AttrsOwner"
-            ],
-        ),
-        "ModuleItem": (
-            enum: ["StructDef", "UnionDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock",
-                   "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ],
-            traits: ["AttrsOwner", "VisibilityOwner"],
-        ),
-        "ImplItem": (
-            enum: ["FnDef", "TypeAliasDef", "ConstDef"],
-            traits: ["AttrsOwner"]
-        ),
-
-        "TupleExpr": (
-            collections: [("exprs", "Expr")]
-        ),
-        "ArrayExpr": (
-            collections: [("exprs", "Expr")]
-        ),
-        "ParenExpr": (options: ["Expr"]),
-        "PathExpr": (options: ["Path"]),
-        "LambdaExpr": (
-            options: [
-                "ParamList", "RetType",
-                ["body", "Expr"],
-            ]
-        ),
-        "IfExpr": (
-            options: [ "Condition" ]
-        ),
-        "LoopExpr": (
-            traits: ["LoopBodyOwner"],
-        ),
-        "TryBlockExpr": (
-            options: [["body", "BlockExpr"]],
-        ),
-        "ForExpr": (
-            traits: ["LoopBodyOwner"],
-            options: [
-                "Pat",
-                ["iterable", "Expr"],
-            ]
-        ),
-        "WhileExpr": (
-            traits: ["LoopBodyOwner"],
-            options: [ "Condition" ]
-        ),
-        "ContinueExpr": (),
-        "BreakExpr": (options: ["Expr"]),
-        "Label": (),
-        "BlockExpr": (
-            options: [ "Block" ]
-        ),
-        "ReturnExpr": (options: ["Expr"]),
-        "MatchExpr": (
-            options: [ "Expr", "MatchArmList" ],
-        ),
-        "MatchArmList": (
-            collections: [ ("arms", "MatchArm") ],
-            traits: [ "AttrsOwner" ]
-        ),
-        "MatchArm": (
-            options: [
-                [ "guard", "MatchGuard" ],
-                "Expr",
-            ],
-            collections: [ ("pats", "Pat") ],
-            traits: [ "AttrsOwner" ]
-        ),
-        "MatchGuard": (options: ["Expr"]),
-        "RecordLit": (options: ["Path", "RecordFieldList"]),
-        "RecordFieldList": (
-            collections: [ ("fields", "RecordField") ],
-            options: [["spread", "Expr"]]
-        ),
-        "RecordField": (options: ["NameRef", "Expr"]),
-        "CallExpr": (
-            traits: ["ArgListOwner"],
-            options: [ "Expr" ],
-        ),
-        "MethodCallExpr": (
-            traits: ["ArgListOwner"],
-            options: [ "Expr", "NameRef", "TypeArgList" ],
-        ),
-        "IndexExpr": (),
-        "FieldExpr": (options: ["Expr", "NameRef"]),
-        "AwaitExpr": (options: ["Expr"]),
-        "TryExpr": (options: ["Expr"]),
-        "CastExpr": (options: ["Expr", "TypeRef"]),
-        "RefExpr": (options: ["Expr"]),
-        "PrefixExpr": (options: ["Expr"]),
-        "BoxExpr": (options: ["Expr"]),
-        "RangeExpr": (),
-        "BinExpr": (),
-
-        "Literal": (),
-
-        "Expr": (
-            enum: [
-                "TupleExpr",
-                "ArrayExpr",
-                "ParenExpr",
-                "PathExpr",
-                "LambdaExpr",
-                "IfExpr",
-                "LoopExpr",
-                "ForExpr",
-                "WhileExpr",
-                "ContinueExpr",
-                "BreakExpr",
-                "Label",
-                "BlockExpr",
-                "ReturnExpr",
-                "MatchExpr",
-                "RecordLit",
-                "CallExpr",
-                "IndexExpr",
-                "MethodCallExpr",
-                "FieldExpr",
-                "AwaitExpr",
-                "TryExpr",
-                "TryBlockExpr",
-                "CastExpr",
-                "RefExpr",
-                "PrefixExpr",
-                "RangeExpr",
-                "BinExpr",
-                "Literal",
-                "MacroCall",
-                "BoxExpr",
-            ],
-        ),
-
-        "RefPat": ( options: [ "Pat" ]),
-        "BoxPat": ( options: [ "Pat" ]),
-        "BindPat": (
-            options: [ "Pat" ],
-            traits: ["NameOwner"]
-        ),
-        "PlaceholderPat": (),
-        "DotDotPat": (),
-        "PathPat": ( options: [ "Path" ] ),
-        "RecordPat": ( options: ["RecordFieldPatList", "Path"] ),
-        "RecordFieldPatList": (
-            collections: [
-                ("record_field_pats", "RecordFieldPat"),
-                ("bind_pats", "BindPat"),
-            ]
-        ),
-        "RecordFieldPat": (
-            traits: ["NameOwner"],
-            options: ["Pat"]
-        ),
-        "TupleStructPat": (
-            options: ["Path"],
-            collections: [("args", "Pat")],
-        ),
-        "TuplePat": ( collections: [("args", "Pat")] ),
-        "SlicePat": (),
-        "RangePat": (),
-        "LiteralPat": (options: ["Literal"]),
-
-        "Pat": (
-            enum: [
-                "RefPat",
-                "BoxPat",
-                "BindPat",
-                "PlaceholderPat",
-                "DotDotPat",
-                "PathPat",
-                "RecordPat",
-                "TupleStructPat",
-                "TuplePat",
-                "SlicePat",
-                "RangePat",
-                "LiteralPat",
-            ],
-        ),
-
-        "Visibility": (),
-        "Name": (),
-        "NameRef": (),
-        "MacroCall": (
-            traits: [ "NameOwner", "AttrsOwner","DocCommentsOwner" ],
-            options: [ "TokenTree", "Path" ],
-        ),
-        "AttrInput": ( enum: [ "Literal", "TokenTree" ] ),
-        "Attr": ( options: [ "Path", [ "input", "AttrInput" ] ] ),
-        "TokenTree": (),
-        "TypeParamList": (
-            collections: [
-                ("type_params", "TypeParam" ),
-                ("lifetime_params", "LifetimeParam" ),
-            ]
-        ),
-        "TypeParam": (
-            options: [("default_type", "TypeRef")],
-            traits: ["NameOwner", "AttrsOwner", "TypeBoundsOwner"],
-        ),
-        "ConstParam": (
-            options: [("default_val", "Expr")],
-            traits: ["NameOwner", "AttrsOwner", "TypeAscriptionOwner"],
-        ),
-        "LifetimeParam": (
-            traits: ["AttrsOwner"],
-        ),
-        "TypeBound": (
-            options: [
-                "TypeRef",
-            ]
-        ),
-        "TypeBoundList": (
-            collections: [
-                ("bounds", "TypeBound"),
-            ]
-        ),
-        "WherePred": (
-            options: [
-                "TypeRef",
-            ],
-            traits: [
-                "TypeBoundsOwner",
-            ],
-        ),
-        "WhereClause": (
-            collections: [
-                ("predicates", "WherePred"),
-            ],
-        ),
-        "ExprStmt": (
-            options: [ ["expr", "Expr"] ]
-        ),
-        "LetStmt": (
-            options: [
-                ["pat", "Pat"],
-                ["initializer", "Expr"],
-            ],
-            traits: [
-                "TypeAscriptionOwner",
-            ]
-        ),
-        "Condition": (
-            options: [ "Pat", "Expr" ]
-        ),
-        "Stmt": (
-            enum: ["ExprStmt", "LetStmt"],
-        ),
-        "Block": (
-            options: [ "Expr" ],
-            collections: [
-                ("statements", "Stmt"),
-            ],
-            traits: [
-                "AttrsOwner",
-                "ModuleItemOwner",
-            ]
-        ),
-        "ParamList": (
-            options: [ "SelfParam" ],
-            collections: [
-                ("params", "Param"),
-            ]
-        ),
-        "SelfParam": (
-            traits: [
-                "TypeAscriptionOwner",
-                "AttrsOwner",
-            ]
-        ),
-        "Param": (
-            options: [ "Pat" ],
-            traits: [
-                "TypeAscriptionOwner",
-                "AttrsOwner",
-            ]
-        ),
-        "UseItem": (
-            traits: ["AttrsOwner", "VisibilityOwner"],
-            options: [ "UseTree" ],
-        ),
-        "UseTree": (
-            options: [ "Path", "UseTreeList", "Alias" ]
-        ),
-        "Alias": (
-            traits: ["NameOwner"],
-        ),
-        "UseTreeList": (
-            collections: [("use_trees", "UseTree")]
-        ),
-        "ExternCrateItem": (
-            traits: ["AttrsOwner", "VisibilityOwner"],
-            options: ["NameRef", "Alias"],
-        ),
-        "ArgList": (
-            collections: [
-                ("args", "Expr"),
-            ]
-        ),
-        "Path": (
-            options: [
-                ["segment", "PathSegment"],
-                ["qualifier", "Path"],
-            ]
-        ),
-        "PathSegment": (
-            options: [ "NameRef", "TypeArgList", "ParamList", "RetType", "PathType" ]
-        ),
-        "TypeArgList": (collections: [
-            ("type_args", "TypeArg"),
-            ("lifetime_args", "LifetimeArg"),
-            ("assoc_type_args", "AssocTypeArg"),
-        ]),
-        "TypeArg": (options: ["TypeRef"]),
-        "AssocTypeArg": (options: ["NameRef", "TypeRef"]),
-        "LifetimeArg": (),
-
-        "MacroItems": (
-            traits: [ "ModuleItemOwner", "FnDefOwner" ],
-        ),
-
-        "MacroStmts" : (
-            options: [ "Expr" ],
-            collections: [
-                ("statements", "Stmt"),
-            ],
-        )
     },
 )
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index 65cabf00533..72dd5e5812b 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -13,6 +13,4 @@ walkdir = "2.1.3"
 pico-args = "0.3.0"
 quote = "1.0.2"
 proc-macro2 = "1.0.1"
-ron = "0.5.1"
-serde = { version = "1.0.0", features = ["derive"] }
 anyhow = "1.0.19"
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
new file mode 100644
index 00000000000..d494a4a3832
--- /dev/null
+++ b/xtask/src/ast_src.rs
@@ -0,0 +1,618 @@
+pub(crate) struct KindsSrc<'a> {
+    pub(crate) punct: &'a [(&'a str, &'a str)],
+    pub(crate) keywords: &'a [&'a str],
+    pub(crate) contextual_keywords: &'a [&'a str],
+    pub(crate) literals: &'a [&'a str],
+    pub(crate) tokens: &'a [&'a str],
+    pub(crate) nodes: &'a [&'a str],
+}
+
+pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
+    punct: &[
+        (";", "SEMI"),
+        (",", "COMMA"),
+        ("(", "L_PAREN"),
+        (")", "R_PAREN"),
+        ("{", "L_CURLY"),
+        ("}", "R_CURLY"),
+        ("[", "L_BRACK"),
+        ("]", "R_BRACK"),
+        ("<", "L_ANGLE"),
+        (">", "R_ANGLE"),
+        ("@", "AT"),
+        ("#", "POUND"),
+        ("~", "TILDE"),
+        ("?", "QUESTION"),
+        ("$", "DOLLAR"),
+        ("&", "AMP"),
+        ("|", "PIPE"),
+        ("+", "PLUS"),
+        ("*", "STAR"),
+        ("/", "SLASH"),
+        ("^", "CARET"),
+        ("%", "PERCENT"),
+        ("_", "UNDERSCORE"),
+        (".", "DOT"),
+        ("..", "DOTDOT"),
+        ("...", "DOTDOTDOT"),
+        ("..=", "DOTDOTEQ"),
+        (":", "COLON"),
+        ("::", "COLONCOLON"),
+        ("=", "EQ"),
+        ("==", "EQEQ"),
+        ("=>", "FAT_ARROW"),
+        ("!", "EXCL"),
+        ("!=", "NEQ"),
+        ("-", "MINUS"),
+        ("->", "THIN_ARROW"),
+        ("<=", "LTEQ"),
+        (">=", "GTEQ"),
+        ("+=", "PLUSEQ"),
+        ("-=", "MINUSEQ"),
+        ("|=", "PIPEEQ"),
+        ("&=", "AMPEQ"),
+        ("^=", "CARETEQ"),
+        ("/=", "SLASHEQ"),
+        ("*=", "STAREQ"),
+        ("%=", "PERCENTEQ"),
+        ("&&", "AMPAMP"),
+        ("||", "PIPEPIPE"),
+        ("<<", "SHL"),
+        (">>", "SHR"),
+        ("<<=", "SHLEQ"),
+        (">>=", "SHREQ"),
+    ],
+    keywords: &[
+        "as", "async", "await", "box", "break", "const", "continue", "crate", "dyn", "else",
+        "enum", "extern", "false", "fn", "for", "if", "impl", "in", "let", "loop", "macro",
+        "match", "mod", "move", "mut", "pub", "ref", "return", "self", "static", "struct", "super",
+        "trait", "true", "try", "type", "unsafe", "use", "where", "while",
+    ],
+    contextual_keywords: &["auto", "default", "existential", "union"],
+    literals: &[
+        "INT_NUMBER",
+        "FLOAT_NUMBER",
+        "CHAR",
+        "BYTE",
+        "STRING",
+        "RAW_STRING",
+        "BYTE_STRING",
+        "RAW_BYTE_STRING",
+    ],
+    tokens: &[
+        "ERROR",
+        "IDENT",
+        "WHITESPACE",
+        "LIFETIME",
+        "COMMENT",
+        "SHEBANG",
+        "L_DOLLAR",
+        "R_DOLLAR",
+    ],
+    nodes: &[
+        "SOURCE_FILE",
+        "STRUCT_DEF",
+        "UNION_DEF",
+        "ENUM_DEF",
+        "FN_DEF",
+        "RET_TYPE",
+        "EXTERN_CRATE_ITEM",
+        "MODULE",
+        "USE_ITEM",
+        "STATIC_DEF",
+        "CONST_DEF",
+        "TRAIT_DEF",
+        "IMPL_BLOCK",
+        "TYPE_ALIAS_DEF",
+        "MACRO_CALL",
+        "TOKEN_TREE",
+        "MACRO_DEF",
+        "PAREN_TYPE",
+        "TUPLE_TYPE",
+        "NEVER_TYPE",
+        "PATH_TYPE",
+        "POINTER_TYPE",
+        "ARRAY_TYPE",
+        "SLICE_TYPE",
+        "REFERENCE_TYPE",
+        "PLACEHOLDER_TYPE",
+        "FN_POINTER_TYPE",
+        "FOR_TYPE",
+        "IMPL_TRAIT_TYPE",
+        "DYN_TRAIT_TYPE",
+        "REF_PAT",
+        "BOX_PAT",
+        "BIND_PAT",
+        "PLACEHOLDER_PAT",
+        "DOT_DOT_PAT",
+        "PATH_PAT",
+        "RECORD_PAT",
+        "RECORD_FIELD_PAT_LIST",
+        "RECORD_FIELD_PAT",
+        "TUPLE_STRUCT_PAT",
+        "TUPLE_PAT",
+        "SLICE_PAT",
+        "RANGE_PAT",
+        "LITERAL_PAT",
+        // atoms
+        "TUPLE_EXPR",
+        "ARRAY_EXPR",
+        "PAREN_EXPR",
+        "PATH_EXPR",
+        "LAMBDA_EXPR",
+        "IF_EXPR",
+        "WHILE_EXPR",
+        "CONDITION",
+        "LOOP_EXPR",
+        "FOR_EXPR",
+        "CONTINUE_EXPR",
+        "BREAK_EXPR",
+        "LABEL",
+        "BLOCK_EXPR",
+        "RETURN_EXPR",
+        "MATCH_EXPR",
+        "MATCH_ARM_LIST",
+        "MATCH_ARM",
+        "MATCH_GUARD",
+        "RECORD_LIT",
+        "RECORD_FIELD_LIST",
+        "RECORD_FIELD",
+        "TRY_BLOCK_EXPR",
+        "BOX_EXPR",
+        // postfix
+        "CALL_EXPR",
+        "INDEX_EXPR",
+        "METHOD_CALL_EXPR",
+        "FIELD_EXPR",
+        "AWAIT_EXPR",
+        "TRY_EXPR",
+        "CAST_EXPR",
+        // unary
+        "REF_EXPR",
+        "PREFIX_EXPR",
+        "RANGE_EXPR", // just weird
+        "BIN_EXPR",
+        "BLOCK",
+        "EXTERN_BLOCK",
+        "EXTERN_ITEM_LIST",
+        "ENUM_VARIANT",
+        "RECORD_FIELD_DEF_LIST",
+        "RECORD_FIELD_DEF",
+        "TUPLE_FIELD_DEF_LIST",
+        "TUPLE_FIELD_DEF",
+        "ENUM_VARIANT_LIST",
+        "ITEM_LIST",
+        "ATTR",
+        "META_ITEM", // not an item actually
+        "USE_TREE",
+        "USE_TREE_LIST",
+        "PATH",
+        "PATH_SEGMENT",
+        "LITERAL",
+        "ALIAS",
+        "VISIBILITY",
+        "WHERE_CLAUSE",
+        "WHERE_PRED",
+        "ABI",
+        "NAME",
+        "NAME_REF",
+        "LET_STMT",
+        "EXPR_STMT",
+        "TYPE_PARAM_LIST",
+        "LIFETIME_PARAM",
+        "TYPE_PARAM",
+        "CONST_PARAM",
+        "TYPE_ARG_LIST",
+        "LIFETIME_ARG",
+        "TYPE_ARG",
+        "ASSOC_TYPE_ARG",
+        "PARAM_LIST",
+        "PARAM",
+        "SELF_PARAM",
+        "ARG_LIST",
+        "TYPE_BOUND",
+        "TYPE_BOUND_LIST",
+        // macro related
+        "MACRO_ITEMS",
+        "MACRO_STMTS",
+    ],
+};
+
+pub(crate) struct AstSrc<'a> {
+    pub(crate) nodes: &'a [AstNodeSrc<'a>],
+    pub(crate) enums: &'a [AstEnumSrc<'a>],
+}
+
+pub(crate) struct AstNodeSrc<'a> {
+    pub(crate) name: &'a str,
+    pub(crate) traits: &'a [&'a str],
+    pub(crate) fields: &'a [(&'a str, FieldSrc<&'a str>)],
+}
+
+pub(crate) enum FieldSrc<T> {
+    Shorthand,
+    Optional(T),
+    Many(T),
+}
+
+pub(crate) struct AstEnumSrc<'a> {
+    pub(crate) name: &'a str,
+    pub(crate) traits: &'a [&'a str],
+    pub(crate) variants: &'a [&'a str],
+}
+
+macro_rules! ast_nodes {
+    ($(
+        struct $name:ident$(: $($trait:ident),*)? {
+            $($field_name:ident $(: $ty:tt)?),*$(,)?
+        }
+    )*) => {
+        [$(
+            AstNodeSrc {
+                name: stringify!($name),
+                traits: &[$($(stringify!($trait)),*)?],
+                fields: &[$(
+                    (stringify!($field_name), field_ty!($field_name $($ty)?))
+                ),*],
+
+            }
+        ),*]
+    };
+}
+
+macro_rules! field_ty {
+    ($field_name:ident) => {
+        FieldSrc::Shorthand
+    };
+    ($field_name:ident [$ty:ident]) => {
+        FieldSrc::Many(stringify!($ty))
+    };
+    ($field_name:ident $ty:ident) => {
+        FieldSrc::Optional(stringify!($ty))
+    };
+}
+
+macro_rules! ast_enums {
+    ($(
+        enum $name:ident $(: $($trait:ident),*)? {
+            $($variant:ident),*$(,)?
+        }
+    )*) => {
+        [$(
+            AstEnumSrc {
+                name: stringify!($name),
+                traits: &[$($(stringify!($trait)),*)?],
+                variants: &[$(stringify!($variant)),*],
+
+            }
+        ),*]
+    };
+}
+
+pub(crate) const AST_SRC: AstSrc = AstSrc {
+    nodes: &ast_nodes! {
+        struct SourceFile: ModuleItemOwner, FnDefOwner {
+            modules: [Module],
+        }
+
+        struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner {
+            ParamList,
+            RetType,
+            body: BlockExpr,
+        }
+
+        struct RetType { TypeRef }
+
+        struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
+        }
+
+        struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
+            RecordFieldDefList,
+        }
+
+        struct RecordFieldDefList { fields: [RecordFieldDef] }
+        struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { }
+
+        struct TupleFieldDefList { fields: [TupleFieldDef] }
+        struct TupleFieldDef: VisibilityOwner, AttrsOwner {
+            TypeRef,
+        }
+
+        struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
+            variant_list: EnumVariantList,
+        }
+        struct EnumVariantList {
+            variants: [EnumVariant],
+        }
+        struct EnumVariant: NameOwner, DocCommentsOwner, AttrsOwner {
+            Expr
+        }
+
+        struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner {
+            ItemList,
+        }
+
+        struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner {
+            ItemList,
+        }
+
+        struct ItemList: FnDefOwner, ModuleItemOwner {
+            impl_items: [ImplItem],
+        }
+
+        struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
+            body: Expr,
+        }
+
+        struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
+            body: Expr,
+        }
+
+        struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner {
+            TypeRef,
+        }
+
+        struct ImplBlock: TypeParamsOwner, AttrsOwner {
+            ItemList,
+        }
+
+        struct ParenType { TypeRef }
+        struct TupleType { fields: [TypeRef] }
+        struct NeverType { }
+        struct PathType { Path }
+        struct PointerType { TypeRef }
+        struct ArrayType { TypeRef, Expr }
+        struct SliceType { TypeRef }
+        struct ReferenceType { TypeRef }
+        struct PlaceholderType {  }
+        struct FnPointerType { ParamList, RetType }
+        struct ForType { TypeRef }
+        struct ImplTraitType: TypeBoundsOwner {}
+        struct DynTraitType: TypeBoundsOwner {}
+
+        struct TupleExpr { exprs: [Expr] }
+        struct ArrayExpr { exprs: [Expr] }
+        struct ParenExpr { Expr }
+        struct PathExpr  { Path }
+        struct LambdaExpr {
+            ParamList,
+            RetType,
+            body: Expr,
+        }
+        struct IfExpr { Condition }
+        struct LoopExpr: LoopBodyOwner { }
+        struct TryBlockExpr { body: BlockExpr }
+        struct ForExpr: LoopBodyOwner {
+            Pat,
+            iterable: Expr,
+        }
+        struct WhileExpr: LoopBodyOwner { Condition }
+        struct ContinueExpr {}
+        struct BreakExpr { Expr }
+        struct Label {}
+        struct BlockExpr { Block  }
+        struct ReturnExpr { Expr }
+        struct CallExpr: ArgListOwner { Expr }
+        struct MethodCallExpr: ArgListOwner {
+            Expr, NameRef, TypeArgList,
+        }
+        struct IndexExpr {}
+        struct FieldExpr { Expr, NameRef }
+        struct AwaitExpr { Expr }
+        struct TryExpr { Expr }
+        struct CastExpr { Expr, TypeRef }
+        struct RefExpr { Expr }
+        struct PrefixExpr { Expr }
+        struct BoxExpr { Expr }
+        struct RangeExpr {}
+        struct BinExpr {}
+        struct Literal {}
+
+        struct MatchExpr { Expr, MatchArmList }
+        struct MatchArmList: AttrsOwner { arms: [MatchArm] }
+        struct MatchArm: AttrsOwner {
+            pats: [Pat],
+            guard: MatchGuard,
+            Expr,
+         }
+        struct MatchGuard { Expr }
+
+        struct RecordLit { Path, RecordFieldList }
+        struct RecordFieldList {
+            fields: [RecordField],
+            spread: Expr,
+         }
+        struct RecordField { NameRef, Expr }
+
+        struct RefPat { Pat }
+        struct BoxPat { Pat }
+        struct BindPat: NameOwner { Pat }
+        struct PlaceholderPat { }
+        struct DotDotPat { }
+        struct PathPat {  Path }
+        struct SlicePat {}
+        struct RangePat {}
+        struct LiteralPat { Literal }
+
+        struct RecordPat { RecordFieldPatList, Path }
+        struct RecordFieldPatList {
+            record_field_pats: [RecordFieldPat],
+            bind_pats: [BindPat],
+        }
+        struct RecordFieldPat: NameOwner { Pat }
+
+        struct TupleStructPat { Path, args: [Pat] }
+        struct TuplePat { args: [Pat] }
+
+        struct Visibility {}
+        struct Name {}
+        struct NameRef {}
+
+        struct MacroCall: NameOwner, AttrsOwner,DocCommentsOwner {
+            TokenTree, Path
+        }
+        struct Attr { Path, input: AttrInput }
+        struct TokenTree {}
+        struct TypeParamList {
+            type_params: [TypeParam],
+            lifetime_params: [LifetimeParam],
+        }
+        struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner {
+            default_type: TypeRef,
+        }
+        struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner {
+            default_val: Expr,
+        }
+        struct LifetimeParam: AttrsOwner { }
+        struct TypeBound { TypeRef}
+        struct TypeBoundList { bounds: [TypeBound] }
+        struct WherePred: TypeBoundsOwner { TypeRef }
+        struct WhereClause { predicates: [WherePred] }
+        struct ExprStmt { Expr }
+        struct LetStmt: TypeAscriptionOwner {
+            Pat,
+            initializer: Expr,
+        }
+        struct Condition { Pat, Expr }
+        struct Block: AttrsOwner, ModuleItemOwner {
+            statements: [Stmt],
+            Expr,
+        }
+        struct ParamList {
+            SelfParam,
+            params: [Param],
+        }
+        struct SelfParam: TypeAscriptionOwner, AttrsOwner { }
+        struct Param: TypeAscriptionOwner, AttrsOwner {
+            Pat,
+        }
+        struct UseItem: AttrsOwner, VisibilityOwner {
+            UseTree,
+        }
+        struct UseTree {
+            Path, UseTreeList, Alias
+        }
+        struct Alias: NameOwner { }
+        struct UseTreeList { use_trees: [UseTree] }
+        struct ExternCrateItem: AttrsOwner, VisibilityOwner {
+            NameRef, Alias,
+        }
+        struct ArgList {
+            args: [Expr],
+        }
+        struct Path {
+            segment: PathSegment,
+            qualifier: Path,
+        }
+        struct PathSegment {
+            NameRef, TypeArgList, ParamList, RetType, PathType,
+        }
+        struct TypeArgList {
+            type_args: [TypeArg],
+            lifetime_args: [LifetimeArg],
+            assoc_type_args: [AssocTypeArg],
+        }
+        struct TypeArg { TypeRef }
+        struct AssocTypeArg { NameRef, TypeRef }
+        struct LifetimeArg {}
+
+        struct MacroItems: ModuleItemOwner, FnDefOwner { }
+
+        struct MacroStmts {
+            statements: [Stmt],
+            Expr,
+        }
+    },
+    enums: &ast_enums! {
+        enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner {
+            StructDef, EnumDef, UnionDef,
+        }
+
+        enum TypeRef {
+            ParenType,
+            TupleType,
+            NeverType,
+            PathType,
+            PointerType,
+            ArrayType,
+            SliceType,
+            ReferenceType,
+            PlaceholderType,
+            FnPointerType,
+            ForType,
+            ImplTraitType,
+            DynTraitType,
+        }
+
+        enum ModuleItem: AttrsOwner, VisibilityOwner {
+            StructDef,
+            UnionDef,
+            EnumDef,
+            FnDef,
+            TraitDef,
+            TypeAliasDef,
+            ImplBlock,
+            UseItem,
+            ExternCrateItem,
+            ConstDef,
+            StaticDef,
+            Module,
+        }
+
+        enum ImplItem: AttrsOwner {
+            FnDef, TypeAliasDef, ConstDef,
+        }
+
+        enum Expr {
+            TupleExpr,
+            ArrayExpr,
+            ParenExpr,
+            PathExpr,
+            LambdaExpr,
+            IfExpr,
+            LoopExpr,
+            ForExpr,
+            WhileExpr,
+            ContinueExpr,
+            BreakExpr,
+            Label,
+            BlockExpr,
+            ReturnExpr,
+            MatchExpr,
+            RecordLit,
+            CallExpr,
+            IndexExpr,
+            MethodCallExpr,
+            FieldExpr,
+            AwaitExpr,
+            TryExpr,
+            TryBlockExpr,
+            CastExpr,
+            RefExpr,
+            PrefixExpr,
+            RangeExpr,
+            BinExpr,
+            Literal,
+            MacroCall,
+            BoxExpr,
+        }
+
+        enum Pat {
+            RefPat,
+            BoxPat,
+            BindPat,
+            PlaceholderPat,
+            DotDotPat,
+            PathPat,
+            RecordPat,
+            TupleStructPat,
+            TuplePat,
+            SlicePat,
+            RangePat,
+            LiteralPat,
+        }
+
+        enum AttrInput { Literal, TokenTree }
+        enum Stmt { ExprStmt, LetStmt }
+    },
+};
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs
index 53f524f42df..158cfc2d680 100644
--- a/xtask/src/codegen.rs
+++ b/xtask/src/codegen.rs
@@ -24,7 +24,6 @@ pub use self::{
     gen_syntax::generate_syntax,
 };
 
-pub const GRAMMAR: &str = "crates/ra_syntax/src/grammar.ron";
 const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar";
 const OK_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/ok";
 const ERR_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/err";
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index 88f2ac0e35e..0f50ca56933 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -3,149 +3,142 @@
 //! Specifically, it generates the `SyntaxKind` enum and a number of newtype
 //! wrappers around `SyntaxNode` which implement `ra_syntax::AstNode`.
 
-use std::{collections::BTreeMap, fs};
-
 use proc_macro2::{Punct, Spacing};
 use quote::{format_ident, quote};
-use ron;
-use serde::Deserialize;
 
 use crate::{
+    ast_src::{AstSrc, FieldSrc, KindsSrc, AST_SRC, KINDS_SRC},
     codegen::{self, update, Mode},
     project_root, Result,
 };
 
 pub fn generate_syntax(mode: Mode) -> Result<()> {
-    let grammar = project_root().join(codegen::GRAMMAR);
-    let grammar: Grammar = {
-        let text = fs::read_to_string(grammar)?;
-        ron::de::from_str(&text)?
-    };
-
     let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS);
-    let syntax_kinds = generate_syntax_kinds(&grammar)?;
+    let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?;
     update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?;
 
     let ast_file = project_root().join(codegen::AST);
-    let ast = generate_ast(&grammar)?;
+    let ast = generate_ast(AST_SRC)?;
     update(ast_file.as_path(), &ast, mode)?;
 
     Ok(())
 }
 
-fn generate_ast(grammar: &Grammar) -> Result<String> {
-    let nodes = grammar.ast.iter().map(|(name, ast_node)| {
-        let variants =
-            ast_node.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>();
-        let name = format_ident!("{}", name);
-
-        let adt = if variants.is_empty() {
-            let kind = format_ident!("{}", to_upper_snake_case(&name.to_string()));
-            quote! {
-                #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-                pub struct #name {
-                    pub(crate) syntax: SyntaxNode,
-                }
+fn generate_ast(grammar: AstSrc<'_>) -> Result<String> {
+    let nodes = grammar.nodes.iter().map(|node| {
+        let name = format_ident!("{}", node.name);
+        let kind = format_ident!("{}", to_upper_snake_case(&name.to_string()));
+        let traits = node.traits.iter().map(|trait_name| {
+            let trait_name = format_ident!("{}", trait_name);
+            quote!(impl ast::#trait_name for #name {})
+        });
 
-                impl AstNode for #name {
-                    fn can_cast(kind: SyntaxKind) -> bool {
-                        match kind {
-                            #kind => true,
-                            _ => false,
+        let methods = node.fields.iter().map(|(name, field)| {
+            let method_name = match field {
+                FieldSrc::Shorthand => format_ident!("{}", to_lower_snake_case(&name)),
+                _ => format_ident!("{}", name),
+            };
+            let ty = match field {
+                FieldSrc::Optional(ty) | FieldSrc::Many(ty) => ty,
+                FieldSrc::Shorthand => name,
+            };
+            let ty = format_ident!("{}", ty);
+
+            match field {
+                FieldSrc::Many(_) => {
+                    quote! {
+                        pub fn #method_name(&self) -> AstChildren<#ty> {
+                            AstChildren::new(&self.syntax)
                         }
                     }
-                    fn cast(syntax: SyntaxNode) -> Option<Self> {
-                        if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
+                }
+                FieldSrc::Optional(_) | FieldSrc::Shorthand => {
+                    quote! {
+                        pub fn #method_name(&self) -> Option<#ty> {
+                            AstChildren::new(&self.syntax).next()
+                        }
                     }
-                    fn syntax(&self) -> &SyntaxNode { &self.syntax }
                 }
             }
-        } else {
-            let kinds = variants
-                .iter()
-                .map(|name| format_ident!("{}", to_upper_snake_case(&name.to_string())))
-                .collect::<Vec<_>>();
-
-            quote! {
-                #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-                pub enum #name {
-                    #(#variants(#variants),)*
-                }
+        });
 
-                #(
-                impl From<#variants> for #name {
-                    fn from(node: #variants) -> #name {
-                        #name::#variants(node)
-                    }
-                }
-                )*
+        quote! {
+            #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+            pub struct #name {
+                pub(crate) syntax: SyntaxNode,
+            }
 
-                impl AstNode for #name {
-                    fn can_cast(kind: SyntaxKind) -> bool {
-                        match kind {
-                            #(#kinds)|* => true,
-                            _ => false,
-                        }
-                    }
-                    fn cast(syntax: SyntaxNode) -> Option<Self> {
-                        let res = match syntax.kind() {
-                            #(
-                            #kinds => #name::#variants(#variants { syntax }),
-                            )*
-                            _ => return None,
-                        };
-                        Some(res)
-                    }
-                    fn syntax(&self) -> &SyntaxNode {
-                        match self {
-                            #(
-                            #name::#variants(it) => &it.syntax,
-                            )*
-                        }
+            impl AstNode for #name {
+                fn can_cast(kind: SyntaxKind) -> bool {
+                    match kind {
+                        #kind => true,
+                        _ => false,
                     }
                 }
+                fn cast(syntax: SyntaxNode) -> Option<Self> {
+                    if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
+                }
+                fn syntax(&self) -> &SyntaxNode { &self.syntax }
             }
-        };
+            #(#traits)*
+
+            impl #name {
+                #(#methods)*
+            }
+        }
+    });
 
-        let traits = ast_node.traits.iter().map(|trait_name| {
+    let enums = grammar.enums.iter().map(|en| {
+        let variants = en.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>();
+        let name = format_ident!("{}", en.name);
+        let kinds = variants
+            .iter()
+            .map(|name| format_ident!("{}", to_upper_snake_case(&name.to_string())))
+            .collect::<Vec<_>>();
+        let traits = en.traits.iter().map(|trait_name| {
             let trait_name = format_ident!("{}", trait_name);
             quote!(impl ast::#trait_name for #name {})
         });
 
-        let collections = ast_node.collections.iter().map(|(name, kind)| {
-            let method_name = format_ident!("{}", name);
-            let kind = format_ident!("{}", kind);
-            quote! {
-                pub fn #method_name(&self) -> AstChildren<#kind> {
-                    AstChildren::new(&self.syntax)
-                }
+        quote! {
+            #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+            pub enum #name {
+                #(#variants(#variants),)*
             }
-        });
 
-        let options = ast_node.options.iter().map(|attr| {
-            let method_name = match attr {
-                Attr::Type(t) => format_ident!("{}", to_lower_snake_case(&t)),
-                Attr::NameType(n, _) => format_ident!("{}", n),
-            };
-            let ty = match attr {
-                Attr::Type(t) | Attr::NameType(_, t) => format_ident!("{}", t),
-            };
-            quote! {
-                pub fn #method_name(&self) -> Option<#ty> {
-                    AstChildren::new(&self.syntax).next()
+            #(
+            impl From<#variants> for #name {
+                fn from(node: #variants) -> #name {
+                    #name::#variants(node)
                 }
             }
-        });
-
-        quote! {
-            #adt
-
-            #(#traits)*
+            )*
 
-            impl #name {
-                #(#collections)*
-                #(#options)*
+            impl AstNode for #name {
+                fn can_cast(kind: SyntaxKind) -> bool {
+                    match kind {
+                        #(#kinds)|* => true,
+                        _ => false,
+                    }
+                }
+                fn cast(syntax: SyntaxNode) -> Option<Self> {
+                    let res = match syntax.kind() {
+                        #(
+                        #kinds => #name::#variants(#variants { syntax }),
+                        )*
+                        _ => return None,
+                    };
+                    Some(res)
+                }
+                fn syntax(&self) -> &SyntaxNode {
+                    match self {
+                        #(
+                        #name::#variants(it) => &it.syntax,
+                        )*
+                    }
+                }
             }
+            #(#traits)*
         }
     });
 
@@ -156,13 +149,14 @@ fn generate_ast(grammar: &Grammar) -> Result<String> {
         };
 
         #(#nodes)*
+        #(#enums)*
     };
 
     let pretty = codegen::reformat(ast)?;
     Ok(pretty)
 }
 
-fn generate_syntax_kinds(grammar: &Grammar) -> Result<String> {
+fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> Result<String> {
     let (single_byte_tokens_values, single_byte_tokens): (Vec<_>, Vec<_>) = grammar
         .punct
         .iter()
@@ -274,38 +268,6 @@ fn generate_syntax_kinds(grammar: &Grammar) -> Result<String> {
     codegen::reformat(ast)
 }
 
-#[derive(Deserialize, Debug)]
-struct Grammar {
-    punct: Vec<(String, String)>,
-    keywords: Vec<String>,
-    contextual_keywords: Vec<String>,
-    literals: Vec<String>,
-    tokens: Vec<String>,
-    nodes: Vec<String>,
-    ast: BTreeMap<String, AstNode>,
-}
-
-#[derive(Deserialize, Debug)]
-struct AstNode {
-    #[serde(default)]
-    #[serde(rename = "enum")]
-    variants: Vec<String>,
-
-    #[serde(default)]
-    traits: Vec<String>,
-    #[serde(default)]
-    collections: Vec<(String, String)>,
-    #[serde(default)]
-    options: Vec<Attr>,
-}
-
-#[derive(Deserialize, Debug)]
-#[serde(untagged)]
-enum Attr {
-    Type(String),
-    NameType(String, String),
-}
-
 fn to_upper_snake_case(s: &str) -> String {
     let mut buf = String::with_capacity(s.len());
     let mut prev_is_upper = None;
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index 40a6682be99..51a868dee97 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -1,6 +1,7 @@
 //! FIXME: write short doc here
 
 pub mod codegen;
+mod ast_src;
 
 use anyhow::Context;
 pub use anyhow::Result;