Repository: rust-analyzer/rust-analyzer
Pull request #1697 (2019-08-19 09:28:58)

Use quote instead of tera for boilerplate generation


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 1c16b281ba..4ef0134d7d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -352,11 +352,6 @@ dependencies = [
  "syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "deunicode"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "difference"
 version = "2.0.0"
@@ -406,15 +401,6 @@ name = "encode_unicode"
 version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "error-chain"
-version = "0.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "backtrace 0.3.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "failure"
 version = "0.1.5"
@@ -556,11 +542,6 @@ dependencies = [
  "wasi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "glob"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "glob"
 version = "0.3.0"
@@ -586,21 +567,6 @@ dependencies = [
  "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "humansize"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "idna"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "idna"
 version = "0.2.0"
@@ -1003,15 +969,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro-hack 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "percent-encoding"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
 [[package]]
 name = "percent-encoding"
 version = "2.1.0"
@@ -1076,7 +1037,7 @@ version = "0.5.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1128,7 +1089,7 @@ dependencies = [
 
 [[package]]
 name = "quote"
-version = "1.0.1"
+version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1362,8 +1323,12 @@ name = "ra_tools"
 version = "0.1.0"
 dependencies = [
  "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "teraron 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1613,6 +1578,16 @@ dependencies = [
  "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "ron"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "rowan"
 version = "0.6.2"
@@ -1717,7 +1692,7 @@ version = "1.0.99"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1737,7 +1712,7 @@ version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "syn 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1768,14 +1743,6 @@ name = "slab"
 version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "slug"
-version = "0.1.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "deunicode 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "smallvec"
 version = "0.6.10"
@@ -1826,7 +1793,7 @@ version = "1.0.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1854,36 +1821,6 @@ dependencies = [
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "tera"
-version = "0.11.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "pest 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "teraron"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ron 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "termios"
 version = "0.3.1"
@@ -1958,50 +1895,6 @@ name = "ucd-trie"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "unic-char-property"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unic-char-range 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "unic-char-range"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "unic-common"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "unic-segment"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unic-ucd-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "unic-ucd-segment"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unic-char-property 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "unic-char-range 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "unic-ucd-version 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "unic-ucd-version"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "unic-common 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "unicase"
 version = "2.4.0"
@@ -2046,16 +1939,6 @@ name = "unicode-xid"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
-[[package]]
-name = "url"
-version = "1.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
 [[package]]
 name = "url"
 version = "2.1.0"
@@ -2200,7 +2083,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
 "checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
 "checksum derive-new 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c3fd04571b29c91cfbe1e7c9a228e069ac8635f180ffb4ccd6a6907617ee8bb0"
-"checksum deunicode 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "850878694b7933ca4c9569d30a34b55031b9b139ee1fc7b94a527c4ef960d690"
 "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
 "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
 "checksum drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "69b26e475fd29098530e709294e94e661974c851aed42512793f120fed4e199f"
@@ -2209,7 +2091,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum ena 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "25b4e5febb25f08c49f1b07dc33a182729a6b21edfb562b5aef95f78e0dbe5bb"
 "checksum ena 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3dc01d68e08ca384955a3aeba9217102ca1aa85b6e168639bf27739f1d749d87"
 "checksum encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd"
-"checksum error-chain 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ab49e9dcb602294bc42f9a7dfc9bc6e936fca4418ea300dbfb84fe16de0b7d9"
 "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
 "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
 "checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
@@ -2227,12 +2108,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
 "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
 "checksum getrandom 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "2512b3191f22e2763a5db387f1c9409379772e2050841722eb4a8c4f497bf096"
-"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
 "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
 "checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2"
 "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
-"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
-"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
 "checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
 "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
 "checksum indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2c60da1c9abea75996b70a931bba6c750730399005b61ccd853cee50ef3d0d0c"
@@ -2279,7 +2157,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b"
 "checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49"
 "checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5"
-"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
 "checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
 "checksum pest 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "933085deae3f32071f135d799d75667b63c8dc1f4537159756e3d4ceab41868c"
 "checksum pest_derive 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0"
@@ -2293,7 +2170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf147e022eacf0c8a054ab864914a7602618adba841d800a9a9868a5237a529f"
 "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
 "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
-"checksum quote 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "49d77c41ca8767f2f41394c11a4eebccab83da25e7cc035387a3125f02be90a3"
+"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
 "checksum ra_rustc_lexer 0.1.0-pre.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6baccda91574dfadd7f8a0bc8f9f110f874b6b484289b2536d3dbf4f0d5d97bb"
 "checksum ra_vfs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb7cd4e302032c5ab514f1c01c89727cd96fd950dd36f9ebee9252df45d9fb1a"
 "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
@@ -2320,6 +2197,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c"
 "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
 "checksum ron 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "17f52a24414403f81528b67488cf8edc4eda977d3af1646bb6b106a600ead78f"
+"checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5"
 "checksum rowan 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dc2b79612dedc9004083a61448eb669d336d56690aab29fbd7249e8c8ab41d8c"
 "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
 "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
@@ -2338,7 +2216,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum serde_yaml 0.8.9 (registry+https://github.com/rust-lang/crates.io-index)" = "38b08a9a90e5260fe01c6480ec7c811606df6d3a660415808c3c3fa8ed95b582"
 "checksum sha-1 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "23962131a91661d643c98940b20fcaffe62d776a823247be80a48fcb8b6fce68"
 "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
-"checksum slug 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b3bc762e6a4b6c6fcaade73e77f9ebc6991b676f88bb2358bddb56560f073373"
 "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7"
 "checksum smol_str 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "590700be3630457c56f8c73c0ea39881476ad7076cd84057d44f4f38f79914fb"
 "checksum stacker 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fb79482f57cf598af52094ec4cc3b3c42499d3ce5bd426f2ac41515b7e57404b"
@@ -2348,8 +2225,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum syn 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2ae5cd13590144ea968ba5d5520da7a4c08415861014399b5b349f74591c375f"
 "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
 "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
-"checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3"
-"checksum teraron 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9a447d012fef5c222f4b11a98fcef2a7e347a57f28be9957c5c390ac9a0e41e0"
 "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625"
 "checksum text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e08bbcb7a3adbda0eb23431206b653bdad3d8dea311e72d36bf2215e27a42579"
 "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
@@ -2358,12 +2233,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
 "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
 "checksum ucd-trie 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8f00ed7be0c1ff1e24f46c3d2af4859f7e863672ba3a6e92e7cff702bf9f06c2"
-"checksum unic-char-property 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce36d3f7ce754afdbccccf8ff0dd0134e50fb44aaae579f96218856e9e5dbd1e"
-"checksum unic-char-range 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9ab85fab42ad1b26cafc03bf891f69cb4d6e15f491030e89a0122197baa8ae8"
-"checksum unic-common 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff8d4a7ade929ef7d971e16ced21a8cd56a63869aa6032dfb8cb083cf7d077bf"
-"checksum unic-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ca47cbb09fb5fcd066b5867d11dc528302fa465277882797d6a836e1ee6f9e"
-"checksum unic-ucd-segment 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48f1a08ce0409a9e391b88d1930118eec48af12742fc538bcec55f775865776e"
-"checksum unic-ucd-version 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1f5e6c6c53c2d0ece4a5964bc55fcff8602153063cb4fab20958ff32998ff6"
 "checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6"
 "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
 "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426"
@@ -2371,7 +2240,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
 "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
-"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
 "checksum url 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61"
 "checksum uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a"
 "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index 4b5abb516c..415839cb5f 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -1,16 +1,11 @@
-// This file is automatically generated based on the file `./generated.rs.tera` when `cargo gen-syntax` is run
-// Do not edit manually
+// Generated file, do not edit by hand, see `crate/ra_tools/src/codegen`
 
 #![allow(bad_style, missing_docs, unreachable_pub)]
-#![cfg_attr(rustfmt, rustfmt_skip)]
 use super::SyntaxInfo;
-
-/// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`.
+#[doc = r" The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`."]
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
 #[repr(u16)]
 pub enum SyntaxKind {
-    // Technical SyntaxKinds: they appear temporally during parsing,
-    // but never end up in the final tree
     #[doc(hidden)]
     TOMBSTONE,
     #[doc(hidden)]
@@ -242,477 +237,280 @@ pub enum SyntaxKind {
     TYPE_BOUND_LIST,
     MACRO_ITEMS,
     MACRO_STMTS,
-    // Technical kind so that we can cast from u16 safely
     #[doc(hidden)]
     __LAST,
 }
 use self::SyntaxKind::*;
-
-#[macro_export]
-macro_rules! T {
-    (;) => { $crate::SyntaxKind::SEMI };
-    (,) => { $crate::SyntaxKind::COMMA };
-    ('(') => { $crate::SyntaxKind::L_PAREN };
-    (')') => { $crate::SyntaxKind::R_PAREN };
-    ('{') => { $crate::SyntaxKind::L_CURLY };
-    ('}') => { $crate::SyntaxKind::R_CURLY };
-    ('[') => { $crate::SyntaxKind::L_BRACK };
-    (']') => { $crate::SyntaxKind::R_BRACK };
-    (<) => { $crate::SyntaxKind::L_ANGLE };
-    (>) => { $crate::SyntaxKind::R_ANGLE };
-    (@) => { $crate::SyntaxKind::AT };
-    (#) => { $crate::SyntaxKind::POUND };
-    (~) => { $crate::SyntaxKind::TILDE };
-    (?) => { $crate::SyntaxKind::QUESTION };
-    ($) => { $crate::SyntaxKind::DOLLAR };
-    (&) => { $crate::SyntaxKind::AMP };
-    (|) => { $crate::SyntaxKind::PIPE };
-    (+) => { $crate::SyntaxKind::PLUS };
-    (*) => { $crate::SyntaxKind::STAR };
-    (/) => { $crate::SyntaxKind::SLASH };
-    (^) => { $crate::SyntaxKind::CARET };
-    (%) => { $crate::SyntaxKind::PERCENT };
-    (_) => { $crate::SyntaxKind::UNDERSCORE };
-    (.) => { $crate::SyntaxKind::DOT };
-    (..) => { $crate::SyntaxKind::DOTDOT };
-    (...) => { $crate::SyntaxKind::DOTDOTDOT };
-    (..=) => { $crate::SyntaxKind::DOTDOTEQ };
-    (:) => { $crate::SyntaxKind::COLON };
-    (::) => { $crate::SyntaxKind::COLONCOLON };
-    (=) => { $crate::SyntaxKind::EQ };
-    (==) => { $crate::SyntaxKind::EQEQ };
-    (=>) => { $crate::SyntaxKind::FAT_ARROW };
-    (!) => { $crate::SyntaxKind::EXCL };
-    (!=) => { $crate::SyntaxKind::NEQ };
-    (-) => { $crate::SyntaxKind::MINUS };
-    (->) => { $crate::SyntaxKind::THIN_ARROW };
-    (<=) => { $crate::SyntaxKind::LTEQ };
-    (>=) => { $crate::SyntaxKind::GTEQ };
-    (+=) => { $crate::SyntaxKind::PLUSEQ };
-    (-=) => { $crate::SyntaxKind::MINUSEQ };
-    (|=) => { $crate::SyntaxKind::PIPEEQ };
-    (&=) => { $crate::SyntaxKind::AMPEQ };
-    (^=) => { $crate::SyntaxKind::CARETEQ };
-    (/=) => { $crate::SyntaxKind::SLASHEQ };
-    (*=) => { $crate::SyntaxKind::STAREQ };
-    (%=) => { $crate::SyntaxKind::PERCENTEQ };
-    (&&) => { $crate::SyntaxKind::AMPAMP };
-    (||) => { $crate::SyntaxKind::PIPEPIPE };
-    (<<) => { $crate::SyntaxKind::SHL };
-    (>>) => { $crate::SyntaxKind::SHR };
-    (<<=) => { $crate::SyntaxKind::SHLEQ };
-    (>>=) => { $crate::SyntaxKind::SHREQ };
-    (async) => { $crate::SyntaxKind::ASYNC_KW };
-    (use) => { $crate::SyntaxKind::USE_KW };
-    (fn) => { $crate::SyntaxKind::FN_KW };
-    (struct) => { $crate::SyntaxKind::STRUCT_KW };
-    (enum) => { $crate::SyntaxKind::ENUM_KW };
-    (trait) => { $crate::SyntaxKind::TRAIT_KW };
-    (impl) => { $crate::SyntaxKind::IMPL_KW };
-    (dyn) => { $crate::SyntaxKind::DYN_KW };
-    (true) => { $crate::SyntaxKind::TRUE_KW };
-    (false) => { $crate::SyntaxKind::FALSE_KW };
-    (as) => { $crate::SyntaxKind::AS_KW };
-    (extern) => { $crate::SyntaxKind::EXTERN_KW };
-    (crate) => { $crate::SyntaxKind::CRATE_KW };
-    (mod) => { $crate::SyntaxKind::MOD_KW };
-    (pub) => { $crate::SyntaxKind::PUB_KW };
-    (self) => { $crate::SyntaxKind::SELF_KW };
-    (super) => { $crate::SyntaxKind::SUPER_KW };
-    (in) => { $crate::SyntaxKind::IN_KW };
-    (where) => { $crate::SyntaxKind::WHERE_KW };
-    (for) => { $crate::SyntaxKind::FOR_KW };
-    (loop) => { $crate::SyntaxKind::LOOP_KW };
-    (while) => { $crate::SyntaxKind::WHILE_KW };
-    (continue) => { $crate::SyntaxKind::CONTINUE_KW };
-    (break) => { $crate::SyntaxKind::BREAK_KW };
-    (if) => { $crate::SyntaxKind::IF_KW };
-    (else) => { $crate::SyntaxKind::ELSE_KW };
-    (match) => { $crate::SyntaxKind::MATCH_KW };
-    (const) => { $crate::SyntaxKind::CONST_KW };
-    (static) => { $crate::SyntaxKind::STATIC_KW };
-    (mut) => { $crate::SyntaxKind::MUT_KW };
-    (unsafe) => { $crate::SyntaxKind::UNSAFE_KW };
-    (type) => { $crate::SyntaxKind::TYPE_KW };
-    (ref) => { $crate::SyntaxKind::REF_KW };
-    (let) => { $crate::SyntaxKind::LET_KW };
-    (move) => { $crate::SyntaxKind::MOVE_KW };
-    (return) => { $crate::SyntaxKind::RETURN_KW };
-    (try) => { $crate::SyntaxKind::TRY_KW };
-    (box) => { $crate::SyntaxKind::BOX_KW };
-    (await) => { $crate::SyntaxKind::AWAIT_KW };
-    (auto) => { $crate::SyntaxKind::AUTO_KW };
-    (default) => { $crate::SyntaxKind::DEFAULT_KW };
-    (existential) => { $crate::SyntaxKind::EXISTENTIAL_KW };
-    (union) => { $crate::SyntaxKind::UNION_KW };
-}
-
 impl From<u16> for SyntaxKind {
     fn from(d: u16) -> SyntaxKind {
         assert!(d <= (__LAST as u16));
         unsafe { std::mem::transmute::<u16, SyntaxKind>(d) }
     }
 }
-
 impl From<SyntaxKind> for u16 {
     fn from(k: SyntaxKind) -> u16 {
         k as u16
     }
 }
-
 impl SyntaxKind {
     pub fn is_keyword(self) -> bool {
         match self {
-            | ASYNC_KW
-            | USE_KW
-            | FN_KW
-            | STRUCT_KW
-            | ENUM_KW
-            | TRAIT_KW
-            | IMPL_KW
-            | DYN_KW
-            | TRUE_KW
-            | FALSE_KW
-            | AS_KW
-            | EXTERN_KW
-            | CRATE_KW
-            | MOD_KW
-            | PUB_KW
-            | SELF_KW
-            | SUPER_KW
-            | IN_KW
-            | WHERE_KW
-            | FOR_KW
-            | LOOP_KW
-            | WHILE_KW
-            | CONTINUE_KW
-            | BREAK_KW
-            | IF_KW
-            | ELSE_KW
-            | MATCH_KW
-            | CONST_KW
-            | STATIC_KW
-            | MUT_KW
-            | UNSAFE_KW
-            | TYPE_KW
-            | REF_KW
-            | LET_KW
-            | MOVE_KW
-            | RETURN_KW
-            | TRY_KW
-            | BOX_KW
-            | AWAIT_KW
-            | AUTO_KW
-            | DEFAULT_KW
-            | EXISTENTIAL_KW
-            | UNION_KW
-                => true,
-            _ => false
+            ASYNC_KW | USE_KW | FN_KW | STRUCT_KW | ENUM_KW | TRAIT_KW | IMPL_KW | DYN_KW
+            | TRUE_KW | FALSE_KW | AS_KW | EXTERN_KW | CRATE_KW | MOD_KW | PUB_KW | SELF_KW
+            | SUPER_KW | IN_KW | WHERE_KW | FOR_KW | LOOP_KW | WHILE_KW | CONTINUE_KW
+            | BREAK_KW | IF_KW | ELSE_KW | MATCH_KW | CONST_KW | STATIC_KW | MUT_KW | UNSAFE_KW
+            | TYPE_KW | REF_KW | LET_KW | MOVE_KW | RETURN_KW | TRY_KW | BOX_KW | AWAIT_KW
+            | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW => true,
+            _ => false,
         }
     }
-
     pub fn is_punct(self) -> bool {
         match self {
-            | SEMI
-            | COMMA
-            | L_PAREN
-            | R_PAREN
-            | L_CURLY
-            | R_CURLY
-            | L_BRACK
-            | R_BRACK
-            | L_ANGLE
-            | R_ANGLE
-            | AT
-            | POUND
-            | TILDE
-            | QUESTION
-            | DOLLAR
-            | AMP
-            | PIPE
-            | PLUS
-            | STAR
-            | SLASH
-            | CARET
-            | PERCENT
-            | UNDERSCORE
-            | DOT
-            | DOTDOT
-            | DOTDOTDOT
-            | DOTDOTEQ
-            | COLON
-            | COLONCOLON
-            | EQ
-            | EQEQ
-            | FAT_ARROW
-            | EXCL
-            | NEQ
-            | MINUS
-            | THIN_ARROW
-            | LTEQ
-            | GTEQ
-            | PLUSEQ
-            | MINUSEQ
-            | PIPEEQ
-            | AMPEQ
-            | CARETEQ
-            | SLASHEQ
-            | STAREQ
-            | PERCENTEQ
-            | AMPAMP
-            | PIPEPIPE
-            | SHL
-            | SHR
-            | SHLEQ
-            | SHREQ
-                => true,
-            _ => false
+            SEMI | COMMA | L_PAREN | R_PAREN | L_CURLY | R_CURLY | L_BRACK | R_BRACK | L_ANGLE
+            | R_ANGLE | AT | POUND | TILDE | QUESTION | DOLLAR | AMP | PIPE | PLUS | STAR
+            | SLASH | CARET | PERCENT | UNDERSCORE | DOT | DOTDOT | DOTDOTDOT | DOTDOTEQ
+            | COLON | COLONCOLON | EQ | EQEQ | FAT_ARROW | EXCL | NEQ | MINUS | THIN_ARROW
+            | LTEQ | GTEQ | PLUSEQ | MINUSEQ | PIPEEQ | AMPEQ | CARETEQ | SLASHEQ | STAREQ
+            | PERCENTEQ | AMPAMP | PIPEPIPE | SHL | SHR | SHLEQ | SHREQ => true,
+            _ => false,
         }
     }
     pub fn is_literal(self) -> bool {
         match self {
-            | INT_NUMBER
-            | FLOAT_NUMBER
-            | CHAR
-            | BYTE
-            | STRING
-            | RAW_STRING
-            | BYTE_STRING
-            | RAW_BYTE_STRING
-                => true,
-            _ => false
+            INT_NUMBER | FLOAT_NUMBER | CHAR | BYTE | STRING | RAW_STRING | BYTE_STRING
+            | RAW_BYTE_STRING => true,
+            _ => false,
         }
     }
-
     pub(crate) fn info(self) -> &'static SyntaxInfo {
         match self {
-            SEMI => &SyntaxInfo { name: "SEMI" },
-            COMMA => &SyntaxInfo { name: "COMMA" },
-            L_PAREN => &SyntaxInfo { name: "L_PAREN" },
-            R_PAREN => &SyntaxInfo { name: "R_PAREN" },
-            L_CURLY => &SyntaxInfo { name: "L_CURLY" },
-            R_CURLY => &SyntaxInfo { name: "R_CURLY" },
-            L_BRACK => &SyntaxInfo { name: "L_BRACK" },
-            R_BRACK => &SyntaxInfo { name: "R_BRACK" },
-            L_ANGLE => &SyntaxInfo { name: "L_ANGLE" },
-            R_ANGLE => &SyntaxInfo { name: "R_ANGLE" },
-            AT => &SyntaxInfo { name: "AT" },
-            POUND => &SyntaxInfo { name: "POUND" },
-            TILDE => &SyntaxInfo { name: "TILDE" },
-            QUESTION => &SyntaxInfo { name: "QUESTION" },
-            DOLLAR => &SyntaxInfo { name: "DOLLAR" },
-            AMP => &SyntaxInfo { name: "AMP" },
-            PIPE => &SyntaxInfo { name: "PIPE" },
-            PLUS => &SyntaxInfo { name: "PLUS" },
-            STAR => &SyntaxInfo { name: "STAR" },
-            SLASH => &SyntaxInfo { name: "SLASH" },
-            CARET => &SyntaxInfo { name: "CARET" },
-            PERCENT => &SyntaxInfo { name: "PERCENT" },
-            UNDERSCORE => &SyntaxInfo { name: "UNDERSCORE" },
-            DOT => &SyntaxInfo { name: "DOT" },
-            DOTDOT => &SyntaxInfo { name: "DOTDOT" },
-            DOTDOTDOT => &SyntaxInfo { name: "DOTDOTDOT" },
-            DOTDOTEQ => &SyntaxInfo { name: "DOTDOTEQ" },
-            COLON => &SyntaxInfo { name: "COLON" },
-            COLONCOLON => &SyntaxInfo { name: "COLONCOLON" },
-            EQ => &SyntaxInfo { name: "EQ" },
-            EQEQ => &SyntaxInfo { name: "EQEQ" },
-            FAT_ARROW => &SyntaxInfo { name: "FAT_ARROW" },
-            EXCL => &SyntaxInfo { name: "EXCL" },
-            NEQ => &SyntaxInfo { name: "NEQ" },
-            MINUS => &SyntaxInfo { name: "MINUS" },
-            THIN_ARROW => &SyntaxInfo { name: "THIN_ARROW" },
-            LTEQ => &SyntaxInfo { name: "LTEQ" },
-            GTEQ => &SyntaxInfo { name: "GTEQ" },
-            PLUSEQ => &SyntaxInfo { name: "PLUSEQ" },
-            MINUSEQ => &SyntaxInfo { name: "MINUSEQ" },
-            PIPEEQ => &SyntaxInfo { name: "PIPEEQ" },
-            AMPEQ => &SyntaxInfo { name: "AMPEQ" },
-            CARETEQ => &SyntaxInfo { name: "CARETEQ" },
-            SLASHEQ => &SyntaxInfo { name: "SLASHEQ" },
-            STAREQ => &SyntaxInfo { name: "STAREQ" },
-            PERCENTEQ => &SyntaxInfo { name: "PERCENTEQ" },
-            AMPAMP => &SyntaxInfo { name: "AMPAMP" },
-            PIPEPIPE => &SyntaxInfo { name: "PIPEPIPE" },
-            SHL => &SyntaxInfo { name: "SHL" },
-            SHR => &SyntaxInfo { name: "SHR" },
-            SHLEQ => &SyntaxInfo { name: "SHLEQ" },
-            SHREQ => &SyntaxInfo { name: "SHREQ" },
-            ASYNC_KW => &SyntaxInfo { name: "ASYNC_KW" },
-            USE_KW => &SyntaxInfo { name: "USE_KW" },
-            FN_KW => &SyntaxInfo { name: "FN_KW" },
-            STRUCT_KW => &SyntaxInfo { name: "STRUCT_KW" },
-            ENUM_KW => &SyntaxInfo { name: "ENUM_KW" },
-            TRAIT_KW => &SyntaxInfo { name: "TRAIT_KW" },
-            IMPL_KW => &SyntaxInfo { name: "IMPL_KW" },
-            DYN_KW => &SyntaxInfo { name: "DYN_KW" },
-            TRUE_KW => &SyntaxInfo { name: "TRUE_KW" },
-            FALSE_KW => &SyntaxInfo { name: "FALSE_KW" },
-            AS_KW => &SyntaxInfo { name: "AS_KW" },
-            EXTERN_KW => &SyntaxInfo { name: "EXTERN_KW" },
-            CRATE_KW => &SyntaxInfo { name: "CRATE_KW" },
-            MOD_KW => &SyntaxInfo { name: "MOD_KW" },
-            PUB_KW => &SyntaxInfo { name: "PUB_KW" },
-            SELF_KW => &SyntaxInfo { name: "SELF_KW" },
-            SUPER_KW => &SyntaxInfo { name: "SUPER_KW" },
-            IN_KW => &SyntaxInfo { name: "IN_KW" },
-            WHERE_KW => &SyntaxInfo { name: "WHERE_KW" },
-            FOR_KW => &SyntaxInfo { name: "FOR_KW" },
-            LOOP_KW => &SyntaxInfo { name: "LOOP_KW" },
-            WHILE_KW => &SyntaxInfo { name: "WHILE_KW" },
-            CONTINUE_KW => &SyntaxInfo { name: "CONTINUE_KW" },
-            BREAK_KW => &SyntaxInfo { name: "BREAK_KW" },
-            IF_KW => &SyntaxInfo { name: "IF_KW" },
-            ELSE_KW => &SyntaxInfo { name: "ELSE_KW" },
-            MATCH_KW => &SyntaxInfo { name: "MATCH_KW" },
-            CONST_KW => &SyntaxInfo { name: "CONST_KW" },
-            STATIC_KW => &SyntaxInfo { name: "STATIC_KW" },
-            MUT_KW => &SyntaxInfo { name: "MUT_KW" },
-            UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" },
-            TYPE_KW => &SyntaxInfo { name: "TYPE_KW" },
-            REF_KW => &SyntaxInfo { name: "REF_KW" },
-            LET_KW => &SyntaxInfo { name: "LET_KW" },
-            MOVE_KW => &SyntaxInfo { name: "MOVE_KW" },
-            RETURN_KW => &SyntaxInfo { name: "RETURN_KW" },
-            TRY_KW => &SyntaxInfo { name: "TRY_KW" },
-            BOX_KW => &SyntaxInfo { name: "BOX_KW" },
-            AWAIT_KW => &SyntaxInfo { name: "AWAIT_KW" },
-            AUTO_KW => &SyntaxInfo { name: "AUTO_KW" },
-            DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" },
-            EXISTENTIAL_KW => &SyntaxInfo { name: "EXISTENTIAL_KW" },
-            UNION_KW => &SyntaxInfo { name: "UNION_KW" },
-            INT_NUMBER => &SyntaxInfo { name: "INT_NUMBER" },
-            FLOAT_NUMBER => &SyntaxInfo { name: "FLOAT_NUMBER" },
-            CHAR => &SyntaxInfo { name: "CHAR" },
-            BYTE => &SyntaxInfo { name: "BYTE" },
-            STRING => &SyntaxInfo { name: "STRING" },
-            RAW_STRING => &SyntaxInfo { name: "RAW_STRING" },
-            BYTE_STRING => &SyntaxInfo { name: "BYTE_STRING" },
-            RAW_BYTE_STRING => &SyntaxInfo { name: "RAW_BYTE_STRING" },
-            ERROR => &SyntaxInfo { name: "ERROR" },
-            IDENT => &SyntaxInfo { name: "IDENT" },
-            WHITESPACE => &SyntaxInfo { name: "WHITESPACE" },
-            LIFETIME => &SyntaxInfo { name: "LIFETIME" },
-            COMMENT => &SyntaxInfo { name: "COMMENT" },
-            SHEBANG => &SyntaxInfo { name: "SHEBANG" },
-            L_DOLLAR => &SyntaxInfo { name: "L_DOLLAR" },
-            R_DOLLAR => &SyntaxInfo { name: "R_DOLLAR" },
-            SOURCE_FILE => &SyntaxInfo { name: "SOURCE_FILE" },
-            STRUCT_DEF => &SyntaxInfo { name: "STRUCT_DEF" },
-            ENUM_DEF => &SyntaxInfo { name: "ENUM_DEF" },
-            FN_DEF => &SyntaxInfo { name: "FN_DEF" },
-            RET_TYPE => &SyntaxInfo { name: "RET_TYPE" },
-            EXTERN_CRATE_ITEM => &SyntaxInfo { name: "EXTERN_CRATE_ITEM" },
-            MODULE => &SyntaxInfo { name: "MODULE" },
-            USE_ITEM => &SyntaxInfo { name: "USE_ITEM" },
-            STATIC_DEF => &SyntaxInfo { name: "STATIC_DEF" },
-            CONST_DEF => &SyntaxInfo { name: "CONST_DEF" },
-            TRAIT_DEF => &SyntaxInfo { name: "TRAIT_DEF" },
-            IMPL_BLOCK => &SyntaxInfo { name: "IMPL_BLOCK" },
-            TYPE_ALIAS_DEF => &SyntaxInfo { name: "TYPE_ALIAS_DEF" },
-            MACRO_CALL => &SyntaxInfo { name: "MACRO_CALL" },
-            TOKEN_TREE => &SyntaxInfo { name: "TOKEN_TREE" },
-            PAREN_TYPE => &SyntaxInfo { name: "PAREN_TYPE" },
-            TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" },
-            NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" },
-            PATH_TYPE => &SyntaxInfo { name: "PATH_TYPE" },
-            POINTER_TYPE => &SyntaxInfo { name: "POINTER_TYPE" },
-            ARRAY_TYPE => &SyntaxInfo { name: "ARRAY_TYPE" },
-            SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" },
-            REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" },
-            PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_TYPE" },
-            FN_POINTER_TYPE => &SyntaxInfo { name: "FN_POINTER_TYPE" },
-            FOR_TYPE => &SyntaxInfo { name: "FOR_TYPE" },
-            IMPL_TRAIT_TYPE => &SyntaxInfo { name: "IMPL_TRAIT_TYPE" },
-            DYN_TRAIT_TYPE => &SyntaxInfo { name: "DYN_TRAIT_TYPE" },
-            REF_PAT => &SyntaxInfo { name: "REF_PAT" },
-            BIND_PAT => &SyntaxInfo { name: "BIND_PAT" },
-            PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" },
-            PATH_PAT => &SyntaxInfo { name: "PATH_PAT" },
-            STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" },
-            FIELD_PAT_LIST => &SyntaxInfo { name: "FIELD_PAT_LIST" },
-            FIELD_PAT => &SyntaxInfo { name: "FIELD_PAT" },
-            TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" },
-            TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
-            SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" },
-            RANGE_PAT => &SyntaxInfo { name: "RANGE_PAT" },
-            LITERAL_PAT => &SyntaxInfo { name: "LITERAL_PAT" },
-            TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
-            ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" },
-            PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" },
-            PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
-            LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" },
-            IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
-            WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" },
-            CONDITION => &SyntaxInfo { name: "CONDITION" },
-            LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" },
-            FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" },
-            CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" },
-            BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" },
-            LABEL => &SyntaxInfo { name: "LABEL" },
-            BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
-            RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" },
-            MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" },
-            MATCH_ARM_LIST => &SyntaxInfo { name: "MATCH_ARM_LIST" },
-            MATCH_ARM => &SyntaxInfo { name: "MATCH_ARM" },
-            MATCH_GUARD => &SyntaxInfo { name: "MATCH_GUARD" },
-            STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" },
-            NAMED_FIELD_LIST => &SyntaxInfo { name: "NAMED_FIELD_LIST" },
-            NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
-            TRY_BLOCK_EXPR => &SyntaxInfo { name: "TRY_BLOCK_EXPR" },
-            BOX_EXPR => &SyntaxInfo { name: "BOX_EXPR" },
-            CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" },
-            INDEX_EXPR => &SyntaxInfo { name: "INDEX_EXPR" },
-            METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" },
-            FIELD_EXPR => &SyntaxInfo { name: "FIELD_EXPR" },
-            AWAIT_EXPR => &SyntaxInfo { name: "AWAIT_EXPR" },
-            TRY_EXPR => &SyntaxInfo { name: "TRY_EXPR" },
-            CAST_EXPR => &SyntaxInfo { name: "CAST_EXPR" },
-            REF_EXPR => &SyntaxInfo { name: "REF_EXPR" },
-            PREFIX_EXPR => &SyntaxInfo { name: "PREFIX_EXPR" },
-            RANGE_EXPR => &SyntaxInfo { name: "RANGE_EXPR" },
-            BIN_EXPR => &SyntaxInfo { name: "BIN_EXPR" },
-            BLOCK => &SyntaxInfo { name: "BLOCK" },
-            EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
-            EXTERN_ITEM_LIST => &SyntaxInfo { name: "EXTERN_ITEM_LIST" },
-            ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
-            NAMED_FIELD_DEF_LIST => &SyntaxInfo { name: "NAMED_FIELD_DEF_LIST" },
-            NAMED_FIELD_DEF => &SyntaxInfo { name: "NAMED_FIELD_DEF" },
-            POS_FIELD_DEF_LIST => &SyntaxInfo { name: "POS_FIELD_DEF_LIST" },
-            POS_FIELD_DEF => &SyntaxInfo { name: "POS_FIELD_DEF" },
-            ENUM_VARIANT_LIST => &SyntaxInfo { name: "ENUM_VARIANT_LIST" },
-            ITEM_LIST => &SyntaxInfo { name: "ITEM_LIST" },
-            ATTR => &SyntaxInfo { name: "ATTR" },
-            META_ITEM => &SyntaxInfo { name: "META_ITEM" },
-            USE_TREE => &SyntaxInfo { name: "USE_TREE" },
-            USE_TREE_LIST => &SyntaxInfo { name: "USE_TREE_LIST" },
-            PATH => &SyntaxInfo { name: "PATH" },
-            PATH_SEGMENT => &SyntaxInfo { name: "PATH_SEGMENT" },
-            LITERAL => &SyntaxInfo { name: "LITERAL" },
-            ALIAS => &SyntaxInfo { name: "ALIAS" },
-            VISIBILITY => &SyntaxInfo { name: "VISIBILITY" },
-            WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" },
-            WHERE_PRED => &SyntaxInfo { name: "WHERE_PRED" },
-            ABI => &SyntaxInfo { name: "ABI" },
-            NAME => &SyntaxInfo { name: "NAME" },
-            NAME_REF => &SyntaxInfo { name: "NAME_REF" },
-            LET_STMT => &SyntaxInfo { name: "LET_STMT" },
-            EXPR_STMT => &SyntaxInfo { name: "EXPR_STMT" },
-            TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
-            LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" },
-            TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" },
-            TYPE_ARG_LIST => &SyntaxInfo { name: "TYPE_ARG_LIST" },
-            LIFETIME_ARG => &SyntaxInfo { name: "LIFETIME_ARG" },
-            TYPE_ARG => &SyntaxInfo { name: "TYPE_ARG" },
-            ASSOC_TYPE_ARG => &SyntaxInfo { name: "ASSOC_TYPE_ARG" },
-            PARAM_LIST => &SyntaxInfo { name: "PARAM_LIST" },
-            PARAM => &SyntaxInfo { name: "PARAM" },
-            SELF_PARAM => &SyntaxInfo { name: "SELF_PARAM" },
-            ARG_LIST => &SyntaxInfo { name: "ARG_LIST" },
-            TYPE_BOUND => &SyntaxInfo { name: "TYPE_BOUND" },
-            TYPE_BOUND_LIST => &SyntaxInfo { name: "TYPE_BOUND_LIST" },
-            MACRO_ITEMS => &SyntaxInfo { name: "MACRO_ITEMS" },
-            MACRO_STMTS => &SyntaxInfo { name: "MACRO_STMTS" },
+            SEMI => &SyntaxInfo { name: stringify!(SEMI) },
+            COMMA => &SyntaxInfo { name: stringify!(COMMA) },
+            L_PAREN => &SyntaxInfo { name: stringify!(L_PAREN) },
+            R_PAREN => &SyntaxInfo { name: stringify!(R_PAREN) },
+            L_CURLY => &SyntaxInfo { name: stringify!(L_CURLY) },
+            R_CURLY => &SyntaxInfo { name: stringify!(R_CURLY) },
+            L_BRACK => &SyntaxInfo { name: stringify!(L_BRACK) },
+            R_BRACK => &SyntaxInfo { name: stringify!(R_BRACK) },
+            L_ANGLE => &SyntaxInfo { name: stringify!(L_ANGLE) },
+            R_ANGLE => &SyntaxInfo { name: stringify!(R_ANGLE) },
+            AT => &SyntaxInfo { name: stringify!(AT) },
+            POUND => &SyntaxInfo { name: stringify!(POUND) },
+            TILDE => &SyntaxInfo { name: stringify!(TILDE) },
+            QUESTION => &SyntaxInfo { name: stringify!(QUESTION) },
+            DOLLAR => &SyntaxInfo { name: stringify!(DOLLAR) },
+            AMP => &SyntaxInfo { name: stringify!(AMP) },
+            PIPE => &SyntaxInfo { name: stringify!(PIPE) },
+            PLUS => &SyntaxInfo { name: stringify!(PLUS) },
+            STAR => &SyntaxInfo { name: stringify!(STAR) },
+            SLASH => &SyntaxInfo { name: stringify!(SLASH) },
+            CARET => &SyntaxInfo { name: stringify!(CARET) },
+            PERCENT => &SyntaxInfo { name: stringify!(PERCENT) },
+            UNDERSCORE => &SyntaxInfo { name: stringify!(UNDERSCORE) },
+            DOT => &SyntaxInfo { name: stringify!(DOT) },
+            DOTDOT => &SyntaxInfo { name: stringify!(DOTDOT) },
+            DOTDOTDOT => &SyntaxInfo { name: stringify!(DOTDOTDOT) },
+            DOTDOTEQ => &SyntaxInfo { name: stringify!(DOTDOTEQ) },
+            COLON => &SyntaxInfo { name: stringify!(COLON) },
+            COLONCOLON => &SyntaxInfo { name: stringify!(COLONCOLON) },
+            EQ => &SyntaxInfo { name: stringify!(EQ) },
+            EQEQ => &SyntaxInfo { name: stringify!(EQEQ) },
+            FAT_ARROW => &SyntaxInfo { name: stringify!(FAT_ARROW) },
+            EXCL => &SyntaxInfo { name: stringify!(EXCL) },
+            NEQ => &SyntaxInfo { name: stringify!(NEQ) },
+            MINUS => &SyntaxInfo { name: stringify!(MINUS) },
+            THIN_ARROW => &SyntaxInfo { name: stringify!(THIN_ARROW) },
+            LTEQ => &SyntaxInfo { name: stringify!(LTEQ) },
+            GTEQ => &SyntaxInfo { name: stringify!(GTEQ) },
+            PLUSEQ => &SyntaxInfo { name: stringify!(PLUSEQ) },
+            MINUSEQ => &SyntaxInfo { name: stringify!(MINUSEQ) },
+            PIPEEQ => &SyntaxInfo { name: stringify!(PIPEEQ) },
+            AMPEQ => &SyntaxInfo { name: stringify!(AMPEQ) },
+            CARETEQ => &SyntaxInfo { name: stringify!(CARETEQ) },
+            SLASHEQ => &SyntaxInfo { name: stringify!(SLASHEQ) },
+            STAREQ => &SyntaxInfo { name: stringify!(STAREQ) },
+            PERCENTEQ => &SyntaxInfo { name: stringify!(PERCENTEQ) },
+            AMPAMP => &SyntaxInfo { name: stringify!(AMPAMP) },
+            PIPEPIPE => &SyntaxInfo { name: stringify!(PIPEPIPE) },
+            SHL => &SyntaxInfo { name: stringify!(SHL) },
+            SHR => &SyntaxInfo { name: stringify!(SHR) },
+            SHLEQ => &SyntaxInfo { name: stringify!(SHLEQ) },
+            SHREQ => &SyntaxInfo { name: stringify!(SHREQ) },
+            ASYNC_KW => &SyntaxInfo { name: stringify!(ASYNC_KW) },
+            USE_KW => &SyntaxInfo { name: stringify!(USE_KW) },
+            FN_KW => &SyntaxInfo { name: stringify!(FN_KW) },
+            STRUCT_KW => &SyntaxInfo { name: stringify!(STRUCT_KW) },
+            ENUM_KW => &SyntaxInfo { name: stringify!(ENUM_KW) },
+            TRAIT_KW => &SyntaxInfo { name: stringify!(TRAIT_KW) },
+            IMPL_KW => &SyntaxInfo { name: stringify!(IMPL_KW) },
+            DYN_KW => &SyntaxInfo { name: stringify!(DYN_KW) },
+            TRUE_KW => &SyntaxInfo { name: stringify!(TRUE_KW) },
+            FALSE_KW => &SyntaxInfo { name: stringify!(FALSE_KW) },
+            AS_KW => &SyntaxInfo { name: stringify!(AS_KW) },
+            EXTERN_KW => &SyntaxInfo { name: stringify!(EXTERN_KW) },
+            CRATE_KW => &SyntaxInfo { name: stringify!(CRATE_KW) },
+            MOD_KW => &SyntaxInfo { name: stringify!(MOD_KW) },
+            PUB_KW => &SyntaxInfo { name: stringify!(PUB_KW) },
+            SELF_KW => &SyntaxInfo { name: stringify!(SELF_KW) },
+            SUPER_KW => &SyntaxInfo { name: stringify!(SUPER_KW) },
+            IN_KW => &SyntaxInfo { name: stringify!(IN_KW) },
+            WHERE_KW => &SyntaxInfo { name: stringify!(WHERE_KW) },
+            FOR_KW => &SyntaxInfo { name: stringify!(FOR_KW) },
+            LOOP_KW => &SyntaxInfo { name: stringify!(LOOP_KW) },
+            WHILE_KW => &SyntaxInfo { name: stringify!(WHILE_KW) },
+            CONTINUE_KW => &SyntaxInfo { name: stringify!(CONTINUE_KW) },
+            BREAK_KW => &SyntaxInfo { name: stringify!(BREAK_KW) },
+            IF_KW => &SyntaxInfo { name: stringify!(IF_KW) },
+            ELSE_KW => &SyntaxInfo { name: stringify!(ELSE_KW) },
+            MATCH_KW => &SyntaxInfo { name: stringify!(MATCH_KW) },
+            CONST_KW => &SyntaxInfo { name: stringify!(CONST_KW) },
+            STATIC_KW => &SyntaxInfo { name: stringify!(STATIC_KW) },
+            MUT_KW => &SyntaxInfo { name: stringify!(MUT_KW) },
+            UNSAFE_KW => &SyntaxInfo { name: stringify!(UNSAFE_KW) },
+            TYPE_KW => &SyntaxInfo { name: stringify!(TYPE_KW) },
+            REF_KW => &SyntaxInfo { name: stringify!(REF_KW) },
+            LET_KW => &SyntaxInfo { name: stringify!(LET_KW) },
+            MOVE_KW => &SyntaxInfo { name: stringify!(MOVE_KW) },
+            RETURN_KW => &SyntaxInfo { name: stringify!(RETURN_KW) },
+            TRY_KW => &SyntaxInfo { name: stringify!(TRY_KW) },
+            BOX_KW => &SyntaxInfo { name: stringify!(BOX_KW) },
+            AWAIT_KW => &SyntaxInfo { name: stringify!(AWAIT_KW) },
+            AUTO_KW => &SyntaxInfo { name: stringify!(AUTO_KW) },
+            DEFAULT_KW => &SyntaxInfo { name: stringify!(DEFAULT_KW) },
+            EXISTENTIAL_KW => &SyntaxInfo { name: stringify!(EXISTENTIAL_KW) },
+            UNION_KW => &SyntaxInfo { name: stringify!(UNION_KW) },
+            INT_NUMBER => &SyntaxInfo { name: stringify!(INT_NUMBER) },
+            FLOAT_NUMBER => &SyntaxInfo { name: stringify!(FLOAT_NUMBER) },
+            CHAR => &SyntaxInfo { name: stringify!(CHAR) },
+            BYTE => &SyntaxInfo { name: stringify!(BYTE) },
+            STRING => &SyntaxInfo { name: stringify!(STRING) },
+            RAW_STRING => &SyntaxInfo { name: stringify!(RAW_STRING) },
+            BYTE_STRING => &SyntaxInfo { name: stringify!(BYTE_STRING) },
+            RAW_BYTE_STRING => &SyntaxInfo { name: stringify!(RAW_BYTE_STRING) },
+            ERROR => &SyntaxInfo { name: stringify!(ERROR) },
+            IDENT => &SyntaxInfo { name: stringify!(IDENT) },
+            WHITESPACE => &SyntaxInfo { name: stringify!(WHITESPACE) },
+            LIFETIME => &SyntaxInfo { name: stringify!(LIFETIME) },
+            COMMENT => &SyntaxInfo { name: stringify!(COMMENT) },
+            SHEBANG => &SyntaxInfo { name: stringify!(SHEBANG) },
+            L_DOLLAR => &SyntaxInfo { name: stringify!(L_DOLLAR) },
+            R_DOLLAR => &SyntaxInfo { name: stringify!(R_DOLLAR) },
+            SOURCE_FILE => &SyntaxInfo { name: stringify!(SOURCE_FILE) },
+            STRUCT_DEF => &SyntaxInfo { name: stringify!(STRUCT_DEF) },
+            ENUM_DEF => &SyntaxInfo { name: stringify!(ENUM_DEF) },
+            FN_DEF => &SyntaxInfo { name: stringify!(FN_DEF) },
+            RET_TYPE => &SyntaxInfo { name: stringify!(RET_TYPE) },
+            EXTERN_CRATE_ITEM => &SyntaxInfo { name: stringify!(EXTERN_CRATE_ITEM) },
+            MODULE => &SyntaxInfo { name: stringify!(MODULE) },
+            USE_ITEM => &SyntaxInfo { name: stringify!(USE_ITEM) },
+            STATIC_DEF => &SyntaxInfo { name: stringify!(STATIC_DEF) },
+            CONST_DEF => &SyntaxInfo { name: stringify!(CONST_DEF) },
+            TRAIT_DEF => &SyntaxInfo { name: stringify!(TRAIT_DEF) },
+            IMPL_BLOCK => &SyntaxInfo { name: stringify!(IMPL_BLOCK) },
+            TYPE_ALIAS_DEF => &SyntaxInfo { name: stringify!(TYPE_ALIAS_DEF) },
+            MACRO_CALL => &SyntaxInfo { name: stringify!(MACRO_CALL) },
+            TOKEN_TREE => &SyntaxInfo { name: stringify!(TOKEN_TREE) },
+            PAREN_TYPE => &SyntaxInfo { name: stringify!(PAREN_TYPE) },
+            TUPLE_TYPE => &SyntaxInfo { name: stringify!(TUPLE_TYPE) },
+            NEVER_TYPE => &SyntaxInfo { name: stringify!(NEVER_TYPE) },
+            PATH_TYPE => &SyntaxInfo { name: stringify!(PATH_TYPE) },
+            POINTER_TYPE => &SyntaxInfo { name: stringify!(POINTER_TYPE) },
+            ARRAY_TYPE => &SyntaxInfo { name: stringify!(ARRAY_TYPE) },
+            SLICE_TYPE => &SyntaxInfo { name: stringify!(SLICE_TYPE) },
+            REFERENCE_TYPE => &SyntaxInfo { name: stringify!(REFERENCE_TYPE) },
+            PLACEHOLDER_TYPE => &SyntaxInfo { name: stringify!(PLACEHOLDER_TYPE) },
+            FN_POINTER_TYPE => &SyntaxInfo { name: stringify!(FN_POINTER_TYPE) },
+            FOR_TYPE => &SyntaxInfo { name: stringify!(FOR_TYPE) },
+            IMPL_TRAIT_TYPE => &SyntaxInfo { name: stringify!(IMPL_TRAIT_TYPE) },
+            DYN_TRAIT_TYPE => &SyntaxInfo { name: stringify!(DYN_TRAIT_TYPE) },
+            REF_PAT => &SyntaxInfo { name: stringify!(REF_PAT) },
+            BIND_PAT => &SyntaxInfo { name: stringify!(BIND_PAT) },
+            PLACEHOLDER_PAT => &SyntaxInfo { name: stringify!(PLACEHOLDER_PAT) },
+            PATH_PAT => &SyntaxInfo { name: stringify!(PATH_PAT) },
+            STRUCT_PAT => &SyntaxInfo { name: stringify!(STRUCT_PAT) },
+            FIELD_PAT_LIST => &SyntaxInfo { name: stringify!(FIELD_PAT_LIST) },
+            FIELD_PAT => &SyntaxInfo { name: stringify!(FIELD_PAT) },
+            TUPLE_STRUCT_PAT => &SyntaxInfo { name: stringify!(TUPLE_STRUCT_PAT) },
+            TUPLE_PAT => &SyntaxInfo { name: stringify!(TUPLE_PAT) },
+            SLICE_PAT => &SyntaxInfo { name: stringify!(SLICE_PAT) },
+            RANGE_PAT => &SyntaxInfo { name: stringify!(RANGE_PAT) },
+            LITERAL_PAT => &SyntaxInfo { name: stringify!(LITERAL_PAT) },
+            TUPLE_EXPR => &SyntaxInfo { name: stringify!(TUPLE_EXPR) },
+            ARRAY_EXPR => &SyntaxInfo { name: stringify!(ARRAY_EXPR) },
+            PAREN_EXPR => &SyntaxInfo { name: stringify!(PAREN_EXPR) },
+            PATH_EXPR => &SyntaxInfo { name: stringify!(PATH_EXPR) },
+            LAMBDA_EXPR => &SyntaxInfo { name: stringify!(LAMBDA_EXPR) },
+            IF_EXPR => &SyntaxInfo { name: stringify!(IF_EXPR) },
+            WHILE_EXPR => &SyntaxInfo { name: stringify!(WHILE_EXPR) },
+            CONDITION => &SyntaxInfo { name: stringify!(CONDITION) },
+            LOOP_EXPR => &SyntaxInfo { name: stringify!(LOOP_EXPR) },
+            FOR_EXPR => &SyntaxInfo { name: stringify!(FOR_EXPR) },
+            CONTINUE_EXPR => &SyntaxInfo { name: stringify!(CONTINUE_EXPR) },
+            BREAK_EXPR => &SyntaxInfo { name: stringify!(BREAK_EXPR) },
+            LABEL => &SyntaxInfo { name: stringify!(LABEL) },
+            BLOCK_EXPR => &SyntaxInfo { name: stringify!(BLOCK_EXPR) },
+            RETURN_EXPR => &SyntaxInfo { name: stringify!(RETURN_EXPR) },
+            MATCH_EXPR => &SyntaxInfo { name: stringify!(MATCH_EXPR) },
+            MATCH_ARM_LIST => &SyntaxInfo { name: stringify!(MATCH_ARM_LIST) },
+            MATCH_ARM => &SyntaxInfo { name: stringify!(MATCH_ARM) },
+            MATCH_GUARD => &SyntaxInfo { name: stringify!(MATCH_GUARD) },
+            STRUCT_LIT => &SyntaxInfo { name: stringify!(STRUCT_LIT) },
+            NAMED_FIELD_LIST => &SyntaxInfo { name: stringify!(NAMED_FIELD_LIST) },
+            NAMED_FIELD => &SyntaxInfo { name: stringify!(NAMED_FIELD) },
+            TRY_BLOCK_EXPR => &SyntaxInfo { name: stringify!(TRY_BLOCK_EXPR) },
+            BOX_EXPR => &SyntaxInfo { name: stringify!(BOX_EXPR) },
+            CALL_EXPR => &SyntaxInfo { name: stringify!(CALL_EXPR) },
+            INDEX_EXPR => &SyntaxInfo { name: stringify!(INDEX_EXPR) },
+            METHOD_CALL_EXPR => &SyntaxInfo { name: stringify!(METHOD_CALL_EXPR) },
+            FIELD_EXPR => &SyntaxInfo { name: stringify!(FIELD_EXPR) },
+            AWAIT_EXPR => &SyntaxInfo { name: stringify!(AWAIT_EXPR) },
+            TRY_EXPR => &SyntaxInfo { name: stringify!(TRY_EXPR) },
+            CAST_EXPR => &SyntaxInfo { name: stringify!(CAST_EXPR) },
+            REF_EXPR => &SyntaxInfo { name: stringify!(REF_EXPR) },
+            PREFIX_EXPR => &SyntaxInfo { name: stringify!(PREFIX_EXPR) },
+            RANGE_EXPR => &SyntaxInfo { name: stringify!(RANGE_EXPR) },
+            BIN_EXPR => &SyntaxInfo { name: stringify!(BIN_EXPR) },
+            BLOCK => &SyntaxInfo { name: stringify!(BLOCK) },
+            EXTERN_BLOCK => &SyntaxInfo { name: stringify!(EXTERN_BLOCK) },
+            EXTERN_ITEM_LIST => &SyntaxInfo { name: stringify!(EXTERN_ITEM_LIST) },
+            ENUM_VARIANT => &SyntaxInfo { name: stringify!(ENUM_VARIANT) },
+            NAMED_FIELD_DEF_LIST => &SyntaxInfo { name: stringify!(NAMED_FIELD_DEF_LIST) },
+            NAMED_FIELD_DEF => &SyntaxInfo { name: stringify!(NAMED_FIELD_DEF) },
+            POS_FIELD_DEF_LIST => &SyntaxInfo { name: stringify!(POS_FIELD_DEF_LIST) },
+            POS_FIELD_DEF => &SyntaxInfo { name: stringify!(POS_FIELD_DEF) },
+            ENUM_VARIANT_LIST => &SyntaxInfo { name: stringify!(ENUM_VARIANT_LIST) },
+            ITEM_LIST => &SyntaxInfo { name: stringify!(ITEM_LIST) },
+            ATTR => &SyntaxInfo { name: stringify!(ATTR) },
+            META_ITEM => &SyntaxInfo { name: stringify!(META_ITEM) },
+            USE_TREE => &SyntaxInfo { name: stringify!(USE_TREE) },
+            USE_TREE_LIST => &SyntaxInfo { name: stringify!(USE_TREE_LIST) },
+            PATH => &SyntaxInfo { name: stringify!(PATH) },
+            PATH_SEGMENT => &SyntaxInfo { name: stringify!(PATH_SEGMENT) },
+            LITERAL => &SyntaxInfo { name: stringify!(LITERAL) },
+            ALIAS => &SyntaxInfo { name: stringify!(ALIAS) },
+            VISIBILITY => &SyntaxInfo { name: stringify!(VISIBILITY) },
+            WHERE_CLAUSE => &SyntaxInfo { name: stringify!(WHERE_CLAUSE) },
+            WHERE_PRED => &SyntaxInfo { name: stringify!(WHERE_PRED) },
+            ABI => &SyntaxInfo { name: stringify!(ABI) },
+            NAME => &SyntaxInfo { name: stringify!(NAME) },
+            NAME_REF => &SyntaxInfo { name: stringify!(NAME_REF) },
+            LET_STMT => &SyntaxInfo { name: stringify!(LET_STMT) },
+            EXPR_STMT => &SyntaxInfo { name: stringify!(EXPR_STMT) },
+            TYPE_PARAM_LIST => &SyntaxInfo { name: stringify!(TYPE_PARAM_LIST) },
+            LIFETIME_PARAM => &SyntaxInfo { name: stringify!(LIFETIME_PARAM) },
+            TYPE_PARAM => &SyntaxInfo { name: stringify!(TYPE_PARAM) },
+            TYPE_ARG_LIST => &SyntaxInfo { name: stringify!(TYPE_ARG_LIST) },
+            LIFETIME_ARG => &SyntaxInfo { name: stringify!(LIFETIME_ARG) },
+            TYPE_ARG => &SyntaxInfo { name: stringify!(TYPE_ARG) },
+            ASSOC_TYPE_ARG => &SyntaxInfo { name: stringify!(ASSOC_TYPE_ARG) },
+            PARAM_LIST => &SyntaxInfo { name: stringify!(PARAM_LIST) },
+            PARAM => &SyntaxInfo { name: stringify!(PARAM) },
+            SELF_PARAM => &SyntaxInfo { name: stringify!(SELF_PARAM) },
+            ARG_LIST => &SyntaxInfo { name: stringify!(ARG_LIST) },
+            TYPE_BOUND => &SyntaxInfo { name: stringify!(TYPE_BOUND) },
+            TYPE_BOUND_LIST => &SyntaxInfo { name: stringify!(TYPE_BOUND_LIST) },
+            MACRO_ITEMS => &SyntaxInfo { name: stringify!(MACRO_ITEMS) },
+            MACRO_STMTS => &SyntaxInfo { name: stringify!(MACRO_STMTS) },
             TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
             EOF => &SyntaxInfo { name: "EOF" },
             __LAST => &SyntaxInfo { name: "__LAST" },
@@ -763,7 +561,6 @@ impl SyntaxKind {
         };
         Some(kw)
     }
-
     pub fn from_char(c: char) -> Option<SyntaxKind> {
         let tok = match c {
             ';' => SEMI,
@@ -794,3 +591,291 @@ impl SyntaxKind {
         Some(tok)
     }
 }
+#[macro_export]
+macro_rules! T {
+    ( ; ) => {
+        $crate::SyntaxKind::SEMI
+    };
+    ( , ) => {
+        $crate::SyntaxKind::COMMA
+    };
+    ( '(' ) => {
+        $crate::SyntaxKind::L_PAREN
+    };
+    ( ')' ) => {
+        $crate::SyntaxKind::R_PAREN
+    };
+    ( '{' ) => {
+        $crate::SyntaxKind::L_CURLY
+    };
+    ( '}' ) => {
+        $crate::SyntaxKind::R_CURLY
+    };
+    ( '[' ) => {
+        $crate::SyntaxKind::L_BRACK
+    };
+    ( ']' ) => {
+        $crate::SyntaxKind::R_BRACK
+    };
+    ( < ) => {
+        $crate::SyntaxKind::L_ANGLE
+    };
+    ( > ) => {
+        $crate::SyntaxKind::R_ANGLE
+    };
+    ( @ ) => {
+        $crate::SyntaxKind::AT
+    };
+    ( # ) => {
+        $crate::SyntaxKind::POUND
+    };
+    ( ~ ) => {
+        $crate::SyntaxKind::TILDE
+    };
+    ( ? ) => {
+        $crate::SyntaxKind::QUESTION
+    };
+    ( $ ) => {
+        $crate::SyntaxKind::DOLLAR
+    };
+    ( & ) => {
+        $crate::SyntaxKind::AMP
+    };
+    ( | ) => {
+        $crate::SyntaxKind::PIPE
+    };
+    ( + ) => {
+        $crate::SyntaxKind::PLUS
+    };
+    ( * ) => {
+        $crate::SyntaxKind::STAR
+    };
+    ( / ) => {
+        $crate::SyntaxKind::SLASH
+    };
+    ( ^ ) => {
+        $crate::SyntaxKind::CARET
+    };
+    ( % ) => {
+        $crate::SyntaxKind::PERCENT
+    };
+    ( _ ) => {
+        $crate::SyntaxKind::UNDERSCORE
+    };
+    ( . ) => {
+        $crate::SyntaxKind::DOT
+    };
+    ( .. ) => {
+        $crate::SyntaxKind::DOTDOT
+    };
+    ( ... ) => {
+        $crate::SyntaxKind::DOTDOTDOT
+    };
+    ( ..= ) => {
+        $crate::SyntaxKind::DOTDOTEQ
+    };
+    ( : ) => {
+        $crate::SyntaxKind::COLON
+    };
+    ( :: ) => {
+        $crate::SyntaxKind::COLONCOLON
+    };
+    ( = ) => {
+        $crate::SyntaxKind::EQ
+    };
+    ( == ) => {
+        $crate::SyntaxKind::EQEQ
+    };
+    ( => ) => {
+        $crate::SyntaxKind::FAT_ARROW
+    };
+    ( ! ) => {
+        $crate::SyntaxKind::EXCL
+    };
+    ( != ) => {
+        $crate::SyntaxKind::NEQ
+    };
+    ( - ) => {
+        $crate::SyntaxKind::MINUS
+    };
+    ( -> ) => {
+        $crate::SyntaxKind::THIN_ARROW
+    };
+    ( <= ) => {
+        $crate::SyntaxKind::LTEQ
+    };
+    ( >= ) => {
+        $crate::SyntaxKind::GTEQ
+    };
+    ( += ) => {
+        $crate::SyntaxKind::PLUSEQ
+    };
+    ( -= ) => {
+        $crate::SyntaxKind::MINUSEQ
+    };
+    ( |= ) => {
+        $crate::SyntaxKind::PIPEEQ
+    };
+    ( &= ) => {
+        $crate::SyntaxKind::AMPEQ
+    };
+    ( ^= ) => {
+        $crate::SyntaxKind::CARETEQ
+    };
+    ( /= ) => {
+        $crate::SyntaxKind::SLASHEQ
+    };
+    ( *= ) => {
+        $crate::SyntaxKind::STAREQ
+    };
+    ( %= ) => {
+        $crate::SyntaxKind::PERCENTEQ
+    };
+    ( && ) => {
+        $crate::SyntaxKind::AMPAMP
+    };
+    ( || ) => {
+        $crate::SyntaxKind::PIPEPIPE
+    };
+    ( << ) => {
+        $crate::SyntaxKind::SHL
+    };
+    ( >> ) => {
+        $crate::SyntaxKind::SHR
+    };
+    ( <<= ) => {
+        $crate::SyntaxKind::SHLEQ
+    };
+    ( >>= ) => {
+        $crate::SyntaxKind::SHREQ
+    };
+    ( async ) => {
+        $crate::SyntaxKind::ASYNC_KW
+    };
+    ( use ) => {
+        $crate::SyntaxKind::USE_KW
+    };
+    ( fn ) => {
+        $crate::SyntaxKind::FN_KW
+    };
+    ( struct ) => {
+        $crate::SyntaxKind::STRUCT_KW
+    };
+    ( enum ) => {
+        $crate::SyntaxKind::ENUM_KW
+    };
+    ( trait ) => {
+        $crate::SyntaxKind::TRAIT_KW
+    };
+    ( impl ) => {
+        $crate::SyntaxKind::IMPL_KW
+    };
+    ( dyn ) => {
+        $crate::SyntaxKind::DYN_KW
+    };
+    ( true ) => {
+        $crate::SyntaxKind::TRUE_KW
+    };
+    ( false ) => {
+        $crate::SyntaxKind::FALSE_KW
+    };
+    ( as ) => {
+        $crate::SyntaxKind::AS_KW
+    };
+    ( extern ) => {
+        $crate::SyntaxKind::EXTERN_KW
+    };
+    ( crate ) => {
+        $crate::SyntaxKind::CRATE_KW
+    };
+    ( mod ) => {
+        $crate::SyntaxKind::MOD_KW
+    };
+    ( pub ) => {
+        $crate::SyntaxKind::PUB_KW
+    };
+    ( self ) => {
+        $crate::SyntaxKind::SELF_KW
+    };
+    ( super ) => {
+        $crate::SyntaxKind::SUPER_KW
+    };
+    ( in ) => {
+        $crate::SyntaxKind::IN_KW
+    };
+    ( where ) => {
+        $crate::SyntaxKind::WHERE_KW
+    };
+    ( for ) => {
+        $crate::SyntaxKind::FOR_KW
+    };
+    ( loop ) => {
+        $crate::SyntaxKind::LOOP_KW
+    };
+    ( while ) => {
+        $crate::SyntaxKind::WHILE_KW
+    };
+    ( continue ) => {
+        $crate::SyntaxKind::CONTINUE_KW
+    };
+    ( break ) => {
+        $crate::SyntaxKind::BREAK_KW
+    };
+    ( if ) => {
+        $crate::SyntaxKind::IF_KW
+    };
+    ( else ) => {
+        $crate::SyntaxKind::ELSE_KW
+    };
+    ( match ) => {
+        $crate::SyntaxKind::MATCH_KW
+    };
+    ( const ) => {
+        $crate::SyntaxKind::CONST_KW
+    };
+    ( static ) => {
+        $crate::SyntaxKind::STATIC_KW
+    };
+    ( mut ) => {
+        $crate::SyntaxKind::MUT_KW
+    };
+    ( unsafe ) => {
+        $crate::SyntaxKind::UNSAFE_KW
+    };
+    ( type ) => {
+        $crate::SyntaxKind::TYPE_KW
+    };
+    ( ref ) => {
+        $crate::SyntaxKind::REF_KW
+    };
+    ( let ) => {
+        $crate::SyntaxKind::LET_KW
+    };
+    ( move ) => {
+        $crate::SyntaxKind::MOVE_KW
+    };
+    ( return ) => {
+        $crate::SyntaxKind::RETURN_KW
+    };
+    ( try ) => {
+        $crate::SyntaxKind::TRY_KW
+    };
+    ( box ) => {
+        $crate::SyntaxKind::BOX_KW
+    };
+    ( await ) => {
+        $crate::SyntaxKind::AWAIT_KW
+    };
+    ( auto ) => {
+        $crate::SyntaxKind::AUTO_KW
+    };
+    ( default ) => {
+        $crate::SyntaxKind::DEFAULT_KW
+    };
+    ( existential ) => {
+        $crate::SyntaxKind::EXISTENTIAL_KW
+    };
+    ( union ) => {
+        $crate::SyntaxKind::UNION_KW
+    };
+}
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs.tera b/crates/ra_parser/src/syntax_kind/generated.rs.tera
deleted file mode 100644
index f5abbec4bc..0000000000
--- a/crates/ra_parser/src/syntax_kind/generated.rs.tera
+++ /dev/null
@@ -1,128 +0,0 @@
-{# THIS File is not automatically generated:
-the below applies to the result of this template
-#}// This file is automatically generated based on the file `./generated.rs.tera` when `cargo gen-syntax` is run
-// Do not edit manually
-
-#![allow(bad_style, missing_docs, unreachable_pub)]
-#![cfg_attr(rustfmt, rustfmt_skip)]
-use super::SyntaxInfo;
-
-/// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`.
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
-#[repr(u16)]
-pub enum SyntaxKind {
-    // Technical SyntaxKinds: they appear temporally during parsing,
-    // but never end up in the final tree
-    #[doc(hidden)]
-    TOMBSTONE,
-    #[doc(hidden)]
-    EOF,
-
-{%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %}
-    {{t.1}},
-{%- endfor -%}
-{% for kw in concat(a=keywords, b=contextual_keywords) %}
-    {{kw | upper}}_KW,
-{%- endfor -%}
-{% for t in concat(a=literals, b=tokens, c=nodes) %}
-    {{t}},
-{%- endfor %}
-    // Technical kind so that we can cast from u16 safely
-    #[doc(hidden)]
-    __LAST,
-}
-use self::SyntaxKind::*;
-
-#[macro_export]
-macro_rules! T {
-{%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %}
-    {%- if t.0 == '{' or t.0 == '}' or t.0 == '[' or t.0 == ']' or t.0 == '(' or t.0 == ')' %}
-    ('{{t.0}}') => { $crate::SyntaxKind::{{t.1}} };
-    {%- else %}
-    ({{t.0}}) => { $crate::SyntaxKind::{{t.1}} };
-    {%- endif %}
-{%- endfor -%}
-{% for kw in concat(a=keywords, b=contextual_keywords) %}
-    ({{kw}}) => { $crate::SyntaxKind::{{kw | upper}}_KW };
-{%- endfor %}
-}
-
-impl From<u16> for SyntaxKind {
-    fn from(d: u16) -> SyntaxKind {
-        assert!(d <= (__LAST as u16));
-        unsafe { std::mem::transmute::<u16, SyntaxKind>(d) }
-    }
-}
-
-impl From<SyntaxKind> for u16 {
-    fn from(k: SyntaxKind) -> u16 {
-        k as u16
-    }
-}
-
-impl SyntaxKind {
-    pub fn is_keyword(self) -> bool {
-        match self {
-{%- for kw in concat(a=keywords, b=contextual_keywords) %}
-            | {{kw | upper}}_KW
-{%- endfor %}
-                => true,
-            _ => false
-        }
-    }
-
-    pub fn is_punct(self) -> bool {
-        match self {
-{%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %}
-            | {{t.1}}
-{%- endfor %}
-                => true,
-            _ => false
-        }
-    }
-    pub fn is_literal(self) -> bool {
-        match self {
-{%- for t in literals %}
-            | {{t}}
-{%- endfor %}
-                => true,
-            _ => false
-        }
-    }
-
-    pub(crate) fn info(self) -> &'static SyntaxInfo {
-        match self {
-{%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %}
-            {{t.1}} => &SyntaxInfo { name: "{{t.1}}" },
-{%- endfor -%}
-{% for kw in concat(a=keywords, b=contextual_keywords) %}
-            {{kw | upper}}_KW => &SyntaxInfo { name: "{{kw | upper}}_KW" },
-{%- endfor -%}
-{% for t in concat(a=literals, b=tokens, c=nodes) %}
-            {{t}} => &SyntaxInfo { name: "{{t}}" },
-{%- endfor %}
-            TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
-            EOF => &SyntaxInfo { name: "EOF" },
-            __LAST => &SyntaxInfo { name: "__LAST" },
-        }
-    }
-    pub fn from_keyword(ident: &str) -> Option<SyntaxKind> {
-        let kw = match ident {
-{%- for kw in keywords %}
-            "{{kw}}" => {{kw | upper}}_KW,
-{%- endfor %}
-            _ => return None,
-        };
-        Some(kw)
-    }
-
-    pub fn from_char(c: char) -> Option<SyntaxKind> {
-        let tok = match c {
-{%- for t in single_byte_tokens %}
-            '{{t.0}}' => {{t.1}},
-{%- endfor %}
-            _ => return None,
-        };
-        Some(tok)
-    }
-}
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index f322e1d84b..0166683807 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -1,25 +1,14 @@
-// This file is automatically generated based on the file `./generated.rs.tera` when `cargo gen-syntax` is run
-// Do not edit manually
-
-//! This module contains auto-generated Rust AST. Like `SyntaxNode`s, AST nodes
-//! are generic over ownership: `X<'a>` things are `Copy` references, `XNode`
-//! are Arc-based. You can switch between the two variants using `.owned` and
-//! `.borrowed` functions. Most of the code works with borowed mode, and only
-//! this mode has all AST accessors.
-
-#![cfg_attr(rustfmt, rustfmt_skip)]
+// Generated file, do not edit by hand, see `crate/ra_tools/src/codegen`
 
 use crate::{
-    SyntaxNode, SyntaxKind::{self, *},
-    ast::{self, AstNode},
+    ast::{self, AstChildren, AstNode},
+    SyntaxKind::{self, *},
+    SyntaxNode,
 };
-
-// Alias
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Alias {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Alias {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -28,21 +17,22 @@ impl AstNode for Alias {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Alias { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::NameOwner for Alias {}
 impl Alias {}
-
-// ArgList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ArgList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ArgList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -51,24 +41,25 @@ impl AstNode for ArgList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ArgList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ArgList {
-    pub fn args(&self) -> impl Iterator<Item = Expr> {
-        super::children(self)
+    pub fn args(&self) -> AstChildren<Expr> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// ArrayExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ArrayExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ArrayExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -77,24 +68,25 @@ impl AstNode for ArrayExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ArrayExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ArrayExpr {
-    pub fn exprs(&self) -> impl Iterator<Item = Expr> {
-        super::children(self)
+    pub fn exprs(&self) -> AstChildren<Expr> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// ArrayType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ArrayType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ArrayType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -103,28 +95,28 @@ impl AstNode for ArrayType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ArrayType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ArrayType {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// AssocTypeArg
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct AssocTypeArg {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for AssocTypeArg {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -133,28 +125,28 @@ impl AstNode for AssocTypeArg {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(AssocTypeArg { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl AssocTypeArg {
     pub fn name_ref(&self) -> Option<NameRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// Attr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Attr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Attr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -163,24 +155,25 @@ impl AstNode for Attr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Attr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl Attr {
     pub fn value(&self) -> Option<TokenTree> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// AwaitExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct AwaitExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for AwaitExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -189,24 +182,25 @@ impl AstNode for AwaitExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(AwaitExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl AwaitExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// BinExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BinExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for BinExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -215,20 +209,21 @@ impl AstNode for BinExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(BinExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl BinExpr {}
-
-// BindPat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BindPat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for BindPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -237,25 +232,26 @@ impl AstNode for BindPat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(BindPat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::NameOwner for BindPat {}
 impl BindPat {
     pub fn pat(&self) -> Option<Pat> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// Block
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Block {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Block {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -264,29 +260,29 @@ impl AstNode for Block {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Block { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::AttrsOwner for Block {}
 impl Block {
-    pub fn statements(&self) -> impl Iterator<Item = Stmt> {
-        super::children(self)
+    pub fn statements(&self) -> AstChildren<Stmt> {
+        AstChildren::new(&self.syntax)
     }
-
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// BlockExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BlockExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for BlockExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -295,24 +291,25 @@ impl AstNode for BlockExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(BlockExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl BlockExpr {
     pub fn block(&self) -> Option<Block> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// BreakExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct BreakExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for BreakExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -321,24 +318,25 @@ impl AstNode for BreakExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(BreakExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl BreakExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// CallExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct CallExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for CallExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -347,25 +345,26 @@ impl AstNode for CallExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(CallExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::ArgListOwner for CallExpr {}
 impl CallExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// CastExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct CastExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for CastExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -374,28 +373,28 @@ impl AstNode for CastExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(CastExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl CastExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// Condition
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Condition {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Condition {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -404,28 +403,28 @@ impl AstNode for Condition {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Condition { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl Condition {
     pub fn pat(&self) -> Option<Pat> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ConstDef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ConstDef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ConstDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -434,12 +433,16 @@ impl AstNode for ConstDef {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ConstDef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::VisibilityOwner for ConstDef {}
 impl ast::NameOwner for ConstDef {}
 impl ast::TypeParamsOwner for ConstDef {}
@@ -448,16 +451,13 @@ impl ast::DocCommentsOwner for ConstDef {}
 impl ast::TypeAscriptionOwner for ConstDef {}
 impl ConstDef {
     pub fn body(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ContinueExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ContinueExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ContinueExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -466,20 +466,21 @@ impl AstNode for ContinueExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ContinueExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ContinueExpr {}
-
-// DynTraitType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct DynTraitType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for DynTraitType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -488,21 +489,22 @@ impl AstNode for DynTraitType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(DynTraitType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::TypeBoundsOwner for DynTraitType {}
 impl DynTraitType {}
-
-// EnumDef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct EnumDef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for EnumDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -511,12 +513,16 @@ impl AstNode for EnumDef {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(EnumDef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::VisibilityOwner for EnumDef {}
 impl ast::NameOwner for EnumDef {}
 impl ast::TypeParamsOwner for EnumDef {}
@@ -524,16 +530,13 @@ impl ast::AttrsOwner for EnumDef {}
 impl ast::DocCommentsOwner for EnumDef {}
 impl EnumDef {
     pub fn variant_list(&self) -> Option<EnumVariantList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// EnumVariant
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct EnumVariant {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for EnumVariant {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -542,27 +545,28 @@ impl AstNode for EnumVariant {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(EnumVariant { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::NameOwner for EnumVariant {}
 impl ast::DocCommentsOwner for EnumVariant {}
 impl ast::AttrsOwner for EnumVariant {}
 impl EnumVariant {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// EnumVariantList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct EnumVariantList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for EnumVariantList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -571,39 +575,49 @@ impl AstNode for EnumVariantList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(EnumVariantList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl EnumVariantList {
-    pub fn variants(&self) -> impl Iterator<Item = EnumVariant> {
-        super::children(self)
+    pub fn variants(&self) -> AstChildren<EnumVariant> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// Expr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Expr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Expr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-             | TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | STRUCT_LIT | CALL_EXPR | INDEX_EXPR | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL => true,
+            TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR
+            | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL
+            | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | STRUCT_LIT | CALL_EXPR | INDEX_EXPR
+            | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR
+            | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL => {
+                true
+            }
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Expr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
-#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ExprKind {
     TupleExpr(TupleExpr),
     ArrayExpr(ArrayExpr),
@@ -637,141 +651,198 @@ pub enum ExprKind {
     MacroCall(MacroCall),
 }
 impl From<TupleExpr> for Expr {
-    fn from(n: TupleExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: TupleExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<ArrayExpr> for Expr {
-    fn from(n: ArrayExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: ArrayExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<ParenExpr> for Expr {
-    fn from(n: ParenExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: ParenExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<PathExpr> for Expr {
-    fn from(n: PathExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: PathExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<LambdaExpr> for Expr {
-    fn from(n: LambdaExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: LambdaExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<IfExpr> for Expr {
-    fn from(n: IfExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: IfExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<LoopExpr> for Expr {
-    fn from(n: LoopExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: LoopExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<ForExpr> for Expr {
-    fn from(n: ForExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: ForExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<WhileExpr> for Expr {
-    fn from(n: WhileExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: WhileExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<ContinueExpr> for Expr {
-    fn from(n: ContinueExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: ContinueExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<BreakExpr> for Expr {
-    fn from(n: BreakExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: BreakExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<Label> for Expr {
-    fn from(n: Label) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: Label) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<BlockExpr> for Expr {
-    fn from(n: BlockExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: BlockExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<ReturnExpr> for Expr {
-    fn from(n: ReturnExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: ReturnExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<MatchExpr> for Expr {
-    fn from(n: MatchExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: MatchExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<StructLit> for Expr {
-    fn from(n: StructLit) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: StructLit) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<CallExpr> for Expr {
-    fn from(n: CallExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: CallExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<IndexExpr> for Expr {
-    fn from(n: IndexExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: IndexExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<MethodCallExpr> for Expr {
-    fn from(n: MethodCallExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: MethodCallExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<FieldExpr> for Expr {
-    fn from(n: FieldExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: FieldExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<AwaitExpr> for Expr {
-    fn from(n: AwaitExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: AwaitExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<TryExpr> for Expr {
-    fn from(n: TryExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: TryExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<TryBlockExpr> for Expr {
-    fn from(n: TryBlockExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: TryBlockExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<CastExpr> for Expr {
-    fn from(n: CastExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: CastExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<RefExpr> for Expr {
-    fn from(n: RefExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: RefExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<PrefixExpr> for Expr {
-    fn from(n: PrefixExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: PrefixExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<RangeExpr> for Expr {
-    fn from(n: RangeExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: RangeExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<BinExpr> for Expr {
-    fn from(n: BinExpr) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: BinExpr) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<Literal> for Expr {
-    fn from(n: Literal) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: Literal) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl From<MacroCall> for Expr {
-    fn from(n: MacroCall) -> Expr { Expr { syntax: n.syntax } }
+    fn from(node: MacroCall) -> Expr {
+        Expr { syntax: node.syntax }
+    }
 }
 impl Expr {
     pub fn kind(&self) -> ExprKind {
-        match self.syntax.kind() {
-            TUPLE_EXPR => ExprKind::TupleExpr(TupleExpr::cast(self.syntax.clone()).unwrap()),
-            ARRAY_EXPR => ExprKind::ArrayExpr(ArrayExpr::cast(self.syntax.clone()).unwrap()),
-            PAREN_EXPR => ExprKind::ParenExpr(ParenExpr::cast(self.syntax.clone()).unwrap()),
-            PATH_EXPR => ExprKind::PathExpr(PathExpr::cast(self.syntax.clone()).unwrap()),
-            LAMBDA_EXPR => ExprKind::LambdaExpr(LambdaExpr::cast(self.syntax.clone()).unwrap()),
-            IF_EXPR => ExprKind::IfExpr(IfExpr::cast(self.syntax.clone()).unwrap()),
-            LOOP_EXPR => ExprKind::LoopExpr(LoopExpr::cast(self.syntax.clone()).unwrap()),
-            FOR_EXPR => ExprKind::ForExpr(ForExpr::cast(self.syntax.clone()).unwrap()),
-            WHILE_EXPR => ExprKind::WhileExpr(WhileExpr::cast(self.syntax.clone()).unwrap()),
-            CONTINUE_EXPR => ExprKind::ContinueExpr(ContinueExpr::cast(self.syntax.clone()).unwrap()),
-            BREAK_EXPR => ExprKind::BreakExpr(BreakExpr::cast(self.syntax.clone()).unwrap()),
-            LABEL => ExprKind::Label(Label::cast(self.syntax.clone()).unwrap()),
-            BLOCK_EXPR => ExprKind::BlockExpr(BlockExpr::cast(self.syntax.clone()).unwrap()),
-            RETURN_EXPR => ExprKind::ReturnExpr(ReturnExpr::cast(self.syntax.clone()).unwrap()),
-            MATCH_EXPR => ExprKind::MatchExpr(MatchExpr::cast(self.syntax.clone()).unwrap()),
-            STRUCT_LIT => ExprKind::StructLit(StructLit::cast(self.syntax.clone()).unwrap()),
-            CALL_EXPR => ExprKind::CallExpr(CallExpr::cast(self.syntax.clone()).unwrap()),
-            INDEX_EXPR => ExprKind::IndexExpr(IndexExpr::cast(self.syntax.clone()).unwrap()),
-            METHOD_CALL_EXPR => ExprKind::MethodCallExpr(MethodCallExpr::cast(self.syntax.clone()).unwrap()),
-            FIELD_EXPR => ExprKind::FieldExpr(FieldExpr::cast(self.syntax.clone()).unwrap()),
-            AWAIT_EXPR => ExprKind::AwaitExpr(AwaitExpr::cast(self.syntax.clone()).unwrap()),
-            TRY_EXPR => ExprKind::TryExpr(TryExpr::cast(self.syntax.clone()).unwrap()),
-            TRY_BLOCK_EXPR => ExprKind::TryBlockExpr(TryBlockExpr::cast(self.syntax.clone()).unwrap()),
-            CAST_EXPR => ExprKind::CastExpr(CastExpr::cast(self.syntax.clone()).unwrap()),
-            REF_EXPR => ExprKind::RefExpr(RefExpr::cast(self.syntax.clone()).unwrap()),
-            PREFIX_EXPR => ExprKind::PrefixExpr(PrefixExpr::cast(self.syntax.clone()).unwrap()),
-            RANGE_EXPR => ExprKind::RangeExpr(RangeExpr::cast(self.syntax.clone()).unwrap()),
-            BIN_EXPR => ExprKind::BinExpr(BinExpr::cast(self.syntax.clone()).unwrap()),
-            LITERAL => ExprKind::Literal(Literal::cast(self.syntax.clone()).unwrap()),
-            MACRO_CALL => ExprKind::MacroCall(MacroCall::cast(self.syntax.clone()).unwrap()),
+        let syntax = self.syntax.clone();
+        match syntax.kind() {
+            TUPLE_EXPR => ExprKind::TupleExpr(TupleExpr { syntax }),
+            ARRAY_EXPR => ExprKind::ArrayExpr(ArrayExpr { syntax }),
+            PAREN_EXPR => ExprKind::ParenExpr(ParenExpr { syntax }),
+            PATH_EXPR => ExprKind::PathExpr(PathExpr { syntax }),
+            LAMBDA_EXPR => ExprKind::LambdaExpr(LambdaExpr { syntax }),
+            IF_EXPR => ExprKind::IfExpr(IfExpr { syntax }),
+            LOOP_EXPR => ExprKind::LoopExpr(LoopExpr { syntax }),
+            FOR_EXPR => ExprKind::ForExpr(ForExpr { syntax }),
+            WHILE_EXPR => ExprKind::WhileExpr(WhileExpr { syntax }),
+            CONTINUE_EXPR => ExprKind::ContinueExpr(ContinueExpr { syntax }),
+            BREAK_EXPR => ExprKind::BreakExpr(BreakExpr { syntax }),
+            LABEL => ExprKind::Label(Label { syntax }),
+            BLOCK_EXPR => ExprKind::BlockExpr(BlockExpr { syntax }),
+            RETURN_EXPR => ExprKind::ReturnExpr(ReturnExpr { syntax }),
+            MATCH_EXPR => ExprKind::MatchExpr(MatchExpr { syntax }),
+            STRUCT_LIT => ExprKind::StructLit(StructLit { syntax }),
+            CALL_EXPR => ExprKind::CallExpr(CallExpr { syntax }),
+            INDEX_EXPR => ExprKind::IndexExpr(IndexExpr { syntax }),
+            METHOD_CALL_EXPR => ExprKind::MethodCallExpr(MethodCallExpr { syntax }),
+            FIELD_EXPR => ExprKind::FieldExpr(FieldExpr { syntax }),
+            AWAIT_EXPR => ExprKind::AwaitExpr(AwaitExpr { syntax }),
+            TRY_EXPR => ExprKind::TryExpr(TryExpr { syntax }),
+            TRY_BLOCK_EXPR => ExprKind::TryBlockExpr(TryBlockExpr { syntax }),
+            CAST_EXPR => ExprKind::CastExpr(CastExpr { syntax }),
+            REF_EXPR => ExprKind::RefExpr(RefExpr { syntax }),
+            PREFIX_EXPR => ExprKind::PrefixExpr(PrefixExpr { syntax }),
+            RANGE_EXPR => ExprKind::RangeExpr(RangeExpr { syntax }),
+            BIN_EXPR => ExprKind::BinExpr(BinExpr { syntax }),
+            LITERAL => ExprKind::Literal(Literal { syntax }),
+            MACRO_CALL => ExprKind::MacroCall(MacroCall { syntax }),
             _ => unreachable!(),
         }
     }
 }
-
 impl Expr {}
-
-// ExprStmt
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ExprStmt {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ExprStmt {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -780,24 +851,25 @@ impl AstNode for ExprStmt {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ExprStmt { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ExprStmt {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ExternCrateItem
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ExternCrateItem {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ExternCrateItem {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -806,28 +878,28 @@ impl AstNode for ExternCrateItem {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ExternCrateItem { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ExternCrateItem {
     pub fn name_ref(&self) -> Option<NameRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn alias(&self) -> Option<Alias> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// FieldExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FieldExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for FieldExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -836,28 +908,28 @@ impl AstNode for FieldExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(FieldExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl FieldExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn name_ref(&self) -> Option<NameRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// FieldPat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FieldPat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for FieldPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -866,25 +938,26 @@ impl AstNode for FieldPat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(FieldPat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::NameOwner for FieldPat {}
 impl FieldPat {
     pub fn pat(&self) -> Option<Pat> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// FieldPatList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FieldPatList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for FieldPatList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -893,28 +966,28 @@ impl AstNode for FieldPatList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(FieldPatList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl FieldPatList {
-    pub fn field_pats(&self) -> impl Iterator<Item = FieldPat> {
-        super::children(self)
+    pub fn field_pats(&self) -> AstChildren<FieldPat> {
+        AstChildren::new(&self.syntax)
     }
-
-    pub fn bind_pats(&self) -> impl Iterator<Item = BindPat> {
-        super::children(self)
+    pub fn bind_pats(&self) -> AstChildren<BindPat> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// FnDef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FnDef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for FnDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -923,12 +996,16 @@ impl AstNode for FnDef {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(FnDef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::VisibilityOwner for FnDef {}
 impl ast::NameOwner for FnDef {}
 impl ast::TypeParamsOwner for FnDef {}
@@ -936,24 +1013,19 @@ impl ast::AttrsOwner for FnDef {}
 impl ast::DocCommentsOwner for FnDef {}
 impl FnDef {
     pub fn param_list(&self) -> Option<ParamList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn body(&self) -> Option<Block> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn ret_type(&self) -> Option<RetType> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// FnPointerType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FnPointerType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for FnPointerType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -962,28 +1034,28 @@ impl AstNode for FnPointerType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(FnPointerType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl FnPointerType {
     pub fn param_list(&self) -> Option<ParamList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn ret_type(&self) -> Option<RetType> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ForExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ForExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ForExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -992,29 +1064,29 @@ impl AstNode for ForExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ForExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::LoopBodyOwner for ForExpr {}
 impl ForExpr {
     pub fn pat(&self) -> Option<Pat> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn iterable(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ForType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ForType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ForType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1023,24 +1095,25 @@ impl AstNode for ForType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ForType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ForType {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// IfExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct IfExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for IfExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1049,24 +1122,25 @@ impl AstNode for IfExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(IfExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl IfExpr {
     pub fn condition(&self) -> Option<Condition> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ImplBlock
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ImplBlock {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ImplBlock {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1075,74 +1149,81 @@ impl AstNode for ImplBlock {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ImplBlock { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::TypeParamsOwner for ImplBlock {}
 impl ast::AttrsOwner for ImplBlock {}
 impl ImplBlock {
     pub fn item_list(&self) -> Option<ItemList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ImplItem
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ImplItem {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ImplItem {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-             | FN_DEF | TYPE_ALIAS_DEF | CONST_DEF => true,
+            FN_DEF | TYPE_ALIAS_DEF | CONST_DEF => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ImplItem { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
-#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ImplItemKind {
     FnDef(FnDef),
     TypeAliasDef(TypeAliasDef),
     ConstDef(ConstDef),
 }
 impl From<FnDef> for ImplItem {
-    fn from(n: FnDef) -> ImplItem { ImplItem { syntax: n.syntax } }
+    fn from(node: FnDef) -> ImplItem {
+        ImplItem { syntax: node.syntax }
+    }
 }
 impl From<TypeAliasDef> for ImplItem {
-    fn from(n: TypeAliasDef) -> ImplItem { ImplItem { syntax: n.syntax } }
+    fn from(node: TypeAliasDef) -> ImplItem {
+        ImplItem { syntax: node.syntax }
+    }
 }
 impl From<ConstDef> for ImplItem {
-    fn from(n: ConstDef) -> ImplItem { ImplItem { syntax: n.syntax } }
+    fn from(node: ConstDef) -> ImplItem {
+        ImplItem { syntax: node.syntax }
+    }
 }
 impl ImplItem {
     pub fn kind(&self) -> ImplItemKind {
-        match self.syntax.kind() {
-            FN_DEF => ImplItemKind::FnDef(FnDef::cast(self.syntax.clone()).unwrap()),
-            TYPE_ALIAS_DEF => ImplItemKind::TypeAliasDef(TypeAliasDef::cast(self.syntax.clone()).unwrap()),
-            CONST_DEF => ImplItemKind::ConstDef(ConstDef::cast(self.syntax.clone()).unwrap()),
+        let syntax = self.syntax.clone();
+        match syntax.kind() {
+            FN_DEF => ImplItemKind::FnDef(FnDef { syntax }),
+            TYPE_ALIAS_DEF => ImplItemKind::TypeAliasDef(TypeAliasDef { syntax }),
+            CONST_DEF => ImplItemKind::ConstDef(ConstDef { syntax }),
             _ => unreachable!(),
         }
     }
 }
-
 impl ImplItem {}
-
-// ImplTraitType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ImplTraitType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ImplTraitType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1151,21 +1232,22 @@ impl AstNode for ImplTraitType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ImplTraitType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::TypeBoundsOwner for ImplTraitType {}
 impl ImplTraitType {}
-
-// IndexExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct IndexExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for IndexExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1174,20 +1256,21 @@ impl AstNode for IndexExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(IndexExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl IndexExpr {}
-
-// ItemList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ItemList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ItemList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1196,26 +1279,27 @@ impl AstNode for ItemList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ItemList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::FnDefOwner for ItemList {}
 impl ast::ModuleItemOwner for ItemList {}
 impl ItemList {
-    pub fn impl_items(&self) -> impl Iterator<Item = ImplItem> {
-        super::children(self)
+    pub fn impl_items(&self) -> AstChildren<ImplItem> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// Label
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Label {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Label {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1224,20 +1308,21 @@ impl AstNode for Label {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Label { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl Label {}
-
-// LambdaExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LambdaExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for LambdaExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1246,28 +1331,28 @@ impl AstNode for LambdaExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(LambdaExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl LambdaExpr {
     pub fn param_list(&self) -> Option<ParamList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn body(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// LetStmt
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LetStmt {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for LetStmt {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1276,29 +1361,29 @@ impl AstNode for LetStmt {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(LetStmt { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::TypeAscriptionOwner for LetStmt {}
 impl LetStmt {
     pub fn pat(&self) -> Option<Pat> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn initializer(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// LifetimeArg
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LifetimeArg {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for LifetimeArg {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1307,20 +1392,21 @@ impl AstNode for LifetimeArg {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(LifetimeArg { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl LifetimeArg {}
-
-// LifetimeParam
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LifetimeParam {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for LifetimeParam {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1329,21 +1415,22 @@ impl AstNode for LifetimeParam {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(LifetimeParam { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::AttrsOwner for LifetimeParam {}
 impl LifetimeParam {}
-
-// Literal
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Literal {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Literal {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1352,20 +1439,21 @@ impl AstNode for Literal {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Literal { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl Literal {}
-
-// LiteralPat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LiteralPat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for LiteralPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1374,24 +1462,25 @@ impl AstNode for LiteralPat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(LiteralPat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl LiteralPat {
     pub fn literal(&self) -> Option<Literal> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// LoopExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LoopExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for LoopExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1400,21 +1489,22 @@ impl AstNode for LoopExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(LoopExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::LoopBodyOwner for LoopExpr {}
 impl LoopExpr {}
-
-// MacroCall
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MacroCall {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for MacroCall {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1423,31 +1513,31 @@ impl AstNode for MacroCall {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(MacroCall { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::NameOwner for MacroCall {}
 impl ast::AttrsOwner for MacroCall {}
 impl ast::DocCommentsOwner for MacroCall {}
 impl MacroCall {
     pub fn token_tree(&self) -> Option<TokenTree> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn path(&self) -> Option<Path> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// MacroItems
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MacroItems {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for MacroItems {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1456,22 +1546,23 @@ impl AstNode for MacroItems {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(MacroItems { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::ModuleItemOwner for MacroItems {}
 impl ast::FnDefOwner for MacroItems {}
 impl MacroItems {}
-
-// MacroStmts
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MacroStmts {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for MacroStmts {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1480,28 +1571,28 @@ impl AstNode for MacroStmts {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(MacroStmts { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl MacroStmts {
-    pub fn statements(&self) -> impl Iterator<Item = Stmt> {
-        super::children(self)
+    pub fn statements(&self) -> AstChildren<Stmt> {
+        AstChildren::new(&self.syntax)
     }
-
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// MatchArm
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MatchArm {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for MatchArm {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1510,33 +1601,32 @@ impl AstNode for MatchArm {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(MatchArm { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::AttrsOwner for MatchArm {}
 impl MatchArm {
-    pub fn pats(&self) -> impl Iterator<Item = Pat> {
-        super::children(self)
+    pub fn pats(&self) -> AstChildren<Pat> {
+        AstChildren::new(&self.syntax)
     }
-
     pub fn guard(&self) -> Option<MatchGuard> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// MatchArmList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MatchArmList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for MatchArmList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1545,25 +1635,26 @@ impl AstNode for MatchArmList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(MatchArmList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::AttrsOwner for MatchArmList {}
 impl MatchArmList {
-    pub fn arms(&self) -> impl Iterator<Item = MatchArm> {
-        super::children(self)
+    pub fn arms(&self) -> AstChildren<MatchArm> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// MatchExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MatchExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for MatchExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1572,28 +1663,28 @@ impl AstNode for MatchExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(MatchExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl MatchExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn match_arm_list(&self) -> Option<MatchArmList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// MatchGuard
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MatchGuard {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for MatchGuard {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1602,24 +1693,25 @@ impl AstNode for MatchGuard {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(MatchGuard { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl MatchGuard {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// MethodCallExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct MethodCallExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for MethodCallExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1628,33 +1720,32 @@ impl AstNode for MethodCallExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(MethodCallExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::ArgListOwner for MethodCallExpr {}
 impl MethodCallExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn name_ref(&self) -> Option<NameRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn type_arg_list(&self) -> Option<TypeArgList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// Module
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Module {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Module {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1663,43 +1754,48 @@ impl AstNode for Module {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Module { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::VisibilityOwner for Module {}
 impl ast::NameOwner for Module {}
 impl ast::AttrsOwner for Module {}
 impl ast::DocCommentsOwner for Module {}
 impl Module {
     pub fn item_list(&self) -> Option<ItemList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ModuleItem
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ModuleItem {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ModuleItem {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-             | STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_BLOCK | USE_ITEM | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true,
+            STRUCT_DEF | ENUM_DEF | FN_DEF | TRAIT_DEF | TYPE_ALIAS_DEF | IMPL_BLOCK | USE_ITEM
+            | EXTERN_CRATE_ITEM | CONST_DEF | STATIC_DEF | MODULE => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ModuleItem { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
-#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ModuleItemKind {
     StructDef(StructDef),
     EnumDef(EnumDef),
@@ -1714,65 +1810,84 @@ pub enum ModuleItemKind {
     Module(Module),
 }
 impl From<StructDef> for ModuleItem {
-    fn from(n: StructDef) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: StructDef) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl From<EnumDef> for ModuleItem {
-    fn from(n: EnumDef) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: EnumDef) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl From<FnDef> for ModuleItem {
-    fn from(n: FnDef) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: FnDef) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl From<TraitDef> for ModuleItem {
-    fn from(n: TraitDef) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: TraitDef) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl From<TypeAliasDef> for ModuleItem {
-    fn from(n: TypeAliasDef) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: TypeAliasDef) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl From<ImplBlock> for ModuleItem {
-    fn from(n: ImplBlock) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: ImplBlock) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl From<UseItem> for ModuleItem {
-    fn from(n: UseItem) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: UseItem) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl From<ExternCrateItem> for ModuleItem {
-    fn from(n: ExternCrateItem) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: ExternCrateItem) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl From<ConstDef> for ModuleItem {
-    fn from(n: ConstDef) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: ConstDef) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl From<StaticDef> for ModuleItem {
-    fn from(n: StaticDef) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: StaticDef) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl From<Module> for ModuleItem {
-    fn from(n: Module) -> ModuleItem { ModuleItem { syntax: n.syntax } }
+    fn from(node: Module) -> ModuleItem {
+        ModuleItem { syntax: node.syntax }
+    }
 }
 impl ModuleItem {
     pub fn kind(&self) -> ModuleItemKind {
-        match self.syntax.kind() {
-            STRUCT_DEF => ModuleItemKind::StructDef(StructDef::cast(self.syntax.clone()).unwrap()),
-            ENUM_DEF => ModuleItemKind::EnumDef(EnumDef::cast(self.syntax.clone()).unwrap()),
-            FN_DEF => ModuleItemKind::FnDef(FnDef::cast(self.syntax.clone()).unwrap()),
-            TRAIT_DEF => ModuleItemKind::TraitDef(TraitDef::cast(self.syntax.clone()).unwrap()),
-            TYPE_ALIAS_DEF => ModuleItemKind::TypeAliasDef(TypeAliasDef::cast(self.syntax.clone()).unwrap()),
-            IMPL_BLOCK => ModuleItemKind::ImplBlock(ImplBlock::cast(self.syntax.clone()).unwrap()),
-            USE_ITEM => ModuleItemKind::UseItem(UseItem::cast(self.syntax.clone()).unwrap()),
-            EXTERN_CRATE_ITEM => ModuleItemKind::ExternCrateItem(ExternCrateItem::cast(self.syntax.clone()).unwrap()),
-            CONST_DEF => ModuleItemKind::ConstDef(ConstDef::cast(self.syntax.clone()).unwrap()),
-            STATIC_DEF => ModuleItemKind::StaticDef(StaticDef::cast(self.syntax.clone()).unwrap()),
-            MODULE => ModuleItemKind::Module(Module::cast(self.syntax.clone()).unwrap()),
+        let syntax = self.syntax.clone();
+        match syntax.kind() {
+            STRUCT_DEF => ModuleItemKind::StructDef(StructDef { syntax }),
+            ENUM_DEF => ModuleItemKind::EnumDef(EnumDef { syntax }),
+            FN_DEF => ModuleItemKind::FnDef(FnDef { syntax }),
+            TRAIT_DEF => ModuleItemKind::TraitDef(TraitDef { syntax }),
+            TYPE_ALIAS_DEF => ModuleItemKind::TypeAliasDef(TypeAliasDef { syntax }),
+            IMPL_BLOCK => ModuleItemKind::ImplBlock(ImplBlock { syntax }),
+            USE_ITEM => ModuleItemKind::UseItem(UseItem { syntax }),
+            EXTERN_CRATE_ITEM => ModuleItemKind::ExternCrateItem(ExternCrateItem { syntax }),
+            CONST_DEF => ModuleItemKind::ConstDef(ConstDef { syntax }),
+            STATIC_DEF => ModuleItemKind::StaticDef(StaticDef { syntax }),
+            MODULE => ModuleItemKind::Module(Module { syntax }),
             _ => unreachable!(),
         }
     }
 }
-
 impl ModuleItem {}
-
-// Name
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Name {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Name {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1781,20 +1896,21 @@ impl AstNode for Name {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Name { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl Name {}
-
-// NameRef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct NameRef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for NameRef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1803,20 +1919,21 @@ impl AstNode for NameRef {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(NameRef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl NameRef {}
-
-// NamedField
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct NamedField {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for NamedField {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1825,28 +1942,28 @@ impl AstNode for NamedField {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(NamedField { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl NamedField {
     pub fn name_ref(&self) -> Option<NameRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// NamedFieldDef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct NamedFieldDef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for NamedFieldDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1855,25 +1972,26 @@ impl AstNode for NamedFieldDef {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(NamedFieldDef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::VisibilityOwner for NamedFieldDef {}
 impl ast::NameOwner for NamedFieldDef {}
 impl ast::AttrsOwner for NamedFieldDef {}
 impl ast::DocCommentsOwner for NamedFieldDef {}
 impl ast::TypeAscriptionOwner for NamedFieldDef {}
 impl NamedFieldDef {}
-
-// NamedFieldDefList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct NamedFieldDefList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for NamedFieldDefList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1882,24 +2000,25 @@ impl AstNode for NamedFieldDefList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(NamedFieldDefList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl NamedFieldDefList {
-    pub fn fields(&self) -> impl Iterator<Item = NamedFieldDef> {
-        super::children(self)
+    pub fn fields(&self) -> AstChildren<NamedFieldDef> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// NamedFieldList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct NamedFieldList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for NamedFieldList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1908,28 +2027,28 @@ impl AstNode for NamedFieldList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(NamedFieldList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl NamedFieldList {
-    pub fn fields(&self) -> impl Iterator<Item = NamedField> {
-        super::children(self)
+    pub fn fields(&self) -> AstChildren<NamedField> {
+        AstChildren::new(&self.syntax)
     }
-
     pub fn spread(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// NeverType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct NeverType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for NeverType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -1938,66 +2057,71 @@ impl AstNode for NeverType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(NeverType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl NeverType {}
-
-// NominalDef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct NominalDef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for NominalDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-             | STRUCT_DEF | ENUM_DEF => true,
+            STRUCT_DEF | ENUM_DEF => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(NominalDef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
-#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum NominalDefKind {
     StructDef(StructDef),
     EnumDef(EnumDef),
 }
 impl From<StructDef> for NominalDef {
-    fn from(n: StructDef) -> NominalDef { NominalDef { syntax: n.syntax } }
+    fn from(node: StructDef) -> NominalDef {
+        NominalDef { syntax: node.syntax }
+    }
 }
 impl From<EnumDef> for NominalDef {
-    fn from(n: EnumDef) -> NominalDef { NominalDef { syntax: n.syntax } }
+    fn from(node: EnumDef) -> NominalDef {
+        NominalDef { syntax: node.syntax }
+    }
 }
 impl NominalDef {
     pub fn kind(&self) -> NominalDefKind {
-        match self.syntax.kind() {
-            STRUCT_DEF => NominalDefKind::StructDef(StructDef::cast(self.syntax.clone()).unwrap()),
-            ENUM_DEF => NominalDefKind::EnumDef(EnumDef::cast(self.syntax.clone()).unwrap()),
+        let syntax = self.syntax.clone();
+        match syntax.kind() {
+            STRUCT_DEF => NominalDefKind::StructDef(StructDef { syntax }),
+            ENUM_DEF => NominalDefKind::EnumDef(EnumDef { syntax }),
             _ => unreachable!(),
         }
     }
 }
-
 impl ast::NameOwner for NominalDef {}
 impl ast::TypeParamsOwner for NominalDef {}
 impl ast::AttrsOwner for NominalDef {}
 impl NominalDef {}
-
-// Param
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Param {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Param {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2006,26 +2130,27 @@ impl AstNode for Param {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Param { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::TypeAscriptionOwner for Param {}
 impl ast::AttrsOwner for Param {}
 impl Param {
     pub fn pat(&self) -> Option<Pat> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ParamList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ParamList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ParamList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2034,28 +2159,28 @@ impl AstNode for ParamList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ParamList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ParamList {
-    pub fn params(&self) -> impl Iterator<Item = Param> {
-        super::children(self)
+    pub fn params(&self) -> AstChildren<Param> {
+        AstChildren::new(&self.syntax)
     }
-
     pub fn self_param(&self) -> Option<SelfParam> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ParenExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ParenExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ParenExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2064,24 +2189,25 @@ impl AstNode for ParenExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ParenExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ParenExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ParenType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ParenType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ParenType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2090,39 +2216,44 @@ impl AstNode for ParenType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ParenType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ParenType {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// Pat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Pat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Pat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-             | REF_PAT | BIND_PAT | PLACEHOLDER_PAT | PATH_PAT | STRUCT_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT | LITERAL_PAT => true,
+            REF_PAT | BIND_PAT | PLACEHOLDER_PAT | PATH_PAT | STRUCT_PAT | TUPLE_STRUCT_PAT
+            | TUPLE_PAT | SLICE_PAT | RANGE_PAT | LITERAL_PAT => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Pat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
-#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum PatKind {
     RefPat(RefPat),
     BindPat(BindPat),
@@ -2136,61 +2267,78 @@ pub enum PatKind {
     LiteralPat(LiteralPat),
 }
 impl From<RefPat> for Pat {
-    fn from(n: RefPat) -> Pat { Pat { syntax: n.syntax } }
+    fn from(node: RefPat) -> Pat {
+        Pat { syntax: node.syntax }
+    }
 }
 impl From<BindPat> for Pat {
-    fn from(n: BindPat) -> Pat { Pat { syntax: n.syntax } }
+    fn from(node: BindPat) -> Pat {
+        Pat { syntax: node.syntax }
+    }
 }
 impl From<PlaceholderPat> for Pat {
-    fn from(n: PlaceholderPat) -> Pat { Pat { syntax: n.syntax } }
+    fn from(node: PlaceholderPat) -> Pat {
+        Pat { syntax: node.syntax }
+    }
 }
 impl From<PathPat> for Pat {
-    fn from(n: PathPat) -> Pat { Pat { syntax: n.syntax } }
+    fn from(node: PathPat) -> Pat {
+        Pat { syntax: node.syntax }
+    }
 }
 impl From<StructPat> for Pat {
-    fn from(n: StructPat) -> Pat { Pat { syntax: n.syntax } }
+    fn from(node: StructPat) -> Pat {
+        Pat { syntax: node.syntax }
+    }
 }
 impl From<TupleStructPat> for Pat {
-    fn from(n: TupleStructPat) -> Pat { Pat { syntax: n.syntax } }
+    fn from(node: TupleStructPat) -> Pat {
+        Pat { syntax: node.syntax }
+    }
 }
 impl From<TuplePat> for Pat {
-    fn from(n: TuplePat) -> Pat { Pat { syntax: n.syntax } }
+    fn from(node: TuplePat) -> Pat {
+        Pat { syntax: node.syntax }
+    }
 }
 impl From<SlicePat> for Pat {
-    fn from(n: SlicePat) -> Pat { Pat { syntax: n.syntax } }
+    fn from(node: SlicePat) -> Pat {
+        Pat { syntax: node.syntax }
+    }
 }
 impl From<RangePat> for Pat {
-    fn from(n: RangePat) -> Pat { Pat { syntax: n.syntax } }
+    fn from(node: RangePat) -> Pat {
+        Pat { syntax: node.syntax }
+    }
 }
 impl From<LiteralPat> for Pat {
-    fn from(n: LiteralPat) -> Pat { Pat { syntax: n.syntax } }
+    fn from(node: LiteralPat) -> Pat {
+        Pat { syntax: node.syntax }
+    }
 }
 impl Pat {
     pub fn kind(&self) -> PatKind {
-        match self.syntax.kind() {
-            REF_PAT => PatKind::RefPat(RefPat::cast(self.syntax.clone()).unwrap()),
-            BIND_PAT => PatKind::BindPat(BindPat::cast(self.syntax.clone()).unwrap()),
-            PLACEHOLDER_PAT => PatKind::PlaceholderPat(PlaceholderPat::cast(self.syntax.clone()).unwrap()),
-            PATH_PAT => PatKind::PathPat(PathPat::cast(self.syntax.clone()).unwrap()),
-            STRUCT_PAT => PatKind::StructPat(StructPat::cast(self.syntax.clone()).unwrap()),
-            TUPLE_STRUCT_PAT => PatKind::TupleStructPat(TupleStructPat::cast(self.syntax.clone()).unwrap()),
-            TUPLE_PAT => PatKind::TuplePat(TuplePat::cast(self.syntax.clone()).unwrap()),
-            SLICE_PAT => PatKind::SlicePat(SlicePat::cast(self.syntax.clone()).unwrap()),
-            RANGE_PAT => PatKind::RangePat(RangePat::cast(self.syntax.clone()).unwrap()),
-            LITERAL_PAT => PatKind::LiteralPat(LiteralPat::cast(self.syntax.clone()).unwrap()),
+        let syntax = self.syntax.clone();
+        match syntax.kind() {
+            REF_PAT => PatKind::RefPat(RefPat { syntax }),
+            BIND_PAT => PatKind::BindPat(BindPat { syntax }),
+            PLACEHOLDER_PAT => PatKind::PlaceholderPat(PlaceholderPat { syntax }),
+            PATH_PAT => PatKind::PathPat(PathPat { syntax }),
+            STRUCT_PAT => PatKind::StructPat(StructPat { syntax }),
+            TUPLE_STRUCT_PAT => PatKind::TupleStructPat(TupleStructPat { syntax }),
+            TUPLE_PAT => PatKind::TuplePat(TuplePat { syntax }),
+            SLICE_PAT => PatKind::SlicePat(SlicePat { syntax }),
+            RANGE_PAT => PatKind::RangePat(RangePat { syntax }),
+            LITERAL_PAT => PatKind::LiteralPat(LiteralPat { syntax }),
             _ => unreachable!(),
         }
     }
 }
-
 impl Pat {}
-
-// Path
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Path {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Path {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2199,28 +2347,28 @@ impl AstNode for Path {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Path { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl Path {
     pub fn segment(&self) -> Option<PathSegment> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn qualifier(&self) -> Option<Path> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// PathExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PathExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for PathExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2229,24 +2377,25 @@ impl AstNode for PathExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(PathExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl PathExpr {
     pub fn path(&self) -> Option<Path> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// PathPat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PathPat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for PathPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2255,24 +2404,25 @@ impl AstNode for PathPat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(PathPat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl PathPat {
     pub fn path(&self) -> Option<Path> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// PathSegment
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PathSegment {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for PathSegment {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2281,28 +2431,28 @@ impl AstNode for PathSegment {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(PathSegment { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl PathSegment {
     pub fn name_ref(&self) -> Option<NameRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn type_arg_list(&self) -> Option<TypeArgList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// PathType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PathType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for PathType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2311,24 +2461,25 @@ impl AstNode for PathType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(PathType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl PathType {
     pub fn path(&self) -> Option<Path> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// PlaceholderPat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PlaceholderPat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for PlaceholderPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2337,20 +2488,21 @@ impl AstNode for PlaceholderPat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(PlaceholderPat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl PlaceholderPat {}
-
-// PlaceholderType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PlaceholderType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for PlaceholderType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2359,20 +2511,21 @@ impl AstNode for PlaceholderType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(PlaceholderType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl PlaceholderType {}
-
-// PointerType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PointerType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for PointerType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2381,24 +2534,25 @@ impl AstNode for PointerType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(PointerType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl PointerType {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// PosFieldDef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PosFieldDef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for PosFieldDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2407,26 +2561,27 @@ impl AstNode for PosFieldDef {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(PosFieldDef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::VisibilityOwner for PosFieldDef {}
 impl ast::AttrsOwner for PosFieldDef {}
 impl PosFieldDef {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// PosFieldDefList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PosFieldDefList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for PosFieldDefList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2435,24 +2590,25 @@ impl AstNode for PosFieldDefList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(PosFieldDefList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl PosFieldDefList {
-    pub fn fields(&self) -> impl Iterator<Item = PosFieldDef> {
-        super::children(self)
+    pub fn fields(&self) -> AstChildren<PosFieldDef> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// PrefixExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct PrefixExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for PrefixExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2461,24 +2617,25 @@ impl AstNode for PrefixExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(PrefixExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl PrefixExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// RangeExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RangeExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for RangeExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2487,20 +2644,21 @@ impl AstNode for RangeExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(RangeExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl RangeExpr {}
-
-// RangePat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RangePat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for RangePat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2509,20 +2667,21 @@ impl AstNode for RangePat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(RangePat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl RangePat {}
-
-// RefExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RefExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for RefExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2531,24 +2690,25 @@ impl AstNode for RefExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(RefExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl RefExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// RefPat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RefPat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for RefPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2557,24 +2717,25 @@ impl AstNode for RefPat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(RefPat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl RefPat {
     pub fn pat(&self) -> Option<Pat> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ReferenceType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ReferenceType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ReferenceType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2583,24 +2744,25 @@ impl AstNode for ReferenceType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ReferenceType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ReferenceType {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// RetType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct RetType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for RetType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2609,24 +2771,25 @@ impl AstNode for RetType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(RetType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl RetType {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// ReturnExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct ReturnExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for ReturnExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2635,24 +2798,25 @@ impl AstNode for ReturnExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(ReturnExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ReturnExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// SelfParam
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct SelfParam {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for SelfParam {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2661,22 +2825,23 @@ impl AstNode for SelfParam {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(SelfParam { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::TypeAscriptionOwner for SelfParam {}
 impl ast::AttrsOwner for SelfParam {}
 impl SelfParam {}
-
-// SlicePat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct SlicePat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for SlicePat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2685,20 +2850,21 @@ impl AstNode for SlicePat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(SlicePat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl SlicePat {}
-
-// SliceType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct SliceType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for SliceType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2707,24 +2873,25 @@ impl AstNode for SliceType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(SliceType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl SliceType {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// SourceFile
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct SourceFile {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for SourceFile {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2733,26 +2900,27 @@ impl AstNode for SourceFile {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(SourceFile { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::ModuleItemOwner for SourceFile {}
 impl ast::FnDefOwner for SourceFile {}
 impl SourceFile {
-    pub fn modules(&self) -> impl Iterator<Item = Module> {
-        super::children(self)
+    pub fn modules(&self) -> AstChildren<Module> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// StaticDef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct StaticDef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for StaticDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2761,12 +2929,16 @@ impl AstNode for StaticDef {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(StaticDef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::VisibilityOwner for StaticDef {}
 impl ast::NameOwner for StaticDef {}
 impl ast::TypeParamsOwner for StaticDef {}
@@ -2775,59 +2947,60 @@ impl ast::DocCommentsOwner for StaticDef {}
 impl ast::TypeAscriptionOwner for StaticDef {}
 impl StaticDef {
     pub fn body(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// Stmt
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Stmt {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Stmt {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-             | EXPR_STMT | LET_STMT => true,
+            EXPR_STMT | LET_STMT => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Stmt { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
-#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum StmtKind {
     ExprStmt(ExprStmt),
     LetStmt(LetStmt),
 }
 impl From<ExprStmt> for Stmt {
-    fn from(n: ExprStmt) -> Stmt { Stmt { syntax: n.syntax } }
+    fn from(node: ExprStmt) -> Stmt {
+        Stmt { syntax: node.syntax }
+    }
 }
 impl From<LetStmt> for Stmt {
-    fn from(n: LetStmt) -> Stmt { Stmt { syntax: n.syntax } }
+    fn from(node: LetStmt) -> Stmt {
+        Stmt { syntax: node.syntax }
+    }
 }
 impl Stmt {
     pub fn kind(&self) -> StmtKind {
-        match self.syntax.kind() {
-            EXPR_STMT => StmtKind::ExprStmt(ExprStmt::cast(self.syntax.clone()).unwrap()),
-            LET_STMT => StmtKind::LetStmt(LetStmt::cast(self.syntax.clone()).unwrap()),
+        let syntax = self.syntax.clone();
+        match syntax.kind() {
+            EXPR_STMT => StmtKind::ExprStmt(ExprStmt { syntax }),
+            LET_STMT => StmtKind::LetStmt(LetStmt { syntax }),
             _ => unreachable!(),
         }
     }
 }
-
 impl Stmt {}
-
-// StructDef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct StructDef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for StructDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2836,25 +3009,26 @@ impl AstNode for StructDef {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(StructDef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::VisibilityOwner for StructDef {}
 impl ast::NameOwner for StructDef {}
 impl ast::TypeParamsOwner for StructDef {}
 impl ast::AttrsOwner for StructDef {}
 impl ast::DocCommentsOwner for StructDef {}
 impl StructDef {}
-
-// StructLit
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct StructLit {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for StructLit {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2863,28 +3037,28 @@ impl AstNode for StructLit {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(StructLit { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl StructLit {
     pub fn path(&self) -> Option<Path> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn named_field_list(&self) -> Option<NamedFieldList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// StructPat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct StructPat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for StructPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2893,28 +3067,28 @@ impl AstNode for StructPat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(StructPat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl StructPat {
     pub fn field_pat_list(&self) -> Option<FieldPatList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn path(&self) -> Option<Path> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// TokenTree
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TokenTree {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TokenTree {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2923,20 +3097,21 @@ impl AstNode for TokenTree {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TokenTree { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TokenTree {}
-
-// TraitDef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TraitDef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TraitDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2945,12 +3120,16 @@ impl AstNode for TraitDef {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TraitDef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::VisibilityOwner for TraitDef {}
 impl ast::NameOwner for TraitDef {}
 impl ast::AttrsOwner for TraitDef {}
@@ -2959,16 +3138,13 @@ impl ast::TypeParamsOwner for TraitDef {}
 impl ast::TypeBoundsOwner for TraitDef {}
 impl TraitDef {
     pub fn item_list(&self) -> Option<ItemList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// TryBlockExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TryBlockExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TryBlockExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -2977,21 +3153,22 @@ impl AstNode for TryBlockExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TryBlockExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::TryBlockBodyOwner for TryBlockExpr {}
 impl TryBlockExpr {}
-
-// TryExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TryExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TryExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3000,24 +3177,25 @@ impl AstNode for TryExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TryExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TryExpr {
     pub fn expr(&self) -> Option<Expr> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// TupleExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TupleExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TupleExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3026,24 +3204,25 @@ impl AstNode for TupleExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TupleExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TupleExpr {
-    pub fn exprs(&self) -> impl Iterator<Item = Expr> {
-        super::children(self)
+    pub fn exprs(&self) -> AstChildren<Expr> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// TuplePat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TuplePat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TuplePat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3052,24 +3231,25 @@ impl AstNode for TuplePat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TuplePat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TuplePat {
-    pub fn args(&self) -> impl Iterator<Item = Pat> {
-        super::children(self)
+    pub fn args(&self) -> AstChildren<Pat> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// TupleStructPat
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TupleStructPat {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TupleStructPat {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3078,28 +3258,28 @@ impl AstNode for TupleStructPat {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TupleStructPat { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TupleStructPat {
-    pub fn args(&self) -> impl Iterator<Item = Pat> {
-        super::children(self)
+    pub fn args(&self) -> AstChildren<Pat> {
+        AstChildren::new(&self.syntax)
     }
-
     pub fn path(&self) -> Option<Path> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// TupleType
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TupleType {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TupleType {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3108,24 +3288,25 @@ impl AstNode for TupleType {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TupleType { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TupleType {
-    pub fn fields(&self) -> impl Iterator<Item = TypeRef> {
-        super::children(self)
+    pub fn fields(&self) -> AstChildren<TypeRef> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// TypeAliasDef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeAliasDef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TypeAliasDef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3134,12 +3315,16 @@ impl AstNode for TypeAliasDef {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TypeAliasDef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::VisibilityOwner for TypeAliasDef {}
 impl ast::NameOwner for TypeAliasDef {}
 impl ast::TypeParamsOwner for TypeAliasDef {}
@@ -3148,16 +3333,13 @@ impl ast::DocCommentsOwner for TypeAliasDef {}
 impl ast::TypeBoundsOwner for TypeAliasDef {}
 impl TypeAliasDef {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// TypeArg
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeArg {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TypeArg {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3166,24 +3348,25 @@ impl AstNode for TypeArg {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TypeArg { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TypeArg {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// TypeArgList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeArgList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TypeArgList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3192,32 +3375,31 @@ impl AstNode for TypeArgList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TypeArgList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TypeArgList {
-    pub fn type_args(&self) -> impl Iterator<Item = TypeArg> {
-        super::children(self)
+    pub fn type_args(&self) -> AstChildren<TypeArg> {
+        AstChildren::new(&self.syntax)
     }
-
-    pub fn lifetime_args(&self) -> impl Iterator<Item = LifetimeArg> {
-        super::children(self)
+    pub fn lifetime_args(&self) -> AstChildren<LifetimeArg> {
+        AstChildren::new(&self.syntax)
     }
-
-    pub fn assoc_type_args(&self) -> impl Iterator<Item = AssocTypeArg> {
-        super::children(self)
+    pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// TypeBound
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeBound {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TypeBound {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3226,24 +3408,25 @@ impl AstNode for TypeBound {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TypeBound { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TypeBound {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// TypeBoundList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeBoundList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TypeBoundList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3252,24 +3435,25 @@ impl AstNode for TypeBoundList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TypeBoundList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TypeBoundList {
-    pub fn bounds(&self) -> impl Iterator<Item = TypeBound> {
-        super::children(self)
+    pub fn bounds(&self) -> AstChildren<TypeBound> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// TypeParam
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeParam {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TypeParam {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3278,24 +3462,25 @@ impl AstNode for TypeParam {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TypeParam { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::NameOwner for TypeParam {}
 impl ast::AttrsOwner for TypeParam {}
 impl ast::TypeBoundsOwner for TypeParam {}
 impl ast::DefaultTypeParamOwner for TypeParam {}
 impl TypeParam {}
-
-// TypeParamList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeParamList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TypeParamList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3304,43 +3489,48 @@ impl AstNode for TypeParamList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TypeParamList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl TypeParamList {
-    pub fn type_params(&self) -> impl Iterator<Item = TypeParam> {
-        super::children(self)
+    pub fn type_params(&self) -> AstChildren<TypeParam> {
+        AstChildren::new(&self.syntax)
     }
-
-    pub fn lifetime_params(&self) -> impl Iterator<Item = LifetimeParam> {
-        super::children(self)
+    pub fn lifetime_params(&self) -> AstChildren<LifetimeParam> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// TypeRef
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct TypeRef {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for TypeRef {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
-             | PAREN_TYPE | TUPLE_TYPE | NEVER_TYPE | PATH_TYPE | POINTER_TYPE | ARRAY_TYPE | SLICE_TYPE | REFERENCE_TYPE | PLACEHOLDER_TYPE | FN_POINTER_TYPE | FOR_TYPE | IMPL_TRAIT_TYPE | DYN_TRAIT_TYPE => true,
+            PAREN_TYPE | TUPLE_TYPE | NEVER_TYPE | PATH_TYPE | POINTER_TYPE | ARRAY_TYPE
+            | SLICE_TYPE | REFERENCE_TYPE | PLACEHOLDER_TYPE | FN_POINTER_TYPE | FOR_TYPE
+            | IMPL_TRAIT_TYPE | DYN_TRAIT_TYPE => true,
             _ => false,
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(TypeRef { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
-#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum TypeRefKind {
     ParenType(ParenType),
     TupleType(TupleType),
@@ -3357,73 +3547,96 @@ pub enum TypeRefKind {
     DynTraitType(DynTraitType),
 }
 impl From<ParenType> for TypeRef {
-    fn from(n: ParenType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: ParenType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<TupleType> for TypeRef {
-    fn from(n: TupleType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: TupleType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<NeverType> for TypeRef {
-    fn from(n: NeverType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: NeverType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<PathType> for TypeRef {
-    fn from(n: PathType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: PathType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<PointerType> for TypeRef {
-    fn from(n: PointerType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: PointerType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<ArrayType> for TypeRef {
-    fn from(n: ArrayType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: ArrayType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<SliceType> for TypeRef {
-    fn from(n: SliceType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: SliceType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<ReferenceType> for TypeRef {
-    fn from(n: ReferenceType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: ReferenceType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<PlaceholderType> for TypeRef {
-    fn from(n: PlaceholderType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: PlaceholderType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<FnPointerType> for TypeRef {
-    fn from(n: FnPointerType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: FnPointerType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<ForType> for TypeRef {
-    fn from(n: ForType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: ForType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<ImplTraitType> for TypeRef {
-    fn from(n: ImplTraitType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: ImplTraitType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl From<DynTraitType> for TypeRef {
-    fn from(n: DynTraitType) -> TypeRef { TypeRef { syntax: n.syntax } }
+    fn from(node: DynTraitType) -> TypeRef {
+        TypeRef { syntax: node.syntax }
+    }
 }
 impl TypeRef {
     pub fn kind(&self) -> TypeRefKind {
-        match self.syntax.kind() {
-            PAREN_TYPE => TypeRefKind::ParenType(ParenType::cast(self.syntax.clone()).unwrap()),
-            TUPLE_TYPE => TypeRefKind::TupleType(TupleType::cast(self.syntax.clone()).unwrap()),
-            NEVER_TYPE => TypeRefKind::NeverType(NeverType::cast(self.syntax.clone()).unwrap()),
-            PATH_TYPE => TypeRefKind::PathType(PathType::cast(self.syntax.clone()).unwrap()),
-            POINTER_TYPE => TypeRefKind::PointerType(PointerType::cast(self.syntax.clone()).unwrap()),
-            ARRAY_TYPE => TypeRefKind::ArrayType(ArrayType::cast(self.syntax.clone()).unwrap()),
-            SLICE_TYPE => TypeRefKind::SliceType(SliceType::cast(self.syntax.clone()).unwrap()),
-            REFERENCE_TYPE => TypeRefKind::ReferenceType(ReferenceType::cast(self.syntax.clone()).unwrap()),
-            PLACEHOLDER_TYPE => TypeRefKind::PlaceholderType(PlaceholderType::cast(self.syntax.clone()).unwrap()),
-            FN_POINTER_TYPE => TypeRefKind::FnPointerType(FnPointerType::cast(self.syntax.clone()).unwrap()),
-            FOR_TYPE => TypeRefKind::ForType(ForType::cast(self.syntax.clone()).unwrap()),
-            IMPL_TRAIT_TYPE => TypeRefKind::ImplTraitType(ImplTraitType::cast(self.syntax.clone()).unwrap()),
-            DYN_TRAIT_TYPE => TypeRefKind::DynTraitType(DynTraitType::cast(self.syntax.clone()).unwrap()),
+        let syntax = self.syntax.clone();
+        match syntax.kind() {
+            PAREN_TYPE => TypeRefKind::ParenType(ParenType { syntax }),
+            TUPLE_TYPE => TypeRefKind::TupleType(TupleType { syntax }),
+            NEVER_TYPE => TypeRefKind::NeverType(NeverType { syntax }),
+            PATH_TYPE => TypeRefKind::PathType(PathType { syntax }),
+            POINTER_TYPE => TypeRefKind::PointerType(PointerType { syntax }),
+            ARRAY_TYPE => TypeRefKind::ArrayType(ArrayType { syntax }),
+            SLICE_TYPE => TypeRefKind::SliceType(SliceType { syntax }),
+            REFERENCE_TYPE => TypeRefKind::ReferenceType(ReferenceType { syntax }),
+            PLACEHOLDER_TYPE => TypeRefKind::PlaceholderType(PlaceholderType { syntax }),
+            FN_POINTER_TYPE => TypeRefKind::FnPointerType(FnPointerType { syntax }),
+            FOR_TYPE => TypeRefKind::ForType(ForType { syntax }),
+            IMPL_TRAIT_TYPE => TypeRefKind::ImplTraitType(ImplTraitType { syntax }),
+            DYN_TRAIT_TYPE => TypeRefKind::DynTraitType(DynTraitType { syntax }),
             _ => unreachable!(),
         }
     }
 }
-
 impl TypeRef {}
-
-// UseItem
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct UseItem {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for UseItem {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3432,25 +3645,26 @@ impl AstNode for UseItem {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(UseItem { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::AttrsOwner for UseItem {}
 impl UseItem {
     pub fn use_tree(&self) -> Option<UseTree> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// UseTree
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct UseTree {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for UseTree {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3459,32 +3673,31 @@ impl AstNode for UseTree {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(UseTree { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl UseTree {
     pub fn path(&self) -> Option<Path> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn use_tree_list(&self) -> Option<UseTreeList> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
-
     pub fn alias(&self) -> Option<Alias> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// UseTreeList
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct UseTreeList {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for UseTreeList {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3493,24 +3706,25 @@ impl AstNode for UseTreeList {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(UseTreeList { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl UseTreeList {
-    pub fn use_trees(&self) -> impl Iterator<Item = UseTree> {
-        super::children(self)
+    pub fn use_trees(&self) -> AstChildren<UseTree> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// Visibility
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct Visibility {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for Visibility {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3519,20 +3733,21 @@ impl AstNode for Visibility {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(Visibility { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl Visibility {}
-
-// WhereClause
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct WhereClause {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for WhereClause {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3541,24 +3756,25 @@ impl AstNode for WhereClause {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(WhereClause { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl WhereClause {
-    pub fn predicates(&self) -> impl Iterator<Item = WherePred> {
-        super::children(self)
+    pub fn predicates(&self) -> AstChildren<WherePred> {
+        AstChildren::new(&self.syntax)
     }
 }
-
-// WherePred
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct WherePred {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for WherePred {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3567,25 +3783,26 @@ impl AstNode for WherePred {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(WherePred { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::TypeBoundsOwner for WherePred {}
 impl WherePred {
     pub fn type_ref(&self) -> Option<TypeRef> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
-// WhileExpr
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct WhileExpr {
     pub(crate) syntax: SyntaxNode,
 }
-
 impl AstNode for WhileExpr {
     fn can_cast(kind: SyntaxKind) -> bool {
         match kind {
@@ -3594,16 +3811,19 @@ impl AstNode for WhileExpr {
         }
     }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some(WhileExpr { syntax }) } else { None }
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode {
+        &self.syntax
     }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
-
-
 impl ast::LoopBodyOwner for WhileExpr {}
 impl WhileExpr {
     pub fn condition(&self) -> Option<Condition> {
-        super::child_opt(self)
+        AstChildren::new(&self.syntax).next()
     }
 }
-
diff --git a/crates/ra_syntax/src/ast/generated.rs.tera b/crates/ra_syntax/src/ast/generated.rs.tera
deleted file mode 100644
index 03b4bf3a1e..0000000000
--- a/crates/ra_syntax/src/ast/generated.rs.tera
+++ /dev/null
@@ -1,101 +0,0 @@
-{# THIS File is not automatically generated:
-the below applies to the result of this template
-#}// This file is automatically generated based on the file `./generated.rs.tera` when `cargo gen-syntax` is run
-// Do not edit manually
-
-//! This module contains auto-generated Rust AST. Like `SyntaxNode`s, AST nodes
-//! are generic over ownership: `X<'a>` things are `Copy` references, `XNode`
-//! are Arc-based. You can switch between the two variants using `.owned` and
-//! `.borrowed` functions. Most of the code works with borowed mode, and only
-//! this mode has all AST accessors.
-
-#![cfg_attr(rustfmt, rustfmt_skip)]
-
-use crate::{
-    SyntaxNode, SyntaxKind::{self, *},
-    ast::{self, AstNode},
-};
-{% for node, methods in ast %}
-// {{ node }}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct {{ node }} {
-    pub(crate) syntax: SyntaxNode,
-}
-
-impl AstNode for {{ node }} {
-    fn can_cast(kind: SyntaxKind) -> bool {
-        match kind {
-            {%- if methods.enum %}
-            {% for kind in methods.enum %} | {{ kind | SCREAM }} {%- endfor -%}
-            {% else %}
-            {{ node | SCREAM }}
-            {%- endif %} => true,
-            _ => false,
-        }
-    }
-    fn cast(syntax: SyntaxNode) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) { Some({{ node }} { syntax }) } else { None }
-    }
-    fn syntax(&self) -> &SyntaxNode { &self.syntax }
-}
-
-{% if methods.enum %}
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum {{ node }}Kind {
-{%- for kind in methods.enum %}
-    {{ kind }}({{ kind }}),
-{%- endfor %}
-}
-
-{%- for kind in methods.enum %}
-impl From<{{ kind }}> for {{ node }} {
-    fn from(n: {{ kind }}) -> {{ node }} { {{ node }} { syntax: n.syntax } }
-}
-{%- endfor %}
-impl {{ node }} {
-    pub fn kind(&self) -> {{ node }}Kind {
-        match self.syntax.kind() {
-            {%- for kind in methods.enum %}
-            {{ kind | SCREAM }} => {{ node }}Kind::{{ kind }}({{ kind }}::cast(self.syntax.clone()).unwrap()),
-            {%- endfor %}
-            _ => unreachable!(),
-        }
-    }
-}
-{% endif %}
-{% if methods.traits -%}
-
-{%- for t in methods.traits -%}
-impl ast::{{ t }} for {{ node }} {}
-{% endfor -%}
-
-{%- endif -%}
-
-impl {{ node }} {
-{%- if methods.collections -%}
-{%- for m in methods.collections -%}
-{%- set method_name = m.0 -%}
-{%- set ChildName = m.1 %}
-    pub fn {{ method_name }}(&self) -> impl Iterator<Item = {{ ChildName }}> {
-        super::children(self)
-    }
-{% endfor -%}
-{%- endif -%}
-
-{%- if methods.options -%}
-{%- for m in methods.options -%}
-
-{%- if m is string -%}
-{%- set method_name = m | snake -%}
-{%- set ChildName = m %}
-{%- else -%}
-{%- set method_name = m.0 -%}
-{%- set ChildName = m.1 %}
-{%- endif %}
-    pub fn {{ method_name }}(&self) -> Option<{{ ChildName }}> {
-        super::child_opt(self)
-    }
-{% endfor -%}
-{%- endif -%}
-}
-{% endfor %}
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index f2c20573e8..26efeeba99 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -2,61 +2,61 @@
 // See `cargo gen-syntax` (defined in crates/tools/src/main.rs)
 Grammar(
     single_byte_tokens: [
-        [";", "SEMI"],
-        [",", "COMMA"],
-        ["(", "L_PAREN"],
-        [")", "R_PAREN"],
-        ["{", "L_CURLY"],
-        ["}", "R_CURLY"],
-        ["[", "L_BRACK"],
-        ["]", "R_BRACK"],
-        ["<", "L_ANGLE"],
-        [">", "R_ANGLE"],
-        ["@", "AT"],
-        ["#", "POUND"],
-        ["~", "TILDE"],
-        ["?", "QUESTION"],
-        ["$", "DOLLAR"],
-        ["&", "AMP"],
-        ["|", "PIPE"],
-        ["+", "PLUS"],
-        ["*", "STAR"],
-        ["/", "SLASH"],
-        ["^", "CARET"],
-        ["%", "PERCENT"],
-        ["_", "UNDERSCORE"],
+        (";", "SEMI"),
+        (",", "COMMA"),
+        ("(", "L_PAREN"),
+        (")", "R_PAREN"),
+        ("{", "L_CURLY"),
+        ("}", "R_CURLY"),
+        ("[", "L_BRACK"),
+        ("]", "R_BRACK"),
+        ("<", "L_ANGLE"),
+        (">", "R_ANGLE"),
+        ("@", "AT"),
+        ("#", "POUND"),
+        ("~", "TILDE"),
+        ("?", "QUESTION"),
+        ("$", "DOLLAR"),
+        ("&", "AMP"),
+        ("|", "PIPE"),
+        ("+", "PLUS"),
+        ("*", "STAR"),
+        ("/", "SLASH"),
+        ("^", "CARET"),
+        ("%", "PERCENT"),
+        ("_", "UNDERSCORE"),
     ],
     // Tokens for which the longest match must be chosen (e.g. `..` is a DOTDOT, but `.` is a DOT)
     multi_byte_tokens: [
-        [".", "DOT"],
-        ["..", "DOTDOT"],
-        ["...", "DOTDOTDOT"],
-        ["..=", "DOTDOTEQ"],
-        [":", "COLON"],
-        ["::", "COLONCOLON"],
-        ["=", "EQ"],
-        ["==", "EQEQ"],
-        ["=>", "FAT_ARROW"],
-        ["!", "EXCL"],
-        ["!=", "NEQ"],
-        ["-", "MINUS"],
-        ["->", "THIN_ARROW"],
-        ["<=", "LTEQ"],
-        [">=", "GTEQ"],
-        ["+=", "PLUSEQ"],
-        ["-=", "MINUSEQ"],
-        ["|=", "PIPEEQ"],
-        ["&=", "AMPEQ"],
-        ["^=", "CARETEQ"],
-        ["/=", "SLASHEQ"],
-        ["*=", "STAREQ"],
-        ["%=", "PERCENTEQ"],
-        ["&&", "AMPAMP"],
-        ["||", "PIPEPIPE"],
-        ["<<", "SHL"],
-        [">>", "SHR"],
-        ["<<=", "SHLEQ"],
-        [">>=", "SHREQ"],
+        (".", "DOT"),
+        ("..", "DOTDOT"),
+        ("...", "DOTDOTDOT"),
+        ("..=", "DOTDOTEQ"),
+        (":", "COLON"),
+        ("::", "COLONCOLON"),
+        ("=", "EQ"),
+        ("==", "EQEQ"),
+        ("=>", "FAT_ARROW"),
+        ("!", "EXCL"),
+        ("!=", "NEQ"),
+        ("-", "MINUS"),
+        ("->", "THIN_ARROW"),
+        ("<=", "LTEQ"),
+        (">=", "GTEQ"),
+        ("+=", "PLUSEQ"),
+        ("-=", "MINUSEQ"),
+        ("|=", "PIPEEQ"),
+        ("&=", "AMPEQ"),
+        ("^=", "CARETEQ"),
+        ("/=", "SLASHEQ"),
+        ("*=", "STAREQ"),
+        ("%=", "PERCENTEQ"),
+        ("&&", "AMPAMP"),
+        ("||", "PIPEPIPE"),
+        ("<<", "SHL"),
+        (">>", "SHR"),
+        ("<<=", "SHLEQ"),
+        (">>=", "SHREQ"),
     ],
     keywords: [
         "async",
@@ -263,7 +263,7 @@ Grammar(
         "SourceFile": (
             traits: [ "ModuleItemOwner", "FnDefOwner" ],
             collections: [
-                ["modules", "Module"],
+                ("modules", "Module"),
             ]
         ),
         "FnDef": (
@@ -286,7 +286,7 @@ Grammar(
                 "DocCommentsOwner"
             ]
         ),
-        "NamedFieldDefList": (collections: [["fields", "NamedFieldDef"]]),
+        "NamedFieldDefList": (collections: [("fields", "NamedFieldDef")]),
         "NamedFieldDef": (
             traits: [
                 "VisibilityOwner",
@@ -296,7 +296,7 @@ Grammar(
                 "TypeAscriptionOwner"
             ]
         ),
-        "PosFieldDefList": (collections: [["fields", "PosFieldDef"]]),
+        "PosFieldDefList": (collections: [("fields", "PosFieldDef")]),
         "PosFieldDef": ( traits: ["VisibilityOwner", "AttrsOwner"], options: ["TypeRef"]),
         "EnumDef": ( traits: [
             "VisibilityOwner",
@@ -305,7 +305,7 @@ Grammar(
             "AttrsOwner",
             "DocCommentsOwner"
         ], options: [["variant_list", "EnumVariantList"]] ),
-        "EnumVariantList": ( collections: [["variants", "EnumVariant"]] ),
+        "EnumVariantList": ( collections: [("variants", "EnumVariant")] ),
         "EnumVariant": ( traits: ["NameOwner", "DocCommentsOwner", "AttrsOwner"], options: ["Expr"] ),
         "TraitDef": (
             traits: ["VisibilityOwner", "NameOwner", "AttrsOwner", "DocCommentsOwner", "TypeParamsOwner", "TypeBoundsOwner"],
@@ -316,7 +316,7 @@ Grammar(
             options: [ "ItemList" ]
         ),
         "ItemList": (
-            collections: [["impl_items", "ImplItem"]],
+            collections: [("impl_items", "ImplItem")],
             traits: [ "FnDefOwner", "ModuleItemOwner" ],
         ),
         "ConstDef": (
@@ -355,7 +355,7 @@ Grammar(
         "ImplBlock": (options: ["ItemList"], traits: ["TypeParamsOwner", "AttrsOwner"]),
 
         "ParenType": (options: ["TypeRef"]),
-        "TupleType": ( collections: [["fields", "TypeRef"]] ),
+        "TupleType": ( collections: [("fields", "TypeRef")] ),
         "NeverType": (),
         "PathType": (options: ["Path"]),
         "PointerType": (options: ["TypeRef"]),
@@ -405,10 +405,10 @@ Grammar(
         ),
 
         "TupleExpr": (
-            collections: [["exprs", "Expr"]]
+            collections: [("exprs", "Expr")]
         ),
         "ArrayExpr": (
-            collections: [["exprs", "Expr"]]
+            collections: [("exprs", "Expr")]
         ),
         "ParenExpr": (options: ["Expr"]),
         "PathExpr": (options: ["Path"]),
@@ -449,7 +449,7 @@ Grammar(
             options: [ "Expr", "MatchArmList" ],
         ),
         "MatchArmList": (
-            collections: [ ["arms", "MatchArm"] ],
+            collections: [ ("arms", "MatchArm") ],
             traits: [ "AttrsOwner" ]
         ),
         "MatchArm": (
@@ -457,13 +457,13 @@ Grammar(
                 [ "guard", "MatchGuard" ],
                 "Expr",
             ],
-            collections: [ [ "pats", "Pat" ] ],
+            collections: [ ("pats", "Pat") ],
             traits: [ "AttrsOwner" ]
         ),
         "MatchGuard": (options: ["Expr"]),
         "StructLit": (options: ["Path", "NamedFieldList"]),
         "NamedFieldList": (
-            collections: [ ["fields", "NamedField"] ],
+            collections: [ ("fields", "NamedField") ],
             options: [["spread", "Expr"]]
         ),
         "NamedField": (options: ["NameRef", "Expr"]),
@@ -532,8 +532,8 @@ Grammar(
         "StructPat": ( options: ["FieldPatList", "Path"] ),
         "FieldPatList": (
             collections: [
-                ["field_pats", "FieldPat"],
-                ["bind_pats", "BindPat"],
+                ("field_pats", "FieldPat"),
+                ("bind_pats", "BindPat"),
             ]
         ),
         "FieldPat": (
@@ -542,9 +542,9 @@ Grammar(
         ),
         "TupleStructPat": (
             options: ["Path"],
-            collections: [["args", "Pat"]],
+            collections: [("args", "Pat")],
         ),
-        "TuplePat": ( collections: [["args", "Pat"]] ),
+        "TuplePat": ( collections: [("args", "Pat")] ),
         "SlicePat": (),
         "RangePat": (),
         "LiteralPat": (options: ["Literal"]),
@@ -575,8 +575,8 @@ Grammar(
         "TokenTree": (),
         "TypeParamList": (
             collections: [
-                ["type_params", "TypeParam" ],
-                ["lifetime_params", "LifetimeParam" ],
+                ("type_params", "TypeParam" ),
+                ("lifetime_params", "LifetimeParam" ),
             ]
         ),
         "TypeParam": ( traits: ["NameOwner", "AttrsOwner", "TypeBoundsOwner", "DefaultTypeParamOwner"] ),
@@ -590,7 +590,7 @@ Grammar(
         ),
         "TypeBoundList": (
             collections: [
-                ["bounds", "TypeBound"],
+                ("bounds", "TypeBound"),
             ]
         ),
         "WherePred": (
@@ -603,7 +603,7 @@ Grammar(
         ),
         "WhereClause": (
             collections: [
-                ["predicates", "WherePred"],
+                ("predicates", "WherePred"),
             ],
         ),
         "ExprStmt": (
@@ -627,7 +627,7 @@ Grammar(
         "Block": (
             options: [ "Expr" ],
             collections: [
-                ["statements", "Stmt"],
+                ("statements", "Stmt"),
             ],
             traits: [
                 "AttrsOwner",
@@ -636,7 +636,7 @@ Grammar(
         "ParamList": (
             options: [ "SelfParam" ],
             collections: [
-                ["params", "Param"]
+                ("params", "Param"),
             ]
         ),
         "SelfParam": (
@@ -663,14 +663,14 @@ Grammar(
             traits: ["NameOwner"],
         ),
         "UseTreeList": (
-            collections: [["use_trees", "UseTree"]]
+            collections: [("use_trees", "UseTree")]
         ),
         "ExternCrateItem": (
             options: ["NameRef", "Alias"],
         ),
         "ArgList": (
             collections: [
-                ["args", "Expr"]
+                ("args", "Expr"),
             ]
         ),
         "Path": (
@@ -683,22 +683,22 @@ Grammar(
             options: [ "NameRef", "TypeArgList" ]
         ),
         "TypeArgList": (collections: [
-            ["type_args", "TypeArg"],
-            ["lifetime_args", "LifetimeArg"],
-            ["assoc_type_args", "AssocTypeArg"],
+            ("type_args", "TypeArg"),
+            ("lifetime_args", "LifetimeArg"),
+            ("assoc_type_args", "AssocTypeArg"),
         ]),
         "TypeArg": (options: ["TypeRef"]),
         "AssocTypeArg": (options: ["NameRef", "TypeRef"]),
         "LifetimeArg": (),
 
         "MacroItems": (
-            traits: [ "ModuleItemOwner", "FnDefOwner" ],            
+            traits: [ "ModuleItemOwner", "FnDefOwner" ],
         ),
 
         "MacroStmts" : (
             options: [ "Expr" ],
             collections: [
-                ["statements", "Stmt"],
+                ("statements", "Stmt"),
             ],
         )
     },
diff --git a/crates/ra_tools/Cargo.toml b/crates/ra_tools/Cargo.toml
index 9c54309929..4c9aa1cc3f 100644
--- a/crates/ra_tools/Cargo.toml
+++ b/crates/ra_tools/Cargo.toml
@@ -6,7 +6,11 @@ authors = ["rust-analyzer developers"]
 publish = false
 
 [dependencies]
-teraron = "0.1.0"
 walkdir = "2.1.3"
 itertools = "0.8.0"
 clap = "2.32.0"
+quote = "1.0.2"
+proc-macro2 = "1.0.1"
+ron = "0.5.1"
+heck = "0.3.0"
+serde = { version = "1.0.0", features = ["derive"] }
diff --git a/crates/ra_tools/src/boilerplate_gen.rs b/crates/ra_tools/src/boilerplate_gen.rs
new file mode 100644
index 0000000000..7ef51e82ad
--- /dev/null
+++ b/crates/ra_tools/src/boilerplate_gen.rs
@@ -0,0 +1,342 @@
+use std::{
+    collections::BTreeMap,
+    fs,
+    io::Write,
+    process::{Command, Stdio},
+};
+
+use heck::{ShoutySnakeCase, SnakeCase};
+use proc_macro2::{Punct, Spacing};
+use quote::{format_ident, quote};
+use ron;
+use serde::Deserialize;
+
+use crate::{project_root, update, Mode, Result, AST, GRAMMAR, SYNTAX_KINDS};
+
+pub fn generate_boilerplate(mode: Mode) -> Result<()> {
+    let grammar = project_root().join(GRAMMAR);
+    let grammar: Grammar = {
+        let text = fs::read_to_string(grammar)?;
+        ron::de::from_str(&text)?
+    };
+
+    let syntax_kinds_file = project_root().join(SYNTAX_KINDS);
+    let syntax_kinds = generate_syntax_kinds(&grammar)?;
+    update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?;
+
+    let ast_file = project_root().join(AST);
+    let ast = generate_ast(&grammar)?;
+    update(ast_file.as_path(), &ast, mode)?;
+
+    Ok(())
+}
+
+fn generate_ast(grammar: &Grammar) -> Result<String> {
+    let nodes = grammar.ast.iter().map(|(name, ast_node)| {
+        let variants =
+            ast_node.variants.iter().map(|var| format_ident!("{}", var)).collect::<Vec<_>>();
+        let name = format_ident!("{}", name);
+
+        let kinds = if variants.is_empty() { vec![name.clone()] } else { variants.clone() }
+            .into_iter()
+            .map(|name| format_ident!("{}", name.to_string().to_shouty_snake_case()))
+            .collect::<Vec<_>>();
+
+        let variants = if variants.is_empty() {
+            None
+        } else {
+            let kind_enum = format_ident!("{}Kind", name);
+            Some(quote!(
+                pub enum #kind_enum {
+                    #(#variants(#variants),)*
+                }
+
+                #(
+                impl From<#variants> for #name {
+                    fn from(node: #variants) -> #name {
+                        #name { syntax: node.syntax }
+                    }
+                }
+                )*
+
+                impl #name {
+                    pub fn kind(&self) -> #kind_enum {
+                        let syntax = self.syntax.clone();
+                        match syntax.kind() {
+                            #(
+                            #kinds =>
+                                #kind_enum::#variants(#variants { syntax }),
+                            )*
+                            _ => unreachable!(),
+                        }
+                    }
+                }
+            ))
+        };
+
+        let traits = ast_node.traits.iter().map(|trait_name| {
+            let trait_name = format_ident!("{}", trait_name);
+            quote!(impl ast::#trait_name for #name {})
+        });
+
+        let collections = ast_node.collections.iter().map(|(name, kind)| {
+            let method_name = format_ident!("{}", name);
+            let kind = format_ident!("{}", kind);
+            quote! {
+                pub fn #method_name(&self) -> AstChildren<#kind> {
+                    AstChildren::new(&self.syntax)
+                }
+            }
+        });
+
+        let options = ast_node.options.iter().map(|attr| {
+            let method_name = match attr {
+                Attr::Type(t) => format_ident!("{}", t.to_snake_case()),
+                Attr::NameType(n, _) => format_ident!("{}", n),
+            };
+            let ty = match attr {
+                Attr::Type(t) | Attr::NameType(_, t) => format_ident!("{}", t),
+            };
+            quote! {
+                pub fn #method_name(&self) -> Option<#ty> {
+                    AstChildren::new(&self.syntax).next()
+                }
+            }
+        });
+
+        quote! {
+            #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+            pub struct #name {
+                pub(crate) syntax: SyntaxNode,
+            }
+
+            impl AstNode for #name {
+                fn can_cast(kind: SyntaxKind) -> bool {
+                    match kind {
+                        #(#kinds)|* => true,
+                        _ => false,
+                    }
+                }
+                fn cast(syntax: SyntaxNode) -> Option<Self> {
+                    if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
+                }
+                fn syntax(&self) -> &SyntaxNode { &self.syntax }
+            }
+
+            #variants
+
+            #(#traits)*
+
+            impl #name {
+                #(#collections)*
+                #(#options)*
+            }
+        }
+    });
+
+    let ast = quote! {
+        use crate::{
+            SyntaxNode, SyntaxKind::{self, *},
+            ast::{self, AstNode, AstChildren},
+        };
+
+        #(#nodes)*
+    };
+
+    let pretty = reformat(ast)?;
+    Ok(pretty)
+}
+
+fn generate_syntax_kinds(grammar: &Grammar) -> Result<String> {
+    let single_byte_tokens_values =
+        grammar.single_byte_tokens.iter().map(|(token, _name)| token.chars().next().unwrap());
+    let single_byte_tokens = grammar
+        .single_byte_tokens
+        .iter()
+        .map(|(_token, name)| format_ident!("{}", name))
+        .collect::<Vec<_>>();
+
+    let punctuation_values =
+        grammar.single_byte_tokens.iter().chain(grammar.multi_byte_tokens.iter()).map(
+            |(token, _name)| {
+                if "{}[]()".contains(token) {
+                    let c = token.chars().next().unwrap();
+                    quote! { #c }
+                } else {
+                    let cs = token.chars().map(|c| Punct::new(c, Spacing::Joint));
+                    quote! { #(#cs)* }
+                }
+            },
+        );
+    let punctuation = single_byte_tokens
+        .clone()
+        .into_iter()
+        .chain(grammar.multi_byte_tokens.iter().map(|(_token, name)| format_ident!("{}", name)))
+        .collect::<Vec<_>>();
+
+    let full_keywords_values = &grammar.keywords;
+    let full_keywords =
+        full_keywords_values.iter().map(|kw| format_ident!("{}_KW", kw.to_shouty_snake_case()));
+
+    let all_keywords_values =
+        grammar.keywords.iter().chain(grammar.contextual_keywords.iter()).collect::<Vec<_>>();
+    let all_keywords_idents = all_keywords_values.iter().map(|kw| format_ident!("{}", kw));
+    let all_keywords = all_keywords_values
+        .iter()
+        .map(|name| format_ident!("{}_KW", name.to_shouty_snake_case()))
+        .collect::<Vec<_>>();
+
+    let literals =
+        grammar.literals.iter().map(|name| format_ident!("{}", name)).collect::<Vec<_>>();
+
+    let tokens = grammar.tokens.iter().map(|name| format_ident!("{}", name)).collect::<Vec<_>>();
+
+    let nodes = grammar.nodes.iter().map(|name| format_ident!("{}", name)).collect::<Vec<_>>();
+
+    let ast = quote! {
+        #![allow(bad_style, missing_docs, unreachable_pub)]
+        use super::SyntaxInfo;
+
+        /// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`.
+        #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+        #[repr(u16)]
+        pub enum SyntaxKind {
+            // Technical SyntaxKinds: they appear temporally during parsing,
+            // but never end up in the final tree
+            #[doc(hidden)]
+            TOMBSTONE,
+            #[doc(hidden)]
+            EOF,
+            #(#punctuation,)*
+            #(#all_keywords,)*
+            #(#literals,)*
+            #(#tokens,)*
+            #(#nodes,)*
+
+            // Technical kind so that we can cast from u16 safely
+            #[doc(hidden)]
+            __LAST,
+        }
+        use self::SyntaxKind::*;
+
+        impl From<u16> for SyntaxKind {
+            fn from(d: u16) -> SyntaxKind {
+                assert!(d <= (__LAST as u16));
+                unsafe { std::mem::transmute::<u16, SyntaxKind>(d) }
+            }
+        }
+
+        impl From<SyntaxKind> for u16 {
+            fn from(k: SyntaxKind) -> u16 {
+                k as u16
+            }
+        }
+
+        impl SyntaxKind {
+            pub fn is_keyword(self) -> bool {
+                match self {
+                    #(#all_keywords)|* => true,
+                    _ => false,
+                }
+            }
+
+            pub fn is_punct(self) -> bool {
+                match self {
+                    #(#punctuation)|* => true,
+                    _ => false,
+                }
+            }
+
+            pub fn is_literal(self) -> bool {
+                match self {
+                    #(#literals)|* => true,
+                    _ => false,
+                }
+            }
+
+            pub(crate) fn info(self) -> &'static SyntaxInfo {
+                match self {
+                    #(#punctuation => &SyntaxInfo { name: stringify!(#punctuation) },)*
+                    #(#all_keywords => &SyntaxInfo { name: stringify!(#all_keywords) },)*
+                    #(#literals => &SyntaxInfo { name: stringify!(#literals) },)*
+                    #(#tokens => &SyntaxInfo { name: stringify!(#tokens) },)*
+                    #(#nodes => &SyntaxInfo { name: stringify!(#nodes) },)*
+                    TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
+                    EOF => &SyntaxInfo { name: "EOF" },
+                    __LAST => &SyntaxInfo { name: "__LAST" },
+                }
+            }
+
+            pub fn from_keyword(ident: &str) -> Option<SyntaxKind> {
+                let kw = match ident {
+                    #(#full_keywords_values => #full_keywords,)*
+                    _ => return None,
+                };
+                Some(kw)
+            }
+
+            pub fn from_char(c: char) -> Option<SyntaxKind> {
+                let tok = match c {
+                    #(#single_byte_tokens_values => #single_byte_tokens,)*
+                    _ => return None,
+                };
+                Some(tok)
+            }
+        }
+
+        #[macro_export]
+        macro_rules! T {
+            #((#punctuation_values) => { $crate::SyntaxKind::#punctuation };)*
+            #((#all_keywords_idents) => { $crate::SyntaxKind::#all_keywords };)*
+        }
+    };
+
+    reformat(ast)
+}
+
+fn reformat(text: impl std::fmt::Display) -> Result<String> {
+    let mut rustfmt = Command::new("rustfmt")
+        .arg("--config-path")
+        .arg(project_root().join("rustfmt.toml"))
+        .stdin(Stdio::piped())
+        .stdout(Stdio::piped())
+        .spawn()?;
+    write!(rustfmt.stdin.take().unwrap(), "{}", text)?;
+    let output = rustfmt.wait_with_output()?;
+    let stdout = String::from_utf8(output.stdout)?;
+    let preamble = "Generated file, do not edit by hand, see `crate/ra_tools/src/codegen`";
+    Ok(format!("// {}\n\n{}", preamble, stdout))
+}
+
+#[derive(Deserialize, Debug)]
+struct Grammar {
+    single_byte_tokens: Vec<(String, String)>,
+    multi_byte_tokens: Vec<(String, String)>,
+    keywords: Vec<String>,
+    contextual_keywords: Vec<String>,
+    literals: Vec<String>,
+    tokens: Vec<String>,
+    nodes: Vec<String>,
+    ast: BTreeMap<String, AstNode>,
+}
+
+#[derive(Deserialize, Debug)]
+struct AstNode {
+    #[serde(default)]
+    #[serde(rename = "enum")]
+    variants: Vec<String>,
+
+    #[serde(default)]
+    traits: Vec<String>,
+    #[serde(default)]
+    collections: Vec<(String, String)>,
+    #[serde(default)]
+    options: Vec<Attr>,
+}
+
+#[derive(Deserialize, Debug)]
+#[serde(untagged)]
+enum Attr {
+    Type(String),
+    NameType(String, String),
+}
diff --git a/crates/ra_tools/src/lib.rs b/crates/ra_tools/src/lib.rs
index bb7845f7d9..d47660369e 100644
--- a/crates/ra_tools/src/lib.rs
+++ b/crates/ra_tools/src/lib.rs
@@ -1,3 +1,5 @@
+mod boilerplate_gen;
+
 use std::{
     collections::HashMap,
     error::Error,
@@ -9,7 +11,7 @@ use std::{
 
 use itertools::Itertools;
 
-pub use teraron::{Mode, Overwrite, Verify};
+pub use self::boilerplate_gen::generate_boilerplate;
 
 pub type Result<T> = std::result::Result<T, Box<dyn Error>>;
 
@@ -18,10 +20,17 @@ const GRAMMAR_DIR: &str = "crates/ra_parser/src/grammar";
 const OK_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/ok";
 const ERR_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/err";
 
-pub const SYNTAX_KINDS: &str = "crates/ra_parser/src/syntax_kind/generated.rs.tera";
-pub const AST: &str = "crates/ra_syntax/src/ast/generated.rs.tera";
+pub const SYNTAX_KINDS: &str = "crates/ra_parser/src/syntax_kind/generated.rs";
+pub const AST: &str = "crates/ra_syntax/src/ast/generated.rs";
 const TOOLCHAIN: &str = "stable";
 
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+pub enum Mode {
+    Overwrite,
+    Verify,
+}
+pub use Mode::*;
+
 #[derive(Debug)]
 pub struct Test {
     pub name: String,
@@ -66,15 +75,6 @@ pub fn collect_tests(s: &str) -> Vec<(usize, Test)> {
     res
 }
 
-pub fn generate(mode: Mode) -> Result<()> {
-    let grammar = project_root().join(GRAMMAR);
-    let syntax_kinds = project_root().join(SYNTAX_KINDS);
-    let ast = project_root().join(AST);
-    teraron::generate(&syntax_kinds, &grammar, mode)?;
-    teraron::generate(&ast, &grammar, mode)?;
-    Ok(())
-}
-
 pub fn project_root() -> PathBuf {
     Path::new(&env!("CARGO_MANIFEST_DIR")).ancestors().nth(2).unwrap().to_path_buf()
 }
@@ -227,7 +227,7 @@ pub fn gen_tests(mode: Mode) -> Result<()> {
                     tests_dir.join(file_name)
                 }
             };
-            teraron::update(&path, &test.text, mode)?;
+            update(&path, &test.text, mode)?;
         }
         Ok(())
     }
@@ -311,3 +311,20 @@ fn existing_tests(dir: &Path, ok: bool) -> Result<HashMap<String, (PathBuf, Test
     }
     Ok(res)
 }
+
+/// A helper to update file on disk if it has changed.
+/// With verify = false,
+pub fn update(path: &Path, contents: &str, mode: Mode) -> Result<()> {
+    match fs::read_to_string(path) {
+        Ok(ref old_contents) if old_contents == contents => {
+            return Ok(());
+        }
+        _ => (),
+    }
+    if mode == Verify {
+        Err(format!("`{}` is not up-to-date", path.display()))?;
+    }
+    eprintln!("updating {}", path.display());
+    fs::write(path, contents)?;
+    Ok(())
+}
diff --git a/crates/ra_tools/src/main.rs b/crates/ra_tools/src/main.rs
index 54d96e4462..03cb9d5a73 100644
--- a/crates/ra_tools/src/main.rs
+++ b/crates/ra_tools/src/main.rs
@@ -1,8 +1,8 @@
 use clap::{App, Arg, SubCommand};
 use core::str;
 use ra_tools::{
-    gen_tests, generate, install_format_hook, run, run_clippy, run_fuzzer, run_rustfmt, Cmd,
-    Overwrite, Result,
+    gen_tests, generate_boilerplate, install_format_hook, run, run_clippy, run_fuzzer, run_rustfmt,
+    Cmd, Overwrite, Result,
 };
 use std::{env, path::PathBuf};
 
@@ -49,7 +49,7 @@ fn main() -> Result<()> {
             install(opts)?
         }
         ("gen-tests", _) => gen_tests(Overwrite)?,
-        ("gen-syntax", _) => generate(Overwrite)?,
+        ("gen-syntax", _) => generate_boilerplate(Overwrite)?,
         ("format", _) => run_rustfmt(Overwrite)?,
         ("format-hook", _) => install_format_hook()?,
         ("lint", _) => run_clippy()?,
diff --git a/editors/code/src/server.ts b/editors/code/src/server.ts
index 3273d87497..2b4c25c284 100644
--- a/editors/code/src/server.ts
+++ b/editors/code/src/server.ts
@@ -1,17 +1,9 @@
-import { homedir } from 'os';
 import * as lc from 'vscode-languageclient';
 
 import { window, workspace } from 'vscode';
 import { Config } from './config';
 import { Highlighter } from './highlighting';
 
-function expandPathResolving(path: string) {
-    if (path.startsWith('~/')) {
-        return path.replace('~', homedir());
-    }
-    return path;
-}
-
 export class Server {
     public static highlighter = new Highlighter();
     public static config = new Config();
@@ -28,7 +20,7 @@ export class Server {
         }
 
         const run: lc.Executable = {
-            command: expandPathResolving(this.config.raLspServerPath),
+            command: this.config.raLspServerPath,
             options: { cwd: folder }
         };
         const serverOptions: lc.ServerOptions = {


Test patch:
diff --git a/crates/ra_tools/tests/cli.rs b/crates/ra_tools/tests/cli.rs
index ae0eb337d2..c672e57889 100644
--- a/crates/ra_tools/tests/cli.rs
+++ b/crates/ra_tools/tests/cli.rs
@@ -1,10 +1,10 @@
 use walkdir::WalkDir;
 
-use ra_tools::{gen_tests, generate, project_root, run_rustfmt, Verify};
+use ra_tools::{gen_tests, generate_boilerplate, project_root, run_rustfmt, Verify};
 
 #[test]
 fn generated_grammar_is_fresh() {
-    if let Err(error) = generate(Verify) {
+    if let Err(error) = generate_boilerplate(Verify) {
         panic!("{}. Please update it by running `cargo gen-syntax`", error);
     }
 }