about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock7
-rw-r--r--crates/ra_hir_def/src/type_ref.rs2
-rw-r--r--crates/ra_syntax/src/ast/expr_ext.rs2
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs3010
-rw-r--r--crates/ra_syntax/src/ast/node_ext.rs16
-rw-r--r--xtask/Cargo.toml9
-rw-r--r--xtask/src/ast_src.rs1984
-rw-r--r--xtask/src/codegen/gen_syntax.rs224
-rw-r--r--xtask/src/codegen/rust.ungram529
9 files changed, 1591 insertions, 4192 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ff225399e08..b7a9516e3d6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1750,6 +1750,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "ungrammar"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ee12e4891ab3acc2d95d5023022ace22020247bb8a8d1ece875a443f7dab37d"
+
+[[package]]
 name = "unicode-bidi"
 version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1893,5 +1899,6 @@ dependencies = [
  "pico-args",
  "proc-macro2",
  "quote",
+ "ungrammar",
  "walkdir",
 ]
diff --git a/crates/ra_hir_def/src/type_ref.rs b/crates/ra_hir_def/src/type_ref.rs
index e90b2a0b928..970fc9af54e 100644
--- a/crates/ra_hir_def/src/type_ref.rs
+++ b/crates/ra_hir_def/src/type_ref.rs
@@ -1,7 +1,7 @@
 //! HIR for references to types. Paths in these are not yet resolved. They can
 //! be directly created from an ast::TypeRef, without further queries.
 
-use ra_syntax::ast::{self, TypeAscriptionOwner, TypeBoundsOwner};
+use ra_syntax::ast::{self, TypeAscriptionOwner};
 
 use crate::{body::LowerCtx, path::Path};
 
diff --git a/crates/ra_syntax/src/ast/expr_ext.rs b/crates/ra_syntax/src/ast/expr_ext.rs
index db5438d6870..69c85c809de 100644
--- a/crates/ra_syntax/src/ast/expr_ext.rs
+++ b/crates/ra_syntax/src/ast/expr_ext.rs
@@ -7,6 +7,8 @@ use crate::{
     SyntaxToken, T,
 };
 
