Merge pull request #19990 from Veykril/push-zkvrlrotmuzr

Generate annotations for macro defined items if their name is in the input
diff --git a/Cargo.lock b/Cargo.lock
index 01de430..c2b4e21 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -13,9 +13,9 @@
 
 [[package]]
 name = "adler2"
-version = "2.0.0"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
+checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
 
 [[package]]
 name = "allocator-api2"
@@ -25,9 +25,9 @@
 
 [[package]]
 name = "anyhow"
-version = "1.0.97"
+version = "1.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
+checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
 
 [[package]]
 name = "arbitrary"
@@ -60,7 +60,7 @@
  "cfg-if",
  "libc",
  "miniz_oxide",
- "object",
+ "object 0.36.7",
  "rustc-demangle",
  "windows-targets 0.52.6",
 ]
@@ -100,51 +100,68 @@
 
 [[package]]
 name = "bitflags"
-version = "2.9.0"
+version = "2.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
+checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
 
 [[package]]
 name = "borsh"
-version = "1.5.5"
+version = "1.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5430e3be710b68d984d1391c854eb431a9d548640711faa54eecb1df93db91cc"
+checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce"
 dependencies = [
  "cfg_aliases",
 ]
 
 [[package]]
 name = "boxcar"
-version = "0.2.12"
+version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "66bb12751a83493ef4b8da1120451a262554e216a247f14b48cb5e8fe7ed8bdf"
+checksum = "26c4925bc979b677330a8c7fe7a8c94af2dbb4a2d37b4a20a80d884400f46baa"
 
 [[package]]
 name = "camino"
-version = "1.1.9"
+version = "1.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3"
+checksum = "0da45bc31171d8d6960122e222a67740df867c1dd53b4d51caa297084c185cab"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "cargo-platform"
-version = "0.1.9"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea"
+checksum = "84982c6c0ae343635a3a4ee6dedef965513735c8b183caa7289fa6e27399ebd4"
 dependencies = [
  "serde",
 ]
 
 [[package]]
