Repository: rust-analyzer/rust-analyzer
Pull request #3911 (2020-04-09 11:00:39)

Genrate token accessors
bors r+
🤖


Patch:
diff --git a/crates/ra_assists/src/handlers/add_impl.rs b/crates/ra_assists/src/handlers/add_impl.rs
index 6622eadb2d..72a201b6d2 100644
--- a/crates/ra_assists/src/handlers/add_impl.rs
+++ b/crates/ra_assists/src/handlers/add_impl.rs
@@ -1,5 +1,5 @@
 use ra_syntax::{
-    ast::{self, AstNode, NameOwner, TypeParamsOwner},
+    ast::{self, AstNode, AstToken, NameOwner, TypeParamsOwner},
     TextUnit,
 };
 use stdx::{format_to, SepBy};
@@ -42,7 +42,7 @@ pub(crate) fn add_impl(ctx: AssistCtx) -> Option<Assist> {
         if let Some(type_params) = type_params {
             let lifetime_params = type_params
                 .lifetime_params()
-                .filter_map(|it| it.lifetime_token())
+                .filter_map(|it| it.lifetime())
                 .map(|it| it.text().clone());
             let type_params =
                 type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone());
diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs
index 240b19fa37..c10397249f 100644
--- a/crates/ra_assists/src/handlers/add_new.rs
+++ b/crates/ra_assists/src/handlers/add_new.rs
@@ -1,7 +1,8 @@
 use hir::Adt;
 use ra_syntax::{
     ast::{
-        self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner,
+        self, AstNode, AstToken, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner,
+        VisibilityOwner,
     },
     TextUnit, T,
 };
@@ -105,7 +106,7 @@ fn generate_impl_text(strukt: &ast::StructDef, code: &str) -> String {
     if let Some(type_params) = type_params {
         let lifetime_params = type_params
             .lifetime_params()
-            .filter_map(|it| it.lifetime_token())
+            .filter_map(|it| it.lifetime())
             .map(|it| it.text().clone());
         let type_params =
             type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone());
diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs
index 1edbdc14c7..8a02f1a32c 100644
--- a/crates/ra_assists/src/handlers/introduce_variable.rs
+++ b/crates/ra_assists/src/handlers/introduce_variable.rs
@@ -124,7 +124,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> {
             }
         }
 
-        if ast::Stmt::cast(node.clone()).is_some() {
+        if ast::Stmt::cast(node.clone().into()).is_some() {
             return Some((node, false));
         }
 
diff --git a/crates/ra_assists/src/handlers/merge_imports.rs b/crates/ra_assists/src/handlers/merge_imports.rs
index 5d4b74e567..f8b3ddb4e1 100644
--- a/crates/ra_assists/src/handlers/merge_imports.rs
+++ b/crates/ra_assists/src/handlers/merge_imports.rs
@@ -3,7 +3,7 @@ use std::iter::successors;
 use ra_syntax::{
     algo::{neighbor, SyntaxRewriter},
     ast::{self, edit::AstNodeEdit, make},
-    AstNode, Direction, InsertPosition, SyntaxElement, T,
+    AstNode, AstToken, Direction, InsertPosition, SyntaxElement, T,
 };
 
 use crate::{Assist, AssistCtx, AssistId};
@@ -82,7 +82,7 @@ fn try_merge_trees(old: &ast::UseTree, new: &ast::UseTree) -> Option<ast::UseTre
             .filter(|it| it.kind() != T!['{'] && it.kind() != T!['}']),
     );
     let use_tree_list = lhs.use_tree_list()?;
-    let pos = InsertPosition::Before(use_tree_list.r_curly()?.into());
+    let pos = InsertPosition::Before(use_tree_list.r_curly()?.syntax().clone().into());
     let use_tree_list = use_tree_list.insert_children(pos, to_insert);
     Some(lhs.with_use_tree_list(use_tree_list))
 }
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs
index db27f9b839..0b4ba1bbe6 100644
--- a/crates/ra_fmt/src/lib.rs
+++ b/crates/ra_fmt/src/lib.rs
@@ -60,10 +60,10 @@ pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> {
     } else {
         // Unwrap `{ continue; }`
         let (stmt,) = block.statements().next_tuple()?;
-        if has_anything_else(stmt.syntax()) {
-            return None;
-        }
         if let ast::Stmt::ExprStmt(expr_stmt) = stmt {
+            if has_anything_else(expr_stmt.syntax()) {
+                return None;
+            }
             let expr = expr_stmt.expr()?;
             match expr.syntax().kind() {
                 CONTINUE_EXPR | BREAK_EXPR | RETURN_EXPR => return Some(expr),
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 8d4b8b0f0f..b02de5d67d 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -482,14 +482,16 @@ impl ExprCollector<'_> {
         self.collect_block_items(&block);
         let statements = block
             .statements()
-            .map(|s| match s {
+            .filter_map(|s| match s {
                 ast::Stmt::LetStmt(stmt) => {
                     let pat = self.collect_pat_opt(stmt.pat());
                     let type_ref = stmt.ascribed_type().map(TypeRef::from_ast);
                     let initializer = stmt.initializer().map(|e| self.collect_expr(e));
-                    Statement::Let { pat, type_ref, initializer }
+                    Some(Statement::Let { pat, type_ref, initializer })
+                }
+                ast::Stmt::ExprStmt(stmt) => {
+                    Some(Statement::Expr(self.collect_expr_opt(stmt.expr())))
                 }
-                ast::Stmt::ExprStmt(stmt) => Statement::Expr(self.collect_expr_opt(stmt.expr())),
             })
             .collect();
         let tail = block.expr().map(|e| self.collect_expr(e));
@@ -541,6 +543,7 @@ impl ExprCollector<'_> {
                     let ast_id = self.expander.ast_id(&def);
                     (TraitLoc { container, ast_id }.intern(self.db).into(), def.name())
                 }
+                ast::ModuleItem::ExternBlock(_) => continue, // FIXME: collect from extern blocks
                 ast::ModuleItem::ImplDef(_)
                 | ast::ModuleItem::UseItem(_)
                 | ast::ModuleItem::ExternCrateItem(_)
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 8f190e7f91..a9dff3a5d5 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -266,6 +266,10 @@ impl RawItemsCollector {
                 self.add_macro(current_module, it);
                 return;
             }
+            ast::ModuleItem::ExternBlock(_) => {
+                // FIXME: add extern block
+                return;
+            }
         };
         if let Some(name) = name {
             let name = name.as_name();
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
index 4900000fe4..3c13cb2c78 100644
--- a/crates/ra_hir_def/src/path/lower.rs
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -28,7 +28,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
     loop {
         let segment = path.segment()?;
 
-        if segment.has_colon_colon() {
+        if segment.coloncolon().is_some() {
             kind = PathKind::Abs;
         }
 
diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs
index 278d5196e7..6ec944228c 100644
--- a/crates/ra_hir_def/src/path/lower/lower_use.rs
+++ b/crates/ra_hir_def/src/path/lower/lower_use.rs
@@ -34,7 +34,7 @@ pub(crate) fn lower_use_tree(
         let alias = tree.alias().map(|a| {
             a.name().map(|it| it.as_name()).map_or(ImportAlias::Underscore, ImportAlias::Alias)
         });
-        let is_glob = tree.has_star();
+        let is_glob = tree.star().is_some();
         if let Some(ast_path) = tree.path() {
             // Handle self in a path.
             // E.g. `use something::{self, <...>}`
diff --git a/crates/ra_hir_def/src/visibility.rs b/crates/ra_hir_def/src/visibility.rs
index 62513873ef..1482d3be04 100644
--- a/crates/ra_hir_def/src/visibility.rs
+++ b/crates/ra_hir_def/src/visibility.rs
@@ -84,6 +84,10 @@ impl RawVisibility {
                 let path = ModPath { kind: PathKind::Super(1), segments: Vec::new() };
                 RawVisibility::Module(path)
             }
+            ast::VisibilityKind::PubSelf => {
+                let path = ModPath { kind: PathKind::Plain, segments: Vec::new() };
+                RawVisibility::Module(path)
+            }
             ast::VisibilityKind::Pub => RawVisibility::Public,
         }
     }
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index 4c16cf1cd9..004f4e5643 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -105,6 +105,7 @@ pub enum SyntaxKind {
     DEFAULT_KW,
     EXISTENTIAL_KW,
     UNION_KW,
+    RAW_KW,
     INT_NUMBER,
     FLOAT_NUMBER,
     CHAR,
@@ -258,7 +259,7 @@ impl SyntaxKind {
             | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW
             | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | STATIC_KW | STRUCT_KW | SUPER_KW
             | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW | WHERE_KW | WHILE_KW
-            | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW => true,
+            | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW | RAW_KW => true,
             _ => false,
         }
     }
@@ -651,4 +652,7 @@ macro_rules! T {
     ( union ) => {
         $crate::SyntaxKind::UNION_KW
     };
+    ( raw ) => {
+        $crate::SyntaxKind::RAW_KW
+    };
 }
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index ab0f44dd2e..e1ebd5b928 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -64,6 +64,22 @@ pub trait AstToken {
     }
 }
 
+mod support {
+    use super::{AstChildren, AstNode, AstToken, SyntaxNode};
+
+    pub(super) fn child<N: AstNode>(parent: &SyntaxNode) -> Option<N> {
+        parent.children().find_map(N::cast)
+    }
+
+    pub(super) fn children<N: AstNode>(parent: &SyntaxNode) -> AstChildren<N> {
+        AstChildren::new(parent)
+    }
+
+    pub(super) fn token<T: AstToken>(parent: &SyntaxNode) -> Option<T> {
+        parent.children_with_tokens().filter_map(|it| it.into_token()).find_map(T::cast)
+    }
+}
+
 /// An iterator over `SyntaxNode` children of a particular AST type.
 #[derive(Debug, Clone)]
 pub struct AstChildren<N> {
@@ -271,7 +287,7 @@ where
     let pred = predicates.next().unwrap();
     let mut bounds = pred.type_bound_list().unwrap().bounds();
 
-    assert_eq!("'a", pred.lifetime_token().unwrap().text());
+    assert_eq!("'a", pred.lifetime().unwrap().text());
 
     assert_bound("'b", bounds.next());
     assert_bound("'c", bounds.next());
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
index b69cae234c..d793109953 100644
--- a/crates/ra_syntax/src/ast/edit.rs
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -99,7 +99,7 @@ impl ast::ItemList {
             None => match self.l_curly() {
                 Some(it) => (
                     "    ".to_string() + &leading_indent(self.syntax()).unwrap_or_default(),
-                    InsertPosition::After(it),
+                    InsertPosition::After(it.syntax().clone().into()),
                 ),
                 None => return self.clone(),
             },
@@ -109,10 +109,6 @@ impl ast::ItemList {
             [ws.ws().into(), item.syntax().clone().into()].into();
         self.insert_children(position, to_insert)
     }
-
-    fn l_curly(&self) -> Option<SyntaxElement> {
-        self.syntax().children_with_tokens().find(|it| it.kind() == T!['{'])
-    }
 }
 
 impl ast::RecordFieldList {
@@ -147,7 +143,7 @@ impl ast::RecordFieldList {
         macro_rules! after_l_curly {
             () => {{
                 let anchor = match self.l_curly() {
-                    Some(it) => it,
+                    Some(it) => it.syntax().clone().into(),
                     None => return self.clone(),
                 };
                 InsertPosition::After(anchor)
@@ -189,24 +185,20 @@ impl ast::RecordFieldList {
 
         self.insert_children(position, to_insert)
     }
-
-    fn l_curly(&self) -> Option<SyntaxElement> {
-        self.syntax().children_with_tokens().find(|it| it.kind() == T!['{'])
-    }
 }
 
 impl ast::TypeParam {
     #[must_use]
     pub fn remove_bounds(&self) -> ast::TypeParam {
-        let colon = match self.colon_token() {
+        let colon = match self.colon() {
             Some(it) => it,
             None => return self.clone(),
         };
         let end = match self.type_bound_list() {
             Some(it) => it.syntax().clone().into(),
-            None => colon.clone().into(),
+            None => colon.syntax().clone().into(),
         };
-        self.replace_children(colon.into()..=end, iter::empty())
+        self.replace_children(colon.syntax().clone().into()..=end, iter::empty())
     }
 }
 
@@ -305,8 +297,12 @@ impl ast::UseTree {
             Some(it) => it,
             None => return self.clone(),
         };
-        let use_tree =
-            make::use_tree(suffix.clone(), self.use_tree_list(), self.alias(), self.has_star());
+        let use_tree = make::use_tree(
+            suffix.clone(),
+            self.use_tree_list(),
+            self.alias(),
+            self.star().is_some(),
+        );
         let nested = make::use_tree_list(iter::once(use_tree));
         return make::use_tree(prefix.clone(), Some(nested), None, false);
 
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs
index 8bbd946c07..40c8fca3be 100644
--- a/crates/ra_syntax/src/ast/expr_extensions.rs
+++ b/crates/ra_syntax/src/ast/expr_extensions.rs
@@ -52,6 +52,10 @@ impl ast::RefExpr {
     pub fn is_mut(&self) -> bool {
         self.syntax().children_with_tokens().any(|n| n.kind() == T![mut])
     }
+
+    pub fn raw_token(&self) -> Option<SyntaxToken> {
+        None // FIXME: implement &raw
+    }
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index bf7d137be7..33fe60762a 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -4,7 +4,9 @@
 use itertools::Itertools;
 
 use crate::{
-    ast::{self, child_opt, children, AstNode, AttrInput, NameOwner, SyntaxNode},
+    ast::{
+        self, child_opt, children, support, AstNode, AstToken, AttrInput, NameOwner, SyntaxNode,
+    },
     SmolStr, SyntaxElement,
     SyntaxKind::*,
     SyntaxToken, T,
@@ -130,13 +132,6 @@ impl ast::PathSegment {
         };
         Some(res)
     }
-
-    pub fn has_colon_colon(&self) -> bool {
-        match self.syntax.first_child_or_token().map(|s| s.kind()) {
-            Some(T![::]) => true,
-            _ => false,
-        }
-    }
 }
 
 impl ast::Path {
@@ -154,12 +149,6 @@ impl ast::Module {
     }
 }
 
-impl ast::UseTree {
-    pub fn has_star(&self) -> bool {
-        self.syntax().children_with_tokens().any(|it| it.kind() == T![*])
-    }
-}
-
 impl ast::UseTreeList {
     pub fn parent_use_tree(&self) -> ast::UseTree {
         self.syntax()
@@ -167,20 +156,6 @@ impl ast::UseTreeList {
             .and_then(ast::UseTree::cast)
             .expect("UseTreeLists are always nested in UseTrees")
     }
-    pub fn l_curly(&self) -> Option<SyntaxToken> {
-        self.token(T!['{'])
-    }
-
-    pub fn r_curly(&self) -> Option<SyntaxToken> {
-        self.token(T!['}'])
-    }
-
-    fn token(&self, kind: SyntaxKind) -> Option<SyntaxToken> {
-        self.syntax()
-            .children_with_tokens()
-            .filter_map(|it| it.into_token())
-            .find(|it| it.kind() == kind)
-    }
 }
 
 impl ast::ImplDef {
@@ -387,24 +362,9 @@ pub enum SelfParamKind {
 }
 
 impl ast::SelfParam {
-    pub fn self_kw_token(&self) -> SyntaxToken {
-        self.syntax()
-            .children_with_tokens()
-            .filter_map(|it| it.into_token())
-            .find(|it| it.kind() == T![self])
-            .expect("invalid tree: self param must have self")
-    }
-
     pub fn kind(&self) -> SelfParamKind {
-        let borrowed = self.syntax().children_with_tokens().any(|n| n.kind() == T![&]);
-        if borrowed {
-            // check for a `mut` coming after the & -- `mut &self` != `&mut self`
-            if self
-                .syntax()
-                .children_with_tokens()
-                .skip_while(|n| n.kind() != T![&])
-                .any(|n| n.kind() == T![mut])
-            {
+        if self.amp().is_some() {
+            if self.amp_mut_kw().is_some() {
                 SelfParamKind::MutRef
             } else {
                 SelfParamKind::Ref
@@ -413,32 +373,23 @@ impl ast::SelfParam {
             SelfParamKind::Owned
         }
     }
-}
 
-impl ast::LifetimeParam {
-    pub fn lifetime_token(&self) -> Option<SyntaxToken> {
+    /// the "mut" in "mut self", not the one in "&mut self"
+    pub fn mut_kw(&self) -> Option<ast::MutKw> {
         self.syntax()
             .children_with_tokens()
             .filter_map(|it| it.into_token())
-            .find(|it| it.kind() == LIFETIME)
+            .take_while(|it| it.kind() != T![&])
+            .find_map(ast::MutKw::cast)
     }
-}
 
-impl ast::TypeParam {
-    pub fn colon_token(&self) -> Option<SyntaxToken> {
+    /// the "mut" in "&mut self", not the one in "mut self"
+    pub fn amp_mut_kw(&self) -> Option<ast::MutKw> {
         self.syntax()
             .children_with_tokens()
             .filter_map(|it| it.into_token())
-            .find(|it| it.kind() == T![:])
-    }
-}
-
-impl ast::WherePred {
-    pub fn lifetime_token(&self) -> Option<SyntaxToken> {
-        self.syntax()
-            .children_with_tokens()
-            .filter_map(|it| it.into_token())
-            .find(|it| it.kind() == LIFETIME)
+            .skip_while(|it| it.kind() != T![&])
+            .find_map(ast::MutKw::cast)
     }
 }
 
@@ -449,7 +400,7 @@ pub enum TypeBoundKind {
     /// for<'a> ...
     ForType(ast::ForType),
     /// 'a
-    Lifetime(ast::SyntaxToken),
+    Lifetime(ast::Lifetime),
 }
 
 impl ast::TypeBound {
@@ -465,21 +416,28 @@ impl ast::TypeBound {
         }
     }
 
-    fn lifetime(&self) -> Option<SyntaxToken> {
-        self.syntax()
-            .children_with_tokens()
-            .filter_map(|it| it.into_token())
-            .find(|it| it.kind() == LIFETIME)
+    pub fn has_question_mark(&self) -> bool {
+        self.question().is_some()
     }
 
-    pub fn question_mark_token(&self) -> Option<SyntaxToken> {
+    pub fn const_question(&self) -> Option<ast::Question> {
         self.syntax()
             .children_with_tokens()
             .filter_map(|it| it.into_token())
-            .find(|it| it.kind() == T![?])
+            .take_while(|it| it.kind() != T![const])
+            .find_map(ast::Question::cast)
     }
-    pub fn has_question_mark(&self) -> bool {
-        self.question_mark_token().is_some()
+
+    pub fn question(&self) -> Option<ast::Question> {
+        if self.const_kw().is_some() {
+            self.syntax()
+                .children_with_tokens()
+                .filter_map(|it| it.into_token())
+                .skip_while(|it| it.kind() != T![const])
+                .find_map(ast::Question::cast)
+        } else {
+            support::token(&self.syntax)
+        }
     }
 }
 
@@ -493,6 +451,7 @@ pub enum VisibilityKind {
     In(ast::Path),
     PubCrate,
     PubSuper,
+    PubSelf,
     Pub,
 }
 
@@ -504,6 +463,8 @@ impl ast::Visibility {
             VisibilityKind::PubCrate
         } else if self.is_pub_super() {
             VisibilityKind::PubSuper
+        } else if self.is_pub_self() {
+            VisibilityKind::PubSuper
         } else {
             VisibilityKind::Pub
         }
@@ -516,6 +477,10 @@ impl ast::Visibility {
     fn is_pub_super(&self) -> bool {
         self.syntax().children_with_tokens().any(|it| it.kind() == T![super])
     }
+
+    fn is_pub_self(&self) -> bool {
+        self.syntax().children_with_tokens().any(|it| it.kind() == T![self])
+    }
 }
 
 impl ast::MacroCall {
@@ -528,3 +493,41 @@ impl ast::MacroCall {
         }
     }
 }
+
+impl ast::LifetimeParam {
+    pub fn lifetime_bounds(&self) -> impl Iterator<Item = ast::Lifetime> {
+        self.syntax()
+            .children_with_tokens()
+            .filter_map(|it| it.into_token())
+            .skip_while(|x| x.kind() != T![:])
+            .filter_map(ast::Lifetime::cast)
+    }
+}
+
+impl ast::RangePat {
+    pub fn start(&self) -> Option<ast::Pat> {
+        self.syntax()
+            .children_with_tokens()
+            .take_while(|it| !ast::RangeSeparator::can_cast(it.kind()))
+            .filter_map(|it| it.into_node())
+            .find_map(ast::Pat::cast)
+    }
+
+    pub fn end(&self) -> Option<ast::Pat> {
+        self.syntax()
+            .children_with_tokens()
+            .skip_while(|it| !ast::RangeSeparator::can_cast(it.kind()))
+            .filter_map(|it| it.into_node())
+            .find_map(ast::Pat::cast)
+    }
+}
+
+impl ast::TokenTree {
+    pub fn left_delimiter(&self) -> Option<ast::LeftDelimiter> {
+        self.syntax().first_child_or_token()?.into_token().and_then(ast::LeftDelimiter::cast)
+    }
+
+    pub fn right_delimiter(&self) -> Option<ast::RightDelimiter> {
+        self.syntax().last_child_or_token()?.into_token().and_then(ast::RightDelimiter::cast)
+    }
+}
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index 385fddc89e..bd92e9c874 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -2,7 +2,7 @@
 
 #[allow(unused_imports)]
 use crate::{
-    ast::{self, AstChildren, AstNode, AstToken},
+    ast::{self, support, AstChildren, AstNode, AstToken},
     NodeOrToken, SyntaxElement,
     SyntaxKind::{self, *},
     SyntaxNode, SyntaxToken,
@@ -2600,6 +2600,33 @@ impl AstToken for UnionKw {
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct RawKw {
+    pub(crate) syntax: SyntaxToken,
+}
+impl std::fmt::Display for RawKw {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(&self.syntax, f)
+    }
+}
+impl AstToken for RawKw {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            RAW_KW => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxToken) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxToken {
+        &self.syntax
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct IntNumber {
     pub(crate) syntax: SyntaxToken,
 }
@@ -3060,9 +3087,10 @@ impl AstNode for SourceFile {
 }
 impl ast::ModuleItemOwner for SourceFile {}
 impl ast::FnDefOwner for SourceFile {}
+impl ast::AttrsOwner for SourceFile {}
 impl SourceFile {
     pub fn modules(&self) -> AstChildren<Module> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3098,14 +3126,35 @@ 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_kw(&self) -> Option<ConstKw> {
+        support::token(&self.syntax)
+    }
+    pub fn default_kw(&self) -> Option<DefaultKw> {
+        support::token(&self.syntax)
+    }
+    pub fn async_kw(&self) -> Option<AsyncKw> {
+        support::token(&self.syntax)
+    }
+    pub fn unsafe_kw(&self) -> Option<UnsafeKw> {
+        support::token(&self.syntax)
+    }
+    pub fn fn_kw(&self) -> Option<FnKw> {
+        support::token(&self.syntax)
+    }
     pub fn param_list(&self) -> Option<ParamList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn ret_type(&self) -> Option<RetType> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn body(&self) -> Option<BlockExpr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn semi(&self) -> Option<Semi> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3136,8 +3185,11 @@ impl AstNode for RetType {
     }
 }
 impl RetType {
+    pub fn thin_arrow(&self) -> Option<ThinArrow> {
+        support::token(&self.syntax)
+    }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3172,7 +3224,17 @@ impl ast::NameOwner for StructDef {}
 impl ast::TypeParamsOwner for StructDef {}
 impl ast::AttrsOwner for StructDef {}
 impl ast::DocCommentsOwner for StructDef {}
-impl StructDef {}
+impl StructDef {
+    pub fn struct_kw(&self) -> Option<StructKw> {
+        support::token(&self.syntax)
+    }
+    pub fn field_def_list(&self) -> Option<FieldDefList> {
+        support::child(&self.syntax)
+    }
+    pub fn semi(&self) -> Option<Semi> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct UnionDef {
     pub(crate) syntax: SyntaxNode,
@@ -3206,8 +3268,11 @@ impl ast::TypeParamsOwner for UnionDef {}
 impl ast::AttrsOwner for UnionDef {}
 impl ast::DocCommentsOwner for UnionDef {}
 impl UnionDef {
+    pub fn union_kw(&self) -> Option<UnionKw> {
+        support::token(&self.syntax)
+    }
     pub fn record_field_def_list(&self) -> Option<RecordFieldDefList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3238,8 +3303,14 @@ impl AstNode for RecordFieldDefList {
     }
 }
 impl RecordFieldDefList {
+    pub fn l_curly(&self) -> Option<LCurly> {
+        support::token(&self.syntax)
+    }
     pub fn fields(&self) -> AstChildren<RecordFieldDef> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_curly(&self) -> Option<RCurly> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3303,8 +3374,14 @@ impl AstNode for TupleFieldDefList {
     }
 }
 impl TupleFieldDefList {
+    pub fn l_paren(&self) -> Option<LParen> {
+        support::token(&self.syntax)
+    }
     pub fn fields(&self) -> AstChildren<TupleFieldDef> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_paren(&self) -> Option<RParen> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3338,7 +3415,7 @@ impl ast::VisibilityOwner for TupleFieldDef {}
 impl ast::AttrsOwner for TupleFieldDef {}
 impl TupleFieldDef {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3374,8 +3451,11 @@ impl ast::TypeParamsOwner for EnumDef {}
 impl ast::AttrsOwner for EnumDef {}
 impl ast::DocCommentsOwner for EnumDef {}
 impl EnumDef {
+    pub fn enum_kw(&self) -> Option<EnumKw> {
+        support::token(&self.syntax)
+    }
     pub fn variant_list(&self) -> Option<EnumVariantList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3406,8 +3486,14 @@ impl AstNode for EnumVariantList {
     }
 }
 impl EnumVariantList {
+    pub fn l_curly(&self) -> Option<LCurly> {
+        support::token(&self.syntax)
+    }
     pub fn variants(&self) -> AstChildren<EnumVariant> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_curly(&self) -> Option<RCurly> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3437,12 +3523,19 @@ impl AstNode for EnumVariant {
         &self.syntax
     }
 }
+impl ast::VisibilityOwner for EnumVariant {}
 impl ast::NameOwner for EnumVariant {}
 impl ast::DocCommentsOwner for EnumVariant {}
 impl ast::AttrsOwner for EnumVariant {}
 impl EnumVariant {
+    pub fn field_def_list(&self) -> Option<FieldDefList> {
+        support::child(&self.syntax)
+    }
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
+    }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3479,8 +3572,17 @@ impl ast::DocCommentsOwner for TraitDef {}
 impl ast::TypeParamsOwner for TraitDef {}
 impl ast::TypeBoundsOwner for TraitDef {}
 impl TraitDef {
+    pub fn unsafe_kw(&self) -> Option<UnsafeKw> {
+        support::token(&self.syntax)
+    }
+    pub fn auto_kw(&self) -> Option<AutoKw> {
+        support::token(&self.syntax)
+    }
+    pub fn trait_kw(&self) -> Option<TraitKw> {
+        support::token(&self.syntax)
+    }
     pub fn item_list(&self) -> Option<ItemList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3515,8 +3617,14 @@ impl ast::NameOwner for Module {}
 impl ast::AttrsOwner for Module {}
 impl ast::DocCommentsOwner for Module {}
 impl Module {
+    pub fn mod_kw(&self) -> Option<ModKw> {
+        support::token(&self.syntax)
+    }
     pub fn item_list(&self) -> Option<ItemList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn semi(&self) -> Option<Semi> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3549,8 +3657,14 @@ impl AstNode for ItemList {
 impl ast::FnDefOwner for ItemList {}
 impl ast::ModuleItemOwner for ItemList {}
 impl ItemList {
+    pub fn l_curly(&self) -> Option<LCurly> {
+        support::token(&self.syntax)
+    }
     pub fn impl_items(&self) -> AstChildren<ImplItem> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_curly(&self) -> Option<RCurly> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3587,8 +3701,20 @@ impl ast::AttrsOwner for ConstDef {}
 impl ast::DocCommentsOwner for ConstDef {}
 impl ast::TypeAscriptionOwner for ConstDef {}
 impl ConstDef {
+    pub fn default_kw(&self) -> Option<DefaultKw> {
+        support::token(&self.syntax)
+    }
+    pub fn const_kw(&self) -> Option<ConstKw> {
+        support::token(&self.syntax)
+    }
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
+    }
     pub fn body(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn semi(&self) -> Option<Semi> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3625,8 +3751,20 @@ impl ast::AttrsOwner for StaticDef {}
 impl ast::DocCommentsOwner for StaticDef {}
 impl ast::TypeAscriptionOwner for StaticDef {}
 impl StaticDef {
+    pub fn static_kw(&self) -> Option<StaticKw> {
+        support::token(&self.syntax)
+    }
+    pub fn mut_kw(&self) -> Option<MutKw> {
+        support::token(&self.syntax)
+    }
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
+    }
     pub fn body(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn semi(&self) -> Option<Semi> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3663,8 +3801,20 @@ impl ast::AttrsOwner for TypeAliasDef {}
 impl ast::DocCommentsOwner for TypeAliasDef {}
 impl ast::TypeBoundsOwner for TypeAliasDef {}
 impl TypeAliasDef {
+    pub fn default_kw(&self) -> Option<DefaultKw> {
+        support::token(&self.syntax)
+    }
+    pub fn type_kw(&self) -> Option<TypeKw> {
+        support::token(&self.syntax)
+    }
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
+    }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn semi(&self) -> Option<Semi> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3697,8 +3847,26 @@ impl AstNode for ImplDef {
 impl ast::TypeParamsOwner for ImplDef {}
 impl ast::AttrsOwner for ImplDef {}
 impl ImplDef {
+    pub fn default_kw(&self) -> Option<DefaultKw> {
+        support::token(&self.syntax)
+    }
+    pub fn const_kw(&self) -> Option<ConstKw> {
+        support::token(&self.syntax)
+    }
+    pub fn unsafe_kw(&self) -> Option<UnsafeKw> {
+        support::token(&self.syntax)
+    }
+    pub fn impl_kw(&self) -> Option<ImplKw> {
+        support::token(&self.syntax)
+    }
+    pub fn excl(&self) -> Option<Excl> {
+        support::token(&self.syntax)
+    }
+    pub fn for_kw(&self) -> Option<ForKw> {
+        support::token(&self.syntax)
+    }
     pub fn item_list(&self) -> Option<ItemList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3729,8 +3897,14 @@ impl AstNode for ParenType {
     }
 }
 impl ParenType {
+    pub fn l_paren(&self) -> Option<LParen> {
+        support::token(&self.syntax)
+    }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn r_paren(&self) -> Option<RParen> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3761,8 +3935,14 @@ impl AstNode for TupleType {
     }
 }
 impl TupleType {
+    pub fn l_paren(&self) -> Option<LParen> {
+        support::token(&self.syntax)
+    }
     pub fn fields(&self) -> AstChildren<TypeRef> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_paren(&self) -> Option<RParen> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3792,7 +3972,11 @@ impl AstNode for NeverType {
         &self.syntax
     }
 }
-impl NeverType {}
+impl NeverType {
+    pub fn excl(&self) -> Option<Excl> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PathType {
     pub(crate) syntax: SyntaxNode,
@@ -3822,7 +4006,7 @@ impl AstNode for PathType {
 }
 impl PathType {
     pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3853,8 +4037,14 @@ impl AstNode for PointerType {
     }
 }
 impl PointerType {
+    pub fn star(&self) -> Option<Star> {
+        support::token(&self.syntax)
+    }
+    pub fn const_kw(&self) -> Option<ConstKw> {
+        support::token(&self.syntax)
+    }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3885,11 +4075,20 @@ impl AstNode for ArrayType {
     }
 }
 impl ArrayType {
+    pub fn l_brack(&self) -> Option<LBrack> {
+        support::token(&self.syntax)
+    }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn semi(&self) -> Option<Semi> {
+        support::token(&self.syntax)
     }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn r_brack(&self) -> Option<RBrack> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3920,8 +4119,14 @@ impl AstNode for SliceType {
     }
 }
 impl SliceType {
+    pub fn l_brack(&self) -> Option<LBrack> {
+        support::token(&self.syntax)
+    }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn r_brack(&self) -> Option<RBrack> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3952,8 +4157,17 @@ impl AstNode for ReferenceType {
     }
 }
 impl ReferenceType {
+    pub fn amp(&self) -> Option<Amp> {
+        support::token(&self.syntax)
+    }
+    pub fn lifetime(&self) -> Option<Lifetime> {
+        support::token(&self.syntax)
+    }
+    pub fn mut_kw(&self) -> Option<MutKw> {
+        support::token(&self.syntax)
+    }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -3983,7 +4197,11 @@ impl AstNode for PlaceholderType {
         &self.syntax
     }
 }
-impl PlaceholderType {}
+impl PlaceholderType {
+    pub fn underscore(&self) -> Option<Underscore> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FnPointerType {
     pub(crate) syntax: SyntaxNode,
@@ -4012,11 +4230,20 @@ impl AstNode for FnPointerType {
     }
 }
 impl FnPointerType {
+    pub fn abi(&self) -> Option<Abi> {
+        support::child(&self.syntax)
+    }
+    pub fn unsafe_kw(&self) -> Option<UnsafeKw> {
+        support::token(&self.syntax)
+    }
+    pub fn fn_kw(&self) -> Option<FnKw> {
+        support::token(&self.syntax)
+    }
     pub fn param_list(&self) -> Option<ParamList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn ret_type(&self) -> Option<RetType> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4047,8 +4274,14 @@ impl AstNode for ForType {
     }
 }
 impl ForType {
+    pub fn for_kw(&self) -> Option<ForKw> {
+        support::token(&self.syntax)
+    }
+    pub fn type_param_list(&self) -> Option<TypeParamList> {
+        support::child(&self.syntax)
+    }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4079,7 +4312,11 @@ impl AstNode for ImplTraitType {
     }
 }
 impl ast::TypeBoundsOwner for ImplTraitType {}
-impl ImplTraitType {}
+impl ImplTraitType {
+    pub fn impl_kw(&self) -> Option<ImplKw> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct DynTraitType {
     pub(crate) syntax: SyntaxNode,
@@ -4108,7 +4345,11 @@ impl AstNode for DynTraitType {
     }
 }
 impl ast::TypeBoundsOwner for DynTraitType {}
-impl DynTraitType {}
+impl DynTraitType {
+    pub fn dyn_kw(&self) -> Option<DynKw> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TupleExpr {
     pub(crate) syntax: SyntaxNode,
@@ -4136,9 +4377,16 @@ impl AstNode for TupleExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for TupleExpr {}
 impl TupleExpr {
+    pub fn l_paren(&self) -> Option<LParen> {
+        support::token(&self.syntax)
+    }
     pub fn exprs(&self) -> AstChildren<Expr> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_paren(&self) -> Option<RParen> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4168,9 +4416,19 @@ impl AstNode for ArrayExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for ArrayExpr {}
 impl ArrayExpr {
+    pub fn l_brack(&self) -> Option<LBrack> {
+        support::token(&self.syntax)
+    }
     pub fn exprs(&self) -> AstChildren<Expr> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn semi(&self) -> Option<Semi> {
+        support::token(&self.syntax)
+    }
+    pub fn r_brack(&self) -> Option<RBrack> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4200,9 +4458,16 @@ impl AstNode for ParenExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for ParenExpr {}
 impl ParenExpr {
+    pub fn l_paren(&self) -> Option<LParen> {
+        support::token(&self.syntax)
+    }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn r_paren(&self) -> Option<RParen> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4234,7 +4499,7 @@ impl AstNode for PathExpr {
 }
 impl PathExpr {
     pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4264,15 +4529,25 @@ impl AstNode for LambdaExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for LambdaExpr {}
 impl LambdaExpr {
+    pub fn static_kw(&self) -> Option<StaticKw> {
+        support::token(&self.syntax)
+    }
+    pub fn async_kw(&self) -> Option<AsyncKw> {
+        support::token(&self.syntax)
+    }
+    pub fn move_kw(&self) -> Option<MoveKw> {
+        support::token(&self.syntax)
+    }
     pub fn param_list(&self) -> Option<ParamList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn ret_type(&self) -> Option<RetType> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn body(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4302,9 +4577,13 @@ impl AstNode for IfExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for IfExpr {}
 impl IfExpr {
+    pub fn if_kw(&self) -> Option<IfKw> {
+        support::token(&self.syntax)
+    }
     pub fn condition(&self) -> Option<Condition> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4334,8 +4613,13 @@ impl AstNode for LoopExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for LoopExpr {}
 impl ast::LoopBodyOwner for LoopExpr {}
-impl LoopExpr {}
+impl LoopExpr {
+    pub fn loop_kw(&self) -> Option<LoopKw> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TryBlockExpr {
     pub(crate) syntax: SyntaxNode,
@@ -4363,9 +4647,13 @@ impl AstNode for TryBlockExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for TryBlockExpr {}
 impl TryBlockExpr {
+    pub fn try_kw(&self) -> Option<TryKw> {
+        support::token(&self.syntax)
+    }
     pub fn body(&self) -> Option<BlockExpr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4395,13 +4683,20 @@ impl AstNode for ForExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for ForExpr {}
 impl ast::LoopBodyOwner for ForExpr {}
 impl ForExpr {
+    pub fn for_kw(&self) -> Option<ForKw> {
+        support::token(&self.syntax)
+    }
     pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn in_kw(&self) -> Option<InKw> {
+        support::token(&self.syntax)
     }
     pub fn iterable(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4431,10 +4726,14 @@ impl AstNode for WhileExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for WhileExpr {}
 impl ast::LoopBodyOwner for WhileExpr {}
 impl WhileExpr {
+    pub fn while_kw(&self) -> Option<WhileKw> {
+        support::token(&self.syntax)
+    }
     pub fn condition(&self) -> Option<Condition> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4464,7 +4763,15 @@ impl AstNode for ContinueExpr {
         &self.syntax
     }
 }
-impl ContinueExpr {}
+impl ast::AttrsOwner for ContinueExpr {}
+impl ContinueExpr {
+    pub fn continue_kw(&self) -> Option<ContinueKw> {
+        support::token(&self.syntax)
+    }
+    pub fn lifetime(&self) -> Option<Lifetime> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BreakExpr {
     pub(crate) syntax: SyntaxNode,
@@ -4492,9 +4799,16 @@ impl AstNode for BreakExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for BreakExpr {}
 impl BreakExpr {
+    pub fn break_kw(&self) -> Option<BreakKw> {
+        support::token(&self.syntax)
+    }
+    pub fn lifetime(&self) -> Option<Lifetime> {
+        support::token(&self.syntax)
+    }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4524,7 +4838,11 @@ impl AstNode for Label {
         &self.syntax
     }
 }
-impl Label {}
+impl Label {
+    pub fn lifetime(&self) -> Option<Lifetime> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BlockExpr {
     pub(crate) syntax: SyntaxNode,
@@ -4552,9 +4870,16 @@ impl AstNode for BlockExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for BlockExpr {}
 impl BlockExpr {
+    pub fn label(&self) -> Option<Label> {
+        support::child(&self.syntax)
+    }
+    pub fn unsafe_kw(&self) -> Option<UnsafeKw> {
+        support::token(&self.syntax)
+    }
     pub fn block(&self) -> Option<Block> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4584,9 +4909,10 @@ impl AstNode for ReturnExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for ReturnExpr {}
 impl ReturnExpr {
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4619,7 +4945,7 @@ impl AstNode for CallExpr {
 impl ast::ArgListOwner for CallExpr {}
 impl CallExpr {
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4649,16 +4975,20 @@ impl AstNode for MethodCallExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for MethodCallExpr {}
 impl ast::ArgListOwner for MethodCallExpr {}
 impl MethodCallExpr {
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn dot(&self) -> Option<Dot> {
+        support::token(&self.syntax)
     }
     pub fn name_ref(&self) -> Option<NameRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn type_arg_list(&self) -> Option<TypeArgList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4688,7 +5018,15 @@ impl AstNode for IndexExpr {
         &self.syntax
     }
 }
-impl IndexExpr {}
+impl ast::AttrsOwner for IndexExpr {}
+impl IndexExpr {
+    pub fn l_brack(&self) -> Option<LBrack> {
+        support::token(&self.syntax)
+    }
+    pub fn r_brack(&self) -> Option<RBrack> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FieldExpr {
     pub(crate) syntax: SyntaxNode,
@@ -4716,12 +5054,16 @@ impl AstNode for FieldExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for FieldExpr {}
 impl FieldExpr {
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn dot(&self) -> Option<Dot> {
+        support::token(&self.syntax)
     }
     pub fn name_ref(&self) -> Option<NameRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4751,9 +5093,16 @@ impl AstNode for AwaitExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for AwaitExpr {}
 impl AwaitExpr {
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn dot(&self) -> Option<Dot> {
+        support::token(&self.syntax)
+    }
+    pub fn await_kw(&self) -> Option<AwaitKw> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4783,9 +5132,13 @@ impl AstNode for TryExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for TryExpr {}
 impl TryExpr {
+    pub fn try_kw(&self) -> Option<TryKw> {
+        support::token(&self.syntax)
+    }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4815,12 +5168,16 @@ impl AstNode for CastExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for CastExpr {}
 impl CastExpr {
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn as_kw(&self) -> Option<AsKw> {
+        support::token(&self.syntax)
     }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4850,9 +5207,19 @@ impl AstNode for RefExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for RefExpr {}
 impl RefExpr {
+    pub fn amp(&self) -> Option<Amp> {
+        support::token(&self.syntax)
+    }
+    pub fn raw_kw(&self) -> Option<RawKw> {
+        support::token(&self.syntax)
+    }
+    pub fn mut_kw(&self) -> Option<MutKw> {
+        support::token(&self.syntax)
+    }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4882,9 +5249,13 @@ impl AstNode for PrefixExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for PrefixExpr {}
 impl PrefixExpr {
+    pub fn prefix_op(&self) -> Option<PrefixOp> {
+        support::token(&self.syntax)
+    }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4914,9 +5285,13 @@ impl AstNode for BoxExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for BoxExpr {}
 impl BoxExpr {
+    pub fn box_kw(&self) -> Option<BoxKw> {
+        support::token(&self.syntax)
+    }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -4946,7 +5321,12 @@ impl AstNode for RangeExpr {
         &self.syntax
     }
 }
-impl RangeExpr {}
+impl ast::AttrsOwner for RangeExpr {}
+impl RangeExpr {
+    pub fn range_op(&self) -> Option<RangeOp> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BinExpr {
     pub(crate) syntax: SyntaxNode,
@@ -4974,7 +5354,12 @@ impl AstNode for BinExpr {
         &self.syntax
     }
 }
-impl BinExpr {}
+impl ast::AttrsOwner for BinExpr {}
+impl BinExpr {
+    pub fn bin_op(&self) -> Option<BinOp> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Literal {
     pub(crate) syntax: SyntaxNode,
@@ -5002,7 +5387,11 @@ impl AstNode for Literal {
         &self.syntax
     }
 }
-impl Literal {}
+impl Literal {
+    pub fn literal_token(&self) -> Option<LiteralToken> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MatchExpr {
     pub(crate) syntax: SyntaxNode,
@@ -5030,12 +5419,16 @@ impl AstNode for MatchExpr {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for MatchExpr {}
 impl MatchExpr {
+    pub fn match_kw(&self) -> Option<MatchKw> {
+        support::token(&self.syntax)
+    }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn match_arm_list(&self) -> Option<MatchArmList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5067,8 +5460,14 @@ impl AstNode for MatchArmList {
 }
 impl ast::AttrsOwner for MatchArmList {}
 impl MatchArmList {
+    pub fn l_curly(&self) -> Option<LCurly> {
+        support::token(&self.syntax)
+    }
     pub fn arms(&self) -> AstChildren<MatchArm> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_curly(&self) -> Option<RCurly> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5101,13 +5500,16 @@ impl AstNode for MatchArm {
 impl ast::AttrsOwner for MatchArm {}
 impl MatchArm {
     pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn guard(&self) -> Option<MatchGuard> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn fat_arrow(&self) -> Option<FatArrow> {
+        support::token(&self.syntax)
     }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5138,8 +5540,11 @@ impl AstNode for MatchGuard {
     }
 }
 impl MatchGuard {
+    pub fn if_kw(&self) -> Option<IfKw> {
+        support::token(&self.syntax)
+    }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5171,10 +5576,10 @@ impl AstNode for RecordLit {
 }
 impl RecordLit {
     pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn record_field_list(&self) -> Option<RecordFieldList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5205,11 +5610,20 @@ impl AstNode for RecordFieldList {
     }
 }
 impl RecordFieldList {
+    pub fn l_curly(&self) -> Option<LCurly> {
+        support::token(&self.syntax)
+    }
     pub fn fields(&self) -> AstChildren<RecordField> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn dotdot(&self) -> Option<Dotdot> {
+        support::token(&self.syntax)
     }
     pub fn spread(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn r_curly(&self) -> Option<RCurly> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5239,12 +5653,16 @@ impl AstNode for RecordField {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for RecordField {}
 impl RecordField {
     pub fn name_ref(&self) -> Option<NameRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn colon(&self) -> Option<Colon> {
+        support::token(&self.syntax)
     }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5276,7 +5694,7 @@ impl AstNode for OrPat {
 }
 impl OrPat {
     pub fn pats(&self) -> AstChildren<Pat> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5307,8 +5725,14 @@ impl AstNode for ParenPat {
     }
 }
 impl ParenPat {
+    pub fn l_paren(&self) -> Option<LParen> {
+        support::token(&self.syntax)
+    }
     pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn r_paren(&self) -> Option<RParen> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5339,8 +5763,14 @@ impl AstNode for RefPat {
     }
 }
 impl RefPat {
+    pub fn amp(&self) -> Option<Amp> {
+        support::token(&self.syntax)
+    }
+    pub fn mut_kw(&self) -> Option<MutKw> {
+        support::token(&self.syntax)
+    }
     pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5371,8 +5801,11 @@ impl AstNode for BoxPat {
     }
 }
 impl BoxPat {
+    pub fn box_kw(&self) -> Option<BoxKw> {
+        support::token(&self.syntax)
+    }
     pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5402,10 +5835,17 @@ impl AstNode for BindPat {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for BindPat {}
 impl ast::NameOwner for BindPat {}
 impl BindPat {
+    pub fn ref_kw(&self) -> Option<RefKw> {
+        support::token(&self.syntax)
+    }
+    pub fn mut_kw(&self) -> Option<MutKw> {
+        support::token(&self.syntax)
+    }
     pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5435,7 +5875,11 @@ impl AstNode for PlaceholderPat {
         &self.syntax
     }
 }
-impl PlaceholderPat {}
+impl PlaceholderPat {
+    pub fn underscore(&self) -> Option<Underscore> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct DotDotPat {
     pub(crate) syntax: SyntaxNode,
@@ -5463,7 +5907,11 @@ impl AstNode for DotDotPat {
         &self.syntax
     }
 }
-impl DotDotPat {}
+impl DotDotPat {
+    pub fn dotdot(&self) -> Option<Dotdot> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PathPat {
     pub(crate) syntax: SyntaxNode,
@@ -5493,7 +5941,7 @@ impl AstNode for PathPat {
 }
 impl PathPat {
     pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5524,8 +5972,14 @@ impl AstNode for SlicePat {
     }
 }
 impl SlicePat {
+    pub fn l_brack(&self) -> Option<LBrack> {
+        support::token(&self.syntax)
+    }
     pub fn args(&self) -> AstChildren<Pat> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_brack(&self) -> Option<RBrack> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5555,7 +6009,11 @@ impl AstNode for RangePat {
         &self.syntax
     }
 }
-impl RangePat {}
+impl RangePat {
+    pub fn range_separator(&self) -> Option<RangeSeparator> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LiteralPat {
     pub(crate) syntax: SyntaxNode,
@@ -5585,7 +6043,7 @@ impl AstNode for LiteralPat {
 }
 impl LiteralPat {
     pub fn literal(&self) -> Option<Literal> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5617,7 +6075,7 @@ impl AstNode for MacroPat {
 }
 impl MacroPat {
     pub fn macro_call(&self) -> Option<MacroCall> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5649,10 +6107,10 @@ impl AstNode for RecordPat {
 }
 impl RecordPat {
     pub fn record_field_pat_list(&self) -> Option<RecordFieldPatList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5683,11 +6141,23 @@ impl AstNode for RecordFieldPatList {
     }
 }
 impl RecordFieldPatList {
+    pub fn l_curly(&self) -> Option<LCurly> {
+        support::token(&self.syntax)
+    }
+    pub fn pats(&self) -> AstChildren<RecordInnerPat> {
+        support::children(&self.syntax)
+    }
     pub fn record_field_pats(&self) -> AstChildren<RecordFieldPat> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
     }
     pub fn bind_pats(&self) -> AstChildren<BindPat> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn dotdot(&self) -> Option<Dotdot> {
+        support::token(&self.syntax)
+    }
+    pub fn r_curly(&self) -> Option<RCurly> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5717,10 +6187,14 @@ impl AstNode for RecordFieldPat {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for RecordFieldPat {}
 impl ast::NameOwner for RecordFieldPat {}
 impl RecordFieldPat {
+    pub fn colon(&self) -> Option<Colon> {
+        support::token(&self.syntax)
+    }
     pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5752,10 +6226,16 @@ impl AstNode for TupleStructPat {
 }
 impl TupleStructPat {
     pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn l_paren(&self) -> Option<LParen> {
+        support::token(&self.syntax)
     }
     pub fn args(&self) -> AstChildren<Pat> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_paren(&self) -> Option<RParen> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5786,8 +6266,14 @@ impl AstNode for TuplePat {
     }
 }
 impl TuplePat {
+    pub fn l_paren(&self) -> Option<LParen> {
+        support::token(&self.syntax)
+    }
     pub fn args(&self) -> AstChildren<Pat> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_paren(&self) -> Option<RParen> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5817,7 +6303,20 @@ impl AstNode for Visibility {
         &self.syntax
     }
 }
-impl Visibility {}
+impl Visibility {
+    pub fn pub_kw(&self) -> Option<PubKw> {
+        support::token(&self.syntax)
+    }
+    pub fn super_kw(&self) -> Option<SuperKw> {
+        support::token(&self.syntax)
+    }
+    pub fn self_kw(&self) -> Option<SelfKw> {
+        support::token(&self.syntax)
+    }
+    pub fn crate_kw(&self) -> Option<CrateKw> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Name {
     pub(crate) syntax: SyntaxNode,
@@ -5845,7 +6344,11 @@ impl AstNode for Name {
         &self.syntax
     }
 }
-impl Name {}
+impl Name {
+    pub fn ident(&self) -> Option<Ident> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct NameRef {
     pub(crate) syntax: SyntaxNode,
@@ -5873,7 +6376,11 @@ impl AstNode for NameRef {
         &self.syntax
     }
 }
-impl NameRef {}
+impl NameRef {
+    pub fn name_ref_token(&self) -> Option<NameRefToken> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MacroCall {
     pub(crate) syntax: SyntaxNode,
@@ -5905,11 +6412,17 @@ 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(&self) -> Option<Excl> {
+        support::token(&self.syntax)
+    }
     pub fn token_tree(&self) -> Option<TokenTree> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
-    pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+    pub fn semi(&self) -> Option<Semi> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -5940,11 +6453,26 @@ impl AstNode for Attr {
     }
 }
 impl Attr {
+    pub fn pound(&self) -> Option<Pound> {
+        support::token(&self.syntax)
+    }
+    pub fn excl(&self) -> Option<Excl> {
+        support::token(&self.syntax)
+    }
+    pub fn l_brack(&self) -> Option<LBrack> {
+        support::token(&self.syntax)
+    }
     pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
     }
     pub fn input(&self) -> Option<AttrInput> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn r_brack(&self) -> Option<RBrack> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6003,11 +6531,23 @@ impl AstNode for TypeParamList {
     }
 }
 impl TypeParamList {
+    pub fn l_angle(&self) -> Option<LAngle> {
+        support::token(&self.syntax)
+    }
+    pub fn generic_params(&self) -> AstChildren<GenericParam> {
+        support::children(&self.syntax)
+    }
     pub fn type_params(&self) -> AstChildren<TypeParam> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
     }
     pub fn lifetime_params(&self) -> AstChildren<LifetimeParam> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn const_params(&self) -> AstChildren<ConstParam> {
+        support::children(&self.syntax)
+    }
+    pub fn r_angle(&self) -> Option<RAngle> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6041,8 +6581,11 @@ impl ast::NameOwner for TypeParam {}
 impl ast::AttrsOwner for TypeParam {}
 impl ast::TypeBoundsOwner for TypeParam {}
 impl TypeParam {
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
+    }
     pub fn default_type(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6076,8 +6619,11 @@ impl ast::NameOwner for ConstParam {}
 impl ast::AttrsOwner for ConstParam {}
 impl ast::TypeAscriptionOwner for ConstParam {}
 impl ConstParam {
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
+    }
     pub fn default_val(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6108,7 +6654,11 @@ impl AstNode for LifetimeParam {
     }
 }
 impl ast::AttrsOwner for LifetimeParam {}
-impl LifetimeParam {}
+impl LifetimeParam {
+    pub fn lifetime(&self) -> Option<Lifetime> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeBound {
     pub(crate) syntax: SyntaxNode,
@@ -6137,8 +6687,14 @@ impl AstNode for TypeBound {
     }
 }
 impl TypeBound {
+    pub fn lifetime(&self) -> Option<Lifetime> {
+        support::token(&self.syntax)
+    }
+    pub fn const_kw(&self) -> Option<ConstKw> {
+        support::token(&self.syntax)
+    }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6170,7 +6726,7 @@ impl AstNode for TypeBoundList {
 }
 impl TypeBoundList {
     pub fn bounds(&self) -> AstChildren<TypeBound> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6202,8 +6758,11 @@ impl AstNode for WherePred {
 }
 impl ast::TypeBoundsOwner for WherePred {}
 impl WherePred {
+    pub fn lifetime(&self) -> Option<Lifetime> {
+        support::token(&self.syntax)
+    }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6234,8 +6793,43 @@ impl AstNode for WhereClause {
     }
 }
 impl WhereClause {
+    pub fn where_kw(&self) -> Option<WhereKw> {
+        support::token(&self.syntax)
+    }
     pub fn predicates(&self) -> AstChildren<WherePred> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct Abi {
+    pub(crate) syntax: SyntaxNode,
+}
+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 AstNode for Abi {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            ABI => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
+    }
+}
+impl Abi {
+    pub fn string(&self) -> Option<String> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6265,9 +6859,13 @@ impl AstNode for ExprStmt {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for ExprStmt {}
 impl ExprStmt {
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn semi(&self) -> Option<Semi> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6297,13 +6895,20 @@ impl AstNode for LetStmt {
         &self.syntax
     }
 }
+impl ast::AttrsOwner for LetStmt {}
 impl ast::TypeAscriptionOwner for LetStmt {}
 impl LetStmt {
+    pub fn let_kw(&self) -> Option<LetKw> {
+        support::token(&self.syntax)
+    }
     pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
     }
     pub fn initializer(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6334,11 +6939,17 @@ impl AstNode for Condition {
     }
 }
 impl Condition {
+    pub fn let_kw(&self) -> Option<LetKw> {
+        support::token(&self.syntax)
+    }
     pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
     }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6371,11 +6982,17 @@ impl AstNode for Block {
 impl ast::AttrsOwner for Block {}
 impl ast::ModuleItemOwner for Block {}
 impl Block {
+    pub fn l_curly(&self) -> Option<LCurly> {
+        support::token(&self.syntax)
+    }
     pub fn statements(&self) -> AstChildren<Stmt> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
     }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn r_curly(&self) -> Option<RCurly> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6406,11 +7023,17 @@ impl AstNode for ParamList {
     }
 }
 impl ParamList {
+    pub fn l_paren(&self) -> Option<LParen> {
+        support::token(&self.syntax)
+    }
     pub fn self_param(&self) -> Option<SelfParam> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn params(&self) -> AstChildren<Param> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_paren(&self) -> Option<RParen> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6442,7 +7065,17 @@ impl AstNode for SelfParam {
 }
 impl ast::TypeAscriptionOwner for SelfParam {}
 impl ast::AttrsOwner for SelfParam {}
-impl SelfParam {}
+impl SelfParam {
+    pub fn amp(&self) -> Option<Amp> {
+        support::token(&self.syntax)
+    }
+    pub fn lifetime(&self) -> Option<Lifetime> {
+        support::token(&self.syntax)
+    }
+    pub fn self_kw(&self) -> Option<SelfKw> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Param {
     pub(crate) syntax: SyntaxNode,
@@ -6474,7 +7107,10 @@ impl ast::TypeAscriptionOwner for Param {}
 impl ast::AttrsOwner for Param {}
 impl Param {
     pub fn pat(&self) -> Option<Pat> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn dotdotdot(&self) -> Option<Dotdotdot> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6507,8 +7143,11 @@ impl AstNode for UseItem {
 impl ast::AttrsOwner for UseItem {}
 impl ast::VisibilityOwner for UseItem {}
 impl UseItem {
+    pub fn use_kw(&self) -> Option<UseKw> {
+        support::token(&self.syntax)
+    }
     pub fn use_tree(&self) -> Option<UseTree> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6540,13 +7179,16 @@ impl AstNode for UseTree {
 }
 impl UseTree {
     pub fn path(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn star(&self) -> Option<Star> {
+        support::token(&self.syntax)
     }
     pub fn use_tree_list(&self) -> Option<UseTreeList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn alias(&self) -> Option<Alias> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6577,7 +7219,11 @@ impl AstNode for Alias {
     }
 }
 impl ast::NameOwner for Alias {}
-impl Alias {}
+impl Alias {
+    pub fn as_kw(&self) -> Option<AsKw> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct UseTreeList {
     pub(crate) syntax: SyntaxNode,
@@ -6606,8 +7252,14 @@ impl AstNode for UseTreeList {
     }
 }
 impl UseTreeList {
+    pub fn l_curly(&self) -> Option<LCurly> {
+        support::token(&self.syntax)
+    }
     pub fn use_trees(&self) -> AstChildren<UseTree> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_curly(&self) -> Option<RCurly> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6640,11 +7292,17 @@ impl AstNode for ExternCrateItem {
 impl ast::AttrsOwner for ExternCrateItem {}
 impl ast::VisibilityOwner for ExternCrateItem {}
 impl ExternCrateItem {
+    pub fn extern_kw(&self) -> Option<ExternKw> {
+        support::token(&self.syntax)
+    }
+    pub fn crate_kw(&self) -> Option<CrateKw> {
+        support::token(&self.syntax)
+    }
     pub fn name_ref(&self) -> Option<NameRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn alias(&self) -> Option<Alias> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6675,8 +7333,14 @@ impl AstNode for ArgList {
     }
 }
 impl ArgList {
+    pub fn l_paren(&self) -> Option<LParen> {
+        support::token(&self.syntax)
+    }
     pub fn args(&self) -> AstChildren<Expr> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn r_paren(&self) -> Option<RParen> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6708,10 +7372,10 @@ impl AstNode for Path {
 }
 impl Path {
     pub fn segment(&self) -> Option<PathSegment> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn qualifier(&self) -> Option<Path> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6742,20 +7406,29 @@ impl AstNode for PathSegment {
     }
 }
 impl PathSegment {
-    pub fn name_ref(&self) -> Option<NameRef> {
-        AstChildren::new(&self.syntax).next()
+    pub fn coloncolon(&self) -> Option<Coloncolon> {
+        support::token(&self.syntax)
+    }
+    pub fn l_angle(&self) -> Option<LAngle> {
+        support::token(&self.syntax)
+    }
+    pub fn name_ref(&self) -> Option<NameRef> {
+        support::child(&self.syntax)
     }
     pub fn type_arg_list(&self) -> Option<TypeArgList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn param_list(&self) -> Option<ParamList> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn ret_type(&self) -> Option<RetType> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
     pub fn path_type(&self) -> Option<PathType> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn r_angle(&self) -> Option<RAngle> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6786,17 +7459,29 @@ impl AstNode for TypeArgList {
     }
 }
 impl TypeArgList {
+    pub fn coloncolon(&self) -> Option<Coloncolon> {
+        support::token(&self.syntax)
+    }
+    pub fn l_angle(&self) -> Option<LAngle> {
+        support::token(&self.syntax)
+    }
+    pub fn generic_args(&self) -> AstChildren<GenericArg> {
+        support::children(&self.syntax)
+    }
     pub fn type_args(&self) -> AstChildren<TypeArg> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
     }
     pub fn lifetime_args(&self) -> AstChildren<LifetimeArg> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
     }
     pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
+    }
+    pub fn const_args(&self) -> AstChildren<ConstArg> {
+        support::children(&self.syntax)
     }
-    pub fn const_arg(&self) -> AstChildren<ConstArg> {
-        AstChildren::new(&self.syntax)
+    pub fn r_angle(&self) -> Option<RAngle> {
+        support::token(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6828,7 +7513,7 @@ impl AstNode for TypeArg {
 }
 impl TypeArg {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6858,12 +7543,16 @@ impl AstNode for AssocTypeArg {
         &self.syntax
     }
 }
+impl ast::TypeBoundsOwner for AssocTypeArg {}
 impl AssocTypeArg {
     pub fn name_ref(&self) -> Option<NameRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
     }
     pub fn type_ref(&self) -> Option<TypeRef> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6893,7 +7582,11 @@ impl AstNode for LifetimeArg {
         &self.syntax
     }
 }
-impl LifetimeArg {}
+impl LifetimeArg {
+    pub fn lifetime(&self) -> Option<Lifetime> {
+        support::token(&self.syntax)
+    }
+}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ConstArg {
     pub(crate) syntax: SyntaxNode,
@@ -6923,10 +7616,13 @@ impl AstNode for ConstArg {
 }
 impl ConstArg {
     pub fn literal(&self) -> Option<Literal> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
     }
     pub fn block_expr(&self) -> Option<BlockExpr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -6988,10 +7684,161 @@ impl AstNode for MacroStmts {
 }
 impl MacroStmts {
     pub fn statements(&self) -> AstChildren<Stmt> {
-        AstChildren::new(&self.syntax)
+        support::children(&self.syntax)
     }
     pub fn expr(&self) -> Option<Expr> {
-        AstChildren::new(&self.syntax).next()
+        support::child(&self.syntax)
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct ExternItemList {
+    pub(crate) syntax: SyntaxNode,
+}
+impl std::fmt::Display for ExternItemList {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstNode for ExternItemList {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            EXTERN_ITEM_LIST => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
+    }
+}
+impl ast::FnDefOwner for ExternItemList {}
+impl ast::ModuleItemOwner for ExternItemList {}
+impl ExternItemList {
+    pub fn l_curly(&self) -> Option<LCurly> {
+        support::token(&self.syntax)
+    }
+    pub fn extern_items(&self) -> AstChildren<ExternItem> {
+        support::children(&self.syntax)
+    }
+    pub fn r_curly(&self) -> Option<RCurly> {
+        support::token(&self.syntax)
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct ExternBlock {
+    pub(crate) syntax: SyntaxNode,
+}
+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 AstNode for ExternBlock {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            EXTERN_BLOCK => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
+    }
+}
+impl ExternBlock {
+    pub fn abi(&self) -> Option<Abi> {
+        support::child(&self.syntax)
+    }
+    pub fn extern_item_list(&self) -> Option<ExternItemList> {
+        support::child(&self.syntax)
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct MetaItem {
+    pub(crate) syntax: SyntaxNode,
+}
+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 AstNode for MetaItem {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            META_ITEM => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
+    }
+}
+impl MetaItem {
+    pub fn path(&self) -> Option<Path> {
+        support::child(&self.syntax)
+    }
+    pub fn eq(&self) -> Option<Eq> {
+        support::token(&self.syntax)
+    }
+    pub fn attr_input(&self) -> Option<AttrInput> {
+        support::child(&self.syntax)
+    }
+    pub fn nested_meta_items(&self) -> AstChildren<MetaItem> {
+        support::children(&self.syntax)
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct MacroDef {
+    pub(crate) syntax: SyntaxNode,
+}
+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 AstNode for MacroDef {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            MACRO_DEF => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
+    }
+}
+impl MacroDef {
+    pub fn name(&self) -> Option<Name> {
+        support::child(&self.syntax)
+    }
+    pub fn token_tree(&self) -> Option<TokenTree> {
+        support::child(&self.syntax)
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -7048,6 +7895,114 @@ impl ast::NameOwner for NominalDef {}
 impl ast::TypeParamsOwner for NominalDef {}
 impl ast::AttrsOwner for NominalDef {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum GenericParam {
+    LifetimeParam(LifetimeParam),
+    TypeParam(TypeParam),
+    ConstParam(ConstParam),
+}
+impl From<LifetimeParam> for GenericParam {
+    fn from(node: LifetimeParam) -> GenericParam {
+        GenericParam::LifetimeParam(node)
+    }
+}
+impl From<TypeParam> for GenericParam {
+    fn from(node: TypeParam) -> GenericParam {
+        GenericParam::TypeParam(node)
+    }
+}
+impl From<ConstParam> for GenericParam {
+    fn from(node: ConstParam) -> GenericParam {
+        GenericParam::ConstParam(node)
+    }
+}
+impl std::fmt::Display for GenericParam {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstNode for GenericParam {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            LIFETIME_PARAM | TYPE_PARAM | CONST_PARAM => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        let res = match syntax.kind() {
+            LIFETIME_PARAM => GenericParam::LifetimeParam(LifetimeParam { syntax }),
+            TYPE_PARAM => GenericParam::TypeParam(TypeParam { syntax }),
+            CONST_PARAM => GenericParam::ConstParam(ConstParam { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            GenericParam::LifetimeParam(it) => &it.syntax,
+            GenericParam::TypeParam(it) => &it.syntax,
+            GenericParam::ConstParam(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum GenericArg {
+    LifetimeArg(LifetimeArg),
+    TypeArg(TypeArg),
+    ConstArg(ConstArg),
+    AssocTypeArg(AssocTypeArg),
+}
+impl From<LifetimeArg> for GenericArg {
+    fn from(node: LifetimeArg) -> GenericArg {
+        GenericArg::LifetimeArg(node)
+    }
+}
+impl From<TypeArg> for GenericArg {
+    fn from(node: TypeArg) -> GenericArg {
+        GenericArg::TypeArg(node)
+    }
+}
+impl From<ConstArg> for GenericArg {
+    fn from(node: ConstArg) -> GenericArg {
+        GenericArg::ConstArg(node)
+    }
+}
+impl From<AssocTypeArg> for GenericArg {
+    fn from(node: AssocTypeArg) -> GenericArg {
+        GenericArg::AssocTypeArg(node)
+    }
+}
+impl std::fmt::Display for GenericArg {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstNode for GenericArg {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            LIFETIME_ARG | TYPE_ARG | CONST_ARG | ASSOC_TYPE_ARG => 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 }),
+            _ => 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,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum TypeRef {
     ParenType(ParenType),
     TupleType(TupleType),
@@ -7194,6 +8149,7 @@ pub enum ModuleItem {
     StaticDef(StaticDef),
     Module(Module),
     MacroCall(MacroCall),
+    ExternBlock(ExternBlock),
 }
 impl From<StructDef> for ModuleItem {
     fn from(node: StructDef) -> ModuleItem {
@@ -7260,6 +8216,11 @@ impl From<MacroCall> for ModuleItem {
         ModuleItem::MacroCall(node)
     }
 }
+impl From<ExternBlock> for ModuleItem {
+    fn from(node: ExternBlock) -> ModuleItem {
+        ModuleItem::ExternBlock(node)
+    }
+}
 impl std::fmt::Display for ModuleItem {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -7269,7 +8230,8 @@ 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 => true,
+            | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE | MACRO_CALL
+            | EXTERN_BLOCK => true,
             _ => false,
         }
     }
@@ -7288,6 +8250,7 @@ impl AstNode for ModuleItem {
             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)
@@ -7307,9 +8270,11 @@ impl AstNode for ModuleItem {
             ModuleItem::StaticDef(it) => &it.syntax,
             ModuleItem::Module(it) => &it.syntax,
             ModuleItem::MacroCall(it) => &it.syntax,
+            ModuleItem::ExternBlock(it) => &it.syntax,
         }
     }
 }
+impl ast::NameOwner for ModuleItem {}
 impl ast::AttrsOwner for ModuleItem {}
 impl ast::VisibilityOwner for ModuleItem {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -7362,8 +8327,54 @@ impl AstNode for ImplItem {
         }
     }
 }
+impl ast::NameOwner for ImplItem {}
 impl ast::AttrsOwner for ImplItem {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum ExternItem {
+    FnDef(FnDef),
+    StaticDef(StaticDef),
+}
+impl From<FnDef> for ExternItem {
+    fn from(node: FnDef) -> ExternItem {
+        ExternItem::FnDef(node)
+    }
+}
+impl From<StaticDef> for ExternItem {
+    fn from(node: StaticDef) -> ExternItem {
+        ExternItem::StaticDef(node)
+    }
+}
+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 AstNode for ExternItem {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            FN_DEF | STATIC_DEF => 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 }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            ExternItem::FnDef(it) => &it.syntax,
+            ExternItem::StaticDef(it) => &it.syntax,
+        }
+    }
+}
+impl ast::NameOwner for ExternItem {}
+impl ast::AttrsOwner for ExternItem {}
+impl ast::VisibilityOwner for ExternItem {}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Expr {
     TupleExpr(TupleExpr),
     ArrayExpr(ArrayExpr),
@@ -7642,6 +8653,7 @@ impl AstNode for Expr {
         }
     }
 }
+impl ast::AttrsOwner for Expr {}
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Pat {
     OrPat(OrPat),
@@ -7791,6 +8803,48 @@ impl AstNode for Pat {
     }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum RecordInnerPat {
+    RecordFieldPat(RecordFieldPat),
+    BindPat(BindPat),
+}
+impl From<RecordFieldPat> for RecordInnerPat {
+    fn from(node: RecordFieldPat) -> RecordInnerPat {
+        RecordInnerPat::RecordFieldPat(node)
+    }
+}
+impl From<BindPat> for RecordInnerPat {
+    fn from(node: BindPat) -> RecordInnerPat {
+        RecordInnerPat::BindPat(node)
+    }
+}
+impl std::fmt::Display for RecordInnerPat {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstNode for RecordInnerPat {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            RECORD_FIELD_PAT | BIND_PAT => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        let res = match syntax.kind() {
+            RECORD_FIELD_PAT => RecordInnerPat::RecordFieldPat(RecordFieldPat { syntax }),
+            BIND_PAT => RecordInnerPat::BindPat(BindPat { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            RecordInnerPat::RecordFieldPat(it) => &it.syntax,
+            RecordInnerPat::BindPat(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum AttrInput {
     Literal(Literal),
     TokenTree(TokenTree),
@@ -7834,19 +8888,19 @@ impl AstNode for AttrInput {
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum Stmt {
-    ExprStmt(ExprStmt),
     LetStmt(LetStmt),
-}
-impl From<ExprStmt> for Stmt {
-    fn from(node: ExprStmt) -> Stmt {
-        Stmt::ExprStmt(node)
-    }
+    ExprStmt(ExprStmt),
 }
 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 std::fmt::Display for Stmt {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -7855,22 +8909,717 @@ impl std::fmt::Display for Stmt {
 impl AstNode for Stmt {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-            EXPR_STMT | LET_STMT => true,
+            LET_STMT | EXPR_STMT => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         let res = match syntax.kind() {
-            EXPR_STMT => Stmt::ExprStmt(ExprStmt { syntax }),
             LET_STMT => Stmt::LetStmt(LetStmt { syntax }),
+            EXPR_STMT => Stmt::ExprStmt(ExprStmt { syntax }),
             _ => return None,
         };
         Some(res)
     }
     fn syntax(&self) -> &SyntaxNode {
         match self {
-            Stmt::ExprStmt(it) => &it.syntax,
             Stmt::LetStmt(it) => &it.syntax,
+            Stmt::ExprStmt(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum LeftDelimiter {
+    LParen(LParen),
+    LBrack(LBrack),
+    LCurly(LCurly),
+}
+impl From<LParen> for LeftDelimiter {
+    fn from(node: LParen) -> LeftDelimiter {
+        LeftDelimiter::LParen(node)
+    }
+}
+impl From<LBrack> for LeftDelimiter {
+    fn from(node: LBrack) -> LeftDelimiter {
+        LeftDelimiter::LBrack(node)
+    }
+}
+impl From<LCurly> for LeftDelimiter {
+    fn from(node: LCurly) -> LeftDelimiter {
+        LeftDelimiter::LCurly(node)
+    }
+}
+impl std::fmt::Display for LeftDelimiter {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstToken for LeftDelimiter {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            L_PAREN | L_BRACK | L_CURLY => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxToken) -> Option<Self> {
+        let res = match syntax.kind() {
+            L_PAREN => LeftDelimiter::LParen(LParen { syntax }),
+            L_BRACK => LeftDelimiter::LBrack(LBrack { syntax }),
+            L_CURLY => LeftDelimiter::LCurly(LCurly { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxToken {
+        match self {
+            LeftDelimiter::LParen(it) => &it.syntax,
+            LeftDelimiter::LBrack(it) => &it.syntax,
+            LeftDelimiter::LCurly(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum RightDelimiter {
+    RParen(RParen),
+    RBrack(RBrack),
+    RCurly(RCurly),
+}
+impl From<RParen> for RightDelimiter {
+    fn from(node: RParen) -> RightDelimiter {
+        RightDelimiter::RParen(node)
+    }
+}
+impl From<RBrack> for RightDelimiter {
+    fn from(node: RBrack) -> RightDelimiter {
+        RightDelimiter::RBrack(node)
+    }
+}
+impl From<RCurly> for RightDelimiter {
+    fn from(node: RCurly) -> RightDelimiter {
+        RightDelimiter::RCurly(node)
+    }
+}
+impl std::fmt::Display for RightDelimiter {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstToken for RightDelimiter {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            R_PAREN | R_BRACK | R_CURLY => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxToken) -> Option<Self> {
+        let res = match syntax.kind() {
+            R_PAREN => RightDelimiter::RParen(RParen { syntax }),
+            R_BRACK => RightDelimiter::RBrack(RBrack { syntax }),
+            R_CURLY => RightDelimiter::RCurly(RCurly { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxToken {
+        match self {
+            RightDelimiter::RParen(it) => &it.syntax,
+            RightDelimiter::RBrack(it) => &it.syntax,
+            RightDelimiter::RCurly(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum RangeSeparator {
+    Dotdot(Dotdot),
+    Dotdotdot(Dotdotdot),
+    Dotdoteq(Dotdoteq),
+}
+impl From<Dotdot> for RangeSeparator {
+    fn from(node: Dotdot) -> RangeSeparator {
+        RangeSeparator::Dotdot(node)
+    }
+}
+impl From<Dotdotdot> for RangeSeparator {
+    fn from(node: Dotdotdot) -> RangeSeparator {
+        RangeSeparator::Dotdotdot(node)
+    }
+}
+impl From<Dotdoteq> for RangeSeparator {
+    fn from(node: Dotdoteq) -> RangeSeparator {
+        RangeSeparator::Dotdoteq(node)
+    }
+}
+impl std::fmt::Display for RangeSeparator {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstToken for RangeSeparator {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            DOTDOT | DOTDOTDOT | DOTDOTEQ => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxToken) -> Option<Self> {
+        let res = match syntax.kind() {
+            DOTDOT => RangeSeparator::Dotdot(Dotdot { syntax }),
+            DOTDOTDOT => RangeSeparator::Dotdotdot(Dotdotdot { syntax }),
+            DOTDOTEQ => RangeSeparator::Dotdoteq(Dotdoteq { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxToken {
+        match self {
+            RangeSeparator::Dotdot(it) => &it.syntax,
+            RangeSeparator::Dotdotdot(it) => &it.syntax,
+            RangeSeparator::Dotdoteq(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum BinOp {
+    Pipepipe(Pipepipe),
+    Ampamp(Ampamp),
+    Eqeq(Eqeq),
+    Neq(Neq),
+    Lteq(Lteq),
+    Gteq(Gteq),
+    LAngle(LAngle),
+    RAngle(RAngle),
+    Plus(Plus),
+    Star(Star),
+    Minus(Minus),
+    Slash(Slash),
+    Percent(Percent),
+    Shl(Shl),
+    Shr(Shr),
+    Caret(Caret),
+    Pipe(Pipe),
+    Amp(Amp),
+    Eq(Eq),
+    Pluseq(Pluseq),
+    Slasheq(Slasheq),
+    Stareq(Stareq),
+    Percenteq(Percenteq),
+    Shreq(Shreq),
+    Shleq(Shleq),
+    Minuseq(Minuseq),
+    Pipeeq(Pipeeq),
+    Ampeq(Ampeq),
+    Careteq(Careteq),
+}
+impl From<Pipepipe> for BinOp {
+    fn from(node: Pipepipe) -> BinOp {
+        BinOp::Pipepipe(node)
+    }
+}
+impl From<Ampamp> for BinOp {
+    fn from(node: Ampamp) -> BinOp {
+        BinOp::Ampamp(node)
+    }
+}
+impl From<Eqeq> for BinOp {
+    fn from(node: Eqeq) -> BinOp {
+        BinOp::Eqeq(node)
+    }
+}
+impl From<Neq> for BinOp {
+    fn from(node: Neq) -> BinOp {
+        BinOp::Neq(node)
+    }
+}
+impl From<Lteq> for BinOp {
+    fn from(node: Lteq) -> BinOp {
+        BinOp::Lteq(node)
+    }
+}
+impl From<Gteq> for BinOp {
+    fn from(node: Gteq) -> BinOp {
+        BinOp::Gteq(node)
+    }
+}
+impl From<LAngle> for BinOp {
+    fn from(node: LAngle) -> BinOp {
+        BinOp::LAngle(node)
+    }
+}
+impl From<RAngle> for BinOp {
+    fn from(node: RAngle) -> BinOp {
+        BinOp::RAngle(node)
+    }
+}
+impl From<Plus> for BinOp {
+    fn from(node: Plus) -> BinOp {
+        BinOp::Plus(node)
+    }
+}
+impl From<Star> for BinOp {
+    fn from(node: Star) -> BinOp {
+        BinOp::Star(node)
+    }
+}
+impl From<Minus> for BinOp {
+    fn from(node: Minus) -> BinOp {
+        BinOp::Minus(node)
+    }
+}
+impl From<Slash> for BinOp {
+    fn from(node: Slash) -> BinOp {
+        BinOp::Slash(node)
+    }
+}
+impl From<Percent> for BinOp {
+    fn from(node: Percent) -> BinOp {
+        BinOp::Percent(node)
+    }
+}
+impl From<Shl> for BinOp {
+    fn from(node: Shl) -> BinOp {
+        BinOp::Shl(node)
+    }
+}
+impl From<Shr> for BinOp {
+    fn from(node: Shr) -> BinOp {
+        BinOp::Shr(node)
+    }
+}
+impl From<Caret> for BinOp {
+    fn from(node: Caret) -> BinOp {
+        BinOp::Caret(node)
+    }
+}
+impl From<Pipe> for BinOp {
+    fn from(node: Pipe) -> BinOp {
+        BinOp::Pipe(node)
+    }
+}
+impl From<Amp> for BinOp {
+    fn from(node: Amp) -> BinOp {
+        BinOp::Amp(node)
+    }
+}
+impl From<Eq> for BinOp {
+    fn from(node: Eq) -> BinOp {
+        BinOp::Eq(node)
+    }
+}
+impl From<Pluseq> for BinOp {
+    fn from(node: Pluseq) -> BinOp {
+        BinOp::Pluseq(node)
+    }
+}
+impl From<Slasheq> for BinOp {
+    fn from(node: Slasheq) -> BinOp {
+        BinOp::Slasheq(node)
+    }
+}
+impl From<Stareq> for BinOp {
+    fn from(node: Stareq) -> BinOp {
+        BinOp::Stareq(node)
+    }
+}
+impl From<Percenteq> for BinOp {
+    fn from(node: Percenteq) -> BinOp {
+        BinOp::Percenteq(node)
+    }
+}
+impl From<Shreq> for BinOp {
+    fn from(node: Shreq) -> BinOp {
+        BinOp::Shreq(node)
+    }
+}
+impl From<Shleq> for BinOp {
+    fn from(node: Shleq) -> BinOp {
+        BinOp::Shleq(node)
+    }
+}
+impl From<Minuseq> for BinOp {
+    fn from(node: Minuseq) -> BinOp {
+        BinOp::Minuseq(node)
+    }
+}
+impl From<Pipeeq> for BinOp {
+    fn from(node: Pipeeq) -> BinOp {
+        BinOp::Pipeeq(node)
+    }
+}
+impl From<Ampeq> for BinOp {
+    fn from(node: Ampeq) -> BinOp {
+        BinOp::Ampeq(node)
+    }
+}
+impl From<Careteq> for BinOp {
+    fn from(node: Careteq) -> BinOp {
+        BinOp::Careteq(node)
+    }
+}
+impl std::fmt::Display for BinOp {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstToken for BinOp {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            PIPEPIPE | AMPAMP | EQEQ | NEQ | LTEQ | GTEQ | L_ANGLE | R_ANGLE | PLUS | STAR
+            | MINUS | SLASH | PERCENT | SHL | SHR | CARET | PIPE | AMP | EQ | PLUSEQ | SLASHEQ
+            | STAREQ | PERCENTEQ | SHREQ | SHLEQ | MINUSEQ | PIPEEQ | AMPEQ | CARETEQ => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxToken) -> Option<Self> {
+        let res = match syntax.kind() {
+            PIPEPIPE => BinOp::Pipepipe(Pipepipe { syntax }),
+            AMPAMP => BinOp::Ampamp(Ampamp { syntax }),
+            EQEQ => BinOp::Eqeq(Eqeq { syntax }),
+            NEQ => BinOp::Neq(Neq { syntax }),
+            LTEQ => BinOp::Lteq(Lteq { syntax }),
+            GTEQ => BinOp::Gteq(Gteq { syntax }),
+            L_ANGLE => BinOp::LAngle(LAngle { syntax }),
+            R_ANGLE => BinOp::RAngle(RAngle { syntax }),
+            PLUS => BinOp::Plus(Plus { syntax }),
+            STAR => BinOp::Star(Star { syntax }),
+            MINUS => BinOp::Minus(Minus { syntax }),
+            SLASH => BinOp::Slash(Slash { syntax }),
+            PERCENT => BinOp::Percent(Percent { syntax }),
+            SHL => BinOp::Shl(Shl { syntax }),
+            SHR => BinOp::Shr(Shr { syntax }),
+            CARET => BinOp::Caret(Caret { syntax }),
+            PIPE => BinOp::Pipe(Pipe { syntax }),
+            AMP => BinOp::Amp(Amp { syntax }),
+            EQ => BinOp::Eq(Eq { syntax }),
+            PLUSEQ => BinOp::Pluseq(Pluseq { syntax }),
+            SLASHEQ => BinOp::Slasheq(Slasheq { syntax }),
+            STAREQ => BinOp::Stareq(Stareq { syntax }),
+            PERCENTEQ => BinOp::Percenteq(Percenteq { syntax }),
+            SHREQ => BinOp::Shreq(Shreq { syntax }),
+            SHLEQ => BinOp::Shleq(Shleq { syntax }),
+            MINUSEQ => BinOp::Minuseq(Minuseq { syntax }),
+            PIPEEQ => BinOp::Pipeeq(Pipeeq { syntax }),
+            AMPEQ => BinOp::Ampeq(Ampeq { syntax }),
+            CARETEQ => BinOp::Careteq(Careteq { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxToken {
+        match self {
+            BinOp::Pipepipe(it) => &it.syntax,
+            BinOp::Ampamp(it) => &it.syntax,
+            BinOp::Eqeq(it) => &it.syntax,
+            BinOp::Neq(it) => &it.syntax,
+            BinOp::Lteq(it) => &it.syntax,
+            BinOp::Gteq(it) => &it.syntax,
+            BinOp::LAngle(it) => &it.syntax,
+            BinOp::RAngle(it) => &it.syntax,
+            BinOp::Plus(it) => &it.syntax,
+            BinOp::Star(it) => &it.syntax,
+            BinOp::Minus(it) => &it.syntax,
+            BinOp::Slash(it) => &it.syntax,
+            BinOp::Percent(it) => &it.syntax,
+            BinOp::Shl(it) => &it.syntax,
+            BinOp::Shr(it) => &it.syntax,
+            BinOp::Caret(it) => &it.syntax,
+            BinOp::Pipe(it) => &it.syntax,
+            BinOp::Amp(it) => &it.syntax,
+            BinOp::Eq(it) => &it.syntax,
+            BinOp::Pluseq(it) => &it.syntax,
+            BinOp::Slasheq(it) => &it.syntax,
+            BinOp::Stareq(it) => &it.syntax,
+            BinOp::Percenteq(it) => &it.syntax,
+            BinOp::Shreq(it) => &it.syntax,
+            BinOp::Shleq(it) => &it.syntax,
+            BinOp::Minuseq(it) => &it.syntax,
+            BinOp::Pipeeq(it) => &it.syntax,
+            BinOp::Ampeq(it) => &it.syntax,
+            BinOp::Careteq(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum PrefixOp {
+    Minus(Minus),
+    Excl(Excl),
+    Star(Star),
+}
+impl From<Minus> for PrefixOp {
+    fn from(node: Minus) -> PrefixOp {
+        PrefixOp::Minus(node)
+    }
+}
+impl From<Excl> for PrefixOp {
+    fn from(node: Excl) -> PrefixOp {
+        PrefixOp::Excl(node)
+    }
+}
+impl From<Star> for PrefixOp {
+    fn from(node: Star) -> PrefixOp {
+        PrefixOp::Star(node)
+    }
+}
+impl std::fmt::Display for PrefixOp {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstToken for PrefixOp {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            MINUS | EXCL | STAR => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxToken) -> Option<Self> {
+        let res = match syntax.kind() {
+            MINUS => PrefixOp::Minus(Minus { syntax }),
+            EXCL => PrefixOp::Excl(Excl { syntax }),
+            STAR => PrefixOp::Star(Star { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxToken {
+        match self {
+            PrefixOp::Minus(it) => &it.syntax,
+            PrefixOp::Excl(it) => &it.syntax,
+            PrefixOp::Star(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum RangeOp {
+    Dotdot(Dotdot),
+    Dotdoteq(Dotdoteq),
+}
+impl From<Dotdot> for RangeOp {
+    fn from(node: Dotdot) -> RangeOp {
+        RangeOp::Dotdot(node)
+    }
+}
+impl From<Dotdoteq> for RangeOp {
+    fn from(node: Dotdoteq) -> RangeOp {
+        RangeOp::Dotdoteq(node)
+    }
+}
+impl std::fmt::Display for RangeOp {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstToken for RangeOp {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            DOTDOT | DOTDOTEQ => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxToken) -> Option<Self> {
+        let res = match syntax.kind() {
+            DOTDOT => RangeOp::Dotdot(Dotdot { syntax }),
+            DOTDOTEQ => RangeOp::Dotdoteq(Dotdoteq { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxToken {
+        match self {
+            RangeOp::Dotdot(it) => &it.syntax,
+            RangeOp::Dotdoteq(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum LiteralToken {
+    IntNumber(IntNumber),
+    FloatNumber(FloatNumber),
+    String(String),
+    RawString(RawString),
+    TrueKw(TrueKw),
+    FalseKw(FalseKw),
+    ByteString(ByteString),
+    RawByteString(RawByteString),
+    Char(Char),
+    Byte(Byte),
+}
+impl From<IntNumber> for LiteralToken {
+    fn from(node: IntNumber) -> LiteralToken {
+        LiteralToken::IntNumber(node)
+    }
+}
+impl From<FloatNumber> for LiteralToken {
+    fn from(node: FloatNumber) -> LiteralToken {
+        LiteralToken::FloatNumber(node)
+    }
+}
+impl From<String> for LiteralToken {
+    fn from(node: String) -> LiteralToken {
+        LiteralToken::String(node)
+    }
+}
+impl From<RawString> for LiteralToken {
+    fn from(node: RawString) -> LiteralToken {
+        LiteralToken::RawString(node)
+    }
+}
+impl From<TrueKw> for LiteralToken {
+    fn from(node: TrueKw) -> LiteralToken {
+        LiteralToken::TrueKw(node)
+    }
+}
+impl From<FalseKw> for LiteralToken {
+    fn from(node: FalseKw) -> LiteralToken {
+        LiteralToken::FalseKw(node)
+    }
+}
+impl From<ByteString> for LiteralToken {
+    fn from(node: ByteString) -> LiteralToken {
+        LiteralToken::ByteString(node)
+    }
+}
+impl From<RawByteString> for LiteralToken {
+    fn from(node: RawByteString) -> LiteralToken {
+        LiteralToken::RawByteString(node)
+    }
+}
+impl From<Char> for LiteralToken {
+    fn from(node: Char) -> LiteralToken {
+        LiteralToken::Char(node)
+    }
+}
+impl From<Byte> for LiteralToken {
+    fn from(node: Byte) -> LiteralToken {
+        LiteralToken::Byte(node)
+    }
+}
+impl std::fmt::Display for LiteralToken {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstToken for LiteralToken {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            INT_NUMBER | FLOAT_NUMBER | STRING | RAW_STRING | TRUE_KW | FALSE_KW | BYTE_STRING
+            | RAW_BYTE_STRING | CHAR | BYTE => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxToken) -> Option<Self> {
+        let res = match syntax.kind() {
+            INT_NUMBER => LiteralToken::IntNumber(IntNumber { syntax }),
+            FLOAT_NUMBER => LiteralToken::FloatNumber(FloatNumber { syntax }),
+            STRING => LiteralToken::String(String { syntax }),
+            RAW_STRING => LiteralToken::RawString(RawString { syntax }),
+            TRUE_KW => LiteralToken::TrueKw(TrueKw { syntax }),
+            FALSE_KW => LiteralToken::FalseKw(FalseKw { syntax }),
+            BYTE_STRING => LiteralToken::ByteString(ByteString { syntax }),
+            RAW_BYTE_STRING => LiteralToken::RawByteString(RawByteString { syntax }),
+            CHAR => LiteralToken::Char(Char { syntax }),
+            BYTE => LiteralToken::Byte(Byte { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxToken {
+        match self {
+            LiteralToken::IntNumber(it) => &it.syntax,
+            LiteralToken::FloatNumber(it) => &it.syntax,
+            LiteralToken::String(it) => &it.syntax,
+            LiteralToken::RawString(it) => &it.syntax,
+            LiteralToken::TrueKw(it) => &it.syntax,
+            LiteralToken::FalseKw(it) => &it.syntax,
+            LiteralToken::ByteString(it) => &it.syntax,
+            LiteralToken::RawByteString(it) => &it.syntax,
+            LiteralToken::Char(it) => &it.syntax,
+            LiteralToken::Byte(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum NameRefToken {
+    Ident(Ident),
+    IntNumber(IntNumber),
+}
+impl From<Ident> for NameRefToken {
+    fn from(node: Ident) -> NameRefToken {
+        NameRefToken::Ident(node)
+    }
+}
+impl From<IntNumber> for NameRefToken {
+    fn from(node: IntNumber) -> NameRefToken {
+        NameRefToken::IntNumber(node)
+    }
+}
+impl std::fmt::Display for NameRefToken {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl AstToken for NameRefToken {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            IDENT | INT_NUMBER => true,
+            _ => false,
+        }
+    }
+    fn cast(syntax: SyntaxToken) -> Option<Self> {
+        let res = match syntax.kind() {
+            IDENT => NameRefToken::Ident(Ident { syntax }),
+            INT_NUMBER => NameRefToken::IntNumber(IntNumber { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxToken {
+        match self {
+            NameRefToken::Ident(it) => &it.syntax,
+            NameRefToken::IntNumber(it) => &it.syntax,
+        }
+    }
+}
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum FieldDefList {
+    RecordFieldDefList(RecordFieldDefList),
+    TupleFieldDefList(TupleFieldDefList),
+}
+impl From<RecordFieldDefList> for FieldDefList {
+    fn from(node: RecordFieldDefList) -> FieldDefList {
+        FieldDefList::RecordFieldDefList(node)
+    }
+}
+impl From<TupleFieldDefList> for FieldDefList {
+    fn from(node: TupleFieldDefList) -> FieldDefList {
+        FieldDefList::TupleFieldDefList(node)
+    }
+}
+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 AstNode for FieldDefList {
+    fn can_cast(kind: SyntaxKind) -> bool {
+        match kind {
+            RECORD_FIELD_DEF_LIST | TUPLE_FIELD_DEF_LIST => 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 }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            FieldDefList::RecordFieldDefList(it) => &it.syntax,
+            FieldDefList::TupleFieldDefList(it) => &it.syntax,
         }
     }
 }
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index 576378306f..870e838048 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -5,7 +5,7 @@
 use itertools::Itertools;
 
 use crate::{
-    ast::{self, child_opt, children, AstChildren, AstNode, AstToken},
+    ast::{self, child_opt, children, support, AstChildren, AstNode, AstToken},
     syntax_node::SyntaxElementChildren,
 };
 
@@ -31,6 +31,10 @@ pub trait LoopBodyOwner: AstNode {
     fn loop_body(&self) -> Option<ast::BlockExpr> {
         child_opt(self)
     }
+
+    fn label(&self) -> Option<ast::Label> {
+        child_opt(self)
+    }
 }
 
 pub trait ArgListOwner: AstNode {
@@ -65,6 +69,10 @@ pub trait TypeBoundsOwner: AstNode {
     fn type_bound_list(&self) -> Option<ast::TypeBoundList> {
         child_opt(self)
     }
+
+    fn colon(&self) -> Option<ast::Colon> {
+        support::token(self.syntax())
+    }
 }
 
 pub trait AttrsOwner: AstNode {
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index d9f51ec399..5fed777ace 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -70,7 +70,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
         "match", "mod", "move", "mut", "pub", "ref", "return", "self", "static", "struct", "super",
         "trait", "true", "try", "type", "unsafe", "use", "where", "while",
     ],
-    contextual_keywords: &["auto", "default", "existential", "union"],
+    contextual_keywords: &["auto", "default", "existential", "union", "raw"],
     literals: &[
         "INT_NUMBER",
         "FLOAT_NUMBER",
@@ -297,235 +297,310 @@ macro_rules! ast_enums {
 
 pub(crate) const AST_SRC: AstSrc = AstSrc {
     nodes: &ast_nodes! {
-        struct SourceFile: ModuleItemOwner, FnDefOwner {
+        struct SourceFile: ModuleItemOwner, FnDefOwner, AttrsOwner {
             modules: [Module],
         }
 
         struct FnDef: VisibilityOwner, NameOwner, TypeParamsOwner, DocCommentsOwner, AttrsOwner {
+            Abi,
+            ConstKw,
+            DefaultKw,
+            AsyncKw,
+            UnsafeKw,
+            FnKw,
             ParamList,
             RetType,
             body: BlockExpr,
+            Semi
         }
 
-        struct RetType { TypeRef }
+        struct RetType { ThinArrow, TypeRef }
 
         struct StructDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
+            StructKw,
+            FieldDefList,
+            Semi
         }
 
         struct UnionDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
+            UnionKw,
             RecordFieldDefList,
         }
 
-        struct RecordFieldDefList { fields: [RecordFieldDef] }
+        struct RecordFieldDefList { LCurly, fields: [RecordFieldDef], RCurly }
         struct RecordFieldDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner { }
 
-        struct TupleFieldDefList { fields: [TupleFieldDef] }
+        struct TupleFieldDefList { LParen, fields: [TupleFieldDef], RParen }
         struct TupleFieldDef: VisibilityOwner, AttrsOwner {
             TypeRef,
         }
 
         struct EnumDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner {
+            EnumKw,
             variant_list: EnumVariantList,
         }
         struct EnumVariantList {
+            LCurly,
             variants: [EnumVariant],
+            RCurly
         }
-        struct EnumVariant: NameOwner, DocCommentsOwner, AttrsOwner {
+        struct EnumVariant: VisibilityOwner, NameOwner, DocCommentsOwner, AttrsOwner {
+            FieldDefList,
+            Eq,
             Expr
         }
 
         struct TraitDef: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner, TypeParamsOwner, TypeBoundsOwner {
+            UnsafeKw,
+            AutoKw,
+            TraitKw,
             ItemList,
         }
 
         struct Module: VisibilityOwner, NameOwner, AttrsOwner, DocCommentsOwner {
+            ModKw,
             ItemList,
+            Semi
         }
 
         struct ItemList: FnDefOwner, ModuleItemOwner {
+            LCurly,
             impl_items: [ImplItem],
+            RCurly
         }
 
         struct ConstDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
+            DefaultKw,
+            ConstKw,
+            Eq,
             body: Expr,
+            Semi
         }
 
         struct StaticDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeAscriptionOwner {
+            StaticKw,
+            MutKw,
+            Eq,
             body: Expr,
+            Semi
         }
 
         struct TypeAliasDef: VisibilityOwner, NameOwner, TypeParamsOwner, AttrsOwner, DocCommentsOwner, TypeBoundsOwner {
+            DefaultKw,
+            TypeKw,
+            Eq,
             TypeRef,
+            Semi
         }
 
         struct ImplDef: TypeParamsOwner, AttrsOwner {
+            DefaultKw,
+            ConstKw,
+            UnsafeKw,
+            ImplKw,
+            Excl,
+            ForKw,
             ItemList,
         }
 
-        struct ParenType { TypeRef }
-        struct TupleType { fields: [TypeRef] }
-        struct NeverType { }
+        struct ParenType { LParen, TypeRef, RParen }
+        struct TupleType { LParen, fields: [TypeRef], RParen }
+        struct NeverType { Excl }
         struct PathType { Path }
-        struct PointerType { TypeRef }
-        struct ArrayType { TypeRef, Expr }
-        struct SliceType { TypeRef }
-        struct ReferenceType { TypeRef }
-        struct PlaceholderType {  }
-        struct FnPointerType { ParamList, RetType }
-        struct ForType { TypeRef }
-        struct ImplTraitType: TypeBoundsOwner {}
-        struct DynTraitType: TypeBoundsOwner {}
-
-        struct TupleExpr { exprs: [Expr] }
-        struct ArrayExpr { exprs: [Expr] }
-        struct ParenExpr { Expr }
+        struct PointerType { Star, ConstKw, TypeRef }
+        struct ArrayType { LBrack, TypeRef, Semi, Expr, RBrack }
+        struct SliceType { LBrack, TypeRef, RBrack }
+        struct ReferenceType { Amp, Lifetime, MutKw, TypeRef }
+        struct PlaceholderType { Underscore }
+        struct FnPointerType { Abi, UnsafeKw, FnKw, ParamList, RetType }
+        struct ForType { ForKw, TypeParamList, TypeRef }
+        struct ImplTraitType: TypeBoundsOwner { ImplKw }
+        struct DynTraitType: TypeBoundsOwner { DynKw }
+
+        struct TupleExpr: AttrsOwner { LParen, exprs: [Expr], RParen }
+        struct ArrayExpr: AttrsOwner { LBrack, exprs: [Expr], Semi, RBrack }
+        struct ParenExpr: AttrsOwner { LParen, Expr, RParen }
         struct PathExpr  { Path }
-        struct LambdaExpr {
+        struct LambdaExpr: AttrsOwner {
+            StaticKw,
+            AsyncKw,
+            MoveKw,
             ParamList,
             RetType,
             body: Expr,
         }
-        struct IfExpr { Condition }
-        struct LoopExpr: LoopBodyOwner { }
-        struct TryBlockExpr { body: BlockExpr }
-        struct ForExpr: LoopBodyOwner {
+        struct IfExpr: AttrsOwner { IfKw, Condition }
+        struct LoopExpr: AttrsOwner, LoopBodyOwner { LoopKw }
+        struct TryBlockExpr: AttrsOwner { TryKw, body: BlockExpr }
+        struct ForExpr: AttrsOwner, LoopBodyOwner {
+            ForKw,
             Pat,
+            InKw,
             iterable: Expr,
         }
-        struct WhileExpr: LoopBodyOwner { Condition }
-        struct ContinueExpr {}
-        struct BreakExpr { Expr }
-        struct Label {}
-        struct BlockExpr { Block  }
-        struct ReturnExpr { Expr }
+        struct WhileExpr: AttrsOwner, LoopBodyOwner { WhileKw, Condition }
+        struct ContinueExpr: AttrsOwner { ContinueKw, Lifetime }
+        struct BreakExpr: AttrsOwner { BreakKw, Lifetime, Expr }
+        struct Label { Lifetime }
+        struct BlockExpr: AttrsOwner { Label, UnsafeKw, Block  }
+        struct ReturnExpr: AttrsOwner { Expr }
         struct CallExpr: ArgListOwner { Expr }
-        struct MethodCallExpr: ArgListOwner {
-            Expr, NameRef, TypeArgList,
-        }
-        struct IndexExpr {}
-        struct FieldExpr { Expr, NameRef }
-        struct AwaitExpr { Expr }
-        struct TryExpr { Expr }
-        struct CastExpr { Expr, TypeRef }
-        struct RefExpr { Expr }
-        struct PrefixExpr { Expr }
-        struct BoxExpr { Expr }
-        struct RangeExpr {}
-        struct BinExpr {}
-        struct Literal {}
-
-        struct MatchExpr { Expr, MatchArmList }
-        struct MatchArmList: AttrsOwner { arms: [MatchArm] }
+        struct MethodCallExpr: AttrsOwner, ArgListOwner {
+            Expr, Dot, NameRef, TypeArgList,
+        }
+        struct IndexExpr: AttrsOwner { LBrack, RBrack }
+        struct FieldExpr: AttrsOwner { Expr, Dot, NameRef }
+        struct AwaitExpr: AttrsOwner { Expr, Dot, AwaitKw }
+        struct TryExpr: AttrsOwner { TryKw, Expr }
+        struct CastExpr: AttrsOwner { Expr, AsKw, TypeRef }
+        struct RefExpr: AttrsOwner { Amp, RawKw, MutKw, Expr }
+        struct PrefixExpr: AttrsOwner { PrefixOp, Expr }
+        struct BoxExpr: AttrsOwner { BoxKw, Expr }
+        struct RangeExpr: AttrsOwner { RangeOp }
+        struct BinExpr: AttrsOwner { BinOp }
+        struct Literal { LiteralToken }
+
+        struct MatchExpr: AttrsOwner { MatchKw, Expr, MatchArmList }
+        struct MatchArmList: AttrsOwner { LCurly, arms: [MatchArm], RCurly }
         struct MatchArm: AttrsOwner {
             pat: Pat,
             guard: MatchGuard,
+            FatArrow,
             Expr,
         }
-        struct MatchGuard { Expr }
+        struct MatchGuard { IfKw, Expr }
 
-        struct RecordLit { Path, RecordFieldList }
+        struct RecordLit { Path, RecordFieldList}
         struct RecordFieldList {
+            LCurly,
             fields: [RecordField],
+            Dotdot,
             spread: Expr,
+            RCurly
         }
-        struct RecordField { NameRef, Expr }
+        struct RecordField: AttrsOwner { NameRef, Colon, Expr }
 
         struct OrPat { pats: [Pat] }
-        struct ParenPat { Pat }
-        struct RefPat { Pat }
-        struct BoxPat { Pat }
-        struct BindPat: NameOwner { Pat }
-        struct PlaceholderPat { }
-        struct DotDotPat { }
+        struct ParenPat { LParen, Pat, RParen }
+        struct RefPat { Amp, MutKw, Pat }
+        struct BoxPat { BoxKw, Pat }
+        struct BindPat: AttrsOwner, NameOwner { RefKw, MutKw, Pat }
+        struct PlaceholderPat { Underscore }
+        struct DotDotPat { Dotdot }
         struct PathPat { Path }
-        struct SlicePat { args: [Pat] }
-        struct RangePat {}
+        struct SlicePat { LBrack, args: [Pat], RBrack }
+        struct RangePat { RangeSeparator }
         struct LiteralPat { Literal }
         struct MacroPat { MacroCall }
 
         struct RecordPat { RecordFieldPatList, Path }
         struct RecordFieldPatList {
+            LCurly,
+            pats: [RecordInnerPat],
             record_field_pats: [RecordFieldPat],
             bind_pats: [BindPat],
+            Dotdot,
+            RCurly
         }
-        struct RecordFieldPat: NameOwner { Pat }
+        struct RecordFieldPat: AttrsOwner, NameOwner { Colon, Pat }
 
-        struct TupleStructPat { Path, args: [Pat] }
-        struct TuplePat { args: [Pat] }
+        struct TupleStructPat { Path, LParen, args: [Pat], RParen }
+        struct TuplePat { LParen, args: [Pat], RParen }
 
-        struct Visibility {}
-        struct Name {}
-        struct NameRef {}
+        struct Visibility { PubKw, SuperKw, SelfKw, CrateKw }
+        struct Name { Ident }
+        struct NameRef { NameRefToken }
 
         struct MacroCall: NameOwner, AttrsOwner,DocCommentsOwner {
-            TokenTree, Path
+            Path, Excl, TokenTree, Semi
         }
-        struct Attr { Path, input: AttrInput }
+        struct Attr { Pound, Excl, LBrack, Path, Eq, input: AttrInput, RBrack }
         struct TokenTree {}
         struct TypeParamList {
+            LAngle,
+            generic_params: [GenericParam],
             type_params: [TypeParam],
             lifetime_params: [LifetimeParam],
+            const_params: [ConstParam],
+            RAngle
         }
         struct TypeParam: NameOwner, AttrsOwner, TypeBoundsOwner {
+            Eq,
             default_type: TypeRef,
         }
         struct ConstParam: NameOwner, AttrsOwner, TypeAscriptionOwner {
+            Eq,
             default_val: Expr,
         }
-        struct LifetimeParam: AttrsOwner { }
-        struct TypeBound { TypeRef}
+        struct LifetimeParam: AttrsOwner { Lifetime}
+        struct TypeBound { Lifetime, /* Question,  */ ConstKw, /* Question,  */ TypeRef}
         struct TypeBoundList { bounds: [TypeBound] }
-        struct WherePred: TypeBoundsOwner { TypeRef }
-        struct WhereClause { predicates: [WherePred] }
-        struct ExprStmt { Expr }
-        struct LetStmt: TypeAscriptionOwner {
+        struct WherePred: TypeBoundsOwner { Lifetime, TypeRef }
+        struct WhereClause { WhereKw, predicates: [WherePred] }
+        struct Abi { String }
+        struct ExprStmt: AttrsOwner { Expr, Semi }
+        struct LetStmt: AttrsOwner, TypeAscriptionOwner {
+            LetKw,
             Pat,
+            Eq,
             initializer: Expr,
         }
-        struct Condition { Pat, Expr }
+        struct Condition { LetKw, Pat, Eq, Expr }
         struct Block: AttrsOwner, ModuleItemOwner {
+            LCurly,
             statements: [Stmt],
             Expr,
+            RCurly,
         }
         struct ParamList {
+            LParen,
             SelfParam,
             params: [Param],
+            RParen
         }
-        struct SelfParam: TypeAscriptionOwner, AttrsOwner { }
+        struct SelfParam: TypeAscriptionOwner, AttrsOwner { Amp, Lifetime, SelfKw }
         struct Param: TypeAscriptionOwner, AttrsOwner {
             Pat,
+            Dotdotdot
         }
         struct UseItem: AttrsOwner, VisibilityOwner {
+            UseKw,
             UseTree,
         }
         struct UseTree {
-            Path, UseTreeList, Alias
+            Path, Star, UseTreeList, Alias
         }
-        struct Alias: NameOwner { }
-        struct UseTreeList { use_trees: [UseTree] }
+        struct Alias: NameOwner { AsKw }
+        struct UseTreeList { LCurly, use_trees: [UseTree], RCurly }
         struct ExternCrateItem: AttrsOwner, VisibilityOwner {
-            NameRef, Alias,
+            ExternKw, CrateKw, NameRef, Alias,
         }
         struct ArgList {
+            LParen,
             args: [Expr],
+            RParen
         }
         struct Path {
             segment: PathSegment,
             qualifier: Path,
         }
         struct PathSegment {
-            NameRef, TypeArgList, ParamList, RetType, PathType,
+            Coloncolon, LAngle, NameRef, TypeArgList, ParamList, RetType, PathType, RAngle
         }
         struct TypeArgList {
+            Coloncolon,
+            LAngle,
+            generic_args: [GenericArg],
             type_args: [TypeArg],
             lifetime_args: [LifetimeArg],
             assoc_type_args: [AssocTypeArg],
-            const_arg: [ConstArg],
+            const_args: [ConstArg],
+            RAngle
         }
         struct TypeArg { TypeRef }
-        struct AssocTypeArg { NameRef, TypeRef }
-        struct LifetimeArg {}
-        struct ConstArg { Literal, BlockExpr }
+        struct AssocTypeArg : TypeBoundsOwner { NameRef, Eq, TypeRef }
+        struct LifetimeArg { Lifetime }
+        struct ConstArg { Literal, Eq, BlockExpr }
 
         struct MacroItems: ModuleItemOwner, FnDefOwner { }
 
@@ -533,12 +608,44 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
             statements: [Stmt],
             Expr,
         }
+
+        struct ExternItemList: FnDefOwner, ModuleItemOwner {
+            LCurly,
+            extern_items: [ExternItem],
+            RCurly
+        }
+
+        struct ExternBlock {
+            Abi,
+            ExternItemList
+        }
+
+        struct MetaItem {
+            Path, Eq, AttrInput, nested_meta_items: [MetaItem]
+        }
+
+        struct MacroDef {
+            Name, TokenTree
+        }
     },
     enums: &ast_enums! {
         enum NominalDef: NameOwner, TypeParamsOwner, AttrsOwner {
             StructDef, EnumDef, UnionDef,
         }
 
+        enum GenericParam {
+            LifetimeParam,
+            TypeParam,
+            ConstParam
+        }
+
+        enum GenericArg {
+            LifetimeArg,
+            TypeArg,
+            ConstArg,
+            AssocTypeArg
+        }
+
         enum TypeRef {
             ParenType,
             TupleType,
@@ -555,7 +662,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
             DynTraitType,
         }
 
-        enum ModuleItem: AttrsOwner, VisibilityOwner {
+        enum ModuleItem: NameOwner, AttrsOwner, VisibilityOwner {
             StructDef,
             UnionDef,
             EnumDef,
@@ -569,13 +676,20 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
             StaticDef,
             Module,
             MacroCall,
+            ExternBlock
+        }
+
+        /* impl blocks can also contain MacroCall */
+        enum ImplItem: NameOwner, AttrsOwner {
+            FnDef, TypeAliasDef, ConstDef
         }
 
-        enum ImplItem: AttrsOwner {
-            FnDef, TypeAliasDef, ConstDef,
+        /* extern blocks can also contain MacroCall */
+        enum ExternItem: NameOwner, AttrsOwner, VisibilityOwner {
+            FnDef, StaticDef
         }
 
-        enum Expr {
+        enum Expr: AttrsOwner {
             TupleExpr,
             ArrayExpr,
             ParenExpr,
@@ -627,7 +741,86 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
             MacroPat,
         }
 
+        enum RecordInnerPat {
+            RecordFieldPat,
+            BindPat
+        }
+
         enum AttrInput { Literal, TokenTree }
-        enum Stmt { ExprStmt, LetStmt }
+        enum Stmt {
+            LetStmt,
+            ExprStmt,
+            // macro calls are parsed as expression statements */
+        }
+
+        enum LeftDelimiter { LParen, LBrack, LCurly }
+        enum RightDelimiter { RParen, RBrack, RCurly }
+        enum RangeSeparator { Dotdot, Dotdotdot, Dotdoteq}
+
+        enum BinOp {
+            Pipepipe,
+            Ampamp,
+            Eqeq,
+            Neq,
+            Lteq,
+            Gteq,
+            LAngle,
+            RAngle,
+            Plus,
+            Star,
+            Minus,
+            Slash,
+            Percent,
+            Shl,
+            Shr,
+            Caret,
+            Pipe,
+            Amp,
+            Eq,
+            Pluseq,
+            Slasheq,
+            Stareq,
+            Percenteq,
+            Shreq,
+            Shleq,
+            Minuseq,
+            Pipeeq,
+            Ampeq,
+            Careteq,
+        }
+
+        enum PrefixOp {
+            Minus,
+            Excl,
+            Star
+        }
+
+        enum RangeOp {
+            Dotdot,
+            Dotdoteq
+        }
+
+        enum LiteralToken {
+            IntNumber,
+            FloatNumber,
+            String,
+            RawString,
+            TrueKw,
+            FalseKw,
+            ByteString,
+            RawByteString,
+            Char,
+            Byte
+        }
+
+        enum NameRefToken {
+            Ident,
+            IntNumber
+        }
+
+        enum FieldDefList {
+            RecordFieldDefList,
+            TupleFieldDefList,
+        }
     },
 };
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index 2dfb683718..6dae93aa22 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -146,14 +146,23 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
                 FieldSrc::Many(_) => {
                     quote! {
                         pub fn #method_name(&self) -> AstChildren<#ty> {
-                            AstChildren::new(&self.syntax)
+                            support::children(&self.syntax)
                         }
                     }
                 }
                 FieldSrc::Optional(_) | FieldSrc::Shorthand => {
-                    quote! {
-                        pub fn #method_name(&self) -> Option<#ty> {
-                            AstChildren::new(&self.syntax).next()
+                    let is_token = element_kinds_map[&ty.to_string()].has_tokens;
+                    if is_token {
+                        quote! {
+                            pub fn #method_name(&self) -> Option<#ty> {
+                                support::token(&self.syntax)
+                            }
+                        }
+                    } else {
+                        quote! {
+                            pub fn #method_name(&self) -> Option<#ty> {
+                                support::child(&self.syntax)
+                            }
                         }
                     }
                 }
@@ -205,6 +214,48 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
             quote!(impl ast::#trait_name for #name {})
         });
 
+        let element_kinds = &element_kinds_map[&en.name.to_string()];
+        assert!(
+            element_kinds.has_nodes ^ element_kinds.has_tokens,
+            "{}: {:#?}",
+            name,
+            element_kinds
+        );
+        let specific_ast_trait = {
+            let (ast_trait, syntax_type) = if element_kinds.has_tokens {
+                (quote!(AstToken), quote!(SyntaxToken))
+            } else {
+                (quote!(AstNode), quote!(SyntaxNode))
+            };
+
+            quote! {
+                impl #ast_trait for #name {
+                    fn can_cast(kind: SyntaxKind) -> bool {
+                        match kind {
+                            #(#kinds)|* => true,
+                            _ => false,
+                        }
+                    }
+                    fn cast(syntax: #syntax_type) -> Option<Self> {
+                        let res = match syntax.kind() {
+                            #(
+                            #kinds => #name::#variants(#variants { syntax }),
+                            )*
+                            _ => return None,
+                        };
+                        Some(res)
+                    }
+                    fn syntax(&self) -> &#syntax_type {
+                        match self {
+                            #(
+                            #name::#variants(it) => &it.syntax,
+                            )*
+                        }
+                    }
+                }
+            }
+        };
+
         quote! {
             #[derive(Debug, Clone, PartialEq, Eq, Hash)]
             pub enum #name {
@@ -225,30 +276,8 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
                 }
             }
 
-            impl AstNode for #name {
-                fn can_cast(kind: SyntaxKind) -> bool {
-                    match kind {
-                        #(#kinds)|* => true,
-                        _ => false,
-                    }
-                }
-                fn cast(syntax: SyntaxNode) -> Option<Self> {
-                    let res = match syntax.kind() {
-                        #(
-                        #kinds => #name::#variants(#variants { syntax }),
-                        )*
-                        _ => return None,
-                    };
-                    Some(res)
-                }
-                fn syntax(&self) -> &SyntaxNode {
-                    match self {
-                        #(
-                        #name::#variants(it) => &it.syntax,
-                        )*
-                    }
-                }
-            }
+            #specific_ast_trait
+
             #(#traits)*
         }
     });
@@ -268,7 +297,7 @@ fn generate_ast(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
         #[allow(unused_imports)]
         use crate::{
             SyntaxNode, SyntaxToken, SyntaxElement, NodeOrToken, SyntaxKind::{self, *},
-            ast::{self, AstNode, AstToken, AstChildren},
+            ast::{self, AstNode, AstToken, AstChildren, support},
         };
 
         #(#tokens)*


Test patch:
diff --git a/crates/ra_hir_ty/src/tests.rs b/crates/ra_hir_ty/src/tests.rs
index 608408d88c..ac09662368 100644
--- a/crates/ra_hir_ty/src/tests.rs
+++ b/crates/ra_hir_ty/src/tests.rs
@@ -23,7 +23,7 @@ use insta::assert_snapshot;
 use ra_db::{fixture::WithFixture, salsa::Database, FilePosition, SourceDatabase};
 use ra_syntax::{
     algo,
-    ast::{self, AstNode},
+    ast::{self, AstNode, AstToken},
 };
 use stdx::format_to;
 
@@ -101,7 +101,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
             let node = src_ptr.value.to_node(&src_ptr.file_syntax(&db));
 
             let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.clone()) {
-                (self_param.self_kw_token().text_range(), "self".to_string())
+                (self_param.self_kw().unwrap().syntax().text_range(), "self".to_string())
             } else {
                 (src_ptr.value.range(), node.text().to_string().replace("\n", " "))
             };