+impl ast::AttrsOwner for ast::Expr {}
+
 impl ast::Expr {
     pub fn is_block_like(&self) -> bool {
         match self {
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
index 1fe5f450a43..b2d108a7cab 100644
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ b/crates/ra_syntax/src/ast/generated/nodes.rs
@@ -5,48 +5,34 @@ use crate::{
     SyntaxKind::{self, *},
     SyntaxNode, SyntaxToken, T,
 };
-/// The entire Rust source file. Includes all top-level inner attributes and module items.
-///
-/// [Reference](https://doc.rust-lang.org/reference/crates-and-source-files.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct SourceFile {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::ModuleItemOwner for SourceFile {}
 impl ast::AttrsOwner for SourceFile {}
-impl ast::DocCommentsOwner for SourceFile {}
+impl ast::ModuleItemOwner for SourceFile {}
 impl SourceFile {}
-/// Function definition either with body or not.
-/// Includes all of its attributes and doc comments.
-///
-/// ```
-/// ❰
-///     /// Docs
-///     #[attr]
-///     pub extern "C" fn foo<T>(#[attr] Patern {p}: Pattern) -> u32
-///     where
-///         T: Debug
-///     {
-///         42
-///     }
-/// ❱
-///
-/// extern "C" {
-///     ❰ fn fn_decl(also_variadic_ffi: u32, ...) -> u32; ❱
-/// }
-/// ```
-///
-/// - [Reference](https://doc.rust-lang.org/reference/items/functions.html)
-/// - [Nomicon](https://doc.rust-lang.org/nomicon/ffi.html#variadic-functions)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Attr {
+    pub(crate) syntax: SyntaxNode,
+}
+impl Attr {
+    pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
+    pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
+    pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
+    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+    pub fn input(&self) -> Option<AttrInput> { support::child(&self.syntax) }
+    pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FnDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::VisibilityOwner for FnDef {}
+impl ast::AttrsOwner for FnDef {}
 impl ast::NameOwner for FnDef {}
+impl ast::VisibilityOwner for FnDef {}
 impl ast::TypeParamsOwner for FnDef {}
-impl ast::DocCommentsOwner for FnDef {}
-impl ast::AttrsOwner for FnDef {}
 impl FnDef {
     pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
@@ -59,13 +45,53 @@ impl FnDef {
     pub fn body(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
 }
-/// Return type annotation.
-///
-/// ```
-/// fn foo(a: u32) ❰ -> Option<u32> ❱ { Some(a) }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Visibility {
+    pub(crate) syntax: SyntaxNode,
+}
+impl Visibility {
+    pub fn pub_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![pub]) }
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) }
+    pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
+    pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
+    pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) }
+    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Abi {
+    pub(crate) syntax: SyntaxNode,
+}
+impl Abi {}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Name {
+    pub(crate) syntax: SyntaxNode,
+}
+impl Name {
+    pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct TypeParamList {
+    pub(crate) syntax: SyntaxNode,
+}
+impl TypeParamList {
+    pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
+    pub fn type_params(&self) -> AstChildren<TypeParam> { support::children(&self.syntax) }
+    pub fn lifetime_params(&self) -> AstChildren<LifetimeParam> { support::children(&self.syntax) }
+    pub fn const_params(&self) -> AstChildren<ConstParam> { support::children(&self.syntax) }
+    pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct ParamList {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ParamList {
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn self_param(&self) -> Option<SelfParam> { support::child(&self.syntax) }
+    pub fn params(&self) -> AstChildren<Param> { support::children(&self.syntax) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RetType {
     pub(crate) syntax: SyntaxNode,
@@ -74,204 +100,105 @@ impl RetType {
     pub fn thin_arrow_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![->]) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Struct definition.
-/// Includes all of its attributes and doc comments.
-///
-/// ```
-/// ❰
-///     /// Docs
-///     #[attr]
-///     struct Foo<T> where T: Debug {
-///         /// Docs
-///         #[attr]
-///         pub a: u32,
-///         b: T,
-///     }
-/// ❱
-///
-/// ❰ struct Foo; ❱
-/// ❰ struct Foo<T>(#[attr] T) where T: Debug; ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct WhereClause {
+    pub(crate) syntax: SyntaxNode,
+}
+impl WhereClause {
+    pub fn where_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![where]) }
+    pub fn predicates(&self) -> AstChildren<WherePred> { support::children(&self.syntax) }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct BlockExpr {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ast::AttrsOwner for BlockExpr {}
+impl ast::ModuleItemOwner for BlockExpr {}
+impl BlockExpr {
+    pub fn label(&self) -> Option<Label> { support::child(&self.syntax) }
+    pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
+    pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+    pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct StructDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::VisibilityOwner for StructDef {}
+impl ast::AttrsOwner for StructDef {}
 impl ast::NameOwner for StructDef {}
+impl ast::VisibilityOwner for StructDef {}
 impl ast::TypeParamsOwner for StructDef {}
-impl ast::AttrsOwner for StructDef {}
-impl ast::DocCommentsOwner for StructDef {}
 impl StructDef {
     pub fn struct_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![struct]) }
-    pub fn field_def_list(&self) -> Option<FieldDefList> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
+    pub fn field_def_list(&self) -> Option<FieldDefList> { support::child(&self.syntax) }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct RecordFieldDefList {
+    pub(crate) syntax: SyntaxNode,
+}
+impl RecordFieldDefList {
+    pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
+    pub fn fields(&self) -> AstChildren<RecordFieldDef> { support::children(&self.syntax) }
+    pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct TupleFieldDefList {
+    pub(crate) syntax: SyntaxNode,
+}
+impl TupleFieldDefList {
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn fields(&self) -> AstChildren<TupleFieldDef> { support::children(&self.syntax) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
-/// Union definition.
-/// Includes all of its attributes and doc comments.
-///
-/// ```
-/// ❰
-///     /// Docs
-///     #[attr]
-///     pub union Foo<T> where T: Debug {
-///         /// Docs
-///         #[attr]
-///         a: T,
-///         b: u32,
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/unions.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct UnionDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::VisibilityOwner for UnionDef {}
+impl ast::AttrsOwner for UnionDef {}
 impl ast::NameOwner for UnionDef {}
+impl ast::VisibilityOwner for UnionDef {}
 impl ast::TypeParamsOwner for UnionDef {}
-impl ast::AttrsOwner for UnionDef {}
-impl ast::DocCommentsOwner for UnionDef {}
 impl UnionDef {
     pub fn union_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![union]) }
     pub fn record_field_def_list(&self) -> Option<RecordFieldDefList> {
         support::child(&self.syntax)
     }
 }
-/// Record field definition list including enclosing curly braces.
-///
-/// ```
-/// struct Foo // same for union
-/// ❰
-///     {
-///         a: u32,
-///         b: bool,
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RecordFieldDefList {
-    pub(crate) syntax: SyntaxNode,
-}
-impl RecordFieldDefList {
-    pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
-    pub fn fields(&self) -> AstChildren<RecordFieldDef> { support::children(&self.syntax) }
-    pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
-}
-/// Record field definition including its attributes and doc comments.
-///
-/// ` ``
-/// same for union
-/// struct Foo {
-///      ❰
-///          /// Docs
-///          #[attr]
-///          pub a: u32
-///      ❱
-///
-///      ❰ b: bool ❱
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RecordFieldDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::VisibilityOwner for RecordFieldDef {}
-impl ast::NameOwner for RecordFieldDef {}
 impl ast::AttrsOwner for RecordFieldDef {}
-impl ast::DocCommentsOwner for RecordFieldDef {}
+impl ast::NameOwner for RecordFieldDef {}
+impl ast::VisibilityOwner for RecordFieldDef {}
 impl ast::TypeAscriptionOwner for RecordFieldDef {}
-impl RecordFieldDef {}
-/// Tuple field definition list including enclosing parens.
-///
-/// ```
-/// struct Foo ❰ (u32, String, Vec<u32>) ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TupleFieldDefList {
-    pub(crate) syntax: SyntaxNode,
-}
-impl TupleFieldDefList {
-    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
-    pub fn fields(&self) -> AstChildren<TupleFieldDef> { support::children(&self.syntax) }
-    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+impl RecordFieldDef {
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
 }
-/// Tuple field definition including its attributes.
-///
-/// ```
-/// struct Foo(❰ #[attr] u32 ❱);
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TupleFieldDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::VisibilityOwner for TupleFieldDef {}
 impl ast::AttrsOwner for TupleFieldDef {}
+impl ast::NameOwner for TupleFieldDef {}
+impl ast::VisibilityOwner for TupleFieldDef {}
 impl TupleFieldDef {
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Enum definition.
-/// Includes all of its attributes and doc comments.
-///
-/// ```
-/// ❰
-///     /// Docs
-///     #[attr]
-///     pub enum Foo<T> where T: Debug {
-///         /// Docs
-///         #[attr]
-///         Bar,
-///         Baz(#[attr] u32),
-///         Bruh {
-///             a: u32,
-///             /// Docs
-///             #[attr]
-///             b: T,
-///         }
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct EnumDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::VisibilityOwner for EnumDef {}
+impl ast::AttrsOwner for EnumDef {}
 impl ast::NameOwner for EnumDef {}
+impl ast::VisibilityOwner for EnumDef {}
 impl ast::TypeParamsOwner for EnumDef {}
-impl ast::AttrsOwner for EnumDef {}
-impl ast::DocCommentsOwner for EnumDef {}
 impl EnumDef {
     pub fn enum_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![enum]) }
     pub fn variant_list(&self) -> Option<EnumVariantList> { support::child(&self.syntax) }
 }
-/// Enum variant definition list including enclosing curly braces.
-///
-/// ```
-/// enum Foo
-/// ❰
-///     {
-///         Bar,
-///         Baz(u32),
-///         Bruh {
-///             a: u32
-///         }
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct EnumVariantList {
     pub(crate) syntax: SyntaxNode,
@@ -281,56 +208,25 @@ impl EnumVariantList {
     pub fn variants(&self) -> AstChildren<EnumVariant> { support::children(&self.syntax) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
 }
-/// Enum variant definition including its attributes and discriminant value definition.
-///
-/// ```
-/// enum Foo {
-///     ❰
-///         /// Docs
-///         #[attr]
-///         Bar
-///     ❱
-///
-///     // same for tuple and record variants
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct EnumVariant {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::VisibilityOwner for EnumVariant {}
-impl ast::NameOwner for EnumVariant {}
-impl ast::DocCommentsOwner for EnumVariant {}
 impl ast::AttrsOwner for EnumVariant {}
+impl ast::NameOwner for EnumVariant {}
+impl ast::VisibilityOwner for EnumVariant {}
 impl EnumVariant {
     pub fn field_def_list(&self) -> Option<FieldDefList> { support::child(&self.syntax) }
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Trait definition.
-/// Includes all of its attributes and doc comments.
-///
-/// ```
-/// ❰
-///     /// Docs
-///     #[attr]
-///     pub unsafe trait Foo<T>: Debug where T: Debug {
-///         // ...
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/traits.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TraitDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::VisibilityOwner for TraitDef {}
-impl ast::NameOwner for TraitDef {}
 impl ast::AttrsOwner for TraitDef {}
-impl ast::DocCommentsOwner for TraitDef {}
+impl ast::NameOwner for TraitDef {}
+impl ast::VisibilityOwner for TraitDef {}
 impl ast::TypeParamsOwner for TraitDef {}
 impl ast::TypeBoundsOwner for TraitDef {}
 impl TraitDef {
@@ -339,62 +235,13 @@ impl TraitDef {
     pub fn trait_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![trait]) }
     pub fn item_list(&self) -> Option<ItemList> { support::child(&self.syntax) }
 }
-/// Module definition either with body or not.
-/// Includes all of its inner and outer attributes, module items, doc comments.
-///
-/// ```
-/// ❰
-///     /// Docs
-///     #[attr]
-///     pub mod foo;
-/// ❱
-///
-/// ❰
-///     /// Docs
-///     #[attr]
-///     pub mod bar {
-///        //! Inner docs
-///        #![inner_attr]
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/modules.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Module {
+pub struct TypeBoundList {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::VisibilityOwner for Module {}
-impl ast::NameOwner for Module {}
-impl ast::AttrsOwner for Module {}
-impl ast::DocCommentsOwner for Module {}
-impl Module {
-    pub fn mod_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mod]) }
-    pub fn item_list(&self) -> Option<ItemList> { support::child(&self.syntax) }
-    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
+impl TypeBoundList {
+    pub fn bounds(&self) -> AstChildren<TypeBound> { support::children(&self.syntax) }
 }
-/// Item defintion list.
-/// This is used for both top-level items and impl block items.
-///
-/// ```
-/// ❰
-///     fn foo {}
-///     struct Bar;
-///     enum Baz;
-///     trait Bruh;
-///     const BRUUH: u32 = 42;
-/// ❱
-///
-/// impl Foo
-/// ❰
-///     {
-///         fn bar() {}
-///         const BAZ: u32 = 42;
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ItemList {
     pub(crate) syntax: SyntaxNode,
@@ -405,91 +252,58 @@ impl ItemList {
     pub fn assoc_items(&self) -> AstChildren<AssocItem> { support::children(&self.syntax) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
 }
-/// Constant variable definition.
-/// Includes all of its attributes and doc comments.
-///
-/// ```
-/// ❰
-///     /// Docs
-///     #[attr]
-///     pub const FOO: u32 = 42;
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/constant-items.html)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Module {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ast::AttrsOwner for Module {}
+impl ast::NameOwner for Module {}
+impl ast::VisibilityOwner for Module {}
+impl Module {
+    pub fn mod_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mod]) }
+    pub fn item_list(&self) -> Option<ItemList> { support::child(&self.syntax) }
+    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ConstDef {
     pub(crate) syntax: SyntaxNode,
 }
-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::NameOwner for ConstDef {}
+impl ast::VisibilityOwner for ConstDef {}
 impl ast::TypeAscriptionOwner for ConstDef {}
 impl ConstDef {
     pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
 }
-/// Static variable definition.
-/// Includes all of its attributes and doc comments.
-///
-/// ```
-/// ❰
-///     /// Docs
-///     #[attr]
-///     pub static mut FOO: u32 = 42;
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/static-items.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct StaticDef {
     pub(crate) syntax: SyntaxNode,
 }
-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::NameOwner for StaticDef {}
+impl ast::VisibilityOwner for StaticDef {}
 impl ast::TypeAscriptionOwner for StaticDef {}
 impl StaticDef {
     pub fn static_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![static]) }
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
 }
-/// Type alias definition.
-/// Includes associated type clauses with type bounds.
-///
-/// ```
-/// ❰
-///     /// Docs
-///     #[attr]
-///     pub type Foo<T> where T: Debug = T;
-/// ❱
-///
-/// trait Bar {
-///     ❰ type Baz: Debug; ❱
-///     ❰ type Bruh = String; ❱
-///     ❰ type Bruuh: Debug = u32; ❱
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/type-aliases.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeAliasDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::VisibilityOwner for TypeAliasDef {}
+impl ast::AttrsOwner for TypeAliasDef {}
 impl ast::NameOwner for TypeAliasDef {}
+impl ast::VisibilityOwner 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 default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
@@ -498,46 +312,22 @@ impl TypeAliasDef {
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
 }
-/// Inherent and trait impl definition.
-/// Includes all of its inner and outer attributes.
-///
-/// ```
-/// ❰
-///     #[attr]
-///     unsafe impl<T> const !Foo for Bar where T: Debug {
-///         #![inner_attr]
-///         // ...
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/implementations.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ImplDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::TypeParamsOwner for ImplDef {}
 impl ast::AttrsOwner for ImplDef {}
-impl ast::DocCommentsOwner for ImplDef {}
+impl ast::VisibilityOwner for ImplDef {}
+impl ast::TypeParamsOwner for ImplDef {}
 impl ImplDef {
-    pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
+    pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
     pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
     pub fn impl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![impl]) }
     pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
     pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
     pub fn item_list(&self) -> Option<ItemList> { support::child(&self.syntax) }
 }
-/// Parenthesized type reference.
-/// Note: parens are only used for grouping, this is not a tuple type.
-///
-/// ```
-/// // This is effectively just `u32`.
-/// // Single-item tuple must be defined with a trailing comma: `(u32,)`
-/// type Foo = ❰ (u32) ❱;
-///
-/// let bar: &'static ❰ (dyn Debug) ❱ = "bruh";
-/// ```
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ParenType {
     pub(crate) syntax: SyntaxNode,
@@ -547,13 +337,6 @@ impl ParenType {
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
-/// Unnamed tuple type.
-///
-/// ```
-/// let foo: ❰ (u32, bool) ❱ = (42, true);
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/types/tuple.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TupleType {
     pub(crate) syntax: SyntaxNode,
@@ -563,17 +346,6 @@ impl TupleType {
     pub fn fields(&self) -> AstChildren<TypeRef> { support::children(&self.syntax) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
-/// The never type (i.e. the exclamation point).
-///
-/// ```
-/// type T = ❰ ! ❱;
-///
-/// fn no_return() -> ❰ ! ❱ {
-///     loop {}
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/types/never.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct NeverType {
     pub(crate) syntax: SyntaxNode,
@@ -581,17 +353,6 @@ pub struct NeverType {
 impl NeverType {
     pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
 }
-/// Path to a type.
-/// Includes single identifier type names and elaborate paths with
-/// generic parameters.
-///
-/// ```
-/// type Foo = ❰ String ❱;
-/// type Bar = ❰ std::vec::Vec<T> ❱;
-/// type Baz = ❰ ::bruh::<Bruuh as Iterator>::Item ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/paths.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PathType {
     pub(crate) syntax: SyntaxNode,
@@ -599,14 +360,15 @@ pub struct PathType {
 impl PathType {
     pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
 }
-/// Raw pointer type.
-///
-/// ```
-/// type Foo = ❰ *const u32 ❱;
-/// type Bar = ❰ *mut u32 ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/types/pointer.html#raw-pointers-const-and-mut)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Path {
+    pub(crate) syntax: SyntaxNode,
+}
+impl Path {
+    pub fn qualifier(&self) -> Option<Path> { support::child(&self.syntax) }
+    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
+    pub fn segment(&self) -> Option<PathSegment> { support::child(&self.syntax) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PointerType {
     pub(crate) syntax: SyntaxNode,
@@ -617,13 +379,6 @@ impl PointerType {
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Array type.
-///
-/// ```
-/// type Foo = ❰ [u32; 24 - 3] ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/types/array.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ArrayType {
     pub(crate) syntax: SyntaxNode,
@@ -635,13 +390,6 @@ impl ArrayType {
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
 }
-/// Slice type.
-///
-/// ```
-/// type Foo = ❰ [u8] ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/types/slice.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct SliceType {
     pub(crate) syntax: SyntaxNode,
@@ -651,13 +399,6 @@ impl SliceType {
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
     pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
 }
-/// Reference type.
-///
-/// ```
-/// type Foo = ❰ &'static str ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/types/pointer.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ReferenceType {
     pub(crate) syntax: SyntaxNode,
@@ -670,13 +411,6 @@ impl ReferenceType {
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Placeholder type (i.e. the underscore).
-///
-/// ```
-/// let foo: ❰ _ ❱ = 42_u32;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/types/inferred.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PlaceholderType {
     pub(crate) syntax: SyntaxNode,
@@ -684,15 +418,6 @@ pub struct PlaceholderType {
 impl PlaceholderType {
     pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
 }
-/// Function pointer type (not to be confused with `Fn*` family of traits).
-///
-/// ```
-/// type Foo = ❰ async fn(#[attr] u32, named: bool) -> u32 ❱;
-///
-/// type Bar = ❰ extern "C" fn(variadic: u32, #[attr] ...) ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/types/function-pointer.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FnPointerType {
     pub(crate) syntax: SyntaxNode,
@@ -704,13 +429,6 @@ impl FnPointerType {
     pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
     pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
 }
-/// Higher order type.
-///
-/// ```
-/// type Foo = ❰ for<'a> fn(&'a str) ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/nomicon/hrtb.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ForType {
     pub(crate) syntax: SyntaxNode,
@@ -720,43 +438,22 @@ impl ForType {
     pub fn type_param_list(&self) -> Option<TypeParamList> { support::child(&self.syntax) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Opaque `impl Trait` type.
-///
-/// ```
-/// fn foo(bar: ❰ impl Debug + Eq ❱) {}
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/types/impl-trait.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ImplTraitType {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::TypeBoundsOwner for ImplTraitType {}
 impl ImplTraitType {
     pub fn impl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![impl]) }
+    pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
 }
-/// Trait object type.
-///
-/// ```
-/// type Foo = ❰ dyn Debug ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/types/trait-object.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct DynTraitType {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::TypeBoundsOwner for DynTraitType {}
 impl DynTraitType {
     pub fn dyn_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![dyn]) }
+    pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
 }
-/// Tuple literal.
-///
-/// ```
-/// ❰ (42, true) ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/tuple-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TupleExpr {
     pub(crate) syntax: SyntaxNode,
@@ -767,15 +464,6 @@ impl TupleExpr {
     pub fn exprs(&self) -> AstChildren<Expr> { support::children(&self.syntax) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
-/// Array literal.
-///
-/// ```
-/// ❰ [#![inner_attr] true, false, true] ❱;
-///
-/// ❰ ["baz"; 24] ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/array-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ArrayExpr {
     pub(crate) syntax: SyntaxNode,
@@ -784,17 +472,10 @@ impl ast::AttrsOwner for ArrayExpr {}
 impl ArrayExpr {
     pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
     pub fn exprs(&self) -> AstChildren<Expr> { support::children(&self.syntax) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
     pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
 }
-/// Parenthesized expression.
-/// Note: parens are only used for grouping, this is not a tuple literal.
-///
-/// ```
-/// ❰ (#![inner_attr] 2 + 2) ❱ * 2;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/grouped-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ParenExpr {
     pub(crate) syntax: SyntaxNode,
@@ -805,19 +486,6 @@ impl ParenExpr {
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
-/// Path to a symbol in expression context.
-/// Includes single identifier variable names and elaborate paths with
-/// generic parameters.
-///
-/// ```
-/// ❰ Some::<i32> ❱;
-/// ❰ foo ❱ + 42;
-/// ❰ Vec::<i32>::push ❱;
-/// ❰ <[i32]>::reverse ❱;
-/// ❰ <String as std::borrow::Borrow<str>>::borrow ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/path-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PathExpr {
     pub(crate) syntax: SyntaxNode,
@@ -825,17 +493,6 @@ pub struct PathExpr {
 impl PathExpr {
     pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
 }
-/// Anonymous callable object literal a.k.a. closure, lambda or functor.
-///
-/// ```
-/// ❰ || 42 ❱;
-/// ❰ |a: u32| val + 1 ❱;
-/// ❰ async |#[attr] Pattern(_): Pattern| { bar } ❱;
-/// ❰ move || baz ❱;
-/// ❰ || -> u32 { closure_with_ret_type_annotation_requires_block_expr } ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/closure-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LambdaExpr {
     pub(crate) syntax: SyntaxNode,
@@ -849,25 +506,6 @@ impl LambdaExpr {
     pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
     pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// If expression. Includes both regular `if` and `if let` forms.
-/// Beware that `else if` is a special case syntax sugar, because in general
-/// there has to be block expression after `else`.
-///
-/// ```
-/// ❰ if bool_cond { 42 } ❱
-/// ❰ if bool_cond { 42 } else { 24 } ❱
-/// ❰ if bool_cond { 42 } else if bool_cond2 { 42 } ❱
-///
-/// ❰
-///     if let Pattern(foo) = bar {
-///         foo
-///     } else {
-///         panic!();
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/if-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct IfExpr {
     pub(crate) syntax: SyntaxNode,
@@ -877,40 +515,16 @@ impl IfExpr {
     pub fn if_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![if]) }
     pub fn condition(&self) -> Option<Condition> { support::child(&self.syntax) }
 }
-/// Unconditional loop expression.
-///
-/// ```
-/// ❰
-///     loop {
-///         // yeah, it's that simple...
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LoopExpr {
+pub struct Condition {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::AttrsOwner for LoopExpr {}
-impl ast::LoopBodyOwner for LoopExpr {}
-impl LoopExpr {
-    pub fn loop_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![loop]) }
+impl Condition {
+    pub fn let_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![let]) }
+    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Block expression with an optional prefix (label, try ketword,
-/// unsafe keyword, async keyword...).
-///
-/// ```
-/// ❰
-///     'label: try {
-///         None?
-///     }
-/// ❱
-/// ```
-///
-/// - [try block](https://doc.rust-lang.org/unstable-book/language-features/try-blocks.html)
-/// - [unsafe block](https://doc.rust-lang.org/reference/expressions/block-expr.html#unsafe-blocks)
-/// - [async block](https://doc.rust-lang.org/reference/expressions/block-expr.html#async-blocks)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct EffectExpr {
     pub(crate) syntax: SyntaxNode,
@@ -923,19 +537,24 @@ impl EffectExpr {
     pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
     pub fn block_expr(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
 }
-/// For loop expression.
-/// Note: record struct literals are not valid as iterable expression
-/// due to ambiguity.
-///
-/// ```
-/// ❰
-/// for i in (0..4) {
-///     dbg!(i);
-/// }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Label {
+    pub(crate) syntax: SyntaxNode,
+}
+impl Label {
+    pub fn lifetime_token(&self) -> Option<SyntaxToken> {
+        support::token(&self.syntax, T![lifetime])
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct LoopExpr {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ast::AttrsOwner for LoopExpr {}
+impl ast::LoopBodyOwner for LoopExpr {}
+impl LoopExpr {
+    pub fn loop_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![loop]) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ForExpr {
     pub(crate) syntax: SyntaxNode,
@@ -948,22 +567,6 @@ impl ForExpr {
     pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) }
     pub fn iterable(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// While loop expression. Includes both regular `while` and `while let` forms.
-///
-/// ```
-/// ❰
-///     while bool_cond {
-///         42;
-///     }
-/// ❱
-/// ❰
-///     while let Pattern(foo) = bar {
-///         bar += 1;
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-loops)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct WhileExpr {
     pub(crate) syntax: SyntaxNode,
@@ -974,22 +577,6 @@ impl WhileExpr {
     pub fn while_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![while]) }
     pub fn condition(&self) -> Option<Condition> { support::child(&self.syntax) }
 }
-/// Continue expression.
-///
-/// ```
-/// while bool_cond {
-///     ❰ continue ❱;
-/// }
-///
-/// 'outer: loop {
-///     loop {
-///         ❰ continue 'outer ❱;
-///     }
-/// }
-///
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#continue-expressions)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ContinueExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1003,25 +590,6 @@ impl ContinueExpr {
         support::token(&self.syntax, T![lifetime])
     }
 }
-/// Break expression.
-///
-/// ```
-/// while bool_cond {
-///     ❰ break ❱;
-/// }
-/// 'outer: loop {
-///     for foo in bar {
-///         ❰ break 'outer ❱;
-///     }
-/// }
-/// 'outer: loop {
-///     loop {
-///         ❰ break 'outer 42 ❱;
-///     }
-/// }
-/// ```
-///
-/// [Refernce](https://doc.rust-lang.org/reference/expressions/loop-expr.html#break-expressions)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BreakExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1034,104 +602,33 @@ impl BreakExpr {
     }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Label.
-///
-/// ```
-/// ❰ 'outer: ❱ loop {}
-///
-/// let foo = ❰ 'bar: ❱ loop {}
-///
-/// ❰ 'baz: ❱ {
-///     break 'baz;
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html?highlight=label#loop-labels)
-/// [Labels for blocks RFC](https://github.com/rust-lang/rfcs/blob/master/text/2046-label-break-value.md)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Label {
-    pub(crate) syntax: SyntaxNode,
-}
-impl Label {
-    pub fn lifetime_token(&self) -> Option<SyntaxToken> {
-        support::token(&self.syntax, T![lifetime])
-    }
-}
-/// Block expression. Includes unsafe blocks and block labels.
-///
-/// ```
-///     let foo = ❰
-///         {
-///             #![inner_attr]
-///             ❰ { } ❱
-///
-///             ❰ 'label: { break 'label } ❱
-///         }
-///     ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/block-expr.html)
-/// [Labels for blocks RFC](https://github.com/rust-lang/rfcs/blob/master/text/2046-label-break-value.md)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct BlockExpr {
-    pub(crate) syntax: SyntaxNode,
-}
-impl ast::AttrsOwner for BlockExpr {}
-impl ast::ModuleItemOwner for BlockExpr {}
-impl BlockExpr {
-    pub fn label(&self) -> Option<Label> { support::child(&self.syntax) }
-    pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
-    pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
-    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
-    pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
-}
-/// Return expression.
-///
-/// ```
-/// || ❰ return 42 ❱;
-///
-/// fn bar() {
-///     ❰ return ❱;
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/return-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ReturnExpr {
     pub(crate) syntax: SyntaxNode,
 }
 impl ast::AttrsOwner for ReturnExpr {}
 impl ReturnExpr {
+    pub fn return_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![return]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Call expression (not to be confused with method call expression, it is
-/// a separate ast node).
-///
-/// ```
-/// ❰ foo() ❱;
-/// ❰ &str::len("bar") ❱;
-/// ❰ <&str as PartialEq<&str>>::eq(&"", &"") ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/call-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct CallExpr {
     pub(crate) syntax: SyntaxNode,
 }
+impl ast::AttrsOwner for CallExpr {}
 impl ast::ArgListOwner for CallExpr {}
 impl CallExpr {
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Method call expression.
-///
-/// ```
-/// ❰ receiver_expr.method() ❱;
-/// ❰ receiver_expr.method::<T>(42, true) ❱;
-///
-/// ❰ ❰ ❰ foo.bar() ❱ .baz() ❱ .bruh() ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/method-call-expr.html)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct ArgList {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ArgList {
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn args(&self) -> AstChildren<Expr> { support::children(&self.syntax) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MethodCallExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1144,31 +641,26 @@ impl MethodCallExpr {
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
     pub fn type_arg_list(&self) -> Option<TypeArgList> { support::child(&self.syntax) }
 }
-/// Index expression a.k.a. subscript operator call.
-///
-/// ```
-/// ❰ foo[42] ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/array-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct IndexExpr {
+pub struct NameRef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::AttrsOwner for IndexExpr {}
-impl IndexExpr {
-    pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
-    pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
+impl NameRef {
+    pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct TypeArgList {
+    pub(crate) syntax: SyntaxNode,
+}
+impl TypeArgList {
+    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
+    pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
+    pub fn type_args(&self) -> AstChildren<TypeArg> { support::children(&self.syntax) }
+    pub fn lifetime_args(&self) -> AstChildren<LifetimeArg> { support::children(&self.syntax) }
+    pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> { support::children(&self.syntax) }
+    pub fn const_args(&self) -> AstChildren<ConstArg> { support::children(&self.syntax) }
+    pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
 }
-/// Field access expression.
-///
-/// ```
-/// ❰ expr.bar ❱;
-///
-/// ❰ ❰ ❰ foo.bar ❱ .baz ❱ .bruh ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/field-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FieldExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1179,13 +671,15 @@ impl FieldExpr {
     pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
 }
-/// Await operator call expression.
-///
-/// ```
-/// ❰ expr.await ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/await-expr.html)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct IndexExpr {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ast::AttrsOwner for IndexExpr {}
+impl IndexExpr {
+    pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
+    pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct AwaitExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1196,13 +690,6 @@ impl AwaitExpr {
     pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
     pub fn await_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![await]) }
 }
-/// The question mark operator call.
-///
-/// ```
-/// ❰ expr? ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TryExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1212,13 +699,6 @@ impl TryExpr {
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn question_mark_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![?]) }
 }
-/// Type cast expression.
-///
-/// ```
-/// ❰ expr as T ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct CastExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1229,16 +709,6 @@ impl CastExpr {
     pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Borrow operator call.
-///
-/// ```
-/// ❰ &foo ❱;
-/// ❰ &mut bar ❱;
-/// ❰ &raw const bar ❱;
-/// ❰ &raw mut bar ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#borrow-operators)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RefExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1251,15 +721,6 @@ impl RefExpr {
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Prefix operator call. This is either `!` or `*` or `-`.
-///
-/// ```
-/// ❰ !foo ❱;
-/// ❰ *bar ❱;
-/// ❰ -42 ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PrefixExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1268,13 +729,6 @@ impl ast::AttrsOwner for PrefixExpr {}
 impl PrefixExpr {
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Box operator call.
-///
-/// ```
-/// ❰ box 42 ❱;
-/// ```
-///
-/// [RFC](https://github.com/rust-lang/rfcs/blob/0806be4f282144cfcd55b1d20284b43f87cbe1c6/text/0809-box-and-in-for-stdlib.md)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BoxExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1284,69 +738,23 @@ impl BoxExpr {
     pub fn box_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![box]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Range operator call.
-///
-/// ```
-/// ❰ 0..42 ❱;
-/// ❰ ..42 ❱;
-/// ❰ 0.. ❱;
-/// ❰ .. ❱;
-/// ❰ 0..=42 ❱;
-/// ❰ ..=42 ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/range-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RangeExpr {
     pub(crate) syntax: SyntaxNode,
 }
 impl ast::AttrsOwner for RangeExpr {}
 impl RangeExpr {}
-/// Binary operator call.
-/// Includes all arithmetic, logic, bitwise and assignment operators.
-///
-/// ```
-/// ❰ 2 + ❰ 2 * 2 ❱ ❱;
-/// ❰ ❰ true && false ❱ || true ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BinExpr {
     pub(crate) syntax: SyntaxNode,
 }
 impl ast::AttrsOwner for BinExpr {}
 impl BinExpr {}
-/// [Raw] string, [raw] byte string, char, byte, integer, float or bool literal.
-///
-/// ```
-/// ❰ "str" ❱;
-/// ❰ br##"raw byte str"## ❱;
-/// ❰ 'c' ❱;
-/// ❰ b'c' ❱;
-/// ❰ 42 ❱;
-/// ❰ 1e9 ❱;
-/// ❰ true ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/literal-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Literal {
     pub(crate) syntax: SyntaxNode,
 }
 impl Literal {}
-/// Match expression.
-///
-/// ```
-/// ❰
-///     match expr {
-///         Pat1 => {}
-///         Pat2(_) => 42,
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MatchExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1357,40 +765,15 @@ impl MatchExpr {
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn match_arm_list(&self) -> Option<MatchArmList> { support::child(&self.syntax) }
 }
-/// Match arm list part of match expression. Includes its inner attributes.
-///
-/// ```
-/// match expr
-/// ❰
-///     {
-///         #![inner_attr]
-///         Pat1 => {}
-///         Pat2(_) => 42,
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MatchArmList {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::AttrsOwner for MatchArmList {}
 impl MatchArmList {
     pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
     pub fn arms(&self) -> AstChildren<MatchArm> { support::children(&self.syntax) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
 }
-/// Match arm.
-/// Note: record struct literals are not valid as target match expression
-/// due to ambiguity.
-/// ```
-/// match expr {
-///     ❰ #[attr] Pattern(it) if bool_cond => it ❱,
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MatchArm {
     pub(crate) syntax: SyntaxNode,
@@ -1402,15 +785,6 @@ impl MatchArm {
     pub fn fat_arrow_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=>]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Match guard.
-///
-/// ```
-/// match expr {
-///     Pattern(it) ❰ if bool_cond ❱ => it,
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html#match-guards)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MatchGuard {
     pub(crate) syntax: SyntaxNode,
@@ -1419,21 +793,6 @@ impl MatchGuard {
     pub fn if_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![if]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Record literal expression. The same syntax is used for structs,
-/// unions and record enum variants.
-///
-/// ```
-/// ❰
-///     foo::Bar {
-///         #![inner_attr]
-///         baz: 42,
-///         bruh: true,
-///         ..spread
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RecordLit {
     pub(crate) syntax: SyntaxNode,
@@ -1442,16 +801,6 @@ impl RecordLit {
     pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
     pub fn record_field_list(&self) -> Option<RecordFieldList> { support::child(&self.syntax) }
 }
-/// Record field list including enclosing curly braces.
-///
-/// foo::Bar ❰
-///     {
-///         baz: 42,
-///         ..spread
-///     }
-/// ❱
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RecordFieldList {
     pub(crate) syntax: SyntaxNode,
@@ -1463,15 +812,6 @@ impl RecordFieldList {
     pub fn spread(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
 }
-/// Record field.
-///
-/// ```
-/// foo::Bar {
-///     ❰ #[attr] baz: 42 ❱
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RecordField {
     pub(crate) syntax: SyntaxNode,
@@ -1482,13 +822,6 @@ impl RecordField {
     pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Disjunction of patterns.
-///
-/// ```
-/// let ❰ Foo(it) | Bar(it) | Baz(it) ❱ = bruh;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct OrPat {
     pub(crate) syntax: SyntaxNode,
@@ -1496,14 +829,6 @@ pub struct OrPat {
 impl OrPat {
     pub fn pats(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
 }
-/// Parenthesized pattern.
-/// Note: parens are only used for grouping, this is not a tuple pattern.
-///
-/// ```
-/// if let ❰ &(0..=42) ❱ = foo {}
-/// ```
-///
-/// https://doc.rust-lang.org/reference/patterns.html#grouped-patterns
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ParenPat {
     pub(crate) syntax: SyntaxNode,
@@ -1513,16 +838,6 @@ impl ParenPat {
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
-/// Reference pattern.
-/// Note: this has nothing to do with `ref` keyword, the latter is used in bind patterns.
-///
-/// ```
-/// let ❰ &mut foo ❱ = bar;
-///
-/// let ❰ & ❰ &mut ❰ &_ ❱ ❱ ❱ = baz;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#reference-patterns)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RefPat {
     pub(crate) syntax: SyntaxNode,
@@ -1532,31 +847,14 @@ impl RefPat {
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
 }
-/// Box pattern.
-///
-/// ```
-/// let ❰ box foo ❱ = box 42;
-/// ```
-///
-/// [Unstable book](https://doc.rust-lang.org/unstable-book/language-features/box-patterns.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BoxPat {
     pub(crate) syntax: SyntaxNode,
 }
 impl BoxPat {
     pub fn box_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![box]) }
-    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
+    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
 }
-/// Bind pattern.
-///
-/// ```
-/// match foo {
-///     Some(❰ ref mut bar ❱) => {}
-///     ❰ baz @ None ❱ => {}
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#identifier-patterns)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BindPat {
     pub(crate) syntax: SyntaxNode,
@@ -1569,13 +867,6 @@ impl BindPat {
     pub fn at_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![@]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
 }
-/// Placeholder pattern a.k.a. the wildcard pattern or the underscore.
-///
-/// ```
-/// let ❰ _ ❱ = foo;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#wildcard-pattern)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PlaceholderPat {
     pub(crate) syntax: SyntaxNode,
@@ -1583,16 +874,6 @@ pub struct PlaceholderPat {
 impl PlaceholderPat {
     pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
 }
-/// Rest-of-the record/tuple pattern.
-/// Note: this is not the unbonded range pattern (even more: it doesn't exist).
-///
-/// ```
-/// let Foo { bar, ❰ .. ❱ } = baz;
-/// let (❰ .. ❱, bruh) = (42, 24, 42);
-/// let Bruuh(❰ .. ❱) = bruuuh;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct DotDotPat {
     pub(crate) syntax: SyntaxNode,
@@ -1600,15 +881,6 @@ pub struct DotDotPat {
 impl DotDotPat {
     pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
 }
-/// Path pattern.
-/// Doesn't include the underscore pattern (it is a special case, namely `PlaceholderPat`).
-///
-/// ```
-/// let ❰ foo::bar::Baz ❱ { .. } = bruh;
-/// if let ❰ CONST ❱ = 42 {}
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#path-patterns)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PathPat {
     pub(crate) syntax: SyntaxNode,
@@ -1616,13 +888,6 @@ pub struct PathPat {
 impl PathPat {
     pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
 }
-/// Slice pattern.
-///
-/// ```
-/// let ❰ [foo, bar, baz] ❱ = [1, 2, 3];
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#slice-patterns)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct SlicePat {
     pub(crate) syntax: SyntaxNode,
@@ -1632,33 +897,14 @@ impl SlicePat {
     pub fn args(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
     pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
 }
-/// Range pattern.
-///
-/// ```
-/// match foo {
-///     ❰ 0..42 ❱ => {}
-///     ❰ 0..=42 ❱ => {}
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#range-patterns)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RangePat {
     pub(crate) syntax: SyntaxNode,
 }
-impl RangePat {}
-/// Literal pattern.
-/// Includes only bool, number, char, and string literals.
-///
-/// ```
-/// match foo {
-///     Number(❰ 42 ❱) => {}
-///     String(❰ "42" ❱) => {}
-///     Bool(❰ true ❱) => {}
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#literal-patterns)
+impl RangePat {
+    pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
+    pub fn dotdoteq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..=]) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LiteralPat {
     pub(crate) syntax: SyntaxNode,
@@ -1666,13 +912,6 @@ pub struct LiteralPat {
 impl LiteralPat {
     pub fn literal(&self) -> Option<Literal> { support::child(&self.syntax) }
 }
-/// Macro invocation in pattern position.
-///
-/// ```
-/// let ❰ foo!(my custom syntax) ❱ = baz;
-///
-/// ```
-/// [Reference](https://doc.rust-lang.org/reference/macros.html#macro-invocation)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MacroPat {
     pub(crate) syntax: SyntaxNode,
@@ -1680,30 +919,28 @@ pub struct MacroPat {
 impl MacroPat {
     pub fn macro_call(&self) -> Option<MacroCall> { support::child(&self.syntax) }
 }
-/// Record literal pattern.
-///
-/// ```
-/// let ❰ foo::Bar { baz, .. } ❱ = bruh;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct MacroCall {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ast::AttrsOwner for MacroCall {}
+impl ast::NameOwner for MacroCall {}
+impl MacroCall {
+    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
+    pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
+    pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
+    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RecordPat {
     pub(crate) syntax: SyntaxNode,
 }
 impl RecordPat {
+    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
     pub fn record_field_pat_list(&self) -> Option<RecordFieldPatList> {
         support::child(&self.syntax)
     }
-    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
 }
-/// Record literal's field patterns list including enclosing curly braces.
-///
-/// ```
-/// let foo::Bar ❰ { baz, bind @ bruh, .. } ❱ = bruuh;
-/// ``
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RecordFieldPatList {
     pub(crate) syntax: SyntaxNode,
@@ -1717,15 +954,6 @@ impl RecordFieldPatList {
     pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
 }
-/// Record literal's field pattern.
-/// Note: record literal can also match tuple structs.
-///
-/// ```
-/// let Foo { ❰ bar: _ ❱ } = baz;
-/// let TupleStruct { ❰ 0: _ ❱ } = bruh;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RecordFieldPat {
     pub(crate) syntax: SyntaxNode,
@@ -1736,13 +964,6 @@ impl RecordFieldPat {
     pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
 }
-/// Tuple struct literal pattern.
-///
-/// ```
-/// let ❰ foo::Bar(baz, bruh) ❱ = bruuh;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#tuple-struct-patterns)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TupleStructPat {
     pub(crate) syntax: SyntaxNode,
@@ -1753,14 +974,6 @@ impl TupleStructPat {
     pub fn args(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
-/// Tuple pattern.
-/// Note: this doesn't include tuple structs (see `TupleStructPat`)
-///
-/// ```
-/// let ❰ (foo, bar, .., baz) ❱ = bruh;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/patterns.html#tuple-patterns)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TuplePat {
     pub(crate) syntax: SyntaxNode,
@@ -1770,209 +983,51 @@ impl TuplePat {
     pub fn args(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
-/// Visibility.
-///
-/// ```
-/// ❰ pub mod ❱ foo;
-/// ❰ pub(crate) ❱ struct Bar;
-/// ❰ pub(self) ❱ enum Baz {}
-/// ❰ pub(super) ❱ fn bruh() {}
-/// ❰ pub(in bruuh::bruuuh) ❱ type T = u64;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/visibility-and-privacy.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Visibility {
-    pub(crate) syntax: SyntaxNode,
-}
-impl Visibility {
-    pub fn pub_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![pub]) }
-    pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) }
-    pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
-    pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
-}
-/// Single identifier.
-/// Note(@matklad): `Name` is for things that install a new name into the scope,
-/// `NameRef` is a usage of a name. Most of the time, this definition/reference
-/// distinction can be determined purely syntactically, ie in
-/// ```
-/// fn foo() { foo() }
-/// ```
-/// the first foo is `Name`, the second one is `NameRef`.
-/// The notable exception are patterns, where in
-/// ``
-/// let x = 92
-/// ```
-/// `x` can be semantically either a name or a name ref, depeding on
-/// wether there's an `x` constant in scope.
-/// We use `Name` for patterns, and disambiguate semantically (see `NameClass` in ide_db).
-///
-/// ```
-/// let ❰ foo ❱ = bar;
-/// struct ❰ Baz ❱;
-/// fn ❰ bruh ❱() {}
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/identifiers.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Name {
+pub struct TokenTree {
     pub(crate) syntax: SyntaxNode,
 }
-impl Name {
-    pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) }
-}
-/// Reference to a name.
-/// See the explanation on the difference between `Name` and `NameRef`
-/// in `Name` ast node docs.
-///
-/// ```
-/// let foo = ❰ bar ❱(❰ Baz(❰ bruh ❱) ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/identifiers.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct NameRef {
-    pub(crate) syntax: SyntaxNode,
+impl TokenTree {
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+    pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
+    pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
+    pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
+    pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
 }
-impl NameRef {}
-/// Macro call.
-/// Includes all of its attributes and doc comments.
-///
-/// ```
-/// ❰
-///     /// Docs
-///     #[attr]
-///     macro_rules! foo {   // macro rules is also a macro call
-///         ($bar: tt) => {}
-///     }
-/// ❱
-///
-/// // semicolon is a part of `MacroCall` when it is used in item positions
-/// ❰ foo!(); ❱
-///
-/// fn main() {
-///     ❰ foo!() ❱; // macro call in expression positions doesn't include the semi
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/macros.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MacroCall {
+pub struct MacroDef {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::NameOwner for MacroCall {}
-impl ast::AttrsOwner for MacroCall {}
-impl ast::DocCommentsOwner for MacroCall {}
-impl MacroCall {
-    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
-    pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
+impl ast::NameOwner for MacroDef {}
+impl MacroDef {
     pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
-    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
-}
-/// Attribute.
-///
-/// ```
-/// ❰ #![inner_attr] ❱
-///
-/// ❰ #[attr] ❱
-/// ❰ #[foo = "bar"] ❱
-/// ❰ #[baz(bruh::bruuh = "42")] ❱
-/// struct Foo;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/attributes.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Attr {
-    pub(crate) syntax: SyntaxNode,
 }
-impl Attr {
-    pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
-    pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
-    pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
-    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
-    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
-    pub fn input(&self) -> Option<AttrInput> { support::child(&self.syntax) }
-    pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
-}
-/// Stores a list of lexer tokens and other `TokenTree`s.
-/// It appears in attributes, macro_rules and macro call (foo!)
-///
-/// ```
-/// macro_call! ❰ { my syntax here } ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/macros.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TokenTree {
+pub struct MacroItems {
     pub(crate) syntax: SyntaxNode,
 }
-impl TokenTree {}
-/// Generic lifetime, type and constants parameters list **declaration**.
-///
-/// ```
-/// fn foo❰ <'a, 'b, T, U, const BAR: u64> ❱() {}
-///
-/// struct Baz❰ <T> ❱(T);
-///
-/// impl❰ <T> ❱ Bruh<T> {}
-///
-/// type Bruuh = for❰ <'a> ❱ fn(&'a str) -> &'a str;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
+impl ast::ModuleItemOwner for MacroItems {}
+impl MacroItems {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TypeParamList {
+pub struct MacroStmts {
     pub(crate) syntax: SyntaxNode,
 }
-impl TypeParamList {
-    pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
-    pub fn type_params(&self) -> AstChildren<TypeParam> { support::children(&self.syntax) }
-    pub fn lifetime_params(&self) -> AstChildren<LifetimeParam> { support::children(&self.syntax) }
-    pub fn const_params(&self) -> AstChildren<ConstParam> { support::children(&self.syntax) }
-    pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
+impl MacroStmts {
+    pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
-/// Single type parameter **declaration**.
-///
-/// ```
-/// fn foo<❰ K ❱, ❰ I ❱, ❰ E: Debug ❱, ❰ V = DefaultType ❱>() {}
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeParam {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::NameOwner for TypeParam {}
 impl ast::AttrsOwner for TypeParam {}
+impl ast::NameOwner for TypeParam {}
 impl ast::TypeBoundsOwner for TypeParam {}
 impl TypeParam {
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn default_type(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Const generic parameter **declaration**.
-/// ```
-/// fn foo<T, U, ❰ const BAR: usize ❱, ❰ const BAZ: bool ❱>() {}
-/// ```
-///
-/// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md#declaring-a-const-parameter)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ConstParam {
-    pub(crate) syntax: SyntaxNode,
-}
-impl ast::NameOwner for ConstParam {}
-impl ast::AttrsOwner for ConstParam {}
-impl ast::TypeAscriptionOwner for ConstParam {}
-impl ConstParam {
-    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
-    pub fn default_val(&self) -> Option<Expr> { support::child(&self.syntax) }
-}
-/// Lifetime parameter **declaration**.
-///
-/// ```
-/// fn foo<❰ 'a ❱, ❰ 'b ❱, V, G, D>(bar: &'a str, baz: &'b mut str) {}
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LifetimeParam {
     pub(crate) syntax: SyntaxNode,
@@ -1983,20 +1038,19 @@ impl LifetimeParam {
         support::token(&self.syntax, T![lifetime])
     }
 }
-/// Type bound declaration clause.
-///
-/// ```
-/// fn foo<T: ❰ ?Sized ❱ + ❰ Debug ❱>() {}
-///
-/// trait Bar<T>
-/// where
-///     T: ❰ Send ❱ + ❰ Sync ❱
-/// {
-///     type Baz: ❰ !Sync ❱ + ❰ Debug ❱ + ❰ ?const Add ❱;
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/trait-bounds.html)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct ConstParam {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ast::AttrsOwner for ConstParam {}
+impl ast::NameOwner for ConstParam {}
+impl ast::TypeAscriptionOwner for ConstParam {}
+impl ConstParam {
+    pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+    pub fn default_val(&self) -> Option<Expr> { support::child(&self.syntax) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeBound {
     pub(crate) syntax: SyntaxNode,
@@ -2008,40 +1062,6 @@ impl TypeBound {
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Type bounds list.
-///
-/// ```
-///
-/// fn foo<T: ❰ ?Sized + Debug ❱>() {}
-///
-/// trait Bar<T>
-/// where
-///     T: ❰ Send + Sync ❱
-/// {
-///     type Baz: ❰ !Sync + Debug ❱;
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/trait-bounds.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TypeBoundList {
-    pub(crate) syntax: SyntaxNode,
-}
-impl TypeBoundList {
-    pub fn bounds(&self) -> AstChildren<TypeBound> { support::children(&self.syntax) }
-}
-/// Single where predicate.
-///
-/// ```
-/// trait Foo<'a, 'b, T>
-/// where
-///     ❰ 'a: 'b ❱,
-///     ❰ T: IntoIterator ❱,
-///     ❰ for<'c> <T as IntoIterator>::Item: Bar<'c> ❱
-/// {}
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/generics.html#where-clauses)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct WherePred {
     pub(crate) syntax: SyntaxNode,
@@ -2055,58 +1075,6 @@ impl WherePred {
     }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Where clause.
-///
-/// ```
-/// trait Foo<'a, T> ❰ where 'a: 'static, T: Debug ❱ {}
-///
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/generics.html#where-clauses)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct WhereClause {
-    pub(crate) syntax: SyntaxNode,
-}
-impl WhereClause {
-    pub fn where_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![where]) }
-    pub fn predicates(&self) -> AstChildren<WherePred> { support::children(&self.syntax) }
-}
-/// Abi declaration.
-/// Note: the abi string is optional.
-///
-/// ```
-/// ❰ extern "C" ❱ {
-///     fn foo() {}
-/// }
-///
-/// type Bar = ❰ extern ❱ fn() -> u32;
-///
-/// type Baz = ❰ extern r#"stdcall"# ❱ fn() -> bool;
-/// ```
-///
-/// - [Extern blocks reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
-/// - [FFI function pointers reference](https://doc.rust-lang.org/reference/items/functions.html#functions)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Abi {
-    pub(crate) syntax: SyntaxNode,
-}
-impl Abi {}
-/// Expression statement.
-///
-/// ```
-/// ❰ 42; ❱
-/// ❰ foo(); ❱
-/// ❰ (); ❱
-/// ❰ {}; ❱
-///
-/// // constructions with trailing curly brace can omit the semicolon
-/// // but only when there are satements immediately after them (this is important!)
-/// ❰ if bool_cond { } ❱
-/// ❰ loop {} ❱
-/// ❰ somestatment; ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/statements.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ExprStmt {
     pub(crate) syntax: SyntaxNode,
@@ -2116,16 +1084,6 @@ impl ExprStmt {
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
 }
-/// Let statement.
-///
-/// ```
-/// ❰ #[attr] let foo; ❱
-/// ❰ let bar: u64; ❱
-/// ❰ let baz = 42; ❱
-/// ❰ let bruh: bool = true; ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/statements.html#let-statements)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LetStmt {
     pub(crate) syntax: SyntaxNode,
@@ -2135,112 +1093,37 @@ impl ast::TypeAscriptionOwner for LetStmt {}
 impl LetStmt {
     pub fn let_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![let]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn initializer(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
 }
-/// Condition of `if` or `while` expression.
-///
-/// ```
-/// if ❰ true ❱ {}
-/// if ❰ let Pat(foo) = bar ❱ {}
-///
-/// while ❰ true ❱ {}
-/// while ❰ let Pat(baz) = bruh ❱ {}
-/// ```
-///
-/// [If expression reference](https://doc.rust-lang.org/reference/expressions/if-expr.html)
-/// [While expression reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-loops)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Condition {
-    pub(crate) syntax: SyntaxNode,
-}
-impl Condition {
-    pub fn let_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![let]) }
-    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
-    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
-    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
-}
-/// Parameter list **declaration**.
-///
-/// ```
-/// fn foo❰ (a: u32, b: bool) ❱ -> u32 {}
-/// let bar = ❰ |a, b| ❱ {};
-///
-/// impl Baz {
-///     fn bruh❰ (&self, a: u32) ❱ {}
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/functions.html)ocs to codegen script
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ParamList {
-    pub(crate) syntax: SyntaxNode,
-}
-impl ParamList {
-    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
-    pub fn self_param(&self) -> Option<SelfParam> { support::child(&self.syntax) }
-    pub fn params(&self) -> AstChildren<Param> { support::children(&self.syntax) }
-    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
-}
-/// Self parameter **declaration**.
-///
-/// ```
-/// impl Bruh {
-///     fn foo(❰ self ❱) {}
-///     fn bar(❰ &self ❱) {}
-///     fn baz(❰ &mut self ❱) {}
-///     fn blah<'a>(❰ &'a self ❱) {}
-///     fn blin(❰ self: Box<Self> ❱) {}
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct SelfParam {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::TypeAscriptionOwner for SelfParam {}
 impl ast::AttrsOwner for SelfParam {}
+impl ast::TypeAscriptionOwner for SelfParam {}
 impl SelfParam {
     pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
-    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
     pub fn lifetime_token(&self) -> Option<SyntaxToken> {
         support::token(&self.syntax, T![lifetime])
     }
+    pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
     pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
 }
-/// Parameter **declaration**.
-///
-/// ```
-/// fn foo(❰ #[attr] Pat(bar): Pat(u32) ❱, ❰ #[attr] _: bool ❱) {}
-///
-/// extern "C" {
-///     fn bar(❰ baz: u32 ❱, ❰ ... ❱) -> u32;
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Param {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::TypeAscriptionOwner for Param {}
 impl ast::AttrsOwner for Param {}
+impl ast::TypeAscriptionOwner for Param {}
 impl Param {
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
     pub fn dotdotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![...]) }
 }
-/// Use declaration.
-///
-/// ```
-/// ❰ #[attr] pub use foo; ❱
-/// ❰ use bar as baz; ❱
-/// ❰ use bruh::{self, bruuh}; ❱
-/// ❰ use { blin::blen, blah::* };
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct UseItem {
     pub(crate) syntax: SyntaxNode,
@@ -2250,53 +1133,19 @@ impl ast::VisibilityOwner for UseItem {}
 impl UseItem {
     pub fn use_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![use]) }
     pub fn use_tree(&self) -> Option<UseTree> { support::child(&self.syntax) }
+    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
 }
-/// Use tree.
-///
-/// ```
-/// pub use ❰ foo::❰ * ❱ ❱;
-/// use ❰ bar as baz ❱;
-/// use ❰ bruh::bruuh::{ ❰ self ❱, ❰ blin ❱ } ❱;
-/// use ❰ { ❰ blin::blen ❱ } ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct UseTree {
     pub(crate) syntax: SyntaxNode,
 }
 impl UseTree {
     pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
+    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
     pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) }
     pub fn use_tree_list(&self) -> Option<UseTreeList> { support::child(&self.syntax) }
     pub fn alias(&self) -> Option<Alias> { support::child(&self.syntax) }
 }
-/// Item alias.
-/// Note: this is not the type alias.
-///
-/// ```
-/// use foo ❰ as bar ❱;
-/// use baz::{bruh ❰ as _ ❱};
-/// extern crate bruuh ❰ as blin ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Alias {
-    pub(crate) syntax: SyntaxNode,
-}
-impl ast::NameOwner for Alias {}
-impl Alias {
-    pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
-}
-/// Sublist of use trees.
-///
-/// ```
-/// use bruh::bruuh::❰ { ❰ self ❱, ❰ blin ❱ } ❱;
-/// use ❰ { blin::blen::❰ {} ❱ } ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct UseTreeList {
     pub(crate) syntax: SyntaxNode,
@@ -2306,14 +1155,14 @@ impl UseTreeList {
     pub fn use_trees(&self) -> AstChildren<UseTree> { support::children(&self.syntax) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
 }
-/// Extern crate item.
-///
-/// ```
-/// ❰ #[attr] pub extern crate foo; ❱
-/// ❰ extern crate self as bar; ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/extern-crates.html)
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Alias {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ast::NameOwner for Alias {}
+impl Alias {
+    pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ExternCrateItem {
     pub(crate) syntax: SyntaxNode,
@@ -2324,59 +1173,10 @@ impl ExternCrateItem {
     pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) }
     pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
+    pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
     pub fn alias(&self) -> Option<Alias> { support::child(&self.syntax) }
+    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
 }
-/// Call site arguments list.
-///
-/// ```
-/// foo::<T, U>❰ (42, true) ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/expressions/call-expr.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ArgList {
-    pub(crate) syntax: SyntaxNode,
-}
-impl ArgList {
-    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
-    pub fn args(&self) -> AstChildren<Expr> { support::children(&self.syntax) }
-    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
-}
-/// Path to a symbol. Includes single identifier names and elaborate paths with
-/// generic parameters.
-///
-/// ```
-/// (0..10).❰ ❰ collect ❱ ::<Vec<_>> ❱();
-/// ❰ ❰ ❰ Vec ❱ ::<u8> ❱ ::with_capacity ❱(1024);
-/// ❰ ❰ <❰ Foo ❱ as ❰ ❰ bar ❱ ::Bar ❱> ❱ ::baz ❱();
-/// ❰ ❰ <❰ bruh ❱> ❱ ::bruuh ❱();
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/paths.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Path {
-    pub(crate) syntax: SyntaxNode,
-}
-impl Path {
-    pub fn segment(&self) -> Option<PathSegment> { support::child(&self.syntax) }
-    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
-    pub fn qualifier(&self) -> Option<Path> { support::child(&self.syntax) }
-}
-/// Segment of the path to a symbol.
-/// Only path segment of an absolute path holds the `::` token,
-/// all other `::` tokens that connect path segments reside under `Path` itself.`
-///
-/// ```
-/// (0..10).❰ collect ❱ :: ❰ <Vec<_>> ❱();
-/// ❰ Vec ❱ :: ❰ <u8> ❱ :: ❰ with_capacity ❱(1024);
-/// ❰ <❰ Foo ❱ as ❰ bar ❱ :: ❰ Bar ❱> ❱ :: ❰ baz ❱();
-/// ❰ <❰ bruh ❱> ❱ :: ❰ bruuh ❱();
-///
-/// // Note that only in this case `::` token is inlcuded:
-/// ❰ ::foo ❱;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/paths.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PathSegment {
     pub(crate) syntax: SyntaxNode,
@@ -2394,50 +1194,22 @@ impl PathSegment {
     pub fn path_type(&self) -> Option<PathType> { support::child(&self.syntax) }
     pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
 }
-/// List of type arguments that are passed at generic instantiation site.
-///
-/// ```
-/// type _ = Foo ❰ ::<'a, u64, Item = Bar, 42, {true}> ❱::Bar;
-///
-/// Vec❰ ::<bool> ❱::();
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TypeArgList {
+pub struct TypeArg {
     pub(crate) syntax: SyntaxNode,
 }
-impl TypeArgList {
-    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
-    pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
-    pub fn generic_args(&self) -> AstChildren<GenericArg> { support::children(&self.syntax) }
-    pub fn type_args(&self) -> AstChildren<TypeArg> { support::children(&self.syntax) }
-    pub fn lifetime_args(&self) -> AstChildren<LifetimeArg> { support::children(&self.syntax) }
-    pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> { support::children(&self.syntax) }
-    pub fn const_args(&self) -> AstChildren<ConstArg> { support::children(&self.syntax) }
-    pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
+impl TypeArg {
+    pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Type argument that is passed at generic instantiation site.
-///
-/// ```
-/// type _ = Foo::<'a, ❰ u64 ❱, ❰ bool ❱, Item = Bar, 42>::Baz;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct TypeArg {
+pub struct LifetimeArg {
     pub(crate) syntax: SyntaxNode,
 }
-impl TypeArg {
-    pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
+impl LifetimeArg {
+    pub fn lifetime_token(&self) -> Option<SyntaxToken> {
+        support::token(&self.syntax, T![lifetime])
+    }
 }
-/// Associated type argument that is passed at generic instantiation site.
-/// ```
-/// type Foo = Bar::<'a, u64, bool, ❰ Item = Baz ❱, 42>::Bruh;
-///
-/// trait Bruh<T>: Iterator<❰ Item: Debug ❱> {}
-/// ```
-///
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct AssocTypeArg {
     pub(crate) syntax: SyntaxNode,
@@ -2448,33 +1220,6 @@ impl AssocTypeArg {
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
 }
-/// Lifetime argument that is passed at generic instantiation site.
-///
-/// ```
-/// fn foo<'a>(s: &'a str) {
-///     bar::<❰ 'a ❱>(s);
-/// }
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LifetimeArg {
-    pub(crate) syntax: SyntaxNode,
-}
-impl LifetimeArg {
-    pub fn lifetime_token(&self) -> Option<SyntaxToken> {
-        support::token(&self.syntax, T![lifetime])
-    }
-}
-/// Constant value argument that is passed at generic instantiation site.
-///
-/// ```
-/// foo::<u32, ❰ { true } ❱>();
-///
-/// bar::<❰ { 2 + 2} ❱>();
-/// ```
-///
-/// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md#declaring-a-const-parameter)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ConstArg {
     pub(crate) syntax: SyntaxNode,
@@ -2483,83 +1228,24 @@ impl ConstArg {
     pub fn literal(&self) -> Option<Literal> { support::child(&self.syntax) }
     pub fn block_expr(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
 }
-/// FIXME: (@edwin0cheng) Remove it to use ItemList instead
-/// https://github.com/rust-analyzer/rust-analyzer/pull/4083#discussion_r422666243
-///
-/// [Reference](https://doc.rust-lang.org/reference/macros.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MacroItems {
-    pub(crate) syntax: SyntaxNode,
-}
-impl ast::ModuleItemOwner for MacroItems {}
-impl MacroItems {}
-/// FIXME: (@edwin0cheng) add some documentation here. As per the writing
-/// of this comment this ast node is not used.
-///
-/// ```
-/// // FIXME: example here
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/macros.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MacroStmts {
+pub struct ExternBlock {
     pub(crate) syntax: SyntaxNode,
 }
-impl MacroStmts {
-    pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
-    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+impl ast::AttrsOwner for ExternBlock {}
+impl ExternBlock {
+    pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
+    pub fn extern_item_list(&self) -> Option<ExternItemList> { support::child(&self.syntax) }
 }
-/// List of items in an extern block.
-///
-/// ```
-/// extern "C" ❰
-///     {
-///         fn foo();
-///         static var: u32;
-///     }
-/// ❱
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ExternItemList {
     pub(crate) syntax: SyntaxNode,
 }
-impl ast::ModuleItemOwner for ExternItemList {}
 impl ExternItemList {
     pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
     pub fn extern_items(&self) -> AstChildren<ExternItem> { support::children(&self.syntax) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
 }
-/// Extern block.
-///
-/// ```
-/// ❰
-///     extern "C" {
-///         fn foo();
-///     }
-/// ❱
-///
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ExternBlock {
-    pub(crate) syntax: SyntaxNode,
-}
-impl ExternBlock {
-    pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
-    pub fn extern_item_list(&self) -> Option<ExternItemList> { support::child(&self.syntax) }
-}
-/// Meta item in an attribute.
-///
-/// ```
-/// #[❰ bar::baz = "42" ❱]
-/// #[❰ bruh(bruuh("true")) ❱]
-/// struct Foo;
-/// ```
-///
-/// [Reference](https://doc.rust-lang.org/reference/attributes.html?highlight=meta,item#meta-item-attribute-syntax)
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MetaItem {
     pub(crate) syntax: SyntaxNode,
@@ -2570,59 +1256,6 @@ impl MetaItem {
     pub fn attr_input(&self) -> Option<AttrInput> { support::child(&self.syntax) }
     pub fn nested_meta_items(&self) -> AstChildren<MetaItem> { support::children(&self.syntax) }
 }
-/// Macro 2.0 definition.
-/// Their syntax is still WIP by rustc team...
-/// ```
-/// ❰
-///     macro foo { }
-/// ❱
-/// ```
-///
-/// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/1584-macros.md)
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct MacroDef {
-    pub(crate) syntax: SyntaxNode,
-}
-impl MacroDef {
-    pub fn name(&self) -> Option<Name> { support::child(&self.syntax) }
-    pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
-}
-/// Any kind of nominal type definition.
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum NominalDef {
-    StructDef(StructDef),
-    EnumDef(EnumDef),
-    UnionDef(UnionDef),
-}
-impl ast::NameOwner for NominalDef {}
-impl ast::TypeParamsOwner for NominalDef {}
-impl ast::AttrsOwner for NominalDef {}
-/// Any kind of generic argument passed at instantiation site
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum GenericArg {
-    LifetimeArg(LifetimeArg),
-    TypeArg(TypeArg),
-    ConstArg(ConstArg),
-    AssocTypeArg(AssocTypeArg),
-}
-/// Any kind of construct valid in type context
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum TypeRef {
-    ParenType(ParenType),
-    TupleType(TupleType),
-    NeverType(NeverType),
-    PathType(PathType),
-    PointerType(PointerType),
-    ArrayType(ArrayType),
-    SliceType(SliceType),
-    ReferenceType(ReferenceType),
-    PlaceholderType(PlaceholderType),
-    FnPointerType(FnPointerType),
-    ForType(ForType),
-    ImplTraitType(ImplTraitType),
-    DynTraitType(DynTraitType),
-}
-/// Any kind of top-level item that may appear in a module
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum ModuleItem {
     StructDef(StructDef),
@@ -2640,32 +1273,28 @@ pub enum ModuleItem {
     MacroCall(MacroCall),
     ExternBlock(ExternBlock),
 }
-impl ast::NameOwner for ModuleItem {}
 impl ast::AttrsOwner for ModuleItem {}
-impl ast::VisibilityOwner for ModuleItem {}
-/// Any kind of item that may appear in an impl block
-///
-/// // FIXME: impl blocks can also contain MacroCall
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum AssocItem {
-    FnDef(FnDef),
-    TypeAliasDef(TypeAliasDef),
-    ConstDef(ConstDef),
+pub enum TypeRef {
+    ParenType(ParenType),
+    TupleType(TupleType),
+    NeverType(NeverType),
+    PathType(PathType),
+    PointerType(PointerType),
+    ArrayType(ArrayType),
+    SliceType(SliceType),
+    ReferenceType(ReferenceType),
+    PlaceholderType(PlaceholderType),
+    FnPointerType(FnPointerType),
+    ForType(ForType),
+    ImplTraitType(ImplTraitType),
+    DynTraitType(DynTraitType),
 }
-impl ast::NameOwner for AssocItem {}
-impl ast::AttrsOwner for AssocItem {}
-/// Any kind of item that may appear in an extern block
-///
-/// // FIXME: extern blocks can also contain MacroCall
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum ExternItem {
-    FnDef(FnDef),
-    StaticDef(StaticDef),
+pub enum FieldDefList {
+    RecordFieldDefList(RecordFieldDefList),
+    TupleFieldDefList(TupleFieldDefList),
 }
-impl ast::NameOwner for ExternItem {}
-impl ast::AttrsOwner for ExternItem {}
-impl ast::VisibilityOwner for ExternItem {}
-/// Any kind of expression
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Expr {
     TupleExpr(TupleExpr),
@@ -2700,8 +1329,15 @@ pub enum Expr {
     MacroCall(MacroCall),
     BoxExpr(BoxExpr),
 }
-impl ast::AttrsOwner for Expr {}
-/// Any kind of pattern
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum AssocItem {
+    FnDef(FnDef),
+    TypeAliasDef(TypeAliasDef),
+    ConstDef(ConstDef),
+}
+impl ast::AttrsOwner for AssocItem {}
+impl ast::NameOwner for AssocItem {}
+impl ast::VisibilityOwner for AssocItem {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Pat {
     OrPat(OrPat),
@@ -2720,26 +1356,35 @@ pub enum Pat {
     LiteralPat(LiteralPat),
     MacroPat(MacroPat),
 }
-/// Any kind of input to an attribute
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum Stmt {
+    LetStmt(LetStmt),
+    ExprStmt(ExprStmt),
+}
+impl ast::AttrsOwner for Stmt {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum AttrInput {
     Literal(Literal),
     TokenTree(TokenTree),
 }
-/// Any kind of statement
-/// Note: there are no empty statements, these are just represented as
-/// bare semicolons without a dedicated statement ast node.
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum Stmt {
-    LetStmt(LetStmt),
-    ExprStmt(ExprStmt),
+pub enum ExternItem {
+    FnDef(FnDef),
+    StaticDef(StaticDef),
 }
-/// Any kind of fields list (record or tuple field lists)
+impl ast::AttrsOwner for ExternItem {}
+impl ast::NameOwner for ExternItem {}
+impl ast::VisibilityOwner for ExternItem {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub enum FieldDefList {
-    RecordFieldDefList(RecordFieldDefList),
-    TupleFieldDefList(TupleFieldDefList),
+pub enum NominalDef {
+    StructDef(StructDef),
+    EnumDef(EnumDef),
+    UnionDef(UnionDef),
 }
+impl ast::AttrsOwner for NominalDef {}
+impl ast::NameOwner for NominalDef {}
+impl ast::TypeParamsOwner for NominalDef {}
+impl ast::VisibilityOwner for NominalDef {}
 impl AstNode for SourceFile {
     fn can_cast(kind: SyntaxKind) -> bool { kind == SOURCE_FILE }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2751,6 +1396,17 @@ impl AstNode for SourceFile {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for Attr {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ATTR }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for FnDef {
     fn can_cast(kind: SyntaxKind) -> bool { kind == FN_DEF }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2762,6 +1418,61 @@ impl AstNode for FnDef {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for Visibility {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == VISIBILITY }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for Abi {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ABI }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for Name {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == NAME }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for TypeParamList {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_PARAM_LIST }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for ParamList {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == PARAM_LIST }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for RetType {
     fn can_cast(kind: SyntaxKind) -> bool { kind == RET_TYPE }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2773,8 +1484,8 @@ impl AstNode for RetType {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for StructDef {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == STRUCT_DEF }
+impl AstNode for WhereClause {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == WHERE_CLAUSE }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -2784,8 +1495,8 @@ impl AstNode for StructDef {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for UnionDef {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == UNION_DEF }
+impl AstNode for BlockExpr {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == BLOCK_EXPR }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -2795,8 +1506,8 @@ impl AstNode for UnionDef {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for RecordFieldDefList {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD_DEF_LIST }
+impl AstNode for StructDef {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == STRUCT_DEF }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -2806,8 +1517,8 @@ impl AstNode for RecordFieldDefList {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for RecordFieldDef {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD_DEF }
+impl AstNode for RecordFieldDefList {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD_DEF_LIST }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -2828,6 +1539,28 @@ impl AstNode for TupleFieldDefList {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for UnionDef {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == UNION_DEF }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for RecordFieldDef {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD_DEF }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for TupleFieldDef {
     fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_FIELD_DEF }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2883,8 +1616,8 @@ impl AstNode for TraitDef {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for Module {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE }
+impl AstNode for TypeBoundList {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND_LIST }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -2905,6 +1638,17 @@ impl AstNode for ItemList {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for Module {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for ConstDef {
     fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_DEF }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -2993,6 +1737,17 @@ impl AstNode for PathType {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for Path {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == PATH }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for PointerType {
     fn can_cast(kind: SyntaxKind) -> bool { kind == POINTER_TYPE }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3158,8 +1913,8 @@ impl AstNode for IfExpr {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for LoopExpr {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == LOOP_EXPR }
+impl AstNode for Condition {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == CONDITION }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3180,6 +1935,28 @@ impl AstNode for EffectExpr {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for Label {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == LABEL }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for LoopExpr {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == LOOP_EXPR }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for ForExpr {
     fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_EXPR }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3224,8 +2001,8 @@ impl AstNode for BreakExpr {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for Label {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == LABEL }
+impl AstNode for ReturnExpr {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == RETURN_EXPR }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3235,8 +2012,8 @@ impl AstNode for Label {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for BlockExpr {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == BLOCK_EXPR }
+impl AstNode for CallExpr {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == CALL_EXPR }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3246,8 +2023,8 @@ impl AstNode for BlockExpr {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for ReturnExpr {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == RETURN_EXPR }
+impl AstNode for ArgList {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ARG_LIST }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3257,8 +2034,8 @@ impl AstNode for ReturnExpr {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for CallExpr {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == CALL_EXPR }
+impl AstNode for MethodCallExpr {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == METHOD_CALL_EXPR }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3268,8 +2045,8 @@ impl AstNode for CallExpr {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for MethodCallExpr {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == METHOD_CALL_EXPR }
+impl AstNode for NameRef {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == NAME_REF }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3279,8 +2056,8 @@ impl AstNode for MethodCallExpr {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for IndexExpr {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == INDEX_EXPR }
+impl AstNode for TypeArgList {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ARG_LIST }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3301,6 +2078,17 @@ impl AstNode for FieldExpr {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for IndexExpr {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == INDEX_EXPR }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for AwaitExpr {
     fn can_cast(kind: SyntaxKind) -> bool { kind == AWAIT_EXPR }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3609,6 +2397,17 @@ impl AstNode for MacroPat {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for MacroCall {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_CALL }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for RecordPat {
     fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_PAT }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3664,41 +2463,8 @@ impl AstNode for TuplePat {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for Visibility {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == VISIBILITY }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
-impl AstNode for Name {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == NAME }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
-impl AstNode for NameRef {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == NAME_REF }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
-impl AstNode for MacroCall {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_CALL }
+impl AstNode for TokenTree {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == TOKEN_TREE }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3708,8 +2474,8 @@ impl AstNode for MacroCall {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for Attr {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == ATTR }
+impl AstNode for MacroDef {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_DEF }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3719,8 +2485,8 @@ impl AstNode for Attr {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for TokenTree {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == TOKEN_TREE }
+impl AstNode for MacroItems {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_ITEMS }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3730,8 +2496,8 @@ impl AstNode for TokenTree {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for TypeParamList {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_PARAM_LIST }
+impl AstNode for MacroStmts {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_STMTS }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3752,17 +2518,6 @@ impl AstNode for TypeParam {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for ConstParam {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_PARAM }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
 impl AstNode for LifetimeParam {
     fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME_PARAM }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3774,8 +2529,8 @@ impl AstNode for LifetimeParam {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for TypeBound {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND }
+impl AstNode for ConstParam {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_PARAM }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3785,8 +2540,8 @@ impl AstNode for TypeBound {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for TypeBoundList {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND_LIST }
+impl AstNode for TypeBound {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3807,28 +2562,6 @@ impl AstNode for WherePred {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for WhereClause {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == WHERE_CLAUSE }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
-impl AstNode for Abi {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == ABI }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
 impl AstNode for ExprStmt {
     fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_STMT }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3851,28 +2584,6 @@ impl AstNode for LetStmt {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for Condition {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == CONDITION }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
-impl AstNode for ParamList {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == PARAM_LIST }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
 impl AstNode for SelfParam {
     fn can_cast(kind: SyntaxKind) -> bool { kind == SELF_PARAM }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3917,17 +2628,6 @@ impl AstNode for UseTree {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for Alias {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == ALIAS }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
 impl AstNode for UseTreeList {
     fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE_LIST }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3939,19 +2639,8 @@ impl AstNode for UseTreeList {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for ExternCrateItem {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == EXTERN_CRATE_ITEM }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
-impl AstNode for ArgList {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == ARG_LIST }
+impl AstNode for Alias {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ALIAS }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3961,8 +2650,8 @@ impl AstNode for ArgList {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for Path {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == PATH }
+impl AstNode for ExternCrateItem {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == EXTERN_CRATE_ITEM }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -3983,17 +2672,6 @@ impl AstNode for PathSegment {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for TypeArgList {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ARG_LIST }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
 impl AstNode for TypeArg {
     fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ARG }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -4005,17 +2683,6 @@ impl AstNode for TypeArg {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for AssocTypeArg {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_TYPE_ARG }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
 impl AstNode for LifetimeArg {
     fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME_ARG }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -4027,8 +2694,8 @@ impl AstNode for LifetimeArg {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for ConstArg {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_ARG }
+impl AstNode for AssocTypeArg {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_TYPE_ARG }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -4038,8 +2705,8 @@ impl AstNode for ConstArg {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for MacroItems {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_ITEMS }
+impl AstNode for ConstArg {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_ARG }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -4049,8 +2716,8 @@ impl AstNode for MacroItems {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for MacroStmts {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_STMTS }
+impl AstNode for ExternBlock {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == EXTERN_BLOCK }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -4071,17 +2738,6 @@ impl AstNode for ExternItemList {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for ExternBlock {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == EXTERN_BLOCK }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
 impl AstNode for MetaItem {
     fn can_cast(kind: SyntaxKind) -> bool { kind == META_ITEM }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -4093,85 +2749,93 @@ impl AstNode for MetaItem {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl AstNode for MacroDef {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_DEF }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+impl From<StructDef> for ModuleItem {
+    fn from(node: StructDef) -> ModuleItem { ModuleItem::StructDef(node) }
 }
-impl From<StructDef> for NominalDef {
-    fn from(node: StructDef) -> NominalDef { NominalDef::StructDef(node) }
+impl From<UnionDef> for ModuleItem {
+    fn from(node: UnionDef) -> ModuleItem { ModuleItem::UnionDef(node) }
 }
-impl From<EnumDef> for NominalDef {
-    fn from(node: EnumDef) -> NominalDef { NominalDef::EnumDef(node) }
+impl From<EnumDef> for ModuleItem {
+    fn from(node: EnumDef) -> ModuleItem { ModuleItem::EnumDef(node) }
 }
-impl From<UnionDef> for NominalDef {
-    fn from(node: UnionDef) -> NominalDef { NominalDef::UnionDef(node) }
+impl From<FnDef> for ModuleItem {
+    fn from(node: FnDef) -> ModuleItem { ModuleItem::FnDef(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 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<ImplDef> for ModuleItem {
+    fn from(node: ImplDef) -> ModuleItem { ModuleItem::ImplDef(node) }
 }
-impl From<LifetimeArg> for GenericArg {
-    fn from(node: LifetimeArg) -> GenericArg { GenericArg::LifetimeArg(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<TypeArg> for GenericArg {
-    fn from(node: TypeArg) -> GenericArg { GenericArg::TypeArg(node) }
+impl From<ConstDef> for ModuleItem {
+    fn from(node: ConstDef) -> ModuleItem { ModuleItem::ConstDef(node) }
 }
-impl From<ConstArg> for GenericArg {
-    fn from(node: ConstArg) -> GenericArg { GenericArg::ConstArg(node) }
+impl From<StaticDef> for ModuleItem {
+    fn from(node: StaticDef) -> ModuleItem { ModuleItem::StaticDef(node) }
 }
-impl From<AssocTypeArg> for GenericArg {
-    fn from(node: AssocTypeArg) -> GenericArg { GenericArg::AssocTypeArg(node) }
+impl From<Module> for ModuleItem {
+    fn from(node: Module) -> ModuleItem { ModuleItem::Module(node) }
 }
-impl AstNode for GenericArg {
+impl From<MacroCall> for ModuleItem {
+    fn from(node: MacroCall) -> ModuleItem { ModuleItem::MacroCall(node) }
+}
+impl From<ExternBlock> for ModuleItem {
+    fn from(node: ExternBlock) -> ModuleItem { ModuleItem::ExternBlock(node) }
+}
+impl AstNode for ModuleItem {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LIFETIME_ARG | TYPE_ARG | CONST_ARG | ASSOC_TYPE_ARG => true,
+            STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_DEF
+            | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE | MACRO_CALL
+            | EXTERN_BLOCK => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
-            LIFETIME_ARG => GenericArg::LifetimeArg(LifetimeArg { syntax }),
-            TYPE_ARG => GenericArg::TypeArg(TypeArg { syntax }),
-            CONST_ARG => GenericArg::ConstArg(ConstArg { syntax }),
-            ASSOC_TYPE_ARG => GenericArg::AssocTypeArg(AssocTypeArg { syntax }),
+            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_DEF => ModuleItem::ImplDef(ImplDef { 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 }),
+            MACRO_CALL => ModuleItem::MacroCall(MacroCall { syntax }),
+            EXTERN_BLOCK => ModuleItem::ExternBlock(ExternBlock { syntax }),
             _ => return None,
         };
         Some(res)
     }
     fn syntax(&self) -> &SyntaxNode {
         match self {
-            GenericArg::LifetimeArg(it) => &it.syntax,
-            GenericArg::TypeArg(it) => &it.syntax,
-            GenericArg::ConstArg(it) => &it.syntax,
-            GenericArg::AssocTypeArg(it) => &it.syntax,
+            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::ImplDef(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,
+            ModuleItem::MacroCall(it) => &it.syntax,
+            ModuleItem::ExternBlock(it) => &it.syntax,
         }
     }
 }
@@ -4260,154 +2924,33 @@ impl AstNode for TypeRef {
         }
     }
 }
-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<ImplDef> for ModuleItem {
-    fn from(node: ImplDef) -> ModuleItem { ModuleItem::ImplDef(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 From<MacroCall> for ModuleItem {
-    fn from(node: MacroCall) -> ModuleItem { ModuleItem::MacroCall(node) }
-}
-impl From<ExternBlock> for ModuleItem {
-    fn from(node: ExternBlock) -> ModuleItem { ModuleItem::ExternBlock(node) }
-}
-impl AstNode for ModuleItem {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            STRUCT_DEF | UNION_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_DEF
-            | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE | MACRO_CALL
-            | EXTERN_BLOCK => 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_DEF => ModuleItem::ImplDef(ImplDef { 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 }),
-            MACRO_CALL => ModuleItem::MacroCall(MacroCall { syntax }),
-            EXTERN_BLOCK => ModuleItem::ExternBlock(ExternBlock { syntax }),
-            _ => return None,
-        };
-        Some(res)
-    }
-    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::ImplDef(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,
-            ModuleItem::MacroCall(it) => &it.syntax,
-            ModuleItem::ExternBlock(it) => &it.syntax,
-        }
-    }
-}
-impl From<FnDef> for AssocItem {
-    fn from(node: FnDef) -> AssocItem { AssocItem::FnDef(node) }
-}
-impl From<TypeAliasDef> for AssocItem {
-    fn from(node: TypeAliasDef) -> AssocItem { AssocItem::TypeAliasDef(node) }
-}
-impl From<ConstDef> for AssocItem {
-    fn from(node: ConstDef) -> AssocItem { AssocItem::ConstDef(node) }
-}
-impl AstNode for AssocItem {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            FN_DEF | TYPE_ALIAS_DEF | CONST_DEF => true,
-            _ => false,
-        }
-    }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        let res = match syntax.kind() {
-            FN_DEF => AssocItem::FnDef(FnDef { syntax }),
-            TYPE_ALIAS_DEF => AssocItem::TypeAliasDef(TypeAliasDef { syntax }),
-            CONST_DEF => AssocItem::ConstDef(ConstDef { syntax }),
-            _ => return None,
-        };
-        Some(res)
-    }
-    fn syntax(&self) -> &SyntaxNode {
-        match self {
-            AssocItem::FnDef(it) => &it.syntax,
-            AssocItem::TypeAliasDef(it) => &it.syntax,
-            AssocItem::ConstDef(it) => &it.syntax,
-        }
-    }
-}
-impl From<FnDef> for ExternItem {
-    fn from(node: FnDef) -> ExternItem { ExternItem::FnDef(node) }
+impl From<RecordFieldDefList> for FieldDefList {
+    fn from(node: RecordFieldDefList) -> FieldDefList { FieldDefList::RecordFieldDefList(node) }
 }
-impl From<StaticDef> for ExternItem {
-    fn from(node: StaticDef) -> ExternItem { ExternItem::StaticDef(node) }
+impl From<TupleFieldDefList> for FieldDefList {
+    fn from(node: TupleFieldDefList) -> FieldDefList { FieldDefList::TupleFieldDefList(node) }
 }
-impl AstNode for ExternItem {
+impl AstNode for FieldDefList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            FN_DEF | STATIC_DEF => true,
+            RECORD_FIELD_DEF_LIST | TUPLE_FIELD_DEF_LIST => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
-            FN_DEF => ExternItem::FnDef(FnDef { syntax }),
-            STATIC_DEF => ExternItem::StaticDef(StaticDef { syntax }),
+            RECORD_FIELD_DEF_LIST => {
+                FieldDefList::RecordFieldDefList(RecordFieldDefList { syntax })
+            }
+            TUPLE_FIELD_DEF_LIST => FieldDefList::TupleFieldDefList(TupleFieldDefList { syntax }),
             _ => return None,
         };
         Some(res)
     }
     fn syntax(&self) -> &SyntaxNode {
         match self {
-            ExternItem::FnDef(it) => &it.syntax,
-            ExternItem::StaticDef(it) => &it.syntax,
+            FieldDefList::RecordFieldDefList(it) => &it.syntax,
+            FieldDefList::TupleFieldDefList(it) => &it.syntax,
         }
     }
 }
@@ -4590,6 +3133,39 @@ impl AstNode for Expr {
         }
     }
 }
+impl From<FnDef> for AssocItem {
+    fn from(node: FnDef) -> AssocItem { AssocItem::FnDef(node) }
+}
+impl From<TypeAliasDef> for AssocItem {
+    fn from(node: TypeAliasDef) -> AssocItem { AssocItem::TypeAliasDef(node) }
+}
+impl From<ConstDef> for AssocItem {
+    fn from(node: ConstDef) -> AssocItem { AssocItem::ConstDef(node) }
+}
+impl AstNode for AssocItem {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            FN_DEF | TYPE_ALIAS_DEF | CONST_DEF => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        let res = match syntax.kind() {
+            FN_DEF => AssocItem::FnDef(FnDef { syntax }),
+            TYPE_ALIAS_DEF => AssocItem::TypeAliasDef(TypeAliasDef { syntax }),
+            CONST_DEF => AssocItem::ConstDef(ConstDef { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            AssocItem::FnDef(it) => &it.syntax,
+            AssocItem::TypeAliasDef(it) => &it.syntax,
+            AssocItem::ConstDef(it) => &it.syntax,
+        }
+    }
+}
 impl From<OrPat> for Pat {
     fn from(node: OrPat) -> Pat { Pat::OrPat(node) }
 }
@@ -4685,6 +3261,34 @@ impl AstNode for Pat {
         }
     }
 }
+impl From<LetStmt> for Stmt {
+    fn from(node: LetStmt) -> Stmt { Stmt::LetStmt(node) }
+}
+impl From<ExprStmt> for Stmt {
+    fn from(node: ExprStmt) -> Stmt { Stmt::ExprStmt(node) }
+}
+impl AstNode for Stmt {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            LET_STMT | EXPR_STMT => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        let res = match syntax.kind() {
+            LET_STMT => Stmt::LetStmt(LetStmt { syntax }),
+            EXPR_STMT => Stmt::ExprStmt(ExprStmt { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            Stmt::LetStmt(it) => &it.syntax,
+            Stmt::ExprStmt(it) => &it.syntax,
+        }
+    }
+}
 impl From<Literal> for AttrInput {
     fn from(node: Literal) -> AttrInput { AttrInput::Literal(node) }
 }
@@ -4713,80 +3317,83 @@ impl AstNode for AttrInput {
         }
     }
 }
-impl From<LetStmt> for Stmt {
-    fn from(node: LetStmt) -> Stmt { Stmt::LetStmt(node) }
+impl From<FnDef> for ExternItem {
+    fn from(node: FnDef) -> ExternItem { ExternItem::FnDef(node) }
 }
-impl From<ExprStmt> for Stmt {
-    fn from(node: ExprStmt) -> Stmt { Stmt::ExprStmt(node) }
+impl From<StaticDef> for ExternItem {
+    fn from(node: StaticDef) -> ExternItem { ExternItem::StaticDef(node) }
 }
-impl AstNode for Stmt {
+impl AstNode for ExternItem {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            LET_STMT | EXPR_STMT => true,
+            FN_DEF | STATIC_DEF => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
-            LET_STMT => Stmt::LetStmt(LetStmt { syntax }),
-            EXPR_STMT => Stmt::ExprStmt(ExprStmt { syntax }),
+            FN_DEF => ExternItem::FnDef(FnDef { syntax }),
+            STATIC_DEF => ExternItem::StaticDef(StaticDef { syntax }),
             _ => return None,
         };
         Some(res)
     }
     fn syntax(&self) -> &SyntaxNode {
         match self {
-            Stmt::LetStmt(it) => &it.syntax,
-            Stmt::ExprStmt(it) => &it.syntax,
+            ExternItem::FnDef(it) => &it.syntax,
+            ExternItem::StaticDef(it) => &it.syntax,
         }
     }
 }
-impl From<RecordFieldDefList> for FieldDefList {
-    fn from(node: RecordFieldDefList) -> FieldDefList { FieldDefList::RecordFieldDefList(node) }
+impl From<StructDef> for NominalDef {
+    fn from(node: StructDef) -> NominalDef { NominalDef::StructDef(node) }
 }
-impl From<TupleFieldDefList> for FieldDefList {
-    fn from(node: TupleFieldDefList) -> FieldDefList { FieldDefList::TupleFieldDefList(node) }
+impl From<EnumDef> for NominalDef {
+    fn from(node: EnumDef) -> NominalDef { NominalDef::EnumDef(node) }
 }
-impl AstNode for FieldDefList {
+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 {
-            RECORD_FIELD_DEF_LIST | TUPLE_FIELD_DEF_LIST => true,
+            STRUCT_DEF | ENUM_DEF | UNION_DEF => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
-            RECORD_FIELD_DEF_LIST => {
-                FieldDefList::RecordFieldDefList(RecordFieldDefList { syntax })
-            }
-            TUPLE_FIELD_DEF_LIST => FieldDefList::TupleFieldDefList(TupleFieldDefList { syntax }),
+            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 {
-            FieldDefList::RecordFieldDefList(it) => &it.syntax,
-            FieldDefList::TupleFieldDefList(it) => &it.syntax,
+            NominalDef::StructDef(it) => &it.syntax,
+            NominalDef::EnumDef(it) => &it.syntax,
+            NominalDef::UnionDef(it) => &it.syntax,
         }
     }
 }
-impl std::fmt::Display for NominalDef {
+impl std::fmt::Display for ModuleItem {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for GenericArg {
+impl std::fmt::Display for TypeRef {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for TypeRef {
+impl std::fmt::Display for FieldDefList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for ModuleItem {
+impl std::fmt::Display for Expr {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -4796,37 +3403,37 @@ impl std::fmt::Display for AssocItem {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for ExternItem {
+impl std::fmt::Display for Pat {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Expr {
+impl std::fmt::Display for Stmt {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Pat {
+impl std::fmt::Display for AttrInput {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for AttrInput {
+impl std::fmt::Display for ExternItem {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Stmt {
+impl std::fmt::Display for NominalDef {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for FieldDefList {
+impl std::fmt::Display for SourceFile {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for SourceFile {
+impl std::fmt::Display for Attr {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -4836,27 +3443,52 @@ impl std::fmt::Display for FnDef {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for Visibility {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for Abi {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for Name {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for TypeParamList {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for ParamList {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for RetType {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for StructDef {
+impl std::fmt::Display for WhereClause {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for UnionDef {
+impl std::fmt::Display for BlockExpr {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for RecordFieldDefList {
+impl std::fmt::Display for StructDef {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for RecordFieldDef {
+impl std::fmt::Display for RecordFieldDefList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -4866,6 +3498,16 @@ impl std::fmt::Display for TupleFieldDefList {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for UnionDef {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for RecordFieldDef {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for TupleFieldDef {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -4891,7 +3533,7 @@ impl std::fmt::Display for TraitDef {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Module {
+impl std::fmt::Display for TypeBoundList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -4901,6 +3543,11 @@ impl std::fmt::Display for ItemList {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for Module {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for ConstDef {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -4941,6 +3588,11 @@ impl std::fmt::Display for PathType {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for Path {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for PointerType {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -5016,7 +3668,7 @@ impl std::fmt::Display for IfExpr {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for LoopExpr {
+impl std::fmt::Display for Condition {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -5026,6 +3678,16 @@ impl std::fmt::Display for EffectExpr {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for Label {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for LoopExpr {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for ForExpr {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -5046,32 +3708,32 @@ impl std::fmt::Display for BreakExpr {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Label {
+impl std::fmt::Display for ReturnExpr {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for BlockExpr {
+impl std::fmt::Display for CallExpr {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for ReturnExpr {
+impl std::fmt::Display for ArgList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for CallExpr {
+impl std::fmt::Display for MethodCallExpr {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for MethodCallExpr {
+impl std::fmt::Display for NameRef {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for IndexExpr {
+impl std::fmt::Display for TypeArgList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -5081,6 +3743,11 @@ impl std::fmt::Display for FieldExpr {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for IndexExpr {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for AwaitExpr {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -5221,6 +3888,11 @@ impl std::fmt::Display for MacroPat {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for MacroCall {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for RecordPat {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -5246,37 +3918,22 @@ impl std::fmt::Display for TuplePat {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Visibility {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for Name {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for NameRef {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for MacroCall {
+impl std::fmt::Display for TokenTree {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Attr {
+impl std::fmt::Display for MacroDef {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for TokenTree {
+impl std::fmt::Display for MacroItems {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for TypeParamList {
+impl std::fmt::Display for MacroStmts {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -5286,22 +3943,17 @@ impl std::fmt::Display for TypeParam {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for ConstParam {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
 impl std::fmt::Display for LifetimeParam {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for TypeBound {
+impl std::fmt::Display for ConstParam {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for TypeBoundList {
+impl std::fmt::Display for TypeBound {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -5311,16 +3963,6 @@ impl std::fmt::Display for WherePred {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for WhereClause {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for Abi {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
 impl std::fmt::Display for ExprStmt {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -5331,16 +3973,6 @@ impl std::fmt::Display for LetStmt {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Condition {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for ParamList {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
 impl std::fmt::Display for SelfParam {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -5361,27 +3993,17 @@ impl std::fmt::Display for UseTree {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Alias {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
 impl std::fmt::Display for UseTreeList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for ExternCrateItem {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for ArgList {
+impl std::fmt::Display for Alias {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Path {
+impl std::fmt::Display for ExternCrateItem {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -5391,37 +4013,27 @@ impl std::fmt::Display for PathSegment {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for TypeArgList {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
 impl std::fmt::Display for TypeArg {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for AssocTypeArg {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
 impl std::fmt::Display for LifetimeArg {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for ConstArg {
+impl std::fmt::Display for AssocTypeArg {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for MacroItems {
+impl std::fmt::Display for ConstArg {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for MacroStmts {
+impl std::fmt::Display for ExternBlock {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -5431,18 +4043,8 @@ impl std::fmt::Display for ExternItemList {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for ExternBlock {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
 impl std::fmt::Display for MetaItem {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for MacroDef {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
diff --git a/crates/ra_syntax/src/ast/node_ext.rs b/crates/ra_syntax/src/ast/node_ext.rs
index 662c6f73ee2..242900643af 100644
--- a/crates/ra_syntax/src/ast/node_ext.rs
+++ b/crates/ra_syntax/src/ast/node_ext.rs
@@ -472,3 +472,19 @@ impl ast::TokenTree {
             .filter(|it| matches!(it.kind(), T!['}'] | T![')'] | T![']']))
     }
 }
+
+impl ast::DocCommentsOwner for ast::SourceFile {}
+impl ast::DocCommentsOwner for ast::FnDef {}
+impl ast::DocCommentsOwner for ast::StructDef {}
+impl ast::DocCommentsOwner for ast::UnionDef {}
+impl ast::DocCommentsOwner for ast::RecordFieldDef {}
+impl ast::DocCommentsOwner for ast::TupleFieldDef {}
+impl ast::DocCommentsOwner for ast::EnumDef {}
+impl ast::DocCommentsOwner for ast::EnumVariant {}
+impl ast::DocCommentsOwner for ast::TraitDef {}
+impl ast::DocCommentsOwner for ast::Module {}
+impl ast::DocCommentsOwner for ast::StaticDef {}
+impl ast::DocCommentsOwner for ast::ConstDef {}
+impl ast::DocCommentsOwner for ast::TypeAliasDef {}
+impl ast::DocCommentsOwner for ast::ImplDef {}
+impl ast::DocCommentsOwner for ast::MacroCall {}
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index d1cfb590902..8140da87f9e 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -10,9 +10,10 @@ license = "MIT OR Apache-2.0"
 doctest = false
 
 [dependencies]
-walkdir = "2.3.1"
-pico-args = "0.3.1"
-quote = "1.0.2"
-proc-macro2 = "1.0.8"
 anyhow = "1.0.26"
 flate2 = "1.0"
+pico-args = "0.3.1"
+proc-macro2 = "1.0.8"
+quote = "1.0.2"
+ungrammar = "0.1.0"
+walkdir = "2.3.1"
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index a6a4d7c3552..83449437bb2 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -223,12 +223,14 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
     ],
 };
 
+#[derive(Default, Debug)]
 pub(crate) struct AstSrc {
     pub(crate) tokens: Vec<String>,
     pub(crate) nodes: Vec<AstNodeSrc>,
     pub(crate) enums: Vec<AstEnumSrc>,
 }
 
+#[derive(Debug)]
 pub(crate) struct AstNodeSrc {
     pub(crate) doc: Vec<String>,
     pub(crate) name: String,
@@ -236,1999 +238,23 @@ pub(crate) struct AstNodeSrc {
     pub(crate) fields: Vec<Field>,
 }
 
+#[derive(Debug, Eq, PartialEq)]
 pub(crate) enum Field {
     Token(String),
     Node { name: String, src: FieldSrc },
 }
 
+#[derive(Debug, Eq, PartialEq)]
 pub(crate) enum FieldSrc {
     Shorthand,
     Optional(String),
     Many(String),
 }
 
+#[derive(Debug)]
 pub(crate) struct AstEnumSrc {
     pub(crate) doc: Vec<String>,
     pub(crate) name: String,
     pub(crate) traits: Vec<String>,
     pub(crate) variants: Vec<String>,
 }
-
-macro_rules! ast_nodes {
-    ($(
-        $(#[doc = $doc:expr])+
-        struct $name:ident$(: $($trait:ident),*)? {
-            $($field_name:ident $(![$token:tt])? $(: $ty:tt)?),*$(,)?
-        }
-    )*) => {
-        vec![$(
-            AstNodeSrc {
-                doc: vec![$($doc.to_string()),*],
-                name: stringify!($name).to_string(),
-                traits: vec![$($(stringify!($trait).to_string()),*)?],
-                fields: vec![
-                    $(field!($(T![$token])? $field_name $($ty)?)),*
-                ],
-
-            }
-        ),*]
-    };
-}
-
-macro_rules! field {
-    (T![$token:tt] T) => {
-        Field::Token(stringify!($token).to_string())
-    };
-    ($field_name:ident) => {
-        Field::Node { name: stringify!($field_name).to_string(), src: FieldSrc::Shorthand }
-    };
-    ($field_name:ident [$ty:ident]) => {
-        Field::Node {
-            name: stringify!($field_name).to_string(),
-            src: FieldSrc::Many(stringify!($ty).to_string()),
-        }
-    };
-    ($field_name:ident $ty:ident) => {
-        Field::Node {
-            name: stringify!($field_name).to_string(),
-            src: FieldSrc::Optional(stringify!($ty).to_string()),
-        }
-    };
-}
-
-macro_rules! ast_enums {
-    ($(
-        $(#[doc = $doc:expr])+
-        enum $name:ident $(: $($trait:ident),*)? {
-            $($variant:ident),*$(,)?
-        }
-    )*) => {
-        vec![$(
-            AstEnumSrc {
-                doc: vec![$($doc.to_string()),*],
-                name: stringify!($name).to_string(),
-                traits: vec![$($(stringify!($trait).to_string()),*)?],
-                variants: vec![$(stringify!($variant).to_string()),*],
-            }
-        ),*]
-    };
-}
-
-pub(crate) fn rust_ast() -> AstSrc {
-    AstSrc {
-        tokens: vec!["Whitespace".into(), "Comment".into(), "String".into(), "RawString".into()],
-        nodes: ast_nodes! {
-            /// The entire Rust source file. Includes all top-level inner attributes and module items.
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/crates-and-source-files.html)
-            struct SourceFile: ModuleItemOwner, AttrsOwner, DocCommentsOwner {
-            }
-
-            /// Function definition either with body or not.
-            /// Includes all of its attributes and doc comments.
-            ///
-            /// ```
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     pub extern "C" fn foo<T>(#[attr] Patern {p}: Pattern) -> u32
-            ///     where
-            ///         T: Debug
-            ///     {
-            ///         42
-            ///     }
-            /// ❱
-            ///
-            /// extern "C" {
-            ///     ❰ fn fn_decl(also_variadic_ffi: u32, ...) -> u32; ❱
-            /// }
-            /// ```
-            ///
-            /// - [Reference](https://doc.rust-lang.org/reference/items/functions.html)
-            /// - [Nomicon](https://doc.rust-lang.org/nomicon/ffi.html#variadic-functions)
-            struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner {
-                Abi,
-                T![const],
-                T![default],
-                T![async],
-                T![unsafe],
-                T![fn],
-                ParamList,
-                RetType,
-                body: BlockExpr,
-                T![;]
-            }
-
-            /// Return type annotation.
-            ///
-            /// ```
-            /// fn foo(a: u32) ❰ -> Option<u32> ❱ { Some(a) }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
-            struct RetType { T![->], TypeRef }
-
-            /// Struct definition.
-            /// Includes all of its attributes and doc comments.
-            ///
-            /// ```
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     struct Foo<T> where T: Debug {
-            ///         /// Docs
-            ///         #[attr]
-            ///         pub a: u32,
-            ///         b: T,
-            ///     }
-            /// ❱
-            ///
-            /// ❰ struct Foo; ❱
-            /// ❰ struct Foo<T>(#[attr] T) where T: Debug; ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
-            struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
-                T![struct],
-                FieldDefList,
-                T![;]
-            }
-
-            /// Union definition.
-            /// Includes all of its attributes and doc comments.
-            ///
-            /// ```
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     pub union Foo<T> where T: Debug {
-            ///         /// Docs
-            ///         #[attr]
-            ///         a: T,
-            ///         b: u32,
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/unions.html)
-            struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
-                T![union],
-                RecordFieldDefList,
-            }
-
-            /// Record field definition list including enclosing curly braces.
-            ///
-            /// ```
-            /// struct Foo // same for union
-            /// ❰
-            ///     {
-            ///         a: u32,
-            ///         b: bool,
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
-            struct RecordFieldDefList { T!['{'], fields: [RecordFieldDef], T!['}'] }
-
-            /// Record field definition including its attributes and doc comments.
-            ///
-            /// ` ``
-            /// same for union
-            /// struct Foo {
-            ///      ❰
-            ///          /// Docs
-            ///          #[attr]
-            ///          pub a: u32
-            ///      ❱
-            ///
-            ///      ❰ b: bool ❱
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
-            struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { }
-
-            /// Tuple field definition list including enclosing parens.
-            ///
-            /// ```
-            /// struct Foo ❰ (u32, String, Vec<u32>) ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
-            struct TupleFieldDefList { T!['('], fields: [TupleFieldDef], T![')'] }
-
-            /// Tuple field definition including its attributes.
-            ///
-            /// ```
-            /// struct Foo(❰ #[attr] u32 ❱);
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/structs.html)
-            struct TupleFieldDef: VisibilityOwner, AttrsOwner {
-                TypeRef,
-            }
-
-            /// Enum definition.
-            /// Includes all of its attributes and doc comments.
-            ///
-            /// ```
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     pub enum Foo<T> where T: Debug {
-            ///         /// Docs
-            ///         #[attr]
-            ///         Bar,
-            ///         Baz(#[attr] u32),
-            ///         Bruh {
-            ///             a: u32,
-            ///             /// Docs
-            ///             #[attr]
-            ///             b: T,
-            ///         }
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
-            struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
-                T![enum],
-                variant_list: EnumVariantList,
-            }
-
-            /// Enum variant definition list including enclosing curly braces.
-            ///
-            /// ```
-            /// enum Foo
-            /// ❰
-            ///     {
-            ///         Bar,
-            ///         Baz(u32),
-            ///         Bruh {
-            ///             a: u32
-            ///         }
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
-            struct EnumVariantList {
-                T!['{'],
-                variants: [EnumVariant],
-                T!['}']
-            }
-
-            /// Enum variant definition including its attributes and discriminant value definition.
-            ///
-            /// ```
-            /// enum Foo {
-            ///     ❰
-            ///         /// Docs
-            ///         #[attr]
-            ///         Bar
-            ///     ❱
-            ///
-            ///     // same for tuple and record variants
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/enumerations.html)
-            struct EnumVariant: VisibilityOwner, NameOwner, DocCommentsOwner, AttrsOwner {
-                FieldDefList,
-                T![=],
-                Expr
-            }
-
-            /// Trait definition.
-            /// Includes all of its attributes and doc comments.
-            ///
-            /// ```
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     pub unsafe trait Foo<T>: Debug where T: Debug {
-            ///         // ...
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/traits.html)
-            struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner {
-                T![unsafe],
-                T![auto],
-                T![trait],
-                ItemList,
-            }
-
-            /// Module definition either with body or not.
-            /// Includes all of its inner and outer attributes, module items, doc comments.
-            ///
-            /// ```
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     pub mod foo;
-            /// ❱
-            ///
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     pub mod bar {
-            ///        //! Inner docs
-            ///        #![inner_attr]
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/modules.html)
-            struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner {
-                T![mod],
-                ItemList,
-                T![;]
-            }
-
-            /// Item defintion list.
-            /// This is used for both top-level items and impl block items.
-            ///
-            /// ```
-            /// ❰
-            ///     fn foo {}
-            ///     struct Bar;
-            ///     enum Baz;
-            ///     trait Bruh;
-            ///     const BRUUH: u32 = 42;
-            /// ❱
-            ///
-            /// impl Foo
-            /// ❰
-            ///     {
-            ///         fn bar() {}
-            ///         const BAZ: u32 = 42;
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items.html)
-            struct ItemList: ModuleItemOwner {
-                T!['{'],
-                assoc_items: [AssocItem],
-                T!['}']
-            }
-
-            /// Constant variable definition.
-            /// Includes all of its attributes and doc comments.
-            ///
-            /// ```
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     pub const FOO: u32 = 42;
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/constant-items.html)
-            struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
-                T![default],
-                T![const],
-                T![=],
-                body: Expr,
-                T![;]
-            }
-
-
-            /// Static variable definition.
-            /// Includes all of its attributes and doc comments.
-            ///
-            /// ```
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     pub static mut FOO: u32 = 42;
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/static-items.html)
-            struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
-                T![static],
-                T![mut],
-                T![=],
-                body: Expr,
-                T![;]
-            }
-
-            /// Type alias definition.
-            /// Includes associated type clauses with type bounds.
-            ///
-            /// ```
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     pub type Foo<T> where T: Debug = T;
-            /// ❱
-            ///
-            /// trait Bar {
-            ///     ❰ type Baz: Debug; ❱
-            ///     ❰ type Bruh = String; ❱
-            ///     ❰ type Bruuh: Debug = u32; ❱
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/type-aliases.html)
-            struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner {
-                T![default],
-                T![type],
-                T![=],
-                TypeRef,
-                T![;]
-            }
-
-            /// Inherent and trait impl definition.
-            /// Includes all of its inner and outer attributes.
-            ///
-            /// ```
-            /// ❰
-            ///     #[attr]
-            ///     unsafe impl<T> const !Foo for Bar where T: Debug {
-            ///         #![inner_attr]
-            ///         // ...
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/implementations.html)
-            struct ImplDef: TypeParamsOwner, AttrsOwner, DocCommentsOwner {
-                T![default],
-                T![const],
-                T![unsafe],
-                T![impl],
-                T![!],
-                T![for],
-                ItemList,
-            }
-
-
-            /// Parenthesized type reference.
-            /// Note: parens are only used for grouping, this is not a tuple type.
-            ///
-            /// ```
-            /// // This is effectively just `u32`.
-            /// // Single-item tuple must be defined with a trailing comma: `(u32,)`
-            /// type Foo = ❰ (u32) ❱;
-            ///
-            /// let bar: &'static ❰ (dyn Debug) ❱ = "bruh";
-            /// ```
-            struct ParenType { T!['('], TypeRef, T![')'] }
-
-            /// Unnamed tuple type.
-            ///
-            /// ```
-            /// let foo: ❰ (u32, bool) ❱ = (42, true);
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/types/tuple.html)
-            struct TupleType { T!['('], fields: [TypeRef], T![')'] }
-
-            /// The never type (i.e. the exclamation point).
-            ///
-            /// ```
-            /// type T = ❰ ! ❱;
-            ///
-            /// fn no_return() -> ❰ ! ❱ {
-            ///     loop {}
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/types/never.html)
-            struct NeverType { T![!] }
-
-            /// Path to a type.
-            /// Includes single identifier type names and elaborate paths with
-            /// generic parameters.
-            ///
-            /// ```
-            /// type Foo = ❰ String ❱;
-            /// type Bar = ❰ std::vec::Vec<T> ❱;
-            /// type Baz = ❰ ::bruh::<Bruuh as Iterator>::Item ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/paths.html)
-            struct PathType { Path }
-
-            /// Raw pointer type.
-            ///
-            /// ```
-            /// type Foo = ❰ *const u32 ❱;
-            /// type Bar = ❰ *mut u32 ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/types/pointer.html#raw-pointers-const-and-mut)
-            struct PointerType { T![*], T![const], T![mut], TypeRef }
-
-            /// Array type.
-            ///
-            /// ```
-            /// type Foo = ❰ [u32; 24 - 3] ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/types/array.html)
-            struct ArrayType { T!['['], TypeRef, T![;], Expr, T![']'] }
-
-            /// Slice type.
-            ///
-            /// ```
-            /// type Foo = ❰ [u8] ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/types/slice.html)
-            struct SliceType { T!['['], TypeRef, T![']'] }
-
-            /// Reference type.
-            ///
-            /// ```
-            /// type Foo = ❰ &'static str ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/types/pointer.html)
-            struct ReferenceType { T![&], T![lifetime], T![mut], TypeRef }
-
-            /// Placeholder type (i.e. the underscore).
-            ///
-            /// ```
-            /// let foo: ❰ _ ❱ = 42_u32;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/types/inferred.html)
-            struct PlaceholderType { T![_] }
-
-            /// Function pointer type (not to be confused with `Fn*` family of traits).
-            ///
-            /// ```
-            /// type Foo = ❰ async fn(#[attr] u32, named: bool) -> u32 ❱;
-            ///
-            /// type Bar = ❰ extern "C" fn(variadic: u32, #[attr] ...) ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/types/function-pointer.html)
-            struct FnPointerType { Abi, T![unsafe], T![fn], ParamList, RetType }
-
-            /// Higher order type.
-            ///
-            /// ```
-            /// type Foo = ❰ for<'a> fn(&'a str) ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/nomicon/hrtb.html)
-            struct ForType { T![for], TypeParamList, TypeRef }
-
-            /// Opaque `impl Trait` type.
-            ///
-            /// ```
-            /// fn foo(bar: ❰ impl Debug + Eq ❱) {}
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/types/impl-trait.html)
-            struct ImplTraitType: TypeBoundsOwner { T![impl] }
-
-            /// Trait object type.
-            ///
-            /// ```
-            /// type Foo = ❰ dyn Debug ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/types/trait-object.html)
-            struct DynTraitType: TypeBoundsOwner { T![dyn] }
-
-            /// Tuple literal.
-            ///
-            /// ```
-            /// ❰ (42, true) ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/tuple-expr.html)
-            struct TupleExpr: AttrsOwner { T!['('], exprs: [Expr], T![')'] }
-
-            /// Array literal.
-            ///
-            /// ```
-            /// ❰ [#![inner_attr] true, false, true] ❱;
-            ///
-            /// ❰ ["baz"; 24] ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/array-expr.html)
-            struct ArrayExpr: AttrsOwner { T!['['], exprs: [Expr], T![;], T![']'] }
-
-            /// Parenthesized expression.
-            /// Note: parens are only used for grouping, this is not a tuple literal.
-            ///
-            /// ```
-            /// ❰ (#![inner_attr] 2 + 2) ❱ * 2;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/grouped-expr.html)
-            struct ParenExpr: AttrsOwner { T!['('], Expr, T![')'] }
-
-            /// Path to a symbol in expression context.
-            /// Includes single identifier variable names and elaborate paths with
-            /// generic parameters.
-            ///
-            /// ```
-            /// ❰ Some::<i32> ❱;
-            /// ❰ foo ❱ + 42;
-            /// ❰ Vec::<i32>::push ❱;
-            /// ❰ <[i32]>::reverse ❱;
-            /// ❰ <String as std::borrow::Borrow<str>>::borrow ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/path-expr.html)
-            struct PathExpr { Path }
-
-            /// Anonymous callable object literal a.k.a. closure, lambda or functor.
-            ///
-            /// ```
-            /// ❰ || 42 ❱;
-            /// ❰ |a: u32| val + 1 ❱;
-            /// ❰ async |#[attr] Pattern(_): Pattern| { bar } ❱;
-            /// ❰ move || baz ❱;
-            /// ❰ || -> u32 { closure_with_ret_type_annotation_requires_block_expr } ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/closure-expr.html)
-            struct LambdaExpr: AttrsOwner {
-                T![static], // Note(@matklad): I belive this is (used to be?) syntax for generators
-                T![async],
-                T![move],
-                ParamList,
-                RetType,
-                body: Expr,
-            }
-
-            /// If expression. Includes both regular `if` and `if let` forms.
-            /// Beware that `else if` is a special case syntax sugar, because in general
-            /// there has to be block expression after `else`.
-            ///
-            /// ```
-            /// ❰ if bool_cond { 42 } ❱
-            /// ❰ if bool_cond { 42 } else { 24 } ❱
-            /// ❰ if bool_cond { 42 } else if bool_cond2 { 42 } ❱
-            ///
-            /// ❰
-            ///     if let Pattern(foo) = bar {
-            ///         foo
-            ///     } else {
-            ///         panic!();
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/if-expr.html)
-            struct IfExpr: AttrsOwner { T![if], Condition }
-
-            /// Unconditional loop expression.
-            ///
-            /// ```
-            /// ❰
-            ///     loop {
-            ///         // yeah, it's that simple...
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html)
-            struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
-
-            /// Block expression with an optional prefix (label, try ketword,
-            /// unsafe keyword, async keyword...).
-            ///
-            /// ```
-            /// ❰
-            ///     'label: try {
-            ///         None?
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// - [try block](https://doc.rust-lang.org/unstable-book/language-features/try-blocks.html)
-            /// - [unsafe block](https://doc.rust-lang.org/reference/expressions/block-expr.html#unsafe-blocks)
-            /// - [async block](https://doc.rust-lang.org/reference/expressions/block-expr.html#async-blocks)
-            struct EffectExpr: AttrsOwner { Label, T![try], T![unsafe], T![async], BlockExpr }
-
-
-            /// For loop expression.
-            /// Note: record struct literals are not valid as iterable expression
-            /// due to ambiguity.
-            ///
-            /// ```
-            /// ❰
-            /// for i in (0..4) {
-            ///     dbg!(i);
-            /// }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#iterator-loops)
-            struct ForExpr: AttrsOwner, LoopBodyOwner {
-                T![for],
-                Pat,
-                T![in],
-                iterable: Expr,
-            }
-
-            /// While loop expression. Includes both regular `while` and `while let` forms.
-            ///
-            /// ```
-            /// ❰
-            ///     while bool_cond {
-            ///         42;
-            ///     }
-            /// ❱
-            /// ❰
-            ///     while let Pattern(foo) = bar {
-            ///         bar += 1;
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-loops)
-            struct WhileExpr: AttrsOwner, LoopBodyOwner { T![while], Condition }
-
-            /// Continue expression.
-            ///
-            /// ```
-            /// while bool_cond {
-            ///     ❰ continue ❱;
-            /// }
-            ///
-            /// 'outer: loop {
-            ///     loop {
-            ///         ❰ continue 'outer ❱;
-            ///     }
-            /// }
-            ///
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#continue-expressions)
-            struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] }
-
-            /// Break expression.
-            ///
-            /// ```
-            /// while bool_cond {
-            ///     ❰ break ❱;
-            /// }
-            /// 'outer: loop {
-            ///     for foo in bar {
-            ///         ❰ break 'outer ❱;
-            ///     }
-            /// }
-            /// 'outer: loop {
-            ///     loop {
-            ///         ❰ break 'outer 42 ❱;
-            ///     }
-            /// }
-            /// ```
-            ///
-            /// [Refernce](https://doc.rust-lang.org/reference/expressions/loop-expr.html#break-expressions)
-            struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr }
-
-            /// Label.
-            ///
-            /// ```
-            /// ❰ 'outer: ❱ loop {}
-            ///
-            /// let foo = ❰ 'bar: ❱ loop {}
-            ///
-            /// ❰ 'baz: ❱ {
-            ///     break 'baz;
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html?highlight=label#loop-labels)
-            /// [Labels for blocks RFC](https://github.com/rust-lang/rfcs/blob/master/text/2046-label-break-value.md)
-            struct Label { T![lifetime] }
-
-            /// Block expression. Includes unsafe blocks and block labels.
-            ///
-            /// ```
-            ///     let foo = ❰
-            ///         {
-            ///             #![inner_attr]
-            ///             ❰ { } ❱
-            ///
-            ///             ❰ 'label: { break 'label } ❱
-            ///         }
-            ///     ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/block-expr.html)
-            /// [Labels for blocks RFC](https://github.com/rust-lang/rfcs/blob/master/text/2046-label-break-value.md)
-            struct BlockExpr: AttrsOwner, ModuleItemOwner {
-                Label, T!['{'], statements: [Stmt], Expr, T!['}'],
-            }
-
-            /// Return expression.
-            ///
-            /// ```
-            /// || ❰ return 42 ❱;
-            ///
-            /// fn bar() {
-            ///     ❰ return ❱;
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/return-expr.html)
-            struct ReturnExpr: AttrsOwner { Expr }
-
-            /// Call expression (not to be confused with method call expression, it is
-            /// a separate ast node).
-            ///
-            /// ```
-            /// ❰ foo() ❱;
-            /// ❰ &str::len("bar") ❱;
-            /// ❰ <&str as PartialEq<&str>>::eq(&"", &"") ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/call-expr.html)
-            struct CallExpr: ArgListOwner { Expr }
-
-            /// Method call expression.
-            ///
-            /// ```
-            /// ❰ receiver_expr.method() ❱;
-            /// ❰ receiver_expr.method::<T>(42, true) ❱;
-            ///
-            /// ❰ ❰ ❰ foo.bar() ❱ .baz() ❱ .bruh() ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/method-call-expr.html)
-            struct MethodCallExpr: AttrsOwner, ArgListOwner {
-                Expr, T![.], NameRef, TypeArgList,
-            }
-
-            /// Index expression a.k.a. subscript operator call.
-            ///
-            /// ```
-            /// ❰ foo[42] ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/array-expr.html)
-            struct IndexExpr: AttrsOwner { T!['['], T![']'] }
-
-            /// Field access expression.
-            ///
-            /// ```
-            /// ❰ expr.bar ❱;
-            ///
-            /// ❰ ❰ ❰ foo.bar ❱ .baz ❱ .bruh ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/field-expr.html)
-            struct FieldExpr: AttrsOwner { Expr, T![.], NameRef }
-
-            /// Await operator call expression.
-            ///
-            /// ```
-            /// ❰ expr.await ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/await-expr.html)
-            struct AwaitExpr: AttrsOwner { Expr, T![.], T![await] }
-
-            /// The question mark operator call.
-            ///
-            /// ```
-            /// ❰ expr? ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#the-question-mark-operator)
-            struct TryExpr: AttrsOwner { Expr, T![?] }
-
-            /// Type cast expression.
-            ///
-            /// ```
-            /// ❰ expr as T ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions)
-            struct CastExpr: AttrsOwner { Expr, T![as], TypeRef }
-
-
-            /// Borrow operator call.
-            ///
-            /// ```
-            /// ❰ &foo ❱;
-            /// ❰ &mut bar ❱;
-            /// ❰ &raw const bar ❱;
-            /// ❰ &raw mut bar ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#borrow-operators)
-            struct RefExpr: AttrsOwner { T![&], T![raw], T![mut], T![const], Expr }
-
-            /// Prefix operator call. This is either `!` or `*` or `-`.
-            ///
-            /// ```
-            /// ❰ !foo ❱;
-            /// ❰ *bar ❱;
-            /// ❰ -42 ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html)
-            struct PrefixExpr: AttrsOwner { /*PrefixOp,*/ Expr }
-
-            /// Box operator call.
-            ///
-            /// ```
-            /// ❰ box 42 ❱;
-            /// ```
-            ///
-            /// [RFC](https://github.com/rust-lang/rfcs/blob/0806be4f282144cfcd55b1d20284b43f87cbe1c6/text/0809-box-and-in-for-stdlib.md)
-            struct BoxExpr: AttrsOwner { T![box], Expr }
-
-            /// Range operator call.
-            ///
-            /// ```
-            /// ❰ 0..42 ❱;
-            /// ❰ ..42 ❱;
-            /// ❰ 0.. ❱;
-            /// ❰ .. ❱;
-            /// ❰ 0..=42 ❱;
-            /// ❰ ..=42 ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/range-expr.html)
-            struct RangeExpr: AttrsOwner { /*RangeOp*/ }
-
-
-            /// Binary operator call.
-            /// Includes all arithmetic, logic, bitwise and assignment operators.
-            ///
-            /// ```
-            /// ❰ 2 + ❰ 2 * 2 ❱ ❱;
-            /// ❰ ❰ true && false ❱ || true ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/operator-expr.html#arithmetic-and-logical-binary-operators)
-            struct BinExpr: AttrsOwner { /*BinOp*/ }
-
-
-            /// [Raw] string, [raw] byte string, char, byte, integer, float or bool literal.
-            ///
-            /// ```
-            /// ❰ "str" ❱;
-            /// ❰ br##"raw byte str"## ❱;
-            /// ❰ 'c' ❱;
-            /// ❰ b'c' ❱;
-            /// ❰ 42 ❱;
-            /// ❰ 1e9 ❱;
-            /// ❰ true ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/literal-expr.html)
-            struct Literal { /*LiteralToken*/ }
-
-            /// Match expression.
-            ///
-            /// ```
-            /// ❰
-            ///     match expr {
-            ///         Pat1 => {}
-            ///         Pat2(_) => 42,
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
-            struct MatchExpr: AttrsOwner { T![match], Expr, MatchArmList }
-
-            /// Match arm list part of match expression. Includes its inner attributes.
-            ///
-            /// ```
-            /// match expr
-            /// ❰
-            ///     {
-            ///         #![inner_attr]
-            ///         Pat1 => {}
-            ///         Pat2(_) => 42,
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
-            struct MatchArmList: AttrsOwner { T!['{'], arms: [MatchArm], T!['}'] }
-
-
-            /// Match arm.
-            /// Note: record struct literals are not valid as target match expression
-            /// due to ambiguity.
-            /// ```
-            /// match expr {
-            ///     ❰ #[attr] Pattern(it) if bool_cond => it ❱,
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html)
-            struct MatchArm: AttrsOwner {
-                pat: Pat,
-                guard: MatchGuard,
-                T![=>],
-                Expr,
-            }
-
-            /// Match guard.
-            ///
-            /// ```
-            /// match expr {
-            ///     Pattern(it) ❰ if bool_cond ❱ => it,
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/match-expr.html#match-guards)
-            struct MatchGuard { T![if], Expr }
-
-            /// Record literal expression. The same syntax is used for structs,
-            /// unions and record enum variants.
-            ///
-            /// ```
-            /// ❰
-            ///     foo::Bar {
-            ///         #![inner_attr]
-            ///         baz: 42,
-            ///         bruh: true,
-            ///         ..spread
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
-            struct RecordLit { Path, RecordFieldList}
-
-            /// Record field list including enclosing curly braces.
-            ///
-            /// foo::Bar ❰
-            ///     {
-            ///         baz: 42,
-            ///         ..spread
-            ///     }
-            /// ❱
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
-            struct RecordFieldList {
-                T!['{'],
-                fields: [RecordField],
-                T![..],
-                spread: Expr,
-                T!['}']
-            }
-
-            /// Record field.
-            ///
-            /// ```
-            /// foo::Bar {
-            ///     ❰ #[attr] baz: 42 ❱
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/struct-expr.html)
-            struct RecordField: AttrsOwner { NameRef, T![:], Expr }
-
-            /// Disjunction of patterns.
-            ///
-            /// ```
-            /// let ❰ Foo(it) | Bar(it) | Baz(it) ❱ = bruh;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html)
-            struct OrPat { pats: [Pat] }
-
-            /// Parenthesized pattern.
-            /// Note: parens are only used for grouping, this is not a tuple pattern.
-            ///
-            /// ```
-            /// if let ❰ &(0..=42) ❱ = foo {}
-            /// ```
-            ///
-            /// https://doc.rust-lang.org/reference/patterns.html#grouped-patterns
-            struct ParenPat { T!['('], Pat, T![')'] }
-
-            /// Reference pattern.
-            /// Note: this has nothing to do with `ref` keyword, the latter is used in bind patterns.
-            ///
-            /// ```
-            /// let ❰ &mut foo ❱ = bar;
-            ///
-            /// let ❰ & ❰ &mut ❰ &_ ❱ ❱ ❱ = baz;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#reference-patterns)
-            struct RefPat { T![&], T![mut], Pat }
-
-            /// Box pattern.
-            ///
-            /// ```
-            /// let ❰ box foo ❱ = box 42;
-            /// ```
-            ///
-            /// [Unstable book](https://doc.rust-lang.org/unstable-book/language-features/box-patterns.html)
-            struct BoxPat { T![box], Pat }
-
-            /// Bind pattern.
-            ///
-            /// ```
-            /// match foo {
-            ///     Some(❰ ref mut bar ❱) => {}
-            ///     ❰ baz @ None ❱ => {}
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#identifier-patterns)
-            struct BindPat: AttrsOwner, NameOwner { T![ref], T![mut], T![@], Pat }
-
-            /// Placeholder pattern a.k.a. the wildcard pattern or the underscore.
-            ///
-            /// ```
-            /// let ❰ _ ❱ = foo;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#wildcard-pattern)
-            struct PlaceholderPat { T![_] }
-
-            /// Rest-of-the record/tuple pattern.
-            /// Note: this is not the unbonded range pattern (even more: it doesn't exist).
-            ///
-            /// ```
-            /// let Foo { bar, ❰ .. ❱ } = baz;
-            /// let (❰ .. ❱, bruh) = (42, 24, 42);
-            /// let Bruuh(❰ .. ❱) = bruuuh;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
-            struct DotDotPat { T![..] }
-
-            /// Path pattern.
-            /// Doesn't include the underscore pattern (it is a special case, namely `PlaceholderPat`).
-            ///
-            /// ```
-            /// let ❰ foo::bar::Baz ❱ { .. } = bruh;
-            /// if let ❰ CONST ❱ = 42 {}
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#path-patterns)
-            struct PathPat { Path }
-
-            /// Slice pattern.
-            ///
-            /// ```
-            /// let ❰ [foo, bar, baz] ❱ = [1, 2, 3];
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#slice-patterns)
-            struct SlicePat { T!['['], args: [Pat], T![']'] }
-
-            /// Range pattern.
-            ///
-            /// ```
-            /// match foo {
-            ///     ❰ 0..42 ❱ => {}
-            ///     ❰ 0..=42 ❱ => {}
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#range-patterns)
-            struct RangePat { } // FIXME(@matklad): here should be T![..], T![..=] I think, if we don't already have an accessor in expresions_ext
-
-            /// Literal pattern.
-            /// Includes only bool, number, char, and string literals.
-            ///
-            /// ```
-            /// match foo {
-            ///     Number(❰ 42 ❱) => {}
-            ///     String(❰ "42" ❱) => {}
-            ///     Bool(❰ true ❱) => {}
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#literal-patterns)
-            struct LiteralPat { Literal }
-
-            /// Macro invocation in pattern position.
-            ///
-            /// ```
-            /// let ❰ foo!(my custom syntax) ❱ = baz;
-            ///
-            /// ```
-            /// [Reference](https://doc.rust-lang.org/reference/macros.html#macro-invocation)
-            struct MacroPat { MacroCall }
-
-            /// Record literal pattern.
-            ///
-            /// ```
-            /// let ❰ foo::Bar { baz, .. } ❱ = bruh;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
-            struct RecordPat { RecordFieldPatList, Path }
-
-            /// Record literal's field patterns list including enclosing curly braces.
-            ///
-            /// ```
-            /// let foo::Bar ❰ { baz, bind @ bruh, .. } ❱ = bruuh;
-            /// ``
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
-            struct RecordFieldPatList {
-                T!['{'],
-                record_field_pats: [RecordFieldPat],
-                bind_pats: [BindPat],
-                T![..],
-                T!['}']
-            }
-
-            /// Record literal's field pattern.
-            /// Note: record literal can also match tuple structs.
-            ///
-            /// ```
-            /// let Foo { ❰ bar: _ ❱ } = baz;
-            /// let TupleStruct { ❰ 0: _ ❱ } = bruh;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#struct-patterns)
-            struct RecordFieldPat: AttrsOwner { NameRef, T![:], Pat }
-
-            /// Tuple struct literal pattern.
-            ///
-            /// ```
-            /// let ❰ foo::Bar(baz, bruh) ❱ = bruuh;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#tuple-struct-patterns)
-            struct TupleStructPat { Path, T!['('], args: [Pat], T![')'] }
-
-            /// Tuple pattern.
-            /// Note: this doesn't include tuple structs (see `TupleStructPat`)
-            ///
-            /// ```
-            /// let ❰ (foo, bar, .., baz) ❱ = bruh;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/patterns.html#tuple-patterns)
-            struct TuplePat { T!['('], args: [Pat], T![')'] }
-
-            /// Visibility.
-            ///
-            /// ```
-            /// ❰ pub mod ❱ foo;
-            /// ❰ pub(crate) ❱ struct Bar;
-            /// ❰ pub(self) ❱ enum Baz {}
-            /// ❰ pub(super) ❱ fn bruh() {}
-            /// ❰ pub(in bruuh::bruuuh) ❱ type T = u64;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/visibility-and-privacy.html)
-            struct Visibility { T![pub], T![super], T![self], T![crate] }
-
-            /// Single identifier.
-            /// Note(@matklad): `Name` is for things that install a new name into the scope,
-            /// `NameRef` is a usage of a name. Most of the time, this definition/reference
-            /// distinction can be determined purely syntactically, ie in
-            /// ```
-            /// fn foo() { foo() }
-            /// ```
-            /// the first foo is `Name`, the second one is `NameRef`.
-            /// The notable exception are patterns, where in
-            /// ``
-            /// let x = 92
-            /// ```
-            /// `x` can be semantically either a name or a name ref, depeding on
-            /// wether there's an `x` constant in scope.
-            /// We use `Name` for patterns, and disambiguate semantically (see `NameClass` in ide_db).
-            ///
-            /// ```
-            /// let ❰ foo ❱ = bar;
-            /// struct ❰ Baz ❱;
-            /// fn ❰ bruh ❱() {}
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/identifiers.html)
-            struct Name { T![ident] }
-
-            /// Reference to a name.
-            /// See the explanation on the difference between `Name` and `NameRef`
-            /// in `Name` ast node docs.
-            ///
-            /// ```
-            /// let foo = ❰ bar ❱(❰ Baz(❰ bruh ❱) ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/identifiers.html)
-            struct NameRef { }
-
-            /// Macro call.
-            /// Includes all of its attributes and doc comments.
-            ///
-            /// ```
-            /// ❰
-            ///     /// Docs
-            ///     #[attr]
-            ///     macro_rules! foo {   // macro rules is also a macro call
-            ///         ($bar: tt) => {}
-            ///     }
-            /// ❱
-            ///
-            /// // semicolon is a part of `MacroCall` when it is used in item positions
-            /// ❰ foo!(); ❱
-            ///
-            /// fn main() {
-            ///     ❰ foo!() ❱; // macro call in expression positions doesn't include the semi
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/macros.html)
-            struct MacroCall: NameOwner, AttrsOwner, DocCommentsOwner {
-                Path, T![!], TokenTree, T![;]
-            }
-
-            /// Attribute.
-            ///
-            /// ```
-            /// ❰ #![inner_attr] ❱
-            ///
-            /// ❰ #[attr] ❱
-            /// ❰ #[foo = "bar"] ❱
-            /// ❰ #[baz(bruh::bruuh = "42")] ❱
-            /// struct Foo;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/attributes.html)
-            struct Attr { T![#], T![!], T!['['], Path, T![=], input: AttrInput, T![']'] }
-
-            /// Stores a list of lexer tokens and other `TokenTree`s.
-            /// It appears in attributes, macro_rules and macro call (foo!)
-            ///
-            /// ```
-            /// macro_call! ❰ { my syntax here } ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/macros.html)
-            struct TokenTree {}
-
-            /// Generic lifetime, type and constants parameters list **declaration**.
-            ///
-            /// ```
-            /// fn foo❰ <'a, 'b, T, U, const BAR: u64> ❱() {}
-            ///
-            /// struct Baz❰ <T> ❱(T);
-            ///
-            /// impl❰ <T> ❱ Bruh<T> {}
-            ///
-            /// type Bruuh = for❰ <'a> ❱ fn(&'a str) -> &'a str;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
-            struct TypeParamList {
-                T![<],
-                type_params: [TypeParam],
-                lifetime_params: [LifetimeParam],
-                const_params: [ConstParam],
-                T![>]
-            }
-
-            /// Single type parameter **declaration**.
-            ///
-            /// ```
-            /// fn foo<❰ K ❱, ❰ I ❱, ❰ E: Debug ❱, ❰ V = DefaultType ❱>() {}
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
-            struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner {
-                T![=],
-                default_type: TypeRef,
-            }
-
-            /// Const generic parameter **declaration**.
-            /// ```
-            /// fn foo<T, U, ❰ const BAR: usize ❱, ❰ const BAZ: bool ❱>() {}
-            /// ```
-            ///
-            /// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md#declaring-a-const-parameter)
-            struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner {
-                T![=],
-                default_val: Expr,
-            }
-
-            /// Lifetime parameter **declaration**.
-            ///
-            /// ```
-            /// fn foo<❰ 'a ❱, ❰ 'b ❱, V, G, D>(bar: &'a str, baz: &'b mut str) {}
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/generics.html)
-            struct LifetimeParam: AttrsOwner { T![lifetime] }
-
-            /// Type bound declaration clause.
-            ///
-            /// ```
-            /// fn foo<T: ❰ ?Sized ❱ + ❰ Debug ❱>() {}
-            ///
-            /// trait Bar<T>
-            /// where
-            ///     T: ❰ Send ❱ + ❰ Sync ❱
-            /// {
-            ///     type Baz: ❰ !Sync ❱ + ❰ Debug ❱ + ❰ ?const Add ❱;
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/trait-bounds.html)
-            struct TypeBound { T![lifetime], /* Question,  */ T![const], /* Question, */ TypeRef }
-
-            /// Type bounds list.
-            ///
-            /// ```
-            ///
-            /// fn foo<T: ❰ ?Sized + Debug ❱>() {}
-            ///
-            /// trait Bar<T>
-            /// where
-            ///     T: ❰ Send + Sync ❱
-            /// {
-            ///     type Baz: ❰ !Sync + Debug ❱;
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/trait-bounds.html)
-            struct TypeBoundList { bounds: [TypeBound] }
-
-            /// Single where predicate.
-            ///
-            /// ```
-            /// trait Foo<'a, 'b, T>
-            /// where
-            ///     ❰ 'a: 'b ❱,
-            ///     ❰ T: IntoIterator ❱,
-            ///     ❰ for<'c> <T as IntoIterator>::Item: Bar<'c> ❱
-            /// {}
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/generics.html#where-clauses)
-            struct WherePred: TypeBoundsOwner { T![for], TypeParamList, T![lifetime], TypeRef }
-
-            /// Where clause.
-            ///
-            /// ```
-            /// trait Foo<'a, T> ❰ where 'a: 'static, T: Debug ❱ {}
-            ///
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/generics.html#where-clauses)
-            struct WhereClause { T![where], predicates: [WherePred] }
-
-            /// Abi declaration.
-            /// Note: the abi string is optional.
-            ///
-            /// ```
-            /// ❰ extern "C" ❱ {
-            ///     fn foo() {}
-            /// }
-            ///
-            /// type Bar = ❰ extern ❱ fn() -> u32;
-            ///
-            /// type Baz = ❰ extern r#"stdcall"# ❱ fn() -> bool;
-            /// ```
-            ///
-            /// - [Extern blocks reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
-            /// - [FFI function pointers reference](https://doc.rust-lang.org/reference/items/functions.html#functions)
-            struct Abi { /*String*/ }
-
-            /// Expression statement.
-            ///
-            /// ```
-            /// ❰ 42; ❱
-            /// ❰ foo(); ❱
-            /// ❰ (); ❱
-            /// ❰ {}; ❱
-            ///
-            /// // constructions with trailing curly brace can omit the semicolon
-            /// // but only when there are satements immediately after them (this is important!)
-            /// ❰ if bool_cond { } ❱
-            /// ❰ loop {} ❱
-            /// ❰ somestatment; ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/statements.html)
-            struct ExprStmt: AttrsOwner { Expr, T![;] }
-
-            /// Let statement.
-            ///
-            /// ```
-            /// ❰ #[attr] let foo; ❱
-            /// ❰ let bar: u64; ❱
-            /// ❰ let baz = 42; ❱
-            /// ❰ let bruh: bool = true; ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/statements.html#let-statements)
-            struct LetStmt: AttrsOwner, TypeAscriptionOwner {
-                T![let],
-                Pat,
-                T![=],
-                initializer: Expr,
-                T![;],
-            }
-
-            /// Condition of `if` or `while` expression.
-            ///
-            /// ```
-            /// if ❰ true ❱ {}
-            /// if ❰ let Pat(foo) = bar ❱ {}
-            ///
-            /// while ❰ true ❱ {}
-            /// while ❰ let Pat(baz) = bruh ❱ {}
-            /// ```
-            ///
-            /// [If expression reference](https://doc.rust-lang.org/reference/expressions/if-expr.html)
-            /// [While expression reference](https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-loops)
-            struct Condition { T![let], Pat, T![=], Expr }
-
-            /// Parameter list **declaration**.
-            ///
-            /// ```
-            /// fn foo❰ (a: u32, b: bool) ❱ -> u32 {}
-            /// let bar = ❰ |a, b| ❱ {};
-            ///
-            /// impl Baz {
-            ///     fn bruh❰ (&self, a: u32) ❱ {}
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)ocs to codegen script
-            struct ParamList { // FIXME: this node is used by closure expressions too, but hey use pipes instead of parens...
-                T!['('],
-                SelfParam,
-                params: [Param],
-                T![')']
-            }
-
-            /// Self parameter **declaration**.
-            ///
-            /// ```
-            /// impl Bruh {
-            ///     fn foo(❰ self ❱) {}
-            ///     fn bar(❰ &self ❱) {}
-            ///     fn baz(❰ &mut self ❱) {}
-            ///     fn blah<'a>(❰ &'a self ❱) {}
-            ///     fn blin(❰ self: Box<Self> ❱) {}
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
-            struct SelfParam: TypeAscriptionOwner, AttrsOwner { T![&], T![mut], T![lifetime], T![self] }
-
-            /// Parameter **declaration**.
-            ///
-            /// ```
-            /// fn foo(❰ #[attr] Pat(bar): Pat(u32) ❱, ❰ #[attr] _: bool ❱) {}
-            ///
-            /// extern "C" {
-            ///     fn bar(❰ baz: u32 ❱, ❰ ... ❱) -> u32;
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/functions.html)
-            struct Param: TypeAscriptionOwner, AttrsOwner {
-                Pat,
-                T![...]
-            }
-
-            /// Use declaration.
-            ///
-            /// ```
-            /// ❰ #[attr] pub use foo; ❱
-            /// ❰ use bar as baz; ❱
-            /// ❰ use bruh::{self, bruuh}; ❱
-            /// ❰ use { blin::blen, blah::* };
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
-            struct UseItem: AttrsOwner, VisibilityOwner {
-                T![use],
-                UseTree,
-            }
-
-            /// Use tree.
-            ///
-            /// ```
-            /// pub use ❰ foo::❰ * ❱ ❱;
-            /// use ❰ bar as baz ❱;
-            /// use ❰ bruh::bruuh::{ ❰ self ❱, ❰ blin ❱ } ❱;
-            /// use ❰ { ❰ blin::blen ❱ } ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
-            struct UseTree {
-                Path, T![*], UseTreeList, Alias
-            }
-
-            /// Item alias.
-            /// Note: this is not the type alias.
-            ///
-            /// ```
-            /// use foo ❰ as bar ❱;
-            /// use baz::{bruh ❰ as _ ❱};
-            /// extern crate bruuh ❰ as blin ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
-            struct Alias: NameOwner { T![as] }
-
-            /// Sublist of use trees.
-            ///
-            /// ```
-            /// use bruh::bruuh::❰ { ❰ self ❱, ❰ blin ❱ } ❱;
-            /// use ❰ { blin::blen::❰ {} ❱ } ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/use-declarations.html)
-            struct UseTreeList { T!['{'], use_trees: [UseTree], T!['}'] }
-
-            /// Extern crate item.
-            ///
-            /// ```
-            /// ❰ #[attr] pub extern crate foo; ❱
-            /// ❰ extern crate self as bar; ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/extern-crates.html)
-            struct ExternCrateItem: AttrsOwner, VisibilityOwner {
-                T![extern], T![crate], NameRef, Alias,
-            }
-
-            /// Call site arguments list.
-            ///
-            /// ```
-            /// foo::<T, U>❰ (42, true) ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/expressions/call-expr.html)
-            struct ArgList {
-                T!['('],
-                args: [Expr],
-                T![')']
-            }
-
-            /// Path to a symbol. Includes single identifier names and elaborate paths with
-            /// generic parameters.
-            ///
-            /// ```
-            /// (0..10).❰ ❰ collect ❱ ::<Vec<_>> ❱();
-            /// ❰ ❰ ❰ Vec ❱ ::<u8> ❱ ::with_capacity ❱(1024);
-            /// ❰ ❰ <❰ Foo ❱ as ❰ ❰ bar ❱ ::Bar ❱> ❱ ::baz ❱();
-            /// ❰ ❰ <❰ bruh ❱> ❱ ::bruuh ❱();
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/paths.html)
-            struct Path {
-                segment: PathSegment,
-                T![::],
-                qualifier: Path,
-            }
-
-            /// Segment of the path to a symbol.
-            /// Only path segment of an absolute path holds the `::` token,
-            /// all other `::` tokens that connect path segments reside under `Path` itself.`
-            ///
-            /// ```
-            /// (0..10).❰ collect ❱ :: ❰ <Vec<_>> ❱();
-            /// ❰ Vec ❱ :: ❰ <u8> ❱ :: ❰ with_capacity ❱(1024);
-            /// ❰ <❰ Foo ❱ as ❰ bar ❱ :: ❰ Bar ❱> ❱ :: ❰ baz ❱();
-            /// ❰ <❰ bruh ❱> ❱ :: ❰ bruuh ❱();
-            ///
-            /// // Note that only in this case `::` token is inlcuded:
-            /// ❰ ::foo ❱;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/paths.html)
-            struct PathSegment {
-                T![::], T![crate], T![self], T![super], T![<], NameRef, TypeArgList, ParamList, RetType, PathType, T![>]
-            }
-
-            /// List of type arguments that are passed at generic instantiation site.
-            ///
-            /// ```
-            /// type _ = Foo ❰ ::<'a, u64, Item = Bar, 42, {true}> ❱::Bar;
-            ///
-            /// Vec❰ ::<bool> ❱::();
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
-            struct TypeArgList {
-                T![::],
-                T![<],
-                generic_args: [GenericArg],
-                type_args: [TypeArg],
-                lifetime_args: [LifetimeArg],
-                assoc_type_args: [AssocTypeArg],
-                const_args: [ConstArg],
-                T![>]
-            }
-
-            /// Type argument that is passed at generic instantiation site.
-            ///
-            /// ```
-            /// type _ = Foo::<'a, ❰ u64 ❱, ❰ bool ❱, Item = Bar, 42>::Baz;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
-            struct TypeArg { TypeRef }
-
-            /// Associated type argument that is passed at generic instantiation site.
-            /// ```
-            /// type Foo = Bar::<'a, u64, bool, ❰ Item = Baz ❱, 42>::Bruh;
-            ///
-            /// trait Bruh<T>: Iterator<❰ Item: Debug ❱> {}
-            /// ```
-            ///
-            struct AssocTypeArg : TypeBoundsOwner { NameRef, T![=], TypeRef }
-
-            /// Lifetime argument that is passed at generic instantiation site.
-            ///
-            /// ```
-            /// fn foo<'a>(s: &'a str) {
-            ///     bar::<❰ 'a ❱>(s);
-            /// }
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/paths.html#paths-in-expressions)
-            struct LifetimeArg { T![lifetime] }
-
-            /// Constant value argument that is passed at generic instantiation site.
-            ///
-            /// ```
-            /// foo::<u32, ❰ { true } ❱>();
-            ///
-            /// bar::<❰ { 2 + 2} ❱>();
-            /// ```
-            ///
-            /// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/2000-const-generics.md#declaring-a-const-parameter)
-            struct ConstArg { Literal, BlockExpr }
-
-
-            /// FIXME: (@edwin0cheng) Remove it to use ItemList instead
-            /// https://github.com/rust-analyzer/rust-analyzer/pull/4083#discussion_r422666243
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/macros.html)
-            struct MacroItems: ModuleItemOwner { }
-
-            /// FIXME: (@edwin0cheng) add some documentation here. As per the writing
-            /// of this comment this ast node is not used.
-            ///
-            /// ```
-            /// // FIXME: example here
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/macros.html)
-            struct MacroStmts {
-                statements: [Stmt],
-                Expr,
-            }
-
-            /// List of items in an extern block.
-            ///
-            /// ```
-            /// extern "C" ❰
-            ///     {
-            ///         fn foo();
-            ///         static var: u32;
-            ///     }
-            /// ❱
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
-            struct ExternItemList: ModuleItemOwner {
-                T!['{'],
-                extern_items: [ExternItem],
-                T!['}']
-            }
-
-            /// Extern block.
-            ///
-            /// ```
-            /// ❰
-            ///     extern "C" {
-            ///         fn foo();
-            ///     }
-            /// ❱
-            ///
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/items/external-blocks.html)
-            struct ExternBlock {
-                Abi,
-                ExternItemList
-            }
-
-            /// Meta item in an attribute.
-            ///
-            /// ```
-            /// #[❰ bar::baz = "42" ❱]
-            /// #[❰ bruh(bruuh("true")) ❱]
-            /// struct Foo;
-            /// ```
-            ///
-            /// [Reference](https://doc.rust-lang.org/reference/attributes.html?highlight=meta,item#meta-item-attribute-syntax)
-            struct MetaItem {
-                Path, T![=], AttrInput, nested_meta_items: [MetaItem]
-            }
-
-            /// Macro 2.0 definition.
-            /// Their syntax is still WIP by rustc team...
-            /// ```
-            /// ❰
-            ///     macro foo { }
-            /// ❱
-            /// ```
-            ///
-            /// [RFC](https://github.com/rust-lang/rfcs/blob/master/text/1584-macros.md)
-            struct MacroDef {
-                Name, TokenTree
-            }
-        },
-        enums: ast_enums! {
-            /// Any kind of nominal type definition.
-            enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner {
-                StructDef, EnumDef, UnionDef,
-            }
-
-            /// Any kind of generic argument passed at instantiation site
-            enum GenericArg {
-                LifetimeArg,
-                TypeArg,
-                ConstArg,
-                AssocTypeArg
-            }
-
-            /// Any kind of construct valid in type context
-            enum TypeRef {
-                ParenType,
-                TupleType,
-                NeverType,
-                PathType,
-                PointerType,
-                ArrayType,
-                SliceType,
-                ReferenceType,
-                PlaceholderType,
-                FnPointerType,
-                ForType,
-                ImplTraitType,
-                DynTraitType,
-            }
-
-            /// Any kind of top-level item that may appear in a module
-            enum ModuleItem: NameOwner, AttrsOwner, VisibilityOwner {
-                StructDef,
-                UnionDef,
-                EnumDef,
-                FnDef,
-                TraitDef,
-                TypeAliasDef,
-                ImplDef,
-                UseItem,
-                ExternCrateItem,
-                ConstDef,
-                StaticDef,
-                Module,
-                MacroCall,
-                ExternBlock
-            }
-
-
-
-            /// Any kind of item that may appear in an impl block
-            ///
-            /// // FIXME: impl blocks can also contain MacroCall
-            enum AssocItem: NameOwner, AttrsOwner {
-                FnDef, TypeAliasDef, ConstDef
-            }
-
-            /// Any kind of item that may appear in an extern block
-            ///
-            /// // FIXME: extern blocks can also contain MacroCall
-            enum ExternItem: NameOwner, AttrsOwner, VisibilityOwner {
-                FnDef, StaticDef
-            }
-
-            /// Any kind of expression
-            enum Expr: AttrsOwner {
-                TupleExpr,
-                ArrayExpr,
-                ParenExpr,
-                PathExpr,
-                LambdaExpr,
-                IfExpr,
-                LoopExpr,
-                ForExpr,
-                WhileExpr,
-                ContinueExpr,
-                BreakExpr,
-                Label,
-                BlockExpr,
-                ReturnExpr,
-                MatchExpr,
-                RecordLit,
-                CallExpr,
-                IndexExpr,
-                MethodCallExpr,
-                FieldExpr,
-                AwaitExpr,
-                TryExpr,
-                EffectExpr,
-                CastExpr,
-                RefExpr,
-                PrefixExpr,
-                RangeExpr,
-                BinExpr,
-                Literal,
-                MacroCall,
-                BoxExpr,
-            }
-
-            /// Any kind of pattern
-            enum Pat {
-                OrPat,
-                ParenPat,
-                RefPat,
-                BoxPat,
-                BindPat,
-                PlaceholderPat,
-                DotDotPat,
-                PathPat,
-                RecordPat,
-                TupleStructPat,
-                TuplePat,
-                SlicePat,
-                RangePat,
-                LiteralPat,
-                MacroPat,
-            }
-
-            /// Any kind of input to an attribute
-            enum AttrInput { Literal, TokenTree }
-
-            /// Any kind of statement
-            /// Note: there are no empty statements, these are just represented as
-            /// bare semicolons without a dedicated statement ast node.
-            enum Stmt {
-                LetStmt,
-                ExprStmt,
-                // macro calls are parsed as expression statements
-            }
-
-            /// Any kind of fields list (record or tuple field lists)
-            enum FieldDefList {
-                RecordFieldDefList,
-                TupleFieldDefList,
-            }
-        },
-    }
-}
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index 5a18b3e2b36..24e8be1fbce 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -3,19 +3,27 @@
 //! Specifically, it generates the `SyntaxKind` enum and a number of newtype
 //! wrappers around `SyntaxNode` which implement `ra_syntax::AstNode`.
 
-use std::{collections::HashSet, fmt::Write};
+use std::{
+    collections::{BTreeSet, HashSet},
+    fmt::Write,
+};
 
 use proc_macro2::{Punct, Spacing};
 use quote::{format_ident, quote};
+use ungrammar::{Grammar, Rule};
 
 use crate::{
-    ast_src::{rust_ast, AstSrc, Field, FieldSrc, KindsSrc, KINDS_SRC},
+    ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Field, FieldSrc, KindsSrc, KINDS_SRC},
     codegen::{self, update, Mode},
     project_root, Result,
 };
 
 pub fn generate_syntax(mode: Mode) -> Result<()> {
-    let ast = rust_ast();
+    let grammar = include_str!("rust.ungram")
+        .parse::<Grammar>()
+        .unwrap_or_else(|err| panic!("\n    \x1b[91merror\x1b[0m: {}\n", err));
+    let ast = lower(&grammar);
+
     let syntax_kinds_file = project_root().join(codegen::SYNTAX_KINDS);
     let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?;
     update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?;
@@ -215,7 +223,9 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> Result<String> {
         .map(|kind| to_pascal_case(kind))
         .filter(|name| !defined_nodes.iter().any(|&it| it == name))
     {
-        eprintln!("Warning: node {} not defined in ast source", node);
+        drop(node)
+        // TODO: restore this
+        // eprintln!("Warning: node {} not defined in ast source", node);
     }
 
     let ast = quote! {
@@ -414,6 +424,10 @@ fn to_pascal_case(s: &str) -> String {
     buf
 }
 
+fn pluralize(s: &str) -> String {
+    format!("{}s", s)
+}
+
 impl Field {
     fn is_many(&self) -> bool {
         matches!(self, Field::Node { src: FieldSrc::Many(_), .. })
@@ -449,6 +463,7 @@ impl Field {
                     "." => "dot",
                     ".." => "dotdot",
                     "..." => "dotdotdot",
+                    "..=" => "dotdoteq",
                     "=>" => "fat_arrow",
                     "@" => "at",
                     ":" => "colon",
@@ -475,3 +490,204 @@ impl Field {
         }
     }
 }
+
+fn lower(grammar: &Grammar) -> AstSrc {
+    let mut res = AstSrc::default();
+    res.tokens = vec!["Whitespace".into(), "Comment".into(), "String".into(), "RawString".into()];
+
+    let nodes = grammar
+        .iter()
+        .filter(|&node| match grammar[node].rule {
+            Rule::Node(it) if it == node => false,
+            _ => true,
+        })
+        .collect::<Vec<_>>();
+
+    for &node in &nodes {
+        let name = grammar[node].name.clone();
+        let rule = &grammar[node].rule;
+        match lower_enum(grammar, rule) {
+            Some(variants) => {
+                let enum_src = AstEnumSrc { doc: Vec::new(), name, traits: Vec::new(), variants };
+                res.enums.push(enum_src);
+            }
+            None => {
+                let mut fields = Vec::new();
+                lower_rule(&mut fields, grammar, rule);
+                res.nodes.push(AstNodeSrc { doc: Vec::new(), name, traits: Vec::new(), fields });
+            }
+        }
+    }
+
+    deduplicate_fields(&mut res);
+    extract_enums(&mut res);
+    extract_struct_traits(&mut res);
+    extract_enum_traits(&mut res);
+    res
+}
+
+fn lower_enum(grammar: &Grammar, rule: &Rule) -> Option<Vec<String>> {
+    let alternatives = match rule {
+        Rule::Alt(it) => it,
+        _ => return None,
+    };
+    let mut variants = Vec::new();
+    for alternative in alternatives {
+        match alternative {
+            Rule::Node(it) => variants.push(grammar[*it].name.clone()),
+            _ => return None,
+        }
+    }
+    Some(variants)
+}
+
+fn lower_rule(acc: &mut Vec<Field>, grammar: &Grammar, rule: &Rule) {
+    match rule {
+        Rule::Node(node) => {
+            let field = Field::Node { name: grammar[*node].name.clone(), src: FieldSrc::Shorthand };
+            acc.push(field);
+        }
+        Rule::Token(token) => {
+            let mut name = grammar[*token].name.clone();
+            if name != "int_number" && name != "string" {
+                if "[]{}()".contains(&name) {
+                    name = format!("'{}'", name);
+                }
+                let field = Field::Token(name);
+                acc.push(field);
+            }
+        }
+        Rule::Rep(inner) => {
+            if let Rule::Node(node) = &**inner {
+                let name = grammar[*node].name.clone();
+                let label = pluralize(&to_lower_snake_case(&name));
+                let field = Field::Node { name: label.clone(), src: FieldSrc::Many(name) };
+                acc.push(field);
+                return;
+            }
+            todo!("{:?}", rule)
+        }
+        Rule::Labeled { label, rule } => {
+            let node = match &**rule {
+                Rule::Rep(inner) | Rule::Opt(inner) => match &**inner {
+                    Rule::Node(node) => node,
+                    _ => todo!("{:?}", rule),
+                },
+                Rule::Node(node) => node,
+                _ => todo!("{:?}", rule),
+            };
+            let field = Field::Node {
+                name: label.clone(),
+                src: match &**rule {
+                    Rule::Rep(_) => FieldSrc::Many(grammar[*node].name.clone()),
+                    _ => FieldSrc::Optional(grammar[*node].name.clone()),
+                },
+            };
+            acc.push(field);
+        }
+        Rule::Seq(rules) | Rule::Alt(rules) => {
+            for rule in rules {
+                lower_rule(acc, grammar, rule)
+            }
+        }
+        Rule::Opt(rule) => lower_rule(acc, grammar, rule),
+    }
+}
+
+fn deduplicate_fields(ast: &mut AstSrc) {
+    eprintln!();
+    for node in &mut ast.nodes {
+        let mut i = 0;
+        'outer: while i < node.fields.len() {
+            for j in 0..i {
+                let f1 = &node.fields[i];
+                let f2 = &node.fields[j];
+                if f1 == f2 {
+                    node.fields.remove(i);
+                    continue 'outer;
+                }
+            }
+            i += 1;
+        }
+    }
+}
+
+fn extract_enums(ast: &mut AstSrc) {
+    for node in &mut ast.nodes {
+        for enm in &ast.enums {
+            let mut to_remove = Vec::new();
+            for (i, field) in node.fields.iter().enumerate() {
+                let ty = field.ty().to_string();
+                if enm.variants.iter().any(|it| it == &ty) {
+                    to_remove.push(i);
+                }
+            }
+            if to_remove.len() == enm.variants.len() {
+                node.remove_field(to_remove);
+                node.fields.push(Field::Node { name: enm.name.clone(), src: FieldSrc::Shorthand });
+            }
+        }
+    }
+}
+
+fn extract_struct_traits(ast: &mut AstSrc) {
+    let traits: &[(&str, &[&str])] = &[
+        ("AttrsOwner", &["attrs"]),
+        ("NameOwner", &["name"]),
+        ("VisibilityOwner", &["visibility"]),
+        ("TypeParamsOwner", &["type_param_list", "where_clause"]),
+        ("TypeBoundsOwner", &["type_bound_list", "colon_token"]),
+        ("ModuleItemOwner", &["items"]),
+        ("TypeAscriptionOwner", &["ascribed_type"]),
+        ("LoopBodyOwner", &["label", "loop_body"]),
+        ("ArgListOwner", &["arg_list"]),
+    ];
+
+    for node in &mut ast.nodes {
+        for (name, methods) in traits {
+            extract_struct_trait(node, name, methods);
+        }
+    }
+}
+
+fn extract_struct_trait(node: &mut AstNodeSrc, trait_name: &str, methods: &[&str]) {
+    let mut to_remove = Vec::new();
+    for (i, field) in node.fields.iter().enumerate() {
+        let method_name = field.method_name().to_string();
+        if methods.iter().any(|&it| it == &method_name) {
+            to_remove.push(i);
+        }
+    }
+    if to_remove.len() == methods.len() {
+        node.traits.push(trait_name.to_string());
+        node.remove_field(to_remove);
+    }
+}
+
+fn extract_enum_traits(ast: &mut AstSrc) {
+    for enm in &mut ast.enums {
+        let nodes = &ast.nodes;
+        let mut variant_traits = enm
+            .variants
+            .iter()
+            .map(|var| nodes.iter().find(|it| &it.name == var).unwrap())
+            .map(|node| node.traits.iter().cloned().collect::<BTreeSet<_>>());
+
+        let mut enum_traits = match variant_traits.next() {
+            Some(it) => it,
+            None => continue,
+        };
+        for traits in variant_traits {
+            enum_traits = enum_traits.intersection(&traits).cloned().collect();
+        }
+        enm.traits = enum_traits.into_iter().collect();
+    }
+}
+
+impl AstNodeSrc {
+    fn remove_field(&mut self, to_remove: Vec<usize>) {
+        to_remove.into_iter().rev().for_each(|idx| {
+            self.fields.remove(idx);
+        });
+    }
+}
diff --git a/xtask/src/codegen/rust.ungram b/xtask/src/codegen/rust.ungram
new file mode 100644
index 00000000000..8a3eb7b291c
--- /dev/null
+++ b/xtask/src/codegen/rust.ungram
@@ -0,0 +1,529 @@
+SourceFile =
+  Attr*
+  items:ModuleItem*
+
+FnDef =
+ Attr* Visibility? Abi? 'const' 'default' 'async' 'unsafe' 'fn' Name TypeParamList?
+ ParamList RetType?
+ WhereClause?
+ (body:BlockExpr | ';')
+
+RetType =
+  '->' TypeRef
+
+StructDef =
+  Attr* Visibility? 'struct' Name TypeParamList? (
+    WhereClause?  (RecordFieldDefList | ';')
+  | TupleFieldDefList WhereClause? ';'
+  )
+
+UnionDef =
+  Attr* Visibility? 'union' Name TypeParamList? WhereClause?
+  RecordFieldDefList
+
+RecordFieldDefList =
+ '{' fields:RecordFieldDef* '}'
+
+RecordFieldDef =
+  Attr* Visibility? Name ':' ascribed_type:TypeRef
+
+TupleFieldDefList =
+  '(' fields:TupleFieldDef* ')'
+
+TupleFieldDef =
+  Attr* Visibility? Name TypeRef
+
+FieldDefList =
+  RecordFieldDefList
+| TupleFieldDefList
+
+EnumDef =
+  Attr* Visibility? 'enum' Name TypeParamList? WhereClause?
+  variant_list:EnumVariantList
+
+EnumVariantList =
+ '{' variants:EnumVariant* '}'
+
+EnumVariant =
+  Attr* Visibility? Name FieldDefList ('=' Expr)?
+
+TraitDef =
+  Attr* Visibility? 'unsafe'? 'auto'? 'trait' Name TypeParamList
+  (':' TypeBoundList?)? WhereClause
+  ItemList
+
+Module =
+  Attr* Visibility? 'mod' Name
+  (ItemList | ';')
+
+ItemList =
+  '{'
+    AssocItem*
+    items:ModuleItem*
+  '}'
+
+ConstDef =
+  Attr* Visibility? 'default'? 'const' Name ':' ascribed_type:TypeRef
+  '=' body:Expr ';'
+
+StaticDef =
+  Attr* Visibility? 'static'? 'mut'? 'static' Name ':' ascribed_type:TypeRef
+  '=' body:Expr ';'
+
+TypeAliasDef =
+  Attr* Visibility? 'default'? 'type' Name TypeParamList? WhereClause? (':' TypeBoundList?)?
+  '=' TypeRef ';'
+
+ImplDef =
+ Attr* Visibility? 'const'? 'default'? 'unsafe'? 'impl' TypeParamList? '!'? 'for'
+ WhereClause?
+ ItemList
+
+ParenType =
+  '(' TypeRef ')'
+
+TupleType =
+  '(' fields:TypeRef* ')'
+
+NeverType =
+  '!'
+
+PathType =
+  Path
+
+PointerType =
+  '*' ('const' | 'mut') TypeRef
+
+ArrayType =
+  '[' TypeRef ';' Expr ']'
+
+SliceType =
+  '[' TypeRef ']'
+
+ReferenceType =
+  '&' 'lifetime'? 'mut'? TypeRef
+
+PlaceholderType =
+   '_'
+
+FnPointerType =
+   Abi 'unsafe'? 'fn' ParamList RetType?
+
+ForType =
+   'for' TypeParamList TypeRef
+
+ImplTraitType =
+  'impl' TypeBoundList
+
+DynTraitType =
+  'dyn' TypeBoundList
+
+TupleExpr =
+  Attr* '(' Expr* ')'
+
+ArrayExpr =
+  Attr* '[' (Expr* | Expr ';' Expr) ']'
+
+ParenExpr =
+  Attr* '(' Expr ')'
+
+PathExpr =
+  Path
+
+LambdaExpr =
+  Attr* 'static'? 'async'? 'move'?  ParamList RetType?
+  body:Expr
+
+IfExpr =
+  Attr* 'if' Condition
+
+Condition =
+  'let' Pat '=' Expr
+| Expr
+
+EffectExpr =
+  Attr* Label? ('try' | 'unsafe' | 'async') BlockExpr
+
+LoopExpr =
+  Attr* Label? 'loop'
+  loop_body:BlockExpr?
+
+ForExpr =
+  Attr* Label? 'for' Pat 'in' iterable:Expr
+  loop_body:BlockExpr?
+
+WhileExpr =
+  Attr* Label? 'while' Condition
+  loop_body:BlockExpr?
+
+ContinueExpr =
+  Attr* 'continue' 'lifetime'?
+
+BreakExpr =
+  Attr* 'break' 'lifetime'? Expr?
+
+Label =
+  'lifetime'
+
+BlockExpr =
+  Attr* Label
+  '{'
+    items:ModuleItem*
+    statements:Stmt*
+    Expr?
+  '}'
+
+ReturnExpr =
+  Attr* 'return' Expr
+
+CallExpr =
+  Attr* Expr ArgList
+
+MethodCallExpr =
+  Attr* Expr '.' NameRef TypeArgList? ArgList
+
+ArgList =
+  '(' args:Expr* ')'
+
+FieldExpr =
+  Attr* Expr '.' NameRef
+
+IndexExpr =
+  Attr* '[' ']'
+
+AwaitExpr =
+  Attr* Expr '.' 'await'
+
+TryExpr =
+  Attr* Expr '?'
+
+CastExpr =
+  Attr* Expr 'as' TypeRef
+
+RefExpr =
+  Attr* '&' ('raw' | 'mut' | 'const') Expr
+
+PrefixExpr =
+  Attr* Expr
+
+BoxExpr =
+  Attr* 'box' Expr
+
+RangeExpr =
+  Attr*
+
+BinExpr =
+  Attr*
+
+Literal =
+  'int_number'
+
+MatchExpr =
+  Attr* 'match' Expr MatchArmList
+
+MatchArmList =
+  '{' arms:MatchArm* '}'
+
+MatchArm =
+  Attr* Pat guard:MatchGuard? '=>' Expr
+
+MatchGuard =
+  'if' Expr
+
+RecordLit =
+ Path RecordFieldList
+
+RecordFieldList =
+  '{'
+    fields:RecordField*
+    ('..' spread:Expr)?
+  '}'
+
+RecordField =
+  Attr* NameRef (':' Expr)?
+
+OrPat =
+  Pat*
+
+ParenPat =
+  '(' Pat ')'
+
+RefPat =
+  '&' 'mut'? Pat
+
+BoxPat =
+  'box' Path
+
+BindPat =
+  Attr* 'ref'? 'mut'? Name ('@' Pat)?
+
+PlaceholderPat =
+  '_'
+
+DotDotPat =
+  '..'
+
+PathPat =
+  Path
+
+SlicePat =
+  '[' args:Pat* ']'
+
+RangePat =
+  '..' | '..='
+
+LiteralPat =
+  Literal
+
+MacroPat =
+  MacroCall
+
+RecordPat =
+  Path RecordFieldPatList
+
+RecordFieldPatList =
+  '{'
+    record_field_pats:RecordFieldPat*
+    BindPat*
+    '..'?
+  '}'
+
+RecordFieldPat =
+  Attr* NameRef ':' Pat
+
+TupleStructPat =
+   Path '(' args:Pat* ')'
+
+TuplePat =
+   '(' args:Pat* ')'
+
+Visibility =
+  'pub' ('(' 'super' | 'self' | 'crate' | 'in' Path ')')?
+
+Name =
+  'ident'
+
+NameRef =
+  'ident' | 'int_number'
+
+MacroCall =
+  Attr* Path '!' Name? TokenTree ';'?
+
+MacroDef =
+  Name TokenTree
+
+TokenTree =
+  '(' ')' | '{' '}' | '[' ']'
+
+MacroItems =
+  items:ModuleItem*
+
+MacroStmts =
+  statements:Stmt*
+  Expr?
+
+Attr =
+  '#' '!'? '[' Path ('=' input:AttrInput)? ']'
+
+TypeParamList =
+  '<'
+    TypeParam*
+    LifetimeParam*
+    ConstParam*
+  '>'
+
+TypeParam =
+  Attr* Name (':' TypeBoundList?)?
+  ('=' default_type:TypeRef)?
+
+ConstParam =
+  Attr* 'const' Name ':' ascribed_type:TypeRef
+  ('=' default_val:Expr)?
+
+LifetimeParam =
+  Attr* 'lifetime'
+
+TypeBound =
+  'lifetime' | 'const'? TypeRef
+
+TypeBoundList =
+   bounds:TypeBound*
+
+WherePred =
+  ('for' TypeParamList)?  ('lifetime' | TypeRef) ':' TypeBoundList
+
+WhereClause =
+  'where' predicates:WherePred*
+
+Abi =
+  'string'
+
+ExprStmt =
+  Attr* Expr ';'
+
+LetStmt =
+  Attr* 'let' Pat (':' ascribed_type:TypeRef)
+  '=' initializer:Expr ';'
+
+ParamList =
+  '(' SelfParam Param* ')'
+
+SelfParam =
+  Attr* ('&' 'lifetime'?)? 'mut'? 'self' (':' ascribed_type:TypeRef)
+
+Param =
+  Attr* Pat (':' ascribed_type:TypeRef)
+| '...'
+
+UseItem =
+  Attr* Visibility? 'use' UseTree ';'
+
+UseTree =
+  Path ('::' ('*' | UseTreeList))  Alias?
+
+UseTreeList =
+  '{' UseTree* '}'
+
+Alias =
+  'as' Name
+
+ExternCrateItem =
+  Attr* Visibility? 'extern' 'crate' (NameRef | 'self') Alias? ';'
+
+Path =
+  (qualifier:Path '::')? segment:PathSegment
+
+PathSegment =
+  '::' | 'crate' | 'self' | 'super'
+| '<' NameRef TypeArgList ParamList RetType PathType '>'
+
+TypeArgList =
+  '::'? '<'
+    TypeArg*
+    LifetimeArg*
+    AssocTypeArg*
+    ConstArg*
+  '>'
+
+TypeArg =
+  TypeRef
+
+AssocTypeArg =
+  NameRef (':' TypeBoundList | '=' TypeRef)
+
+LifetimeArg =
+  'lifetime'
+
+ConstArg =
+  Literal | BlockExpr BlockExpr
+
+ExternBlock =
+  Attr* Abi ExternItemList
+
+ExternItemList =
+  '{' extern_items:ExternItem* '}'
+
+MetaItem =
+  Path '=' AttrInput nested_meta_items:MetaItem*
+
+NominalDef =
+  StructDef
+| EnumDef
+| UnionDef
+
+TypeRef =
+  ParenType
+| TupleType
+| NeverType
+| PathType
+| PointerType
+| ArrayType
+| SliceType
+| ReferenceType
+| PlaceholderType
+| FnPointerType
+| ForType
+| ImplTraitType
+| DynTraitType
+
+AssocItem =
+  FnDef
+| TypeAliasDef
+| ConstDef
+
+ExternItem =
+  FnDef | StaticDef
+
+ModuleItem =
+  StructDef
+| UnionDef
+| EnumDef
+| FnDef
+| TraitDef
+| TypeAliasDef
+| ImplDef
+| UseItem
+| ExternCrateItem
+| ConstDef
+| StaticDef
+| Module
+| MacroCall
+| ExternBlock
+
+AttrInput =
+  Literal
+| TokenTree
+
+Stmt =
+  LetStmt
+| ExprStmt
+
+Pat =
+  OrPat
+| ParenPat
+| RefPat
+| BoxPat
+| BindPat
+| PlaceholderPat
+| DotDotPat
+| PathPat
+| RecordPat
+| TupleStructPat
+| TuplePat
+| SlicePat
+| RangePat
+| LiteralPat
+| MacroPat
+
+Expr =
+  TupleExpr
+| ArrayExpr
+| ParenExpr
+| PathExpr
+| LambdaExpr
+| IfExpr
+| LoopExpr
+| ForExpr
+| WhileExpr
+| ContinueExpr
+| BreakExpr
+| Label
+| BlockExpr
+| ReturnExpr
+| MatchExpr
+| RecordLit
+| CallExpr
+| IndexExpr
+| MethodCallExpr
+| FieldExpr
+| AwaitExpr
+| TryExpr
+| EffectExpr
+| CastExpr
+| RefExpr
+| PrefixExpr
+| RangeExpr
+| BinExpr
+| Literal
+| MacroCall
+| BoxExpr