-name = "cargo_metadata"
-version = "0.19.2"
+name = "cargo-util-schemas"
+version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba"
+checksum = "e63d2780ac94487eb9f1fea7b0d56300abc9eb488800854ca217f102f5caccca"
+dependencies = [
+ "semver",
+ "serde",
+ "serde-untagged",
+ "serde-value",
+ "thiserror 1.0.69",
+ "toml",
+ "unicode-xid",
+ "url",
+]
+
+[[package]]
+name = "cargo_metadata"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4f7835cfc6135093070e95eb2b53e5d9b5c403dc3a6be6040ee026270aa82502"
 dependencies = [
  "camino",
  "cargo-platform",
+ "cargo-util-schemas",
  "semver",
  "serde",
  "serde_json",
@@ -153,9 +170,9 @@
 
 [[package]]
 name = "cc"
-version = "1.2.16"
+version = "1.2.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
+checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac"
 dependencies = [
  "shlex",
 ]
@@ -178,9 +195,9 @@
 
 [[package]]
 name = "cfg-if"
-version = "1.0.0"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
 
 [[package]]
 name = "cfg_aliases"
@@ -190,9 +207,9 @@
 
 [[package]]
 name = "chalk-derive"
-version = "0.102.0"
+version = "0.103.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "feb14e3ff0ebac26d8e58b6ed1417afb60c4a0a44b6425546ee7eb9c75ebb336"
+checksum = "eb4899682de915ca7c0b025bdd0a3d34c75fe12184122fda6805a7baddaa293c"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -202,19 +219,19 @@
 
 [[package]]
 name = "chalk-ir"
-version = "0.102.0"
+version = "0.103.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72f0a61621a088af69fee8df39ec63cf5b6d0b9ab663a740cdeb376aabf2f244"
+checksum = "90a37d2ab99352b4caca135061e7b4ac67024b648c28ed0b787feec4bea4caed"
 dependencies = [
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "chalk-derive",
 ]
 
 [[package]]
 name = "chalk-recursive"
-version = "0.102.0"
+version = "0.103.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cbd3415cc540015533aa4a8ad007696d585dd9c5f81e7c099872f1dd4bf14894"
+checksum = "c855be60e646664bc37c2496d3dc81ca5ef60520930e5e0f0057a0575aff6c19"
 dependencies = [
  "chalk-derive",
  "chalk-ir",
@@ -225,9 +242,9 @@
 
 [[package]]
 name = "chalk-solve"
-version = "0.102.0"
+version = "0.103.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "747707b0c082b3ecf4b1ae28d0d8df708a46cddd22a386f9cc85a312a4de25ff"
+checksum = "477ac6cdfd2013e9f93b09b036c2b607a67b2e728f4777b8422d55a79e9e3a34"
 dependencies = [
  "chalk-derive",
  "chalk-ir",
@@ -374,7 +391,7 @@
  "libc",
  "option-ext",
  "redox_users",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
 ]
 
 [[package]]
@@ -432,6 +449,16 @@
 checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
 
 [[package]]
+name = "erased-serde"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"
+dependencies = [
+ "serde",
+ "typeid",
+]
+
+[[package]]
 name = "expect-test"
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -461,9 +488,9 @@
 
 [[package]]
 name = "flate2"
-version = "1.1.1"
+version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
+checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d"
 dependencies = [
  "crc32fast",
  "miniz_oxide",
@@ -471,9 +498,9 @@
 
 [[package]]
 name = "foldhash"
-version = "0.1.4"
+version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
+checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
 
 [[package]]
 name = "form_urlencoded"
@@ -501,9 +528,9 @@
 
 [[package]]
 name = "getrandom"
-version = "0.2.15"
+version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
 dependencies = [
  "cfg-if",
  "libc",
@@ -524,9 +551,9 @@
 
 [[package]]
 name = "hashbrown"
-version = "0.15.2"
+version = "0.15.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
+checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
 dependencies = [
  "allocator-api2",
  "equivalent",
@@ -539,7 +566,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1"
 dependencies = [
- "hashbrown 0.15.2",
+ "hashbrown 0.15.4",
 ]
 
 [[package]]
@@ -550,9 +577,9 @@
 
 [[package]]
 name = "hermit-abi"
-version = "0.3.9"
+version = "0.5.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
+checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
 
 [[package]]
 name = "hir"
@@ -588,7 +615,7 @@
 dependencies = [
  "arrayvec",
  "base-db",
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "cfg",
  "cov-mark",
  "drop_bomb",
@@ -655,7 +682,7 @@
 dependencies = [
  "arrayvec",
  "base-db",
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "chalk-derive",
  "chalk-ir",
  "chalk-recursive",
@@ -705,21 +732,22 @@
 
 [[package]]
 name = "icu_collections"
-version = "1.5.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
+checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47"
 dependencies = [
  "displaydoc",
+ "potential_utf",
  "yoke",
  "zerofrom",
  "zerovec",
 ]
 
 [[package]]
-name = "icu_locid"
-version = "1.5.0"
+name = "icu_locale_core"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
+checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a"
 dependencies = [
  "displaydoc",
  "litemap",
@@ -729,30 +757,10 @@
 ]
 
 [[package]]
-name = "icu_locid_transform"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
-dependencies = [
- "displaydoc",
- "icu_locid",
- "icu_locid_transform_data",
- "icu_provider",
- "tinystr",
- "zerovec",
-]
-
-[[package]]
-name = "icu_locid_transform_data"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
-
-[[package]]
 name = "icu_normalizer"
-version = "1.5.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
+checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979"
 dependencies = [
  "displaydoc",
  "icu_collections",
@@ -760,68 +768,55 @@
  "icu_properties",
  "icu_provider",
  "smallvec",
- "utf16_iter",
- "utf8_iter",
- "write16",
  "zerovec",
 ]
 
 [[package]]
 name = "icu_normalizer_data"
-version = "1.5.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
+checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3"
 
 [[package]]
 name = "icu_properties"
-version = "1.5.1"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
+checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b"
 dependencies = [
  "displaydoc",
  "icu_collections",
- "icu_locid_transform",
+ "icu_locale_core",
  "icu_properties_data",
  "icu_provider",
- "tinystr",
+ "potential_utf",
+ "zerotrie",
  "zerovec",
 ]
 
 [[package]]
 name = "icu_properties_data"
-version = "1.5.0"
+version = "2.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
+checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632"
 
 [[package]]
 name = "icu_provider"
-version = "1.5.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
+checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af"
 dependencies = [
  "displaydoc",
- "icu_locid",
- "icu_provider_macros",
+ "icu_locale_core",
  "stable_deref_trait",
  "tinystr",
  "writeable",
  "yoke",
  "zerofrom",
+ "zerotrie",
  "zerovec",
 ]
 
 [[package]]
-name = "icu_provider_macros"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
 name = "ide"
 version = "0.0.0"
 dependencies = [
@@ -898,7 +893,7 @@
 dependencies = [
  "arrayvec",
  "base-db",
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "cov-mark",
  "crossbeam-channel",
  "either",
@@ -976,9 +971,9 @@
 
 [[package]]
 name = "idna_adapter"
-version = "1.2.0"
+version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
+checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
 dependencies = [
  "icu_normalizer",
  "icu_properties",
@@ -991,7 +986,7 @@
 checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
 dependencies = [
  "equivalent",
- "hashbrown 0.15.2",
+ "hashbrown 0.15.4",
  "serde",
 ]
 
@@ -1001,7 +996,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3"
 dependencies = [
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "inotify-sys",
  "libc",
 ]
@@ -1057,9 +1052,9 @@
 
 [[package]]
 name = "kqueue"
-version = "1.0.8"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c"
+checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a"
 dependencies = [
  "kqueue-sys",
  "libc",
@@ -1099,19 +1094,19 @@
 
 [[package]]
 name = "libloading"
-version = "0.8.7"
+version = "0.8.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c"
+checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
 dependencies = [
  "cfg-if",
- "windows-targets 0.53.0",
+ "windows-targets 0.53.2",
 ]
 
 [[package]]
 name = "libmimalloc-sys"
-version = "0.1.40"
+version = "0.1.42"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07d0e07885d6a754b9c7993f2625187ad694ee985d60f23355ff0e7077261502"
+checksum = "ec9d6fac27761dabcd4ee73571cdb06b7022dc99089acbe5435691edffaac0f4"
 dependencies = [
  "cc",
  "libc",
@@ -1123,7 +1118,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
 dependencies = [
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "libc",
  "redox_syscall",
 ]
@@ -1149,9 +1144,9 @@
 
 [[package]]
 name = "litemap"
-version = "0.7.5"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
+checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956"
 
 [[package]]
 name = "load-cargo"
@@ -1174,9 +1169,9 @@
 
 [[package]]
 name = "lock_api"
-version = "0.4.12"
+version = "0.4.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
+checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765"
 dependencies = [
  "autocfg",
  "scopeguard",
@@ -1184,9 +1179,9 @@
 
 [[package]]
 name = "log"
-version = "0.4.26"
+version = "0.4.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
+checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
 
 [[package]]
 name = "lsp-server"
@@ -1249,9 +1244,9 @@
 
 [[package]]
 name = "memchr"
-version = "2.7.4"
+version = "2.7.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
 
 [[package]]
 name = "memmap2"
@@ -1273,32 +1268,32 @@
 
 [[package]]
 name = "mimalloc"
-version = "0.1.44"
+version = "0.1.46"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99585191385958383e13f6b822e6b6d8d9cf928e7d286ceb092da92b43c87bc1"
+checksum = "995942f432bbb4822a7e9c3faa87a695185b0d09273ba85f097b54f4e458f2af"
 dependencies = [
  "libmimalloc-sys",
 ]
 
 [[package]]
 name = "miniz_oxide"
-version = "0.8.5"
+version = "0.8.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
+checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
 dependencies = [
  "adler2",
 ]
 
 [[package]]
 name = "mio"
-version = "1.0.3"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
+checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
 dependencies = [
  "libc",
  "log",
  "wasi",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -1316,7 +1311,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
 dependencies = [
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "cfg-if",
  "cfg_aliases",
  "libc",
@@ -1334,7 +1329,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943"
 dependencies = [
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "filetime",
  "fsevent-sys",
  "inotify",
@@ -1369,10 +1364,19 @@
 checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
 
 [[package]]
-name = "num_cpus"
-version = "1.16.0"
+name = "num-traits"
+version = "0.2.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
 dependencies = [
  "hermit-abi",
  "libc",
@@ -1397,10 +1401,19 @@
 ]
 
 [[package]]
-name = "once_cell"
-version = "1.21.1"
+name = "object"
+version = "0.37.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
+checksum = "03fd943161069e1768b4b3d050890ba48730e590f57e56d4aa04e7e090e61b4a"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
 
 [[package]]
 name = "oorandom"
@@ -1415,10 +1428,19 @@
 checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
 
 [[package]]
-name = "parking_lot"
-version = "0.12.3"
+name = "ordered-float"
+version = "2.10.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
+checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.12.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
 dependencies = [
  "lock_api",
  "parking_lot_core",
@@ -1426,9 +1448,9 @@
 
 [[package]]
 name = "parking_lot_core"
-version = "0.9.10"
+version = "0.9.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
+checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5"
 dependencies = [
  "cfg-if",
  "libc",
@@ -1445,7 +1467,7 @@
  "edition",
  "expect-test",
  "ra-ap-rustc_lexer",
- "rustc-literal-escaper",
+ "rustc-literal-escaper 0.0.3",
  "stdx",
  "tracing",
 ]
@@ -1506,9 +1528,18 @@
 
 [[package]]
 name = "portable-atomic"
-version = "1.11.0"
+version = "1.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
+checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
+
+[[package]]
+name = "potential_utf"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585"
+dependencies = [
+ "zerovec",
+]
 
 [[package]]
 name = "powerfmt"
@@ -1542,7 +1573,7 @@
  "libc",
  "libloading",
  "memmap2",
- "object",
+ "object 0.37.1",
  "paths",
  "proc-macro-test",
  "ra-ap-rustc_lexer",
@@ -1569,9 +1600,9 @@
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.94"
+version = "1.0.95"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
+checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
 dependencies = [
  "unicode-ident",
 ]
@@ -1596,7 +1627,7 @@
  "libc",
  "perf-event",
  "tikv-jemalloc-ctl",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
 ]
 
 [[package]]
@@ -1650,7 +1681,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b"
 dependencies = [
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "memchr",
  "unicase",
 ]
@@ -1687,11 +1718,11 @@
 
 [[package]]
 name = "ra-ap-rustc_abi"
-version = "0.113.0"
+version = "0.116.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c33b8fa229789975647ca5426be432c7c327ebde89ab15889928185dbcee3230"
+checksum = "a967e3a9cd3e38b543f503978e0eccee461e3aea3f7b10e944959bff41dbe612"
 dependencies = [
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "ra-ap-rustc_hashes",
  "ra-ap-rustc_index",
  "tracing",
@@ -1699,18 +1730,18 @@
 
 [[package]]
 name = "ra-ap-rustc_hashes"
-version = "0.113.0"
+version = "0.116.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d68a3e389927002f552938a90b04787f6435f55b46fc5691360470d1cb2e99d"
+checksum = "1ea4c755ecbbffa5743c251344f484ebe571ec7bc5b36d80b2a8ae775d1a7a40"
 dependencies = [
  "rustc-stable-hash",
 ]
 
 [[package]]
 name = "ra-ap-rustc_index"
-version = "0.113.0"
+version = "0.116.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "32502273df2838d0ca13f1c67e2a48feef940e591f9771869f07e2db2acede53"
+checksum = "aca7ad7cf911538c619caa2162339fe98637e9e46f11bb0484ef96735df4d64a"
 dependencies = [
  "ra-ap-rustc_index_macros",
  "smallvec",
@@ -1718,9 +1749,9 @@
 
 [[package]]
 name = "ra-ap-rustc_index_macros"
-version = "0.113.0"
+version = "0.116.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a32f081864ae34c7ae6634edfa7a95ab9260ba85015e8b1d347580eda79d14f"
+checksum = "8767ba551c9355bc3031be072cc4bb0381106e5e7cd275e72b7a8c76051c4070"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1729,9 +1760,9 @@
 
 [[package]]
 name = "ra-ap-rustc_lexer"
-version = "0.113.0"
+version = "0.116.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed34c51974718c5bd90d876d1364d9725159fc8030c2382b9cb837034152ed68"
+checksum = "6101374afb267e6c27e4e2eb0b1352e9f3504c1a8f716f619cd39244e2ed92ab"
 dependencies = [
  "memchr",
  "unicode-properties",
@@ -1740,19 +1771,19 @@
 
 [[package]]
 name = "ra-ap-rustc_parse_format"
-version = "0.113.0"
+version = "0.116.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ff0440e5d27facbf4ff13ea651e48c2f6e360b3dbfc56251b41d60719b965fb8"
+checksum = "ecd88a19f00da4f43e6727d5013444cbc399804b5046dfa2bbcd28ebed3970ce"
 dependencies = [
  "ra-ap-rustc_lexer",
- "rustc-literal-escaper",
+ "rustc-literal-escaper 0.0.2",
 ]
 
 [[package]]
 name = "ra-ap-rustc_pattern_analysis"
-version = "0.113.0"
+version = "0.116.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6056efa57aba3aa0cc69a0bf1a8281624c23ad25b05748d11ebcd4668037bfc"
+checksum = "bb332dd32d7850a799862533b1c021e6062558861a4ad57817bf522499fbb892"
 dependencies = [
  "ra-ap-rustc_index",
  "rustc-hash 2.1.1",
@@ -1783,11 +1814,11 @@
 
 [[package]]
 name = "redox_syscall"
-version = "0.5.10"
+version = "0.5.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
+checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
 dependencies = [
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
 ]
 
 [[package]]
@@ -1874,16 +1905,16 @@
  "vfs",
  "vfs-notify",
  "walkdir",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
  "xflags",
  "xshell",
 ]
 
 [[package]]
 name = "rustc-demangle"
-version = "0.1.24"
+version = "0.1.25"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
+checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f"
 
 [[package]]
 name = "rustc-hash"
@@ -1904,6 +1935,12 @@
 checksum = "0041b6238913c41fe704213a4a9329e2f685a156d1781998128b4149c230ad04"
 
 [[package]]
+name = "rustc-literal-escaper"
+version = "0.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78744cd17f5d01c75b709e49807d1363e02a940ccee2e9e72435843fdb0d076e"
+
+[[package]]
 name = "rustc-stable-hash"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1911,11 +1948,11 @@
 
 [[package]]
 name = "rustc_apfloat"
-version = "0.2.2+llvm-462a31f5a5ab"
+version = "0.2.3+llvm-462a31f5a5ab"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "121e2195ff969977a4e2b5c9965ea867fce7e4cb5aee5b09dee698a7932d574f"
+checksum = "486c2179b4796f65bfe2ee33679acf0927ac83ecf583ad6c91c3b4570911b9ad"
 dependencies = [
- "bitflags 2.9.0",
+ "bitflags 2.9.1",
  "smallvec",
 ]
 
@@ -1934,7 +1971,7 @@
  "boxcar",
  "crossbeam-queue",
  "dashmap",
- "hashbrown 0.15.2",
+ "hashbrown 0.15.4",
  "hashlink",
  "indexmap",
  "parking_lot",
@@ -2016,6 +2053,27 @@
 ]
 
 [[package]]
+name = "serde-untagged"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "299d9c19d7d466db4ab10addd5703e4c615dec2a5a16dbbafe191045e87ee66e"
+dependencies = [
+ "erased-serde",
+ "serde",
+ "typeid",
+]
+
+[[package]]
+name = "serde-value"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
+dependencies = [
+ "ordered-float",
+ "serde",
+]
+
+[[package]]
 name = "serde_derive"
 version = "1.0.219"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2052,9 +2110,9 @@
 
 [[package]]
 name = "serde_spanned"
-version = "0.6.8"
+version = "0.6.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
+checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
 dependencies = [
  "serde",
 ]
@@ -2076,9 +2134,9 @@
 
 [[package]]
 name = "smallvec"
-version = "1.14.0"
+version = "1.15.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
 
 [[package]]
 name = "smol_str"
@@ -2122,14 +2180,14 @@
  "libc",
  "miow",
  "tracing",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
 ]
 
 [[package]]
 name = "syn"
-version = "2.0.100"
+version = "2.0.103"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
+checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2138,9 +2196,9 @@
 
 [[package]]
 name = "synstructure"
-version = "0.13.1"
+version = "0.13.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2158,7 +2216,7 @@
  "rayon",
  "rowan",
  "rustc-hash 2.1.1",
- "rustc-literal-escaper",
+ "rustc-literal-escaper 0.0.3",
  "rustc_apfloat",
  "smol_str",
  "stdx",
@@ -2183,9 +2241,9 @@
 
 [[package]]
 name = "tenthash"
-version = "1.0.0"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d092d622df8bb64e5de8dc86a3667702d5f1e0fe2f0604c6035540703c8cd1e"
+checksum = "e5c4bcc0a4fa333239f43662d15fbf995f384b2aeaf89c4ab4c83353d6cbb952"
 
 [[package]]
 name = "test-fixture"
@@ -2270,12 +2328,11 @@
 
 [[package]]
 name = "thread_local"
-version = "1.1.8"
+version = "1.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
+checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185"
 dependencies = [
  "cfg-if",
- "once_cell",
 ]
 
 [[package]]
@@ -2311,9 +2368,9 @@
 
 [[package]]
 name = "time"
-version = "0.3.40"
+version = "0.3.41"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618"
+checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
 dependencies = [
  "deranged",
  "itoa",
@@ -2334,9 +2391,9 @@
 
 [[package]]
 name = "time-macros"
-version = "0.2.21"
+version = "0.2.22"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04"
+checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
 dependencies = [
  "num-conv",
  "time-core",
@@ -2344,9 +2401,9 @@
 
 [[package]]
 name = "tinystr"
-version = "0.7.6"
+version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
+checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b"
 dependencies = [
  "displaydoc",
  "zerovec",
@@ -2354,9 +2411,9 @@
 
 [[package]]
 name = "toml"
-version = "0.8.20"
+version = "0.8.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148"
+checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
 dependencies = [
  "serde",
  "serde_spanned",
@@ -2366,27 +2423,34 @@
 
 [[package]]
 name = "toml_datetime"
-version = "0.6.8"
+version = "0.6.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
+checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
 dependencies = [
  "serde",
 ]
 
 [[package]]
 name = "toml_edit"
-version = "0.22.24"
+version = "0.22.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
+checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
 dependencies = [
  "indexmap",
  "serde",
  "serde_spanned",
  "toml_datetime",
+ "toml_write",
  "winnow",
 ]
 
 [[package]]
+name = "toml_write"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
+
+[[package]]
 name = "toolchain"
 version = "0.0.0"
 dependencies = [
@@ -2407,9 +2471,9 @@
 
 [[package]]
 name = "tracing-attributes"
-version = "0.1.28"
+version = "0.1.29"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
+checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -2418,9 +2482,9 @@
 
 [[package]]
 name = "tracing-core"
-version = "0.1.33"
+version = "0.1.34"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
+checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678"
 dependencies = [
  "once_cell",
  "valuable",
@@ -2486,6 +2550,12 @@
 checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
 
 [[package]]
+name = "typeid"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
+
+[[package]]
 name = "ungrammar"
 version = "1.16.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2528,12 +2598,6 @@
 ]
 
 [[package]]
-name = "utf16_iter"
-version = "1.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
-
-[[package]]
 name = "utf8_iter"
 version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2586,9 +2650,9 @@
 
 [[package]]
 name = "wasi"
-version = "0.11.0+wasi-snapshot-preview1"
+version = "0.11.1+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
 
 [[package]]
 name = "winapi-util"
@@ -2601,9 +2665,9 @@
 
 [[package]]
 name = "windows"
-version = "0.61.1"
+version = "0.61.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419"
+checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893"
 dependencies = [
  "windows-collections",
  "windows-core",
@@ -2623,9 +2687,9 @@
 
 [[package]]
 name = "windows-core"
-version = "0.61.0"
+version = "0.61.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980"
+checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
 dependencies = [
  "windows-implement",
  "windows-interface",
@@ -2636,12 +2700,13 @@
 
 [[package]]
 name = "windows-future"
-version = "0.2.0"
+version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32"
+checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e"
 dependencies = [
  "windows-core",
  "windows-link",
+ "windows-threading",
 ]
 
 [[package]]
@@ -2668,9 +2733,9 @@
 
 [[package]]
 name = "windows-link"
-version = "0.1.1"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
+checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
 
 [[package]]
 name = "windows-numerics"
@@ -2684,18 +2749,18 @@
 
 [[package]]
 name = "windows-result"
-version = "0.3.2"
+version = "0.3.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
+checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
 dependencies = [
  "windows-link",
 ]
 
 [[package]]
 name = "windows-strings"
-version = "0.4.0"
+version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97"
+checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
 dependencies = [
  "windows-link",
 ]
@@ -2728,6 +2793,15 @@
 ]
 
 [[package]]
+name = "windows-sys"
+version = "0.60.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
+dependencies = [
+ "windows-targets 0.53.2",
+]
+
+[[package]]
 name = "windows-targets"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2760,9 +2834,9 @@
 
 [[package]]
 name = "windows-targets"
-version = "0.53.0"
+version = "0.53.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b"
+checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
 dependencies = [
  "windows_aarch64_gnullvm 0.53.0",
  "windows_aarch64_msvc 0.53.0",
@@ -2775,6 +2849,15 @@
 ]
 
 [[package]]
+name = "windows-threading"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6"
+dependencies = [
+ "windows-link",
+]
+
+[[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2914,9 +2997,9 @@
 
 [[package]]
 name = "winnow"
-version = "0.7.3"
+version = "0.7.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1"
+checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
 dependencies = [
  "memchr",
 ]
@@ -2928,16 +3011,10 @@
 checksum = "23f6174b2566cc4a74f95e1367ec343e7fa80c93cc8087f5c4a3d6a1088b2118"
 
 [[package]]
-name = "write16"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
-
-[[package]]
 name = "writeable"
-version = "0.5.5"
+version = "0.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
+checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
 
 [[package]]
 name = "xflags"
@@ -2992,9 +3069,9 @@
 
 [[package]]
 name = "yoke"
-version = "0.7.5"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
+checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc"
 dependencies = [
  "serde",
  "stable_deref_trait",
@@ -3004,9 +3081,9 @@
 
 [[package]]
 name = "yoke-derive"
-version = "0.7.5"
+version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
+checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3036,10 +3113,21 @@
 ]
 
 [[package]]
-name = "zerovec"
-version = "0.10.4"
+name = "zerotrie"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
+checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+]
+
+[[package]]
+name = "zerovec"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428"
 dependencies = [
  "yoke",
  "zerofrom",
@@ -3048,9 +3136,9 @@
 
 [[package]]
 name = "zerovec-derive"
-version = "0.10.3"
+version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
+checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -3059,9 +3147,9 @@
 
 [[package]]
 name = "zip"
-version = "3.0.0"
+version = "4.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "12598812502ed0105f607f941c386f43d441e00148fce9dec3ca5ffb0bde9308"
+checksum = "153a6fff49d264c4babdcfa6b4d534747f520e56e8f0f384f3b808c4b64cc1fd"
 dependencies = [
  "arbitrary",
  "crc32fast",
diff --git a/Cargo.toml b/Cargo.toml
index 975fe27..c5f061c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -87,11 +87,11 @@
 vfs = { path = "./crates/vfs", version = "0.0.0" }
 edition = { path = "./crates/edition", version = "0.0.0" }
 
-ra-ap-rustc_lexer = { version = "0.113", default-features = false }
-ra-ap-rustc_parse_format = { version = "0.113", default-features = false }
-ra-ap-rustc_index = { version = "0.113", default-features = false }
-ra-ap-rustc_abi = { version = "0.113", default-features = false }
-ra-ap-rustc_pattern_analysis = { version = "0.113", default-features = false }
+ra-ap-rustc_lexer = { version = "0.116", default-features = false }
+ra-ap-rustc_parse_format = { version = "0.116", default-features = false }
+ra-ap-rustc_index = { version = "0.116", default-features = false }
+ra-ap-rustc_abi = { version = "0.116", default-features = false }
+ra-ap-rustc_pattern_analysis = { version = "0.116", default-features = false }
 
 # local crates that aren't published to crates.io. These should not have versions.
 
@@ -101,35 +101,35 @@
 lsp-server = { version = "0.7.8" }
 
 # non-local crates
-anyhow = "1.0.97"
+anyhow = "1.0.98"
 arrayvec = "0.7.6"
-bitflags = "2.9.0"
-cargo_metadata = "0.19.2"
-camino = "1.1.9"
-chalk-solve = { version = "0.102.0", default-features = false }
-chalk-ir = "0.102.0"
-chalk-recursive = { version = "0.102.0", default-features = false }
-chalk-derive = "0.102.0"
+bitflags = "2.9.1"
+cargo_metadata = "0.20.0"
+camino = "1.1.10"
+chalk-solve = { version = "0.103.0", default-features = false }
+chalk-ir = "0.103.0"
+chalk-recursive = { version = "0.103.0", default-features = false }
+chalk-derive = "0.103.0"
 crossbeam-channel = "0.5.15"
 dissimilar = "1.0.10"
 dot = "0.1.4"
 either = "1.15.0"
 expect-test = "1.5.1"
-indexmap = { version = "2.8.0", features = ["serde"] }
+indexmap = { version = "2.9.0", features = ["serde"] }
 itertools = "0.14.0"
-libc = "0.2.171"
-libloading = "0.8.6"
+libc = "0.2.172"
+libloading = "0.8.8"
 memmap2 = "0.9.5"
 nohash-hasher = "0.2.0"
 oorandom = "11.1.5"
-object = { version = "0.36.7", default-features = false, features = [
+object = { version = "0.37.1", default-features = false, features = [
   "std",
   "read_core",
   "elf",
   "macho",
   "pe",
 ] }
-process-wrap = { version = "8.2.0", features = ["std"] }
+process-wrap = { version = "8.2.1", features = ["std"] }
 pulldown-cmark-to-cmark = "10.0.4"
 pulldown-cmark = { version = "0.9.6", default-features = false }
 rayon = "1.10.0"
@@ -141,8 +141,8 @@
 serde_derive = { version = "1.0.219" }
 serde_json = "1.0.140"
 rustc-hash = "2.1.1"
-rustc-literal-escaper = "0.0.2"
-smallvec = { version = "1.14.0", features = [
+rustc-literal-escaper = "0.0.3"
+smallvec = { version = "1.15.1", features = [
   "const_new",
   "union",
   "const_generics",
@@ -166,7 +166,7 @@
 # We need to freeze the version of the crate, as the raw-api feature is considered unstable
 dashmap = { version = "=6.1.0", features = ["raw-api", "inline"] }
 # We need to freeze the version of the crate, as it needs to match with dashmap
-hashbrown = { version = "0.14.0", features = [
+hashbrown = { version = "0.14.*", features = [
   "inline-more",
 ], default-features = false }
 
diff --git a/crates/hir-def/Cargo.toml b/crates/hir-def/Cargo.toml
index c1c89e8..c6922ec 100644
--- a/crates/hir-def/Cargo.toml
+++ b/crates/hir-def/Cargo.toml
@@ -25,7 +25,7 @@
 tracing.workspace = true
 smallvec.workspace = true
 triomphe.workspace = true
-rustc_apfloat = "0.2.2"
+rustc_apfloat = "0.2.3"
 text-size.workspace = true
 salsa.workspace = true
 salsa-macros.workspace = true
diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs
index a732880..b509e69 100644
--- a/crates/hir-def/src/attr.rs
+++ b/crates/hir-def/src/attr.rs
@@ -26,7 +26,7 @@
     AdtId, AstIdLoc, AttrDefId, GenericParamId, HasModule, LocalFieldId, Lookup, MacroId,
     VariantId,
     db::DefDatabase,
-    item_tree::AttrOwner,
+    item_tree::block_item_tree_query,
     lang_item::LangItem,
     nameres::{ModuleOrigin, ModuleSource},
     src::{HasChildSource, HasSource},
@@ -523,26 +523,25 @@
                 let mod_data = &def_map[module.local_id];
 
                 let raw_attrs = match mod_data.origin {
-                    ModuleOrigin::File { definition, declaration_tree_id, .. } => {
+                    ModuleOrigin::File { definition, declaration_tree_id, declaration, .. } => {
                         let decl_attrs = declaration_tree_id
                             .item_tree(db)
-                            .raw_attrs(AttrOwner::ModItem(declaration_tree_id.value.into()))
+                            .raw_attrs(declaration.upcast())
                             .clone();
                         let tree = db.file_item_tree(definition.into());
-                        let def_attrs = tree.raw_attrs(AttrOwner::TopLevel).clone();
+                        let def_attrs = tree.top_level_raw_attrs().clone();
                         decl_attrs.merge(def_attrs)
                     }
                     ModuleOrigin::CrateRoot { definition } => {
                         let tree = db.file_item_tree(definition.into());
-                        tree.raw_attrs(AttrOwner::TopLevel).clone()
+                        tree.top_level_raw_attrs().clone()
                     }
-                    ModuleOrigin::Inline { definition_tree_id, .. } => definition_tree_id
-                        .item_tree(db)
-                        .raw_attrs(AttrOwner::ModItem(definition_tree_id.value.into()))
-                        .clone(),
+                    ModuleOrigin::Inline { definition_tree_id, definition } => {
+                        definition_tree_id.item_tree(db).raw_attrs(definition.upcast()).clone()
+                    }
                     ModuleOrigin::BlockExpr { id, .. } => {
-                        let tree = db.block_item_tree(id);
-                        tree.raw_attrs(AttrOwner::TopLevel).clone()
+                        let tree = block_item_tree_query(db, id);
+                        tree.top_level_raw_attrs().clone()
                     }
                 };
                 Attrs::expand_cfg_attr(db, module.krate, raw_attrs)
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index 362c0da..27fe62c 100644
--- a/crates/hir-def/src/db.rs
+++ b/crates/hir-def/src/db.rs
@@ -24,7 +24,7 @@
     },
     hir::generics::GenericParams,
     import_map::ImportMap,
-    item_tree::{AttrOwner, ItemTree},
+    item_tree::{ItemTree, file_item_tree_query},
     lang_item::{self, LangItem},
     nameres::{
         assoc::{ImplItems, TraitItems},
@@ -108,11 +108,9 @@
     fn expand_proc_attr_macros(&self) -> bool;
 
     /// Computes an [`ItemTree`] for the given file or macro expansion.
-    #[salsa::invoke(ItemTree::file_item_tree_query)]
-    fn file_item_tree(&self, file_id: HirFileId) -> Arc<ItemTree>;
-
-    #[salsa::invoke(ItemTree::block_item_tree_query)]
-    fn block_item_tree(&self, block_id: BlockId) -> Arc<ItemTree>;
+    #[salsa::invoke(file_item_tree_query)]
+    #[salsa::transparent]
+    fn file_item_tree(&self, file_id: HirFileId) -> &ItemTree;
 
     /// Turns a MacroId into a MacroDefId, describing the macro's definition post name resolution.
     #[salsa::invoke(macro_def)]
@@ -376,7 +374,7 @@
 fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: Crate) -> bool {
     let file = crate_id.data(db).root_file_id(db);
     let item_tree = db.file_item_tree(file.into());
-    let attrs = item_tree.raw_attrs(AttrOwner::TopLevel);
+    let attrs = item_tree.top_level_raw_attrs();
     for attr in &**attrs {
         match attr.path().as_ident() {
             Some(ident) if *ident == sym::no_std => return true,
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index 81c8f56..bf482d3 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -37,8 +37,8 @@
 
 use std::{
     fmt::{self, Debug},
-    hash::{Hash, Hasher},
-    ops::{Index, Range},
+    hash::Hash,
+    ops::Index,
     sync::OnceLock,
 };
 
@@ -51,12 +51,12 @@
     name::Name,
 };
 use intern::Interned;
-use la_arena::{Arena, Idx, RawIdx};
+use la_arena::{Idx, RawIdx};
 use rustc_hash::FxHashMap;
-use smallvec::SmallVec;
 use span::{AstIdNode, Edition, FileAstId, SyntaxContext};
 use stdx::never;
 use syntax::{SyntaxKind, ast, match_ast};
+use thin_vec::ThinVec;
 use triomphe::Arc;
 
 use crate::{BlockId, Lookup, attr::Attrs, db::DefDatabase};
@@ -64,13 +64,13 @@
 pub(crate) use crate::item_tree::lower::{lower_use_tree, visibility_from_ast};
 
 #[derive(Copy, Clone, Eq, PartialEq)]
-pub struct RawVisibilityId(u32);
+pub(crate) struct RawVisibilityId(u32);
 
 impl RawVisibilityId {
-    pub const PUB: Self = RawVisibilityId(u32::MAX);
-    pub const PRIV_IMPLICIT: Self = RawVisibilityId(u32::MAX - 1);
-    pub const PRIV_EXPLICIT: Self = RawVisibilityId(u32::MAX - 2);
-    pub const PUB_CRATE: Self = RawVisibilityId(u32::MAX - 3);
+    const PUB: Self = RawVisibilityId(u32::MAX);
+    const PRIV_IMPLICIT: Self = RawVisibilityId(u32::MAX - 1);
+    const PRIV_EXPLICIT: Self = RawVisibilityId(u32::MAX - 2);
+    const PUB_CRATE: Self = RawVisibilityId(u32::MAX - 3);
 }
 
 impl fmt::Debug for RawVisibilityId {
@@ -86,112 +86,115 @@
     }
 }
 
+#[salsa_macros::tracked(returns(ref))]
+pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> ItemTree {
+    let _p = tracing::info_span!("file_item_tree_query", ?file_id).entered();
+
+    let ctx = lower::Ctx::new(db, file_id);
+    let syntax = db.parse_or_expand(file_id);
+    let mut item_tree = match_ast! {
+        match syntax {
+            ast::SourceFile(file) => {
+                let top_attrs = RawAttrs::new(db, &file, ctx.span_map());
+                let mut item_tree = ctx.lower_module_items(&file);
+                item_tree.top_attrs = top_attrs;
+                item_tree
+            },
+            ast::MacroItems(items) => {
+                ctx.lower_module_items(&items)
+            },
+            ast::MacroStmts(stmts) => {
+                // The produced statements can include items, which should be added as top-level
+                // items.
+                ctx.lower_macro_stmts(stmts)
+            },
+            _ => {
+                if never!(syntax.kind() == SyntaxKind::ERROR, "{:?} from {:?} {}", file_id, syntax, syntax) {
+                    return Default::default();
+                }
+                panic!("cannot create item tree for file {file_id:?} from {syntax:?} {syntax}");
+            },
+        }
+    };
+
+    item_tree.shrink_to_fit();
+    item_tree
+}
+
+#[salsa_macros::tracked(returns(ref))]
+pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
+    let _p = tracing::info_span!("block_item_tree_query", ?block).entered();
+    // Blocks have a tendency to be empty due to macro calls that do not expand to items,
+    // so deduplicate this case via `Arc` to reduce the size of the query storage here.
+    static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
+
+    let loc = block.lookup(db);
+    let block = loc.ast_id.to_node(db);
+
+    let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
+    let mut item_tree = ctx.lower_block(&block);
+    if item_tree.small_data.is_empty()
+        && item_tree.big_data.is_empty()
+        && item_tree.top_level.is_empty()
+        && item_tree.attrs.is_empty()
+        && item_tree.top_attrs.is_empty()
+    {
+        EMPTY
+            .get_or_init(|| {
+                Arc::new(ItemTree {
+                    top_level: Box::new([]),
+                    attrs: FxHashMap::default(),
+                    small_data: FxHashMap::default(),
+                    big_data: FxHashMap::default(),
+                    top_attrs: RawAttrs::EMPTY,
+                    vis: ItemVisibilities { arena: ThinVec::new() },
+                })
+            })
+            .clone()
+    } else {
+        item_tree.shrink_to_fit();
+        Arc::new(item_tree)
+    }
+}
 /// The item tree of a source file.
 #[derive(Debug, Default, Eq, PartialEq)]
 pub struct ItemTree {
-    top_level: SmallVec<[ModItem; 1]>,
-    attrs: FxHashMap<AttrOwner, RawAttrs>,
-
-    data: Option<Box<ItemTreeData>>,
+    top_level: Box<[ModItemId]>,
+    top_attrs: RawAttrs,
+    attrs: FxHashMap<FileAstId<ast::Item>, RawAttrs>,
+    vis: ItemVisibilities,
+    // FIXME: They values store the key, turn this into a FxHashSet<ModItem> instead?
+    big_data: FxHashMap<FileAstId<ast::Item>, BigModItem>,
+    small_data: FxHashMap<FileAstId<ast::Item>, SmallModItem>,
 }
 
 impl ItemTree {
-    pub(crate) fn file_item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> {
-        let _p = tracing::info_span!("file_item_tree_query", ?file_id).entered();
-        static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
-
-        let ctx = lower::Ctx::new(db, file_id);
-        let syntax = db.parse_or_expand(file_id);
-        let mut top_attrs = None;
-        let mut item_tree = match_ast! {
-            match syntax {
-                ast::SourceFile(file) => {
-                    top_attrs = Some(RawAttrs::new(db, &file, ctx.span_map()));
-                    ctx.lower_module_items(&file)
-                },
-                ast::MacroItems(items) => {
-                    ctx.lower_module_items(&items)
-                },
-                ast::MacroStmts(stmts) => {
-                    // The produced statements can include items, which should be added as top-level
-                    // items.
-                    ctx.lower_macro_stmts(stmts)
-                },
-                _ => {
-                    if never!(syntax.kind() == SyntaxKind::ERROR, "{:?} from {:?} {}", file_id, syntax, syntax) {
-                        return Default::default();
-                    }
-                    panic!("cannot create item tree for file {file_id:?} from {syntax:?} {syntax}");
-                },
-            }
-        };
-
-        if let Some(attrs) = top_attrs {
-            item_tree.attrs.insert(AttrOwner::TopLevel, attrs);
-        }
-        if item_tree.data.is_none() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty()
-        {
-            EMPTY
-                .get_or_init(|| {
-                    Arc::new(ItemTree {
-                        top_level: SmallVec::new_const(),
-                        attrs: FxHashMap::default(),
-                        data: None,
-                    })
-                })
-                .clone()
-        } else {
-            item_tree.shrink_to_fit();
-            Arc::new(item_tree)
-        }
-    }
-
-    pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc<ItemTree> {
-        let _p = tracing::info_span!("block_item_tree_query", ?block).entered();
-        static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
-
-        let loc = block.lookup(db);
-        let block = loc.ast_id.to_node(db);
-
-        let ctx = lower::Ctx::new(db, loc.ast_id.file_id);
-        let mut item_tree = ctx.lower_block(&block);
-        if item_tree.data.is_none() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty()
-        {
-            EMPTY
-                .get_or_init(|| {
-                    Arc::new(ItemTree {
-                        top_level: SmallVec::new_const(),
-                        attrs: FxHashMap::default(),
-                        data: None,
-                    })
-                })
-                .clone()
-        } else {
-            item_tree.shrink_to_fit();
-            Arc::new(item_tree)
-        }
-    }
-
     /// Returns an iterator over all items located at the top level of the `HirFileId` this
     /// `ItemTree` was created from.
-    pub fn top_level_items(&self) -> &[ModItem] {
+    pub(crate) fn top_level_items(&self) -> &[ModItemId] {
         &self.top_level
     }
 
     /// Returns the inner attributes of the source file.
-    pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: Crate) -> Attrs {
-        Attrs::expand_cfg_attr(
-            db,
-            krate,
-            self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone(),
-        )
+    pub(crate) fn top_level_raw_attrs(&self) -> &RawAttrs {
+        &self.top_attrs
     }
 
-    pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs {
+    /// Returns the inner attributes of the source file.
+    pub(crate) fn top_level_attrs(&self, db: &dyn DefDatabase, krate: Crate) -> Attrs {
+        Attrs::expand_cfg_attr(db, krate, self.top_attrs.clone())
+    }
+
+    pub(crate) fn raw_attrs(&self, of: FileAstId<ast::Item>) -> &RawAttrs {
         self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY)
     }
 
-    pub(crate) fn attrs(&self, db: &dyn DefDatabase, krate: Crate, of: AttrOwner) -> Attrs {
+    pub(crate) fn attrs(
+        &self,
+        db: &dyn DefDatabase,
+        krate: Crate,
+        of: FileAstId<ast::Item>,
+    ) -> Attrs {
         Attrs::expand_cfg_attr(db, krate, self.raw_attrs(of).clone())
     }
 
@@ -199,105 +202,79 @@
     ///
     /// For more detail, see [`ItemTreeDataStats`].
     pub fn item_tree_stats(&self) -> ItemTreeDataStats {
-        match self.data {
-            Some(ref data) => ItemTreeDataStats {
-                traits: data.traits.len(),
-                impls: data.impls.len(),
-                mods: data.mods.len(),
-                macro_calls: data.macro_calls.len(),
-                macro_rules: data.macro_rules.len(),
-            },
-            None => ItemTreeDataStats::default(),
+        let mut traits = 0;
+        let mut impls = 0;
+        let mut mods = 0;
+        let mut macro_calls = 0;
+        let mut macro_rules = 0;
+        for item in self.small_data.values() {
+            match item {
+                SmallModItem::Trait(_) => traits += 1,
+                SmallModItem::Impl(_) => impls += 1,
+                SmallModItem::MacroRules(_) => macro_rules += 1,
+                SmallModItem::MacroCall(_) => macro_calls += 1,
+                _ => {}
+            }
         }
+        for item in self.big_data.values() {
+            match item {
+                BigModItem::Mod(_) => mods += 1,
+                _ => {}
+            }
+        }
+        ItemTreeDataStats { traits, impls, mods, macro_calls, macro_rules }
     }
 
     pub fn pretty_print(&self, db: &dyn DefDatabase, edition: Edition) -> String {
         pretty::print_item_tree(db, self, edition)
     }
 
-    fn data(&self) -> &ItemTreeData {
-        self.data.as_ref().expect("attempted to access data of empty ItemTree")
-    }
-
-    fn data_mut(&mut self) -> &mut ItemTreeData {
-        self.data.get_or_insert_with(Box::default)
-    }
-
     fn shrink_to_fit(&mut self) {
-        let ItemTree { top_level, attrs, data } = self;
-        top_level.shrink_to_fit();
+        let ItemTree { top_level: _, attrs, big_data, small_data, vis: _, top_attrs: _ } = self;
         attrs.shrink_to_fit();
-        if let Some(data) = data {
-            let ItemTreeData {
-                uses,
-                extern_crates,
-                extern_blocks,
-                functions,
-                structs,
-                unions,
-                enums,
-                consts,
-                statics,
-                traits,
-                trait_aliases,
-                impls,
-                type_aliases,
-                mods,
-                macro_calls,
-                macro_rules,
-                macro_defs,
-                vis: _,
-            } = &mut **data;
-
-            uses.shrink_to_fit();
-            extern_crates.shrink_to_fit();
-            extern_blocks.shrink_to_fit();
-            functions.shrink_to_fit();
-            structs.shrink_to_fit();
-            unions.shrink_to_fit();
-            enums.shrink_to_fit();
-            consts.shrink_to_fit();
-            statics.shrink_to_fit();
-            traits.shrink_to_fit();
-            trait_aliases.shrink_to_fit();
-            impls.shrink_to_fit();
-            type_aliases.shrink_to_fit();
-            mods.shrink_to_fit();
-            macro_calls.shrink_to_fit();
-            macro_rules.shrink_to_fit();
-            macro_defs.shrink_to_fit();
-        }
+        big_data.shrink_to_fit();
+        small_data.shrink_to_fit();
     }
 }
 
 #[derive(Default, Debug, Eq, PartialEq)]
 struct ItemVisibilities {
-    arena: Box<[RawVisibility]>,
+    arena: ThinVec<RawVisibility>,
 }
 
-#[derive(Default, Debug, Eq, PartialEq)]
-struct ItemTreeData {
-    uses: Arena<Use>,
-    extern_crates: Arena<ExternCrate>,
-    extern_blocks: Arena<ExternBlock>,
-    functions: Arena<Function>,
-    structs: Arena<Struct>,
-    unions: Arena<Union>,
-    enums: Arena<Enum>,
-    consts: Arena<Const>,
-    statics: Arena<Static>,
-    traits: Arena<Trait>,
-    trait_aliases: Arena<TraitAlias>,
-    impls: Arena<Impl>,
-    type_aliases: Arena<TypeAlias>,
-    mods: Arena<Mod>,
-    macro_calls: Arena<MacroCall>,
-    macro_rules: Arena<MacroRules>,
-    macro_defs: Arena<Macro2>,
-
-    vis: ItemVisibilities,
+#[derive(Debug, Clone, Eq, PartialEq)]
+enum SmallModItem {
+    Const(Const),
+    Enum(Enum),
+    ExternBlock(ExternBlock),
+    Function(Function),
+    Impl(Impl),
+    Macro2(Macro2),
+    MacroCall(MacroCall),
+    MacroRules(MacroRules),
+    Static(Static),
+    Struct(Struct),
+    Trait(Trait),
+    TraitAlias(TraitAlias),
+    TypeAlias(TypeAlias),
+    Union(Union),
 }
 
+#[derive(Debug, Clone, Eq, PartialEq)]
+enum BigModItem {
+    ExternCrate(ExternCrate),
+    Mod(Mod),
+    Use(Use),
+}
+
+// `ModItem` is stored a bunch in `ItemTree`'s so we pay the max for each item. It should stay as
+// small as possible which is why we split them in two, most common ones are 3 usize but some rarer
+// ones are 5.
+#[cfg(target_pointer_width = "64")]
+const _: [(); std::mem::size_of::<BigModItem>()] = [(); std::mem::size_of::<[usize; 5]>()];
+#[cfg(target_pointer_width = "64")]
+const _: [(); std::mem::size_of::<SmallModItem>()] = [(); std::mem::size_of::<[usize; 3]>()];
+
 #[derive(Default, Debug, Eq, PartialEq)]
 pub struct ItemTreeDataStats {
     pub traits: usize,
@@ -307,73 +284,13 @@
     pub macro_rules: usize,
 }
 
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
-pub enum AttrOwner {
-    /// Attributes on an item.
-    ModItem(ModItem),
-    /// Inner attributes of the source file.
-    TopLevel,
-}
-
-impl From<ModItem> for AttrOwner {
-    #[inline]
-    fn from(value: ModItem) -> Self {
-        AttrOwner::ModItem(value)
-    }
-}
-
 /// Trait implemented by all nodes in the item tree.
-pub trait ItemTreeNode: Clone {
+pub(crate) trait ItemTreeNode: Clone {
     type Source: AstIdNode;
-
-    fn ast_id(&self) -> FileAstId<Self::Source>;
-
-    /// Looks up an instance of `Self` in an item tree.
-    fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self;
 }
 
-pub struct FileItemTreeId<N>(Idx<N>);
-
-impl<N> FileItemTreeId<N> {
-    pub fn range_iter(range: Range<Self>) -> impl Iterator<Item = Self> + Clone {
-        (range.start.index().into_raw().into_u32()..range.end.index().into_raw().into_u32())
-            .map(RawIdx::from_u32)
-            .map(Idx::from_raw)
-            .map(Self)
-    }
-}
-
-impl<N> FileItemTreeId<N> {
-    pub fn index(&self) -> Idx<N> {
-        self.0
-    }
-}
-
-impl<N> Clone for FileItemTreeId<N> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-impl<N> Copy for FileItemTreeId<N> {}
-
-impl<N> PartialEq for FileItemTreeId<N> {
-    fn eq(&self, other: &FileItemTreeId<N>) -> bool {
-        self.0 == other.0
-    }
-}
-impl<N> Eq for FileItemTreeId<N> {}
-
-impl<N> Hash for FileItemTreeId<N> {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.0.hash(state)
-    }
-}
-
-impl<N> fmt::Debug for FileItemTreeId<N> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
+#[allow(type_alias_bounds)]
+pub(crate) type ItemTreeAstId<T: ItemTreeNode> = FileAstId<T::Source>;
 
 /// Identifies a particular [`ItemTree`].
 #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
@@ -383,14 +300,14 @@
 }
 
 impl TreeId {
-    pub fn new(file: HirFileId, block: Option<BlockId>) -> Self {
+    pub(crate) fn new(file: HirFileId, block: Option<BlockId>) -> Self {
         Self { file, block }
     }
 
-    pub fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> {
+    pub(crate) fn item_tree<'db>(&self, db: &'db dyn DefDatabase) -> &'db ItemTree {
         match self.block {
-            Some(block) => db.block_item_tree(block),
-            None => db.file_item_tree(self.file),
+            Some(block) => block_item_tree_query(db, block),
+            None => file_item_tree_query(db, self.file),
         }
     }
 
@@ -399,85 +316,32 @@
         self.file
     }
 
-    pub fn is_block(self) -> bool {
+    pub(crate) fn is_block(self) -> bool {
         self.block.is_some()
     }
 }
 
-#[derive(Debug)]
-pub struct ItemTreeId<N> {
-    tree: TreeId,
-    pub value: FileItemTreeId<N>,
-}
-
-impl<N> ItemTreeId<N> {
-    pub fn new(tree: TreeId, idx: FileItemTreeId<N>) -> Self {
-        Self { tree, value: idx }
-    }
-
-    pub fn file_id(self) -> HirFileId {
-        self.tree.file
-    }
-
-    pub fn tree_id(self) -> TreeId {
-        self.tree
-    }
-
-    pub fn item_tree(self, db: &dyn DefDatabase) -> Arc<ItemTree> {
-        self.tree.item_tree(db)
-    }
-
-    pub fn resolved<R>(self, db: &dyn DefDatabase, cb: impl FnOnce(&N) -> R) -> R
-    where
-        ItemTree: Index<FileItemTreeId<N>, Output = N>,
-    {
-        cb(&self.tree.item_tree(db)[self.value])
-    }
-}
-
-impl<N> Copy for ItemTreeId<N> {}
-impl<N> Clone for ItemTreeId<N> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-impl<N> PartialEq for ItemTreeId<N> {
-    fn eq(&self, other: &Self) -> bool {
-        self.tree == other.tree && self.value == other.value
-    }
-}
-
-impl<N> Eq for ItemTreeId<N> {}
-
-impl<N> Hash for ItemTreeId<N> {
-    fn hash<H: Hasher>(&self, state: &mut H) {
-        self.tree.hash(state);
-        self.value.hash(state);
-    }
-}
-
 macro_rules! mod_items {
-    ( $( $typ:ident in $fld:ident -> $ast:ty ),+ $(,)? ) => {
+    ($mod_item:ident -> $( $typ:ident in $fld:ident -> $ast:ty ),+ $(,)? ) => {
         #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
-        pub enum ModItem {
+        pub(crate) enum $mod_item {
             $(
-                $typ(FileItemTreeId<$typ>),
+                $typ(FileAstId<$ast>),
             )+
         }
 
-        impl ModItem {
-            pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
+        impl $mod_item {
+            pub(crate) fn ast_id(self) -> FileAstId<ast::Item> {
                 match self {
-                    $(ModItem::$typ(it) => tree[it.index()].ast_id().upcast()),+
+                    $($mod_item::$typ(it) => it.upcast()),+
                 }
             }
         }
 
         $(
-            impl From<FileItemTreeId<$typ>> for ModItem {
-                fn from(id: FileItemTreeId<$typ>) -> ModItem {
-                    ModItem::$typ(id)
+            impl From<FileAstId<$ast>> for $mod_item {
+                fn from(id: FileAstId<$ast>) -> $mod_item {
+                    ModItemId::$typ(id)
                 }
             }
         )+
@@ -485,21 +349,19 @@
         $(
             impl ItemTreeNode for $typ {
                 type Source = $ast;
-
-                fn ast_id(&self) -> FileAstId<Self::Source> {
-                    self.ast_id
-                }
-
-                fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self {
-                    &tree.data().$fld[index]
-                }
             }
 
-            impl Index<Idx<$typ>> for ItemTree {
+            impl Index<FileAstId<$ast>> for ItemTree {
                 type Output = $typ;
 
-                fn index(&self, index: Idx<$typ>) -> &Self::Output {
-                    &self.data().$fld[index]
+                #[allow(unused_imports)]
+                fn index(&self, index: FileAstId<$ast>) -> &Self::Output {
+                    use BigModItem::*;
+                    use SmallModItem::*;
+                    match &self.$fld[&index.upcast()] {
+                        $typ(item) => item,
+                        _ => panic!("expected item of type `{}` at index `{:?}`", stringify!($typ), index),
+                    }
                 }
             }
         )+
@@ -507,23 +369,24 @@
 }
 
 mod_items! {
-    Use in uses -> ast::Use,
-    ExternCrate in extern_crates -> ast::ExternCrate,
-    ExternBlock in extern_blocks -> ast::ExternBlock,
-    Function in functions -> ast::Fn,
-    Struct in structs -> ast::Struct,
-    Union in unions -> ast::Union,
-    Enum in enums -> ast::Enum,
-    Const in consts -> ast::Const,
-    Static in statics -> ast::Static,
-    Trait in traits -> ast::Trait,
-    TraitAlias in trait_aliases -> ast::TraitAlias,
-    Impl in impls -> ast::Impl,
-    TypeAlias in type_aliases -> ast::TypeAlias,
-    Mod in mods -> ast::Module,
-    MacroCall in macro_calls -> ast::MacroCall,
-    MacroRules in macro_rules -> ast::MacroRules,
-    Macro2 in macro_defs -> ast::MacroDef,
+ModItemId ->
+    Const in small_data -> ast::Const,
+    Enum in small_data -> ast::Enum,
+    ExternBlock in small_data -> ast::ExternBlock,
+    ExternCrate in big_data -> ast::ExternCrate,
+    Function in small_data -> ast::Fn,
+    Impl in small_data -> ast::Impl,
+    Macro2 in small_data -> ast::MacroDef,
+    MacroCall in small_data -> ast::MacroCall,
+    MacroRules in small_data -> ast::MacroRules,
+    Mod in big_data -> ast::Module,
+    Static in small_data -> ast::Static,
+    Struct in small_data -> ast::Struct,
+    Trait in small_data -> ast::Trait,
+    TraitAlias in small_data -> ast::TraitAlias,
+    TypeAlias in small_data -> ast::TypeAlias,
+    Union in small_data -> ast::Union,
+    Use in big_data -> ast::Use,
 }
 
 impl Index<RawVisibilityId> for ItemTree {
@@ -554,31 +417,24 @@
                     VisibilityExplicitness::Explicit,
                 )
             }),
-            _ => &self.data().vis.arena[index.0 as usize],
+            _ => &self.vis.arena[index.0 as usize],
         }
     }
 }
 
-impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
-    type Output = N;
-    fn index(&self, id: FileItemTreeId<N>) -> &N {
-        N::lookup(self, id.index())
-    }
-}
-
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Use {
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::Use>,
-    pub use_tree: UseTree,
+    pub(crate) visibility: RawVisibilityId,
+    pub(crate) use_tree: UseTree,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct UseTree {
-    pub index: Idx<ast::UseTree>,
     kind: UseTreeKind,
 }
 
+// FIXME: Would be nice to encode `None` into this
+// We could just use a `Name` where `_` well means `_` ..
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ImportAlias {
     /// Unnamed alias, as in `use Foo as _;`
@@ -632,43 +488,37 @@
 pub struct ExternCrate {
     pub name: Name,
     pub alias: Option<ImportAlias>,
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::ExternCrate>,
+    pub(crate) visibility: RawVisibilityId,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct ExternBlock {
-    pub ast_id: FileAstId<ast::ExternBlock>,
-    pub children: Box<[ModItem]>,
+    pub(crate) children: Box<[ModItemId]>,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Function {
     pub name: Name,
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::Fn>,
+    pub(crate) visibility: RawVisibilityId,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Struct {
     pub name: Name,
-    pub visibility: RawVisibilityId,
+    pub(crate) visibility: RawVisibilityId,
     pub shape: FieldsShape,
-    pub ast_id: FileAstId<ast::Struct>,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Union {
     pub name: Name,
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::Union>,
+    pub(crate) visibility: RawVisibilityId,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Enum {
     pub name: Name,
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::Enum>,
+    pub(crate) visibility: RawVisibilityId,
 }
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -706,55 +556,47 @@
 pub struct Const {
     /// `None` for `const _: () = ();`
     pub name: Option<Name>,
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::Const>,
+    pub(crate) visibility: RawVisibilityId,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Static {
     pub name: Name,
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::Static>,
+    pub(crate) visibility: RawVisibilityId,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Trait {
     pub name: Name,
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::Trait>,
+    pub(crate) visibility: RawVisibilityId,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct TraitAlias {
     pub name: Name,
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::TraitAlias>,
+    pub(crate) visibility: RawVisibilityId,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
-pub struct Impl {
-    pub ast_id: FileAstId<ast::Impl>,
-}
+pub struct Impl {}
 
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct TypeAlias {
     pub name: Name,
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::TypeAlias>,
+    pub(crate) visibility: RawVisibilityId,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Mod {
     pub name: Name,
-    pub visibility: RawVisibilityId,
-    pub kind: ModKind,
-    pub ast_id: FileAstId<ast::Module>,
+    pub(crate) visibility: RawVisibilityId,
+    pub(crate) kind: ModKind,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq)]
-pub enum ModKind {
+pub(crate) enum ModKind {
     /// `mod m { ... }`
-    Inline { items: Box<[ModItem]> },
+    Inline { items: Box<[ModItemId]> },
     /// `mod m;`
     Outline,
 }
@@ -763,7 +605,6 @@
 pub struct MacroCall {
     /// Path to the called macro.
     pub path: Interned<ModPath>,
-    pub ast_id: FileAstId<ast::MacroCall>,
     pub expand_to: ExpandTo,
     pub ctxt: SyntaxContext,
 }
@@ -772,15 +613,13 @@
 pub struct MacroRules {
     /// The name of the declared macro.
     pub name: Name,
-    pub ast_id: FileAstId<ast::MacroRules>,
 }
 
 /// "Macros 2.0" macro definition.
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Macro2 {
     pub name: Name,
-    pub visibility: RawVisibilityId,
-    pub ast_id: FileAstId<ast::MacroDef>,
+    pub(crate) visibility: RawVisibilityId,
 }
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -793,15 +632,17 @@
     TypeOnly,
 }
 
-impl UseTree {
+impl Use {
     /// Expands the `UseTree` into individually imported `ModPath`s.
     pub fn expand(
         &self,
         mut cb: impl FnMut(Idx<ast::UseTree>, ModPath, ImportKind, Option<ImportAlias>),
     ) {
-        self.expand_impl(None, &mut cb)
+        self.use_tree.expand_impl(None, &mut 0, &mut cb)
     }
+}
 
+impl UseTree {
     /// The [`UseTreeKind`] of this `UseTree`.
     pub fn kind(&self) -> &UseTreeKind {
         &self.kind
@@ -810,6 +651,7 @@
     fn expand_impl(
         &self,
         prefix: Option<ModPath>,
+        counting_index: &mut u32,
         cb: &mut impl FnMut(Idx<ast::UseTree>, ModPath, ImportKind, Option<ImportAlias>),
     ) {
         fn concat_mod_paths(
@@ -845,17 +687,27 @@
         match &self.kind {
             UseTreeKind::Single { path, alias } => {
                 if let Some((path, kind)) = concat_mod_paths(prefix, path) {
-                    cb(self.index, path, kind, alias.clone());
+                    cb(Idx::from_raw(RawIdx::from_u32(*counting_index)), path, kind, alias.clone());
                 }
             }
             UseTreeKind::Glob { path: Some(path) } => {
                 if let Some((path, _)) = concat_mod_paths(prefix, path) {
-                    cb(self.index, path, ImportKind::Glob, None);
+                    cb(
+                        Idx::from_raw(RawIdx::from_u32(*counting_index)),
+                        path,
+                        ImportKind::Glob,
+                        None,
+                    );
                 }
             }
             UseTreeKind::Glob { path: None } => {
                 if let Some(prefix) = prefix {
-                    cb(self.index, prefix, ImportKind::Glob, None);
+                    cb(
+                        Idx::from_raw(RawIdx::from_u32(*counting_index)),
+                        prefix,
+                        ImportKind::Glob,
+                        None,
+                    );
                 }
             }
             UseTreeKind::Prefixed { prefix: additional_prefix, list } => {
@@ -867,7 +719,8 @@
                     None => prefix,
                 };
                 for tree in &**list {
-                    tree.expand_impl(prefix.clone(), cb);
+                    *counting_index += 1;
+                    tree.expand_impl(prefix.clone(), counting_index, cb);
                 }
             }
         }
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index 26d209c..fe1b8e3 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -10,7 +10,7 @@
     span_map::{SpanMap, SpanMapRef},
 };
 use la_arena::Arena;
-use span::{AstIdMap, SyntaxContext};
+use span::{AstIdMap, FileAstId, SyntaxContext};
 use syntax::{
     AstNode,
     ast::{self, HasModuleItem, HasName},
@@ -20,24 +20,21 @@
 use crate::{
     db::DefDatabase,
     item_tree::{
-        AttrOwner, Const, Enum, ExternBlock, ExternCrate, FieldsShape, FileItemTreeId, Function,
-        Idx, Impl, ImportAlias, Interned, ItemTree, ItemTreeData, Macro2, MacroCall, MacroRules,
-        Mod, ModItem, ModKind, ModPath, RawAttrs, RawVisibility, RawVisibilityId, Static, Struct,
-        StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
+        BigModItem, Const, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl,
+        ImportAlias, Interned, ItemTree, ItemTreeAstId, Macro2, MacroCall, MacroRules, Mod,
+        ModItemId, ModKind, ModPath, RawAttrs, RawVisibility, RawVisibilityId, SmallModItem,
+        Static, Struct, StructKind, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
         VisibilityExplicitness,
     },
 };
 
-fn id<N>(index: Idx<N>) -> FileItemTreeId<N> {
-    FileItemTreeId(index)
-}
-
 pub(super) struct Ctx<'a> {
     db: &'a dyn DefDatabase,
     tree: ItemTree,
     source_ast_id_map: Arc<AstIdMap>,
     span_map: OnceCell<SpanMap>,
     file: HirFileId,
+    top_level: Vec<ModItemId>,
     visibilities: FxIndexSet<RawVisibility>,
 }
 
@@ -50,6 +47,7 @@
             file,
             span_map: OnceCell::new(),
             visibilities: FxIndexSet::default(),
+            top_level: Vec::new(),
         }
     }
 
@@ -58,16 +56,14 @@
     }
 
     pub(super) fn lower_module_items(mut self, item_owner: &dyn HasModuleItem) -> ItemTree {
-        self.tree.top_level =
-            item_owner.items().flat_map(|item| self.lower_mod_item(&item)).collect();
-        if let Some(data) = &mut self.tree.data {
-            data.vis.arena = self.visibilities.into_iter().collect();
-        }
+        self.top_level = item_owner.items().flat_map(|item| self.lower_mod_item(&item)).collect();
+        self.tree.vis.arena = self.visibilities.into_iter().collect();
+        self.tree.top_level = self.top_level.into_boxed_slice();
         self.tree
     }
 
     pub(super) fn lower_macro_stmts(mut self, stmts: ast::MacroStmts) -> ItemTree {
-        self.tree.top_level = stmts
+        self.top_level = stmts
             .statements()
             .filter_map(|stmt| {
                 match stmt {
@@ -91,20 +87,19 @@
             if let Some(call) = tail_macro.macro_call() {
                 cov_mark::hit!(macro_stmt_with_trailing_macro_expr);
                 if let Some(mod_item) = self.lower_mod_item(&call.into()) {
-                    self.tree.top_level.push(mod_item);
+                    self.top_level.push(mod_item);
                 }
             }
         }
 
-        if let Some(data) = &mut self.tree.data {
-            data.vis.arena = self.visibilities.into_iter().collect();
-        }
+        self.tree.vis.arena = self.visibilities.into_iter().collect();
+        self.tree.top_level = self.top_level.into_boxed_slice();
         self.tree
     }
 
     pub(super) fn lower_block(mut self, block: &ast::BlockExpr) -> ItemTree {
-        self.tree.attrs.insert(AttrOwner::TopLevel, RawAttrs::new(self.db, block, self.span_map()));
-        self.tree.top_level = block
+        self.tree.top_attrs = RawAttrs::new(self.db, block, self.span_map());
+        self.top_level = block
             .statements()
             .filter_map(|stmt| match stmt {
                 ast::Stmt::Item(item) => self.lower_mod_item(&item),
@@ -120,22 +115,17 @@
         if let Some(ast::Expr::MacroExpr(expr)) = block.tail_expr() {
             if let Some(call) = expr.macro_call() {
                 if let Some(mod_item) = self.lower_mod_item(&call.into()) {
-                    self.tree.top_level.push(mod_item);
+                    self.top_level.push(mod_item);
                 }
             }
         }
-        if let Some(data) = &mut self.tree.data {
-            data.vis.arena = self.visibilities.into_iter().collect();
-        }
+        self.tree.vis.arena = self.visibilities.into_iter().collect();
+        self.tree.top_level = self.top_level.into_boxed_slice();
         self.tree
     }
 
-    fn data(&mut self) -> &mut ItemTreeData {
-        self.tree.data_mut()
-    }
-
-    fn lower_mod_item(&mut self, item: &ast::Item) -> Option<ModItem> {
-        let mod_item: ModItem = match item {
+    fn lower_mod_item(&mut self, item: &ast::Item) -> Option<ModItemId> {
+        let mod_item: ModItemId = match item {
             ast::Item::Struct(ast) => self.lower_struct(ast)?.into(),
             ast::Item::Union(ast) => self.lower_union(ast)?.into(),
             ast::Item::Enum(ast) => self.lower_enum(ast)?.into(),
@@ -155,12 +145,12 @@
             ast::Item::ExternBlock(ast) => self.lower_extern_block(ast).into(),
         };
         let attrs = RawAttrs::new(self.db, item, self.span_map());
-        self.add_attrs(mod_item.into(), attrs);
+        self.add_attrs(mod_item.ast_id(), attrs);
 
         Some(mod_item)
     }
 
-    fn add_attrs(&mut self, item: AttrOwner, attrs: RawAttrs) {
+    fn add_attrs(&mut self, item: FileAstId<ast::Item>, attrs: RawAttrs) {
         if !attrs.is_empty() {
             match self.tree.attrs.entry(item) {
                 Entry::Occupied(mut entry) => {
@@ -173,76 +163,78 @@
         }
     }
 
-    fn lower_struct(&mut self, strukt: &ast::Struct) -> Option<FileItemTreeId<Struct>> {
+    fn lower_struct(&mut self, strukt: &ast::Struct) -> Option<ItemTreeAstId<Struct>> {
         let visibility = self.lower_visibility(strukt);
         let name = strukt.name()?.as_name();
         let ast_id = self.source_ast_id_map.ast_id(strukt);
         let shape = adt_shape(strukt.kind());
-        let res = Struct { name, visibility, shape, ast_id };
-        let id = id(self.data().structs.alloc(res));
+        let res = Struct { name, visibility, shape };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Struct(res));
 
-        Some(id)
+        Some(ast_id)
     }
 
-    fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
+    fn lower_union(&mut self, union: &ast::Union) -> Option<ItemTreeAstId<Union>> {
         let visibility = self.lower_visibility(union);
         let name = union.name()?.as_name();
         let ast_id = self.source_ast_id_map.ast_id(union);
-        let res = Union { name, visibility, ast_id };
-        let id = id(self.data().unions.alloc(res));
-        Some(id)
+        let res = Union { name, visibility };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Union(res));
+        Some(ast_id)
     }
 
-    fn lower_enum(&mut self, enum_: &ast::Enum) -> Option<FileItemTreeId<Enum>> {
+    fn lower_enum(&mut self, enum_: &ast::Enum) -> Option<ItemTreeAstId<Enum>> {
         let visibility = self.lower_visibility(enum_);
         let name = enum_.name()?.as_name();
         let ast_id = self.source_ast_id_map.ast_id(enum_);
-        let res = Enum { name, visibility, ast_id };
-        let id = id(self.data().enums.alloc(res));
-        Some(id)
+        let res = Enum { name, visibility };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Enum(res));
+        Some(ast_id)
     }
 
-    fn lower_function(&mut self, func: &ast::Fn) -> Option<FileItemTreeId<Function>> {
+    fn lower_function(&mut self, func: &ast::Fn) -> Option<ItemTreeAstId<Function>> {
         let visibility = self.lower_visibility(func);
         let name = func.name()?.as_name();
 
         let ast_id = self.source_ast_id_map.ast_id(func);
 
-        let res = Function { name, visibility, ast_id };
+        let res = Function { name, visibility };
 
-        let id = id(self.data().functions.alloc(res));
-        Some(id)
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Function(res));
+        Some(ast_id)
     }
 
     fn lower_type_alias(
         &mut self,
         type_alias: &ast::TypeAlias,
-    ) -> Option<FileItemTreeId<TypeAlias>> {
+    ) -> Option<ItemTreeAstId<TypeAlias>> {
         let name = type_alias.name()?.as_name();
         let visibility = self.lower_visibility(type_alias);
         let ast_id = self.source_ast_id_map.ast_id(type_alias);
-        let res = TypeAlias { name, visibility, ast_id };
-        let id = id(self.data().type_aliases.alloc(res));
-        Some(id)
+        let res = TypeAlias { name, visibility };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::TypeAlias(res));
+        Some(ast_id)
     }
 
-    fn lower_static(&mut self, static_: &ast::Static) -> Option<FileItemTreeId<Static>> {
+    fn lower_static(&mut self, static_: &ast::Static) -> Option<ItemTreeAstId<Static>> {
         let name = static_.name()?.as_name();
         let visibility = self.lower_visibility(static_);
         let ast_id = self.source_ast_id_map.ast_id(static_);
-        let res = Static { name, visibility, ast_id };
-        Some(id(self.data().statics.alloc(res)))
+        let res = Static { name, visibility };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Static(res));
+        Some(ast_id)
     }
 
-    fn lower_const(&mut self, konst: &ast::Const) -> FileItemTreeId<Const> {
+    fn lower_const(&mut self, konst: &ast::Const) -> ItemTreeAstId<Const> {
         let name = konst.name().map(|it| it.as_name());
         let visibility = self.lower_visibility(konst);
         let ast_id = self.source_ast_id_map.ast_id(konst);
-        let res = Const { name, visibility, ast_id };
-        id(self.data().consts.alloc(res))
+        let res = Const { name, visibility };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Const(res));
+        ast_id
     }
 
-    fn lower_module(&mut self, module: &ast::Module) -> Option<FileItemTreeId<Mod>> {
+    fn lower_module(&mut self, module: &ast::Module) -> Option<ItemTreeAstId<Mod>> {
         let name = module.name()?.as_name();
         let visibility = self.lower_visibility(module);
         let kind = if module.semicolon_token().is_some() {
@@ -259,56 +251,59 @@
             }
         };
         let ast_id = self.source_ast_id_map.ast_id(module);
-        let res = Mod { name, visibility, kind, ast_id };
-        Some(id(self.data().mods.alloc(res)))
+        let res = Mod { name, visibility, kind };
+        self.tree.big_data.insert(ast_id.upcast(), BigModItem::Mod(res));
+        Some(ast_id)
     }
 
-    fn lower_trait(&mut self, trait_def: &ast::Trait) -> Option<FileItemTreeId<Trait>> {
+    fn lower_trait(&mut self, trait_def: &ast::Trait) -> Option<ItemTreeAstId<Trait>> {
         let name = trait_def.name()?.as_name();
         let visibility = self.lower_visibility(trait_def);
         let ast_id = self.source_ast_id_map.ast_id(trait_def);
 
-        let def = Trait { name, visibility, ast_id };
-        let id = id(self.data().traits.alloc(def));
-        Some(id)
+        let def = Trait { name, visibility };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Trait(def));
+        Some(ast_id)
     }
 
     fn lower_trait_alias(
         &mut self,
         trait_alias_def: &ast::TraitAlias,
-    ) -> Option<FileItemTreeId<TraitAlias>> {
+    ) -> Option<ItemTreeAstId<TraitAlias>> {
         let name = trait_alias_def.name()?.as_name();
         let visibility = self.lower_visibility(trait_alias_def);
         let ast_id = self.source_ast_id_map.ast_id(trait_alias_def);
 
-        let alias = TraitAlias { name, visibility, ast_id };
-        let id = id(self.data().trait_aliases.alloc(alias));
-        Some(id)
+        let alias = TraitAlias { name, visibility };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::TraitAlias(alias));
+        Some(ast_id)
     }
 
-    fn lower_impl(&mut self, impl_def: &ast::Impl) -> FileItemTreeId<Impl> {
+    fn lower_impl(&mut self, impl_def: &ast::Impl) -> ItemTreeAstId<Impl> {
         let ast_id = self.source_ast_id_map.ast_id(impl_def);
         // Note that trait impls don't get implicit `Self` unlike traits, because here they are a
         // type alias rather than a type parameter, so this is handled by the resolver.
-        let res = Impl { ast_id };
-        id(self.data().impls.alloc(res))
+        let res = Impl {};
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Impl(res));
+        ast_id
     }
 
-    fn lower_use(&mut self, use_item: &ast::Use) -> Option<FileItemTreeId<Use>> {
+    fn lower_use(&mut self, use_item: &ast::Use) -> Option<ItemTreeAstId<Use>> {
         let visibility = self.lower_visibility(use_item);
         let ast_id = self.source_ast_id_map.ast_id(use_item);
         let (use_tree, _) = lower_use_tree(self.db, use_item.use_tree()?, &mut |range| {
             self.span_map().span_for_range(range).ctx
         })?;
 
-        let res = Use { visibility, ast_id, use_tree };
-        Some(id(self.data().uses.alloc(res)))
+        let res = Use { visibility, use_tree };
+        self.tree.big_data.insert(ast_id.upcast(), BigModItem::Use(res));
+        Some(ast_id)
     }
 
     fn lower_extern_crate(
         &mut self,
         extern_crate: &ast::ExternCrate,
-    ) -> Option<FileItemTreeId<ExternCrate>> {
+    ) -> Option<ItemTreeAstId<ExternCrate>> {
         let name = extern_crate.name_ref()?.as_name();
         let alias = extern_crate.rename().map(|a| {
             a.name().map(|it| it.as_name()).map_or(ImportAlias::Underscore, ImportAlias::Alias)
@@ -316,11 +311,12 @@
         let visibility = self.lower_visibility(extern_crate);
         let ast_id = self.source_ast_id_map.ast_id(extern_crate);
 
-        let res = ExternCrate { name, alias, visibility, ast_id };
-        Some(id(self.data().extern_crates.alloc(res)))
+        let res = ExternCrate { name, alias, visibility };
+        self.tree.big_data.insert(ast_id.upcast(), BigModItem::ExternCrate(res));
+        Some(ast_id)
     }
 
-    fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> {
+    fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<ItemTreeAstId<MacroCall>> {
         let span_map = self.span_map();
         let path = m.path()?;
         let range = path.syntax().text_range();
@@ -329,29 +325,32 @@
         })?);
         let ast_id = self.source_ast_id_map.ast_id(m);
         let expand_to = hir_expand::ExpandTo::from_call_site(m);
-        let res = MacroCall { path, ast_id, expand_to, ctxt: span_map.span_for_range(range).ctx };
-        Some(id(self.data().macro_calls.alloc(res)))
+        let res = MacroCall { path, expand_to, ctxt: span_map.span_for_range(range).ctx };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::MacroCall(res));
+        Some(ast_id)
     }
 
-    fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> {
+    fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<ItemTreeAstId<MacroRules>> {
         let name = m.name()?;
         let ast_id = self.source_ast_id_map.ast_id(m);
 
-        let res = MacroRules { name: name.as_name(), ast_id };
-        Some(id(self.data().macro_rules.alloc(res)))
+        let res = MacroRules { name: name.as_name() };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::MacroRules(res));
+        Some(ast_id)
     }
 
-    fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<Macro2>> {
+    fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<ItemTreeAstId<Macro2>> {
         let name = m.name()?;
 
         let ast_id = self.source_ast_id_map.ast_id(m);
         let visibility = self.lower_visibility(m);
 
-        let res = Macro2 { name: name.as_name(), ast_id, visibility };
-        Some(id(self.data().macro_defs.alloc(res)))
+        let res = Macro2 { name: name.as_name(), visibility };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::Macro2(res));
+        Some(ast_id)
     }
 
-    fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> FileItemTreeId<ExternBlock> {
+    fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> ItemTreeAstId<ExternBlock> {
         let ast_id = self.source_ast_id_map.ast_id(block);
         let children: Box<[_]> = block.extern_item_list().map_or(Box::new([]), |list| {
             list.extern_items()
@@ -360,21 +359,22 @@
                     // (in other words, the knowledge that they're in an extern block must not be used).
                     // This is because an extern block can contain macros whose ItemTree's top-level items
                     // should be considered to be in an extern block too.
-                    let mod_item: ModItem = match &item {
+                    let mod_item: ModItemId = match &item {
                         ast::ExternItem::Fn(ast) => self.lower_function(ast)?.into(),
                         ast::ExternItem::Static(ast) => self.lower_static(ast)?.into(),
                         ast::ExternItem::TypeAlias(ty) => self.lower_type_alias(ty)?.into(),
                         ast::ExternItem::MacroCall(call) => self.lower_macro_call(call)?.into(),
                     };
                     let attrs = RawAttrs::new(self.db, &item, self.span_map());
-                    self.add_attrs(mod_item.into(), attrs);
+                    self.add_attrs(mod_item.ast_id(), attrs);
                     Some(mod_item)
                 })
                 .collect()
         });
 
-        let res = ExternBlock { ast_id, children };
-        id(self.data().extern_blocks.alloc(res))
+        let res = ExternBlock { children };
+        self.tree.small_data.insert(ast_id.upcast(), SmallModItem::ExternBlock(res));
+        ast_id
     }
 
     fn lower_visibility(&mut self, item: &dyn ast::HasVisibility) -> RawVisibilityId {
@@ -425,17 +425,15 @@
                 }
             };
 
+            self.mapping.alloc(tree.clone());
             let list = use_tree_list
                 .use_trees()
                 .filter_map(|tree| self.lower_use_tree(tree, span_for_range))
                 .collect();
 
-            Some(
-                self.use_tree(
-                    UseTreeKind::Prefixed { prefix: prefix.map(Interned::new), list },
-                    tree,
-                ),
-            )
+            Some(UseTree {
+                kind: UseTreeKind::Prefixed { prefix: prefix.map(Interned::new), list },
+            })
         } else {
             let is_glob = tree.star_token().is_some();
             let path = match tree.path() {
@@ -454,23 +452,20 @@
                     if path.is_none() {
                         cov_mark::hit!(glob_enum_group);
                     }
-                    Some(self.use_tree(UseTreeKind::Glob { path: path.map(Interned::new) }, tree))
+                    self.mapping.alloc(tree.clone());
+                    Some(UseTree { kind: UseTreeKind::Glob { path: path.map(Interned::new) } })
                 }
                 // Globs can't be renamed
                 (_, Some(_), true) | (None, None, false) => None,
                 // `bla::{ as Name}` is invalid
                 (None, Some(_), false) => None,
-                (Some(path), alias, false) => Some(
-                    self.use_tree(UseTreeKind::Single { path: Interned::new(path), alias }, tree),
-                ),
+                (Some(path), alias, false) => {
+                    self.mapping.alloc(tree.clone());
+                    Some(UseTree { kind: UseTreeKind::Single { path: Interned::new(path), alias } })
+                }
             }
         }
     }
-
-    fn use_tree(&mut self, kind: UseTreeKind, ast: ast::UseTree) -> UseTree {
-        let index = self.mapping.alloc(ast);
-        UseTree { index, kind }
-    }
 }
 
 pub(crate) fn lower_use_tree(
diff --git a/crates/hir-def/src/item_tree/pretty.rs b/crates/hir-def/src/item_tree/pretty.rs
index 0c62b86..eb97081 100644
--- a/crates/hir-def/src/item_tree/pretty.rs
+++ b/crates/hir-def/src/item_tree/pretty.rs
@@ -6,9 +6,9 @@
 
 use crate::{
     item_tree::{
-        AttrOwner, Const, DefDatabase, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl,
-        ItemTree, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, RawAttrs, RawVisibilityId,
-        Static, Struct, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
+        Const, DefDatabase, Enum, ExternBlock, ExternCrate, FieldsShape, Function, Impl, ItemTree,
+        Macro2, MacroCall, MacroRules, Mod, ModItemId, ModKind, RawAttrs, RawVisibilityId, Static,
+        Struct, Trait, TraitAlias, TypeAlias, Union, Use, UseTree, UseTreeKind,
     },
     visibility::RawVisibility,
 };
@@ -17,9 +17,7 @@
     let mut p =
         Printer { db, tree, buf: String::new(), indent_level: 0, needs_indent: true, edition };
 
-    if let Some(attrs) = tree.attrs.get(&AttrOwner::TopLevel) {
-        p.print_attrs(attrs, true, "\n");
-    }
+    p.print_attrs(&tree.top_attrs, true, "\n");
     p.blank();
 
     for item in tree.top_level_items() {
@@ -101,8 +99,8 @@
         }
     }
 
-    fn print_attrs_of(&mut self, of: impl Into<AttrOwner>, separated_by: &str) {
-        if let Some(attrs) = self.tree.attrs.get(&of.into()) {
+    fn print_attrs_of(&mut self, of: ModItemId, separated_by: &str) {
+        if let Some(attrs) = self.tree.attrs.get(&of.ast_id()) {
             self.print_attrs(attrs, false, separated_by);
         }
     }
@@ -159,20 +157,20 @@
         }
     }
 
-    fn print_mod_item(&mut self, item: ModItem) {
+    fn print_mod_item(&mut self, item: ModItemId) {
         self.print_attrs_of(item, "\n");
 
         match item {
-            ModItem::Use(it) => {
-                let Use { visibility, use_tree, ast_id } = &self.tree[it];
+            ModItemId::Use(ast_id) => {
+                let Use { visibility, use_tree } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "use ");
                 self.print_use_tree(use_tree);
                 wln!(self, ";");
             }
-            ModItem::ExternCrate(it) => {
-                let ExternCrate { name, alias, visibility, ast_id } = &self.tree[it];
+            ModItemId::ExternCrate(ast_id) => {
+                let ExternCrate { name, alias, visibility } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "extern crate {}", name.display(self.db, self.edition));
@@ -181,8 +179,8 @@
                 }
                 wln!(self, ";");
             }
-            ModItem::ExternBlock(it) => {
-                let ExternBlock { ast_id, children } = &self.tree[it];
+            ModItemId::ExternBlock(ast_id) => {
+                let ExternBlock { children } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 w!(self, "extern {{");
                 self.indented(|this| {
@@ -192,14 +190,14 @@
                 });
                 wln!(self, "}}");
             }
-            ModItem::Function(it) => {
-                let Function { name, visibility, ast_id } = &self.tree[it];
+            ModItemId::Function(ast_id) => {
+                let Function { name, visibility } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 wln!(self, "fn {};", name.display(self.db, self.edition));
             }
-            ModItem::Struct(it) => {
-                let Struct { visibility, name, shape: kind, ast_id } = &self.tree[it];
+            ModItemId::Struct(ast_id) => {
+                let Struct { visibility, name, shape: kind } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "struct {}", name.display(self.db, self.edition));
@@ -210,22 +208,22 @@
                     wln!(self, ";");
                 }
             }
-            ModItem::Union(it) => {
-                let Union { name, visibility, ast_id } = &self.tree[it];
+            ModItemId::Union(ast_id) => {
+                let Union { name, visibility } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "union {}", name.display(self.db, self.edition));
                 self.print_fields(FieldsShape::Record);
                 wln!(self);
             }
-            ModItem::Enum(it) => {
-                let Enum { name, visibility, ast_id } = &self.tree[it];
+            ModItemId::Enum(ast_id) => {
+                let Enum { name, visibility } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "enum {} {{ ... }}", name.display(self.db, self.edition));
             }
-            ModItem::Const(it) => {
-                let Const { name, visibility, ast_id } = &self.tree[it];
+            ModItemId::Const(ast_id) => {
+                let Const { name, visibility } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "const ");
@@ -235,8 +233,8 @@
                 }
                 wln!(self, " = _;");
             }
-            ModItem::Static(it) => {
-                let Static { name, visibility, ast_id } = &self.tree[it];
+            ModItemId::Static(ast_id) => {
+                let Static { name, visibility } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "static ");
@@ -244,33 +242,33 @@
                 w!(self, " = _;");
                 wln!(self);
             }
-            ModItem::Trait(it) => {
-                let Trait { name, visibility, ast_id } = &self.tree[it];
+            ModItemId::Trait(ast_id) => {
+                let Trait { name, visibility } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "trait {} {{ ... }}", name.display(self.db, self.edition));
             }
-            ModItem::TraitAlias(it) => {
-                let TraitAlias { name, visibility, ast_id } = &self.tree[it];
+            ModItemId::TraitAlias(ast_id) => {
+                let TraitAlias { name, visibility } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 wln!(self, "trait {} = ..;", name.display(self.db, self.edition));
             }
-            ModItem::Impl(it) => {
-                let Impl { ast_id } = &self.tree[it];
+            ModItemId::Impl(ast_id) => {
+                let Impl {} = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 w!(self, "impl {{ ... }}");
             }
-            ModItem::TypeAlias(it) => {
-                let TypeAlias { name, visibility, ast_id } = &self.tree[it];
+            ModItemId::TypeAlias(ast_id) => {
+                let TypeAlias { name, visibility } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "type {}", name.display(self.db, self.edition));
                 w!(self, ";");
                 wln!(self);
             }
-            ModItem::Mod(it) => {
-                let Mod { name, visibility, kind, ast_id } = &self.tree[it];
+            ModItemId::Mod(ast_id) => {
+                let Mod { name, visibility, kind } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 w!(self, "mod {}", name.display(self.db, self.edition));
@@ -289,8 +287,8 @@
                     }
                 }
             }
-            ModItem::MacroCall(it) => {
-                let MacroCall { path, ast_id, expand_to, ctxt } = &self.tree[it];
+            ModItemId::MacroCall(ast_id) => {
+                let MacroCall { path, expand_to, ctxt } = &self.tree[ast_id];
                 let _ = writeln!(
                     self,
                     "// AstId: {:#?}, SyntaxContextId: {}, ExpandTo: {:?}",
@@ -300,13 +298,13 @@
                 );
                 wln!(self, "{}!(...);", path.display(self.db, self.edition));
             }
-            ModItem::MacroRules(it) => {
-                let MacroRules { name, ast_id } = &self.tree[it];
+            ModItemId::MacroRules(ast_id) => {
+                let MacroRules { name } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 wln!(self, "macro_rules! {} {{ ... }}", name.display(self.db, self.edition));
             }
-            ModItem::Macro2(it) => {
-                let Macro2 { name, visibility, ast_id } = &self.tree[it];
+            ModItemId::Macro2(ast_id) => {
+                let Macro2 { name, visibility } = &self.tree[ast_id];
                 self.print_ast_id(ast_id.erase());
                 self.print_visibility(*visibility);
                 wln!(self, "macro {} {{ ... }}", name.display(self.db, self.edition));
diff --git a/crates/hir-def/src/lang_item.rs b/crates/hir-def/src/lang_item.rs
index 1614ef0..8f071cd 100644
--- a/crates/hir-def/src/lang_item.rs
+++ b/crates/hir-def/src/lang_item.rs
@@ -377,6 +377,7 @@
     AsyncFnMut,              sym::async_fn_mut,        async_fn_mut_trait,         Target::Trait,          GenericRequirement::Exact(1);
     AsyncFnOnce,             sym::async_fn_once,       async_fn_once_trait,        Target::Trait,          GenericRequirement::Exact(1);
 
+    AsyncFnOnceOutput,       sym::async_fn_once_output,async_fn_once_output,       Target::AssocTy,        GenericRequirement::None;
     FnOnceOutput,            sym::fn_once_output,      fn_once_output,             Target::AssocTy,        GenericRequirement::None;
 
     Future,                  sym::future_trait,        future_trait,               Target::Trait,          GenericRequirement::Exact(0);
diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs
index c908e45..610bb6b 100644
--- a/crates/hir-def/src/nameres.rs
+++ b/crates/hir-def/src/nameres.rs
@@ -80,7 +80,7 @@
     LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId, ProcMacroId, UseId,
     db::DefDatabase,
     item_scope::{BuiltinShadowMode, ItemScope},
-    item_tree::{ItemTreeId, Mod, TreeId},
+    item_tree::TreeId,
     nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode},
     per_ns::PerNs,
     visibility::{Visibility, VisibilityExplicitness},
@@ -289,11 +289,11 @@
     File {
         is_mod_rs: bool,
         declaration: FileAstId<ast::Module>,
-        declaration_tree_id: ItemTreeId<Mod>,
+        declaration_tree_id: TreeId,
         definition: EditionedFileId,
     },
     Inline {
-        definition_tree_id: ItemTreeId<Mod>,
+        definition_tree_id: TreeId,
         definition: FileAstId<ast::Module>,
     },
     /// Pseudo-module introduced by a block scope (contains only inner items).
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 34a129a..29f94ac 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -35,8 +35,8 @@
     db::DefDatabase,
     item_scope::{GlobId, ImportId, ImportOrExternCrate, PerNsGlobImports},
     item_tree::{
-        self, FieldsShape, FileItemTreeId, ImportAlias, ImportKind, ItemTree, ItemTreeId,
-        ItemTreeNode, Macro2, MacroCall, MacroRules, Mod, ModItem, ModKind, TreeId, UseTreeKind,
+        self, FieldsShape, ImportAlias, ImportKind, ItemTree, ItemTreeAstId, Macro2, MacroCall,
+        MacroRules, Mod, ModItemId, ModKind, TreeId,
     },
     macro_call_as_call_id,
     nameres::{
@@ -140,7 +140,6 @@
     id: UseId,
     is_prelude: bool,
     kind: ImportKind,
-    item_tree_id: ItemTreeId<item_tree::Use>,
 }
 
 #[derive(Debug, Eq, PartialEq)]
@@ -154,19 +153,19 @@
 impl Import {
     fn from_use(
         tree: &ItemTree,
-        item_tree_id: ItemTreeId<item_tree::Use>,
+        item: FileAstId<ast::Use>,
         id: UseId,
         is_prelude: bool,
         mut cb: impl FnMut(Self),
     ) {
-        let it = &tree[item_tree_id.value];
+        let it = &tree[item];
         let visibility = &tree[it.visibility];
-        it.use_tree.expand(|idx, path, kind, alias| {
+        it.expand(|idx, path, kind, alias| {
             cb(Self {
                 path,
                 alias,
                 visibility: visibility.clone(),
-                source: ImportSource { use_tree: idx, id, is_prelude, kind, item_tree_id },
+                source: ImportSource { use_tree: idx, id, is_prelude, kind },
             });
         });
     }
@@ -181,15 +180,15 @@
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]
-struct MacroDirective {
+struct MacroDirective<'db> {
     module_id: LocalModuleId,
     depth: usize,
-    kind: MacroDirectiveKind,
+    kind: MacroDirectiveKind<'db>,
     container: ItemContainerId,
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]
-enum MacroDirectiveKind {
+enum MacroDirectiveKind<'db> {
     FnLike {
         ast_id: AstIdWithPath<ast::MacroCall>,
         expand_to: ExpandTo,
@@ -206,30 +205,31 @@
     Attr {
         ast_id: AstIdWithPath<ast::Item>,
         attr: Attr,
-        mod_item: ModItem,
+        mod_item: ModItemId,
         /* is this needed? */ tree: TreeId,
+        item_tree: &'db ItemTree,
     },
 }
 
 /// Walks the tree of module recursively
-struct DefCollector<'a> {
-    db: &'a dyn DefDatabase,
+struct DefCollector<'db> {
+    db: &'db dyn DefDatabase,
     def_map: DefMap,
     local_def_map: LocalDefMap,
     /// Set only in case of blocks.
-    crate_local_def_map: Option<&'a LocalDefMap>,
+    crate_local_def_map: Option<&'db LocalDefMap>,
     // The dependencies of the current crate, including optional deps like `test`.
     deps: FxHashMap<Name, BuiltDependency>,
     glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, GlobId)>>,
     unresolved_imports: Vec<ImportDirective>,
     indeterminate_imports: Vec<(ImportDirective, PerNs)>,
-    unresolved_macros: Vec<MacroDirective>,
+    unresolved_macros: Vec<MacroDirective<'db>>,
     // We'd like to avoid emitting a diagnostics avalanche when some `extern crate` doesn't
     // resolve. When we emit diagnostics for unresolved imports, we only do so if the import
     // doesn't start with an unresolved crate's name.
     unresolved_extern_crates: FxHashSet<Name>,
     mod_dirs: FxHashMap<LocalModuleId, ModDir>,
-    cfg_options: &'a CfgOptions,
+    cfg_options: &'db CfgOptions,
     /// List of procedural macros defined by this crate. This is read from the dynamic library
     /// built by the build system, and is the list of proc-macros we can actually expand. It is
     /// empty when proc-macro support is disabled (in which case we still do name resolution for
@@ -244,10 +244,10 @@
     /// This also stores the attributes to skip when we resolve derive helpers and non-macro
     /// non-builtin attributes in general.
     // FIXME: There has to be a better way to do this
-    skip_attrs: FxHashMap<InFile<ModItem>, AttrId>,
+    skip_attrs: FxHashMap<InFile<FileAstId<ast::Item>>, AttrId>,
 }
 
-impl DefCollector<'_> {
+impl<'db> DefCollector<'db> {
     fn seed_with_top_level(&mut self) {
         let _p = tracing::info_span!("seed_with_top_level").entered();
 
@@ -355,7 +355,7 @@
             macro_depth: 0,
             module_id: DefMap::ROOT,
             tree_id: TreeId::new(file_id.into(), None),
-            item_tree: &item_tree,
+            item_tree,
             mod_dir: ModDir::root(),
         }
         .collect_in_top_module(item_tree.top_level_items());
@@ -376,7 +376,7 @@
                 macro_depth: 0,
                 module_id: DefMap::ROOT,
                 tree_id,
-                item_tree: &item_tree,
+                item_tree,
                 mod_dir: ModDir::root(),
             }
             .collect_in_top_module(item_tree.top_level_items());
@@ -459,7 +459,7 @@
             self.unresolved_macros.iter().enumerate().find_map(|(idx, directive)| match &directive
                 .kind
             {
-                MacroDirectiveKind::Attr { ast_id, mod_item, attr, tree } => {
+                MacroDirectiveKind::Attr { ast_id, mod_item, attr, tree, item_tree } => {
                     self.def_map.diagnostics.push(DefDiagnostic::unresolved_macro_call(
                         directive.module_id,
                         MacroCallKind::Attr {
@@ -470,16 +470,22 @@
                         attr.path().clone(),
                     ));
 
-                    self.skip_attrs.insert(ast_id.ast_id.with_value(*mod_item), attr.id);
+                    self.skip_attrs.insert(ast_id.ast_id.with_value(mod_item.ast_id()), attr.id);
 
-                    Some((idx, directive, *mod_item, *tree))
+                    Some((idx, directive, *mod_item, *tree, *item_tree))
                 }
                 _ => None,
             });
 
         match unresolved_attr {
-            Some((pos, &MacroDirective { module_id, depth, container, .. }, mod_item, tree_id)) => {
-                let item_tree = &tree_id.item_tree(self.db);
+            Some((
+                pos,
+                &MacroDirective { module_id, depth, container, .. },
+                mod_item,
+                tree_id,
+                item_tree,
+            )) => {
+                // FIXME: Remove this clone
                 let mod_dir = self.mod_dirs[&module_id].clone();
                 ModCollector {
                     def_collector: self,
@@ -860,7 +866,6 @@
                 kind: kind @ (ImportKind::Plain | ImportKind::TypeOnly),
                 id,
                 use_tree,
-                item_tree_id,
                 ..
             } => {
                 let name = match &import.alias {
@@ -893,13 +898,11 @@
                         let Some(ImportOrExternCrate::ExternCrate(_)) = def.import else {
                             return false;
                         };
-                        let item_tree = item_tree_id.item_tree(self.db);
-                        let use_kind = item_tree[item_tree_id.value].use_tree.kind();
-                        let UseTreeKind::Single { path, .. } = use_kind else {
+                        if kind == ImportKind::Glob {
                             return false;
-                        };
-                        matches!(path.kind, PathKind::Plain | PathKind::SELF)
-                            && path.segments().len() < 2
+                        }
+                        matches!(import.path.kind, PathKind::Plain | PathKind::SELF)
+                            && import.path.segments().len() < 2
                     };
                     if is_extern_crate_reimport_without_prefix() {
                         def.vis = vis;
@@ -1253,7 +1256,7 @@
     fn resolve_macros(&mut self) -> ReachedFixedPoint {
         let mut macros = mem::take(&mut self.unresolved_macros);
         let mut resolved = Vec::new();
-        let mut push_resolved = |directive: &MacroDirective, call_id| {
+        let mut push_resolved = |directive: &MacroDirective<'_>, call_id| {
             resolved.push((directive.module_id, directive.depth, directive.container, call_id));
         };
 
@@ -1266,7 +1269,7 @@
         let mut eager_callback_buffer = vec![];
         let mut res = ReachedFixedPoint::Yes;
         // Retain unresolved macros after this round of resolution.
-        let mut retain = |directive: &MacroDirective| {
+        let mut retain = |directive: &MacroDirective<'db>| {
             let subns = match &directive.kind {
                 MacroDirectiveKind::FnLike { .. } => MacroSubNs::Bang,
                 MacroDirectiveKind::Attr { .. } | MacroDirectiveKind::Derive { .. } => {
@@ -1361,22 +1364,29 @@
                         return Resolved::Yes;
                     }
                 }
-                MacroDirectiveKind::Attr { ast_id: file_ast_id, mod_item, attr, tree } => {
+                MacroDirectiveKind::Attr {
+                    ast_id: file_ast_id,
+                    mod_item,
+                    attr,
+                    tree,
+                    item_tree,
+                } => {
                     let &AstIdWithPath { ast_id, ref path } = file_ast_id;
                     let file_id = ast_id.file_id;
 
                     let mut recollect_without = |collector: &mut Self| {
                         // Remove the original directive since we resolved it.
                         let mod_dir = collector.mod_dirs[&directive.module_id].clone();
-                        collector.skip_attrs.insert(InFile::new(file_id, *mod_item), attr.id);
+                        collector
+                            .skip_attrs
+                            .insert(InFile::new(file_id, mod_item.ast_id()), attr.id);
 
-                        let item_tree = tree.item_tree(self.db);
                         ModCollector {
                             def_collector: collector,
                             macro_depth: directive.depth,
                             module_id: directive.module_id,
                             tree_id: *tree,
-                            item_tree: &item_tree,
+                            item_tree,
                             mod_dir,
                         }
                         .collect(&[*mod_item], directive.container);
@@ -1429,11 +1439,10 @@
                         // normal (as that would just be an identity expansion with extra output)
                         // Instead we treat derive attributes special and apply them separately.
 
-                        let item_tree = tree.item_tree(self.db);
                         let ast_adt_id: FileAstId<ast::Adt> = match *mod_item {
-                            ModItem::Struct(strukt) => item_tree[strukt].ast_id().upcast(),
-                            ModItem::Union(union) => item_tree[union].ast_id().upcast(),
-                            ModItem::Enum(enum_) => item_tree[enum_].ast_id().upcast(),
+                            ModItemId::Struct(ast_id) => ast_id.upcast(),
+                            ModItemId::Union(ast_id) => ast_id.upcast(),
+                            ModItemId::Enum(ast_id) => ast_id.upcast(),
                             _ => {
                                 let diag = DefDiagnostic::invalid_derive_target(
                                     directive.module_id,
@@ -1565,7 +1574,7 @@
             macro_depth: depth,
             tree_id: TreeId::new(file_id, None),
             module_id,
-            item_tree: &item_tree,
+            item_tree,
             mod_dir,
         }
         .collect(item_tree.top_level_items(), container);
@@ -1642,8 +1651,7 @@
                 import:
                     Import {
                         ref path,
-                        source:
-                            ImportSource { use_tree, id, is_prelude: _, kind: _, item_tree_id: _ },
+                        source: ImportSource { use_tree, id, is_prelude: _, kind: _ },
                         ..
                     },
                 ..
@@ -1667,22 +1675,22 @@
 }
 
 /// Walks a single module, populating defs, imports and macros
-struct ModCollector<'a, 'b> {
-    def_collector: &'a mut DefCollector<'b>,
+struct ModCollector<'a, 'db> {
+    def_collector: &'a mut DefCollector<'db>,
     macro_depth: usize,
     module_id: LocalModuleId,
     tree_id: TreeId,
-    item_tree: &'a ItemTree,
+    item_tree: &'db ItemTree,
     mod_dir: ModDir,
 }
 
 impl ModCollector<'_, '_> {
-    fn collect_in_top_module(&mut self, items: &[ModItem]) {
+    fn collect_in_top_module(&mut self, items: &[ModItemId]) {
         let module = self.def_collector.def_map.module_id(self.module_id);
         self.collect(items, module.into())
     }
 
-    fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
+    fn collect(&mut self, items: &[ModItemId], container: ItemContainerId) {
         let krate = self.def_collector.def_map.krate;
         let is_crate_root =
             self.module_id == DefMap::ROOT && self.def_collector.def_map.block.is_none();
@@ -1721,29 +1729,11 @@
                 .unwrap_or(Visibility::Public)
         };
 
-        let mut process_mod_item = |item: ModItem| {
-            let attrs = self.item_tree.attrs(db, krate, item.into());
+        let mut process_mod_item = |item: ModItemId| {
+            let attrs = self.item_tree.attrs(db, krate, item.ast_id());
             if let Some(cfg) = attrs.cfg() {
                 if !self.is_cfg_enabled(&cfg) {
-                    let ast_id = match item {
-                        ModItem::Use(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::ExternCrate(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::ExternBlock(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::Function(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::Struct(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::Union(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::Enum(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::Const(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::Static(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::Trait(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::TraitAlias(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::Impl(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::TypeAlias(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::Mod(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::MacroCall(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::MacroRules(it) => self.item_tree[it].ast_id.erase(),
-                        ModItem::Macro2(it) => self.item_tree[it].ast_id.erase(),
-                    };
+                    let ast_id = item.ast_id().erase();
                     self.emit_unconfigured_diagnostic(InFile::new(self.file_id(), ast_id), &cfg);
                     return;
                 }
@@ -1761,35 +1751,27 @@
                 self.def_collector.crate_local_def_map.unwrap_or(&self.def_collector.local_def_map);
 
             match item {
-                ModItem::Mod(m) => self.collect_module(m, &attrs),
-                ModItem::Use(item_tree_id) => {
-                    let id = UseLoc {
-                        container: module,
-                        id: InFile::new(self.file_id(), self.item_tree[item_tree_id].ast_id),
-                    }
-                    .intern(db);
+                ModItemId::Mod(m) => self.collect_module(m, &attrs),
+                ModItemId::Use(item_tree_id) => {
+                    let id =
+                        UseLoc { container: module, id: InFile::new(self.file_id(), item_tree_id) }
+                            .intern(db);
                     let is_prelude = attrs.by_key(sym::prelude_import).exists();
-                    Import::from_use(
-                        self.item_tree,
-                        ItemTreeId::new(self.tree_id, item_tree_id),
-                        id,
-                        is_prelude,
-                        |import| {
-                            self.def_collector.unresolved_imports.push(ImportDirective {
-                                module_id: self.module_id,
-                                import,
-                                status: PartialResolvedImport::Unresolved,
-                            });
-                        },
-                    )
+                    Import::from_use(self.item_tree, item_tree_id, id, is_prelude, |import| {
+                        self.def_collector.unresolved_imports.push(ImportDirective {
+                            module_id: self.module_id,
+                            import,
+                            status: PartialResolvedImport::Unresolved,
+                        });
+                    })
                 }
-                ModItem::ExternCrate(item_tree_id) => {
-                    let item_tree::ExternCrate { name, visibility, alias, ast_id } =
+                ModItemId::ExternCrate(item_tree_id) => {
+                    let item_tree::ExternCrate { name, visibility, alias } =
                         &self.item_tree[item_tree_id];
 
                     let id = ExternCrateLoc {
                         container: module,
-                        id: InFile::new(self.tree_id.file_id(), *ast_id),
+                        id: InFile::new(self.tree_id.file_id(), item_tree_id),
                     }
                     .intern(db);
                     def_map.modules[self.module_id].scope.define_extern_crate_decl(id);
@@ -1852,15 +1834,15 @@
                         self.def_collector.def_map.diagnostics.push(
                             DefDiagnostic::unresolved_extern_crate(
                                 module_id,
-                                InFile::new(self.file_id(), *ast_id),
+                                InFile::new(self.file_id(), item_tree_id),
                             ),
                         );
                     }
                 }
-                ModItem::ExternBlock(block) => {
+                ModItemId::ExternBlock(block) => {
                     let extern_block_id = ExternBlockLoc {
                         container: module,
-                        id: InFile::new(self.file_id(), self.item_tree[block].ast_id),
+                        id: InFile::new(self.file_id(), block),
                     }
                     .intern(db);
                     self.def_collector.def_map.modules[self.module_id]
@@ -1871,24 +1853,20 @@
                         ItemContainerId::ExternBlockId(extern_block_id),
                     )
                 }
-                ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac], container),
-                ModItem::MacroRules(id) => self.collect_macro_rules(id, module),
-                ModItem::Macro2(id) => self.collect_macro_def(id, module),
-                ModItem::Impl(imp) => {
-                    let impl_id = ImplLoc {
-                        container: module,
-                        id: InFile::new(self.file_id(), self.item_tree[imp].ast_id),
-                    }
-                    .intern(db);
+                ModItemId::MacroCall(mac) => self.collect_macro_call(mac, container),
+                ModItemId::MacroRules(id) => self.collect_macro_rules(id, module),
+                ModItemId::Macro2(id) => self.collect_macro_def(id, module),
+                ModItemId::Impl(imp) => {
+                    let impl_id =
+                        ImplLoc { container: module, id: InFile::new(self.file_id(), imp) }
+                            .intern(db);
                     self.def_collector.def_map.modules[self.module_id].scope.define_impl(impl_id)
                 }
-                ModItem::Function(id) => {
+                ModItemId::Function(id) => {
                     let it = &self.item_tree[id];
-                    let fn_id = FunctionLoc {
-                        container,
-                        id: InFile::new(self.tree_id.file_id(), it.ast_id),
-                    }
-                    .intern(db);
+                    let fn_id =
+                        FunctionLoc { container, id: InFile::new(self.tree_id.file_id(), id) }
+                            .intern(db);
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
 
@@ -1899,7 +1877,7 @@
                         if let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) {
                             self.def_collector.export_proc_macro(
                                 proc_macro,
-                                InFile::new(self.file_id(), self.item_tree[id].ast_id()),
+                                InFile::new(self.file_id(), id),
                                 fn_id,
                             );
                         }
@@ -1907,13 +1885,13 @@
 
                     update_def(self.def_collector, fn_id.into(), &it.name, vis, false);
                 }
-                ModItem::Struct(id) => {
+                ModItemId::Struct(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
                     update_def(
                         self.def_collector,
-                        StructLoc { container: module, id: InFile::new(self.file_id(), it.ast_id) }
+                        StructLoc { container: module, id: InFile::new(self.file_id(), id) }
                             .intern(db)
                             .into(),
                         &it.name,
@@ -1921,13 +1899,13 @@
                         !matches!(it.shape, FieldsShape::Record),
                     );
                 }
-                ModItem::Union(id) => {
+                ModItemId::Union(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
                     update_def(
                         self.def_collector,
-                        UnionLoc { container: module, id: InFile::new(self.file_id(), it.ast_id) }
+                        UnionLoc { container: module, id: InFile::new(self.file_id(), id) }
                             .intern(db)
                             .into(),
                         &it.name,
@@ -1935,21 +1913,19 @@
                         false,
                     );
                 }
-                ModItem::Enum(id) => {
+                ModItemId::Enum(id) => {
                     let it = &self.item_tree[id];
-                    let enum_ = EnumLoc {
-                        container: module,
-                        id: InFile::new(self.tree_id.file_id(), it.ast_id),
-                    }
-                    .intern(db);
+                    let enum_ =
+                        EnumLoc { container: module, id: InFile::new(self.tree_id.file_id(), id) }
+                            .intern(db);
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
                     update_def(self.def_collector, enum_.into(), &it.name, vis, false);
                 }
-                ModItem::Const(id) => {
+                ModItemId::Const(id) => {
                     let it = &self.item_tree[id];
                     let const_id =
-                        ConstLoc { container, id: InFile::new(self.tree_id.file_id(), it.ast_id) }
+                        ConstLoc { container, id: InFile::new(self.tree_id.file_id(), id) }
                             .intern(db);
 
                     match &it.name {
@@ -1966,13 +1942,13 @@
                         }
                     }
                 }
-                ModItem::Static(id) => {
+                ModItemId::Static(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
                     update_def(
                         self.def_collector,
-                        StaticLoc { container, id: InFile::new(self.file_id(), it.ast_id) }
+                        StaticLoc { container, id: InFile::new(self.file_id(), id) }
                             .intern(db)
                             .into(),
                         &it.name,
@@ -1980,13 +1956,13 @@
                         false,
                     );
                 }
-                ModItem::Trait(id) => {
+                ModItemId::Trait(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
                     update_def(
                         self.def_collector,
-                        TraitLoc { container: module, id: InFile::new(self.file_id(), it.ast_id) }
+                        TraitLoc { container: module, id: InFile::new(self.file_id(), id) }
                             .intern(db)
                             .into(),
                         &it.name,
@@ -1994,30 +1970,27 @@
                         false,
                     );
                 }
-                ModItem::TraitAlias(id) => {
+                ModItemId::TraitAlias(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
                     update_def(
                         self.def_collector,
-                        TraitAliasLoc {
-                            container: module,
-                            id: InFile::new(self.file_id(), it.ast_id),
-                        }
-                        .intern(db)
-                        .into(),
+                        TraitAliasLoc { container: module, id: InFile::new(self.file_id(), id) }
+                            .intern(db)
+                            .into(),
                         &it.name,
                         vis,
                         false,
                     );
                 }
-                ModItem::TypeAlias(id) => {
+                ModItemId::TypeAlias(id) => {
                     let it = &self.item_tree[id];
 
                     let vis = resolve_vis(def_map, local_def_map, &self.item_tree[it.visibility]);
                     update_def(
                         self.def_collector,
-                        TypeAliasLoc { container, id: InFile::new(self.file_id(), it.ast_id) }
+                        TypeAliasLoc { container, id: InFile::new(self.file_id(), id) }
                             .intern(db)
                             .into(),
                         &it.name,
@@ -2034,12 +2007,12 @@
         if is_crate_root {
             items
                 .iter()
-                .filter(|it| matches!(it, ModItem::ExternCrate(..)))
+                .filter(|it| matches!(it, ModItemId::ExternCrate(..)))
                 .copied()
                 .for_each(&mut process_mod_item);
             items
                 .iter()
-                .filter(|it| !matches!(it, ModItem::ExternCrate(..)))
+                .filter(|it| !matches!(it, ModItemId::ExternCrate(..)))
                 .copied()
                 .for_each(process_mod_item);
         } else {
@@ -2080,19 +2053,18 @@
         );
     }
 
-    fn collect_module(&mut self, module_id: FileItemTreeId<Mod>, attrs: &Attrs) {
+    fn collect_module(&mut self, module_ast_id: ItemTreeAstId<Mod>, attrs: &Attrs) {
         let path_attr = attrs.by_key(sym::path).string_value_unescape();
         let is_macro_use = attrs.by_key(sym::macro_use).exists();
-        let module = &self.item_tree[module_id];
+        let module = &self.item_tree[module_ast_id];
         match &module.kind {
             // inline module, just recurse
             ModKind::Inline { items } => {
                 let module_id = self.push_child_module(
                     module.name.clone(),
-                    module.ast_id,
+                    module_ast_id,
                     None,
                     &self.item_tree[module.visibility],
-                    module_id,
                 );
 
                 let Some(mod_dir) =
@@ -2115,7 +2087,7 @@
             }
             // out of line module, resolve, parse and recurse
             ModKind::Outline => {
-                let ast_id = AstId::new(self.file_id(), module.ast_id);
+                let ast_id = AstId::new(self.file_id(), module_ast_id);
                 let db = self.def_collector.db;
                 match self.mod_dir.resolve_declaration(
                     db,
@@ -2134,10 +2106,7 @@
                         match is_enabled {
                             Err(cfg) => {
                                 self.emit_unconfigured_diagnostic(
-                                    InFile::new(
-                                        self.file_id(),
-                                        self.item_tree[module_id].ast_id.erase(),
-                                    ),
+                                    InFile::new(self.file_id(), module_ast_id.erase()),
                                     &cfg,
                                 );
                             }
@@ -2147,14 +2116,13 @@
                                     ast_id.value,
                                     Some((file_id, is_mod_rs)),
                                     &self.item_tree[module.visibility],
-                                    module_id,
                                 );
                                 ModCollector {
                                     def_collector: self.def_collector,
                                     macro_depth: self.macro_depth,
                                     module_id,
                                     tree_id: TreeId::new(file_id.into(), None),
-                                    item_tree: &item_tree,
+                                    item_tree,
                                     mod_dir,
                                 }
                                 .collect_in_top_module(item_tree.top_level_items());
@@ -2175,7 +2143,6 @@
                             ast_id.value,
                             None,
                             &self.item_tree[module.visibility],
-                            module_id,
                         );
                         self.def_collector.def_map.diagnostics.push(
                             DefDiagnostic::unresolved_module(self.module_id, ast_id, candidates),
@@ -2192,7 +2159,6 @@
         declaration: FileAstId<ast::Module>,
         definition: Option<(EditionedFileId, bool)>,
         visibility: &crate::visibility::RawVisibility,
-        mod_tree_id: FileItemTreeId<Mod>,
     ) -> LocalModuleId {
         let def_map = &mut self.def_collector.def_map;
         let vis = def_map
@@ -2205,15 +2171,14 @@
             )
             .unwrap_or(Visibility::Public);
         let origin = match definition {
-            None => ModuleOrigin::Inline {
-                definition: declaration,
-                definition_tree_id: ItemTreeId::new(self.tree_id, mod_tree_id),
-            },
+            None => {
+                ModuleOrigin::Inline { definition: declaration, definition_tree_id: self.tree_id }
+            }
             Some((definition, is_mod_rs)) => ModuleOrigin::File {
                 declaration,
                 definition,
                 is_mod_rs,
-                declaration_tree_id: ItemTreeId::new(self.tree_id, mod_tree_id),
+                declaration_tree_id: self.tree_id,
             },
         };
 
@@ -2254,11 +2219,14 @@
     fn resolve_attributes(
         &mut self,
         attrs: &Attrs,
-        mod_item: ModItem,
+        mod_item: ModItemId,
         container: ItemContainerId,
     ) -> Result<(), ()> {
-        let mut ignore_up_to =
-            self.def_collector.skip_attrs.get(&InFile::new(self.file_id(), mod_item)).copied();
+        let mut ignore_up_to = self
+            .def_collector
+            .skip_attrs
+            .get(&InFile::new(self.file_id(), mod_item.ast_id()))
+            .copied();
         let iter = attrs
             .iter()
             .dedup_by(|a, b| {
@@ -2288,11 +2256,7 @@
                 attr.path.display(self.def_collector.db, Edition::LATEST)
             );
 
-            let ast_id = AstIdWithPath::new(
-                self.file_id(),
-                mod_item.ast_id(self.item_tree),
-                attr.path.clone(),
-            );
+            let ast_id = AstIdWithPath::new(self.file_id(), mod_item.ast_id(), attr.path.clone());
             self.def_collector.unresolved_macros.push(MacroDirective {
                 module_id: self.module_id,
                 depth: self.macro_depth + 1,
@@ -2301,6 +2265,7 @@
                     attr: attr.clone(),
                     mod_item,
                     tree: self.tree_id,
+                    item_tree: self.item_tree,
                 },
                 container,
             });
@@ -2311,11 +2276,11 @@
         Ok(())
     }
 
-    fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>, module: ModuleId) {
+    fn collect_macro_rules(&mut self, ast_id: ItemTreeAstId<MacroRules>, module: ModuleId) {
         let krate = self.def_collector.def_map.krate;
-        let mac = &self.item_tree[id];
-        let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
-        let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast());
+        let mac = &self.item_tree[ast_id];
+        let attrs = self.item_tree.attrs(self.def_collector.db, krate, ast_id.upcast());
+        let f_ast_id = InFile::new(self.file_id(), ast_id.upcast());
 
         let export_attr = || attrs.by_key(sym::macro_export);
 
@@ -2362,7 +2327,7 @@
                     self.def_collector
                         .def_map
                         .diagnostics
-                        .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
+                        .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, f_ast_id));
                     return;
                 }
             }
@@ -2378,16 +2343,13 @@
 
         let macro_id = MacroRulesLoc {
             container: module,
-            id: InFile::new(self.file_id(), mac.ast_id),
+            id: InFile::new(self.file_id(), ast_id),
             flags,
             expander,
             edition: self.def_collector.def_map.data.edition,
         }
         .intern(self.def_collector.db);
-        self.def_collector.def_map.macro_def_to_macro_id.insert(
-            InFile::new(self.file_id(), self.item_tree[id].ast_id()).erase(),
-            macro_id.into(),
-        );
+        self.def_collector.def_map.macro_def_to_macro_id.insert(f_ast_id.erase(), macro_id.into());
         self.def_collector.define_macro_rules(
             self.module_id,
             mac.name.clone(),
@@ -2396,14 +2358,14 @@
         );
     }
 
-    fn collect_macro_def(&mut self, id: FileItemTreeId<Macro2>, module: ModuleId) {
+    fn collect_macro_def(&mut self, ast_id: ItemTreeAstId<Macro2>, module: ModuleId) {
         let krate = self.def_collector.def_map.krate;
-        let mac = &self.item_tree[id];
-        let ast_id = InFile::new(self.file_id(), mac.ast_id.upcast());
+        let mac = &self.item_tree[ast_id];
+        let attrs = self.item_tree.attrs(self.def_collector.db, krate, ast_id.upcast());
+        let f_ast_id = InFile::new(self.file_id(), ast_id.upcast());
 
         // Case 1: builtin macros
         let mut helpers_opt = None;
-        let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
         let expander = if attrs.by_key(sym::rustc_builtin_macro).exists() {
             if let Some(expander) = find_builtin_macro(&mac.name) {
                 match expander {
@@ -2435,7 +2397,7 @@
                 self.def_collector
                     .def_map
                     .diagnostics
-                    .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, ast_id));
+                    .push(DefDiagnostic::unimplemented_builtin_macro(self.module_id, f_ast_id));
                 return;
             }
         } else {
@@ -2446,16 +2408,13 @@
 
         let macro_id = Macro2Loc {
             container: module,
-            id: InFile::new(self.file_id(), mac.ast_id),
+            id: InFile::new(self.file_id(), ast_id),
             expander,
             allow_internal_unsafe,
             edition: self.def_collector.def_map.data.edition,
         }
         .intern(self.def_collector.db);
-        self.def_collector.def_map.macro_def_to_macro_id.insert(
-            InFile::new(self.file_id(), self.item_tree[id].ast_id()).erase(),
-            macro_id.into(),
-        );
+        self.def_collector.def_map.macro_def_to_macro_id.insert(f_ast_id.erase(), macro_id.into());
         self.def_collector.define_macro_def(
             self.module_id,
             mac.name.clone(),
@@ -2474,9 +2433,10 @@
 
     fn collect_macro_call(
         &mut self,
-        &MacroCall { ref path, ast_id, expand_to, ctxt }: &MacroCall,
+        ast_id: FileAstId<ast::MacroCall>,
         container: ItemContainerId,
     ) {
+        let &MacroCall { ref path, expand_to, ctxt } = &self.item_tree[ast_id];
         let ast_id = AstIdWithPath::new(self.file_id(), ast_id, path.clone());
         let db = self.def_collector.db;
 
diff --git a/crates/hir-def/src/nameres/tests/incremental.rs b/crates/hir-def/src/nameres/tests/incremental.rs
index 948e8be..7a4ea62 100644
--- a/crates/hir-def/src/nameres/tests/incremental.rs
+++ b/crates/hir-def/src/nameres/tests/incremental.rs
@@ -348,7 +348,7 @@
             assert_eq!(module_data.scope.resolutions().count(), 4);
         });
         let n_recalculated_item_trees =
-            events.iter().filter(|it| it.contains("file_item_tree_shim")).count();
+            events.iter().filter(|it| it.contains("file_item_tree_query")).count();
         assert_eq!(n_recalculated_item_trees, 6);
         let n_reparsed_macros =
             events.iter().filter(|it| it.contains("parse_macro_expansion_shim")).count();
@@ -370,7 +370,7 @@
             assert_eq!(module_data.scope.resolutions().count(), 4);
         });
         let n_recalculated_item_trees =
-            events.iter().filter(|it| it.contains("file_item_tree_shim")).count();
+            events.iter().filter(|it| it.contains("file_item_tree_query")).count();
         assert_eq!(n_recalculated_item_trees, 1, "{events:#?}");
         let n_reparsed_macros =
             events.iter().filter(|it| it.contains("parse_macro_expansion_shim")).count();
@@ -405,10 +405,10 @@
             db.file_item_tree(pos.file_id.into());
         });
         let n_calculated_item_trees =
-            events.iter().filter(|it| it.contains("file_item_tree_shim")).count();
-        assert_eq!(n_calculated_item_trees, 1);
+            events.iter().filter(|it| it.contains("file_item_tree_query")).count();
+        assert_eq!(n_calculated_item_trees, 1, "{events:#?}");
         let n_parsed_files = events.iter().filter(|it| it.contains("parse")).count();
-        assert_eq!(n_parsed_files, 1);
+        assert_eq!(n_parsed_files, 1, "{events:#?}");
     }
 
     // FIXME(salsa-transition): bring this back
@@ -446,6 +446,6 @@
             }
         });
         let n_reparsed_files = events.iter().filter(|it| it.contains("parse(")).count();
-        assert_eq!(n_reparsed_files, 0);
+        assert_eq!(n_reparsed_files, 0, "{events:?}");
     }
 }
diff --git a/crates/hir-ty/Cargo.toml b/crates/hir-ty/Cargo.toml
index efa544c..8b65126 100644
--- a/crates/hir-ty/Cargo.toml
+++ b/crates/hir-ty/Cargo.toml
@@ -31,7 +31,7 @@
 triomphe.workspace = true
 typed-arena = "2.0.2"
 indexmap.workspace = true
-rustc_apfloat = "0.2.2"
+rustc_apfloat = "0.2.3"
 query-group.workspace = true
 salsa.workspace = true
 salsa-macros.workspace = true
diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs
index 710ac6e..f658e23 100644
--- a/crates/hir-ty/src/chalk_db.rs
+++ b/crates/hir-ty/src/chalk_db.rs
@@ -261,10 +261,20 @@
         &self,
         well_known_trait: WellKnownTrait,
     ) -> Option<chalk_ir::TraitId<Interner>> {
-        let lang_attr = lang_item_from_well_known_trait(well_known_trait);
-        let trait_ = lang_attr.resolve_trait(self.db, self.krate)?;
+        let lang_item = lang_item_from_well_known_trait(well_known_trait);
+        let trait_ = lang_item.resolve_trait(self.db, self.krate)?;
         Some(to_chalk_trait_id(trait_))
     }
+    fn well_known_assoc_type_id(
+        &self,
+        assoc_type: rust_ir::WellKnownAssocType,
+    ) -> Option<chalk_ir::AssocTypeId<Interner>> {
+        let lang_item = match assoc_type {
+            rust_ir::WellKnownAssocType::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput,
+        };
+        let alias = lang_item.resolve_type_alias(self.db, self.krate)?;
+        Some(to_assoc_type_id(alias))
+    }
 
     fn program_clauses_for_env(
         &self,
diff --git a/crates/hir-ty/src/tests/incremental.rs b/crates/hir-ty/src/tests/incremental.rs
index a055ef8..74f6bbb 100644
--- a/crates/hir-ty/src/tests/incremental.rs
+++ b/crates/hir-ty/src/tests/incremental.rs
@@ -156,7 +156,7 @@
         let expected = vec![
             "parse_shim".to_owned(),
             "ast_id_map_shim".to_owned(),
-            "file_item_tree_shim".to_owned(),
+            "file_item_tree_query".to_owned(),
             "real_span_map_shim".to_owned(),
             "crate_local_def_map".to_owned(),
             "trait_impls_in_crate_shim".to_owned(),
@@ -216,7 +216,7 @@
         let expected = vec![
             "parse_shim".to_owned(),
             "ast_id_map_shim".to_owned(),
-            "file_item_tree_shim".to_owned(),
+            "file_item_tree_query".to_owned(),
             "real_span_map_shim".to_owned(),
             "crate_local_def_map".to_owned(),
             "trait_impls_in_crate_shim".to_owned(),
@@ -273,7 +273,7 @@
         let expected = vec![
             "parse_shim".to_owned(),
             "ast_id_map_shim".to_owned(),
-            "file_item_tree_shim".to_owned(),
+            "file_item_tree_query".to_owned(),
             "real_span_map_shim".to_owned(),
             "crate_local_def_map".to_owned(),
             "trait_impls_in_crate_shim".to_owned(),
@@ -342,7 +342,7 @@
         let expected = vec![
             "parse_shim".to_owned(),
             "ast_id_map_shim".to_owned(),
-            "file_item_tree_shim".to_owned(),
+            "file_item_tree_query".to_owned(),
             "real_span_map_shim".to_owned(),
             "crate_local_def_map".to_owned(),
             "trait_impls_in_crate_shim".to_owned(),
diff --git a/crates/ide-db/Cargo.toml b/crates/ide-db/Cargo.toml
index 583318d..acde1d6 100644
--- a/crates/ide-db/Cargo.toml
+++ b/crates/ide-db/Cargo.toml
@@ -22,7 +22,7 @@
 itertools.workspace = true
 arrayvec.workspace = true
 indexmap.workspace = true
-memchr = "2.7.4"
+memchr = "2.7.5"
 salsa.workspace = true
 salsa-macros.workspace = true
 query-group.workspace = true
diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml
index 1d19daf..2f8ed88 100644
--- a/crates/ide/Cargo.toml
+++ b/crates/ide/Cargo.toml
@@ -25,7 +25,7 @@
 smallvec.workspace = true
 triomphe.workspace = true
 nohash-hasher.workspace = true
-rustc_apfloat = "0.2.2"
+rustc_apfloat = "0.2.3"
 
 # local deps
 cfg.workspace = true
diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs
index fc922dd..d5cbb73 100644
--- a/crates/intern/src/symbol/symbols.rs
+++ b/crates/intern/src/symbol/symbols.rs
@@ -222,6 +222,7 @@
     fn_once_output,
     fn_once,
     async_fn_once,
+    async_fn_once_output,
     async_fn_mut,
     async_fn,
     fn_ptr_addr,
diff --git a/crates/proc-macro-srv/proc-macro-test/Cargo.toml b/crates/proc-macro-srv/proc-macro-test/Cargo.toml
index eddefb3..c416d99 100644
--- a/crates/proc-macro-srv/proc-macro-test/Cargo.toml
+++ b/crates/proc-macro-srv/proc-macro-test/Cargo.toml
@@ -9,4 +9,4 @@
 [lib]
 
 [build-dependencies]
-cargo_metadata = "0.19.2"
+cargo_metadata = "0.20.0"
diff --git a/crates/profile/Cargo.toml b/crates/profile/Cargo.toml
index 1fb1383..bae891c 100644
--- a/crates/profile/Cargo.toml
+++ b/crates/profile/Cargo.toml
@@ -12,7 +12,7 @@
 [lib]
 
 [dependencies]
-cfg-if = "1.0.0"
+cfg-if = "1.0.1"
 jemalloc-ctl = { version = "0.5.4", package = "tikv-jemalloc-ctl", optional = true }
 
 [target.'cfg(all(target_os = "linux", not(target_env = "ohos")))'.dependencies]
@@ -22,7 +22,7 @@
 libc.workspace = true
 
 [target.'cfg(windows)'.dependencies]
-windows-sys = { version = "0.59", features = [
+windows-sys = { version = "0.60", features = [
     "Win32_System_Threading",
     "Win32_System_ProcessStatus",
 ] }
diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs
index bb02284..1fade7b 100644
--- a/crates/project-model/src/cargo_workspace.rs
+++ b/crates/project-model/src/cargo_workspace.rs
@@ -492,7 +492,7 @@
             is_virtual_workspace &= manifest != ws_manifest_path;
             let pkg = packages.alloc(PackageData {
                 id: id.repr.clone(),
-                name,
+                name: name.to_string(),
                 version,
                 manifest: manifest.clone(),
                 targets: Vec::new(),
@@ -547,10 +547,12 @@
                 .flat_map(|dep| DepKind::iter(&dep.dep_kinds).map(move |kind| (dep, kind)));
             for (dep_node, kind) in dependencies {
                 let &pkg = pkg_by_id.get(&dep_node.pkg).unwrap();
-                let dep = PackageDependency { name: dep_node.name.clone(), pkg, kind };
+                let dep = PackageDependency { name: dep_node.name.to_string(), pkg, kind };
                 packages[source].dependencies.push(dep);
             }
-            packages[source].active_features.extend(node.features);
+            packages[source]
+                .active_features
+                .extend(node.features.into_iter().map(|it| it.to_string()));
         }
 
         CargoWorkspace {
diff --git a/crates/project-model/src/sysroot.rs b/crates/project-model/src/sysroot.rs
index d4055d9..ebd86e3 100644
--- a/crates/project-model/src/sysroot.rs
+++ b/crates/project-model/src/sysroot.rs
@@ -339,7 +339,7 @@
                     Some(_) => {
                         tracing::warn!("unknown rustc-std-workspace-* crate: {}", package.name)
                     }
-                    None => match &*package.name {
+                    None => match &**package.name {
                         "core" => real_core = Some(package.id.clone()),
                         "alloc" => real_alloc = Some(package.id.clone()),
                         "std" => real_std = Some(package.id.clone()),
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index b59d068..5e63521 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -29,7 +29,7 @@
 itertools.workspace = true
 scip = "0.5.2"
 lsp-types = { version = "=0.95.0", features = ["proposed"] }
-parking_lot = "0.12.3"
+parking_lot = "0.12.4"
 xflags = "0.3.2"
 oorandom = "11.1.5"
 rayon.workspace = true
@@ -37,19 +37,19 @@
 serde_json = { workspace = true, features = ["preserve_order"] }
 serde.workspace = true
 serde_derive.workspace = true
-tenthash = "1.0.0"
-num_cpus = "1.16.0"
-mimalloc = { version = "0.1.44", default-features = false, optional = true }
+tenthash = "1.1.0"
+num_cpus = "1.17.0"
+mimalloc = { version = "0.1.46", default-features = false, optional = true }
 lsp-server.workspace = true
 tracing.workspace = true
 tracing-subscriber.workspace = true
 tracing-tree.workspace = true
 triomphe.workspace = true
-toml = "0.8.20"
+toml = "0.8.23"
 nohash-hasher.workspace = true
 walkdir = "2.5.0"
 semver.workspace = true
-memchr = "2.7.4"
+memchr = "2.7.5"
 cargo_metadata.workspace = true
 process-wrap.workspace = true
 
@@ -75,7 +75,7 @@
 paths.workspace = true
 
 [target.'cfg(windows)'.dependencies]
-windows-sys = { version = "0.59", features = [
+windows-sys = { version = "0.60", features = [
   "Win32_System_Diagnostics_Debug",
   "Win32_System_Threading",
 ] }
diff --git a/crates/stdx/Cargo.toml b/crates/stdx/Cargo.toml
index b37aded..a6d5781 100644
--- a/crates/stdx/Cargo.toml
+++ b/crates/stdx/Cargo.toml
@@ -12,7 +12,7 @@
 [lib]
 
 [dependencies]
-backtrace = { version = "0.3.74", optional = true }
+backtrace = { version = "0.3.75", optional = true }
 jod-thread = "1.0.0"
 crossbeam-channel.workspace = true
 itertools.workspace = true
@@ -25,7 +25,7 @@
 
 [target.'cfg(windows)'.dependencies]
 miow = "0.6.0"
-windows-sys = { version = "0.59", features = ["Win32_Foundation"] }
+windows-sys = { version = "0.60", features = ["Win32_Foundation"] }
 
 [features]
 # Uncomment to enable for the whole crate graph
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml
index 4c77048..9d3aaa8 100644
--- a/crates/syntax/Cargo.toml
+++ b/crates/syntax/Cargo.toml
@@ -27,7 +27,7 @@
 [dev-dependencies]
 rayon.workspace = true
 expect-test = "1.5.1"
-rustc_apfloat = "0.2.2"
+rustc_apfloat = "0.2.3"
 
 test-utils.workspace = true
 
diff --git a/lib/lsp-server/Cargo.toml b/lib/lsp-server/Cargo.toml
index 1dc6d3c..35a5a4d 100644
--- a/lib/lsp-server/Cargo.toml
+++ b/lib/lsp-server/Cargo.toml
@@ -7,7 +7,7 @@
 edition = "2024"
 
 [dependencies]
-log = "0.4.26"
+log = "0.4.27"
 serde_json = "1.0.140"
 serde = { version = "1.0.219" }
 serde_derive = { version = "1.0.219" }
@@ -15,7 +15,7 @@
 
 [dev-dependencies]
 lsp-types = "=0.95"
-ctrlc = "3.4.5"
+ctrlc = "3.4.7"
 
 [lints]
 workspace = true
diff --git a/lib/lsp-server/src/msg.rs b/lib/lsp-server/src/msg.rs
index 2749557..399d674 100644
--- a/lib/lsp-server/src/msg.rs
+++ b/lib/lsp-server/src/msg.rs
@@ -283,12 +283,12 @@
     buf.resize(size, 0);
     inp.read_exact(&mut buf)?;
     let buf = String::from_utf8(buf).map_err(invalid_data)?;
-    log::debug!("< {}", buf);
+    log::debug!("< {buf}");
     Ok(Some(buf))
 }
 
 fn write_msg_text(out: &mut dyn Write, msg: &str) -> io::Result<()> {
-    log::debug!("> {}", msg);
+    log::debug!("> {msg}");
     write!(out, "Content-Length: {}\r\n\r\n", msg.len())?;
     out.write_all(msg.as_bytes())?;
     out.flush()?;
diff --git a/lib/lsp-server/src/stdio.rs b/lib/lsp-server/src/stdio.rs
index c558b6c..eccc89f 100644
--- a/lib/lsp-server/src/stdio.rs
+++ b/lib/lsp-server/src/stdio.rs
@@ -38,7 +38,7 @@
             while let Some(msg) = Message::read(&mut stdin)? {
                 let is_exit = matches!(&msg, Message::Notification(n) if n.is_exit());
 
-                debug!("sending message {:#?}", msg);
+                debug!("sending message {msg:#?}");
                 if let Err(e) = reader_sender.send(msg) {
                     return Err(io::Error::other(e));
                 }
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index bb7d83c..8cd5811 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -9,14 +9,14 @@
 [dependencies]
 anyhow.workspace = true
 directories = "6.0"
-flate2 = "1.1.0"
+flate2 = "1.1.2"
 write-json = "0.1.4"
 xshell.workspace = true
 xflags = "0.3.2"
 time = { version = "0.3", default-features = false }
-zip = { version = "3.0", default-features = false, features = ["deflate-flate2", "time"] }
+zip = { version = "4.0", default-features = false, features = ["deflate-flate2", "time"] }
 stdx.workspace = true
-proc-macro2 = "1.0.94"
+proc-macro2 = "1.0.95"
 quote = "1.0.40"
 ungrammar = "1.16.1"
 either.workspace = true