Repository: rust-lang/rust-analyzer
Pull request #16892 (2024-03-19 15:19:59)

internal: Don't eagerly try to read crate root file contents before VFS
Fixes https://github.com/rust-lang/rust-analyzer/issues/8623


Patch:
diff --git a/.github/workflows/publish-libs.yaml b/.github/workflows/publish-libs.yaml
index 34ca53e2e5..862373ec1c 100644
--- a/.github/workflows/publish-libs.yaml
+++ b/.github/workflows/publish-libs.yaml
@@ -32,5 +32,4 @@ jobs:
           git config --global user.name "GitHub Action"
           # Remove r-a crates from the workspaces so we don't auto-publish them as well
           sed -i 's/ "crates\/\*"//' ./Cargo.toml
-          sed -i 's/ "xtask\/"//' ./Cargo.toml
           cargo workspaces publish --yes --exact --from-git --no-git-commit --allow-dirty
diff --git a/Cargo.lock b/Cargo.lock
index 733e119b04..ce2cccf53a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1875,16 +1875,20 @@ dependencies = [
  "itertools",
  "once_cell",
  "parser",
+ "proc-macro2",
+ "quote",
  "ra-ap-rustc_lexer",
  "rayon",
  "rowan",
  "rustc-hash",
  "smol_str",
+ "sourcegen",
  "stdx",
  "test-utils",
  "text-edit",
  "tracing",
  "triomphe",
+ "ungrammar",
 ]
 
 [[package]]
@@ -2441,12 +2445,8 @@ version = "0.1.0"
 dependencies = [
  "anyhow",
  "flate2",
- "itertools",
- "proc-macro2",
- "quote",
  "stdx",
  "time",
- "ungrammar",
  "write-json",
  "xflags",
  "xshell",
diff --git a/crates/hir-ty/Cargo.toml b/crates/hir-ty/Cargo.toml
index a2711f8cbe..3cfedcdcb4 100644
--- a/crates/hir-ty/Cargo.toml
+++ b/crates/hir-ty/Cargo.toml
@@ -53,7 +53,7 @@ expect-test = "1.4.0"
 tracing.workspace = true
 tracing-subscriber.workspace = true
 tracing-tree.workspace = true
-project-model.workspace = true
+project-model = { path = "../project-model" }
 
 # local deps
 test-utils.workspace = true
diff --git a/crates/hir-ty/src/diagnostics/expr.rs b/crates/hir-ty/src/diagnostics/expr.rs
index 20b0da441d..b3128712dc 100644
--- a/crates/hir-ty/src/diagnostics/expr.rs
+++ b/crates/hir-ty/src/diagnostics/expr.rs
@@ -11,6 +11,7 @@ use hir_def::{ItemContainerId, Lookup};
 use hir_expand::name;
 use itertools::Itertools;
 use rustc_hash::FxHashSet;
+use rustc_pattern_analysis::usefulness::{compute_match_usefulness, PlaceValidity};
 use syntax::{ast, AstNode};
 use tracing::debug;
 use triomphe::Arc;
@@ -233,7 +234,13 @@ impl ExprValidator {
             return;
         }
 
-        let report = match cx.compute_match_usefulness(m_arms.as_slice(), scrut_ty.clone()) {
+        let report = match compute_match_usefulness(
+            &cx,
+            m_arms.as_slice(),
+            scrut_ty.clone(),
+            PlaceValidity::ValidOnly,
+            None,
+        ) {
             Ok(report) => report,
             Err(()) => return,
         };
@@ -275,7 +282,13 @@ impl ExprValidator {
                 continue;
             }
 
-            let report = match cx.compute_match_usefulness(&[match_arm], ty.clone()) {
+            let report = match compute_match_usefulness(
+                &cx,
+                &[match_arm],
+                ty.clone(),
+                PlaceValidity::ValidOnly,
+                None,
+            ) {
                 Ok(v) => v,
                 Err(e) => {
                     debug!(?e, "match usefulness error");
diff --git a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
index f45beb4c92..81ce51429c 100644
--- a/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
+++ b/crates/hir-ty/src/diagnostics/match_check/pat_analysis.rs
@@ -8,7 +8,6 @@ use rustc_hash::FxHashMap;
 use rustc_pattern_analysis::{
     constructor::{Constructor, ConstructorSet, VariantVisibility},
     index::IdxContainer,
-    usefulness::{compute_match_usefulness, PlaceValidity, UsefulnessReport},
     Captures, PatCx, PrivateUninhabitedField,
 };
 use smallvec::{smallvec, SmallVec};
@@ -60,18 +59,6 @@ impl<'p> MatchCheckCtx<'p> {
         Self { module, body, db, exhaustive_patterns, min_exhaustive_patterns }
     }
 
-    pub(crate) fn compute_match_usefulness(
-        &self,
-        arms: &[MatchArm<'p>],
-        scrut_ty: Ty,
-    ) -> Result<UsefulnessReport<'p, Self>, ()> {
-        // FIXME: Determine place validity correctly. For now, err on the safe side.
-        let place_validity = PlaceValidity::MaybeInvalid;
-        // Measured to take ~100ms on modern hardware.
-        let complexity_limit = Some(500000);
-        compute_match_usefulness(self, arms, scrut_ty, place_validity, complexity_limit)
-    }
-
     fn is_uninhabited(&self, ty: &Ty) -> bool {
         is_ty_uninhabited_from(ty, self.module, self.db)
     }
@@ -478,6 +465,7 @@ impl<'p> PatCx for MatchCheckCtx<'p> {
     }
 
     fn complexity_exceeded(&self) -> Result<(), Self::Error> {
+        // FIXME(Nadrieril): make use of the complexity counter.
         Err(())
     }
 }
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 9d7be9a421..4f9697f7fe 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -3628,41 +3628,16 @@ impl Impl {
                     .filter(filter),
             );
         }
-
-        if let Some(block) =
-            ty.adt_id(Interner).and_then(|def| def.0.module(db.upcast()).containing_block())
-        {
-            if let Some(inherent_impls) = db.inherent_impls_in_block(block) {
-                all.extend(
-                    inherent_impls.for_self_ty(&ty).iter().cloned().map(Self::from).filter(filter),
-                );
-            }
-            if let Some(trait_impls) = db.trait_impls_in_block(block) {
-                all.extend(
-                    trait_impls
-                        .for_self_ty_without_blanket_impls(fp)
-                        .map(Self::from)
-                        .filter(filter),
-                );
-            }
-        }
-
         all
     }
 
     pub fn all_for_trait(db: &dyn HirDatabase, trait_: Trait) -> Vec<Impl> {
-        let module = trait_.module(db);
-        let krate = module.krate();
+        let krate = trait_.module(db).krate();
         let mut all = Vec::new();
         for Crate { id } in krate.transitive_reverse_dependencies(db) {
             let impls = db.trait_impls_in_crate(id);
             all.extend(impls.for_trait(trait_.id).map(Self::from))
         }
-        if let Some(block) = module.id.containing_block() {
-            if let Some(trait_impls) = db.trait_impls_in_block(block) {
-                all.extend(trait_impls.for_trait(trait_.id).map(Self::from));
-            }
-        }
         all
     }
 
diff --git a/crates/ide-diagnostics/src/handlers/missing_match_arms.rs b/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
index 045154614f..67daa172b2 100644
--- a/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
+++ b/crates/ide-diagnostics/src/handlers/missing_match_arms.rs
@@ -23,7 +23,6 @@ mod tests {
         },
         DiagnosticsConfig,
     };
-    use test_utils::skip_slow_tests;
 
     #[track_caller]
     fn check_diagnostics_no_bails(ra_fixture: &str) {
@@ -1005,32 +1004,6 @@ fn f() {
         );
     }
 
-    #[test]
-    fn exponential_match() {
-        if skip_slow_tests() {
-            return;
-        }
-        // Constructs a match where match checking takes exponential time. Ensures we bail early.
-        use std::fmt::Write;
-        let struct_arity = 50;
-        let mut code = String::new();
-        write!(code, "struct BigStruct {{").unwrap();
-        for i in 0..struct_arity {
-            write!(code, "  field{i}: bool,").unwrap();
-        }
-        write!(code, "}}").unwrap();
-        write!(code, "fn big_match(s: BigStruct) {{").unwrap();
-        write!(code, "  match s {{").unwrap();
-        for i in 0..struct_arity {
-            write!(code, "    BigStruct {{ field{i}: true, ..}} => {{}},").unwrap();
-            write!(code, "    BigStruct {{ field{i}: false, ..}} => {{}},").unwrap();
-        }
-        write!(code, "    _ => {{}},").unwrap();
-        write!(code, "  }}").unwrap();
-        write!(code, "}}").unwrap();
-        check_diagnostics_no_bails(&code);
-    }
-
     mod rust_unstable {
         use super::*;
 
diff --git a/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
index 00352266dd..6602aca2fa 100644
--- a/crates/ide-diagnostics/src/handlers/mutability_errors.rs
+++ b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
@@ -51,12 +51,8 @@ pub(crate) fn need_mut(ctx: &DiagnosticsContext<'_>, d: &hir::NeedMut) -> Option
 // Diagnostic: unused-mut
 //
 // This diagnostic is triggered when a mutable variable isn't actually mutated.
-pub(crate) fn unused_mut(ctx: &DiagnosticsContext<'_>, d: &hir::UnusedMut) -> Option<Diagnostic> {
+pub(crate) fn unused_mut(ctx: &DiagnosticsContext<'_>, d: &hir::UnusedMut) -> Diagnostic {
     let ast = d.local.primary_source(ctx.sema.db).syntax_ptr();
-    if ast.file_id.macro_file().is_some() {
-        // FIXME: Our infra can't handle allow from within macro expansions rn
-        return None;
-    }
     let fixes = (|| {
         let file_id = ast.file_id.file_id()?;
         let mut edit_builder = TextEdit::builder();
@@ -80,16 +76,14 @@ pub(crate) fn unused_mut(ctx: &DiagnosticsContext<'_>, d: &hir::UnusedMut) -> Op
         )])
     })();
     let ast = d.local.primary_source(ctx.sema.db).syntax_ptr();
-    Some(
-        Diagnostic::new_with_syntax_node_ptr(
-            ctx,
-            DiagnosticCode::RustcLint("unused_mut"),
-            "variable does not need to be mutable",
-            ast,
-        )
-        .experimental() // Not supporting `#[allow(unused_mut)]` in proc macros leads to false positive.
-        .with_fixes(fixes),
+    Diagnostic::new_with_syntax_node_ptr(
+        ctx,
+        DiagnosticCode::RustcLint("unused_mut"),
+        "variable does not need to be mutable",
+        ast,
     )
+    .experimental() // Not supporting `#[allow(unused_mut)]` in proc macros leads to false positive.
+    .with_fixes(fixes)
 }
 
 pub(super) fn token(parent: &SyntaxNode, kind: SyntaxKind) -> Option<SyntaxToken> {
diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs
index 270cf844c6..dea802204a 100644
--- a/crates/ide-diagnostics/src/lib.rs
+++ b/crates/ide-diagnostics/src/lib.rs
@@ -387,10 +387,7 @@ pub fn diagnostics(
             AnyDiagnostic::UnresolvedMethodCall(d) => handlers::unresolved_method::unresolved_method(&ctx, &d),
             AnyDiagnostic::UnresolvedModule(d) => handlers::unresolved_module::unresolved_module(&ctx, &d),
             AnyDiagnostic::UnresolvedProcMacro(d) => handlers::unresolved_proc_macro::unresolved_proc_macro(&ctx, &d, config.proc_macros_enabled, config.proc_attr_macros_enabled),
-            AnyDiagnostic::UnusedMut(d) => match handlers::mutability_errors::unused_mut(&ctx, &d) {
-                Some(it) => it,
-                None => continue,
-            },
+            AnyDiagnostic::UnusedMut(d) => handlers::mutability_errors::unused_mut(&ctx, &d),
             AnyDiagnostic::UnusedVariable(d) => match handlers::unused_variables::unused_variables(&ctx, &d) {
                 Some(it) => it,
                 None => continue,
diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs
index 76e5e9dd92..8a12cbaccc 100644
--- a/crates/ide/src/goto_implementation.rs
+++ b/crates/ide/src/goto_implementation.rs
@@ -337,77 +337,6 @@ impl Tr for S {
     const C: usize = 4;
         //^
 }
-"#,
-        );
-    }
-
-    #[test]
-    fn goto_adt_implementation_inside_block() {
-        check(
-            r#"
-//- minicore: copy, derive
-trait Bar {}
-
-fn test() {
-    #[derive(Copy)]
-  //^^^^^^^^^^^^^^^
-    struct Foo$0;
-
-    impl Foo {}
-       //^^^
-
-    trait Baz {}
-
-    impl Bar for Foo {}
-               //^^^
-
-    impl Baz for Foo {}
-               //^^^
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn goto_trait_implementation_inside_block() {
-        check(
-            r#"
-struct Bar;
-
-fn test() {
-    trait Foo$0 {}
-
-    struct Baz;
-
-    impl Foo for Bar {}
-               //^^^
-
-    impl Foo for Baz {}
-               //^^^
-}
-"#,
-        );
-        check(
-            r#"
-struct Bar;
-
-fn test() {
-    trait Foo {
-        fn foo$0() {}
-    }
-
-    struct Baz;
-
-    impl Foo for Bar {
-        fn foo() {}
-         //^^^
-    }
-
-    impl Foo for Baz {
-        fn foo() {}
-         //^^^
-    }
-}
 "#,
         );
     }
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index 54ed5f0ba2..72848a1f2b 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/crates/parser/src/grammar/expressions/atom.rs
@@ -490,18 +490,6 @@ fn match_expr(p: &mut Parser<'_>) -> CompletedMarker {
     m.complete(p, MATCH_EXPR)
 }
 
-// test_err match_arms_recovery
-// fn foo() {
-//     match () {
-//         _ => (),,
-//         _ => ,
-//         _ => (),
-//          => (),
-//         if true => (),
-//         _ => (),
-//         () if => (),
-//     }
-// }
 pub(crate) fn match_arm_list(p: &mut Parser<'_>) {
     assert!(p.at(T!['{']));
     let m = p.start();
@@ -523,10 +511,6 @@ pub(crate) fn match_arm_list(p: &mut Parser<'_>) {
             error_block(p, "expected match arm");
             continue;
         }
-        if p.at(T![,]) {
-            p.err_and_bump("expected pattern");
-            continue;
-        }
         match_arm(p);
     }
     p.expect(T!['}']);
@@ -560,30 +544,26 @@ fn match_arm(p: &mut Parser<'_>) {
     // }
     attributes::outer_attrs(p);
 
-    patterns::pattern_top_r(p, TokenSet::new(&[T![=], T![if]]));
+    patterns::pattern_top_r(p, TokenSet::EMPTY);
     if p.at(T![if]) {
         match_guard(p);
     }
     p.expect(T![=>]);
-    if p.eat(T![,]) {
-        p.error("expected expression");
-    } else {
-        let blocklike = match expr_stmt(p, None) {
-            Some((_, blocklike)) => blocklike,
-            None => BlockLike::NotBlock,
-        };
-
-        // test match_arms_commas
-        // fn foo() {
-        //     match () {
-        //         _ => (),
-        //         _ => {}
-        //         _ => ()
-        //     }
-        // }
-        if !p.eat(T![,]) && !blocklike.is_block() && !p.at(T!['}']) {
-            p.error("expected `,`");
-        }
+    let blocklike = match expr_stmt(p, None) {
+        Some((_, blocklike)) => blocklike,
+        None => BlockLike::NotBlock,
+    };
+
+    // test match_arms_commas
+    // fn foo() {
+    //     match () {
+    //         _ => (),
+    //         _ => {}
+    //         _ => ()
+    //     }
+    // }
+    if !p.eat(T![,]) && !blocklike.is_block() && !p.at(T!['}']) {
+        p.error("expected `,`");
     }
     m.complete(p, MATCH_ARM);
 }
@@ -599,11 +579,7 @@ fn match_guard(p: &mut Parser<'_>) -> CompletedMarker {
     assert!(p.at(T![if]));
     let m = p.start();
     p.bump(T![if]);
-    if p.at(T![=]) {
-        p.error("expected expression");
-    } else {
-        expr(p);
-    }
+    expr(p);
     m.complete(p, MATCH_GUARD)
 }
 
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index 1b4c33d858..8516ffa0df 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -307,16 +307,18 @@ impl GlobalState {
             for file in changed_files {
                 let vfs_path = vfs.file_path(file.file_id);
                 if let Some(path) = vfs_path.as_path() {
-                    let path = path.to_path_buf();
-                    if reload::should_refresh_for_change(&path, file.kind()) {
-                        workspace_structure_change = Some((path.clone(), false));
+                    has_structure_changes = file.is_created_or_deleted();
+
+                    if file.is_modified() && path.extension() == Some("rs") {
+                        modified_rust_files.push(file.file_id);
                     }
+
+                    let path = path.to_path_buf();
                     if file.is_created_or_deleted() {
-                        has_structure_changes = true;
-                        workspace_structure_change =
-                            Some((path, self.crate_graph_file_dependencies.contains(vfs_path)));
-                    } else if path.extension() == Some("rs".as_ref()) {
-                        modified_rust_files.push(file.file_id);
+                        workspace_structure_change.get_or_insert((path, false)).1 |=
+                            self.crate_graph_file_dependencies.contains(vfs_path);
+                    } else if reload::should_refresh_for_change(&path, file.kind()) {
+                        workspace_structure_change.get_or_insert((path.clone(), false));
                     }
                 }
 
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 666bf2920e..d602506939 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -653,7 +653,7 @@ impl GlobalState {
                 };
 
                 if let Some(state) = state {
-                    self.report_progress("Building build-artifacts", state, msg, None, None);
+                    self.report_progress("Building", state, msg, None, None);
                 }
             }
             Task::LoadProcMacros(progress) => {
@@ -669,7 +669,7 @@ impl GlobalState {
                 };
 
                 if let Some(state) = state {
-                    self.report_progress("Loading proc-macros", state, msg, None, None);
+                    self.report_progress("Loading", state, msg, None, None);
                 }
             }
             Task::BuildDepsHaveChanged => self.build_deps_changed = true,
@@ -860,7 +860,7 @@ impl GlobalState {
                 let title = if self.flycheck.len() == 1 {
                     format!("{}", self.config.flycheck())
                 } else {
-                    format!("{} (#{})", self.config.flycheck(), id + 1)
+                    format!("cargo check (#{})", id + 1)
                 };
                 self.report_progress(
                     &title,
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 5dc152142e..507f584ff7 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -524,32 +524,15 @@ impl GlobalState {
         // crate graph construction relies on these paths, record them so when one of them gets
         // deleted or created we trigger a reconstruction of the crate graph
         let mut crate_graph_file_dependencies = FxHashSet::default();
-        self.report_progress(
-            "Building CrateGraph",
-            crate::lsp::utils::Progress::Begin,
-            None,
-            None,
-            None,
-        );
 
         let (crate_graph, proc_macro_paths, layouts, toolchains) = {
             // Create crate graph from all the workspaces
             let vfs = &mut self.vfs.write().0;
-            let loader = &mut self.loader;
 
             let load = |path: &AbsPath| {
-                let _p = tracing::span!(tracing::Level::DEBUG, "switch_workspaces::load").entered();
                 let vfs_path = vfs::VfsPath::from(path.to_path_buf());
                 crate_graph_file_dependencies.insert(vfs_path.clone());
-                match vfs.file_id(&vfs_path) {
-                    Some(file_id) => Some(file_id),
-                    None => {
-                        // FIXME: Consider not loading this here?
-                        let contents = loader.handle.load_sync(path);
-                        vfs.set_file_contents(vfs_path.clone(), contents);
-                        vfs.file_id(&vfs_path)
-                    }
-                }
+                vfs.file_id(&vfs_path)
             };
 
             ws_to_crate_graph(&self.workspaces, self.config.extra_env(), load)
@@ -569,13 +552,6 @@ impl GlobalState {
         change.set_toolchains(toolchains);
         self.analysis_host.apply_change(change);
         self.crate_graph_file_dependencies = crate_graph_file_dependencies;
-        self.report_progress(
-            "Building CrateGraph",
-            crate::lsp::utils::Progress::End,
-            None,
-            None,
-            None,
-        );
 
         self.process_changes();
         self.reload_flycheck();
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml
index 1809ca7dea..9a8d73cf7f 100644
--- a/crates/syntax/Cargo.toml
+++ b/crates/syntax/Cargo.toml
@@ -33,8 +33,12 @@ text-edit.workspace = true
 [dev-dependencies]
 rayon.workspace = true
 expect-test = "1.4.0"
+proc-macro2 = "1.0.47"
+quote = "1.0.20"
+ungrammar = "1.16.1"
 
 test-utils.workspace = true
+sourcegen.workspace = true
 
 [features]
 in-rust-tree = []
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index c82bc4151a..e880165366 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -44,10 +44,10 @@ pub struct ArrayType {
 }
 impl ArrayType {
     pub fn const_arg(&self) -> Option<ConstArg> { support::child(&self.syntax) }
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
     pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -56,12 +56,12 @@ pub struct AsmExpr {
 }
 impl ast::HasAttrs for AsmExpr {}
 impl AsmExpr {
+    pub fn asm_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![asm]) }
+    pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
-    pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
     pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
-    pub fn asm_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![asm]) }
-    pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -82,12 +82,12 @@ pub struct AssocTypeArg {
 impl ast::HasTypeBounds for AssocTypeArg {}
 impl AssocTypeArg {
     pub fn const_arg(&self) -> Option<ConstArg> { support::child(&self.syntax) }
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn generic_arg_list(&self) -> Option<GenericArgList> { support::child(&self.syntax) }
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
     pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
     pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
     pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -95,10 +95,10 @@ pub struct Attr {
     pub(crate) syntax: SyntaxNode,
 }
 impl Attr {
-    pub fn meta(&self) -> Option<Meta> { support::child(&self.syntax) }
     pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
-    pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
     pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
+    pub fn meta(&self) -> Option<Meta> { support::child(&self.syntax) }
+    pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
     pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
 }
 
@@ -108,9 +108,9 @@ pub struct AwaitExpr {
 }
 impl ast::HasAttrs for AwaitExpr {}
 impl AwaitExpr {
-    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
-    pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
     pub fn await_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![await]) }
+    pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -119,8 +119,8 @@ pub struct BecomeExpr {
 }
 impl ast::HasAttrs for BecomeExpr {}
 impl BecomeExpr {
-    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn become_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![become]) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -136,10 +136,10 @@ pub struct BlockExpr {
 }
 impl ast::HasAttrs for BlockExpr {}
 impl BlockExpr {
-    pub fn label(&self) -> Option<Label> { support::child(&self.syntax) }
-    pub fn stmt_list(&self) -> Option<StmtList> { support::child(&self.syntax) }
     pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
+    pub fn label(&self) -> Option<Label> { support::child(&self.syntax) }
+    pub fn stmt_list(&self) -> Option<StmtList> { support::child(&self.syntax) }
     pub fn try_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![try]) }
     pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
 }
@@ -149,8 +149,8 @@ pub struct BoxPat {
     pub(crate) syntax: SyntaxNode,
 }
 impl BoxPat {
-    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn box_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![box]) }
+    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -159,9 +159,9 @@ pub struct BreakExpr {
 }
 impl ast::HasAttrs for BreakExpr {}
 impl BreakExpr {
+    pub fn break_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![break]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
-    pub fn break_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![break]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -180,9 +180,9 @@ pub struct CastExpr {
 }
 impl ast::HasAttrs for CastExpr {}
 impl CastExpr {
+    pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -191,14 +191,14 @@ pub struct ClosureExpr {
 }
 impl ast::HasAttrs for ClosureExpr {}
 impl ClosureExpr {
-    pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
-    pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
-    pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
-    pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
     pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
+    pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
     pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
+    pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
     pub fn move_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![move]) }
+    pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
+    pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
     pub fn static_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![static]) }
 }
 
@@ -212,13 +212,13 @@ impl ast::HasName for Const {}
 impl ast::HasVisibility for Const {}
 impl Const {
     pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
-    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
-    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
-    pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
     pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
+    pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -245,11 +245,11 @@ pub struct ConstParam {
 impl ast::HasAttrs for ConstParam {}
 impl ast::HasName for ConstParam {}
 impl ConstParam {
-    pub fn default_val(&self) -> Option<ConstArg> { support::child(&self.syntax) }
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
-    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
+    pub fn default_val(&self) -> Option<ConstArg> { support::child(&self.syntax) }
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -258,10 +258,10 @@ pub struct ContinueExpr {
 }
 impl ast::HasAttrs for ContinueExpr {}
 impl ContinueExpr {
-    pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
     pub fn continue_token(&self) -> Option<SyntaxToken> {
         support::token(&self.syntax, T![continue])
     }
+    pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -269,8 +269,8 @@ pub struct DynTraitType {
     pub(crate) syntax: SyntaxNode,
 }
 impl DynTraitType {
-    pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
     pub fn dyn_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![dyn]) }
+    pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -283,8 +283,8 @@ impl ast::HasGenericParams for Enum {}
 impl ast::HasName for Enum {}
 impl ast::HasVisibility for Enum {}
 impl Enum {
-    pub fn variant_list(&self) -> Option<VariantList> { support::child(&self.syntax) }
     pub fn enum_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![enum]) }
+    pub fn variant_list(&self) -> Option<VariantList> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -316,11 +316,11 @@ impl ast::HasAttrs for ExternCrate {}
 impl ast::HasDocComments for ExternCrate {}
 impl ast::HasVisibility for ExternCrate {}
 impl ExternCrate {
+    pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
+    pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) }
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
     pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
-    pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
-    pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -340,9 +340,9 @@ pub struct FieldExpr {
 }
 impl ast::HasAttrs for FieldExpr {}
 impl FieldExpr {
+    pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
-    pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -356,14 +356,14 @@ impl ast::HasName for Fn {}
 impl ast::HasVisibility for Fn {}
 impl Fn {
     pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
-    pub fn body(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
-    pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
-    pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
-    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
     pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
+    pub fn body(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
     pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
     pub fn fn_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![fn]) }
+    pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
+    pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
+    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
     pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
 }
 
@@ -373,11 +373,11 @@ pub struct FnPtrType {
 }
 impl FnPtrType {
     pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
-    pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
-    pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
     pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
     pub fn fn_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![fn]) }
+    pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
+    pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
     pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
 }
 
@@ -387,9 +387,9 @@ pub struct ForExpr {
 }
 impl ast::HasAttrs for ForExpr {}
 impl ForExpr {
-    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
     pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) }
+    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -397,9 +397,9 @@ pub struct ForType {
     pub(crate) syntax: SyntaxNode,
 }
 impl ForType {
+    pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
     pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
     pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -408,8 +408,8 @@ pub struct FormatArgsArg {
 }
 impl ast::HasName for FormatArgsArg {}
 impl FormatArgsArg {
-    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -419,15 +419,15 @@ pub struct FormatArgsExpr {
 impl ast::HasAttrs for FormatArgsExpr {}
 impl FormatArgsExpr {
     pub fn args(&self) -> AstChildren<FormatArgsArg> { support::children(&self.syntax) }
-    pub fn template(&self) -> Option<Expr> { support::child(&self.syntax) }
-    pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
-    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
-    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
-    pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
     pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
+    pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
     pub fn format_args_token(&self) -> Option<SyntaxToken> {
         support::token(&self.syntax, T![format_args])
     }
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+    pub fn template(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -435,8 +435,8 @@ pub struct GenericArgList {
     pub(crate) syntax: SyntaxNode,
 }
 impl GenericArgList {
-    pub fn generic_args(&self) -> AstChildren<GenericArg> { support::children(&self.syntax) }
     pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
+    pub fn generic_args(&self) -> AstChildren<GenericArg> { support::children(&self.syntax) }
     pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
     pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
 }
@@ -458,9 +458,9 @@ pub struct IdentPat {
 impl ast::HasAttrs for IdentPat {}
 impl ast::HasName for IdentPat {}
 impl IdentPat {
-    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn at_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![@]) }
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
+    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn ref_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ref]) }
 }
 
@@ -484,9 +484,9 @@ impl ast::HasGenericParams for Impl {}
 impl ast::HasVisibility for Impl {}
 impl Impl {
     pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) }
-    pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
     pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
+    pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
     pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
     pub fn impl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![impl]) }
     pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
@@ -497,8 +497,8 @@ pub struct ImplTraitType {
     pub(crate) syntax: SyntaxNode,
 }
 impl ImplTraitType {
-    pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
     pub fn impl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![impl]) }
+    pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -535,8 +535,8 @@ pub struct Label {
     pub(crate) syntax: SyntaxNode,
 }
 impl Label {
-    pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
     pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
+    pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -554,10 +554,10 @@ pub struct LetExpr {
 }
 impl ast::HasAttrs for LetExpr {}
 impl LetExpr {
-    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
-    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn let_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![let]) }
+    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -566,14 +566,14 @@ pub struct LetStmt {
 }
 impl ast::HasAttrs for LetStmt {}
 impl LetStmt {
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn initializer(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn let_else(&self) -> Option<LetElse> { support::child(&self.syntax) }
+    pub fn let_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![let]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
-    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
-    pub fn let_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![let]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -637,10 +637,10 @@ pub struct MacroCall {
 impl ast::HasAttrs for MacroCall {}
 impl ast::HasDocComments for MacroCall {}
 impl MacroCall {
-    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
-    pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
     pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
+    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
+    pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -663,12 +663,12 @@ pub struct MacroEagerInput {
 }
 impl MacroEagerInput {
     pub fn exprs(&self) -> AstChildren<Expr> { support::children(&self.syntax) }
-    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
-    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
     pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
-    pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
     pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -703,11 +703,11 @@ impl ast::HasDocComments for MacroRules {}
 impl ast::HasName for MacroRules {}
 impl ast::HasVisibility for MacroRules {}
 impl MacroRules {
-    pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
     pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
     pub fn macro_rules_token(&self) -> Option<SyntaxToken> {
         support::token(&self.syntax, T![macro_rules])
     }
+    pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -733,11 +733,11 @@ pub struct MatchArm {
 }
 impl ast::HasAttrs for MatchArm {}
 impl MatchArm {
+    pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+    pub fn fat_arrow_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=>]) }
     pub fn guard(&self) -> Option<MatchGuard> { support::child(&self.syntax) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
-    pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
-    pub fn fat_arrow_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=>]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -775,10 +775,10 @@ pub struct Meta {
     pub(crate) syntax: SyntaxNode,
 }
 impl Meta {
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
     pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
-    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -788,10 +788,10 @@ pub struct MethodCallExpr {
 impl ast::HasArgList for MethodCallExpr {}
 impl ast::HasAttrs for MethodCallExpr {}
 impl MethodCallExpr {
+    pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
     pub fn generic_arg_list(&self) -> Option<GenericArgList> { support::child(&self.syntax) }
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
     pub fn receiver(&self) -> Option<Expr> { support::child(&self.syntax) }
-    pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -804,8 +804,8 @@ impl ast::HasName for Module {}
 impl ast::HasVisibility for Module {}
 impl Module {
     pub fn item_list(&self) -> Option<ItemList> { support::child(&self.syntax) }
-    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
     pub fn mod_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mod]) }
+    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -843,16 +843,16 @@ pub struct OffsetOfExpr {
 }
 impl ast::HasAttrs for OffsetOfExpr {}
 impl OffsetOfExpr {
+    pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
+    pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
     pub fn fields(&self) -> AstChildren<NameRef> { support::children(&self.syntax) }
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
     pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
-    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
-    pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
-    pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
     pub fn offset_of_token(&self) -> Option<SyntaxToken> {
         support::token(&self.syntax, T![offset_of])
     }
+    pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -869,10 +869,10 @@ pub struct Param {
 }
 impl ast::HasAttrs for Param {}
 impl Param {
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
+    pub fn dotdotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![...]) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn dotdotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![...]) }
-    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -880,12 +880,12 @@ pub struct ParamList {
     pub(crate) syntax: SyntaxNode,
 }
 impl ParamList {
-    pub fn params(&self) -> AstChildren<Param> { support::children(&self.syntax) }
-    pub fn self_param(&self) -> Option<SelfParam> { support::child(&self.syntax) }
-    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
-    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
     pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn params(&self) -> AstChildren<Param> { support::children(&self.syntax) }
     pub fn pipe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![|]) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+    pub fn self_param(&self) -> Option<SelfParam> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -904,8 +904,8 @@ pub struct ParenPat {
     pub(crate) syntax: SyntaxNode,
 }
 impl ParenPat {
-    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
 
@@ -914,9 +914,9 @@ pub struct ParenType {
     pub(crate) syntax: SyntaxNode,
 }
 impl ParenType {
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -924,9 +924,9 @@ pub struct Path {
     pub(crate) syntax: SyntaxNode,
 }
 impl Path {
+    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
     pub fn qualifier(&self) -> Option<Path> { support::child(&self.syntax) }
     pub fn segment(&self) -> Option<PathSegment> { support::child(&self.syntax) }
-    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -951,16 +951,16 @@ pub struct PathSegment {
     pub(crate) syntax: SyntaxNode,
 }
 impl PathSegment {
+    pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
+    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
     pub fn generic_arg_list(&self) -> Option<GenericArgList> { support::child(&self.syntax) }
+    pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
     pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
     pub fn path_type(&self) -> Option<PathType> { support::child(&self.syntax) }
+    pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
     pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
     pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
-    pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
-    pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
-    pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -985,10 +985,10 @@ pub struct PtrType {
     pub(crate) syntax: SyntaxNode,
 }
 impl PtrType {
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
+    pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1021,9 +1021,9 @@ pub struct RecordExprField {
 }
 impl ast::HasAttrs for RecordExprField {}
 impl RecordExprField {
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
-    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1032,11 +1032,11 @@ pub struct RecordExprFieldList {
 }
 impl ast::HasAttrs for RecordExprFieldList {}
 impl RecordExprFieldList {
+    pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
     pub fn fields(&self) -> AstChildren<RecordExprField> { support::children(&self.syntax) }
-    pub fn spread(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
-    pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
+    pub fn spread(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1048,8 +1048,8 @@ impl ast::HasDocComments for RecordField {}
 impl ast::HasName for RecordField {}
 impl ast::HasVisibility for RecordField {}
 impl RecordField {
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1079,9 +1079,9 @@ pub struct RecordPatField {
 }
 impl ast::HasAttrs for RecordPatField {}
 impl RecordPatField {
+    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
     pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
     pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
-    pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1090,9 +1090,9 @@ pub struct RecordPatFieldList {
 }
 impl RecordPatFieldList {
     pub fn fields(&self) -> AstChildren<RecordPatField> { support::children(&self.syntax) }
-    pub fn rest_pat(&self) -> Option<RestPat> { support::child(&self.syntax) }
     pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
+    pub fn rest_pat(&self) -> Option<RestPat> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1101,9 +1101,9 @@ pub struct RefExpr {
 }
 impl ast::HasAttrs for RefExpr {}
 impl RefExpr {
-    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
     pub fn raw_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![raw]) }
 }
@@ -1113,9 +1113,9 @@ pub struct RefPat {
     pub(crate) syntax: SyntaxNode,
 }
 impl RefPat {
-    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
     pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
+    pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1123,10 +1123,10 @@ pub struct RefType {
     pub(crate) syntax: SyntaxNode,
 }
 impl RefType {
-    pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
+    pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1135,8 +1135,8 @@ pub struct Rename {
 }
 impl ast::HasName for Rename {}
 impl Rename {
-    pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
     pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
+    pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1153,8 +1153,8 @@ pub struct RetType {
     pub(crate) syntax: SyntaxNode,
 }
 impl RetType {
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn thin_arrow_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![->]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1174,11 +1174,11 @@ pub struct SelfParam {
 impl ast::HasAttrs for SelfParam {}
 impl ast::HasName for SelfParam {}
 impl SelfParam {
-    pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
     pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
+    pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1186,8 +1186,8 @@ pub struct SlicePat {
     pub(crate) syntax: SyntaxNode,
 }
 impl SlicePat {
-    pub fn pats(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
     pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
+    pub fn pats(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
     pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
 }
 
@@ -1196,9 +1196,9 @@ pub struct SliceType {
     pub(crate) syntax: SyntaxNode,
 }
 impl SliceType {
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
     pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1222,12 +1222,12 @@ impl ast::HasName for Static {}
 impl ast::HasVisibility for Static {}
 impl Static {
     pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
-    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
+    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
     pub fn static_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![static]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1236,10 +1236,10 @@ pub struct StmtList {
 }
 impl ast::HasAttrs for StmtList {}
 impl StmtList {
-    pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
-    pub fn tail_expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
+    pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
+    pub fn tail_expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1262,12 +1262,12 @@ pub struct TokenTree {
     pub(crate) syntax: SyntaxNode,
 }
 impl TokenTree {
-    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
-    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
     pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
-    pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
     pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1297,10 +1297,10 @@ impl ast::HasGenericParams for TraitAlias {}
 impl ast::HasName for TraitAlias {}
 impl ast::HasVisibility for TraitAlias {}
 impl TraitAlias {
-    pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
-    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
     pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
     pub fn trait_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![trait]) }
+    pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1361,8 +1361,8 @@ pub struct TupleStructPat {
 }
 impl TupleStructPat {
     pub fn fields(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
-    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
     pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
 
@@ -1387,10 +1387,10 @@ impl ast::HasName for TypeAlias {}
 impl ast::HasTypeBounds for TypeAlias {}
 impl ast::HasVisibility for TypeAlias {}
 impl TypeAlias {
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
-    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+    pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
     pub fn type_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![type]) }
 }
 
@@ -1407,12 +1407,12 @@ pub struct TypeBound {
     pub(crate) syntax: SyntaxNode,
 }
 impl TypeBound {
-    pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
-    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn question_mark_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![?]) }
     pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
     pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
+    pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
+    pub fn question_mark_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![?]) }
     pub fn tilde_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![~]) }
+    pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1466,9 +1466,9 @@ impl ast::HasAttrs for Use {}
 impl ast::HasDocComments for Use {}
 impl ast::HasVisibility for Use {}
 impl Use {
-    pub fn use_tree(&self) -> Option<UseTree> { support::child(&self.syntax) }
     pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
     pub fn use_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![use]) }
+    pub fn use_tree(&self) -> Option<UseTree> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1476,11 +1476,11 @@ pub struct UseTree {
     pub(crate) syntax: SyntaxNode,
 }
 impl UseTree {
+    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
     pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
     pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) }
-    pub fn use_tree_list(&self) -> Option<UseTreeList> { support::child(&self.syntax) }
     pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) }
-    pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
+    pub fn use_tree_list(&self) -> Option<UseTreeList> { support::child(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1488,9 +1488,9 @@ pub struct UseTreeList {
     pub(crate) syntax: SyntaxNode,
 }
 impl UseTreeList {
-    pub fn use_trees(&self) -> AstChildren<UseTree> { support::children(&self.syntax) }
     pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
+    pub fn use_trees(&self) -> AstChildren<UseTree> { support::children(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1502,9 +1502,9 @@ impl ast::HasDocComments for Variant {}
 impl ast::HasName for Variant {}
 impl ast::HasVisibility for Variant {}
 impl Variant {
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn field_list(&self) -> Option<FieldList> { support::child(&self.syntax) }
-    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1512,9 +1512,9 @@ pub struct VariantList {
     pub(crate) syntax: SyntaxNode,
 }
 impl VariantList {
-    pub fn variants(&self) -> AstChildren<Variant> { support::children(&self.syntax) }
     pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
     pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
+    pub fn variants(&self) -> AstChildren<Variant> { support::children(&self.syntax) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1522,11 +1522,11 @@ pub struct Visibility {
     pub(crate) syntax: SyntaxNode,
 }
 impl Visibility {
-    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
-    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
-    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
     pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) }
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
     pub fn pub_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![pub]) }
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1544,10 +1544,10 @@ pub struct WherePred {
 }
 impl ast::HasTypeBounds for WherePred {}
 impl WherePred {
+    pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
     pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
     pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
     pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
-    pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1573,8 +1573,8 @@ pub struct YeetExpr {
 }
 impl ast::HasAttrs for YeetExpr {}
 impl YeetExpr {
-    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn do_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![do]) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
     pub fn yeet_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![yeet]) }
 }
 
@@ -4123,78 +4123,78 @@ impl AstNode for AnyHasAttrs {
     fn can_cast(kind: SyntaxKind) -> bool {
         matches!(
             kind,
-            ARRAY_EXPR
-                | ASM_EXPR
+            MACRO_CALL
+                | SOURCE_FILE
+                | CONST
+                | ENUM
+                | EXTERN_BLOCK
+                | EXTERN_CRATE
+                | FN
+                | IMPL
+                | MACRO_RULES
+                | MACRO_DEF
+                | MODULE
+                | STATIC
+                | STRUCT
+                | TRAIT
+                | TRAIT_ALIAS
+                | TYPE_ALIAS
+                | UNION
+                | USE
+                | ITEM_LIST
+                | BLOCK_EXPR
+                | SELF_PARAM
+                | PARAM
+                | RECORD_FIELD
+                | TUPLE_FIELD
+                | VARIANT
                 | ASSOC_ITEM_LIST
+                | EXTERN_ITEM_LIST
+                | CONST_PARAM
+                | LIFETIME_PARAM
+                | TYPE_PARAM
+                | LET_STMT
+                | ARRAY_EXPR
+                | ASM_EXPR
                 | AWAIT_EXPR
-                | BECOME_EXPR
                 | BIN_EXPR
-                | BLOCK_EXPR
                 | BREAK_EXPR
                 | CALL_EXPR
                 | CAST_EXPR
                 | CLOSURE_EXPR
-                | CONST
-                | CONST_PARAM
                 | CONTINUE_EXPR
-                | ENUM
-                | EXTERN_BLOCK
-                | EXTERN_CRATE
-                | EXTERN_ITEM_LIST
                 | FIELD_EXPR
-                | FN
                 | FOR_EXPR
                 | FORMAT_ARGS_EXPR
-                | IDENT_PAT
                 | IF_EXPR
-                | IMPL
                 | INDEX_EXPR
-                | ITEM_LIST
-                | LET_EXPR
-                | LET_STMT
-                | LIFETIME_PARAM
                 | LITERAL
                 | LOOP_EXPR
-                | MACRO_CALL
-                | MACRO_DEF
-                | MACRO_RULES
-                | MATCH_ARM
-                | MATCH_ARM_LIST
                 | MATCH_EXPR
                 | METHOD_CALL_EXPR
-                | MODULE
                 | OFFSET_OF_EXPR
-                | PARAM
                 | PAREN_EXPR
                 | PATH_EXPR
                 | PREFIX_EXPR
                 | RANGE_EXPR
-                | RECORD_EXPR_FIELD
-                | RECORD_EXPR_FIELD_LIST
-                | RECORD_FIELD
-                | RECORD_PAT_FIELD
                 | REF_EXPR
-                | REST_PAT
                 | RETURN_EXPR
-                | SELF_PARAM
-                | SOURCE_FILE
-                | STATIC
-                | STMT_LIST
-                | STRUCT
-                | TRAIT
-                | TRAIT_ALIAS
+                | BECOME_EXPR
                 | TRY_EXPR
                 | TUPLE_EXPR
-                | TUPLE_FIELD
-                | TYPE_ALIAS
-                | TYPE_PARAM
-                | UNDERSCORE_EXPR
-                | UNION
-                | USE
-                | VARIANT
                 | WHILE_EXPR
-                | YEET_EXPR
                 | YIELD_EXPR
+                | YEET_EXPR
+                | LET_EXPR
+                | UNDERSCORE_EXPR
+                | STMT_LIST
+                | RECORD_EXPR_FIELD_LIST
+                | RECORD_EXPR_FIELD
+                | MATCH_ARM_LIST
+                | MATCH_ARM
+                | IDENT_PAT
+                | REST_PAT
+                | RECORD_PAT_FIELD
         )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -4212,26 +4212,26 @@ impl AstNode for AnyHasDocComments {
     fn can_cast(kind: SyntaxKind) -> bool {
         matches!(
             kind,
-            CONST
+            MACRO_CALL
+                | SOURCE_FILE
+                | CONST
                 | ENUM
                 | EXTERN_BLOCK
                 | EXTERN_CRATE
                 | FN
                 | IMPL
-                | MACRO_CALL
-                | MACRO_DEF
                 | MACRO_RULES
+                | MACRO_DEF
                 | MODULE
-                | RECORD_FIELD
-                | SOURCE_FILE
                 | STATIC
                 | STRUCT
                 | TRAIT
                 | TRAIT_ALIAS
-                | TUPLE_FIELD
                 | TYPE_ALIAS
                 | UNION
                 | USE
+                | RECORD_FIELD
+                | TUPLE_FIELD
                 | VARIANT
         )
     }
@@ -4275,7 +4275,7 @@ impl AnyHasModuleItem {
     }
 }
 impl AstNode for AnyHasModuleItem {
-    fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, ITEM_LIST | MACRO_ITEMS | SOURCE_FILE) }
+    fn can_cast(kind: SyntaxKind) -> bool { matches!(kind, MACRO_ITEMS | SOURCE_FILE | ITEM_LIST) }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
         Self::can_cast(syntax.kind()).then_some(AnyHasModuleItem { syntax })
     }
@@ -4292,25 +4292,25 @@ impl AstNode for AnyHasName {
         matches!(
             kind,
             CONST
-                | CONST_PARAM
                 | ENUM
                 | FN
-                | FORMAT_ARGS_ARG
-                | IDENT_PAT
-                | MACRO_DEF
                 | MACRO_RULES
+                | MACRO_DEF
                 | MODULE
-                | RECORD_FIELD
-                | RENAME
-                | SELF_PARAM
                 | STATIC
                 | STRUCT
                 | TRAIT
                 | TRAIT_ALIAS
                 | TYPE_ALIAS
-                | TYPE_PARAM
                 | UNION
+                | RENAME
+                | SELF_PARAM
+                | RECORD_FIELD
                 | VARIANT
+                | CONST_PARAM
+                | TYPE_PARAM
+                | FORMAT_ARGS_ARG
+                | IDENT_PAT
         )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -4328,7 +4328,7 @@ impl AstNode for AnyHasTypeBounds {
     fn can_cast(kind: SyntaxKind) -> bool {
         matches!(
             kind,
-            ASSOC_TYPE_ARG | LIFETIME_PARAM | TRAIT | TYPE_ALIAS | TYPE_PARAM | WHERE_PRED
+            ASSOC_TYPE_ARG | TRAIT | TYPE_ALIAS | LIFETIME_PARAM | TYPE_PARAM | WHERE_PRED
         )
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -4351,18 +4351,18 @@ impl AstNode for AnyHasVisibility {
                 | EXTERN_CRATE
                 | FN
                 | IMPL
-                | MACRO_DEF
                 | MACRO_RULES
+                | MACRO_DEF
                 | MODULE
-                | RECORD_FIELD
                 | STATIC
                 | STRUCT
                 | TRAIT
                 | TRAIT_ALIAS
-                | TUPLE_FIELD
                 | TYPE_ALIAS
                 | UNION
                 | USE
+                | RECORD_FIELD
+                | TUPLE_FIELD
                 | VARIANT
         )
     }
@@ -4371,62 +4371,12 @@ impl AstNode for AnyHasVisibility {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-impl std::fmt::Display for Adt {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for AssocItem {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for Expr {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for ExternItem {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for FieldList {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-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 std::fmt::Display for GenericParam {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for Item {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for Pat {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for Stmt {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        std::fmt::Display::fmt(self.syntax(), f)
-    }
-}
-impl std::fmt::Display for Type {
+impl std::fmt::Display for Abi {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
-impl std::fmt::Display for Abi {
+impl std::fmt::Display for Adt {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
@@ -4451,6 +4401,11 @@ impl std::fmt::Display for AsmExpr {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for AssocItem {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for AssocItemList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -4546,6 +4501,11 @@ impl std::fmt::Display for Enum {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for Expr {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for ExprStmt {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -4561,6 +4521,11 @@ impl std::fmt::Display for ExternCrate {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for ExternItem {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for ExternItemList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -4571,6 +4536,11 @@ impl std::fmt::Display for FieldExpr {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for FieldList {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for Fn {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -4601,11 +4571,21 @@ impl std::fmt::Display for FormatArgsExpr {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+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 std::fmt::Display for GenericArgList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+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 std::fmt::Display for GenericParamList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -4641,6 +4621,11 @@ impl std::fmt::Display for InferType {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for Item {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for ItemList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -4826,6 +4811,11 @@ impl std::fmt::Display for ParenType {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for Pat {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for Path {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -4971,6 +4961,11 @@ impl std::fmt::Display for Static {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for Stmt {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for StmtList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -5031,6 +5026,11 @@ impl std::fmt::Display for TupleType {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for Type {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for TypeAlias {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
diff --git a/crates/syntax/src/ast/generated/tokens.rs b/crates/syntax/src/ast/generated/tokens.rs
index 651a8ebbf7..f5863e9efe 100644
--- a/crates/syntax/src/ast/generated/tokens.rs
+++ b/crates/syntax/src/ast/generated/tokens.rs
@@ -7,16 +7,16 @@ use crate::{
 };
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Byte {
+pub struct Whitespace {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for Byte {
+impl std::fmt::Display for Whitespace {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for Byte {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == BYTE }
+impl AstToken for Whitespace {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == WHITESPACE }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -28,16 +28,16 @@ impl AstToken for Byte {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ByteString {
+pub struct Comment {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for ByteString {
+impl std::fmt::Display for Comment {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for ByteString {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == BYTE_STRING }
+impl AstToken for Comment {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == COMMENT }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -49,16 +49,16 @@ impl AstToken for ByteString {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct CString {
+pub struct String {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for CString {
+impl std::fmt::Display for String {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for CString {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == C_STRING }
+impl AstToken for String {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == STRING }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -70,16 +70,16 @@ impl AstToken for CString {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Char {
+pub struct ByteString {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for Char {
+impl std::fmt::Display for ByteString {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for Char {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == CHAR }
+impl AstToken for ByteString {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == BYTE_STRING }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -91,16 +91,16 @@ impl AstToken for Char {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Comment {
+pub struct CString {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for Comment {
+impl std::fmt::Display for CString {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for Comment {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == COMMENT }
+impl AstToken for CString {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == C_STRING }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -112,16 +112,16 @@ impl AstToken for Comment {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct FloatNumber {
+pub struct IntNumber {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for FloatNumber {
+impl std::fmt::Display for IntNumber {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for FloatNumber {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == FLOAT_NUMBER }
+impl AstToken for IntNumber {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == INT_NUMBER }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -133,16 +133,16 @@ impl AstToken for FloatNumber {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Ident {
+pub struct FloatNumber {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for Ident {
+impl std::fmt::Display for FloatNumber {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for Ident {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == IDENT }
+impl AstToken for FloatNumber {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == FLOAT_NUMBER }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -154,16 +154,16 @@ impl AstToken for Ident {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct IntNumber {
+pub struct Char {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for IntNumber {
+impl std::fmt::Display for Char {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for IntNumber {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == INT_NUMBER }
+impl AstToken for Char {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == CHAR }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -175,16 +175,16 @@ impl AstToken for IntNumber {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct String {
+pub struct Byte {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for String {
+impl std::fmt::Display for Byte {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for String {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == STRING }
+impl AstToken for Byte {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == BYTE }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -196,16 +196,16 @@ impl AstToken for String {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Whitespace {
+pub struct Ident {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for Whitespace {
+impl std::fmt::Display for Ident {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for Whitespace {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == WHITESPACE }
+impl AstToken for Ident {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == IDENT }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
diff --git a/xtask/src/codegen/grammar/ast_src.rs b/crates/syntax/src/tests/ast_src.rs
similarity index 100%
rename from xtask/src/codegen/grammar/ast_src.rs
rename to crates/syntax/src/tests/ast_src.rs
diff --git a/xtask/src/codegen/grammar.rs b/crates/syntax/src/tests/sourcegen_ast.rs
similarity index 92%
rename from xtask/src/codegen/grammar.rs
rename to crates/syntax/src/tests/sourcegen_ast.rs
index cc2fadc975..1572bbe32c 100644
--- a/xtask/src/codegen/grammar.rs
+++ b/crates/syntax/src/tests/sourcegen_ast.rs
@@ -3,45 +3,37 @@
 //! Specifically, it generates the `SyntaxKind` enum and a number of newtype
 //! wrappers around `SyntaxNode` which implement `syntax::AstNode`.
 
-#![allow(clippy::disallowed_types)]
-
-use std::{
-    collections::{BTreeSet, HashSet},
-    fmt::Write,
-    fs,
-};
+use std::{collections::BTreeSet, fmt::Write};
 
 use itertools::Itertools;
 use proc_macro2::{Punct, Spacing};
 use quote::{format_ident, quote};
+use rustc_hash::FxHashSet;
 use ungrammar::{Grammar, Rule};
 
-use crate::{
-    codegen::{add_preamble, ensure_file_contents, reformat},
-    project_root,
+use crate::tests::ast_src::{
+    AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC,
 };
 
-mod ast_src;
-use self::ast_src::{AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC};
-
-pub(crate) fn generate(check: bool) {
+#[test]
+fn sourcegen_ast() {
     let syntax_kinds = generate_syntax_kinds(KINDS_SRC);
-    let syntax_kinds_file = project_root().join("crates/parser/src/syntax_kind/generated.rs");
-    ensure_file_contents(syntax_kinds_file.as_path(), &syntax_kinds, check);
+    let syntax_kinds_file =
+        sourcegen::project_root().join("crates/parser/src/syntax_kind/generated.rs");
+    sourcegen::ensure_file_contents(syntax_kinds_file.as_path(), &syntax_kinds);
 
-    let grammar = fs::read_to_string(project_root().join("crates/syntax/rust.ungram"))
-        .unwrap()
-        .parse()
-        .unwrap();
+    let grammar =
+        include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/rust.ungram")).parse().unwrap();
     let ast = lower(&grammar);
 
     let ast_tokens = generate_tokens(&ast);
-    let ast_tokens_file = project_root().join("crates/syntax/src/ast/generated/tokens.rs");
-    ensure_file_contents(ast_tokens_file.as_path(), &ast_tokens, check);
+    let ast_tokens_file =
+        sourcegen::project_root().join("crates/syntax/src/ast/generated/tokens.rs");
+    sourcegen::ensure_file_contents(ast_tokens_file.as_path(), &ast_tokens);
 
     let ast_nodes = generate_nodes(KINDS_SRC, &ast);
-    let ast_nodes_file = project_root().join("crates/syntax/src/ast/generated/nodes.rs");
-    ensure_file_contents(ast_nodes_file.as_path(), &ast_nodes, check);
+    let ast_nodes_file = sourcegen::project_root().join("crates/syntax/src/ast/generated/nodes.rs");
+    sourcegen::ensure_file_contents(ast_nodes_file.as_path(), &ast_nodes);
 }
 
 fn generate_tokens(grammar: &AstSrc) -> String {
@@ -68,9 +60,9 @@ fn generate_tokens(grammar: &AstSrc) -> String {
         }
     });
 
-    add_preamble(
+    sourcegen::add_preamble(
         "sourcegen_ast",
-        reformat(
+        sourcegen::reformat(
             quote! {
                 use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken};
                 #(#tokens)*
@@ -85,6 +77,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
     let (node_defs, node_boilerplate_impls): (Vec<_>, Vec<_>) = grammar
         .nodes
         .iter()
+        .sorted_by_key(|it| it.name.clone())
         .map(|node| {
             let name = format_ident!("{}", node.name);
             let kind = format_ident!("{}", to_upper_snake_case(&node.name));
@@ -96,12 +89,13 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
                     node.name != "ForExpr" && node.name != "WhileExpr"
                         || trait_name.as_str() != "HasLoopBody"
                 })
+                .sorted()
                 .map(|trait_name| {
                     let trait_name = format_ident!("{}", trait_name);
                     quote!(impl ast::#trait_name for #name {})
                 });
 
-            let methods = node.fields.iter().map(|field| {
+            let methods = node.fields.iter().sorted_by_key(|it| it.method_name()).map(|field| {
                 let method_name = field.method_name();
                 let ty = field.ty();
 
@@ -157,6 +151,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
     let (enum_defs, enum_boilerplate_impls): (Vec<_>, Vec<_>) = grammar
         .enums
         .iter()
+        .sorted_by_key(|it| it.name.clone())
         .map(|en| {
             let variants: Vec<_> =
                 en.variants.iter().map(|var| format_ident!("{}", var)).sorted().collect();
@@ -221,13 +216,14 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
             )
         })
         .unzip();
+
     let (any_node_defs, any_node_boilerplate_impls): (Vec<_>, Vec<_>) = grammar
         .nodes
         .iter()
         .flat_map(|node| node.traits.iter().map(move |t| (t, node)))
         .into_group_map()
         .into_iter()
-        .sorted_by_key(|(name, _)| *name)
+        .sorted_by_key(|(k, _)| *k)
         .map(|(trait_name, nodes)| {
             let name = format_ident!("Any{}", trait_name);
             let trait_name = format_ident!("{}", trait_name);
@@ -274,17 +270,19 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
     let node_names = grammar.nodes.iter().map(|it| &it.name);
 
     let display_impls =
-        enum_names.chain(node_names.clone()).map(|it| format_ident!("{}", it)).map(|name| {
-            quote! {
-                impl std::fmt::Display for #name {
-                    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-                        std::fmt::Display::fmt(self.syntax(), f)
+        enum_names.chain(node_names.clone()).map(|it| format_ident!("{}", it)).sorted().map(
+            |name| {
+                quote! {
+                    impl std::fmt::Display for #name {
+                        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+                            std::fmt::Display::fmt(self.syntax(), f)
+                        }
                     }
                 }
-            }
-        });
+            },
+        );
 
-    let defined_nodes: HashSet<_> = node_names.collect();
+    let defined_nodes: FxHashSet<_> = node_names.collect();
 
     for node in kinds
         .nodes
@@ -328,7 +326,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
         }
     }
 
-    let res = add_preamble("sourcegen_ast", reformat(res));
+    let res = sourcegen::add_preamble("sourcegen_ast", sourcegen::reformat(res));
     res.replace("#[derive", "\n#[derive")
 }
 
@@ -458,7 +456,7 @@ fn generate_syntax_kinds(grammar: KindsSrc<'_>) -> String {
         }
     };
 
-    add_preamble("sourcegen_ast", reformat(ast.to_string()))
+    sourcegen::add_preamble("sourcegen_ast", sourcegen::reformat(ast.to_string()))
 }
 
 fn to_upper_snake_case(s: &str) -> String {
@@ -608,20 +606,6 @@ fn lower(grammar: &Grammar) -> AstSrc {
     extract_enums(&mut res);
     extract_struct_traits(&mut res);
     extract_enum_traits(&mut res);
-    res.nodes.sort_by_key(|it| it.name.clone());
-    res.enums.sort_by_key(|it| it.name.clone());
-    res.tokens.sort();
-    res.nodes.iter_mut().for_each(|it| {
-        it.traits.sort();
-        it.fields.sort_by_key(|it| match it {
-            Field::Token(name) => (true, name.clone()),
-            Field::Node { name, .. } => (false, name.clone()),
-        });
-    });
-    res.enums.iter_mut().for_each(|it| {
-        it.traits.sort();
-        it.variants.sort();
-    });
     res
 }
 
diff --git a/crates/vfs/src/lib.rs b/crates/vfs/src/lib.rs
index 824ce39870..9d723f8143 100644
--- a/crates/vfs/src/lib.rs
+++ b/crates/vfs/src/lib.rs
@@ -121,6 +121,11 @@ impl ChangedFile {
         matches!(self.change, Change::Create(_) | Change::Delete)
     }
 
+    /// Returns `true` if the change is [`Modify`](ChangeKind::Modify).
+    pub fn is_modified(&self) -> bool {
+        matches!(self.change, Change::Modify(_))
+    }
+
     pub fn kind(&self) -> ChangeKind {
         match self.change {
             Change::Create(_) => ChangeKind::Create,
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index a83d32e414..5e758e0190 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -15,10 +15,6 @@ xflags = "0.3.0"
 time = { version = "0.3", default-features = false }
 zip = { version = "0.6", default-features = false, features = ["deflate", "time"] }
 stdx.workspace = true
-proc-macro2 = "1.0.47"
-quote = "1.0.20"
-ungrammar = "1.16.1"
-itertools.workspace = true
 # Avoid adding more dependencies to this crate
 
 [lints]
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs
index 7dc1b40783..40f872a24a 100644
--- a/xtask/src/codegen.rs
+++ b/xtask/src/codegen.rs
@@ -9,7 +9,6 @@ use crate::{flags, project_root};
 
 pub(crate) mod assists_doc_tests;
 pub(crate) mod diagnostics_docs;
-mod grammar;
 mod lints;
 
 impl flags::Codegen {
@@ -21,7 +20,6 @@ impl flags::Codegen {
                 // lints::generate(self.check) Updating clones the rust repo, so don't run it unless
                 // explicitly asked for
             }
-            flags::CodegenType::Grammar => grammar::generate(self.check),
             flags::CodegenType::AssistsDocTests => assists_doc_tests::generate(self.check),
             flags::CodegenType::DiagnosticsDocs => diagnostics_docs::generate(self.check),
             flags::CodegenType::LintDefinitions => lints::generate(self.check),
diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs
index f7ae0eb1b4..681c588bd0 100644
--- a/xtask/src/flags.rs
+++ b/xtask/src/flags.rs
@@ -91,7 +91,6 @@ pub struct Codegen {
 pub enum CodegenType {
     #[default]
     All,
-    Grammar,
     AssistsDocTests,
     DiagnosticsDocs,
     LintDefinitions,
@@ -102,7 +101,6 @@ impl FromStr for CodegenType {
     fn from_str(s: &str) -> Result<Self, Self::Err> {
         match s {
             "all" => Ok(Self::All),
-            "grammar" => Ok(Self::Grammar),
             "assists-doc-tests" => Ok(Self::AssistsDocTests),
             "diagnostics-docs" => Ok(Self::DiagnosticsDocs),
             "lints-definitions" => Ok(Self::LintDefinitions),


Test patch:
diff --git a/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rast b/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rast
deleted file mode 100644
index 5b191945e4..0000000000
--- a/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rast
+++ /dev/null
@@ -1,113 +0,0 @@
-SOURCE_FILE
-  FN
-    FN_KW "fn"
-    WHITESPACE " "
-    NAME
-      IDENT "foo"
-    PARAM_LIST
-      L_PAREN "("
-      R_PAREN ")"
-    WHITESPACE " "
-    BLOCK_EXPR
-      STMT_LIST
-        L_CURLY "{"
-        WHITESPACE "\n    "
-        MATCH_EXPR
-          MATCH_KW "match"
-          WHITESPACE " "
-          TUPLE_EXPR
-            L_PAREN "("
-            R_PAREN ")"
-          WHITESPACE " "
-          MATCH_ARM_LIST
-            L_CURLY "{"
-            WHITESPACE "\n        "
-            MATCH_ARM
-              WILDCARD_PAT
-                UNDERSCORE "_"
-              WHITESPACE " "
-              FAT_ARROW "=>"
-              WHITESPACE " "
-              TUPLE_EXPR
-                L_PAREN "("
-                R_PAREN ")"
-              COMMA ","
-            ERROR
-              COMMA ","
-            WHITESPACE "\n        "
-            MATCH_ARM
-              WILDCARD_PAT
-                UNDERSCORE "_"
-              WHITESPACE " "
-              FAT_ARROW "=>"
-              WHITESPACE " "
-              COMMA ","
-            WHITESPACE "\n        "
-            MATCH_ARM
-              WILDCARD_PAT
-                UNDERSCORE "_"
-              WHITESPACE " "
-              FAT_ARROW "=>"
-              WHITESPACE " "
-              TUPLE_EXPR
-                L_PAREN "("
-                R_PAREN ")"
-              COMMA ","
-            WHITESPACE "\n         "
-            MATCH_ARM
-              FAT_ARROW "=>"
-              WHITESPACE " "
-              TUPLE_EXPR
-                L_PAREN "("
-                R_PAREN ")"
-              COMMA ","
-            WHITESPACE "\n        "
-            MATCH_ARM
-              MATCH_GUARD
-                IF_KW "if"
-                WHITESPACE " "
-                LITERAL
-                  TRUE_KW "true"
-              WHITESPACE " "
-              FAT_ARROW "=>"
-              WHITESPACE " "
-              TUPLE_EXPR
-                L_PAREN "("
-                R_PAREN ")"
-              COMMA ","
-            WHITESPACE "\n        "
-            MATCH_ARM
-              WILDCARD_PAT
-                UNDERSCORE "_"
-              WHITESPACE " "
-              FAT_ARROW "=>"
-              WHITESPACE " "
-              TUPLE_EXPR
-                L_PAREN "("
-                R_PAREN ")"
-              COMMA ","
-            WHITESPACE "\n        "
-            MATCH_ARM
-              TUPLE_PAT
-                L_PAREN "("
-                R_PAREN ")"
-              WHITESPACE " "
-              MATCH_GUARD
-                IF_KW "if"
-              WHITESPACE " "
-              FAT_ARROW "=>"
-              WHITESPACE " "
-              TUPLE_EXPR
-                L_PAREN "("
-                R_PAREN ")"
-              COMMA ","
-            WHITESPACE "\n    "
-            R_CURLY "}"
-        WHITESPACE "\n"
-        R_CURLY "}"
-  WHITESPACE "\n"
-error 42: expected pattern
-error 58: expected expression
-error 85: expected pattern
-error 100: expected pattern
-error 145: expected expression
diff --git a/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rs b/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rs
deleted file mode 100644
index 173103b2e3..0000000000
--- a/crates/parser/test_data/parser/inline/err/0034_match_arms_recovery.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-fn foo() {
-    match () {
-        _ => (),,
-        _ => ,
-        _ => (),
-         => (),
-        if true => (),
-        _ => (),
-        () if => (),
-    }
-}
diff --git a/crates/syntax/src/tests.rs b/crates/syntax/src/tests.rs
index 439daa358a..5400071c4b 100644
--- a/crates/syntax/src/tests.rs
+++ b/crates/syntax/src/tests.rs
@@ -1,3 +1,8 @@
+#[cfg(not(feature = "in-rust-tree"))]
+mod ast_src;
+#[cfg(not(feature = "in-rust-tree"))]
+mod sourcegen_ast;
+
 use std::{
     fs,
     path::{Path, PathBuf},
@@ -77,25 +82,7 @@ fn reparse_fuzz_tests() {
 fn self_hosting_parsing() {
     let crates_dir = project_root().join("crates");
 
-    let mut files = Vec::new();
-    let mut work = vec![crates_dir.to_path_buf()];
-    while let Some(dir) = work.pop() {
-        for entry in dir.read_dir().unwrap() {
-            let entry = entry.unwrap();
-            let file_type = entry.file_type().unwrap();
-            let path = entry.path();
-            let file_name = &path.file_name().unwrap_or_default().to_str().unwrap_or_default();
-            let is_hidden = file_name.starts_with('.');
-            if !is_hidden {
-                if file_type.is_dir() {
-                    work.push(path);
-                } else if file_type.is_file() && file_name.ends_with(".rs") {
-                    files.push(path);
-                }
-            }
-        }
-    }
-
+    let mut files = ::sourcegen::list_rust_files(&crates_dir);
     files.retain(|path| {
         // Get all files which are not in the crates/syntax/test_data folder
         !path.components().any(|component| component.as_os_str() == "test_data")