Auto merge of #130821 - lcnr:nalgebra-hang-2, r=compiler-errors

add caching to most type folders, rm region uniquification

Fixes the new minimization of the hang in nalgebra and nalgebra itself :3

this is a bit iffy, especially the cache in `TypeRelating`. I believe all the caches are correct, but it definitely adds some non-local complexity in places. The first commit removes region uniquification, reintroducing the ICE from https://github.com/rust-lang/trait-system-refactor-initiative/issues/27. This does not affect coherence and I would like to fix this by introducing OR-region constraints

r? `@compiler-errors`
diff --git a/.typos.toml b/.typos.toml
index e7e764c..febfb23 100644
--- a/.typos.toml
+++ b/.typos.toml
@@ -15,6 +15,7 @@
     '"flate2"',
     "raison d'être",
     "inout",
+    "INOUT",
     "optin"
 ]
 
diff --git a/Cargo.lock b/Cargo.lock
index 4e9319f..dc820fc 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -97,6 +97,15 @@
 checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
 
 [[package]]
+name = "borsh"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed"
+dependencies = [
+ "cfg_aliases 0.2.1",
+]
+
+[[package]]
 name = "byteorder"
 version = "1.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -168,6 +177,12 @@
 checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
 
 [[package]]
+name = "cfg_aliases"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
+
+[[package]]
 name = "chalk-derive"
 version = "0.98.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -982,7 +997,7 @@
 
 [[package]]
 name = "lsp-server"
-version = "0.7.6"
+version = "0.7.7"
 dependencies = [
  "crossbeam-channel",
  "ctrlc",
@@ -994,9 +1009,9 @@
 
 [[package]]
 name = "lsp-server"
-version = "0.7.6"
+version = "0.7.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "248f65b78f6db5d8e1b1604b4098a28b43d21a8eb1deeca22b1c421b276c7095"
+checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9"
 dependencies = [
  "crossbeam-channel",
  "log",
@@ -1029,8 +1044,10 @@
 dependencies = [
  "arrayvec",
  "cov-mark",
+ "expect-test",
  "intern",
  "parser",
+ "ra-ap-rustc_lexer",
  "rustc-hash",
  "smallvec",
  "span",
@@ -1113,7 +1130,7 @@
 dependencies = [
  "bitflags 2.6.0",
  "cfg-if",
- "cfg_aliases",
+ "cfg_aliases 0.1.1",
  "libc",
 ]
 
@@ -1468,9 +1485,9 @@
 
 [[package]]
 name = "ra-ap-rustc_abi"
-version = "0.63.0"
+version = "0.68.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b011c39d409940a890414e3a7b239762ac16d88029ad71b050a8374831b93790"
+checksum = "2a8cb51bb4534ac3e9c74f1d9bd90e607e60f94f734b1cf1a66f753ad2af6ed7"
 dependencies = [
  "bitflags 2.6.0",
  "ra-ap-rustc_index",
@@ -1479,9 +1496,9 @@
 
 [[package]]
 name = "ra-ap-rustc_index"
-version = "0.63.0"
+version = "0.68.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9027acdee649b0b27eb10b7db5be833efee3362d394935c5eed8f0745a9d43ce"
+checksum = "8b640fba2b7ef4f875459e2e76daeb846ef341d1d376fa758962ac0eba79bce6"
 dependencies = [
  "arrayvec",
  "ra-ap-rustc_index_macros",
@@ -1490,9 +1507,9 @@
 
 [[package]]
 name = "ra-ap-rustc_index_macros"
-version = "0.63.0"
+version = "0.68.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "540b86dc0384141ac8e825fc2874cd44bffd4277d99d8ec63ee416f1a98d5997"
+checksum = "faef502419ba5ac9d3079b1a835c6e5b4e605388254bbe55eb5683936f541be9"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1501,9 +1518,9 @@
 
 [[package]]
 name = "ra-ap-rustc_lexer"
-version = "0.63.0"
+version = "0.68.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3bdf98bb457b47b9ae4aeebf867d0ca440c86925e0b6381658c4a02589748c9d"
+checksum = "5da7f9d533b8d5be6704558da741ff20b982ad4647b1e9e08632853e4fecf9d5"
 dependencies = [
  "unicode-properties",
  "unicode-xid",
@@ -1511,9 +1528,9 @@
 
 [[package]]
 name = "ra-ap-rustc_parse_format"
-version = "0.63.0"
+version = "0.68.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8fe3556ab6311bb775220563a300e2bf62ec56404521fe0c511a583937683d5"
+checksum = "94389cf81c651b1bda9ac45d3de6a2d851bb6fd4cb893875daa44e419c94205f"
 dependencies = [
  "ra-ap-rustc_index",
  "ra-ap-rustc_lexer",
@@ -1521,9 +1538,9 @@
 
 [[package]]
 name = "ra-ap-rustc_pattern_analysis"
-version = "0.63.0"
+version = "0.68.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1709080fdeb5db630e1c2644026c2962aaa32416cd92f0190c04b0c21e114b91"
+checksum = "3679d8dd0114ed6000918309f843782738e51c99d8e4baec0d0f706e4d948819"
 dependencies = [
  "ra-ap-rustc_index",
  "rustc-hash",
@@ -1636,7 +1653,7 @@
  "intern",
  "itertools",
  "load-cargo",
- "lsp-server 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lsp-server 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "lsp-types",
  "memchr",
  "mimalloc",
@@ -1843,10 +1860,11 @@
 
 [[package]]
 name = "smol_str"
-version = "0.2.2"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
+checksum = "66eaf762c5af19db3108300515c8aa7a50efc90ff745f4c62288052ebf9fdd25"
 dependencies = [
+ "borsh",
  "serde",
 ]
 
@@ -2607,6 +2625,7 @@
 dependencies = [
  "anyhow",
  "directories",
+ "either",
  "flate2",
  "itertools",
  "proc-macro2",
diff --git a/Cargo.toml b/Cargo.toml
index aa7bd2d..b4587a3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -85,11 +85,11 @@
 vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
 vfs = { path = "./crates/vfs", version = "0.0.0" }
 
-ra-ap-rustc_lexer = { version = "0.63.0", default-features = false }
-ra-ap-rustc_parse_format = { version = "0.63.0", default-features = false }
-ra-ap-rustc_index = { version = "0.63.0", default-features = false }
-ra-ap-rustc_abi = { version = "0.63.0", default-features = false }
-ra-ap-rustc_pattern_analysis = { version = "0.63.0", default-features = false }
+ra-ap-rustc_lexer = { version = "0.68.0", default-features = false }
+ra-ap-rustc_parse_format = { version = "0.68.0", default-features = false }
+ra-ap-rustc_index = { version = "0.68.0", default-features = false }
+ra-ap-rustc_abi = { version = "0.68.0", default-features = false }
+ra-ap-rustc_pattern_analysis = { version = "0.68.0", default-features = false }
 
 # local crates that aren't published to crates.io. These should not have versions.
 test-fixture = { path = "./crates/test-fixture" }
@@ -145,7 +145,7 @@
   "union",
   "const_generics",
 ] }
-smol_str = "0.2.1"
+smol_str = "0.3.1"
 snap = "1.1.0"
 text-size = "1.1.1"
 tracing = "0.1.40"
@@ -185,6 +185,7 @@
 suspicious = { level = "warn", priority = -1 }
 
 ## allow following lints
+too_long_first_doc_paragraph = "allow"
 # subjective
 single_match = "allow"
 # () makes a fine error in most cases
diff --git a/crates/base-db/src/change.rs b/crates/base-db/src/change.rs
index a9d91d6..4fb6654 100644
--- a/crates/base-db/src/change.rs
+++ b/crates/base-db/src/change.rs
@@ -3,11 +3,15 @@
 
 use std::fmt;
 
+use rustc_hash::FxHashMap;
 use salsa::Durability;
 use triomphe::Arc;
 use vfs::FileId;
 
-use crate::{CrateGraph, SourceDatabaseFileInputExt, SourceRoot, SourceRootDatabase, SourceRootId};
+use crate::{
+    CrateGraph, CrateId, CrateWorkspaceData, SourceDatabaseFileInputExt, SourceRoot,
+    SourceRootDatabase, SourceRootId,
+};
 
 /// Encapsulate a bunch of raw `.set` calls on the database.
 #[derive(Default)]
@@ -15,6 +19,7 @@
     pub roots: Option<Vec<SourceRoot>>,
     pub files_changed: Vec<(FileId, Option<String>)>,
     pub crate_graph: Option<CrateGraph>,
+    pub ws_data: Option<FxHashMap<CrateId, Arc<CrateWorkspaceData>>>,
 }
 
 impl fmt::Debug for FileChange {
@@ -50,6 +55,10 @@
         self.crate_graph = Some(graph);
     }
 
+    pub fn set_ws_data(&mut self, data: FxHashMap<CrateId, Arc<CrateWorkspaceData>>) {
+        self.ws_data = Some(data);
+    }
+
     pub fn apply(self, db: &mut dyn SourceRootDatabase) {
         let _p = tracing::info_span!("FileChange::apply").entered();
         if let Some(roots) = self.roots {
@@ -74,6 +83,9 @@
         if let Some(crate_graph) = self.crate_graph {
             db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH);
         }
+        if let Some(data) = self.ws_data {
+            db.set_crate_workspace_data_with_durability(Arc::new(data), Durability::HIGH);
+        }
     }
 }
 
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index 3616fa9..f510933 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -374,37 +374,6 @@
         self.arena.alloc(data)
     }
 
-    /// Remove the crate from crate graph. If any crates depend on this crate, the dependency would be replaced
-    /// with the second input.
-    pub fn remove_and_replace(
-        &mut self,
-        id: CrateId,
-        replace_with: CrateId,
-    ) -> Result<(), CyclicDependenciesError> {
-        for (x, data) in self.arena.iter() {
-            if x == id {
-                continue;
-            }
-            for edge in &data.dependencies {
-                if edge.crate_id == id {
-                    self.check_cycle_after_dependency(edge.crate_id, replace_with)?;
-                }
-            }
-        }
-        // if everything was ok, start to replace
-        for (x, data) in self.arena.iter_mut() {
-            if x == id {
-                continue;
-            }
-            for edge in &mut data.dependencies {
-                if edge.crate_id == id {
-                    edge.crate_id = replace_with;
-                }
-            }
-        }
-        Ok(())
-    }
-
     pub fn add_dep(
         &mut self,
         from: CrateId,
@@ -412,26 +381,17 @@
     ) -> Result<(), CyclicDependenciesError> {
         let _p = tracing::info_span!("add_dep").entered();
 
-        self.check_cycle_after_dependency(from, dep.crate_id)?;
-
-        self.arena[from].add_dep(dep);
-        Ok(())
-    }
-
-    /// Check if adding a dep from `from` to `to` creates a cycle. To figure
-    /// that out, look for a  path in the *opposite* direction, from `to` to
-    /// `from`.
-    fn check_cycle_after_dependency(
-        &self,
-        from: CrateId,
-        to: CrateId,
-    ) -> Result<(), CyclicDependenciesError> {
-        if let Some(path) = self.find_path(&mut FxHashSet::default(), to, from) {
+        // Check if adding a dep from `from` to `to` creates a cycle. To figure
+        // that out, look for a  path in the *opposite* direction, from `to` to
+        // `from`.
+        if let Some(path) = self.find_path(&mut FxHashSet::default(), dep.crate_id, from) {
             let path = path.into_iter().map(|it| (it, self[it].display_name.clone())).collect();
             let err = CyclicDependenciesError { path };
-            assert!(err.from().0 == from && err.to().0 == to);
+            assert!(err.from().0 == from && err.to().0 == dep.crate_id);
             return Err(err);
         }
+
+        self.arena[from].add_dep(dep);
         Ok(())
     }
 
@@ -531,22 +491,15 @@
             .for_each(|(_, data)| data.dependencies.sort_by_key(|dep| dep.crate_id));
     }
 
-    /// Extends this crate graph by adding a complete disjoint second crate
+    /// Extends this crate graph by adding a complete second crate
     /// graph and adjust the ids in the [`ProcMacroPaths`] accordingly.
     ///
-    /// This will deduplicate the crates of the graph where possible.
-    /// Note that for deduplication to fully work, `self`'s crate dependencies must be sorted by crate id.
-    /// If the crate dependencies were sorted, the resulting graph from this `extend` call will also
-    /// have the crate dependencies sorted.
-    ///
-    /// Returns a mapping from `other`'s crate ids to the new crate ids in `self`.
+    /// Returns a map mapping `other`'s IDs to the new IDs in `self`.
     pub fn extend(
         &mut self,
         mut other: CrateGraph,
         proc_macros: &mut ProcMacroPaths,
-        merge: impl Fn((CrateId, &mut CrateData), (CrateId, &CrateData)) -> bool,
     ) -> FxHashMap<CrateId, CrateId> {
-        let m = self.len();
         let topo = other.crates_in_topological_order();
         let mut id_map: FxHashMap<CrateId, CrateId> = FxHashMap::default();
         for topo in topo {
@@ -554,20 +507,13 @@
 
             crate_data.dependencies.iter_mut().for_each(|dep| dep.crate_id = id_map[&dep.crate_id]);
             crate_data.dependencies.sort_by_key(|dep| dep.crate_id);
-            let res = self
-                .arena
-                .iter_mut()
-                .take(m)
-                .find_map(|(id, data)| merge((id, data), (topo, crate_data)).then_some(id));
 
-            let new_id =
-                if let Some(res) = res { res } else { self.arena.alloc(crate_data.clone()) };
+            let new_id = self.arena.alloc(crate_data.clone());
             id_map.insert(topo, new_id);
         }
 
         *proc_macros =
             mem::take(proc_macros).into_iter().map(|(id, macros)| (id_map[&id], macros)).collect();
-
         id_map
     }
 
diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs
index 20ef45d..46e258d 100644
--- a/crates/base-db/src/lib.rs
+++ b/crates/base-db/src/lib.rs
@@ -5,11 +5,12 @@
 
 use std::panic;
 
+use rustc_hash::FxHashMap;
 use salsa::Durability;
 use span::EditionedFileId;
 use syntax::{ast, Parse, SourceFile, SyntaxError};
 use triomphe::Arc;
-use vfs::FileId;
+use vfs::{AbsPathBuf, FileId};
 
 pub use crate::{
     change::FileChange,
@@ -74,19 +75,30 @@
     #[salsa::input]
     fn crate_graph(&self) -> Arc<CrateGraph>;
 
-    // FIXME: Consider removing this, making HirDatabase::target_data_layout an input query
     #[salsa::input]
-    fn data_layout(&self, krate: CrateId) -> TargetLayoutLoadResult;
-
-    #[salsa::input]
-    fn toolchain(&self, krate: CrateId) -> Option<Version>;
+    fn crate_workspace_data(&self) -> Arc<FxHashMap<CrateId, Arc<CrateWorkspaceData>>>;
 
     #[salsa::transparent]
     fn toolchain_channel(&self, krate: CrateId) -> Option<ReleaseChannel>;
 }
 
+/// Crate related data shared by the whole workspace.
+#[derive(Debug, PartialEq, Eq, Hash, Clone)]
+pub struct CrateWorkspaceData {
+    /// The working directory to run proc-macros in. This is usually the workspace root of cargo workspaces.
+    pub proc_macro_cwd: Option<AbsPathBuf>,
+    // FIXME: Consider removing this, making HirDatabase::target_data_layout an input query
+    pub data_layout: TargetLayoutLoadResult,
+    /// Toolchain version used to compile the crate.
+    pub toolchain: Option<Version>,
+}
+
 fn toolchain_channel(db: &dyn SourceDatabase, krate: CrateId) -> Option<ReleaseChannel> {
-    db.toolchain(krate).as_ref().and_then(|v| ReleaseChannel::from_str(&v.pre))
+    db.crate_workspace_data()
+        .get(&krate)?
+        .toolchain
+        .as_ref()
+        .and_then(|v| ReleaseChannel::from_str(&v.pre))
 }
 
 fn parse(db: &dyn SourceDatabase, file_id: EditionedFileId) -> Parse<ast::SourceFile> {
diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs
index dde1f14..9535b5a 100644
--- a/crates/hir-def/src/body.rs
+++ b/crates/hir-def/src/body.rs
@@ -100,7 +100,14 @@
     field_map_back: FxHashMap<ExprId, FieldSource>,
     pat_field_map_back: FxHashMap<PatId, PatFieldSource>,
 
-    format_args_template_map: FxHashMap<ExprId, Vec<(syntax::TextRange, Name)>>,
+    template_map: Option<
+        Box<(
+            // format_args!
+            FxHashMap<ExprId, Vec<(syntax::TextRange, Name)>>,
+            // asm!
+            FxHashMap<ExprId, Vec<Vec<(syntax::TextRange, usize)>>>,
+        )>,
+    >,
 
     expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, MacroFileId>,
 
@@ -220,6 +227,17 @@
         pretty::print_expr_hir(db, self, owner, expr, edition)
     }
 
+    pub fn pretty_print_pat(
+        &self,
+        db: &dyn DefDatabase,
+        owner: DefWithBodyId,
+        pat: PatId,
+        oneline: bool,
+        edition: Edition,
+    ) -> String {
+        pretty::print_pat_hir(db, self, owner, pat, oneline, edition)
+    }
+
     fn new(
         db: &dyn DefDatabase,
         owner: DefWithBodyId,
@@ -426,7 +444,16 @@
         node: InFile<&ast::FormatArgsExpr>,
     ) -> Option<&[(syntax::TextRange, Name)]> {
         let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>);
-        self.format_args_template_map.get(self.expr_map.get(&src)?).map(std::ops::Deref::deref)
+        self.template_map.as_ref()?.0.get(self.expr_map.get(&src)?).map(std::ops::Deref::deref)
+    }
+
+    pub fn asm_template_args(
+        &self,
+        node: InFile<&ast::AsmExpr>,
+    ) -> Option<(ExprId, &[Vec<(syntax::TextRange, usize)>])> {
+        let src = node.map(AstPtr::new).map(AstPtr::upcast::<ast::Expr>);
+        let expr = self.expr_map.get(&src)?;
+        Some(*expr).zip(self.template_map.as_ref()?.1.get(expr).map(std::ops::Deref::deref))
     }
 
     /// Get a reference to the body source map's diagnostics.
@@ -446,11 +473,14 @@
             field_map_back,
             pat_field_map_back,
             expansions,
-            format_args_template_map,
+            template_map,
             diagnostics,
             binding_definitions,
         } = self;
-        format_args_template_map.shrink_to_fit();
+        if let Some(template_map) = template_map {
+            template_map.0.shrink_to_fit();
+            template_map.1.shrink_to_fit();
+        }
         expr_map.shrink_to_fit();
         expr_map_back.shrink_to_fit();
         pat_map.shrink_to_fit();
@@ -463,4 +493,13 @@
         diagnostics.shrink_to_fit();
         binding_definitions.shrink_to_fit();
     }
+
+    pub fn template_map(
+        &self,
+    ) -> Option<&(
+        FxHashMap<Idx<Expr>, Vec<(tt::TextRange, Name)>>,
+        FxHashMap<Idx<Expr>, Vec<Vec<(tt::TextRange, usize)>>>,
+    )> {
+        self.template_map.as_deref()
+    }
 }
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index abf7895..9c54757 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -1,6 +1,8 @@
 //! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr`
 //! representation.
 
+mod asm;
+
 use std::mem;
 
 use base_db::CrateId;
@@ -35,8 +37,8 @@
             FormatPlaceholder, FormatSign, FormatTrait,
         },
         Array, Binding, BindingAnnotation, BindingId, BindingProblems, CaptureBy, ClosureKind,
-        Expr, ExprId, InlineAsm, Label, LabelId, Literal, LiteralOrConst, MatchArm, Movability,
-        OffsetOf, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
+        Expr, ExprId, Label, LabelId, Literal, LiteralOrConst, MatchArm, Movability, OffsetOf, Pat,
+        PatId, RecordFieldPat, RecordLitField, Statement,
     },
     item_scope::BuiltinShadowMode,
     lang_item::LangItem,
@@ -693,10 +695,7 @@
                 }
             }
             ast::Expr::UnderscoreExpr(_) => self.alloc_expr(Expr::Underscore, syntax_ptr),
-            ast::Expr::AsmExpr(e) => {
-                let e = self.collect_expr_opt(e.expr());
-                self.alloc_expr(Expr::InlineAsm(InlineAsm { e }), syntax_ptr)
-            }
+            ast::Expr::AsmExpr(e) => self.lower_inline_asm(e, syntax_ptr),
             ast::Expr::OffsetOfExpr(e) => {
                 let container = Interned::new(TypeRef::from_ast_opt(&self.ctx(), e.ty()));
                 let fields = e.fields().map(|it| it.as_name()).collect();
@@ -737,7 +736,7 @@
     /// `try { <stmts>; }` into `'<new_label>: { <stmts>; ::std::ops::Try::from_output(()) }`
     /// and save the `<new_label>` to use it as a break target for desugaring of the `?` operator.
     fn desugar_try_block(&mut self, e: BlockExpr) -> ExprId {
-        let Some(try_from_output) = LangItem::TryTraitFromOutput.path(self.db, self.krate) else {
+        let Some(try_from_output) = self.lang_path(LangItem::TryTraitFromOutput) else {
             return self.collect_block(e);
         };
         let label = self
@@ -840,10 +839,10 @@
     fn collect_for_loop(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::ForExpr) -> ExprId {
         let Some((into_iter_fn, iter_next_fn, option_some, option_none)) = (|| {
             Some((
-                LangItem::IntoIterIntoIter.path(self.db, self.krate)?,
-                LangItem::IteratorNext.path(self.db, self.krate)?,
-                LangItem::OptionSome.path(self.db, self.krate)?,
-                LangItem::OptionNone.path(self.db, self.krate)?,
+                self.lang_path(LangItem::IntoIterIntoIter)?,
+                self.lang_path(LangItem::IteratorNext)?,
+                self.lang_path(LangItem::OptionSome)?,
+                self.lang_path(LangItem::OptionNone)?,
             ))
         })() else {
             // Some of the needed lang items are missing, so we can't desugar
@@ -896,6 +895,15 @@
             Expr::Match { expr: iter_next_expr, arms: Box::new([none_arm, some_arm]) },
             syntax_ptr,
         );
+        let loop_inner = self.alloc_expr(
+            Expr::Block {
+                id: None,
+                statements: Box::default(),
+                tail: Some(loop_inner),
+                label: None,
+            },
+            syntax_ptr,
+        );
         let loop_outer = self.alloc_expr(Expr::Loop { body: loop_inner, label }, syntax_ptr);
         let iter_binding = self.alloc_binding(iter_name, BindingAnnotation::Mutable);
         let iter_pat = self.alloc_pat_desugared(Pat::Bind { id: iter_binding, subpat: None });
@@ -923,10 +931,10 @@
     fn collect_try_operator(&mut self, syntax_ptr: AstPtr<ast::Expr>, e: ast::TryExpr) -> ExprId {
         let Some((try_branch, cf_continue, cf_break, try_from_residual)) = (|| {
             Some((
-                LangItem::TryTraitBranch.path(self.db, self.krate)?,
-                LangItem::ControlFlowContinue.path(self.db, self.krate)?,
-                LangItem::ControlFlowBreak.path(self.db, self.krate)?,
-                LangItem::TryTraitFromResidual.path(self.db, self.krate)?,
+                self.lang_path(LangItem::TryTraitBranch)?,
+                self.lang_path(LangItem::ControlFlowContinue)?,
+                self.lang_path(LangItem::ControlFlowBreak)?,
+                self.lang_path(LangItem::TryTraitFromResidual)?,
             ))
         })() else {
             // Some of the needed lang items are missing, so we can't desugar
@@ -1839,7 +1847,7 @@
             },
             syntax_ptr,
         );
-        self.source_map.format_args_template_map.insert(idx, mappings);
+        self.source_map.template_map.get_or_insert_with(Default::default).0.insert(idx, mappings);
         idx
     }
 
@@ -2052,7 +2060,12 @@
             is_assignee_expr: false,
         })
     }
+
     // endregion: format
+
+    fn lang_path(&self, lang: LangItem) -> Option<Path> {
+        lang.path(self.db, self.krate)
+    }
 }
 
 fn pat_literal_to_hir(lit: &ast::LiteralPat) -> Option<(Literal, ast::Literal)> {
diff --git a/crates/hir-def/src/body/lower/asm.rs b/crates/hir-def/src/body/lower/asm.rs
new file mode 100644
index 0000000..4213370
--- /dev/null
+++ b/crates/hir-def/src/body/lower/asm.rs
@@ -0,0 +1,276 @@
+//! Lowering of inline assembly.
+use hir_expand::name::Name;
+use intern::Symbol;
+use rustc_hash::{FxHashMap, FxHashSet};
+use syntax::{
+    ast::{self, HasName, IsString},
+    AstNode, AstPtr, AstToken, T,
+};
+use tt::{TextRange, TextSize};
+
+use crate::{
+    body::lower::{ExprCollector, FxIndexSet},
+    hir::{AsmOperand, AsmOptions, Expr, ExprId, InlineAsm, InlineAsmRegOrRegClass},
+};
+
+impl ExprCollector<'_> {
+    pub(super) fn lower_inline_asm(
+        &mut self,
+        asm: ast::AsmExpr,
+        syntax_ptr: AstPtr<ast::Expr>,
+    ) -> ExprId {
+        let mut clobber_abis = FxIndexSet::default();
+        let mut operands = vec![];
+        let mut options = AsmOptions::empty();
+
+        let mut named_pos: FxHashMap<usize, Symbol> = Default::default();
+        let mut named_args: FxHashMap<Symbol, usize> = Default::default();
+        let mut reg_args: FxHashSet<usize> = Default::default();
+        for piece in asm.asm_pieces() {
+            let slot = operands.len();
+            let mut lower_reg = |reg: Option<ast::AsmRegSpec>| {
+                let reg = reg?;
+                if let Some(string) = reg.string_token() {
+                    reg_args.insert(slot);
+                    Some(InlineAsmRegOrRegClass::Reg(Symbol::intern(string.text())))
+                } else {
+                    reg.name_ref().map(|name_ref| {
+                        InlineAsmRegOrRegClass::RegClass(Symbol::intern(&name_ref.text()))
+                    })
+                }
+            };
+
+            let op = match piece {
+                ast::AsmPiece::AsmClobberAbi(clobber_abi) => {
+                    if let Some(abi_name) = clobber_abi.string_token() {
+                        clobber_abis.insert(Symbol::intern(abi_name.text()));
+                    }
+                    continue;
+                }
+                ast::AsmPiece::AsmOptions(opt) => {
+                    opt.asm_options().for_each(|opt| {
+                        options |= match opt.syntax().first_token().map_or(T![$], |it| it.kind()) {
+                            T![att_syntax] => AsmOptions::ATT_SYNTAX,
+                            T![may_unwind] => AsmOptions::MAY_UNWIND,
+                            T![nomem] => AsmOptions::NOMEM,
+                            T![noreturn] => AsmOptions::NORETURN,
+                            T![nostack] => AsmOptions::NOSTACK,
+                            T![preserves_flags] => AsmOptions::PRESERVES_FLAGS,
+                            T![pure] => AsmOptions::PURE,
+                            T![raw] => AsmOptions::RAW,
+                            T![readonly] => AsmOptions::READONLY,
+                            _ => return,
+                        }
+                    });
+                    continue;
+                }
+                ast::AsmPiece::AsmOperandNamed(op) => {
+                    let name = op.name().map(|name| Symbol::intern(&name.text()));
+                    if let Some(name) = &name {
+                        named_args.insert(name.clone(), slot);
+                        named_pos.insert(slot, name.clone());
+                    }
+                    let Some(op) = op.asm_operand() else { continue };
+                    (
+                        name.map(Name::new_symbol_root),
+                        match op {
+                            ast::AsmOperand::AsmRegOperand(op) => {
+                                let Some(dir_spec) = op.asm_dir_spec() else {
+                                    continue;
+                                };
+                                let Some(reg) = lower_reg(op.asm_reg_spec()) else {
+                                    continue;
+                                };
+                                if dir_spec.in_token().is_some() {
+                                    let expr = self.collect_expr_opt(
+                                        op.asm_operand_expr().and_then(|it| it.in_expr()),
+                                    );
+                                    AsmOperand::In { reg, expr }
+                                } else if dir_spec.out_token().is_some() {
+                                    let expr = op
+                                        .asm_operand_expr()
+                                        .and_then(|it| it.in_expr())
+                                        .filter(|it| !matches!(it, ast::Expr::UnderscoreExpr(_)))
+                                        .map(|expr| self.collect_expr(expr));
+                                    AsmOperand::Out { reg, expr, late: false }
+                                } else if dir_spec.lateout_token().is_some() {
+                                    let expr = op
+                                        .asm_operand_expr()
+                                        .and_then(|it| it.in_expr())
+                                        .filter(|it| !matches!(it, ast::Expr::UnderscoreExpr(_)))
+                                        .map(|expr| self.collect_expr(expr));
+
+                                    AsmOperand::Out { reg, expr, late: true }
+                                } else if dir_spec.inout_token().is_some() {
+                                    let Some(op_expr) = op.asm_operand_expr() else { continue };
+                                    let in_expr = self.collect_expr_opt(op_expr.in_expr());
+                                    match op_expr.fat_arrow_token().is_some() {
+                                        true => {
+                                            let out_expr = op_expr
+                                                .out_expr()
+                                                .filter(|it| {
+                                                    !matches!(it, ast::Expr::UnderscoreExpr(_))
+                                                })
+                                                .map(|expr| self.collect_expr(expr));
+
+                                            AsmOperand::SplitInOut {
+                                                reg,
+                                                in_expr,
+                                                out_expr,
+                                                late: false,
+                                            }
+                                        }
+                                        false => {
+                                            AsmOperand::InOut { reg, expr: in_expr, late: false }
+                                        }
+                                    }
+                                } else if dir_spec.inlateout_token().is_some() {
+                                    let Some(op_expr) = op.asm_operand_expr() else { continue };
+                                    let in_expr = self.collect_expr_opt(op_expr.in_expr());
+                                    match op_expr.fat_arrow_token().is_some() {
+                                        true => {
+                                            let out_expr = op_expr
+                                                .out_expr()
+                                                .filter(|it| {
+                                                    !matches!(it, ast::Expr::UnderscoreExpr(_))
+                                                })
+                                                .map(|expr| self.collect_expr(expr));
+
+                                            AsmOperand::SplitInOut {
+                                                reg,
+                                                in_expr,
+                                                out_expr,
+                                                late: true,
+                                            }
+                                        }
+                                        false => {
+                                            AsmOperand::InOut { reg, expr: in_expr, late: true }
+                                        }
+                                    }
+                                } else {
+                                    continue;
+                                }
+                            }
+                            ast::AsmOperand::AsmLabel(l) => {
+                                AsmOperand::Label(self.collect_block_opt(l.block_expr()))
+                            }
+                            ast::AsmOperand::AsmConst(c) => {
+                                AsmOperand::Const(self.collect_expr_opt(c.expr()))
+                            }
+                            ast::AsmOperand::AsmSym(s) => {
+                                let Some(path) =
+                                    s.path().and_then(|p| self.expander.parse_path(self.db, p))
+                                else {
+                                    continue;
+                                };
+                                AsmOperand::Sym(path)
+                            }
+                        },
+                    )
+                }
+            };
+            operands.push(op);
+        }
+
+        let mut mappings = vec![];
+        let mut curarg = 0;
+        if !options.contains(AsmOptions::RAW) {
+            // Don't treat raw asm as a format string.
+            asm.template()
+                .enumerate()
+                .filter_map(|(idx, it)| Some((idx, it.clone(), self.expand_macros_to_string(it)?)))
+                .for_each(|(idx, expr, (s, is_direct_literal))| {
+                    mappings.resize_with(idx + 1, Vec::default);
+                    let Ok(text) = s.value() else {
+                        return;
+                    };
+                    let mappings = &mut mappings[idx];
+                    let template_snippet = match expr {
+                        ast::Expr::Literal(literal) => match literal.kind() {
+                            ast::LiteralKind::String(s) => Some(s.text().to_owned()),
+                            _ => None,
+                        },
+                        _ => None,
+                    };
+                    let str_style = match s.quote_offsets() {
+                        Some(offsets) => {
+                            let raw = usize::from(offsets.quotes.0.len()) - 1;
+                            // subtract 1 for the `r` prefix
+                            (raw != 0).then(|| raw - 1)
+                        }
+                        None => None,
+                    };
+
+                    let mut parser = rustc_parse_format::Parser::new(
+                        &text,
+                        str_style,
+                        template_snippet,
+                        false,
+                        rustc_parse_format::ParseMode::InlineAsm,
+                    );
+                    parser.curarg = curarg;
+
+                    let mut unverified_pieces = Vec::new();
+                    while let Some(piece) = parser.next() {
+                        if !parser.errors.is_empty() {
+                            break;
+                        } else {
+                            unverified_pieces.push(piece);
+                        }
+                    }
+
+                    curarg = parser.curarg;
+
+                    let to_span = |inner_span: rustc_parse_format::InnerSpan| {
+                        is_direct_literal.then(|| {
+                            TextRange::new(
+                                inner_span.start.try_into().unwrap(),
+                                inner_span.end.try_into().unwrap(),
+                            ) - TextSize::from(str_style.map(|it| it + 1).unwrap_or(0) as u32 + 1)
+                        })
+                    };
+                    for piece in unverified_pieces {
+                        match piece {
+                            rustc_parse_format::Piece::String(_) => {}
+                            rustc_parse_format::Piece::NextArgument(arg) => {
+                                // let span = arg_spans.next();
+
+                                let (operand_idx, _name) = match arg.position {
+                                    rustc_parse_format::ArgumentIs(idx)
+                                    | rustc_parse_format::ArgumentImplicitlyIs(idx) => {
+                                        if idx >= operands.len()
+                                            || named_pos.contains_key(&idx)
+                                            || reg_args.contains(&idx)
+                                        {
+                                            (None, None)
+                                        } else {
+                                            (Some(idx), None)
+                                        }
+                                    }
+                                    rustc_parse_format::ArgumentNamed(name) => {
+                                        let name = Symbol::intern(name);
+                                        (
+                                            named_args.get(&name).copied(),
+                                            Some(Name::new_symbol_root(name)),
+                                        )
+                                    }
+                                };
+
+                                if let Some(operand_idx) = operand_idx {
+                                    if let Some(position_span) = to_span(arg.position_span) {
+                                        mappings.push((position_span, operand_idx));
+                                    }
+                                }
+                            }
+                        }
+                    }
+                })
+        };
+        let idx = self.alloc_expr(
+            Expr::InlineAsm(InlineAsm { operands: operands.into_boxed_slice(), options }),
+            syntax_ptr,
+        );
+        self.source_map.template_map.get_or_insert_with(Default::default).1.insert(idx, mappings);
+        idx
+    }
+}
diff --git a/crates/hir-def/src/body/pretty.rs b/crates/hir-def/src/body/pretty.rs
index 55740a6..37167fc 100644
--- a/crates/hir-def/src/body/pretty.rs
+++ b/crates/hir-def/src/body/pretty.rs
@@ -16,6 +16,13 @@
 
 use super::*;
 
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub(super) enum LineFormat {
+    Oneline,
+    Newline,
+    Indentation,
+}
+
 pub(super) fn print_body_hir(
     db: &dyn DefDatabase,
     body: &Body,
@@ -52,7 +59,14 @@
         }
     };
 
-    let mut p = Printer { db, body, buf: header, indent_level: 0, needs_indent: false, edition };
+    let mut p = Printer {
+        db,
+        body,
+        buf: header,
+        indent_level: 0,
+        line_format: LineFormat::Newline,
+        edition,
+    };
     if let DefWithBodyId::FunctionId(it) = owner {
         p.buf.push('(');
         let function_data = &db.function_data(it);
@@ -95,12 +109,38 @@
     expr: ExprId,
     edition: Edition,
 ) -> String {
-    let mut p =
-        Printer { db, body, buf: String::new(), indent_level: 0, needs_indent: false, edition };
+    let mut p = Printer {
+        db,
+        body,
+        buf: String::new(),
+        indent_level: 0,
+        line_format: LineFormat::Newline,
+        edition,
+    };
     p.print_expr(expr);
     p.buf
 }
 
+pub(super) fn print_pat_hir(
+    db: &dyn DefDatabase,
+    body: &Body,
+    _owner: DefWithBodyId,
+    pat: PatId,
+    oneline: bool,
+    edition: Edition,
+) -> String {
+    let mut p = Printer {
+        db,
+        body,
+        buf: String::new(),
+        indent_level: 0,
+        line_format: if oneline { LineFormat::Oneline } else { LineFormat::Newline },
+        edition,
+    };
+    p.print_pat(pat);
+    p.buf
+}
+
 macro_rules! w {
     ($dst:expr, $($arg:tt)*) => {
         { let _ = write!($dst, $($arg)*); }
@@ -109,10 +149,10 @@
 
 macro_rules! wln {
     ($dst:expr) => {
-        { let _ = writeln!($dst); }
+        { $dst.newline(); }
     };
     ($dst:expr, $($arg:tt)*) => {
-        { let _ = writeln!($dst, $($arg)*); }
+        { let _ = w!($dst, $($arg)*); $dst.newline(); }
     };
 }
 
@@ -121,24 +161,30 @@
     body: &'a Body,
     buf: String,
     indent_level: usize,
-    needs_indent: bool,
+    line_format: LineFormat,
     edition: Edition,
 }
 
 impl Write for Printer<'_> {
     fn write_str(&mut self, s: &str) -> fmt::Result {
         for line in s.split_inclusive('\n') {
-            if self.needs_indent {
+            if matches!(self.line_format, LineFormat::Indentation) {
                 match self.buf.chars().rev().find(|ch| *ch != ' ') {
                     Some('\n') | None => {}
                     _ => self.buf.push('\n'),
                 }
                 self.buf.push_str(&"    ".repeat(self.indent_level));
-                self.needs_indent = false;
             }
 
             self.buf.push_str(line);
-            self.needs_indent = line.ends_with('\n');
+
+            if matches!(self.line_format, LineFormat::Newline | LineFormat::Indentation) {
+                self.line_format = if line.ends_with('\n') {
+                    LineFormat::Indentation
+                } else {
+                    LineFormat::Newline
+                };
+            }
         }
 
         Ok(())
@@ -161,14 +207,28 @@
         }
     }
 
+    // Add a newline if the current line is not empty.
+    // If the current line is empty, add a space instead.
+    //
+    // Do not use [`writeln!()`] or [`wln!()`] here, which will result in
+    // infinite recursive calls to this function.
     fn newline(&mut self) {
-        match self.buf.chars().rev().find_position(|ch| *ch != ' ') {
-            Some((_, '\n')) | None => {}
-            Some((idx, _)) => {
-                if idx != 0 {
-                    self.buf.drain(self.buf.len() - idx..);
+        if matches!(self.line_format, LineFormat::Oneline) {
+            match self.buf.chars().last() {
+                Some(' ') | None => {}
+                Some(_) => {
+                    w!(self, " ");
                 }
-                writeln!(self).unwrap()
+            }
+        } else {
+            match self.buf.chars().rev().find_position(|ch| *ch != ' ') {
+                Some((_, '\n')) | None => {}
+                Some((idx, _)) => {
+                    if idx != 0 {
+                        self.buf.drain(self.buf.len() - idx..);
+                    }
+                    w!(self, "\n");
+                }
             }
         }
     }
@@ -539,12 +599,14 @@
                 w!(self, ")");
             }
             Pat::Or(pats) => {
+                w!(self, "(");
                 for (i, pat) in pats.iter().enumerate() {
                     if i != 0 {
                         w!(self, " | ");
                     }
                     self.print_pat(*pat);
                 }
+                w!(self, ")");
             }
             Pat::Record { path, args, ellipsis } => {
                 match path {
@@ -554,12 +616,37 @@
 
                 w!(self, " {{");
                 let edition = self.edition;
+                let oneline = matches!(self.line_format, LineFormat::Oneline);
                 self.indented(|p| {
-                    for arg in args.iter() {
-                        w!(p, "{}: ", arg.name.display(self.db.upcast(), edition));
-                        p.print_pat(arg.pat);
-                        wln!(p, ",");
+                    for (idx, arg) in args.iter().enumerate() {
+                        let field_name = arg.name.display(self.db.upcast(), edition).to_string();
+
+                        let mut same_name = false;
+                        if let Pat::Bind { id, subpat: None } = &self.body[arg.pat] {
+                            if let Binding { name, mode: BindingAnnotation::Unannotated, .. } =
+                                &self.body.bindings[*id]
+                            {
+                                if name.as_str() == field_name {
+                                    same_name = true;
+                                }
+                            }
+                        }
+
+                        w!(p, "{}", field_name);
+
+                        if !same_name {
+                            w!(p, ": ");
+                            p.print_pat(arg.pat);
+                        }
+
+                        // Do not print the extra comma if the line format is oneline
+                        if oneline && idx == args.len() - 1 {
+                            w!(p, " ");
+                        } else {
+                            wln!(p, ",");
+                        }
                     }
+
                     if *ellipsis {
                         wln!(p, "..");
                     }
diff --git a/crates/hir-def/src/body/tests.rs b/crates/hir-def/src/body/tests.rs
index 38fc01d..dd3e79c 100644
--- a/crates/hir-def/src/body/tests.rs
+++ b/crates/hir-def/src/body/tests.rs
@@ -143,6 +143,41 @@
 }
 
 #[test]
+fn desugar_for_loop() {
+    let (db, body, def) = lower(
+        r#"
+//- minicore: iterator
+fn main() {
+    for ident in 0..10 {
+        foo();
+        bar()
+    }
+}
+"#,
+    );
+
+    expect![[r#"
+        fn main() -> () {
+            match builtin#lang(into_iter)(
+                (0) ..(10) ,
+            ) {
+                mut <ra@gennew>11 => loop {
+                    match builtin#lang(next)(
+                        &mut <ra@gennew>11,
+                    ) {
+                        builtin#lang(None) => break,
+                        builtin#lang(Some)(ident) => {
+                            foo();
+                            bar()
+                        },
+                    }
+                },
+            }
+        }"#]]
+    .assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
+}
+
+#[test]
 fn desugar_builtin_format_args() {
     let (db, body, def) = lower(
         r#"
diff --git a/crates/hir-def/src/data/adt.rs b/crates/hir-def/src/data/adt.rs
index a70710e..ba54451 100644
--- a/crates/hir-def/src/data/adt.rs
+++ b/crates/hir-def/src/data/adt.rs
@@ -14,6 +14,7 @@
 use crate::{
     builtin_type::{BuiltinInt, BuiltinUint},
     db::DefDatabase,
+    hir::Expr,
     item_tree::{
         AttrOwner, Field, FieldParent, FieldsShape, ItemTree, ModItem, RawVisibilityId, TreeId,
     },
@@ -317,6 +318,27 @@
             _ => IntegerType::Pointer(true),
         }
     }
+
+    // [Adopted from rustc](https://github.com/rust-lang/rust/blob/bd53aa3bf7a24a70d763182303bd75e5fc51a9af/compiler/rustc_middle/src/ty/adt.rs#L446-L448)
+    pub fn is_payload_free(&self, db: &dyn DefDatabase) -> bool {
+        self.variants.iter().all(|(v, _)| {
+            // The condition check order is slightly modified from rustc
+            // to improve performance by early returning with relatively fast checks
+            let variant = &db.enum_variant_data(*v).variant_data;
+            if !variant.fields().is_empty() {
+                return false;
+            }
+            // The outer if condition is whether this variant has const ctor or not
+            if !matches!(variant.kind(), StructKind::Unit) {
+                let body = db.body((*v).into());
+                // A variant with explicit discriminant
+                if body.exprs[body.body_expr] != Expr::Missing {
+                    return false;
+                }
+            }
+            true
+        })
+    }
 }
 
 impl EnumVariantData {
diff --git a/crates/hir-def/src/hir.rs b/crates/hir-def/src/hir.rs
index 86fd092..d9358a2 100644
--- a/crates/hir-def/src/hir.rs
+++ b/crates/hir-def/src/hir.rs
@@ -307,7 +307,120 @@
 
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct InlineAsm {
-    pub e: ExprId,
+    pub operands: Box<[(Option<Name>, AsmOperand)]>,
+    pub options: AsmOptions,
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub struct AsmOptions(u16);
+bitflags::bitflags! {
+    impl AsmOptions: u16 {
+        const PURE            = 1 << 0;
+        const NOMEM           = 1 << 1;
+        const READONLY        = 1 << 2;
+        const PRESERVES_FLAGS = 1 << 3;
+        const NORETURN        = 1 << 4;
+        const NOSTACK         = 1 << 5;
+        const ATT_SYNTAX      = 1 << 6;
+        const RAW             = 1 << 7;
+        const MAY_UNWIND      = 1 << 8;
+    }
+}
+
+impl AsmOptions {
+    pub const COUNT: usize = Self::all().bits().count_ones() as usize;
+
+    pub const GLOBAL_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW);
+    pub const NAKED_OPTIONS: Self = Self::ATT_SYNTAX.union(Self::RAW).union(Self::NORETURN);
+
+    pub fn human_readable_names(&self) -> Vec<&'static str> {
+        let mut options = vec![];
+
+        if self.contains(AsmOptions::PURE) {
+            options.push("pure");
+        }
+        if self.contains(AsmOptions::NOMEM) {
+            options.push("nomem");
+        }
+        if self.contains(AsmOptions::READONLY) {
+            options.push("readonly");
+        }
+        if self.contains(AsmOptions::PRESERVES_FLAGS) {
+            options.push("preserves_flags");
+        }
+        if self.contains(AsmOptions::NORETURN) {
+            options.push("noreturn");
+        }
+        if self.contains(AsmOptions::NOSTACK) {
+            options.push("nostack");
+        }
+        if self.contains(AsmOptions::ATT_SYNTAX) {
+            options.push("att_syntax");
+        }
+        if self.contains(AsmOptions::RAW) {
+            options.push("raw");
+        }
+        if self.contains(AsmOptions::MAY_UNWIND) {
+            options.push("may_unwind");
+        }
+
+        options
+    }
+}
+
+impl std::fmt::Debug for AsmOptions {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        bitflags::parser::to_writer(self, f)
+    }
+}
+
+#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+pub enum AsmOperand {
+    In {
+        reg: InlineAsmRegOrRegClass,
+        expr: ExprId,
+    },
+    Out {
+        reg: InlineAsmRegOrRegClass,
+        expr: Option<ExprId>,
+        late: bool,
+    },
+    InOut {
+        reg: InlineAsmRegOrRegClass,
+        expr: ExprId,
+        late: bool,
+    },
+    SplitInOut {
+        reg: InlineAsmRegOrRegClass,
+        in_expr: ExprId,
+        out_expr: Option<ExprId>,
+        late: bool,
+    },
+    Label(ExprId),
+    Const(ExprId),
+    Sym(Path),
+}
+
+impl AsmOperand {
+    pub fn reg(&self) -> Option<&InlineAsmRegOrRegClass> {
+        match self {
+            Self::In { reg, .. }
+            | Self::Out { reg, .. }
+            | Self::InOut { reg, .. }
+            | Self::SplitInOut { reg, .. } => Some(reg),
+            Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
+        }
+    }
+
+    pub fn is_clobber(&self) -> bool {
+        matches!(self, AsmOperand::Out { reg: InlineAsmRegOrRegClass::Reg(_), late: _, expr: None })
+    }
+}
+
+#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+pub enum InlineAsmRegOrRegClass {
+    Reg(Symbol),
+    RegClass(Symbol),
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -372,7 +485,21 @@
         match self {
             Expr::Missing => {}
             Expr::Path(_) | Expr::OffsetOf(_) => {}
-            Expr::InlineAsm(it) => f(it.e),
+            Expr::InlineAsm(it) => it.operands.iter().for_each(|(_, op)| match op {
+                AsmOperand::In { expr, .. }
+                | AsmOperand::Out { expr: Some(expr), .. }
+                | AsmOperand::InOut { expr, .. } => f(*expr),
+                AsmOperand::SplitInOut { in_expr, out_expr, .. } => {
+                    f(*in_expr);
+                    if let Some(out_expr) = out_expr {
+                        f(*out_expr);
+                    }
+                }
+                AsmOperand::Out { expr: None, .. }
+                | AsmOperand::Const(_)
+                | AsmOperand::Label(_)
+                | AsmOperand::Sym(_) => (),
+            }),
             Expr::If { condition, then_branch, else_branch } => {
                 f(*condition);
                 f(*then_branch);
diff --git a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index b6dbba1..a3b4883 100644
--- a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -50,11 +50,7 @@
     let i: u64 = 3;
     let o: u64;
     unsafe {
-        builtin #asm ( {
-            $crate::format_args!("mov {0}, {1}");
-            $crate::format_args!("add {0}, 5");
-        }
-        );
+        builtin #asm ("mov {0}, {1}", "add {0}, 5", out (reg)o, in (reg)i, );
     }
 }
 "##]],
@@ -532,3 +528,21 @@
 "##]],
     );
 }
+
+#[test]
+fn test_quote_string() {
+    check(
+        r##"
+#[rustc_builtin_macro]
+macro_rules! stringify {}
+
+fn main() { stringify!("hello"); }
+"##,
+        expect![[r##"
+#[rustc_builtin_macro]
+macro_rules! stringify {}
+
+fn main() { "\"hello\""; }
+"##]],
+    );
+}
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe.rs b/crates/hir-def/src/macro_expansion_tests/mbe.rs
index fc14608..85fb90f 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe.rs
@@ -389,7 +389,7 @@
 
 m! { Foo,# Bar }
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! m {
     ($($i:ident),*) => ($(mod $i {} )*);
     ($($i:ident)#*) => ($(fn $i() {} )*);
@@ -404,27 +404,29 @@
 
 struct Foo;
 struct Bar;
-"##]],
+"#]],
     );
 }
 
 #[test]
 fn test_match_group_pattern_with_multiple_defs() {
+    // FIXME: The pretty printer breaks by leaving whitespace here, +syntaxctxt is used to avoid that
     check(
         r#"
 macro_rules! m {
     ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } );
 }
+// +syntaxctxt
 m! { foo, bar }
 "#,
         expect![[r#"
 macro_rules! m {
     ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } );
 }
-impl Bar {
-    fn foo() {}
-    fn bar() {}
-}
+impl#\1# Bar#\1# {#\1#
+    fn#\1# foo#\0#(#\1#)#\1# {#\1#}#\1#
+    fn#\1# bar#\0#(#\1#)#\1# {#\1#}#\1#
+}#\1#
 "#]],
     );
 }
@@ -480,12 +482,12 @@
 }
 m!{#abc}
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! m {
     ($($i:ident)* #abc) => ( fn baz() { $($i ();)* } );
 }
 fn baz() {}
-"##]],
+"#]],
     )
 }
 
@@ -1189,13 +1191,13 @@
 m! { cfg(target_os = "windows") }
 m! { hello::world }
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! m {
     ($m:meta) => ( #[$m] fn bar() {} )
 }
 #[cfg(target_os = "windows")] fn bar() {}
 #[hello::world] fn bar() {}
-"##]],
+"#]],
     );
 }
 
@@ -1213,7 +1215,7 @@
     */
 }
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! m {
     ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
 }
@@ -1221,7 +1223,7 @@
 #[doc = r"
         MultiLines Doc
     "] fn bar() {}
-"##]],
+"#]],
     );
 }
 
@@ -1234,12 +1236,12 @@
 }
 m! { #[doc = concat!("The `", "bla", "` lang item.")] }
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! m {
     (#[$m:meta]) => ( #[$m] fn bar() {} )
 }
 #[doc = concat!("The `", "bla", "` lang item.")] fn bar() {}
-"##]],
+"#]],
     );
 }
 
@@ -1257,7 +1259,7 @@
     */
 }
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! m {
     ($(#[$ m:meta])+) => ( $(#[$m])+ fn bar() {} )
 }
@@ -1265,7 +1267,7 @@
 #[doc = r"
         莊生曉夢迷蝴蝶,望帝春心託杜鵑。
     "] fn bar() {}
-"##]],
+"#]],
     );
 }
 
@@ -1342,10 +1344,10 @@
 macro_rules! m { ($($tt:tt)*) => { abs!(=> $($tt)*); } }
 m! {#}
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! m { ($($tt:tt)*) => { abs!(=> $($tt)*); } }
 abs!( = > #);
-"##]],
+"#]],
     );
 }
 
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs b/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs
index bf70119..1430e2a 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs
@@ -311,3 +311,150 @@
 "#]],
     );
 }
+
+#[test]
+fn concat() {
+    // FIXME: Should this error? rustc currently accepts it.
+    check(
+        r#"
+macro_rules! m {
+    ( $a:ident, $b:literal ) => {
+        let ${concat($a, _, "123", _foo, $b, _, 123)};
+    };
+}
+
+fn test() {
+    m!( abc, 456 );
+    m!( def, "hello" );
+}
+"#,
+        expect![[r#"
+macro_rules! m {
+    ( $a:ident, $b:literal ) => {
+        let ${concat($a, _, "123", _foo, $b, _, 123)};
+    };
+}
+
+fn test() {
+    let abc_123_foo456_123;;
+    let def_123_foohello_123;;
+}
+"#]],
+    );
+}
+
+#[test]
+fn concat_less_than_two_elements() {
+    // FIXME: Should this error? rustc currently accepts it.
+    check(
+        r#"
+macro_rules! m {
+    () => {
+        let ${concat(abc)};
+    };
+}
+
+fn test() {
+    m!()
+}
+"#,
+        expect![[r#"
+macro_rules! m {
+    () => {
+        let ${concat(abc)};
+    };
+}
+
+fn test() {
+    /* error: macro definition has parse errors */
+}
+"#]],
+    );
+}
+
+#[test]
+fn concat_invalid_ident() {
+    // FIXME: Should this error? rustc currently accepts it.
+    check(
+        r#"
+macro_rules! m {
+    () => {
+        let ${concat(abc, '"')};
+    };
+}
+
+fn test() {
+    m!()
+}
+"#,
+        expect![[r#"
+macro_rules! m {
+    () => {
+        let ${concat(abc, '"')};
+    };
+}
+
+fn test() {
+    /* error: `${concat(..)}` is not generating a valid identifier */let __ra_concat_dummy;
+}
+"#]],
+    );
+}
+
+#[test]
+fn concat_invalid_fragment() {
+    // FIXME: Should this error? rustc currently accepts it.
+    check(
+        r#"
+macro_rules! m {
+    ( $e:expr ) => {
+        let ${concat(abc, $e)};
+    };
+}
+
+fn test() {
+    m!(())
+}
+"#,
+        expect![[r#"
+macro_rules! m {
+    ( $e:expr ) => {
+        let ${concat(abc, $e)};
+    };
+}
+
+fn test() {
+    /* error: metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt` */let abc;
+}
+"#]],
+    );
+}
+
+#[test]
+fn concat_repetition() {
+    // FIXME: Should this error? rustc currently accepts it.
+    check(
+        r#"
+macro_rules! m {
+    ( $($i:ident)* ) => {
+        let ${concat(abc, $i)};
+    };
+}
+
+fn test() {
+    m!(a b c)
+}
+"#,
+        expect![[r#"
+macro_rules! m {
+    ( $($i:ident)* ) => {
+        let ${concat(abc, $i)};
+    };
+}
+
+fn test() {
+    /* error: expected simple binding, found nested binding `i` */let abc;
+}
+"#]],
+    );
+}
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
index 485f72e..1bbed01 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
@@ -139,7 +139,7 @@
 
 STRUCT!{#[cfg_attr(target_arch = "x86", repr(packed))] struct D3DCONTENTPROTECTIONCAPS {Caps : u8 ,}}
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! STRUCT {
     ($(#[$attrs:meta])* struct $name:ident {
         $($field:ident: $ftype:ty,)+
@@ -194,7 +194,7 @@
         }
     }
 }
-"##]],
+"#]],
     );
 }
 
@@ -214,7 +214,7 @@
 }
 int_base!{Binary for isize as usize -> Binary}
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! int_base {
     ($Trait:ident for $T:ident as $U:ident -> $Radix:ident) => {
         #[stable(feature = "rust1", since = "1.0.0")]
@@ -230,7 +230,7 @@
         Binary.fmt_int(*self as usize, f)
     }
 }
-"##]],
+"#]],
     );
 }
 
@@ -318,7 +318,7 @@
 }
 
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! impl_fn_for_zst  {
     {$( $( #[$attr: meta] )*
     struct $Name: ident impl$( <$( $lifetime : lifetime ),+> )? Fn =
@@ -410,7 +410,7 @@
     }
 }
 
-"##]],
+"#]],
     );
 }
 
@@ -511,7 +511,7 @@
     @__apply cfg(all(not(any(not(any(target_os = "solaris", target_os = "illumos")))))),
 }
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! cfg_if {
     ($(if #[cfg($($meta:meta),*)] { $($it:item)* } )else* else { $($it2:item)* })
     => {
@@ -534,7 +534,7 @@
 }
 
 
-"##]],
+"#]],
     );
 }
 
@@ -618,7 +618,7 @@
     fn GetDataSize(&mut self) -> UINT
 }}
 "#,
-        expect![[r##"
+        expect![[r#"
 #[macro_export]
 macro_rules! RIDL {
     (interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident)
@@ -639,7 +639,7 @@
         ((*self .lpVtbl).GetDataSize)(self )
     }
 }
-"##]],
+"#]],
     );
 }
 
@@ -676,7 +676,7 @@
 );
 
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! quick_error {
     (SORT [enum $name:ident $( #[$meta:meta] )*]
         items [$($( #[$imeta:meta] )*
@@ -697,7 +697,7 @@
 }
 quick_error!(ENUMINITION[enum Wrapped#[derive(Debug)]]body[]queue[ = > One: UNIT[] = > Two: TUPLE[s: String]]);
 
-"##]],
+"#]],
     )
 }
 
@@ -746,7 +746,7 @@
     [G, &'a mut G, deref] pub trait Data: GraphBase {@section type type NodeWeight;}
 }
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! delegate_impl {
     ([$self_type:ident, $self_wrap:ty, $self_map:ident]
      pub trait $name:ident $(: $sup:ident)* $(+ $more_sup:ident)* {
@@ -785,7 +785,7 @@
     }
 }
 impl <> Data for &'amut G where G: Data {}
-"##]],
+"#]],
     );
 }
 
@@ -959,14 +959,14 @@
 
 with_std! {mod m;mod f;}
 "#,
-        expect![[r##"
+        expect![[r#"
 macro_rules! with_std {
     ($($i:item)*) => ($(#[cfg(feature = "std")]$i)*)
 }
 
 #[cfg(feature = "std")] mod m;
 #[cfg(feature = "std")] mod f;
-"##]],
+"#]],
     )
 }
 
@@ -1144,3 +1144,27 @@
 "#]],
     );
 }
+
+#[test]
+fn regression_18148() {
+    check(
+        r#"
+macro_rules! m {
+    ( $e:expr ) => {};
+}
+
+fn foo() {
+    m!(r#const);
+}
+"#,
+        expect![[r#"
+macro_rules! m {
+    ( $e:expr ) => {};
+}
+
+fn foo() {
+    ;
+}
+"#]],
+    );
+}
diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs
index 7f76119..450a15b 100644
--- a/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -1,6 +1,6 @@
-//! This module contains tests for macro expansion. Effectively, it covers `tt`,
-//! `mbe`, `proc_macro_api` and `hir_expand` crates. This might seem like a
-//! wrong architecture at the first glance, but is intentional.
+//! This module contains integration tests for macro expansion with name resolution. Effectively, it
+//! covers `tt`, `mbe`, `proc_macro_api` and `hir_expand` crates. This might seem like a  wrong
+//! architecture at the first glance, but is intentional.
 //!
 //! Physically, macro expansion process is intertwined with name resolution. You
 //! can not expand *just* the syntax. So, to be able to write integration tests
@@ -320,6 +320,7 @@
         _: Span,
         _: Span,
         _: Span,
+        _: Option<String>,
     ) -> Result<Subtree, ProcMacroExpansionError> {
         let (parse, _) = syntax_bridge::token_tree_to_syntax_node(
             subtree,
diff --git a/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
index 6f605c0..c0178ad 100644
--- a/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
+++ b/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
@@ -16,12 +16,12 @@
 #[attr1] #[proc_macros::identity] #[attr2]
 struct S;
 "#,
-        expect![[r##"
+        expect![[r#"
 #[attr1] #[proc_macros::identity] #[attr2]
 struct S;
 
 #[attr1]
-#[attr2] struct S;"##]],
+#[attr2] struct S;"#]],
     );
 }
 
@@ -39,7 +39,7 @@
 #[attr2]
 struct S;
 "#,
-        expect![[r##"
+        expect![[r#"
 #[attr1]
 #[derive(Foo)]
 #[derive(proc_macros::DeriveIdentity)]
@@ -49,7 +49,7 @@
 
 #[attr1]
 #[derive(Bar)]
-#[attr2] struct S;"##]],
+#[attr2] struct S;"#]],
     );
 }
 
@@ -62,14 +62,14 @@
 #[proc_macros::identity_when_valid]
 fn foo() { bar.baz(); blub }
 "#,
-        expect![[r##"
+        expect![[r#"
 #[proc_macros::identity_when_valid]
 fn foo() { bar.baz(); blub }
 
 fn foo() {
     bar.baz();
     blub
-}"##]],
+}"#]],
     );
 }
 
diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs
index 11601c6..9bd7d38 100644
--- a/crates/hir-def/src/nameres.rs
+++ b/crates/hir-def/src/nameres.rs
@@ -69,7 +69,7 @@
 use rustc_hash::{FxHashMap, FxHashSet};
 use span::{Edition, EditionedFileId, FileAstId, FileId, ROOT_ERASED_FILE_AST_ID};
 use stdx::format_to;
-use syntax::{ast, SmolStr};
+use syntax::{ast, AstNode, SmolStr, SyntaxNode};
 use triomphe::Arc;
 use tt::TextRange;
 
@@ -291,7 +291,7 @@
 
     /// Returns a node which defines this module.
     /// That is, a file or a `mod foo {}` with items.
-    fn definition_source(&self, db: &dyn DefDatabase) -> InFile<ModuleSource> {
+    pub fn definition_source(&self, db: &dyn DefDatabase) -> InFile<ModuleSource> {
         match self {
             &ModuleOrigin::File { definition, .. } | &ModuleOrigin::CrateRoot { definition } => {
                 let sf = db.parse(definition).tree();
@@ -728,6 +728,16 @@
     BlockExpr(ast::BlockExpr),
 }
 
+impl ModuleSource {
+    pub fn node(&self) -> SyntaxNode {
+        match self {
+            ModuleSource::SourceFile(it) => it.syntax().clone(),
+            ModuleSource::Module(it) => it.syntax().clone(),
+            ModuleSource::BlockExpr(it) => it.syntax().clone(),
+        }
+    }
+}
+
 /// See `sub_namespace_match()`.
 #[derive(Clone, Copy, PartialEq, Eq)]
 pub enum MacroSubNs {
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 96db3db..e09ef4f 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -221,7 +221,7 @@
     deps: FxHashMap<Name, Dependency>,
     glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, UseId)>>,
     unresolved_imports: Vec<ImportDirective>,
-    indeterminate_imports: Vec<ImportDirective>,
+    indeterminate_imports: Vec<(ImportDirective, PerNs)>,
     unresolved_macros: Vec<MacroDirective>,
     mod_dirs: FxHashMap<LocalModuleId, ModDir>,
     cfg_options: &'a CfgOptions,
@@ -415,16 +415,6 @@
 
         self.resolution_loop();
 
-        // Resolve all indeterminate resolved imports again
-        // As some of the macros will expand newly import shadowing partial resolved imports
-        // FIXME: We maybe could skip this, if we handle the indeterminate imports in `resolve_imports`
-        // correctly
-        let partial_resolved = self.indeterminate_imports.drain(..).map(|directive| {
-            ImportDirective { status: PartialResolvedImport::Unresolved, ..directive }
-        });
-        self.unresolved_imports.extend(partial_resolved);
-        self.resolve_imports();
-
         let unresolved_imports = mem::take(&mut self.unresolved_imports);
         // show unresolved imports in completion, etc
         for directive in &unresolved_imports {
@@ -749,9 +739,9 @@
             .filter_map(|mut directive| {
                 directive.status = self.resolve_import(directive.module_id, &directive.import);
                 match directive.status {
-                    PartialResolvedImport::Indeterminate(_) => {
+                    PartialResolvedImport::Indeterminate(resolved) => {
                         self.record_resolved_import(&directive);
-                        self.indeterminate_imports.push(directive);
+                        self.indeterminate_imports.push((directive, resolved));
                         res = ReachedFixedPoint::No;
                         None
                     }
@@ -764,6 +754,33 @@
                 }
             })
             .collect();
+
+        // Resolve all indeterminate resolved imports again
+        // As some of the macros will expand newly import shadowing partial resolved imports
+        // FIXME: We maybe could skip this, if we handle the indeterminate imports in `resolve_imports`
+        // correctly
+        let mut indeterminate_imports = std::mem::take(&mut self.indeterminate_imports);
+        indeterminate_imports.retain_mut(|(directive, partially_resolved)| {
+            let partially_resolved = partially_resolved.availability();
+            directive.status = self.resolve_import(directive.module_id, &directive.import);
+            match directive.status {
+                PartialResolvedImport::Indeterminate(import)
+                    if partially_resolved != import.availability() =>
+                {
+                    self.record_resolved_import(directive);
+                    res = ReachedFixedPoint::No;
+                    false
+                }
+                PartialResolvedImport::Resolved(_) => {
+                    self.record_resolved_import(directive);
+                    res = ReachedFixedPoint::No;
+                    false
+                }
+                _ => true,
+            }
+        });
+        self.indeterminate_imports = indeterminate_imports;
+
         res
     }
 
diff --git a/crates/hir-def/src/per_ns.rs b/crates/hir-def/src/per_ns.rs
index 19485c4..3f3b98c 100644
--- a/crates/hir-def/src/per_ns.rs
+++ b/crates/hir-def/src/per_ns.rs
@@ -3,6 +3,8 @@
 //!
 //! `PerNs` (per namespace) captures this.
 
+use bitflags::bitflags;
+
 use crate::{
     item_scope::{ImportId, ImportOrExternCrate, ItemInNs},
     visibility::Visibility,
@@ -16,6 +18,16 @@
     Macros,
 }
 
+bitflags! {
+    /// Describes only the presence/absence of each namespace, without its value.
+    #[derive(Debug, PartialEq, Eq)]
+    pub(crate) struct NsAvailability : u32 {
+        const TYPES = 1 << 0;
+        const VALUES = 1 << 1;
+        const MACROS = 1 << 2;
+    }
+}
+
 #[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
 pub struct PerNs {
     pub types: Option<(ModuleDefId, Visibility, Option<ImportOrExternCrate>)>,
@@ -24,6 +36,14 @@
 }
 
 impl PerNs {
+    pub(crate) fn availability(&self) -> NsAvailability {
+        let mut result = NsAvailability::empty();
+        result.set(NsAvailability::TYPES, self.types.is_some());
+        result.set(NsAvailability::VALUES, self.values.is_some());
+        result.set(NsAvailability::MACROS, self.macros.is_some());
+        result
+    }
+
     pub fn none() -> PerNs {
         PerNs { types: None, values: None, macros: None }
     }
diff --git a/crates/hir-expand/src/builtin.rs b/crates/hir-expand/src/builtin.rs
index 252430e..7b9b7f3 100644
--- a/crates/hir-expand/src/builtin.rs
+++ b/crates/hir-expand/src/builtin.rs
@@ -1,6 +1,6 @@
 //! Builtin macros and attributes
 #[macro_use]
-mod quote;
+pub mod quote;
 
 mod attr_macro;
 mod derive_macro;
diff --git a/crates/hir-expand/src/builtin/fn_macro.rs b/crates/hir-expand/src/builtin/fn_macro.rs
index 795d9b1..d04225b 100644
--- a/crates/hir-expand/src/builtin/fn_macro.rs
+++ b/crates/hir-expand/src/builtin/fn_macro.rs
@@ -119,9 +119,8 @@
     (module_path, ModulePath) => module_path_expand,
     (assert, Assert) => assert_expand,
     (stringify, Stringify) => stringify_expand,
-    (llvm_asm, LlvmAsm) => asm_expand,
     (asm, Asm) => asm_expand,
-    (global_asm, GlobalAsm) => global_asm_expand,
+    (global_asm, GlobalAsm) => asm_expand,
     (cfg, Cfg) => cfg_expand,
     (core_panic, CorePanic) => panic_expand,
     (std_panic, StdPanic) => panic_expand,
@@ -324,40 +323,15 @@
     tt: &tt::Subtree,
     span: Span,
 ) -> ExpandResult<tt::Subtree> {
-    // We expand all assembly snippets to `format_args!` invocations to get format syntax
-    // highlighting for them.
-    let mut literals = Vec::new();
-    for tt in tt.token_trees.chunks(2) {
-        match tt {
-            [tt::TokenTree::Leaf(tt::Leaf::Literal(lit))]
-            | [tt::TokenTree::Leaf(tt::Leaf::Literal(lit)), tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: ',', span: _, spacing: _ }))] =>
-            {
-                let dollar_krate = dollar_crate(span);
-                literals.push(quote!(span=>#dollar_krate::format_args!(#lit);));
-            }
-            _ => break,
-        }
-    }
-
+    let mut tt = tt.clone();
+    tt.delimiter.kind = tt::DelimiterKind::Parenthesis;
     let pound = mk_pound(span);
     let expanded = quote! {span =>
-        builtin #pound asm (
-            {##literals}
-        )
+        builtin #pound asm #tt
     };
     ExpandResult::ok(expanded)
 }
 
-fn global_asm_expand(
-    _db: &dyn ExpandDatabase,
-    _id: MacroCallId,
-    _tt: &tt::Subtree,
-    span: Span,
-) -> ExpandResult<tt::Subtree> {
-    // Expand to nothing (at item-level)
-    ExpandResult::ok(quote! {span =>})
-}
-
 fn cfg_expand(
     db: &dyn ExpandDatabase,
     id: MacroCallId,
@@ -509,7 +483,7 @@
                 match it.kind {
                     tt::LitKind::Char => {
                         if let Ok(c) = unescape_char(it.symbol.as_str()) {
-                            text.extend(c.escape_default());
+                            text.push(c);
                         }
                         record_span(it.span);
                     }
@@ -517,11 +491,11 @@
                         format_to!(text, "{}", it.symbol.as_str())
                     }
                     tt::LitKind::Str => {
-                        text.push_str(it.symbol.as_str());
+                        text.push_str(unescape_str(&it.symbol).as_str());
                         record_span(it.span);
                     }
                     tt::LitKind::StrRaw(_) => {
-                        format_to!(text, "{}", it.symbol.as_str().escape_debug());
+                        format_to!(text, "{}", it.symbol.as_str());
                         record_span(it.span);
                     }
                     tt::LitKind::Byte
@@ -839,7 +813,7 @@
 
 fn get_env_inner(db: &dyn ExpandDatabase, arg_id: MacroCallId, key: &Symbol) -> Option<String> {
     let krate = db.lookup_intern_macro_call(arg_id).krate;
-    db.crate_graph()[krate].env.get(key.as_str()).map(|it| it.escape_debug().to_string())
+    db.crate_graph()[krate].env.get(key.as_str())
 }
 
 fn env_expand(
diff --git a/crates/hir-expand/src/builtin/quote.rs b/crates/hir-expand/src/builtin/quote.rs
index 5c33f81..418d8d9 100644
--- a/crates/hir-expand/src/builtin/quote.rs
+++ b/crates/hir-expand/src/builtin/quote.rs
@@ -3,6 +3,7 @@
 
 use intern::{sym, Symbol};
 use span::Span;
+use syntax::ToSmolStr;
 use tt::IdentIsRaw;
 
 use crate::name::Name;
@@ -17,6 +18,7 @@
 // 2. #()* pattern repetition not supported now
 //    * But we can do it manually, see `test_quote_derive_copy_hack`
 #[doc(hidden)]
+#[macro_export]
 macro_rules! quote_impl__ {
     ($span:ident) => {
         Vec::<$crate::tt::TokenTree>::new()
@@ -26,8 +28,8 @@
         {
             let children = $crate::builtin::quote::__quote!($span $($tt)*);
             $crate::tt::Subtree {
-                delimiter: crate::tt::Delimiter {
-                    kind: crate::tt::DelimiterKind::$delim,
+                delimiter: $crate::tt::Delimiter {
+                    kind: $crate::tt::DelimiterKind::$delim,
                     open: $span,
                     close: $span,
                 },
@@ -39,9 +41,9 @@
     ( @PUNCT($span:ident) $first:literal ) => {
         {
             vec![
-                crate::tt::Leaf::Punct(crate::tt::Punct {
+                $crate::tt::Leaf::Punct($crate::tt::Punct {
                     char: $first,
-                    spacing: crate::tt::Spacing::Alone,
+                    spacing: $crate::tt::Spacing::Alone,
                     span: $span,
                 }).into()
             ]
@@ -51,14 +53,14 @@
     ( @PUNCT($span:ident) $first:literal, $sec:literal ) => {
         {
             vec![
-                crate::tt::Leaf::Punct(crate::tt::Punct {
+                $crate::tt::Leaf::Punct($crate::tt::Punct {
                     char: $first,
-                    spacing: crate::tt::Spacing::Joint,
+                    spacing: $crate::tt::Spacing::Joint,
                     span: $span,
                 }).into(),
-                crate::tt::Leaf::Punct(crate::tt::Punct {
+                $crate::tt::Leaf::Punct($crate::tt::Punct {
                     char: $sec,
-                    spacing: crate::tt::Spacing::Alone,
+                    spacing: $crate::tt::Spacing::Alone,
                     span: $span,
                 }).into()
             ]
@@ -97,7 +99,7 @@
     // Ident
     ($span:ident $tt:ident ) => {
         vec![ {
-            crate::tt::Leaf::Ident(crate::tt::Ident {
+            $crate::tt::Leaf::Ident($crate::tt::Ident {
                 sym: intern::Symbol::intern(stringify!($tt)),
                 span: $span,
                 is_raw: tt::IdentIsRaw::No,
@@ -108,6 +110,7 @@
     // Puncts
     // FIXME: Not all puncts are handled
     ($span:ident -> ) => {$crate::builtin::quote::__quote!(@PUNCT($span) '-', '>')};
+    ($span:ident => ) => {$crate::builtin::quote::__quote!(@PUNCT($span) '=', '>')};
     ($span:ident & ) => {$crate::builtin::quote::__quote!(@PUNCT($span) '&')};
     ($span:ident , ) => {$crate::builtin::quote::__quote!(@PUNCT($span) ',')};
     ($span:ident : ) => {$crate::builtin::quote::__quote!(@PUNCT($span) ':')};
@@ -117,6 +120,9 @@
     ($span:ident < ) => {$crate::builtin::quote::__quote!(@PUNCT($span) '<')};
     ($span:ident > ) => {$crate::builtin::quote::__quote!(@PUNCT($span) '>')};
     ($span:ident ! ) => {$crate::builtin::quote::__quote!(@PUNCT($span) '!')};
+    ($span:ident # ) => {$crate::builtin::quote::__quote!(@PUNCT($span) '#')};
+    ($span:ident $ ) => {$crate::builtin::quote::__quote!(@PUNCT($span) '$')};
+    ($span:ident * ) => {$crate::builtin::quote::__quote!(@PUNCT($span) '*')};
 
     ($span:ident $first:tt $($tail:tt)+ ) => {
         {
@@ -128,18 +134,19 @@
         }
     };
 }
-pub(super) use quote_impl__ as __quote;
+pub use quote_impl__ as __quote;
 
 /// FIXME:
 /// It probably should implement in proc-macro
-macro_rules! quote_impl {
+#[macro_export]
+macro_rules! quote {
     ($span:ident=> $($tt:tt)* ) => {
         $crate::builtin::quote::IntoTt::to_subtree($crate::builtin::quote::__quote!($span $($tt)*), $span)
     }
 }
-pub(super) use quote_impl as quote;
+pub(super) use quote;
 
-pub(crate) trait IntoTt {
+pub trait IntoTt {
     fn to_subtree(self, span: Span) -> crate::tt::Subtree;
     fn to_tokens(self) -> Vec<crate::tt::TokenTree>;
 }
@@ -167,7 +174,7 @@
     }
 }
 
-pub(crate) trait ToTokenTree {
+pub trait ToTokenTree {
     fn to_token(self, span: Span) -> crate::tt::TokenTree;
 }
 
@@ -211,8 +218,8 @@
     _span: crate::tt::Literal => self { self };
     _span: crate::tt::Ident => self { self };
     _span: crate::tt::Punct => self { self };
-    span: &str => self { crate::tt::Literal{symbol: Symbol::intern(self), span, kind: tt::LitKind::Str, suffix: None }};
-    span: String => self { crate::tt::Literal{symbol: Symbol::intern(&self), span, kind: tt::LitKind::Str, suffix: None }};
+    span: &str => self { crate::tt::Literal{symbol: Symbol::intern(&self.escape_default().to_smolstr()), span, kind: tt::LitKind::Str, suffix: None }};
+    span: String => self { crate::tt::Literal{symbol: Symbol::intern(&self.escape_default().to_smolstr()), span, kind: tt::LitKind::Str, suffix: None }};
     span: Name => self {
         let (is_raw, s) = IdentIsRaw::split_from_symbol(self.as_str());
         crate::tt::Ident{sym: Symbol::intern(s), span, is_raw }
diff --git a/crates/hir-expand/src/cfg_process.rs b/crates/hir-expand/src/cfg_process.rs
index 147cf91..01a3103 100644
--- a/crates/hir-expand/src/cfg_process.rs
+++ b/crates/hir-expand/src/cfg_process.rs
@@ -6,7 +6,7 @@
 use intern::{sym, Symbol};
 use rustc_hash::FxHashSet;
 use syntax::{
-    ast::{self, Attr, HasAttrs, Meta, VariantList},
+    ast::{self, Attr, HasAttrs, Meta, TokenTree, VariantList},
     AstNode, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, T,
 };
 use tracing::{debug, warn};
@@ -17,7 +17,7 @@
     if !attr.simple_name().as_deref().map(|v| v == "cfg")? {
         return None;
     }
-    let cfg = parse_from_attr_meta(attr.meta()?)?;
+    let cfg = parse_from_attr_token_tree(&attr.meta()?.token_tree()?)?;
     let enabled = db.crate_graph()[krate].cfg_options.check(&cfg) != Some(false);
     Some(enabled)
 }
@@ -26,7 +26,15 @@
     if !attr.simple_name().as_deref().map(|v| v == "cfg_attr")? {
         return None;
     }
-    let cfg_expr = parse_from_attr_meta(attr.meta()?)?;
+    check_cfg_attr_value(db, &attr.token_tree()?, krate)
+}
+
+pub fn check_cfg_attr_value(
+    db: &dyn ExpandDatabase,
+    attr: &TokenTree,
+    krate: CrateId,
+) -> Option<bool> {
+    let cfg_expr = parse_from_attr_token_tree(attr)?;
     let enabled = db.crate_graph()[krate].cfg_options.check(&cfg_expr) != Some(false);
     Some(enabled)
 }
@@ -238,8 +246,7 @@
     Some(remove)
 }
 /// Parses a `cfg` attribute from the meta
-fn parse_from_attr_meta(meta: Meta) -> Option<CfgExpr> {
-    let tt = meta.token_tree()?;
+fn parse_from_attr_token_tree(tt: &TokenTree) -> Option<CfgExpr> {
     let mut iter = tt
         .token_trees_and_tokens()
         .filter(is_not_whitespace)
@@ -328,7 +335,7 @@
     use expect_test::{expect, Expect};
     use syntax::{ast::Attr, AstNode, SourceFile};
 
-    use crate::cfg_process::parse_from_attr_meta;
+    use crate::cfg_process::parse_from_attr_token_tree;
 
     fn check_dnf_from_syntax(input: &str, expect: Expect) {
         let parse = SourceFile::parse(input, span::Edition::CURRENT);
@@ -342,7 +349,7 @@
         let node = node.clone_subtree();
         assert_eq!(node.syntax().text_range().start(), 0.into());
 
-        let cfg = parse_from_attr_meta(node.meta().unwrap()).unwrap();
+        let cfg = parse_from_attr_token_tree(&node.meta().unwrap().token_tree().unwrap()).unwrap();
         let actual = format!("#![cfg({})]", DnfExpr::new(&cfg));
         expect.assert_eq(&actual);
     }
diff --git a/crates/hir-expand/src/change.rs b/crates/hir-expand/src/change.rs
index 8b3f69d..de3a7b9 100644
--- a/crates/hir-expand/src/change.rs
+++ b/crates/hir-expand/src/change.rs
@@ -1,10 +1,10 @@
 //! Defines a unit of change that can applied to the database to get the next
 //! state. Changes are transactional.
 use base_db::{
-    salsa::Durability, CrateGraph, CrateId, FileChange, SourceRoot, SourceRootDatabase,
-    TargetLayoutLoadResult, Version,
+    salsa::Durability, CrateGraph, CrateId, CrateWorkspaceData, FileChange, SourceRoot,
+    SourceRootDatabase,
 };
-use la_arena::RawIdx;
+use rustc_hash::FxHashMap;
 use span::FileId;
 use triomphe::Arc;
 
@@ -14,8 +14,6 @@
 pub struct ChangeWithProcMacros {
     pub source_change: FileChange,
     pub proc_macros: Option<ProcMacros>,
-    pub toolchains: Option<Vec<Option<Version>>>,
-    pub target_data_layouts: Option<Vec<TargetLayoutLoadResult>>,
 }
 
 impl ChangeWithProcMacros {
@@ -28,46 +26,25 @@
         if let Some(proc_macros) = self.proc_macros {
             db.set_proc_macros_with_durability(Arc::new(proc_macros), Durability::HIGH);
         }
-        if let Some(target_data_layouts) = self.target_data_layouts {
-            for (id, val) in target_data_layouts.into_iter().enumerate() {
-                db.set_data_layout_with_durability(
-                    CrateId::from_raw(RawIdx::from(id as u32)),
-                    val,
-                    Durability::HIGH,
-                );
-            }
-        }
-        if let Some(toolchains) = self.toolchains {
-            for (id, val) in toolchains.into_iter().enumerate() {
-                db.set_toolchain_with_durability(
-                    CrateId::from_raw(RawIdx::from(id as u32)),
-                    val,
-                    Durability::HIGH,
-                );
-            }
-        }
     }
 
     pub fn change_file(&mut self, file_id: FileId, new_text: Option<String>) {
         self.source_change.change_file(file_id, new_text)
     }
 
-    pub fn set_crate_graph(&mut self, graph: CrateGraph) {
-        self.source_change.set_crate_graph(graph)
+    pub fn set_crate_graph(
+        &mut self,
+        graph: CrateGraph,
+        ws_data: FxHashMap<CrateId, Arc<CrateWorkspaceData>>,
+    ) {
+        self.source_change.set_crate_graph(graph);
+        self.source_change.set_ws_data(ws_data);
     }
 
     pub fn set_proc_macros(&mut self, proc_macros: ProcMacros) {
         self.proc_macros = Some(proc_macros);
     }
 
-    pub fn set_toolchains(&mut self, toolchains: Vec<Option<Version>>) {
-        self.toolchains = Some(toolchains);
-    }
-
-    pub fn set_target_data_layouts(&mut self, target_data_layouts: Vec<TargetLayoutLoadResult>) {
-        self.target_data_layouts = Some(target_data_layouts);
-    }
-
     pub fn set_roots(&mut self, roots: Vec<SourceRoot>) {
         self.source_change.set_roots(roots)
     }
diff --git a/crates/hir-expand/src/declarative.rs b/crates/hir-expand/src/declarative.rs
index b1a6eed..86dd4ae 100644
--- a/crates/hir-expand/src/declarative.rs
+++ b/crates/hir-expand/src/declarative.rs
@@ -1,4 +1,4 @@
-//! Compiled declarative macro expanders (`macro_rules!`` and `macro`)
+//! Compiled declarative macro expanders (`macro_rules!` and `macro`)
 
 use base_db::CrateId;
 use intern::sym;
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index 19c3c9c..9538097 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -21,6 +21,7 @@
 
 mod cfg_process;
 mod fixup;
+mod prettify_macro_expansion_;
 
 use attrs::collect_attrs;
 use rustc_hash::FxHashMap;
@@ -51,7 +52,11 @@
     span_map::{ExpansionSpanMap, SpanMap},
 };
 
-pub use crate::files::{AstId, ErasedAstId, FileRange, InFile, InMacroFile, InRealFile};
+pub use crate::{
+    cfg_process::check_cfg_attr_value,
+    files::{AstId, ErasedAstId, FileRange, InFile, InMacroFile, InRealFile},
+    prettify_macro_expansion_::prettify_macro_expansion,
+};
 
 pub use mbe::{DeclarativeMacro, ValueResult};
 pub use span::{HirFileId, MacroCallId, MacroFileId};
diff --git a/crates/hir-expand/src/prettify_macro_expansion_.rs b/crates/hir-expand/src/prettify_macro_expansion_.rs
new file mode 100644
index 0000000..d928caf
--- /dev/null
+++ b/crates/hir-expand/src/prettify_macro_expansion_.rs
@@ -0,0 +1,60 @@
+//! Pretty printing of macros output.
+
+use base_db::CrateId;
+use rustc_hash::FxHashMap;
+use syntax::NodeOrToken;
+use syntax::{ast::make, SyntaxNode};
+
+use crate::{db::ExpandDatabase, span_map::ExpansionSpanMap};
+
+/// Inserts whitespace and replaces `$crate` in macro expansions.
+#[expect(deprecated)]
+pub fn prettify_macro_expansion(
+    db: &dyn ExpandDatabase,
+    syn: SyntaxNode,
+    span_map: &ExpansionSpanMap,
+    target_crate_id: CrateId,
+) -> SyntaxNode {
+    let crate_graph = db.crate_graph();
+    let target_crate = &crate_graph[target_crate_id];
+    let mut syntax_ctx_id_to_dollar_crate_replacement = FxHashMap::default();
+    syntax_bridge::prettify_macro_expansion::prettify_macro_expansion(syn, &mut |dollar_crate| {
+        let ctx = span_map.span_at(dollar_crate.text_range().start()).ctx;
+        let replacement =
+            syntax_ctx_id_to_dollar_crate_replacement.entry(ctx).or_insert_with(|| {
+                let ctx_data = db.lookup_intern_syntax_context(ctx);
+                let macro_call_id =
+                    ctx_data.outer_expn.expect("`$crate` cannot come from `SyntaxContextId::ROOT`");
+                let macro_call = db.lookup_intern_macro_call(macro_call_id);
+                let macro_def_crate = macro_call.def.krate;
+                // First, if this is the same crate as the macro, nothing will work but `crate`.
+                // If not, if the target trait has the macro's crate as a dependency, using the dependency name
+                // will work in inserted code and match the user's expectation.
+                // If not, the crate's display name is what the dependency name is likely to be once such dependency
+                // is inserted, and also understandable to the user.
+                // Lastly, if nothing else found, resort to leaving `$crate`.
+                if target_crate_id == macro_def_crate {
+                    make::tokens::crate_kw()
+                } else if let Some(dep) =
+                    target_crate.dependencies.iter().find(|dep| dep.crate_id == macro_def_crate)
+                {
+                    make::tokens::ident(&dep.name)
+                } else if let Some(crate_name) = &crate_graph[macro_def_crate].display_name {
+                    make::tokens::ident(crate_name.crate_name())
+                } else {
+                    return dollar_crate.clone();
+                }
+            });
+        if replacement.text() == "$crate" {
+            // The parent may have many children, and looking for the token may yield incorrect results.
+            return dollar_crate.clone();
+        }
+        // We need to `clone_subtree()` but rowan doesn't provide such operation for tokens.
+        let parent = replacement.parent().unwrap().clone_subtree().clone_for_update();
+        parent
+            .children_with_tokens()
+            .filter_map(NodeOrToken::into_token)
+            .find(|it| it.kind() == replacement.kind())
+            .unwrap()
+    })
+}
diff --git a/crates/hir-expand/src/proc_macro.rs b/crates/hir-expand/src/proc_macro.rs
index 26bb3a3..fe09f03 100644
--- a/crates/hir-expand/src/proc_macro.rs
+++ b/crates/hir-expand/src/proc_macro.rs
@@ -29,6 +29,7 @@
         def_site: Span,
         call_site: Span,
         mixed_site: Span,
+        current_dir: Option<String>,
     ) -> Result<tt::Subtree, ProcMacroExpansionError>;
 }
 
@@ -234,8 +235,18 @@
                 let krate_graph = db.crate_graph();
                 // Proc macros have access to the environment variables of the invoking crate.
                 let env = &krate_graph[calling_crate].env;
-                match proc_macro.expander.expand(tt, attr_arg, env, def_site, call_site, mixed_site)
-                {
+                match proc_macro.expander.expand(
+                    tt,
+                    attr_arg,
+                    env,
+                    def_site,
+                    call_site,
+                    mixed_site,
+                    db.crate_workspace_data()[&calling_crate]
+                        .proc_macro_cwd
+                        .as_ref()
+                        .map(ToString::to_string),
+                ) {
                     Ok(t) => ExpandResult::ok(t),
                     Err(err) => match err {
                         // Don't discard the item in case something unexpected happened while expanding attributes
diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs
index a3e4da5..e74e3d7 100644
--- a/crates/hir-ty/src/chalk_db.rs
+++ b/crates/hir-ty/src/chalk_db.rs
@@ -381,9 +381,9 @@
         TyKind::Error.intern(Interner)
     }
 
-    fn is_object_safe(&self, _trait_id: chalk_ir::TraitId<Interner>) -> bool {
-        // FIXME: implement actual object safety
-        true
+    fn is_object_safe(&self, trait_id: chalk_ir::TraitId<Interner>) -> bool {
+        let trait_ = from_chalk_trait_id(trait_id);
+        crate::object_safety::object_safety(self.db, trait_).is_none()
     }
 
     fn closure_kind(
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs
index 8b6cde9..968a828 100644
--- a/crates/hir-ty/src/consteval.rs
+++ b/crates/hir-ty/src/consteval.rs
@@ -11,7 +11,7 @@
     ConstBlockLoc, EnumVariantId, GeneralConstId, StaticId,
 };
 use hir_expand::Lookup;
-use stdx::never;
+use stdx::{never, IsNoneOr};
 use triomphe::Arc;
 
 use crate::{
@@ -184,6 +184,22 @@
     }
 }
 
+pub fn try_const_isize(db: &dyn HirDatabase, c: &Const) -> Option<i128> {
+    match &c.data(Interner).value {
+        chalk_ir::ConstValue::BoundVar(_) => None,
+        chalk_ir::ConstValue::InferenceVar(_) => None,
+        chalk_ir::ConstValue::Placeholder(_) => None,
+        chalk_ir::ConstValue::Concrete(c) => match &c.interned {
+            ConstScalar::Bytes(it, _) => Some(i128::from_le_bytes(pad16(it, true))),
+            ConstScalar::UnevaluatedConst(c, subst) => {
+                let ec = db.const_eval(*c, subst.clone(), None).ok()?;
+                try_const_isize(db, &ec)
+            }
+            _ => None,
+        },
+    }
+}
+
 pub(crate) fn const_eval_recover(
     _: &dyn HirDatabase,
     _: &Cycle,
@@ -256,8 +272,8 @@
 ) -> Result<i128, ConstEvalError> {
     let def = variant_id.into();
     let body = db.body(def);
+    let loc = variant_id.lookup(db.upcast());
     if body.exprs[body.body_expr] == Expr::Missing {
-        let loc = variant_id.lookup(db.upcast());
         let prev_idx = loc.index.checked_sub(1);
         let value = match prev_idx {
             Some(prev_idx) => {
@@ -269,13 +285,21 @@
         };
         return Ok(value);
     }
+
+    let repr = db.enum_data(loc.parent).repr;
+    let is_signed = IsNoneOr::is_none_or(repr.and_then(|repr| repr.int), |int| int.is_signed());
+
     let mir_body = db.monomorphized_mir_body(
         def,
         Substitution::empty(Interner),
         db.trait_environment_for_body(def),
     )?;
     let c = interpret_mir(db, mir_body, false, None).0?;
-    let c = try_const_usize(db, &c).unwrap() as i128;
+    let c = if is_signed {
+        try_const_isize(db, &c).unwrap()
+    } else {
+        try_const_usize(db, &c).unwrap() as i128
+    };
     Ok(c)
 }
 
diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs
index 8622825..7093fca 100644
--- a/crates/hir-ty/src/consteval/tests.rs
+++ b/crates/hir-ty/src/consteval/tests.rs
@@ -186,7 +186,13 @@
 
 #[test]
 fn casts() {
-    check_number(r#"const GOAL: usize = 12 as *const i32 as usize"#, 12);
+    check_number(
+        r#"
+    //- minicore: sized
+    const GOAL: usize = 12 as *const i32 as usize
+        "#,
+        12,
+    );
     check_number(
         r#"
     //- minicore: coerce_unsized, index, slice
@@ -204,7 +210,7 @@
         r#"
     //- minicore: coerce_unsized, index, slice
     const GOAL: i16 = {
-        let a = &mut 5;
+        let a = &mut 5_i16;
         let z = a as *mut _;
         unsafe { *z }
     };
@@ -244,7 +250,13 @@
         "#,
         4,
     );
-    check_number(r#"const GOAL: i32 = -12i8 as i32"#, -12);
+    check_number(
+        r#"
+    //- minicore: sized
+    const GOAL: i32 = -12i8 as i32
+        "#,
+        -12,
+    );
 }
 
 #[test]
@@ -1544,7 +1556,7 @@
         Bar,
     }
     #[derive(Clone)]
-    struct X(i32, Z, i64)
+    struct X(i32, Z, i64);
     #[derive(Clone)]
     struct Y {
         field1: i32,
@@ -1562,20 +1574,20 @@
     );
     check_number(
         r#"
-    //- minicore: default, derive, builtin_impls
-    #[derive(Default)]
-    struct X(i32, Y, i64)
-    #[derive(Default)]
-    struct Y {
-        field1: i32,
-        field2: u8,
-    }
+//- minicore: default, derive, builtin_impls
+#[derive(Default)]
+struct X(i32, Y, i64);
+#[derive(Default)]
+struct Y {
+    field1: i32,
+    field2: u8,
+}
 
-    const GOAL: u8 = {
-        let x = X::default();
-        x.1.field2
-    };
-    "#,
+const GOAL: u8 = {
+    let x = X::default();
+    x.1.field2
+};
+"#,
         0,
     );
 }
@@ -1911,6 +1923,7 @@
     );
     check_number(
         r#"
+    //- minicore: sized
     fn add2(x: u8) -> u8 {
         x + 2
     }
@@ -2007,7 +2020,7 @@
     );
     check_number(
         r#"
-    //- minicore: coerce_unsized, fn
+    //- minicore: coerce_unsized, fn, dispatch_from_dyn
     fn add2(x: u8) -> u8 {
         x + 2
     }
@@ -2062,7 +2075,7 @@
 fn dyn_trait() {
     check_number(
         r#"
-    //- minicore: coerce_unsized, index, slice
+    //- minicore: coerce_unsized, index, slice, dispatch_from_dyn
     trait Foo {
         fn foo(&self) -> u8 { 10 }
     }
@@ -2085,7 +2098,7 @@
     );
     check_number(
         r#"
-    //- minicore: coerce_unsized, index, slice
+    //- minicore: coerce_unsized, index, slice, dispatch_from_dyn
     trait Foo {
         fn foo(&self) -> i32 { 10 }
     }
@@ -2109,7 +2122,7 @@
     );
     check_number(
         r#"
-    //- minicore: coerce_unsized, index, slice
+    //- minicore: coerce_unsized, index, slice, dispatch_from_dyn
     trait A {
         fn x(&self) -> i32;
     }
@@ -2422,6 +2435,7 @@
 fn extern_weak_statics() {
     check_number(
         r#"
+    //- minicore: sized
     extern "C" {
         #[linkage = "extern_weak"]
         static __dso_handle: *mut u8;
@@ -2716,6 +2730,7 @@
     );
     check_number(
         r#"
+    //- minicore: sized
     struct S<T>(*mut T);
 
     trait MySized: Sized {
@@ -2813,7 +2828,7 @@
         y.0
     };
     "#,
-        |e| matches!(e, ConstEvalError::MirLowerError(MirLowerError::TypeMismatch(_))),
+        |e| matches!(e, ConstEvalError::MirLowerError(MirLowerError::HasErrors)),
     );
 }
 
diff --git a/crates/hir-ty/src/consteval/tests/intrinsics.rs b/crates/hir-ty/src/consteval/tests/intrinsics.rs
index 5972b80..c570617 100644
--- a/crates/hir-ty/src/consteval/tests/intrinsics.rs
+++ b/crates/hir-ty/src/consteval/tests/intrinsics.rs
@@ -89,7 +89,7 @@
     );
     check_number(
         r#"
-        //- minicore: coerce_unsized, fmt, builtin_impls
+        //- minicore: coerce_unsized, fmt, builtin_impls, dispatch_from_dyn
         extern "rust-intrinsic" {
             pub fn size_of_val<T: ?Sized>(_: *const T) -> usize;
         }
@@ -311,6 +311,7 @@
 fn allocator() {
     check_number(
         r#"
+        //- minicore: sized
         extern "Rust" {
             #[rustc_allocator]
             fn __rust_alloc(size: usize, align: usize) -> *mut u8;
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 9a1f215..ce5a821 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -11,7 +11,7 @@
 use hir_def::{
     db::DefDatabase, hir::ExprId, layout::TargetDataLayout, AdtId, BlockId, CallableDefId,
     ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId,
-    LifetimeParamId, LocalFieldId, StaticId, TypeAliasId, TypeOrConstParamId, VariantId,
+    LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, TypeOrConstParamId, VariantId,
 };
 use la_arena::ArenaMap;
 use smallvec::SmallVec;
@@ -24,6 +24,7 @@
     lower::{GenericDefaults, GenericPredicates},
     method_resolution::{InherentImpls, TraitImpls, TyFingerprint},
     mir::{BorrowckResult, MirBody, MirLowerError},
+    object_safety::ObjectSafetyViolation,
     Binders, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult, Interner,
     PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId,
 };
@@ -107,6 +108,9 @@
     #[salsa::invoke(crate::layout::target_data_layout_query)]
     fn target_data_layout(&self, krate: CrateId) -> Result<Arc<TargetDataLayout>, Arc<str>>;
 
+    #[salsa::invoke(crate::object_safety::object_safety_of_trait_query)]
+    fn object_safety_of_trait(&self, trait_: TraitId) -> Option<ObjectSafetyViolation>;
+
     #[salsa::invoke(crate::lower::ty_query)]
     #[salsa::cycle(crate::lower::ty_recover)]
     fn ty(&self, def: TyDefId) -> Binders<Ty>;
@@ -150,6 +154,9 @@
     #[salsa::invoke(crate::lower::generic_predicates_query)]
     fn generic_predicates(&self, def: GenericDefId) -> GenericPredicates;
 
+    #[salsa::invoke(crate::lower::generic_predicates_without_parent_query)]
+    fn generic_predicates_without_parent(&self, def: GenericDefId) -> GenericPredicates;
+
     #[salsa::invoke(crate::lower::trait_environment_for_body_query)]
     #[salsa::transparent]
     fn trait_environment_for_body(&self, def: DefWithBodyId) -> Arc<TraitEnvironment>;
diff --git a/crates/hir-ty/src/diagnostics/decl_check.rs b/crates/hir-ty/src/diagnostics/decl_check.rs
index 024fc32..82517e6 100644
--- a/crates/hir-ty/src/diagnostics/decl_check.rs
+++ b/crates/hir-ty/src/diagnostics/decl_check.rs
@@ -16,13 +16,13 @@
 use std::fmt;
 
 use hir_def::{
-    data::adt::VariantData, db::DefDatabase, hir::Pat, src::HasSource, AdtId, AttrDefId, ConstId,
-    EnumId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, ModuleDefId, ModuleId,
-    StaticId, StructId, TraitId, TypeAliasId,
+    data::adt::VariantData, db::DefDatabase, hir::Pat, src::HasSource, AdtId, ConstId, EnumId,
+    EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup, ModuleDefId, ModuleId, StaticId,
+    StructId, TraitId, TypeAliasId,
 };
 use hir_expand::{
     name::{AsName, Name},
-    HirFileId, HirFileIdExt, MacroFileIdExt,
+    HirFileId, HirFileIdExt,
 };
 use intern::sym;
 use stdx::{always, never};
@@ -36,14 +36,6 @@
 
 use self::case_conv::{to_camel_case, to_lower_snake_case, to_upper_snake_case};
 
-mod allow {
-    pub(super) const BAD_STYLE: &str = "bad_style";
-    pub(super) const NONSTANDARD_STYLE: &str = "nonstandard_style";
-    pub(super) const NON_SNAKE_CASE: &str = "non_snake_case";
-    pub(super) const NON_UPPER_CASE_GLOBAL: &str = "non_upper_case_globals";
-    pub(super) const NON_CAMEL_CASE_TYPES: &str = "non_camel_case_types";
-}
-
 pub fn incorrect_case(db: &dyn HirDatabase, owner: ModuleDefId) -> Vec<IncorrectCase> {
     let _p = tracing::info_span!("incorrect_case").entered();
     let mut validator = DeclValidator::new(db);
@@ -160,92 +152,7 @@
         }
     }
 
-    /// Checks whether not following the convention is allowed for this item.
-    fn allowed(&self, id: AttrDefId, allow_name: &str, recursing: bool) -> bool {
-        let is_allowed = |def_id| {
-            let attrs = self.db.attrs(def_id);
-            // don't bug the user about directly no_mangle annotated stuff, they can't do anything about it
-            (!recursing && attrs.by_key(&sym::no_mangle).exists())
-                || attrs.by_key(&sym::allow).tt_values().any(|tt| {
-                    let allows = tt.to_string();
-                    allows.contains(allow_name)
-                        || allows.contains(allow::BAD_STYLE)
-                        || allows.contains(allow::NONSTANDARD_STYLE)
-                })
-        };
-        let db = self.db.upcast();
-        let file_id_is_derive = || {
-            match id {
-                AttrDefId::ModuleId(m) => {
-                    m.def_map(db)[m.local_id].origin.file_id().map(Into::into)
-                }
-                AttrDefId::FunctionId(f) => Some(f.lookup(db).id.file_id()),
-                AttrDefId::StaticId(sid) => Some(sid.lookup(db).id.file_id()),
-                AttrDefId::ConstId(cid) => Some(cid.lookup(db).id.file_id()),
-                AttrDefId::TraitId(tid) => Some(tid.lookup(db).id.file_id()),
-                AttrDefId::TraitAliasId(taid) => Some(taid.lookup(db).id.file_id()),
-                AttrDefId::ImplId(iid) => Some(iid.lookup(db).id.file_id()),
-                AttrDefId::ExternBlockId(id) => Some(id.lookup(db).id.file_id()),
-                AttrDefId::ExternCrateId(id) => Some(id.lookup(db).id.file_id()),
-                AttrDefId::UseId(id) => Some(id.lookup(db).id.file_id()),
-                // These warnings should not explore macro definitions at all
-                AttrDefId::MacroId(_) => None,
-                AttrDefId::AdtId(aid) => match aid {
-                    AdtId::StructId(sid) => Some(sid.lookup(db).id.file_id()),
-                    AdtId::EnumId(eid) => Some(eid.lookup(db).id.file_id()),
-                    // Unions aren't yet supported
-                    AdtId::UnionId(_) => None,
-                },
-                AttrDefId::FieldId(_) => None,
-                AttrDefId::EnumVariantId(_) => None,
-                AttrDefId::TypeAliasId(_) => None,
-                AttrDefId::GenericParamId(_) => None,
-            }
-            .map_or(false, |file_id| {
-                matches!(file_id.macro_file(), Some(file_id) if file_id.is_custom_derive(db.upcast()) || file_id.is_builtin_derive(db.upcast()))
-            })
-        };
-
-        let parent = || {
-            match id {
-                AttrDefId::ModuleId(m) => m.containing_module(db).map(|v| v.into()),
-                AttrDefId::FunctionId(f) => Some(f.lookup(db).container.into()),
-                AttrDefId::StaticId(sid) => Some(sid.lookup(db).container.into()),
-                AttrDefId::ConstId(cid) => Some(cid.lookup(db).container.into()),
-                AttrDefId::TraitId(tid) => Some(tid.lookup(db).container.into()),
-                AttrDefId::TraitAliasId(taid) => Some(taid.lookup(db).container.into()),
-                AttrDefId::ImplId(iid) => Some(iid.lookup(db).container.into()),
-                AttrDefId::ExternBlockId(id) => Some(id.lookup(db).container.into()),
-                AttrDefId::ExternCrateId(id) => Some(id.lookup(db).container.into()),
-                AttrDefId::UseId(id) => Some(id.lookup(db).container.into()),
-                // These warnings should not explore macro definitions at all
-                AttrDefId::MacroId(_) => None,
-                AttrDefId::AdtId(aid) => match aid {
-                    AdtId::StructId(sid) => Some(sid.lookup(db).container.into()),
-                    AdtId::EnumId(eid) => Some(eid.lookup(db).container.into()),
-                    // Unions aren't yet supported
-                    AdtId::UnionId(_) => None,
-                },
-                AttrDefId::FieldId(_) => None,
-                AttrDefId::EnumVariantId(_) => None,
-                AttrDefId::TypeAliasId(_) => None,
-                AttrDefId::GenericParamId(_) => None,
-            }
-            .is_some_and(|mid| self.allowed(mid, allow_name, true))
-        };
-        is_allowed(id)
-            // FIXME: this is a hack to avoid false positives in derive macros currently
-            || file_id_is_derive()
-            // go upwards one step or give up
-            || parent()
-    }
-
     fn validate_module(&mut self, module_id: ModuleId) {
-        // Check whether non-snake case identifiers are allowed for this module.
-        if self.allowed(module_id.into(), allow::NON_SNAKE_CASE, false) {
-            return;
-        }
-
         // Check the module name.
         let Some(module_name) = module_id.name(self.db.upcast()) else { return };
         let Some(module_name_replacement) =
@@ -270,11 +177,6 @@
     }
 
     fn validate_trait(&mut self, trait_id: TraitId) {
-        // Check whether non-snake case identifiers are allowed for this trait.
-        if self.allowed(trait_id.into(), allow::NON_CAMEL_CASE_TYPES, false) {
-            return;
-        }
-
         // Check the trait name.
         let data = self.db.trait_data(trait_id);
         self.create_incorrect_case_diagnostic_for_item_name(
@@ -292,21 +194,24 @@
             return;
         }
 
-        // Check whether non-snake case identifiers are allowed for this function.
-        if self.allowed(func.into(), allow::NON_SNAKE_CASE, false) {
-            return;
-        }
-
         // Check the function name.
         // Skipped if function is an associated item of a trait implementation.
         if !self.is_trait_impl_container(container) {
             let data = self.db.function_data(func);
-            self.create_incorrect_case_diagnostic_for_item_name(
-                func,
-                &data.name,
-                CaseType::LowerSnakeCase,
-                IdentType::Function,
-            );
+
+            // Don't run the lint on extern "[not Rust]" fn items with the
+            // #[no_mangle] attribute.
+            let no_mangle = data.attrs.by_key(&sym::no_mangle).exists();
+            if no_mangle && data.abi.as_ref().is_some_and(|abi| *abi != sym::Rust) {
+                cov_mark::hit!(extern_func_no_mangle_ignored);
+            } else {
+                self.create_incorrect_case_diagnostic_for_item_name(
+                    func,
+                    &data.name,
+                    CaseType::LowerSnakeCase,
+                    IdentType::Function,
+                );
+            }
         } else {
             cov_mark::hit!(trait_impl_assoc_func_name_incorrect_case_ignored);
         }
@@ -389,17 +294,13 @@
 
     fn validate_struct(&mut self, struct_id: StructId) {
         // Check the structure name.
-        let non_camel_case_allowed =
-            self.allowed(struct_id.into(), allow::NON_CAMEL_CASE_TYPES, false);
-        if !non_camel_case_allowed {
-            let data = self.db.struct_data(struct_id);
-            self.create_incorrect_case_diagnostic_for_item_name(
-                struct_id,
-                &data.name,
-                CaseType::UpperCamelCase,
-                IdentType::Structure,
-            );
-        }
+        let data = self.db.struct_data(struct_id);
+        self.create_incorrect_case_diagnostic_for_item_name(
+            struct_id,
+            &data.name,
+            CaseType::UpperCamelCase,
+            IdentType::Structure,
+        );
 
         // Check the field names.
         self.validate_struct_fields(struct_id);
@@ -407,10 +308,6 @@
 
     /// Check incorrect names for struct fields.
     fn validate_struct_fields(&mut self, struct_id: StructId) {
-        if self.allowed(struct_id.into(), allow::NON_SNAKE_CASE, false) {
-            return;
-        }
-
         let data = self.db.struct_data(struct_id);
         let VariantData::Record(fields) = data.variant_data.as_ref() else {
             return;
@@ -484,11 +381,6 @@
     fn validate_enum(&mut self, enum_id: EnumId) {
         let data = self.db.enum_data(enum_id);
 
-        // Check whether non-camel case names are allowed for this enum.
-        if self.allowed(enum_id.into(), allow::NON_CAMEL_CASE_TYPES, false) {
-            return;
-        }
-
         // Check the enum name.
         self.create_incorrect_case_diagnostic_for_item_name(
             enum_id,
@@ -653,10 +545,6 @@
             return;
         }
 
-        if self.allowed(const_id.into(), allow::NON_UPPER_CASE_GLOBAL, false) {
-            return;
-        }
-
         let data = self.db.const_data(const_id);
         let Some(name) = &data.name else {
             return;
@@ -676,10 +564,6 @@
             return;
         }
 
-        if self.allowed(static_id.into(), allow::NON_UPPER_CASE_GLOBAL, false) {
-            return;
-        }
-
         self.create_incorrect_case_diagnostic_for_item_name(
             static_id,
             &data.name,
@@ -695,11 +579,6 @@
             return;
         }
 
-        // Check whether non-snake case identifiers are allowed for this type alias.
-        if self.allowed(type_alias_id.into(), allow::NON_CAMEL_CASE_TYPES, false) {
-            return;
-        }
-
         // Check the type alias name.
         let data = self.db.type_alias_data(type_alias_id);
         self.create_incorrect_case_diagnostic_for_item_name(
diff --git a/crates/hir-ty/src/diagnostics/unsafe_check.rs b/crates/hir-ty/src/diagnostics/unsafe_check.rs
index 3f54cdd..ff45c72 100644
--- a/crates/hir-ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir-ty/src/diagnostics/unsafe_check.rs
@@ -5,6 +5,7 @@
     body::Body,
     hir::{Expr, ExprId, UnaryOp},
     resolver::{resolver_for_expr, ResolveValueResult, Resolver, ValueNs},
+    type_ref::Rawness,
     DefWithBodyId,
 };
 
@@ -12,7 +13,10 @@
     db::HirDatabase, utils::is_fn_unsafe_to_call, InferenceResult, Interner, TyExt, TyKind,
 };
 
-pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> Vec<ExprId> {
+/// Returns `(unsafe_exprs, fn_is_unsafe)`.
+///
+/// If `fn_is_unsafe` is false, `unsafe_exprs` are hard errors. If true, they're `unsafe_op_in_unsafe_fn`.
+pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> (Vec<ExprId>, bool) {
     let _p = tracing::info_span!("missing_unsafe").entered();
 
     let mut res = Vec::new();
@@ -23,9 +27,6 @@
         | DefWithBodyId::VariantId(_)
         | DefWithBodyId::InTypeConstId(_) => false,
     };
-    if is_unsafe {
-        return res;
-    }
 
     let body = db.body(def);
     let infer = db.infer(def);
@@ -35,7 +36,7 @@
         }
     });
 
-    res
+    (res, is_unsafe)
 }
 
 pub struct UnsafeExpr {
@@ -87,12 +88,20 @@
             let g = resolver.update_to_inner_scope(db.upcast(), def, current);
             let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path);
             if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial {
-                if db.static_data(id).mutable {
+                let static_data = db.static_data(id);
+                if static_data.mutable || static_data.is_extern {
                     unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block });
                 }
             }
             resolver.reset_to_guard(g);
         }
+        Expr::Ref { expr, rawness: Rawness::RawPtr, mutability: _ } => {
+            if let Expr::Path(_) = body.exprs[*expr] {
+                // Do not report unsafe for `addr_of[_mut]!(EXTERN_OR_MUT_STATIC)`,
+                // see https://github.com/rust-lang/rust/pull/125834.
+                return;
+            }
+        }
         Expr::MethodCall { .. } => {
             if infer
                 .method_resolution(current)
diff --git a/crates/hir-ty/src/generics.rs b/crates/hir-ty/src/generics.rs
index a96c101..89ca707 100644
--- a/crates/hir-ty/src/generics.rs
+++ b/crates/hir-ty/src/generics.rs
@@ -225,6 +225,23 @@
     }
 }
 
+pub(crate) fn trait_self_param_idx(db: &dyn DefDatabase, def: GenericDefId) -> Option<usize> {
+    match def {
+        GenericDefId::TraitId(_) | GenericDefId::TraitAliasId(_) => {
+            let params = db.generic_params(def);
+            params.trait_self_param().map(|idx| idx.into_raw().into_u32() as usize)
+        }
+        GenericDefId::ImplId(_) => None,
+        _ => {
+            let parent_def = parent_generic_def(db, def)?;
+            let parent_params = db.generic_params(parent_def);
+            let parent_self_idx = parent_params.trait_self_param()?.into_raw().into_u32() as usize;
+            let self_params = db.generic_params(def);
+            Some(self_params.len() + parent_self_idx)
+        }
+    }
+}
+
 fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Option<GenericDefId> {
     let container = match def {
         GenericDefId::FunctionId(it) => it.lookup(db).container,
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 062ea27..8bc3c50 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -13,7 +13,7 @@
 //! to certain types. To record this, we use the union-find implementation from
 //! the `ena` crate, which is extracted from rustc.
 
-mod cast;
+pub(crate) mod cast;
 pub(crate) mod closure;
 mod coerce;
 mod expr;
@@ -76,7 +76,7 @@
 #[allow(unreachable_pub)]
 pub use unify::{could_unify, could_unify_deeply};
 
-use cast::CastCheck;
+use cast::{CastCheck, CastError};
 pub(crate) use closure::{CaptureKind, CapturedItem, CapturedItemWithoutTy};
 
 /// The entry point of type inference.
@@ -254,6 +254,16 @@
         expr: ExprId,
         expected: Ty,
     },
+    CastToUnsized {
+        expr: ExprId,
+        cast_ty: Ty,
+    },
+    InvalidCast {
+        expr: ExprId,
+        error: CastError,
+        expr_ty: Ty,
+        cast_ty: Ty,
+    },
 }
 
 /// A mismatch between an expected and an inferred type.
@@ -456,6 +466,7 @@
     pub(crate) closure_info: FxHashMap<ClosureId, (Vec<CapturedItem>, FnTrait)>,
     // FIXME: remove this field
     pub mutated_bindings_in_closure: FxHashSet<BindingId>,
+    pub coercion_casts: FxHashSet<ExprId>,
 }
 
 impl InferenceResult {
@@ -666,7 +677,7 @@
         let InferenceContext {
             mut table,
             mut result,
-            deferred_cast_checks,
+            mut deferred_cast_checks,
             tuple_field_accesses_rev,
             ..
         } = self;
@@ -695,15 +706,25 @@
             closure_info: _,
             mutated_bindings_in_closure: _,
             tuple_field_access_types: _,
+            coercion_casts,
         } = &mut result;
-
         table.fallback_if_possible();
 
         // Comment from rustc:
         // Even though coercion casts provide type hints, we check casts after fallback for
         // backwards compatibility. This makes fallback a stronger type hint than a cast coercion.
-        for cast in deferred_cast_checks {
-            cast.check(&mut table);
+        let mut apply_adjustments = |expr, adj| {
+            expr_adjustments.insert(expr, adj);
+        };
+        let mut set_coercion_cast = |expr| {
+            coercion_casts.insert(expr);
+        };
+        for cast in deferred_cast_checks.iter_mut() {
+            if let Err(diag) =
+                cast.check(&mut table, &mut apply_adjustments, &mut set_coercion_cast)
+            {
+                diagnostics.push(diag);
+            }
         }
 
         // FIXME resolve obligations as well (use Guidance if necessary)
@@ -732,7 +753,7 @@
             *has_errors = *has_errors || ty.contains_unknown();
         }
 
-        *has_errors = !type_mismatches.is_empty();
+        *has_errors |= !type_mismatches.is_empty();
 
         type_mismatches.retain(|_, mismatch| {
             mismatch.expected = table.resolve_completely(mismatch.expected.clone());
@@ -775,20 +796,30 @@
         });
         for (_, subst) in method_resolutions.values_mut() {
             *subst = table.resolve_completely(subst.clone());
+            *has_errors =
+                *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
         }
         for (_, subst) in assoc_resolutions.values_mut() {
             *subst = table.resolve_completely(subst.clone());
+            *has_errors =
+                *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
         }
         for adjustment in expr_adjustments.values_mut().flatten() {
             adjustment.target = table.resolve_completely(adjustment.target.clone());
+            *has_errors = *has_errors || adjustment.target.contains_unknown();
         }
         for adjustment in pat_adjustments.values_mut().flatten() {
             *adjustment = table.resolve_completely(adjustment.clone());
+            *has_errors = *has_errors || adjustment.contains_unknown();
         }
         result.tuple_field_access_types = tuple_field_accesses_rev
             .into_iter()
             .enumerate()
             .map(|(idx, subst)| (TupleId(idx as u32), table.resolve_completely(subst)))
+            .inspect(|(_, subst)| {
+                *has_errors =
+                    *has_errors || subst.type_parameters(Interner).any(|ty| ty.contains_unknown());
+            })
             .collect();
         result
     }
diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs
index 060b5f3..caa3960 100644
--- a/crates/hir-ty/src/infer/cast.rs
+++ b/crates/hir-ty/src/infer/cast.rs
@@ -1,47 +1,451 @@
 //! Type cast logic. Basically coercion + additional casts.
 
-use crate::{infer::unify::InferenceTable, Interner, Ty, TyExt, TyKind};
+use chalk_ir::{Mutability, Scalar, TyVariableKind, UintTy};
+use hir_def::{hir::ExprId, AdtId};
+use stdx::never;
+
+use crate::{
+    infer::unify::InferenceTable, Adjustment, Binders, DynTy, InferenceDiagnostic, Interner,
+    PlaceholderIndex, QuantifiedWhereClauses, Ty, TyExt, TyKind, TypeFlags, WhereClause,
+};
+
+#[derive(Debug)]
+pub(crate) enum Int {
+    I,
+    U(UintTy),
+    Bool,
+    Char,
+    CEnum,
+    InferenceVar,
+}
+
+#[derive(Debug)]
+pub(crate) enum CastTy {
+    Int(Int),
+    Float,
+    FnPtr,
+    Ptr(Ty, Mutability),
+    // `DynStar` is Not supported yet in r-a
+}
+
+impl CastTy {
+    pub(crate) fn from_ty(table: &mut InferenceTable<'_>, t: &Ty) -> Option<Self> {
+        match t.kind(Interner) {
+            TyKind::Scalar(Scalar::Bool) => Some(Self::Int(Int::Bool)),
+            TyKind::Scalar(Scalar::Char) => Some(Self::Int(Int::Char)),
+            TyKind::Scalar(Scalar::Int(_)) => Some(Self::Int(Int::I)),
+            TyKind::Scalar(Scalar::Uint(it)) => Some(Self::Int(Int::U(*it))),
+            TyKind::InferenceVar(_, TyVariableKind::Integer) => Some(Self::Int(Int::InferenceVar)),
+            TyKind::InferenceVar(_, TyVariableKind::Float) => Some(Self::Float),
+            TyKind::Scalar(Scalar::Float(_)) => Some(Self::Float),
+            TyKind::Adt(..) => {
+                let (AdtId::EnumId(id), _) = t.as_adt()? else {
+                    return None;
+                };
+                let enum_data = table.db.enum_data(id);
+                if enum_data.is_payload_free(table.db.upcast()) {
+                    Some(Self::Int(Int::CEnum))
+                } else {
+                    None
+                }
+            }
+            TyKind::Raw(m, ty) => Some(Self::Ptr(table.resolve_ty_shallow(ty), *m)),
+            TyKind::Function(_) => Some(Self::FnPtr),
+            _ => None,
+        }
+    }
+}
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+pub enum CastError {
+    Unknown,
+    CastToBool,
+    CastToChar,
+    DifferingKinds,
+    SizedUnsizedCast,
+    IllegalCast,
+    IntToFatCast,
+    NeedDeref,
+    NeedViaPtr,
+    NeedViaThinPtr,
+    NeedViaInt,
+    NonScalar,
+    UnknownCastPtrKind,
+    UnknownExprPtrKind,
+}
+
+impl CastError {
+    fn into_diagnostic(self, expr: ExprId, expr_ty: Ty, cast_ty: Ty) -> InferenceDiagnostic {
+        InferenceDiagnostic::InvalidCast { expr, error: self, expr_ty, cast_ty }
+    }
+}
 
 #[derive(Clone, Debug)]
 pub(super) struct CastCheck {
+    expr: ExprId,
+    source_expr: ExprId,
     expr_ty: Ty,
     cast_ty: Ty,
 }
 
 impl CastCheck {
-    pub(super) fn new(expr_ty: Ty, cast_ty: Ty) -> Self {
-        Self { expr_ty, cast_ty }
+    pub(super) fn new(expr: ExprId, source_expr: ExprId, expr_ty: Ty, cast_ty: Ty) -> Self {
+        Self { expr, source_expr, expr_ty, cast_ty }
     }
 
-    pub(super) fn check(self, table: &mut InferenceTable<'_>) {
-        // FIXME: This function currently only implements the bits that influence the type
-        // inference. We should return the adjustments on success and report diagnostics on error.
-        let expr_ty = table.resolve_ty_shallow(&self.expr_ty);
-        let cast_ty = table.resolve_ty_shallow(&self.cast_ty);
+    pub(super) fn check<F, G>(
+        &mut self,
+        table: &mut InferenceTable<'_>,
+        apply_adjustments: &mut F,
+        set_coercion_cast: &mut G,
+    ) -> Result<(), InferenceDiagnostic>
+    where
+        F: FnMut(ExprId, Vec<Adjustment>),
+        G: FnMut(ExprId),
+    {
+        table.resolve_obligations_as_possible();
+        self.expr_ty = table.resolve_ty_shallow(&self.expr_ty);
+        self.cast_ty = table.resolve_ty_shallow(&self.cast_ty);
 
-        if table.coerce(&expr_ty, &cast_ty).is_ok() {
-            return;
+        if self.expr_ty.contains_unknown() || self.cast_ty.contains_unknown() {
+            return Ok(());
         }
 
-        if check_ref_to_ptr_cast(expr_ty, cast_ty, table) {
-            // Note that this type of cast is actually split into a coercion to a
-            // pointer type and a cast:
-            // &[T; N] -> *[T; N] -> *T
+        if !self.cast_ty.data(Interner).flags.contains(TypeFlags::HAS_TY_INFER)
+            && !table.is_sized(&self.cast_ty)
+        {
+            return Err(InferenceDiagnostic::CastToUnsized {
+                expr: self.expr,
+                cast_ty: self.cast_ty.clone(),
+            });
         }
 
-        // FIXME: Check other kinds of non-coercion casts and report error if any?
+        // Chalk doesn't support trait upcasting and fails to solve some obvious goals
+        // when the trait environment contains some recursive traits (See issue #18047)
+        // We skip cast checks for such cases for now, until the next-gen solver.
+        if contains_dyn_trait(&self.cast_ty) {
+            return Ok(());
+        }
+
+        if let Ok((adj, _)) = table.coerce(&self.expr_ty, &self.cast_ty) {
+            apply_adjustments(self.source_expr, adj);
+            set_coercion_cast(self.source_expr);
+            return Ok(());
+        }
+
+        self.do_check(table, apply_adjustments)
+            .map_err(|e| e.into_diagnostic(self.expr, self.expr_ty.clone(), self.cast_ty.clone()))
+    }
+
+    fn do_check<F>(
+        &self,
+        table: &mut InferenceTable<'_>,
+        apply_adjustments: &mut F,
+    ) -> Result<(), CastError>
+    where
+        F: FnMut(ExprId, Vec<Adjustment>),
+    {
+        let (t_from, t_cast) =
+            match (CastTy::from_ty(table, &self.expr_ty), CastTy::from_ty(table, &self.cast_ty)) {
+                (Some(t_from), Some(t_cast)) => (t_from, t_cast),
+                (None, Some(t_cast)) => match self.expr_ty.kind(Interner) {
+                    TyKind::FnDef(..) => {
+                        let sig = self.expr_ty.callable_sig(table.db).expect("FnDef had no sig");
+                        let sig = table.normalize_associated_types_in(sig);
+                        let fn_ptr = TyKind::Function(sig.to_fn_ptr()).intern(Interner);
+                        if let Ok((adj, _)) = table.coerce(&self.expr_ty, &fn_ptr) {
+                            apply_adjustments(self.source_expr, adj);
+                        } else {
+                            return Err(CastError::IllegalCast);
+                        }
+
+                        (CastTy::FnPtr, t_cast)
+                    }
+                    TyKind::Ref(mutbl, _, inner_ty) => {
+                        let inner_ty = table.resolve_ty_shallow(inner_ty);
+                        return match t_cast {
+                            CastTy::Int(_) | CastTy::Float => match inner_ty.kind(Interner) {
+                                TyKind::Scalar(
+                                    Scalar::Int(_) | Scalar::Uint(_) | Scalar::Float(_),
+                                )
+                                | TyKind::InferenceVar(
+                                    _,
+                                    TyVariableKind::Integer | TyVariableKind::Float,
+                                ) => Err(CastError::NeedDeref),
+
+                                _ => Err(CastError::NeedViaPtr),
+                            },
+                            // array-ptr-cast
+                            CastTy::Ptr(t, m) => {
+                                let t = table.resolve_ty_shallow(&t);
+                                if !table.is_sized(&t) {
+                                    return Err(CastError::IllegalCast);
+                                }
+                                self.check_ref_cast(
+                                    table,
+                                    &inner_ty,
+                                    *mutbl,
+                                    &t,
+                                    m,
+                                    apply_adjustments,
+                                )
+                            }
+                            _ => Err(CastError::NonScalar),
+                        };
+                    }
+                    _ => return Err(CastError::NonScalar),
+                },
+                _ => return Err(CastError::NonScalar),
+            };
+
+        // rustc checks whether the `expr_ty` is foreign adt with `non_exhaustive` sym
+
+        match (t_from, t_cast) {
+            (_, CastTy::Int(Int::CEnum) | CastTy::FnPtr) => Err(CastError::NonScalar),
+            (_, CastTy::Int(Int::Bool)) => Err(CastError::CastToBool),
+            (CastTy::Int(Int::U(UintTy::U8)), CastTy::Int(Int::Char)) => Ok(()),
+            (_, CastTy::Int(Int::Char)) => Err(CastError::CastToChar),
+            (CastTy::Int(Int::Bool | Int::CEnum | Int::Char), CastTy::Float) => {
+                Err(CastError::NeedViaInt)
+            }
+            (CastTy::Int(Int::Bool | Int::CEnum | Int::Char) | CastTy::Float, CastTy::Ptr(..))
+            | (CastTy::Ptr(..) | CastTy::FnPtr, CastTy::Float) => Err(CastError::IllegalCast),
+            (CastTy::Ptr(src, _), CastTy::Ptr(dst, _)) => {
+                self.check_ptr_ptr_cast(table, &src, &dst)
+            }
+            (CastTy::Ptr(src, _), CastTy::Int(_)) => self.check_ptr_addr_cast(table, &src),
+            (CastTy::Int(_), CastTy::Ptr(dst, _)) => self.check_addr_ptr_cast(table, &dst),
+            (CastTy::FnPtr, CastTy::Ptr(dst, _)) => self.check_fptr_ptr_cast(table, &dst),
+            (CastTy::Int(Int::CEnum), CastTy::Int(_)) => Ok(()),
+            (CastTy::Int(Int::Char | Int::Bool), CastTy::Int(_)) => Ok(()),
+            (CastTy::Int(_) | CastTy::Float, CastTy::Int(_) | CastTy::Float) => Ok(()),
+            (CastTy::FnPtr, CastTy::Int(_)) => Ok(()),
+        }
+    }
+
+    fn check_ref_cast<F>(
+        &self,
+        table: &mut InferenceTable<'_>,
+        t_expr: &Ty,
+        m_expr: Mutability,
+        t_cast: &Ty,
+        m_cast: Mutability,
+        apply_adjustments: &mut F,
+    ) -> Result<(), CastError>
+    where
+        F: FnMut(ExprId, Vec<Adjustment>),
+    {
+        // Mutability order is opposite to rustc. `Mut < Not`
+        if m_expr <= m_cast {
+            if let TyKind::Array(ety, _) = t_expr.kind(Interner) {
+                // Coerce to a raw pointer so that we generate RawPtr in MIR.
+                let array_ptr_type = TyKind::Raw(m_expr, t_expr.clone()).intern(Interner);
+                if let Ok((adj, _)) = table.coerce(&self.expr_ty, &array_ptr_type) {
+                    apply_adjustments(self.source_expr, adj);
+                } else {
+                    never!(
+                        "could not cast from reference to array to pointer to array ({:?} to {:?})",
+                        self.expr_ty,
+                        array_ptr_type
+                    );
+                }
+
+                // This is a less strict condition than rustc's `demand_eqtype`,
+                // but false negative is better than false positive
+                if table.coerce(ety, t_cast).is_ok() {
+                    return Ok(());
+                }
+            }
+        }
+
+        Err(CastError::IllegalCast)
+    }
+
+    fn check_ptr_ptr_cast(
+        &self,
+        table: &mut InferenceTable<'_>,
+        src: &Ty,
+        dst: &Ty,
+    ) -> Result<(), CastError> {
+        let src_kind = pointer_kind(src, table).map_err(|_| CastError::Unknown)?;
+        let dst_kind = pointer_kind(dst, table).map_err(|_| CastError::Unknown)?;
+
+        match (src_kind, dst_kind) {
+            (Some(PointerKind::Error), _) | (_, Some(PointerKind::Error)) => Ok(()),
+            (_, None) => Err(CastError::UnknownCastPtrKind),
+            (_, Some(PointerKind::Thin)) => Ok(()),
+            (None, _) => Err(CastError::UnknownExprPtrKind),
+            (Some(PointerKind::Thin), _) => Err(CastError::SizedUnsizedCast),
+            (Some(PointerKind::VTable(src_tty)), Some(PointerKind::VTable(dst_tty))) => {
+                let principal = |tty: &Binders<QuantifiedWhereClauses>| {
+                    tty.skip_binders().as_slice(Interner).first().and_then(|pred| {
+                        if let WhereClause::Implemented(tr) = pred.skip_binders() {
+                            Some(tr.trait_id)
+                        } else {
+                            None
+                        }
+                    })
+                };
+                match (principal(&src_tty), principal(&dst_tty)) {
+                    (Some(src_principal), Some(dst_principal)) => {
+                        if src_principal == dst_principal {
+                            return Ok(());
+                        }
+                        let src_principal =
+                            table.db.trait_datum(table.trait_env.krate, src_principal);
+                        let dst_principal =
+                            table.db.trait_datum(table.trait_env.krate, dst_principal);
+                        if src_principal.is_auto_trait() && dst_principal.is_auto_trait() {
+                            Ok(())
+                        } else {
+                            Err(CastError::DifferingKinds)
+                        }
+                    }
+                    _ => Err(CastError::Unknown),
+                }
+            }
+            (Some(src_kind), Some(dst_kind)) if src_kind == dst_kind => Ok(()),
+            (_, _) => Err(CastError::DifferingKinds),
+        }
+    }
+
+    fn check_ptr_addr_cast(
+        &self,
+        table: &mut InferenceTable<'_>,
+        expr_ty: &Ty,
+    ) -> Result<(), CastError> {
+        match pointer_kind(expr_ty, table).map_err(|_| CastError::Unknown)? {
+            None => Err(CastError::UnknownExprPtrKind),
+            Some(PointerKind::Error) => Ok(()),
+            Some(PointerKind::Thin) => Ok(()),
+            _ => Err(CastError::NeedViaThinPtr),
+        }
+    }
+
+    fn check_addr_ptr_cast(
+        &self,
+        table: &mut InferenceTable<'_>,
+        cast_ty: &Ty,
+    ) -> Result<(), CastError> {
+        match pointer_kind(cast_ty, table).map_err(|_| CastError::Unknown)? {
+            None => Err(CastError::UnknownCastPtrKind),
+            Some(PointerKind::Error) => Ok(()),
+            Some(PointerKind::Thin) => Ok(()),
+            Some(PointerKind::VTable(_)) => Err(CastError::IntToFatCast),
+            Some(PointerKind::Length) => Err(CastError::IntToFatCast),
+            Some(PointerKind::OfAlias | PointerKind::OfParam(_)) => Err(CastError::IntToFatCast),
+        }
+    }
+
+    fn check_fptr_ptr_cast(
+        &self,
+        table: &mut InferenceTable<'_>,
+        cast_ty: &Ty,
+    ) -> Result<(), CastError> {
+        match pointer_kind(cast_ty, table).map_err(|_| CastError::Unknown)? {
+            None => Err(CastError::UnknownCastPtrKind),
+            Some(PointerKind::Error) => Ok(()),
+            Some(PointerKind::Thin) => Ok(()),
+            _ => Err(CastError::IllegalCast),
+        }
     }
 }
 
-fn check_ref_to_ptr_cast(expr_ty: Ty, cast_ty: Ty, table: &mut InferenceTable<'_>) -> bool {
-    let Some((expr_inner_ty, _, _)) = expr_ty.as_reference() else {
-        return false;
+#[derive(PartialEq, Eq)]
+enum PointerKind {
+    // thin pointer
+    Thin,
+    // trait object
+    VTable(Binders<QuantifiedWhereClauses>),
+    // slice
+    Length,
+    OfAlias,
+    OfParam(PlaceholderIndex),
+    Error,
+}
+
+fn pointer_kind(ty: &Ty, table: &mut InferenceTable<'_>) -> Result<Option<PointerKind>, ()> {
+    let ty = table.resolve_ty_shallow(ty);
+
+    if table.is_sized(&ty) {
+        return Ok(Some(PointerKind::Thin));
+    }
+
+    match ty.kind(Interner) {
+        TyKind::Slice(_) | TyKind::Str => Ok(Some(PointerKind::Length)),
+        TyKind::Dyn(DynTy { bounds, .. }) => Ok(Some(PointerKind::VTable(bounds.clone()))),
+        TyKind::Adt(chalk_ir::AdtId(id), subst) => {
+            let AdtId::StructId(id) = *id else {
+                never!("`{:?}` should be sized but is not?", ty);
+                return Err(());
+            };
+
+            let struct_data = table.db.struct_data(id);
+            if let Some((last_field, _)) = struct_data.variant_data.fields().iter().last() {
+                let last_field_ty =
+                    table.db.field_types(id.into())[last_field].clone().substitute(Interner, subst);
+                pointer_kind(&last_field_ty, table)
+            } else {
+                Ok(Some(PointerKind::Thin))
+            }
+        }
+        TyKind::Tuple(_, subst) => {
+            match subst.iter(Interner).last().and_then(|arg| arg.ty(Interner)) {
+                None => Ok(Some(PointerKind::Thin)),
+                Some(ty) => pointer_kind(ty, table),
+            }
+        }
+        TyKind::Foreign(_) => Ok(Some(PointerKind::Thin)),
+        TyKind::Alias(_) | TyKind::AssociatedType(..) | TyKind::OpaqueType(..) => {
+            Ok(Some(PointerKind::OfAlias))
+        }
+        TyKind::Error => Ok(Some(PointerKind::Error)),
+        TyKind::Placeholder(idx) => Ok(Some(PointerKind::OfParam(*idx))),
+        TyKind::BoundVar(_) | TyKind::InferenceVar(..) => Ok(None),
+        TyKind::Scalar(_)
+        | TyKind::Array(..)
+        | TyKind::CoroutineWitness(..)
+        | TyKind::Raw(..)
+        | TyKind::Ref(..)
+        | TyKind::FnDef(..)
+        | TyKind::Function(_)
+        | TyKind::Closure(..)
+        | TyKind::Coroutine(..)
+        | TyKind::Never => {
+            never!("`{:?}` should be sized but is not?", ty);
+            Err(())
+        }
+    }
+}
+
+fn contains_dyn_trait(ty: &Ty) -> bool {
+    use std::ops::ControlFlow;
+
+    use chalk_ir::{
+        visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
+        DebruijnIndex,
     };
-    let Some((cast_inner_ty, _)) = cast_ty.as_raw_ptr() else {
-        return false;
-    };
-    let TyKind::Array(expr_elt_ty, _) = expr_inner_ty.kind(Interner) else {
-        return false;
-    };
-    table.coerce(expr_elt_ty, cast_inner_ty).is_ok()
+
+    struct DynTraitVisitor;
+
+    impl TypeVisitor<Interner> for DynTraitVisitor {
+        type BreakTy = ();
+
+        fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
+            self
+        }
+
+        fn interner(&self) -> Interner {
+            Interner
+        }
+
+        fn visit_ty(&mut self, ty: &Ty, outer_binder: DebruijnIndex) -> ControlFlow<Self::BreakTy> {
+            match ty.kind(Interner) {
+                TyKind::Dyn(_) => ControlFlow::Break(()),
+                _ => ty.super_visit_with(self.as_dyn(), outer_binder),
+            }
+        }
+    }
+
+    ty.visit_with(DynTraitVisitor.as_dyn(), DebruijnIndex::INNERMOST).is_break()
 }
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 36327d1..5cad08b 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -10,7 +10,10 @@
 use either::Either;
 use hir_def::{
     data::adt::VariantData,
-    hir::{Array, BinaryOp, BindingId, CaptureBy, Expr, ExprId, Pat, PatId, Statement, UnaryOp},
+    hir::{
+        Array, AsmOperand, BinaryOp, BindingId, CaptureBy, Expr, ExprId, Pat, PatId, Statement,
+        UnaryOp,
+    },
     lang_item::LangItem,
     resolver::{resolver_for_expr, ResolveValueResult, ValueNs},
     DefWithBodyId, FieldId, HasModule, TupleFieldId, TupleId, VariantId,
@@ -666,7 +669,21 @@
     fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) {
         match &self.body[tgt_expr] {
             Expr::OffsetOf(_) => (),
-            Expr::InlineAsm(e) => self.walk_expr_without_adjust(e.e),
+            Expr::InlineAsm(e) => e.operands.iter().for_each(|(_, op)| match op {
+                AsmOperand::In { expr, .. }
+                | AsmOperand::Out { expr: Some(expr), .. }
+                | AsmOperand::InOut { expr, .. } => self.walk_expr_without_adjust(*expr),
+                AsmOperand::SplitInOut { in_expr, out_expr, .. } => {
+                    self.walk_expr_without_adjust(*in_expr);
+                    if let Some(out_expr) = out_expr {
+                        self.walk_expr_without_adjust(*out_expr);
+                    }
+                }
+                AsmOperand::Out { expr: None, .. }
+                | AsmOperand::Const(_)
+                | AsmOperand::Label(_)
+                | AsmOperand::Sym(_) => (),
+            }),
             Expr::If { condition, then_branch, else_branch } => {
                 self.consume_expr(*condition);
                 self.consume_expr(*then_branch);
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 89d92ea..a04e7b1 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -9,7 +9,8 @@
 use either::Either;
 use hir_def::{
     hir::{
-        ArithOp, Array, BinaryOp, ClosureKind, Expr, ExprId, LabelId, Literal, Statement, UnaryOp,
+        ArithOp, Array, AsmOperand, AsmOptions, BinaryOp, ClosureKind, Expr, ExprId, LabelId,
+        Literal, Statement, UnaryOp,
     },
     lang_item::{LangItem, LangItemTarget},
     path::{GenericArg, GenericArgs, Path},
@@ -41,9 +42,9 @@
     primitive::{self, UintTy},
     static_lifetime, to_chalk_trait_id,
     traits::FnTrait,
-    Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, FnAbi, FnPointer, FnSig,
-    FnSubst, Interner, Rawness, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder,
-    TyExt, TyKind,
+    Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, CallableSig, FnAbi, FnPointer,
+    FnSig, FnSubst, Interner, Rawness, Scalar, Substitution, TraitEnvironment, TraitRef, Ty,
+    TyBuilder, TyExt, TyKind,
 };
 
 use super::{
@@ -610,7 +611,12 @@
             Expr::Cast { expr, type_ref } => {
                 let cast_ty = self.make_ty(type_ref);
                 let expr_ty = self.infer_expr(*expr, &Expectation::Castable(cast_ty.clone()));
-                self.deferred_cast_checks.push(CastCheck::new(expr_ty, cast_ty.clone()));
+                self.deferred_cast_checks.push(CastCheck::new(
+                    tgt_expr,
+                    *expr,
+                    expr_ty,
+                    cast_ty.clone(),
+                ));
                 cast_ty
             }
             Expr::Ref { expr, rawness, mutability } => {
@@ -845,7 +851,7 @@
                 };
 
                 for (expr, ty) in exprs.iter().zip(tys.iter_mut()) {
-                    self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
+                    *ty = self.infer_expr_coerce(*expr, &Expectation::has_type(ty.clone()));
                 }
 
                 TyKind::Tuple(tys.len(), Substitution::from_iter(Interner, tys)).intern(Interner)
@@ -889,21 +895,52 @@
                         TyKind::Scalar(Scalar::Int(primitive::int_ty_from_builtin(*int_ty)))
                             .intern(Interner)
                     }
-                    None => self.table.new_integer_var(),
+                    None => {
+                        let expected_ty = expected.to_option(&mut self.table);
+                        let opt_ty = match expected_ty.as_ref().map(|it| it.kind(Interner)) {
+                            Some(TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))) => expected_ty,
+                            Some(TyKind::Scalar(Scalar::Char)) => {
+                                Some(TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner))
+                            }
+                            Some(TyKind::Raw(..) | TyKind::FnDef(..) | TyKind::Function(..)) => {
+                                Some(TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner))
+                            }
+                            _ => None,
+                        };
+                        opt_ty.unwrap_or_else(|| self.table.new_integer_var())
+                    }
                 },
                 Literal::Uint(_v, ty) => match ty {
                     Some(int_ty) => {
                         TyKind::Scalar(Scalar::Uint(primitive::uint_ty_from_builtin(*int_ty)))
                             .intern(Interner)
                     }
-                    None => self.table.new_integer_var(),
+                    None => {
+                        let expected_ty = expected.to_option(&mut self.table);
+                        let opt_ty = match expected_ty.as_ref().map(|it| it.kind(Interner)) {
+                            Some(TyKind::Scalar(Scalar::Int(_) | Scalar::Uint(_))) => expected_ty,
+                            Some(TyKind::Scalar(Scalar::Char)) => {
+                                Some(TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner))
+                            }
+                            Some(TyKind::Raw(..) | TyKind::FnDef(..) | TyKind::Function(..)) => {
+                                Some(TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner))
+                            }
+                            _ => None,
+                        };
+                        opt_ty.unwrap_or_else(|| self.table.new_integer_var())
+                    }
                 },
                 Literal::Float(_v, ty) => match ty {
                     Some(float_ty) => {
                         TyKind::Scalar(Scalar::Float(primitive::float_ty_from_builtin(*float_ty)))
                             .intern(Interner)
                     }
-                    None => self.table.new_float_var(),
+                    None => {
+                        let opt_ty = expected.to_option(&mut self.table).filter(|ty| {
+                            matches!(ty.kind(Interner), TyKind::Scalar(Scalar::Float(_)))
+                        });
+                        opt_ty.unwrap_or_else(|| self.table.new_float_var())
+                    }
                 },
             },
             Expr::Underscore => {
@@ -919,9 +956,61 @@
                 expected
             }
             Expr::OffsetOf(_) => TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(Interner),
-            Expr::InlineAsm(it) => {
-                self.infer_expr_no_expect(it.e);
-                self.result.standard_types.unit.clone()
+            Expr::InlineAsm(asm) => {
+                let mut check_expr_asm_operand = |expr, is_input: bool| {
+                    let ty = self.infer_expr_no_expect(expr);
+
+                    // If this is an input value, we require its type to be fully resolved
+                    // at this point. This allows us to provide helpful coercions which help
+                    // pass the type candidate list in a later pass.
+                    //
+                    // We don't require output types to be resolved at this point, which
+                    // allows them to be inferred based on how they are used later in the
+                    // function.
+                    if is_input {
+                        let ty = self.resolve_ty_shallow(&ty);
+                        match ty.kind(Interner) {
+                            TyKind::FnDef(def, parameters) => {
+                                let fnptr_ty = TyKind::Function(
+                                    CallableSig::from_def(self.db, *def, parameters).to_fn_ptr(),
+                                )
+                                .intern(Interner);
+                                _ = self.coerce(Some(expr), &ty, &fnptr_ty);
+                            }
+                            TyKind::Ref(mutbl, _, base_ty) => {
+                                let ptr_ty = TyKind::Raw(*mutbl, base_ty.clone()).intern(Interner);
+                                _ = self.coerce(Some(expr), &ty, &ptr_ty);
+                            }
+                            _ => {}
+                        }
+                    }
+                };
+
+                let diverge = asm.options.contains(AsmOptions::NORETURN);
+                asm.operands.iter().for_each(|(_, operand)| match *operand {
+                    AsmOperand::In { expr, .. } => check_expr_asm_operand(expr, true),
+                    AsmOperand::Out { expr: Some(expr), .. } | AsmOperand::InOut { expr, .. } => {
+                        check_expr_asm_operand(expr, false)
+                    }
+                    AsmOperand::Out { expr: None, .. } => (),
+                    AsmOperand::SplitInOut { in_expr, out_expr, .. } => {
+                        check_expr_asm_operand(in_expr, true);
+                        if let Some(out_expr) = out_expr {
+                            check_expr_asm_operand(out_expr, false);
+                        }
+                    }
+                    // FIXME
+                    AsmOperand::Label(_) => (),
+                    // FIXME
+                    AsmOperand::Const(_) => (),
+                    // FIXME
+                    AsmOperand::Sym(_) => (),
+                });
+                if diverge {
+                    self.result.standard_types.never.clone()
+                } else {
+                    self.result.standard_types.unit.clone()
+                }
             }
         };
         // use a new type variable if we got unknown here
diff --git a/crates/hir-ty/src/infer/mutability.rs b/crates/hir-ty/src/infer/mutability.rs
index 7fed5f0..8e52725 100644
--- a/crates/hir-ty/src/infer/mutability.rs
+++ b/crates/hir-ty/src/infer/mutability.rs
@@ -3,7 +3,9 @@
 
 use chalk_ir::{cast::Cast, Mutability};
 use hir_def::{
-    hir::{Array, BinaryOp, BindingAnnotation, Expr, ExprId, PatId, Statement, UnaryOp},
+    hir::{
+        Array, AsmOperand, BinaryOp, BindingAnnotation, Expr, ExprId, PatId, Statement, UnaryOp,
+    },
     lang_item::LangItem,
 };
 use hir_expand::name::Name;
@@ -39,7 +41,25 @@
     fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutability) {
         match &self.body[tgt_expr] {
             Expr::Missing => (),
-            Expr::InlineAsm(e) => self.infer_mut_expr_without_adjust(e.e, Mutability::Not),
+            Expr::InlineAsm(e) => {
+                e.operands.iter().for_each(|(_, op)| match op {
+                    AsmOperand::In { expr, .. }
+                    | AsmOperand::Out { expr: Some(expr), .. }
+                    | AsmOperand::InOut { expr, .. } => {
+                        self.infer_mut_expr_without_adjust(*expr, Mutability::Not)
+                    }
+                    AsmOperand::SplitInOut { in_expr, out_expr, .. } => {
+                        self.infer_mut_expr_without_adjust(*in_expr, Mutability::Not);
+                        if let Some(out_expr) = out_expr {
+                            self.infer_mut_expr_without_adjust(*out_expr, Mutability::Not);
+                        }
+                    }
+                    AsmOperand::Out { expr: None, .. }
+                    | AsmOperand::Label(_)
+                    | AsmOperand::Sym(_)
+                    | AsmOperand::Const(_) => (),
+                });
+            }
             Expr::OffsetOf(_) => (),
             &Expr::If { condition, then_branch, else_branch } => {
                 self.infer_mut_expr(condition, Mutability::Not);
@@ -129,7 +149,7 @@
                                     target,
                                 }) = base_adjustments
                                 {
-                                    // For assignee exprs `IndexMut` obiligations are already applied
+                                    // For assignee exprs `IndexMut` obligations are already applied
                                     if !is_assignee_expr {
                                         if let TyKind::Ref(_, _, ty) = target.kind(Interner) {
                                             base_ty = Some(ty.clone());
diff --git a/crates/hir-ty/src/infer/path.rs b/crates/hir-ty/src/infer/path.rs
index 0b44bbe..e4841c7 100644
--- a/crates/hir-ty/src/infer/path.rs
+++ b/crates/hir-ty/src/infer/path.rs
@@ -247,8 +247,12 @@
                     &self.resolver,
                     self.owner.into(),
                 );
-                let trait_ref =
-                    ctx.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
+                let trait_ref = ctx.lower_trait_ref_from_resolved_path(
+                    trait_,
+                    resolved_segment,
+                    self.table.new_type_var(),
+                );
+
                 self.resolve_trait_assoc_item(trait_ref, segment, id)
             }
             (def, _) => {
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index c0f5ddd..7300453 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -9,6 +9,7 @@
 use chalk_solve::infer::ParameterEnaVariableExt;
 use either::Either;
 use ena::unify::UnifyKey;
+use hir_def::{lang_item::LangItem, AdtId};
 use hir_expand::name::Name;
 use intern::sym;
 use rustc_hash::FxHashMap;
@@ -21,7 +22,7 @@
     to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue,
     DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData, Guidance, InEnvironment,
     InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy, ProjectionTyExt, Scalar,
-    Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, VariableKind,
+    Solution, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt, TyKind, VariableKind,
     WhereClause,
 };
 
@@ -265,14 +266,16 @@
             }
             let v = InferenceVar::from(i as u32);
             let root = self.var_unification_table.inference_var_root(v);
-            if let Some(data) = self.type_variable_table.get_mut(root.index() as usize) {
-                *data |= TypeVariableFlags::DIVERGING;
-            }
+            self.modify_type_variable_flag(root, |f| {
+                *f |= TypeVariableFlags::DIVERGING;
+            });
         }
     }
 
     pub(super) fn set_diverging(&mut self, iv: InferenceVar, diverging: bool) {
-        self.type_variable_table[iv.index() as usize].set(TypeVariableFlags::DIVERGING, diverging);
+        self.modify_type_variable_flag(iv, |f| {
+            f.set(TypeVariableFlags::DIVERGING, diverging);
+        });
     }
 
     fn fallback_value(&self, iv: InferenceVar, kind: TyVariableKind) -> Ty {
@@ -369,6 +372,18 @@
         var
     }
 
+    fn modify_type_variable_flag<F>(&mut self, var: InferenceVar, cb: F)
+    where
+        F: FnOnce(&mut TypeVariableFlags),
+    {
+        let idx = var.index() as usize;
+        if self.type_variable_table.len() <= idx {
+            self.extend_type_variable_table(idx);
+        }
+        if let Some(f) = self.type_variable_table.get_mut(idx) {
+            cb(f);
+        }
+    }
     fn extend_type_variable_table(&mut self, to_index: usize) {
         let count = to_index - self.type_variable_table.len() + 1;
         self.type_variable_table.extend(iter::repeat(TypeVariableFlags::default()).take(count));
@@ -898,6 +913,37 @@
             _ => c,
         }
     }
+
+    /// Check if given type is `Sized` or not
+    pub(crate) fn is_sized(&mut self, ty: &Ty) -> bool {
+        // Early return for some obvious types
+        if matches!(ty.kind(Interner), TyKind::Scalar(..) | TyKind::Ref(..) | TyKind::Raw(..)) {
+            return true;
+        }
+        if let Some((AdtId::StructId(id), subst)) = ty.as_adt() {
+            let struct_data = self.db.struct_data(id);
+            if let Some((last_field, _)) = struct_data.variant_data.fields().iter().last() {
+                let last_field_ty =
+                    self.db.field_types(id.into())[last_field].clone().substitute(Interner, subst);
+                // Structs can have DST as its last field and such cases are not handled
+                // as unsized by the chalk, so we do this manually
+                return self.is_sized(&last_field_ty);
+            }
+        }
+        let Some(sized) = self
+            .db
+            .lang_item(self.trait_env.krate, LangItem::Sized)
+            .and_then(|sized| sized.as_trait())
+        else {
+            return false;
+        };
+        let sized_pred = WhereClause::Implemented(TraitRef {
+            trait_id: to_chalk_trait_id(sized),
+            substitution: Substitution::from1(Interner, ty.clone()),
+        });
+        let goal = GoalData::DomainGoal(chalk_ir::DomainGoal::Holds(sized_pred)).intern(Interner);
+        matches!(self.try_obligation(goal), Some(Solution::Unique(_)))
+    }
 }
 
 impl fmt::Debug for InferenceTable<'_> {
diff --git a/crates/hir-ty/src/layout.rs b/crates/hir-ty/src/layout.rs
index 25362d2..4cdc0db 100644
--- a/crates/hir-ty/src/layout.rs
+++ b/crates/hir-ty/src/layout.rs
@@ -72,6 +72,7 @@
 
 #[derive(Debug, PartialEq, Eq, Clone)]
 pub enum LayoutError {
+    EmptyUnion,
     HasErrorConst,
     HasErrorType,
     HasPlaceholder,
@@ -80,6 +81,7 @@
     RecursiveTypeWithoutIndirection,
     SizeOverflow,
     TargetLayoutNotAvailable,
+    UnexpectedUnsized,
     Unknown,
     UserReprTooSmall,
 }
@@ -88,6 +90,7 @@
 impl fmt::Display for LayoutError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
+            LayoutError::EmptyUnion => write!(f, "type is an union with no fields"),
             LayoutError::HasErrorConst => write!(f, "type contains an unevaluatable const"),
             LayoutError::HasErrorType => write!(f, "type contains an error"),
             LayoutError::HasPlaceholder => write!(f, "type contains placeholders"),
@@ -98,6 +101,9 @@
             }
             LayoutError::SizeOverflow => write!(f, "size overflow"),
             LayoutError::TargetLayoutNotAvailable => write!(f, "target layout not available"),
+            LayoutError::UnexpectedUnsized => {
+                write!(f, "an unsized type was found where a sized type was expected")
+            }
             LayoutError::Unknown => write!(f, "unknown"),
             LayoutError::UserReprTooSmall => {
                 write!(f, "the `#[repr]` hint is too small to hold the discriminants of the enum")
@@ -109,9 +115,8 @@
 impl<F> From<LayoutCalculatorError<F>> for LayoutError {
     fn from(err: LayoutCalculatorError<F>) -> Self {
         match err {
-            LayoutCalculatorError::UnexpectedUnsized(_) | LayoutCalculatorError::EmptyUnion => {
-                LayoutError::Unknown
-            }
+            LayoutCalculatorError::EmptyUnion => LayoutError::EmptyUnion,
+            LayoutCalculatorError::UnexpectedUnsized(_) => LayoutError::UnexpectedUnsized,
             LayoutCalculatorError::SizeOverflow => LayoutError::SizeOverflow,
         }
     }
diff --git a/crates/hir-ty/src/layout/target.rs b/crates/hir-ty/src/layout/target.rs
index 9b14245..7d77f6d 100644
--- a/crates/hir-ty/src/layout/target.rs
+++ b/crates/hir-ty/src/layout/target.rs
@@ -11,8 +11,8 @@
     db: &dyn HirDatabase,
     krate: CrateId,
 ) -> Result<Arc<TargetDataLayout>, Arc<str>> {
-    match db.data_layout(krate) {
-        Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(&it) {
+    match &db.crate_workspace_data()[&krate].data_layout {
+        Ok(it) => match TargetDataLayout::parse_from_llvm_datalayout_string(it) {
             Ok(it) => Ok(Arc::new(it)),
             Err(e) => {
                 Err(match e {
@@ -42,6 +42,6 @@
                 }.into())
             }
         },
-        Err(e) => Err(e),
+        Err(e) => Err(e.clone()),
     }
 }
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index 26ab025..5ed41b9 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -42,6 +42,7 @@
 pub mod layout;
 pub mod method_resolution;
 pub mod mir;
+pub mod object_safety;
 pub mod primitive;
 pub mod traits;
 
@@ -82,6 +83,7 @@
 pub use builder::{ParamKind, TyBuilder};
 pub use chalk_ext::*;
 pub use infer::{
+    cast::CastError,
     closure::{CaptureKind, CapturedItem},
     could_coerce, could_unify, could_unify_deeply, Adjust, Adjustment, AutoBorrow, BindingMode,
     InferenceDiagnostic, InferenceResult, OverloadedDeref, PointerCast,
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 370d9ba..c6c2108 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -58,7 +58,7 @@
     },
     db::HirDatabase,
     error_lifetime,
-    generics::{generics, Generics},
+    generics::{generics, trait_self_param_idx, Generics},
     make_binders,
     mapping::{from_chalk_trait_id, lt_to_placeholder_idx, ToChalk},
     static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
@@ -516,8 +516,11 @@
             TypeNs::TraitId(trait_) => {
                 let ty = match remaining_segments.len() {
                     1 => {
-                        let trait_ref =
-                            self.lower_trait_ref_from_resolved_path(trait_, resolved_segment, None);
+                        let trait_ref = self.lower_trait_ref_from_resolved_path(
+                            trait_,
+                            resolved_segment,
+                            TyKind::Error.intern(Interner),
+                        );
                         let segment = remaining_segments.first().unwrap();
                         let found = self
                             .db
@@ -952,11 +955,17 @@
         Substitution::from_iter(Interner, substs)
     }
 
-    fn lower_trait_ref_from_path(
+    pub(crate) fn lower_trait_ref_from_resolved_path(
         &self,
-        path: &Path,
-        explicit_self_ty: Option<Ty>,
-    ) -> Option<TraitRef> {
+        resolved: TraitId,
+        segment: PathSegment<'_>,
+        explicit_self_ty: Ty,
+    ) -> TraitRef {
+        let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
+        TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
+    }
+
+    fn lower_trait_ref_from_path(&self, path: &Path, explicit_self_ty: Ty) -> Option<TraitRef> {
         let resolved = match self.resolver.resolve_path_in_type_ns_fully(self.db.upcast(), path)? {
             // FIXME(trait_alias): We need to handle trait alias here.
             TypeNs::TraitId(tr) => tr,
@@ -966,21 +975,7 @@
         Some(self.lower_trait_ref_from_resolved_path(resolved, segment, explicit_self_ty))
     }
 
-    pub(crate) fn lower_trait_ref_from_resolved_path(
-        &self,
-        resolved: TraitId,
-        segment: PathSegment<'_>,
-        explicit_self_ty: Option<Ty>,
-    ) -> TraitRef {
-        let substs = self.trait_ref_substs_from_path(segment, resolved, explicit_self_ty);
-        TraitRef { trait_id: to_chalk_trait_id(resolved), substitution: substs }
-    }
-
-    fn lower_trait_ref(
-        &self,
-        trait_ref: &HirTraitRef,
-        explicit_self_ty: Option<Ty>,
-    ) -> Option<TraitRef> {
+    fn lower_trait_ref(&self, trait_ref: &HirTraitRef, explicit_self_ty: Ty) -> Option<TraitRef> {
         self.lower_trait_ref_from_path(&trait_ref.path, explicit_self_ty)
     }
 
@@ -988,9 +983,9 @@
         &self,
         segment: PathSegment<'_>,
         resolved: TraitId,
-        explicit_self_ty: Option<Ty>,
+        explicit_self_ty: Ty,
     ) -> Substitution {
-        self.substs_from_path_segment(segment, Some(resolved.into()), false, explicit_self_ty)
+        self.substs_from_path_segment(segment, Some(resolved.into()), false, Some(explicit_self_ty))
     }
 
     pub(crate) fn lower_where_predicate<'b>(
@@ -1041,7 +1036,7 @@
         let mut trait_ref = None;
         let clause = match bound.as_ref() {
             TypeBound::Path(path, TraitBoundModifier::None) => {
-                trait_ref = self.lower_trait_ref_from_path(path, Some(self_ty));
+                trait_ref = self.lower_trait_ref_from_path(path, self_ty);
                 trait_ref.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
             }
             TypeBound::Path(path, TraitBoundModifier::Maybe) => {
@@ -1053,7 +1048,7 @@
                 // `?Sized` has no of them.
                 // If we got another trait here ignore the bound completely.
                 let trait_id = self
-                    .lower_trait_ref_from_path(path, Some(self_ty.clone()))
+                    .lower_trait_ref_from_path(path, self_ty.clone())
                     .map(|trait_ref| trait_ref.hir_trait_id());
                 if trait_id == sized_trait {
                     self.unsized_types.borrow_mut().insert(self_ty);
@@ -1062,7 +1057,7 @@
             }
             TypeBound::ForLifetime(_, path) => {
                 // FIXME Don't silently drop the hrtb lifetimes here
-                trait_ref = self.lower_trait_ref_from_path(path, Some(self_ty));
+                trait_ref = self.lower_trait_ref_from_path(path, self_ty);
                 trait_ref.clone().map(WhereClause::Implemented).map(crate::wrap_empty_binders)
             }
             TypeBound::Lifetime(l) => {
@@ -1700,6 +1695,28 @@
     db: &dyn HirDatabase,
     def: GenericDefId,
 ) -> GenericPredicates {
+    generic_predicates_filtered_by(db, def, |_, _| true)
+}
+
+/// Resolve the where clause(s) of an item with generics,
+/// except the ones inherited from the parent
+pub(crate) fn generic_predicates_without_parent_query(
+    db: &dyn HirDatabase,
+    def: GenericDefId,
+) -> GenericPredicates {
+    generic_predicates_filtered_by(db, def, |_, d| *d == def)
+}
+
+/// Resolve the where clause(s) of an item with generics,
+/// except the ones inherited from the parent
+fn generic_predicates_filtered_by<F>(
+    db: &dyn HirDatabase,
+    def: GenericDefId,
+    filter: F,
+) -> GenericPredicates
+where
+    F: Fn(&WherePredicate, &GenericDefId) -> bool,
+{
     let resolver = def.resolver(db.upcast());
     let (impl_trait_lowering, param_lowering) = match def {
         GenericDefId::FunctionId(_) => {
@@ -1714,6 +1731,7 @@
 
     let mut predicates = resolver
         .where_predicates_in_scope()
+        .filter(|(pred, def)| filter(pred, def))
         .flat_map(|(pred, def)| {
             ctx.lower_where_predicate(pred, def, false).map(|p| make_binders(db, &generics, p))
         })
@@ -1747,21 +1765,7 @@
         .lang_item(resolver.krate(), LangItem::Sized)
         .and_then(|lang_item| lang_item.as_trait().map(to_chalk_trait_id))?;
 
-    let get_trait_self_idx = |container: ItemContainerId| {
-        if matches!(container, ItemContainerId::TraitId(_)) {
-            let generics = generics(db.upcast(), def);
-            Some(generics.len_self())
-        } else {
-            None
-        }
-    };
-    let trait_self_idx = match def {
-        GenericDefId::TraitId(_) => Some(0),
-        GenericDefId::FunctionId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
-        GenericDefId::ConstId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
-        GenericDefId::TypeAliasId(it) => get_trait_self_idx(it.lookup(db.upcast()).container),
-        _ => None,
-    };
+    let trait_self_idx = trait_self_param_idx(db.upcast(), def);
 
     Some(
         substitution
@@ -2117,7 +2121,7 @@
         .with_type_param_mode(ParamLoweringMode::Variable);
     let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
     let target_trait = impl_data.target_trait.as_ref()?;
-    Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
+    Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, self_ty)?))
 }
 
 pub(crate) fn return_type_impl_traits(
diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs
index 22d4da0..8e815aa 100644
--- a/crates/hir-ty/src/mir.rs
+++ b/crates/hir-ty/src/mir.rs
@@ -185,8 +185,8 @@
                         never!("Out of bound tuple field");
                         TyKind::Error.intern(Interner)
                     }),
-                _ => {
-                    never!("Only tuple has tuple field");
+                ty => {
+                    never!("Only tuple has tuple field: {:?}", ty);
                     TyKind::Error.intern(Interner)
                 }
             },
@@ -837,7 +837,9 @@
     PointerFromExposedAddress,
     /// All sorts of pointer-to-pointer casts. Note that reference-to-raw-ptr casts are
     /// translated into `&raw mut/const *r`, i.e., they are not actually casts.
-    Pointer(PointerCast),
+    PtrToPtr,
+    /// Pointer related casts that are done by coercions.
+    PointerCoercion(PointerCast),
     /// Cast into a dyn* object.
     DynStar,
     IntToInt,
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 1bb0c18..0d42617 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -421,9 +421,25 @@
             }
             MirEvalError::MirLowerError(func, err) => {
                 let function_name = db.function_data(*func);
+                let self_ = match func.lookup(db.upcast()).container {
+                    ItemContainerId::ImplId(impl_id) => Some({
+                        let generics = crate::generics::generics(db.upcast(), impl_id.into());
+                        let substs = generics.placeholder_subst(db);
+                        db.impl_self_ty(impl_id)
+                            .substitute(Interner, &substs)
+                            .display(db, edition)
+                            .to_string()
+                    }),
+                    ItemContainerId::TraitId(it) => {
+                        Some(db.trait_data(it).name.display(db.upcast(), edition).to_string())
+                    }
+                    _ => None,
+                };
                 writeln!(
                     f,
-                    "MIR lowering for function `{}` ({:?}) failed due:",
+                    "MIR lowering for function `{}{}{}` ({:?}) failed due:",
+                    self_.as_deref().unwrap_or_default(),
+                    if self_.is_some() { "::" } else { "" },
                     function_name.name.display(db.upcast(), edition),
                     func
                 )?;
@@ -1475,7 +1491,7 @@
                 }
             }
             Rvalue::Cast(kind, operand, target_ty) => match kind {
-                CastKind::Pointer(cast) => match cast {
+                CastKind::PointerCoercion(cast) => match cast {
                     PointerCast::ReifyFnPointer | PointerCast::ClosureFnPointer(_) => {
                         let current_ty = self.operand_ty(operand, locals)?;
                         if let TyKind::FnDef(_, _) | TyKind::Closure(_, _) =
@@ -1506,6 +1522,7 @@
                 },
                 CastKind::DynStar => not_supported!("dyn star cast"),
                 CastKind::IntToInt
+                | CastKind::PtrToPtr
                 | CastKind::PointerExposeAddress
                 | CastKind::PointerFromExposedAddress => {
                     let current_ty = self.operand_ty(operand, locals)?;
diff --git a/crates/hir-ty/src/mir/eval/tests.rs b/crates/hir-ty/src/mir/eval/tests.rs
index 371a527..595a78d 100644
--- a/crates/hir-ty/src/mir/eval/tests.rs
+++ b/crates/hir-ty/src/mir/eval/tests.rs
@@ -399,7 +399,7 @@
     fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32;
 }
 
-fn my_cmp(x: &[u8], y: &[u8]) -> i32 {
+fn my_cmp(x: &[u8; 3], y: &[u8; 3]) -> i32 {
     memcmp(x as *const u8, y as *const u8, x.len())
 }
 
@@ -779,6 +779,7 @@
 fn posix_getenv() {
     check_pass(
         r#"
+//- minicore: sized
 //- /main.rs env:foo=bar
 
 type c_char = u8;
@@ -849,7 +850,7 @@
 fn regression_14966() {
     check_pass(
         r#"
-//- minicore: fn, copy, coerce_unsized
+//- minicore: fn, copy, coerce_unsized, dispatch_from_dyn
 trait A<T> {
     fn a(&self) {}
 }
diff --git a/crates/hir-ty/src/mir/lower.rs b/crates/hir-ty/src/mir/lower.rs
index 9e23550..a2cb122 100644
--- a/crates/hir-ty/src/mir/lower.rs
+++ b/crates/hir-ty/src/mir/lower.rs
@@ -31,7 +31,7 @@
     display::HirDisplay,
     error_lifetime,
     generics::generics,
-    infer::{CaptureKind, CapturedItem, TypeMismatch},
+    infer::{cast::CastTy, unify::InferenceTable, CaptureKind, CapturedItem, TypeMismatch},
     inhabitedness::is_ty_uninhabited_from,
     layout::LayoutError,
     mapping::ToChalk,
@@ -94,7 +94,8 @@
     UnresolvedField,
     UnsizedTemporary(Ty),
     MissingFunctionDefinition(DefWithBodyId, ExprId),
-    TypeMismatch(Option<TypeMismatch>),
+    TypeMismatch(TypeMismatch),
+    HasErrors,
     /// This should never happen. Type mismatch should catch everything.
     TypeError(&'static str),
     NotSupported(String),
@@ -179,15 +180,13 @@
                     body.pretty_print_expr(db.upcast(), *owner, *it, edition)
                 )?;
             }
-            MirLowerError::TypeMismatch(e) => match e {
-                Some(e) => writeln!(
-                    f,
-                    "Type mismatch: Expected {}, found {}",
-                    e.expected.display(db, edition),
-                    e.actual.display(db, edition),
-                )?,
-                None => writeln!(f, "Type mismatch: types mismatch with {{unknown}}",)?,
-            },
+            MirLowerError::HasErrors => writeln!(f, "Type inference result contains errors")?,
+            MirLowerError::TypeMismatch(e) => writeln!(
+                f,
+                "Type mismatch: Expected {}, found {}",
+                e.expected.display(db, edition),
+                e.actual.display(db, edition),
+            )?,
             MirLowerError::GenericArgNotProvided(id, subst) => {
                 let parent = id.parent;
                 let param = &db.generic_params(parent)[id.local_id];
@@ -362,7 +361,7 @@
                         current,
                         place,
                         Rvalue::Cast(
-                            CastKind::Pointer(*cast),
+                            CastKind::PointerCoercion(*cast),
                             Operand::Copy(p),
                             last.target.clone(),
                         ),
@@ -898,14 +897,26 @@
                 let Some((it, current)) = self.lower_expr_to_some_operand(*expr, current)? else {
                     return Ok(None);
                 };
-                let source_ty = self.infer[*expr].clone();
-                let target_ty = self.infer[expr_id].clone();
-                self.push_assignment(
-                    current,
-                    place,
-                    Rvalue::Cast(cast_kind(&source_ty, &target_ty)?, it, target_ty),
-                    expr_id.into(),
-                );
+                // Since we don't have THIR, this is the "zipped" version of [rustc's HIR lowering](https://github.com/rust-lang/rust/blob/e71f9529121ca8f687e4b725e3c9adc3f1ebab4d/compiler/rustc_mir_build/src/thir/cx/expr.rs#L165-L178)
+                // and [THIR lowering as RValue](https://github.com/rust-lang/rust/blob/a4601859ae3875732797873612d424976d9e3dd0/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs#L193-L313)
+                let rvalue = if self.infer.coercion_casts.contains(expr) {
+                    Rvalue::Use(it)
+                } else {
+                    let source_ty = self.infer[*expr].clone();
+                    let target_ty = self.infer[expr_id].clone();
+                    let cast_kind = if source_ty.as_reference().is_some() {
+                        CastKind::PointerCoercion(PointerCast::ArrayToPointer)
+                    } else {
+                        let mut table = InferenceTable::new(
+                            self.db,
+                            self.db.trait_environment_for_body(self.owner),
+                        );
+                        cast_kind(&mut table, &source_ty, &target_ty)?
+                    };
+
+                    Rvalue::Cast(cast_kind, it, target_ty)
+                };
+                self.push_assignment(current, place, rvalue, expr_id.into());
                 Ok(Some(current))
             }
             Expr::Ref { expr, rawness: _, mutability } => {
@@ -2005,40 +2016,21 @@
     }
 }
 
-fn cast_kind(source_ty: &Ty, target_ty: &Ty) -> Result<CastKind> {
-    Ok(match (source_ty.kind(Interner), target_ty.kind(Interner)) {
-        (TyKind::FnDef(..), TyKind::Function(_)) => CastKind::Pointer(PointerCast::ReifyFnPointer),
-        (TyKind::Scalar(s), TyKind::Scalar(t)) => match (s, t) {
-            (chalk_ir::Scalar::Float(_), chalk_ir::Scalar::Float(_)) => CastKind::FloatToFloat,
-            (chalk_ir::Scalar::Float(_), _) => CastKind::FloatToInt,
-            (_, chalk_ir::Scalar::Float(_)) => CastKind::IntToFloat,
-            (_, _) => CastKind::IntToInt,
-        },
-        (TyKind::Scalar(_), TyKind::Raw(..)) => CastKind::PointerFromExposedAddress,
-        (TyKind::Raw(..), TyKind::Scalar(_)) => CastKind::PointerExposeAddress,
-        (TyKind::Raw(_, a) | TyKind::Ref(_, _, a), TyKind::Raw(_, b) | TyKind::Ref(_, _, b)) => {
-            CastKind::Pointer(if a == b {
-                PointerCast::MutToConstPointer
-            } else if matches!(b.kind(Interner), TyKind::Slice(_))
-                && matches!(a.kind(Interner), TyKind::Array(_, _))
-                || matches!(b.kind(Interner), TyKind::Dyn(_))
-            {
-                PointerCast::Unsize
-            } else if matches!(a.kind(Interner), TyKind::Slice(s) if s == b) {
-                PointerCast::ArrayToPointer
-            } else {
-                // cast between two sized pointer, like *const i32 to *const i8, or two unsized pointer, like
-                // slice to slice, slice to str, ... . These are no-ops (even in the unsized case, no metadata
-                // will be touched) but there is no specific variant
-                // for it in `PointerCast` so we use `MutToConstPointer`
-                PointerCast::MutToConstPointer
-            })
+fn cast_kind(table: &mut InferenceTable<'_>, source_ty: &Ty, target_ty: &Ty) -> Result<CastKind> {
+    let from = CastTy::from_ty(table, source_ty);
+    let cast = CastTy::from_ty(table, target_ty);
+    Ok(match (from, cast) {
+        (Some(CastTy::Ptr(..) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
+            CastKind::PointerExposeAddress
         }
-        // Enum to int casts
-        (TyKind::Scalar(_), TyKind::Adt(..)) | (TyKind::Adt(..), TyKind::Scalar(_)) => {
-            CastKind::IntToInt
-        }
-        (a, b) => not_supported!("Unknown cast between {a:?} and {b:?}"),
+        (Some(CastTy::Int(_)), Some(CastTy::Ptr(..))) => CastKind::PointerFromExposedAddress,
+        (Some(CastTy::Int(_)), Some(CastTy::Int(_))) => CastKind::IntToInt,
+        (Some(CastTy::FnPtr), Some(CastTy::Ptr(..))) => CastKind::FnPtrToPtr,
+        (Some(CastTy::Float), Some(CastTy::Int(_))) => CastKind::FloatToInt,
+        (Some(CastTy::Int(_)), Some(CastTy::Float)) => CastKind::IntToFloat,
+        (Some(CastTy::Float), Some(CastTy::Float)) => CastKind::FloatToFloat,
+        (Some(CastTy::Ptr(..)), Some(CastTy::Ptr(..))) => CastKind::PtrToPtr,
+        _ => not_supported!("Unknown cast between {source_ty:?} and {target_ty:?}"),
     })
 }
 
@@ -2191,7 +2183,7 @@
     root_expr: ExprId,
 ) -> Result<MirBody> {
     if infer.has_errors {
-        return Err(MirLowerError::TypeMismatch(None));
+        return Err(MirLowerError::HasErrors);
     }
     let mut ctx = MirLowerCtx::new(db, owner, body, infer);
     // 0 is return local
diff --git a/crates/hir-ty/src/object_safety.rs b/crates/hir-ty/src/object_safety.rs
new file mode 100644
index 0000000..a4c6626
--- /dev/null
+++ b/crates/hir-ty/src/object_safety.rs
@@ -0,0 +1,612 @@
+//! Compute the object-safety of a trait
+
+use std::ops::ControlFlow;
+
+use chalk_ir::{
+    cast::Cast,
+    visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor},
+    DebruijnIndex,
+};
+use chalk_solve::rust_ir::InlineBound;
+use hir_def::{
+    lang_item::LangItem, AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId,
+    TypeAliasId,
+};
+use rustc_hash::FxHashSet;
+use smallvec::SmallVec;
+
+use crate::{
+    all_super_traits,
+    db::HirDatabase,
+    from_assoc_type_id, from_chalk_trait_id,
+    generics::{generics, trait_self_param_idx},
+    lower::callable_item_sig,
+    to_assoc_type_id, to_chalk_trait_id,
+    utils::elaborate_clause_supertraits,
+    AliasEq, AliasTy, Binders, BoundVar, CallableSig, GoalData, ImplTraitId, Interner, OpaqueTyId,
+    ProjectionTyExt, Solution, Substitution, TraitRef, Ty, TyKind, WhereClause,
+};
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum ObjectSafetyViolation {
+    SizedSelf,
+    SelfReferential,
+    Method(FunctionId, MethodViolationCode),
+    AssocConst(ConstId),
+    GAT(TypeAliasId),
+    // This doesn't exist in rustc, but added for better visualization
+    HasNonSafeSuperTrait(TraitId),
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum MethodViolationCode {
+    StaticMethod,
+    ReferencesSelfInput,
+    ReferencesSelfOutput,
+    ReferencesImplTraitInTrait,
+    AsyncFn,
+    WhereClauseReferencesSelf,
+    Generic,
+    UndispatchableReceiver,
+}
+
+pub fn object_safety(db: &dyn HirDatabase, trait_: TraitId) -> Option<ObjectSafetyViolation> {
+    for super_trait in all_super_traits(db.upcast(), trait_).into_iter().skip(1).rev() {
+        if db.object_safety_of_trait(super_trait).is_some() {
+            return Some(ObjectSafetyViolation::HasNonSafeSuperTrait(super_trait));
+        }
+    }
+
+    db.object_safety_of_trait(trait_)
+}
+
+pub fn object_safety_with_callback<F>(
+    db: &dyn HirDatabase,
+    trait_: TraitId,
+    cb: &mut F,
+) -> ControlFlow<()>
+where
+    F: FnMut(ObjectSafetyViolation) -> ControlFlow<()>,
+{
+    for super_trait in all_super_traits(db.upcast(), trait_).into_iter().skip(1).rev() {
+        if db.object_safety_of_trait(super_trait).is_some() {
+            cb(ObjectSafetyViolation::HasNonSafeSuperTrait(trait_))?;
+        }
+    }
+
+    object_safety_of_trait_with_callback(db, trait_, cb)
+}
+
+pub fn object_safety_of_trait_with_callback<F>(
+    db: &dyn HirDatabase,
+    trait_: TraitId,
+    cb: &mut F,
+) -> ControlFlow<()>
+where
+    F: FnMut(ObjectSafetyViolation) -> ControlFlow<()>,
+{
+    // Check whether this has a `Sized` bound
+    if generics_require_sized_self(db, trait_.into()) {
+        cb(ObjectSafetyViolation::SizedSelf)?;
+    }
+
+    // Check if there exist bounds that referencing self
+    if predicates_reference_self(db, trait_) {
+        cb(ObjectSafetyViolation::SelfReferential)?;
+    }
+    if bounds_reference_self(db, trait_) {
+        cb(ObjectSafetyViolation::SelfReferential)?;
+    }
+
+    // rustc checks for non-lifetime binders here, but we don't support HRTB yet
+
+    let trait_data = db.trait_data(trait_);
+    for (_, assoc_item) in &trait_data.items {
+        object_safety_violation_for_assoc_item(db, trait_, *assoc_item, cb)?;
+    }
+
+    ControlFlow::Continue(())
+}
+
+pub fn object_safety_of_trait_query(
+    db: &dyn HirDatabase,
+    trait_: TraitId,
+) -> Option<ObjectSafetyViolation> {
+    let mut res = None;
+    object_safety_of_trait_with_callback(db, trait_, &mut |osv| {
+        res = Some(osv);
+        ControlFlow::Break(())
+    });
+
+    res
+}
+
+fn generics_require_sized_self(db: &dyn HirDatabase, def: GenericDefId) -> bool {
+    let krate = def.module(db.upcast()).krate();
+    let Some(sized) = db.lang_item(krate, LangItem::Sized).and_then(|l| l.as_trait()) else {
+        return false;
+    };
+
+    let Some(trait_self_param_idx) = trait_self_param_idx(db.upcast(), def) else {
+        return false;
+    };
+
+    let predicates = &*db.generic_predicates(def);
+    let predicates = predicates.iter().map(|p| p.skip_binders().skip_binders().clone());
+    elaborate_clause_supertraits(db, predicates).any(|pred| match pred {
+        WhereClause::Implemented(trait_ref) => {
+            if from_chalk_trait_id(trait_ref.trait_id) == sized {
+                if let TyKind::BoundVar(it) =
+                    *trait_ref.self_type_parameter(Interner).kind(Interner)
+                {
+                    // Since `generic_predicates` is `Binder<Binder<..>>`, the `DebrujinIndex` of
+                    // self-parameter is `1`
+                    return it
+                        .index_if_bound_at(DebruijnIndex::ONE)
+                        .is_some_and(|idx| idx == trait_self_param_idx);
+                }
+            }
+            false
+        }
+        _ => false,
+    })
+}
+
+// rustc gathers all the spans that references `Self` for error rendering,
+// but we don't have good way to render such locations.
+// So, just return single boolean value for existence of such `Self` reference
+fn predicates_reference_self(db: &dyn HirDatabase, trait_: TraitId) -> bool {
+    db.generic_predicates(trait_.into())
+        .iter()
+        .any(|pred| predicate_references_self(db, trait_, pred, AllowSelfProjection::No))
+}
+
+// Same as the above, `predicates_reference_self`
+fn bounds_reference_self(db: &dyn HirDatabase, trait_: TraitId) -> bool {
+    let trait_data = db.trait_data(trait_);
+    trait_data
+        .items
+        .iter()
+        .filter_map(|(_, it)| match *it {
+            AssocItemId::TypeAliasId(id) => {
+                let assoc_ty_id = to_assoc_type_id(id);
+                let assoc_ty_data = db.associated_ty_data(assoc_ty_id);
+                Some(assoc_ty_data)
+            }
+            _ => None,
+        })
+        .any(|assoc_ty_data| {
+            assoc_ty_data.binders.skip_binders().bounds.iter().any(|bound| {
+                let def = from_assoc_type_id(assoc_ty_data.id).into();
+                match bound.skip_binders() {
+                    InlineBound::TraitBound(it) => it.args_no_self.iter().any(|arg| {
+                        contains_illegal_self_type_reference(
+                            db,
+                            def,
+                            trait_,
+                            arg,
+                            DebruijnIndex::ONE,
+                            AllowSelfProjection::Yes,
+                        )
+                    }),
+                    InlineBound::AliasEqBound(it) => it.parameters.iter().any(|arg| {
+                        contains_illegal_self_type_reference(
+                            db,
+                            def,
+                            trait_,
+                            arg,
+                            DebruijnIndex::ONE,
+                            AllowSelfProjection::Yes,
+                        )
+                    }),
+                }
+            })
+        })
+}
+
+#[derive(Clone, Copy)]
+enum AllowSelfProjection {
+    Yes,
+    No,
+}
+
+fn predicate_references_self(
+    db: &dyn HirDatabase,
+    trait_: TraitId,
+    predicate: &Binders<Binders<WhereClause>>,
+    allow_self_projection: AllowSelfProjection,
+) -> bool {
+    match predicate.skip_binders().skip_binders() {
+        WhereClause::Implemented(trait_ref) => {
+            trait_ref.substitution.iter(Interner).skip(1).any(|arg| {
+                contains_illegal_self_type_reference(
+                    db,
+                    trait_.into(),
+                    trait_,
+                    arg,
+                    DebruijnIndex::ONE,
+                    allow_self_projection,
+                )
+            })
+        }
+        WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(proj), .. }) => {
+            proj.substitution.iter(Interner).skip(1).any(|arg| {
+                contains_illegal_self_type_reference(
+                    db,
+                    trait_.into(),
+                    trait_,
+                    arg,
+                    DebruijnIndex::ONE,
+                    allow_self_projection,
+                )
+            })
+        }
+        _ => false,
+    }
+}
+
+fn contains_illegal_self_type_reference<T: TypeVisitable<Interner>>(
+    db: &dyn HirDatabase,
+    def: GenericDefId,
+    trait_: TraitId,
+    t: &T,
+    outer_binder: DebruijnIndex,
+    allow_self_projection: AllowSelfProjection,
+) -> bool {
+    let Some(trait_self_param_idx) = trait_self_param_idx(db.upcast(), def) else {
+        return false;
+    };
+    struct IllegalSelfTypeVisitor<'a> {
+        db: &'a dyn HirDatabase,
+        trait_: TraitId,
+        super_traits: Option<SmallVec<[TraitId; 4]>>,
+        trait_self_param_idx: usize,
+        allow_self_projection: AllowSelfProjection,
+    }
+    impl<'a> TypeVisitor<Interner> for IllegalSelfTypeVisitor<'a> {
+        type BreakTy = ();
+
+        fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
+            self
+        }
+
+        fn interner(&self) -> Interner {
+            Interner
+        }
+
+        fn visit_ty(&mut self, ty: &Ty, outer_binder: DebruijnIndex) -> ControlFlow<Self::BreakTy> {
+            match ty.kind(Interner) {
+                TyKind::BoundVar(BoundVar { debruijn, index }) => {
+                    if *debruijn == outer_binder && *index == self.trait_self_param_idx {
+                        ControlFlow::Break(())
+                    } else {
+                        ty.super_visit_with(self.as_dyn(), outer_binder)
+                    }
+                }
+                TyKind::Alias(AliasTy::Projection(proj)) => match self.allow_self_projection {
+                    AllowSelfProjection::Yes => {
+                        let trait_ = proj.trait_(self.db);
+                        if self.super_traits.is_none() {
+                            self.super_traits =
+                                Some(all_super_traits(self.db.upcast(), self.trait_));
+                        }
+                        if self.super_traits.as_ref().is_some_and(|s| s.contains(&trait_)) {
+                            ControlFlow::Continue(())
+                        } else {
+                            ty.super_visit_with(self.as_dyn(), outer_binder)
+                        }
+                    }
+                    AllowSelfProjection::No => ty.super_visit_with(self.as_dyn(), outer_binder),
+                },
+                _ => ty.super_visit_with(self.as_dyn(), outer_binder),
+            }
+        }
+
+        fn visit_const(
+            &mut self,
+            constant: &chalk_ir::Const<Interner>,
+            outer_binder: DebruijnIndex,
+        ) -> std::ops::ControlFlow<Self::BreakTy> {
+            constant.data(Interner).ty.super_visit_with(self.as_dyn(), outer_binder)
+        }
+    }
+
+    let mut visitor = IllegalSelfTypeVisitor {
+        db,
+        trait_,
+        super_traits: None,
+        trait_self_param_idx,
+        allow_self_projection,
+    };
+    t.visit_with(visitor.as_dyn(), outer_binder).is_break()
+}
+
+fn object_safety_violation_for_assoc_item<F>(
+    db: &dyn HirDatabase,
+    trait_: TraitId,
+    item: AssocItemId,
+    cb: &mut F,
+) -> ControlFlow<()>
+where
+    F: FnMut(ObjectSafetyViolation) -> ControlFlow<()>,
+{
+    // Any item that has a `Self : Sized` requisite is otherwise
+    // exempt from the regulations.
+    if generics_require_sized_self(db, item.into()) {
+        return ControlFlow::Continue(());
+    }
+
+    match item {
+        AssocItemId::ConstId(it) => cb(ObjectSafetyViolation::AssocConst(it)),
+        AssocItemId::FunctionId(it) => {
+            virtual_call_violations_for_method(db, trait_, it, &mut |mvc| {
+                cb(ObjectSafetyViolation::Method(it, mvc))
+            })
+        }
+        AssocItemId::TypeAliasId(it) => {
+            let def_map = db.crate_def_map(trait_.krate(db.upcast()));
+            if def_map.is_unstable_feature_enabled(&intern::sym::generic_associated_type_extended) {
+                ControlFlow::Continue(())
+            } else {
+                let generic_params = db.generic_params(item.into());
+                if !generic_params.is_empty() {
+                    cb(ObjectSafetyViolation::GAT(it))
+                } else {
+                    ControlFlow::Continue(())
+                }
+            }
+        }
+    }
+}
+
+fn virtual_call_violations_for_method<F>(
+    db: &dyn HirDatabase,
+    trait_: TraitId,
+    func: FunctionId,
+    cb: &mut F,
+) -> ControlFlow<()>
+where
+    F: FnMut(MethodViolationCode) -> ControlFlow<()>,
+{
+    let func_data = db.function_data(func);
+    if !func_data.has_self_param() {
+        cb(MethodViolationCode::StaticMethod)?;
+    }
+
+    if func_data.is_async() {
+        cb(MethodViolationCode::AsyncFn)?;
+    }
+
+    let sig = callable_item_sig(db, func.into());
+    if sig.skip_binders().params().iter().skip(1).any(|ty| {
+        contains_illegal_self_type_reference(
+            db,
+            func.into(),
+            trait_,
+            ty,
+            DebruijnIndex::INNERMOST,
+            AllowSelfProjection::Yes,
+        )
+    }) {
+        cb(MethodViolationCode::ReferencesSelfInput)?;
+    }
+
+    if contains_illegal_self_type_reference(
+        db,
+        func.into(),
+        trait_,
+        sig.skip_binders().ret(),
+        DebruijnIndex::INNERMOST,
+        AllowSelfProjection::Yes,
+    ) {
+        cb(MethodViolationCode::ReferencesSelfOutput)?;
+    }
+
+    if !func_data.is_async() {
+        if let Some(mvc) = contains_illegal_impl_trait_in_trait(db, &sig) {
+            cb(mvc)?;
+        }
+    }
+
+    let generic_params = db.generic_params(func.into());
+    if generic_params.len_type_or_consts() > 0 {
+        cb(MethodViolationCode::Generic)?;
+    }
+
+    if func_data.has_self_param() && !receiver_is_dispatchable(db, trait_, func, &sig) {
+        cb(MethodViolationCode::UndispatchableReceiver)?;
+    }
+
+    let predicates = &*db.generic_predicates_without_parent(func.into());
+    let trait_self_idx = trait_self_param_idx(db.upcast(), func.into());
+    for pred in predicates {
+        let pred = pred.skip_binders().skip_binders();
+
+        if matches!(pred, WhereClause::TypeOutlives(_)) {
+            continue;
+        }
+
+        // Allow `impl AutoTrait` predicates
+        if let WhereClause::Implemented(TraitRef { trait_id, substitution }) = pred {
+            let trait_data = db.trait_data(from_chalk_trait_id(*trait_id));
+            if trait_data.is_auto
+                && substitution
+                    .as_slice(Interner)
+                    .first()
+                    .and_then(|arg| arg.ty(Interner))
+                    .and_then(|ty| ty.bound_var(Interner))
+                    .is_some_and(|b| {
+                        b.debruijn == DebruijnIndex::ONE && Some(b.index) == trait_self_idx
+                    })
+            {
+                continue;
+            }
+        }
+
+        if contains_illegal_self_type_reference(
+            db,
+            func.into(),
+            trait_,
+            pred,
+            DebruijnIndex::ONE,
+            AllowSelfProjection::Yes,
+        ) {
+            cb(MethodViolationCode::WhereClauseReferencesSelf)?;
+            break;
+        }
+    }
+
+    ControlFlow::Continue(())
+}
+
+fn receiver_is_dispatchable(
+    db: &dyn HirDatabase,
+    trait_: TraitId,
+    func: FunctionId,
+    sig: &Binders<CallableSig>,
+) -> bool {
+    let Some(trait_self_idx) = trait_self_param_idx(db.upcast(), func.into()) else {
+        return false;
+    };
+
+    // `self: Self` can't be dispatched on, but this is already considered object safe.
+    // See rustc's comment on https://github.com/rust-lang/rust/blob/3f121b9461cce02a703a0e7e450568849dfaa074/compiler/rustc_trait_selection/src/traits/object_safety.rs#L433-L437
+    if sig
+        .skip_binders()
+        .params()
+        .first()
+        .and_then(|receiver| receiver.bound_var(Interner))
+        .is_some_and(|b| {
+            b == BoundVar { debruijn: DebruijnIndex::INNERMOST, index: trait_self_idx }
+        })
+    {
+        return true;
+    }
+
+    let placeholder_subst = generics(db.upcast(), func.into()).placeholder_subst(db);
+
+    let substituted_sig = sig.clone().substitute(Interner, &placeholder_subst);
+    let Some(receiver_ty) = substituted_sig.params().first() else {
+        return false;
+    };
+
+    let krate = func.module(db.upcast()).krate();
+    let traits = (
+        db.lang_item(krate, LangItem::Unsize).and_then(|it| it.as_trait()),
+        db.lang_item(krate, LangItem::DispatchFromDyn).and_then(|it| it.as_trait()),
+    );
+    let (Some(unsize_did), Some(dispatch_from_dyn_did)) = traits else {
+        return false;
+    };
+
+    // Type `U`
+    let unsized_self_ty =
+        TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U32)).intern(Interner);
+    // `Receiver[Self => U]`
+    let Some(unsized_receiver_ty) = receiver_for_self_ty(db, func, unsized_self_ty.clone()) else {
+        return false;
+    };
+
+    let self_ty = placeholder_subst.as_slice(Interner)[trait_self_idx].assert_ty_ref(Interner);
+    let unsized_predicate = WhereClause::Implemented(TraitRef {
+        trait_id: to_chalk_trait_id(unsize_did),
+        substitution: Substitution::from_iter(Interner, [self_ty.clone(), unsized_self_ty.clone()]),
+    });
+    let trait_predicate = WhereClause::Implemented(TraitRef {
+        trait_id: to_chalk_trait_id(trait_),
+        substitution: Substitution::from_iter(
+            Interner,
+            std::iter::once(unsized_self_ty.clone().cast(Interner))
+                .chain(placeholder_subst.iter(Interner).skip(1).cloned()),
+        ),
+    });
+
+    let generic_predicates = &*db.generic_predicates(func.into());
+
+    let clauses = std::iter::once(unsized_predicate)
+        .chain(std::iter::once(trait_predicate))
+        .chain(generic_predicates.iter().map(|pred| {
+            pred.clone().substitute(Interner, &placeholder_subst).into_value_and_skipped_binders().0
+        }))
+        .map(|pred| {
+            pred.cast::<chalk_ir::ProgramClause<Interner>>(Interner).into_from_env_clause(Interner)
+        });
+    let env = chalk_ir::Environment::new(Interner).add_clauses(Interner, clauses);
+
+    let obligation = WhereClause::Implemented(TraitRef {
+        trait_id: to_chalk_trait_id(dispatch_from_dyn_did),
+        substitution: Substitution::from_iter(Interner, [receiver_ty.clone(), unsized_receiver_ty]),
+    });
+    let goal = GoalData::DomainGoal(chalk_ir::DomainGoal::Holds(obligation)).intern(Interner);
+
+    let in_env = chalk_ir::InEnvironment::new(&env, goal);
+
+    let mut table = chalk_solve::infer::InferenceTable::<Interner>::new();
+    let canonicalized = table.canonicalize(Interner, in_env);
+    let solution = db.trait_solve(krate, None, canonicalized.quantified);
+
+    matches!(solution, Some(Solution::Unique(_)))
+}
+
+fn receiver_for_self_ty(db: &dyn HirDatabase, func: FunctionId, ty: Ty) -> Option<Ty> {
+    let generics = generics(db.upcast(), func.into());
+    let trait_self_idx = trait_self_param_idx(db.upcast(), func.into())?;
+    let subst = generics.placeholder_subst(db);
+    let subst = Substitution::from_iter(
+        Interner,
+        subst.iter(Interner).enumerate().map(|(idx, arg)| {
+            if idx == trait_self_idx {
+                ty.clone().cast(Interner)
+            } else {
+                arg.clone()
+            }
+        }),
+    );
+    let sig = callable_item_sig(db, func.into());
+    let sig = sig.substitute(Interner, &subst);
+    sig.params_and_return.first().cloned()
+}
+
+fn contains_illegal_impl_trait_in_trait(
+    db: &dyn HirDatabase,
+    sig: &Binders<CallableSig>,
+) -> Option<MethodViolationCode> {
+    struct OpaqueTypeCollector(FxHashSet<OpaqueTyId>);
+
+    impl TypeVisitor<Interner> for OpaqueTypeCollector {
+        type BreakTy = ();
+
+        fn as_dyn(&mut self) -> &mut dyn TypeVisitor<Interner, BreakTy = Self::BreakTy> {
+            self
+        }
+
+        fn interner(&self) -> Interner {
+            Interner
+        }
+
+        fn visit_ty(&mut self, ty: &Ty, outer_binder: DebruijnIndex) -> ControlFlow<Self::BreakTy> {
+            if let TyKind::OpaqueType(opaque_ty_id, _) = ty.kind(Interner) {
+                self.0.insert(*opaque_ty_id);
+            }
+            ty.super_visit_with(self.as_dyn(), outer_binder)
+        }
+    }
+
+    let ret = sig.skip_binders().ret();
+    let mut visitor = OpaqueTypeCollector(FxHashSet::default());
+    ret.visit_with(visitor.as_dyn(), DebruijnIndex::INNERMOST);
+
+    // Since we haven't implemented RPITIT in proper way like rustc yet,
+    // just check whether `ret` contains RPIT for now
+    for opaque_ty in visitor.0 {
+        let impl_trait_id = db.lookup_intern_impl_trait_id(opaque_ty.into());
+        if matches!(impl_trait_id, ImplTraitId::ReturnTypeImplTrait(..)) {
+            return Some(MethodViolationCode::ReferencesImplTraitInTrait);
+        }
+    }
+
+    None
+}
+
+#[cfg(test)]
+mod tests;
diff --git a/crates/hir-ty/src/object_safety/tests.rs b/crates/hir-ty/src/object_safety/tests.rs
new file mode 100644
index 0000000..c2a9117
--- /dev/null
+++ b/crates/hir-ty/src/object_safety/tests.rs
@@ -0,0 +1,393 @@
+use std::ops::ControlFlow;
+
+use hir_def::db::DefDatabase;
+use rustc_hash::{FxHashMap, FxHashSet};
+use syntax::ToSmolStr;
+use test_fixture::WithFixture;
+
+use crate::{object_safety::object_safety_with_callback, test_db::TestDB};
+
+use super::{
+    MethodViolationCode::{self, *},
+    ObjectSafetyViolation,
+};
+
+use ObjectSafetyViolationKind::*;
+
+#[allow(clippy::upper_case_acronyms)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+enum ObjectSafetyViolationKind {
+    SizedSelf,
+    SelfReferential,
+    Method(MethodViolationCode),
+    AssocConst,
+    GAT,
+    HasNonSafeSuperTrait,
+}
+
+fn check_object_safety<'a>(
+    ra_fixture: &str,
+    expected: impl IntoIterator<Item = (&'a str, Vec<ObjectSafetyViolationKind>)>,
+) {
+    let mut expected: FxHashMap<_, _> =
+        expected.into_iter().map(|(id, osvs)| (id, FxHashSet::from_iter(osvs))).collect();
+    let (db, file_ids) = TestDB::with_many_files(ra_fixture);
+    for (trait_id, name) in file_ids.into_iter().flat_map(|file_id| {
+        let module_id = db.module_for_file(file_id);
+        let def_map = module_id.def_map(&db);
+        let scope = &def_map[module_id.local_id].scope;
+        scope
+            .declarations()
+            .filter_map(|def| {
+                if let hir_def::ModuleDefId::TraitId(trait_id) = def {
+                    let name =
+                        db.trait_data(trait_id).name.display_no_db(file_id.edition()).to_smolstr();
+                    Some((trait_id, name))
+                } else {
+                    None
+                }
+            })
+            .collect::<Vec<_>>()
+    }) {
+        let Some(expected) = expected.remove(name.as_str()) else {
+            continue;
+        };
+        let mut osvs = FxHashSet::default();
+        object_safety_with_callback(&db, trait_id, &mut |osv| {
+            osvs.insert(match osv {
+                ObjectSafetyViolation::SizedSelf => SizedSelf,
+                ObjectSafetyViolation::SelfReferential => SelfReferential,
+                ObjectSafetyViolation::Method(_, mvc) => Method(mvc),
+                ObjectSafetyViolation::AssocConst(_) => AssocConst,
+                ObjectSafetyViolation::GAT(_) => GAT,
+                ObjectSafetyViolation::HasNonSafeSuperTrait(_) => HasNonSafeSuperTrait,
+            });
+            ControlFlow::Continue(())
+        });
+        assert_eq!(osvs, expected, "Object safety violations for `{name}` do not match;");
+    }
+
+    let remains: Vec<_> = expected.keys().collect();
+    assert!(remains.is_empty(), "Following traits do not exist in the test fixture; {remains:?}");
+}
+
+#[test]
+fn item_bounds_can_reference_self() {
+    check_object_safety(
+        r#"
+//- minicore: eq
+pub trait Foo {
+    type X: PartialEq;
+    type Y: PartialEq<Self::Y>;
+    type Z: PartialEq<Self::Y>;
+}
+"#,
+        [("Foo", vec![])],
+    );
+}
+
+#[test]
+fn associated_consts() {
+    check_object_safety(
+        r#"
+trait Bar {
+    const X: usize;
+}
+"#,
+        [("Bar", vec![AssocConst])],
+    );
+}
+
+#[test]
+fn bounds_reference_self() {
+    check_object_safety(
+        r#"
+//- minicore: eq
+trait X {
+    type U: PartialEq<Self>;
+}
+"#,
+        [("X", vec![SelfReferential])],
+    );
+}
+
+#[test]
+fn by_value_self() {
+    check_object_safety(
+        r#"
+//- minicore: dispatch_from_dyn
+trait Bar {
+    fn bar(self);
+}
+
+trait Baz {
+    fn baz(self: Self);
+}
+
+trait Quux {
+    // Legal because of the where clause:
+    fn baz(self: Self) where Self : Sized;
+}
+"#,
+        [("Bar", vec![]), ("Baz", vec![]), ("Quux", vec![])],
+    );
+}
+
+#[test]
+fn generic_methods() {
+    check_object_safety(
+        r#"
+//- minicore: dispatch_from_dyn
+trait Bar {
+    fn bar<T>(&self, t: T);
+}
+
+trait Quux {
+    fn bar<T>(&self, t: T)
+        where Self : Sized;
+}
+
+trait Qax {
+    fn bar<'a>(&self, t: &'a ());
+}
+"#,
+        [("Bar", vec![Method(Generic)]), ("Quux", vec![]), ("Qax", vec![])],
+    );
+}
+
+#[test]
+fn mentions_self() {
+    check_object_safety(
+        r#"
+//- minicore: dispatch_from_dyn
+trait Bar {
+    fn bar(&self, x: &Self);
+}
+
+trait Baz {
+    fn baz(&self) -> Self;
+}
+
+trait Quux {
+    fn quux(&self, s: &Self) -> Self where Self : Sized;
+}
+"#,
+        [
+            ("Bar", vec![Method(ReferencesSelfInput)]),
+            ("Baz", vec![Method(ReferencesSelfOutput)]),
+            ("Quux", vec![]),
+        ],
+    );
+}
+
+#[test]
+fn no_static() {
+    check_object_safety(
+        r#"
+//- minicore: dispatch_from_dyn
+trait Foo {
+    fn foo() {}
+}
+"#,
+        [("Foo", vec![Method(StaticMethod)])],
+    );
+}
+
+#[test]
+fn sized_self() {
+    check_object_safety(
+        r#"
+//- minicore: dispatch_from_dyn
+trait Bar: Sized {
+    fn bar<T>(&self, t: T);
+}
+"#,
+        [("Bar", vec![SizedSelf])],
+    );
+
+    check_object_safety(
+        r#"
+//- minicore: dispatch_from_dyn
+trait Bar
+    where Self : Sized
+{
+    fn bar<T>(&self, t: T);
+}
+"#,
+        [("Bar", vec![SizedSelf])],
+    );
+}
+
+#[test]
+fn supertrait_gat() {
+    check_object_safety(
+        r#"
+//- minicore: dispatch_from_dyn
+trait GatTrait {
+    type Gat<T>;
+}
+
+trait SuperTrait<T>: GatTrait {}
+"#,
+        [("GatTrait", vec![GAT]), ("SuperTrait", vec![HasNonSafeSuperTrait])],
+    );
+}
+
+#[test]
+fn supertrait_mentions_self() {
+    check_object_safety(
+        r#"
+//- minicore: dispatch_from_dyn
+trait Bar<T> {
+    fn bar(&self, x: &T);
+}
+
+trait Baz : Bar<Self> {
+}
+"#,
+        [("Bar", vec![]), ("Baz", vec![SizedSelf, SelfReferential])],
+    );
+}
+
+#[test]
+fn rustc_issue_19538() {
+    check_object_safety(
+        r#"
+//- minicore: dispatch_from_dyn
+trait Foo {
+    fn foo<T>(&self, val: T);
+}
+
+trait Bar: Foo {}
+"#,
+        [("Foo", vec![Method(Generic)]), ("Bar", vec![HasNonSafeSuperTrait])],
+    );
+}
+
+#[test]
+fn rustc_issue_22040() {
+    check_object_safety(
+        r#"
+//- minicore: fmt, eq, dispatch_from_dyn
+use core::fmt::Debug;
+
+trait Expr: Debug + PartialEq {
+    fn print_element_count(&self);
+}
+"#,
+        [("Expr", vec![SelfReferential])],
+    );
+}
+
+#[test]
+fn rustc_issue_102762() {
+    check_object_safety(
+        r#"
+//- minicore: future, send, sync, dispatch_from_dyn, deref
+use core::pin::Pin;
+
+struct Box<T: ?Sized> {}
+impl<T: ?Sized> core::ops::Deref for Box<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        loop {}
+    }
+}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T> {}
+
+struct Vec<T> {}
+
+pub trait Fetcher: Send + Sync {
+    fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
+    where
+        Self: Sync,
+    {
+        loop {}
+    }
+}
+"#,
+        [("Fetcher", vec![Method(UndispatchableReceiver)])],
+    );
+}
+
+#[test]
+fn rustc_issue_102933() {
+    check_object_safety(
+        r#"
+//- minicore: future, dispatch_from_dyn, deref
+use core::future::Future;
+
+struct Box<T: ?Sized> {}
+impl<T: ?Sized> core::ops::Deref for Box<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        loop {}
+    }
+}
+impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T> {}
+
+pub trait Service {
+    type Response;
+    type Future: Future<Output = Self::Response>;
+}
+
+pub trait A1: Service<Response = i32> {}
+
+pub trait A2: Service<Future = Box<dyn Future<Output = i32>>> + A1 {
+    fn foo(&self) {}
+}
+
+pub trait B1: Service<Future = Box<dyn Future<Output = i32>>> {}
+
+pub trait B2: Service<Response = i32> + B1 {
+    fn foo(&self) {}
+}
+        "#,
+        [("A2", vec![]), ("B2", vec![])],
+    );
+}
+
+#[test]
+fn rustc_issue_106247() {
+    check_object_safety(
+        r#"
+//- minicore: sync, dispatch_from_dyn
+pub trait Trait {
+    fn method(&self) where Self: Sync;
+}
+"#,
+        [("Trait", vec![])],
+    );
+}
+
+#[test]
+fn std_error_is_object_safe() {
+    check_object_safety(
+        r#"
+//- minicore: fmt, dispatch_from_dyn
+trait Erased<'a>: 'a {}
+
+pub struct Request<'a>(dyn Erased<'a> + 'a);
+
+pub trait Error: core::fmt::Debug + core::fmt::Display {
+    fn provide<'a>(&'a self, request: &mut Request<'a>);
+}
+"#,
+        [("Error", vec![])],
+    );
+}
+
+#[test]
+fn lifetime_gat_is_object_unsafe() {
+    check_object_safety(
+        r#"
+//- minicore: dispatch_from_dyn
+trait Foo {
+    type Bar<'a>;
+}
+"#,
+        [("Foo", vec![ObjectSafetyViolationKind::GAT])],
+    );
+}
diff --git a/crates/hir-ty/src/tests/coercion.rs b/crates/hir-ty/src/tests/coercion.rs
index 908bbc2..2735719 100644
--- a/crates/hir-ty/src/tests/coercion.rs
+++ b/crates/hir-ty/src/tests/coercion.rs
@@ -49,7 +49,7 @@
 //- minicore: coerce_unsized
 fn test() {
     let x: &[isize] = &[1];
-                   // ^^^^ adjustments: Deref(None), Borrow(Ref('?3, Not)), Pointer(Unsize)
+                   // ^^^^ adjustments: Deref(None), Borrow(Ref('?2, Not)), Pointer(Unsize)
     let x: *const [isize] = &[1];
                          // ^^^^ adjustments: Deref(None), Borrow(RawPtr(Not)), Pointer(Unsize)
 }
@@ -148,7 +148,7 @@
 fn test(i: i32) {
     let x = match i {
         2 => foo(&[2]),
-              // ^^^^ adjustments: Deref(None), Borrow(Ref('?10, Not)), Pointer(Unsize)
+              // ^^^^ adjustments: Deref(None), Borrow(Ref('?8, Not)), Pointer(Unsize)
         1 => &[1],
         _ => &[3],
     };
diff --git a/crates/hir-ty/src/tests/macros.rs b/crates/hir-ty/src/tests/macros.rs
index 5454a49..53b69c1 100644
--- a/crates/hir-ty/src/tests/macros.rs
+++ b/crates/hir-ty/src/tests/macros.rs
@@ -1,7 +1,7 @@
 use expect_test::expect;
 use test_utils::{bench, bench_fixture, skip_slow_tests};
 
-use crate::tests::check_infer_with_mismatches;
+use crate::tests::{check_infer_with_mismatches, check_no_mismatches};
 
 use super::{check_infer, check_types};
 
@@ -206,6 +206,7 @@
             100..119 'for _ ...!() {}': ()
             100..119 'for _ ...!() {}': ()
             100..119 'for _ ...!() {}': ()
+            100..119 'for _ ...!() {}': ()
             104..105 '_': IntoIterator::Item<isize>
             117..119 '{}': ()
             124..134 '|| spam!()': impl Fn() -> isize
@@ -299,6 +300,7 @@
             114..133 'for _ ...!() {}': ()
             114..133 'for _ ...!() {}': ()
             114..133 'for _ ...!() {}': ()
+            114..133 'for _ ...!() {}': ()
             118..119 '_': IntoIterator::Item<isize>
             131..133 '{}': ()
             138..148 '|| spam!()': impl Fn() -> isize
@@ -1404,3 +1406,105 @@
 "#,
     );
 }
+
+#[test]
+fn asm_unit() {
+    check_no_mismatches(
+        r#"
+//- minicore: asm
+fn unit() {
+    core::arch::asm!("")
+}
+"#,
+    );
+}
+
+#[test]
+fn asm_no_return() {
+    check_no_mismatches(
+        r#"
+//- minicore: asm
+fn unit() -> ! {
+    core::arch::asm!("", options(noreturn))
+}
+"#,
+    );
+}
+
+#[test]
+fn asm_things() {
+    check_infer(
+        r#"
+//- minicore: asm, concat
+fn main() {
+    unsafe {
+        let foo = 1;
+        let mut o = 0;
+        core::arch::asm!(
+            "%input = OpLoad _ {0}",
+            concat!("%result = ", bar, " _ %input"),
+            "OpStore {1} %result",
+            in(reg) &foo,
+            in(reg) &mut o,
+        );
+        o
+
+        let thread_id: usize;
+        core::arch::asm!("
+            mov {0}, gs:[0x30]
+            mov {0}, [{0}+0x48]
+        ", out(reg) thread_id, options(pure, readonly, nostack));
+
+        static UNMAP_BASE: usize;
+        const MEM_RELEASE: usize;
+        static VirtualFree: usize;
+        const OffPtr: usize;
+        const OffFn: usize;
+        core::arch::asm!("
+            push {free_type}
+            push {free_size}
+            push {base}
+
+            mov eax, fs:[30h]
+            mov eax, [eax+8h]
+            add eax, {off_fn}
+            mov [eax-{off_fn}+{off_ptr}], eax
+
+            push eax
+
+            jmp {virtual_free}
+            ",
+            off_ptr = const OffPtr,
+            off_fn  = const OffFn,
+
+            free_size = const 0,
+            free_type = const MEM_RELEASE,
+
+            virtual_free = sym VirtualFree,
+
+            base = sym UNMAP_BASE,
+            options(noreturn),
+        );
+    }
+}
+"#,
+        expect![[r#"
+            !0..122 'builti...muto,)': ()
+            !0..136 'builti...tack))': ()
+            !0..449 'builti...urn),)': !
+            10..1236 '{     ...   } }': ()
+            16..1234 'unsafe...     }': ()
+            37..40 'foo': i32
+            43..44 '1': i32
+            58..63 'mut o': i32
+            66..67 '0': i32
+            !95..104 'thread_id': usize
+            !103..107 '&foo': &'? i32
+            !104..107 'foo': i32
+            !115..120 '&muto': &'? mut i32
+            !119..120 'o': i32
+            293..294 'o': i32
+            308..317 'thread_id': usize
+        "#]],
+    )
+}
diff --git a/crates/hir-ty/src/tests/method_resolution.rs b/crates/hir-ty/src/tests/method_resolution.rs
index 610fc9b..74acf23 100644
--- a/crates/hir-ty/src/tests/method_resolution.rs
+++ b/crates/hir-ty/src/tests/method_resolution.rs
@@ -1286,6 +1286,7 @@
 fn method_on_dyn_impl() {
     check_types(
         r#"
+//- minicore: coerce_unsized
 trait Foo {}
 
 impl Foo for u32 {}
diff --git a/crates/hir-ty/src/tests/never_type.rs b/crates/hir-ty/src/tests/never_type.rs
index 0ccbcf6..5c63cd0 100644
--- a/crates/hir-ty/src/tests/never_type.rs
+++ b/crates/hir-ty/src/tests/never_type.rs
@@ -371,6 +371,7 @@
             151..172 'for a ...eak; }': ()
             151..172 'for a ...eak; }': ()
             151..172 'for a ...eak; }': ()
+            151..172 'for a ...eak; }': ()
             155..156 'a': {unknown}
             160..161 'b': {unknown}
             162..172 '{ break; }': ()
@@ -387,6 +388,7 @@
             237..250 'for a in b {}': ()
             237..250 'for a in b {}': ()
             237..250 'for a in b {}': ()
+            237..250 'for a in b {}': ()
             241..242 'a': {unknown}
             246..247 'b': {unknown}
             248..250 '{}': ()
@@ -402,6 +404,7 @@
             315..337 'for a ...urn; }': ()
             315..337 'for a ...urn; }': ()
             315..337 'for a ...urn; }': ()
+            315..337 'for a ...urn; }': ()
             319..320 'a': {unknown}
             324..325 'b': {unknown}
             326..337 '{ return; }': ()
diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs
index 57866ac..51c27f8 100644
--- a/crates/hir-ty/src/tests/patterns.rs
+++ b/crates/hir-ty/src/tests/patterns.rs
@@ -57,6 +57,7 @@
             101..151 'for (e...     }': ()
             101..151 'for (e...     }': ()
             101..151 'for (e...     }': ()
+            101..151 'for (e...     }': ()
             105..111 '(e, f)': ({unknown}, {unknown})
             106..107 'e': {unknown}
             109..110 'f': {unknown}
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index 17fbe4d..a3cf12d 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -275,6 +275,7 @@
             32..320 'for co...     }': ()
             32..320 'for co...     }': ()
             32..320 'for co...     }': ()
+            32..320 'for co...     }': ()
             36..43 'content': {unknown}
             47..60 'doesnt_matter': {unknown}
             61..320 '{     ...     }': ()
@@ -1065,7 +1066,7 @@
 fn bare_dyn_trait_binders_9639() {
     check_no_mismatches(
         r#"
-//- minicore: fn, coerce_unsized
+//- minicore: fn, coerce_unsized, dispatch_from_dyn
 fn infix_parse<T, S>(_state: S, _level_code: &Fn(S)) -> T {
     loop {}
 }
@@ -1244,6 +1245,7 @@
             16..66 'for _ ...     }': ()
             16..66 'for _ ...     }': ()
             16..66 'for _ ...     }': ()
+            16..66 'for _ ...     }': ()
             20..21 '_': IntoIterator::Item<()>
             25..39 '{ let x = 0; }': ()
             31..32 'x': i32
@@ -1907,6 +1909,7 @@
     // #15246
     check_types(
         r#"
+//- minicore: sized
 fn unify(_: [bool; 1]) {}
 fn casted(_: *const bool) {}
 fn default<T>() -> T { loop {} }
@@ -1926,6 +1929,7 @@
 fn rustc_test_issue_52437() {
     check_types(
         r#"
+    //- minicore: sized
     fn main() {
         let x = [(); &(&'static: loop { |x| {}; }) as *const _ as usize]
           //^ [(); _]
@@ -2228,3 +2232,66 @@
         "#]],
     );
 }
+
+#[test]
+fn issue_18109() {
+    check_infer(
+        r#"
+//- minicore: option
+struct Map<T, U>(T, U);
+
+impl<T, U> Map<T, U> {
+    fn new() -> Self { loop {} }
+    fn get(&self, _: &T) -> Option<&U> { loop {} }
+}
+
+fn test(x: bool) {
+    let map = Map::new();
+    let _ = match x {
+        true => {
+            let Some(val) = map.get(&8) else { return };
+            *val
+        }
+        false => return,
+        _ => 42,
+    };
+}
+"#,
+        expect![[r#"
+            69..80 '{ loop {} }': Map<T, U>
+            71..78 'loop {}': !
+            76..78 '{}': ()
+            93..97 'self': &'? Map<T, U>
+            99..100 '_': &'? T
+            120..131 '{ loop {} }': Option<&'? U>
+            122..129 'loop {}': !
+            127..129 '{}': ()
+            143..144 'x': bool
+            152..354 '{     ...  }; }': ()
+            162..165 'map': Map<i32, i32>
+            168..176 'Map::new': fn new<i32, i32>() -> Map<i32, i32>
+            168..178 'Map::new()': Map<i32, i32>
+            188..189 '_': i32
+            192..351 'match ...     }': i32
+            198..199 'x': bool
+            210..214 'true': bool
+            210..214 'true': bool
+            218..303 '{     ...     }': i32
+            236..245 'Some(val)': Option<&'? i32>
+            241..244 'val': &'? i32
+            248..251 'map': Map<i32, i32>
+            248..259 'map.get(&8)': Option<&'? i32>
+            256..258 '&8': &'? i32
+            257..258 '8': i32
+            265..275 '{ return }': !
+            267..273 'return': !
+            289..293 '*val': i32
+            290..293 'val': &'? i32
+            312..317 'false': bool
+            312..317 'false': bool
+            321..327 'return': !
+            337..338 '_': bool
+            342..344 '42': i32
+        "#]],
+    );
+}
diff --git a/crates/hir-ty/src/tests/simple.rs b/crates/hir-ty/src/tests/simple.rs
index 1c6fa62..0473ee0 100644
--- a/crates/hir-ty/src/tests/simple.rs
+++ b/crates/hir-ty/src/tests/simple.rs
@@ -917,7 +917,7 @@
             278..279 'A': extern "rust-call" A<i32>(*mut i32) -> A<i32>
             278..292 'A(0 as *mut _)': A<i32>
             278..307 'A(0 as...B(a)))': &'? i32
-            280..281 '0': i32
+            280..281 '0': usize
             280..291 '0 as *mut _': *mut i32
             297..306 '&&B(B(a))': &'? &'? B<B<A<i32>>>
             298..306 '&B(B(a))': &'? B<B<A<i32>>>
@@ -3572,6 +3572,7 @@
 fn ref_to_array_to_ptr_cast() {
     check_types(
         r#"
+//- minicore: sized
 fn default<T>() -> T { loop {} }
 fn foo() {
     let arr = [default()];
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index a98cff2..0b2d6bd 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -1448,14 +1448,20 @@
 fn dyn_trait() {
     check_infer(
         r#"
-//- minicore: sized
+//- minicore: deref, dispatch_from_dyn
 trait Trait<T> {
     fn foo(&self) -> T;
     fn foo2(&self) -> i64;
 }
-fn bar() -> dyn Trait<u64> {}
 
-fn test(x: dyn Trait<u64>, y: &dyn Trait<u64>) {
+struct Box<T: ?Sized> {}
+impl<T: ?Sized> core::ops::Deref for Box<T> {
+    type Target = T;
+}
+
+fn bar() -> Box<dyn Trait<u64>> {}
+
+fn test(x: Box<dyn Trait<u64>>, y: &dyn Trait<u64>) {
     x;
     y;
     let z = bar();
@@ -1469,27 +1475,27 @@
         expect![[r#"
             29..33 'self': &'? Self
             54..58 'self': &'? Self
-            97..99 '{}': dyn Trait<u64>
-            109..110 'x': dyn Trait<u64>
-            128..129 'y': &'? dyn Trait<u64>
-            148..265 '{     ...2(); }': ()
-            154..155 'x': dyn Trait<u64>
-            161..162 'y': &'? dyn Trait<u64>
-            172..173 'z': dyn Trait<u64>
-            176..179 'bar': fn bar() -> dyn Trait<u64>
-            176..181 'bar()': dyn Trait<u64>
-            187..188 'x': dyn Trait<u64>
-            187..194 'x.foo()': u64
-            200..201 'y': &'? dyn Trait<u64>
-            200..207 'y.foo()': u64
-            213..214 'z': dyn Trait<u64>
-            213..220 'z.foo()': u64
-            226..227 'x': dyn Trait<u64>
-            226..234 'x.foo2()': i64
-            240..241 'y': &'? dyn Trait<u64>
-            240..248 'y.foo2()': i64
-            254..255 'z': dyn Trait<u64>
-            254..262 'z.foo2()': i64
+            198..200 '{}': Box<dyn Trait<u64>>
+            210..211 'x': Box<dyn Trait<u64>>
+            234..235 'y': &'? dyn Trait<u64>
+            254..371 '{     ...2(); }': ()
+            260..261 'x': Box<dyn Trait<u64>>
+            267..268 'y': &'? dyn Trait<u64>
+            278..279 'z': Box<dyn Trait<u64>>
+            282..285 'bar': fn bar() -> Box<dyn Trait<u64>>
+            282..287 'bar()': Box<dyn Trait<u64>>
+            293..294 'x': Box<dyn Trait<u64>>
+            293..300 'x.foo()': u64
+            306..307 'y': &'? dyn Trait<u64>
+            306..313 'y.foo()': u64
+            319..320 'z': Box<dyn Trait<u64>>
+            319..326 'z.foo()': u64
+            332..333 'x': Box<dyn Trait<u64>>
+            332..340 'x.foo2()': i64
+            346..347 'y': &'? dyn Trait<u64>
+            346..354 'y.foo2()': i64
+            360..361 'z': Box<dyn Trait<u64>>
+            360..368 'z.foo2()': i64
         "#]],
     );
 }
@@ -1534,7 +1540,7 @@
 fn dyn_trait_bare() {
     check_infer(
         r#"
-//- minicore: sized
+//- minicore: sized, dispatch_from_dyn
 trait Trait {
     fn foo(&self) -> u64;
 }
@@ -1570,7 +1576,7 @@
 
     check_infer_with_mismatches(
         r#"
-//- minicore: fn, coerce_unsized
+//- minicore: fn, coerce_unsized, dispatch_from_dyn
 struct S;
 impl S {
     fn foo(&self) {}
@@ -3106,7 +3112,7 @@
     cov_mark::check!(dyn_fn_param_informs_call_site_closure_signature);
     check_types(
         r#"
-//- minicore: fn, coerce_unsized
+//- minicore: fn, coerce_unsized, dispatch_from_dyn
 struct S;
 impl S {
     fn inherent(&self) -> u8 { 0 }
@@ -3151,7 +3157,7 @@
     // The type mismatch is because we don't define Unsize and CoerceUnsized
     check_infer_with_mismatches(
         r#"
-//- minicore: fn, deref, option
+//- minicore: fn, deref, option, dispatch_from_dyn
 #[lang = "owned_box"]
 pub struct Box<T: ?Sized> {
     inner: *mut T,
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index ffb9724..0b3cdb2 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -4,7 +4,9 @@
 //! This probably isn't the best way to do this -- ideally, diagnostics should
 //! be expressed in terms of hir types themselves.
 pub use hir_ty::diagnostics::{CaseType, IncorrectCase};
-use hir_ty::{db::HirDatabase, diagnostics::BodyValidationDiagnostic, InferenceDiagnostic};
+use hir_ty::{
+    db::HirDatabase, diagnostics::BodyValidationDiagnostic, CastError, InferenceDiagnostic,
+};
 
 use cfg::{CfgExpr, CfgOptions};
 use either::Either;
@@ -50,10 +52,12 @@
 diagnostics![
     AwaitOutsideOfAsync,
     BreakOutsideOfLoop,
+    CastToUnsized,
     ExpectedFunction,
     InactiveCode,
     IncoherentImpl,
     IncorrectCase,
+    InvalidCast,
     InvalidDeriveTarget,
     MacroDefError,
     MacroError,
@@ -254,6 +258,8 @@
 #[derive(Debug)]
 pub struct MissingUnsafe {
     pub expr: InFile<AstPtr<ast::Expr>>,
+    /// If true, the diagnostics is an `unsafe_op_in_unsafe_fn` lint instead of a hard error.
+    pub only_lint: bool,
 }
 
 #[derive(Debug)]
@@ -364,6 +370,20 @@
     pub if_expr: InFile<AstPtr<ast::IfExpr>>,
 }
 
+#[derive(Debug)]
+pub struct CastToUnsized {
+    pub expr: InFile<AstPtr<ast::Expr>>,
+    pub cast_ty: Type,
+}
+
+#[derive(Debug)]
+pub struct InvalidCast {
+    pub expr: InFile<AstPtr<ast::Expr>>,
+    pub error: CastError,
+    pub expr_ty: Type,
+    pub cast_ty: Type,
+}
+
 impl AnyDiagnostic {
     pub(crate) fn body_validation_diagnostic(
         db: &dyn HirDatabase,
@@ -620,6 +640,16 @@
                 };
                 MismatchedTupleStructPatArgCount { expr_or_pat, expected, found }.into()
             }
+            InferenceDiagnostic::CastToUnsized { expr, cast_ty } => {
+                let expr = expr_syntax(*expr)?;
+                CastToUnsized { expr, cast_ty: Type::new(db, def, cast_ty.clone()) }.into()
+            }
+            InferenceDiagnostic::InvalidCast { expr, error, expr_ty, cast_ty } => {
+                let expr = expr_syntax(*expr)?;
+                let expr_ty = Type::new(db, def, expr_ty.clone());
+                let cast_ty = Type::new(db, def, cast_ty.clone());
+                InvalidCast { expr, error: *error, expr_ty, cast_ty }.into()
+            }
         })
     }
 }
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 923dca6..c2b2fbe 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -99,17 +99,20 @@
         }
 
         // FIXME: Use resolved `param.ty` once we no longer discard lifetimes
+        let body = db.body(self.id.into());
         for (type_ref, param) in data.params.iter().zip(self.assoc_fn_params(db)).skip(skip_self) {
-            let local = param.as_local(db).map(|it| it.name(db));
             if !first {
                 f.write_str(", ")?;
             } else {
                 first = false;
             }
-            match local {
-                Some(name) => write!(f, "{}: ", name.display(f.db.upcast(), f.edition()))?,
-                None => f.write_str("_: ")?,
-            }
+
+            let pat_id = body.params[param.idx - body.self_param.is_some() as usize];
+            let pat_str =
+                body.pretty_print_pat(db.upcast(), self.id.into(), pat_id, true, f.edition());
+            f.write_str(&pat_str)?;
+
+            f.write_str(": ")?;
             type_ref.hir_fmt(f)?;
         }
 
diff --git a/crates/hir/src/has_source.rs b/crates/hir/src/has_source.rs
index 7d52a28..82c90ac 100644
--- a/crates/hir/src/has_source.rs
+++ b/crates/hir/src/has_source.rs
@@ -14,8 +14,8 @@
 
 use crate::{
     db::HirDatabase, Adt, Callee, Const, Enum, ExternCrateDecl, Field, FieldSource, Function, Impl,
-    Label, LifetimeParam, LocalSource, Macro, Module, Param, SelfParam, Static, Struct, Trait,
-    TraitAlias, TypeAlias, TypeOrConstParam, Union, Variant,
+    InlineAsmOperand, Label, LifetimeParam, LocalSource, Macro, Module, Param, SelfParam, Static,
+    Struct, Trait, TraitAlias, TypeAlias, TypeOrConstParam, Union, Variant,
 };
 
 pub trait HasSource {
@@ -292,3 +292,26 @@
         Some(self.id.lookup(db.upcast()).source(db.upcast()))
     }
 }
+
+impl HasSource for InlineAsmOperand {
+    type Ast = ast::AsmOperandNamed;
+    fn source(self, db: &dyn HirDatabase) -> Option<InFile<Self::Ast>> {
+        let (_body, source_map) = db.body_with_source_map(self.owner);
+        if let Ok(src) = source_map.expr_syntax(self.expr) {
+            let root = src.file_syntax(db.upcast());
+            return src
+                .map(|ast| match ast.to_node(&root) {
+                    ast::Expr::AsmExpr(asm) => asm
+                        .asm_pieces()
+                        .filter_map(|it| match it {
+                            ast::AsmPiece::AsmOperandNamed(it) => Some(it),
+                            _ => None,
+                        })
+                        .nth(self.index),
+                    _ => None,
+                })
+                .transpose();
+        }
+        None
+    }
+}
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 58340c7..8f5db32 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -43,7 +43,7 @@
     body::{BodyDiagnostic, SyntheticSyntax},
     data::adt::VariantData,
     generics::{LifetimeParamData, TypeOrConstParamData, TypeParamProvenance},
-    hir::{BindingAnnotation, BindingId, ExprOrPatId, LabelId, Pat},
+    hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, Pat},
     item_tree::{AttrOwner, FieldParent, ItemTreeFieldId, ItemTreeNode},
     lang_item::LangItemTarget,
     layout::{self, ReprOptions, TargetDataLayout},
@@ -66,7 +66,7 @@
     diagnostics::BodyValidationDiagnostic,
     error_lifetime, known_const_to_ast,
     layout::{Layout as TyLayout, RustcEnumVariantIdx, RustcFieldIdx, TagEncoding},
-    method_resolution::{self},
+    method_resolution,
     mir::{interpret_mir, MutBorrowKind},
     primitive::UintTy,
     traits::FnTrait,
@@ -80,7 +80,7 @@
 use rustc_hash::FxHashSet;
 use smallvec::SmallVec;
 use span::{Edition, EditionedFileId, FileId, MacroCallId, SyntaxContextId};
-use stdx::{impl_from, never};
+use stdx::{format_to, impl_from, never};
 use syntax::{
     ast::{self, HasAttrs as _, HasGenericParams, HasName},
     format_smolstr, AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, TextRange, ToSmolStr, T,
@@ -137,6 +137,7 @@
         hygiene::{marks_rev, SyntaxContextExt},
         inert_attr_macro::AttributeTemplate,
         name::Name,
+        prettify_macro_expansion,
         proc_macro::{ProcMacros, ProcMacrosBuilder},
         tt, ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt,
     },
@@ -145,7 +146,8 @@
         display::{ClosureStyle, HirDisplay, HirDisplayError, HirWrite},
         layout::LayoutError,
         mir::{MirEvalError, MirLowerError},
-        FnAbi, PointerCast, Safety,
+        object_safety::{MethodViolationCode, ObjectSafetyViolation},
+        CastError, FnAbi, PointerCast, Safety,
     },
     // FIXME: Properly encapsulate mir
     hir_ty::{mir, Interner as ChalkTyInterner},
@@ -1882,9 +1884,10 @@
             );
         }
 
-        for expr in hir_ty::diagnostics::missing_unsafe(db, self.into()) {
+        let (unafe_exprs, only_lint) = hir_ty::diagnostics::missing_unsafe(db, self.into());
+        for expr in unafe_exprs {
             match source_map.expr_syntax(expr) {
-                Ok(expr) => acc.push(MissingUnsafe { expr }.into()),
+                Ok(expr) => acc.push(MissingUnsafe { expr, only_lint }.into()),
                 Err(SyntheticSyntax) => {
                     // FIXME: Here and elsewhere in this file, the `expr` was
                     // desugared, report or assert that this doesn't happen.
@@ -2206,6 +2209,35 @@
         db.function_data(self.id).is_async()
     }
 
+    pub fn returns_impl_future(self, db: &dyn HirDatabase) -> bool {
+        if self.is_async(db) {
+            return true;
+        }
+
+        let Some(impl_traits) = self.ret_type(db).as_impl_traits(db) else { return false };
+        let Some(future_trait_id) =
+            db.lang_item(self.ty(db).env.krate, LangItem::Future).and_then(|t| t.as_trait())
+        else {
+            return false;
+        };
+        let Some(sized_trait_id) =
+            db.lang_item(self.ty(db).env.krate, LangItem::Sized).and_then(|t| t.as_trait())
+        else {
+            return false;
+        };
+
+        let mut has_impl_future = false;
+        impl_traits
+            .filter(|t| {
+                let fut = t.id == future_trait_id;
+                has_impl_future |= fut;
+                !fut && t.id != sized_trait_id
+            })
+            // all traits but the future trait must be auto traits
+            .all(|t| t.is_auto(db))
+            && has_impl_future
+    }
+
     /// Does this function have `#[test]` attribute?
     pub fn is_test(self, db: &dyn HirDatabase) -> bool {
         db.function_data(self.id).attrs.is_test()
@@ -2522,6 +2554,17 @@
         Type::from_value_def(db, self.id)
     }
 
+    /// Evaluate the constant and return the result as a string.
+    ///
+    /// This function is intended for IDE assistance, different from [`Const::render_eval`].
+    pub fn eval(self, db: &dyn HirDatabase, edition: Edition) -> Result<String, ConstEvalError> {
+        let c = db.const_eval(self.id.into(), Substitution::empty(Interner), None)?;
+        Ok(format!("{}", c.display(db, edition)))
+    }
+
+    /// Evaluate the constant and return the result as a string, with more detailed information.
+    ///
+    /// This function is intended for user-facing display.
     pub fn render_eval(
         self,
         db: &dyn HirDatabase,
@@ -2536,10 +2579,16 @@
                         let value = u128::from_le_bytes(mir::pad16(b, false));
                         let value_signed =
                             i128::from_le_bytes(mir::pad16(b, matches!(s, Scalar::Int(_))));
-                        if value >= 10 {
-                            return Ok(format!("{value_signed} ({value:#X})"));
+                        let mut result = if let Scalar::Int(_) = s {
+                            value_signed.to_string()
                         } else {
-                            return Ok(format!("{value_signed}"));
+                            value.to_string()
+                        };
+                        if value >= 10 {
+                            format_to!(result, " ({value:#X})");
+                            return Ok(result);
+                        } else {
+                            return Ok(result);
                         }
                     }
                 }
@@ -2641,6 +2690,10 @@
             .count()
     }
 
+    pub fn object_safety(&self, db: &dyn HirDatabase) -> Option<ObjectSafetyViolation> {
+        hir_ty::object_safety::object_safety(db, self.id)
+    }
+
     fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId<ast::Item>, MacroCallId)]> {
         db.trait_data(self.id)
             .macro_calls
@@ -5211,6 +5264,26 @@
     }
 }
 
+#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
+pub struct InlineAsmOperand {
+    owner: DefWithBodyId,
+    expr: ExprId,
+    index: usize,
+}
+
+impl InlineAsmOperand {
+    pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody {
+        self.owner.into()
+    }
+
+    pub fn name(&self, db: &dyn HirDatabase) -> Option<Name> {
+        match &db.body(self.owner)[self.expr] {
+            hir_def::hir::Expr::InlineAsm(e) => e.operands.get(self.index)?.0.clone(),
+            _ => None,
+        }
+    }
+}
+
 // FIXME: Document this
 #[derive(Debug)]
 pub struct Callable {
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 763f530..fa14b53 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -13,7 +13,8 @@
 use hir_def::{
     hir::Expr,
     lower::LowerCtx,
-    nameres::MacroSubNs,
+    nameres::{MacroSubNs, ModuleOrigin},
+    path::ModPath,
     resolver::{self, HasResolver, Resolver, TypeNs},
     type_ref::Mutability,
     AsMacroCall, DefWithBodyId, FunctionId, MacroId, TraitId, VariantId,
@@ -31,7 +32,7 @@
 use itertools::Itertools;
 use rustc_hash::{FxHashMap, FxHashSet};
 use smallvec::{smallvec, SmallVec};
-use span::{EditionedFileId, FileId};
+use span::{EditionedFileId, FileId, HirFileIdRepr};
 use stdx::TupleExt;
 use syntax::{
     algo::skip_trivia_token,
@@ -46,9 +47,9 @@
     source_analyzer::{resolve_hir_path, SourceAnalyzer},
     Access, Adjust, Adjustment, Adt, AutoBorrow, BindingMode, BuiltinAttr, Callable, Const,
     ConstParam, Crate, DeriveHelper, Enum, Field, Function, HasSource, HirFileId, Impl, InFile,
-    Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, OverloadedDeref, Path, ScopeDef,
-    Static, Struct, ToolModule, Trait, TraitAlias, TupleField, Type, TypeAlias, TypeParam, Union,
-    Variant, VariantDef,
+    InlineAsmOperand, ItemInNs, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name,
+    OverloadedDeref, Path, ScopeDef, Static, Struct, ToolModule, Trait, TraitAlias, TupleField,
+    Type, TypeAlias, TypeParam, Union, Variant, VariantDef,
 };
 
 const CONTINUE_NO_BREAKS: ControlFlow<Infallible, ()> = ControlFlow::Continue(());
@@ -322,6 +323,47 @@
         tree
     }
 
+    pub fn find_parent_file(&self, file_id: HirFileId) -> Option<InFile<SyntaxNode>> {
+        match file_id.repr() {
+            HirFileIdRepr::FileId(file_id) => {
+                let module = self.file_to_module_defs(file_id.file_id()).next()?;
+                let def_map = self.db.crate_def_map(module.krate().id);
+                match def_map[module.id.local_id].origin {
+                    ModuleOrigin::CrateRoot { .. } => None,
+                    ModuleOrigin::File { declaration, declaration_tree_id, .. } => {
+                        let file_id = declaration_tree_id.file_id();
+                        let in_file = InFile::new(file_id, declaration);
+                        let node = in_file.to_node(self.db.upcast());
+                        let root = find_root(node.syntax());
+                        self.cache(root, file_id);
+                        Some(in_file.with_value(node.syntax().clone()))
+                    }
+                    _ => unreachable!("FileId can only belong to a file module"),
+                }
+            }
+            HirFileIdRepr::MacroFile(macro_file) => {
+                let node = self
+                    .db
+                    .lookup_intern_macro_call(macro_file.macro_call_id)
+                    .to_node(self.db.upcast());
+                let root = find_root(&node.value);
+                self.cache(root, node.file_id);
+                Some(node)
+            }
+        }
+    }
+
+    /// Returns the `SyntaxNode` of the module. If this is a file module, returns
+    /// the `SyntaxNode` of the *definition* file, not of the *declaration*.
+    pub fn module_definition_node(&self, module: Module) -> InFile<SyntaxNode> {
+        let def_map = module.id.def_map(self.db.upcast());
+        let definition = def_map[module.id.local_id].origin.definition_source(self.db.upcast());
+        let definition = definition.map(|it| it.node());
+        let root_node = find_root(&definition.value);
+        self.cache(root_node, definition.file_id);
+        definition
+    }
+
     pub fn parse_or_expand(&self, file_id: HirFileId) -> SyntaxNode {
         let node = self.db.parse_or_expand(file_id);
         self.cache(node.clone(), file_id);
@@ -344,6 +386,19 @@
         Some(node)
     }
 
+    pub fn check_cfg_attr(&self, attr: &ast::TokenTree) -> Option<bool> {
+        let file_id = self.find_file(attr.syntax()).file_id;
+        let krate = match file_id.repr() {
+            HirFileIdRepr::FileId(file_id) => {
+                self.file_to_module_defs(file_id.file_id()).next()?.krate().id
+            }
+            HirFileIdRepr::MacroFile(macro_file) => {
+                self.db.lookup_intern_macro_call(macro_file.macro_call_id).krate
+            }
+        };
+        hir_expand::check_cfg_attr_value(self.db.upcast(), attr, krate)
+    }
+
     /// Expands the macro if it isn't one of the built-in ones that expand to custom syntax or dummy
     /// expansions.
     pub fn expand_allowed_builtins(&self, macro_call: &ast::MacroCall) -> Option<SyntaxNode> {
@@ -367,7 +422,6 @@
                     | BuiltinFnLikeExpander::File
                     | BuiltinFnLikeExpander::ModulePath
                     | BuiltinFnLikeExpander::Asm
-                    | BuiltinFnLikeExpander::LlvmAsm
                     | BuiltinFnLikeExpander::GlobalAsm
                     | BuiltinFnLikeExpander::LogSyntax
                     | BuiltinFnLikeExpander::TraceMacros
@@ -408,7 +462,7 @@
             Some(
                 calls
                     .into_iter()
-                    .map(|call| macro_call_to_macro_id(ctx, call?).map(|id| Macro { id }))
+                    .map(|call| macro_call_to_macro_id(self, ctx, call?).map(|id| Macro { id }))
                     .collect(),
             )
         })
@@ -546,11 +600,11 @@
         )
     }
 
-    /// Retrieves all the formatting parts of the format_args! template string.
+    /// Retrieves all the formatting parts of the format_args! (or `asm!`) template string.
     pub fn as_format_args_parts(
         &self,
         string: &ast::String,
-    ) -> Option<Vec<(TextRange, Option<PathResolution>)>> {
+    ) -> Option<Vec<(TextRange, Option<Either<PathResolution, InlineAsmOperand>>)>> {
         let quote = string.open_quote_text_range()?;
 
         let token = self.wrap_token_infile(string.syntax().clone()).into_real_file().ok()?;
@@ -560,14 +614,33 @@
                 let string = ast::String::cast(token)?;
                 let literal =
                     string.syntax().parent().filter(|it| it.kind() == SyntaxKind::LITERAL)?;
-                let format_args = ast::FormatArgsExpr::cast(literal.parent()?)?;
-                let source_analyzer = self.analyze_no_infer(format_args.syntax())?;
-                let format_args = self.wrap_node_infile(format_args);
-                let res = source_analyzer
-                    .as_format_args_parts(self.db, format_args.as_ref())?
-                    .map(|(range, res)| (range + quote.end(), res))
-                    .collect();
-                Some(res)
+                let parent = literal.parent()?;
+                if let Some(format_args) = ast::FormatArgsExpr::cast(parent.clone()) {
+                    let source_analyzer = self.analyze_no_infer(format_args.syntax())?;
+                    let format_args = self.wrap_node_infile(format_args);
+                    let res = source_analyzer
+                        .as_format_args_parts(self.db, format_args.as_ref())?
+                        .map(|(range, res)| (range + quote.end(), res.map(Either::Left)))
+                        .collect();
+                    Some(res)
+                } else {
+                    let asm = ast::AsmExpr::cast(parent)?;
+                    let source_analyzer = self.analyze_no_infer(asm.syntax())?;
+                    let line = asm.template().position(|it| *it.syntax() == literal)?;
+                    let asm = self.wrap_node_infile(asm);
+                    let (owner, (expr, asm_parts)) = source_analyzer.as_asm_parts(asm.as_ref())?;
+                    let res = asm_parts
+                        .get(line)?
+                        .iter()
+                        .map(|&(range, index)| {
+                            (
+                                range + quote.end(),
+                                Some(Either::Right(InlineAsmOperand { owner, expr, index })),
+                            )
+                        })
+                        .collect();
+                    Some(res)
+                }
             })()
             .map_or(ControlFlow::Continue(()), ControlFlow::Break)
         })
@@ -578,7 +651,7 @@
         &self,
         original_token: SyntaxToken,
         offset: TextSize,
-    ) -> Option<(TextRange, Option<PathResolution>)> {
+    ) -> Option<(TextRange, Option<Either<PathResolution, InlineAsmOperand>>)> {
         let original_string = ast::String::cast(original_token.clone())?;
         let original_token = self.wrap_token_infile(original_token).into_real_file().ok()?;
         let quote = original_string.open_quote_text_range()?;
@@ -599,13 +672,27 @@
         &self,
         string: ast::String,
         offset: TextSize,
-    ) -> Option<(TextRange, Option<PathResolution>)> {
+    ) -> Option<(TextRange, Option<Either<PathResolution, InlineAsmOperand>>)> {
         debug_assert!(offset <= string.syntax().text_range().len());
         let literal = string.syntax().parent().filter(|it| it.kind() == SyntaxKind::LITERAL)?;
-        let format_args = ast::FormatArgsExpr::cast(literal.parent()?)?;
-        let source_analyzer = &self.analyze_no_infer(format_args.syntax())?;
-        let format_args = self.wrap_node_infile(format_args);
-        source_analyzer.resolve_offset_in_format_args(self.db, format_args.as_ref(), offset)
+        let parent = literal.parent()?;
+        if let Some(format_args) = ast::FormatArgsExpr::cast(parent.clone()) {
+            let source_analyzer = &self.analyze_no_infer(format_args.syntax())?;
+            let format_args = self.wrap_node_infile(format_args);
+            source_analyzer
+                .resolve_offset_in_format_args(self.db, format_args.as_ref(), offset)
+                .map(|(range, res)| (range, res.map(Either::Left)))
+        } else {
+            let asm = ast::AsmExpr::cast(parent)?;
+            let source_analyzer = &self.analyze_no_infer(asm.syntax())?;
+            let line = asm.template().position(|it| *it.syntax() == literal)?;
+            let asm = self.wrap_node_infile(asm);
+            source_analyzer.resolve_offset_in_asm_template(asm.as_ref(), line, offset).map(
+                |(owner, (expr, range, index))| {
+                    (range, Some(Either::Right(InlineAsmOperand { owner, expr, index })))
+                },
+            )
+        }
     }
 
     /// Maps a node down by mapping its first and last token down.
@@ -818,16 +905,7 @@
             let InMacroFile { file_id, value: mapped_tokens } = self.with_ctx(|ctx| {
                 Some(
                     ctx.cache
-                        .expansion_info_cache
-                        .entry(macro_file)
-                        .or_insert_with(|| {
-                            let exp_info = macro_file.expansion_info(self.db.upcast());
-
-                            let InMacroFile { file_id, value } = exp_info.expanded();
-                            self.cache(value, file_id.into());
-
-                            exp_info
-                        })
+                        .get_or_insert_expansion(self, macro_file)
                         .map_range_down(span)?
                         .map(SmallVec::<[_; 2]>::from_iter),
                 )
@@ -1113,11 +1191,7 @@
                     let macro_file = file_id.macro_file()?;
 
                     self.with_ctx(|ctx| {
-                        let expansion_info = ctx
-                            .cache
-                            .expansion_info_cache
-                            .entry(macro_file)
-                            .or_insert_with(|| macro_file.expansion_info(self.db.upcast()));
+                        let expansion_info = ctx.cache.get_or_insert_expansion(self, macro_file);
                         expansion_info.arg().map(|node| node?.parent()).transpose()
                     })
                 }
@@ -1333,7 +1407,7 @@
         let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call);
         self.with_ctx(|ctx| {
             ctx.macro_call_to_macro_call(macro_call)
-                .and_then(|call| macro_call_to_macro_id(ctx, call))
+                .and_then(|call| macro_call_to_macro_id(self, ctx, call))
                 .map(Into::into)
         })
         .or_else(|| {
@@ -1375,7 +1449,7 @@
         let item_in_file = self.wrap_node_infile(item.clone());
         let id = self.with_ctx(|ctx| {
             let macro_call_id = ctx.item_to_macro_call(item_in_file.as_ref())?;
-            macro_call_to_macro_id(ctx, macro_call_id)
+            macro_call_to_macro_id(self, ctx, macro_call_id)
         })?;
         Some(Macro { id })
     }
@@ -1384,6 +1458,16 @@
         self.analyze(path.syntax())?.resolve_path(self.db, path)
     }
 
+    pub fn resolve_mod_path(
+        &self,
+        scope: &SyntaxNode,
+        path: &ModPath,
+    ) -> Option<impl Iterator<Item = ItemInNs>> {
+        let analyze = self.analyze(scope)?;
+        let items = analyze.resolver.resolve_module_path_in_items(self.db.upcast(), path);
+        Some(items.iter_items().map(|(item, _)| item.into()))
+    }
+
     fn resolve_variant(&self, record_lit: ast::RecordExpr) -> Option<VariantId> {
         self.analyze(record_lit.syntax())?.resolve_variant(self.db, record_lit)
     }
@@ -1685,6 +1769,7 @@
 }
 
 fn macro_call_to_macro_id(
+    sema: &SemanticsImpl<'_>,
     ctx: &mut SourceToDefCtx<'_, '_>,
     macro_call_id: MacroCallId,
 ) -> Option<MacroId> {
@@ -1700,11 +1785,7 @@
                     it.to_ptr(db).to_node(&db.parse(file_id).syntax_node())
                 }
                 HirFileIdRepr::MacroFile(macro_file) => {
-                    let expansion_info = ctx
-                        .cache
-                        .expansion_info_cache
-                        .entry(macro_file)
-                        .or_insert_with(|| macro_file.expansion_info(ctx.db.upcast()));
+                    let expansion_info = ctx.cache.get_or_insert_expansion(sema, macro_file);
                     it.to_ptr(db).to_node(&expansion_info.expanded().value)
                 }
             };
@@ -1716,11 +1797,7 @@
                     it.to_ptr(db).to_node(&db.parse(file_id).syntax_node())
                 }
                 HirFileIdRepr::MacroFile(macro_file) => {
-                    let expansion_info = ctx
-                        .cache
-                        .expansion_info_cache
-                        .entry(macro_file)
-                        .or_insert_with(|| macro_file.expansion_info(ctx.db.upcast()));
+                    let expansion_info = ctx.cache.get_or_insert_expansion(sema, macro_file);
                     it.to_ptr(db).to_node(&expansion_info.expanded().value)
                 }
             };
@@ -1771,6 +1848,7 @@
     (crate::Label, ast::Label, label_to_def),
     (crate::Adt, ast::Adt, adt_to_def),
     (crate::ExternCrateDecl, ast::ExternCrate, extern_crate_to_def),
+    (crate::InlineAsmOperand, ast::AsmOperandNamed, asm_operand_to_def),
     (MacroCallId, ast::MacroCall, macro_call_to_macro_call),
 ];
 
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index 09df639..c1e4e1d 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -99,7 +99,8 @@
     VariantId,
 };
 use hir_expand::{
-    attrs::AttrId, name::AsName, ExpansionInfo, HirFileId, HirFileIdExt, MacroCallId,
+    attrs::AttrId, name::AsName, ExpansionInfo, HirFileId, HirFileIdExt, InMacroFile, MacroCallId,
+    MacroFileIdExt,
 };
 use rustc_hash::FxHashMap;
 use smallvec::SmallVec;
@@ -110,15 +111,32 @@
     AstNode, AstPtr, SyntaxNode,
 };
 
-use crate::{db::HirDatabase, InFile};
+use crate::{db::HirDatabase, InFile, InlineAsmOperand, SemanticsImpl};
 
 #[derive(Default)]
 pub(super) struct SourceToDefCache {
     pub(super) dynmap_cache: FxHashMap<(ChildContainer, HirFileId), DynMap>,
-    pub(super) expansion_info_cache: FxHashMap<MacroFileId, ExpansionInfo>,
+    expansion_info_cache: FxHashMap<MacroFileId, ExpansionInfo>,
     pub(super) file_to_def_cache: FxHashMap<FileId, SmallVec<[ModuleId; 1]>>,
 }
 
+impl SourceToDefCache {
+    pub(super) fn get_or_insert_expansion(
+        &mut self,
+        sema: &SemanticsImpl<'_>,
+        macro_file: MacroFileId,
+    ) -> &ExpansionInfo {
+        self.expansion_info_cache.entry(macro_file).or_insert_with(|| {
+            let exp_info = macro_file.expansion_info(sema.db.upcast());
+
+            let InMacroFile { file_id, value } = exp_info.expanded();
+            sema.cache(value, file_id.into());
+
+            exp_info
+        })
+    }
+}
+
 pub(super) struct SourceToDefCtx<'db, 'cache> {
     pub(super) db: &'db dyn HirDatabase,
     pub(super) cache: &'cache mut SourceToDefCache,
@@ -273,6 +291,25 @@
             ast::Adt::Union(it) => self.union_to_def(InFile::new(file_id, it)).map(AdtId::UnionId),
         }
     }
+
+    pub(super) fn asm_operand_to_def(
+        &mut self,
+        src: InFile<&ast::AsmOperandNamed>,
+    ) -> Option<InlineAsmOperand> {
+        let asm = src.value.syntax().parent().and_then(ast::AsmExpr::cast)?;
+        let index = asm
+            .asm_pieces()
+            .filter_map(|it| match it {
+                ast::AsmPiece::AsmOperandNamed(it) => Some(it),
+                _ => None,
+            })
+            .position(|it| it == *src.value)?;
+        let container = self.find_pat_or_label_container(src.syntax_ref())?;
+        let (_, source_map) = self.db.body_with_source_map(container);
+        let expr = source_map.node_expr(src.with_value(&ast::Expr::AsmExpr(asm)))?;
+        Some(InlineAsmOperand { owner: container, expr, index })
+    }
+
     pub(super) fn bind_pat_to_def(
         &mut self,
         src: InFile<&ast::IdentPat>,
@@ -281,7 +318,7 @@
         let (body, source_map) = self.db.body_with_source_map(container);
         let src = src.cloned().map(ast::Pat::from);
         let pat_id = source_map.node_pat(src.as_ref())?;
-        // the pattern could resolve to a constant, verify that that is not the case
+        // the pattern could resolve to a constant, verify that this is not the case
         if let crate::Pat::Bind { id, .. } = body[pat_id] {
             Some((container, id))
         } else {
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index be01168..3da67ae 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -904,6 +904,22 @@
         })
     }
 
+    pub(crate) fn resolve_offset_in_asm_template(
+        &self,
+        asm: InFile<&ast::AsmExpr>,
+        line: usize,
+        offset: TextSize,
+    ) -> Option<(DefWithBodyId, (ExprId, TextRange, usize))> {
+        let (def, _, body_source_map) = self.def.as_ref()?;
+        let (expr, args) = body_source_map.asm_template_args(asm)?;
+        Some(*def).zip(
+            args.get(line)?
+                .iter()
+                .find(|(range, _)| range.contains_inclusive(offset))
+                .map(|(range, idx)| (expr, *range, *idx)),
+        )
+    }
+
     pub(crate) fn as_format_args_parts<'a>(
         &'a self,
         db: &'a dyn HirDatabase,
@@ -927,6 +943,14 @@
         ))
     }
 
+    pub(crate) fn as_asm_parts(
+        &self,
+        asm: InFile<&ast::AsmExpr>,
+    ) -> Option<(DefWithBodyId, (ExprId, &[Vec<(TextRange, usize)>]))> {
+        let (def, _, body_source_map) = self.def.as_ref()?;
+        Some(*def).zip(body_source_map.asm_template_args(asm))
+    }
+
     fn resolve_impl_method_or_trait_def(
         &self,
         db: &dyn HirDatabase,
diff --git a/crates/ide-assists/Cargo.toml b/crates/ide-assists/Cargo.toml
index df52562..2a14fbe 100644
--- a/crates/ide-assists/Cargo.toml
+++ b/crates/ide-assists/Cargo.toml
@@ -34,5 +34,8 @@
 test-utils.workspace = true
 test-fixture.workspace = true
 
+[features]
+in-rust-tree = []
+
 [lints]
 workspace = true
diff --git a/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/crates/ide-assists/src/handlers/add_missing_match_arms.rs
index b6abb06..a211ca8 100644
--- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs
+++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs
@@ -1,12 +1,13 @@
 use std::iter::{self, Peekable};
 
 use either::Either;
-use hir::{sym, Adt, Crate, HasAttrs, HasSource, ImportPathConfig, ModuleDef, Semantics};
+use hir::{sym, Adt, Crate, HasAttrs, ImportPathConfig, ModuleDef, Semantics};
+use ide_db::syntax_helpers::suggest_name;
 use ide_db::RootDatabase;
 use ide_db::{famous_defs::FamousDefs, helpers::mod_path_to_ast};
 use itertools::Itertools;
 use syntax::ast::edit_in_place::Removable;
-use syntax::ast::{self, make, AstNode, HasName, MatchArmList, MatchExpr, Pat};
+use syntax::ast::{self, make, AstNode, MatchArmList, MatchExpr, Pat};
 
 use crate::{utils, AssistContext, AssistId, AssistKind, Assists};
 
@@ -90,7 +91,7 @@
             .into_iter()
             .filter_map(|variant| {
                 Some((
-                    build_pat(ctx.db(), module, variant, cfg)?,
+                    build_pat(ctx, module, variant, cfg)?,
                     variant.should_be_hidden(ctx.db(), module.krate()),
                 ))
             })
@@ -141,9 +142,8 @@
                 let is_hidden = variants
                     .iter()
                     .any(|variant| variant.should_be_hidden(ctx.db(), module.krate()));
-                let patterns = variants
-                    .into_iter()
-                    .filter_map(|variant| build_pat(ctx.db(), module, variant, cfg));
+                let patterns =
+                    variants.into_iter().filter_map(|variant| build_pat(ctx, module, variant, cfg));
 
                 (ast::Pat::from(make::tuple_pat(patterns)), is_hidden)
             })
@@ -174,9 +174,8 @@
                 let is_hidden = variants
                     .iter()
                     .any(|variant| variant.should_be_hidden(ctx.db(), module.krate()));
-                let patterns = variants
-                    .into_iter()
-                    .filter_map(|variant| build_pat(ctx.db(), module, variant, cfg));
+                let patterns =
+                    variants.into_iter().filter_map(|variant| build_pat(ctx, module, variant, cfg));
                 (ast::Pat::from(make::slice_pat(patterns)), is_hidden)
             })
             .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat));
@@ -438,33 +437,39 @@
 }
 
 fn build_pat(
-    db: &RootDatabase,
+    ctx: &AssistContext<'_>,
     module: hir::Module,
     var: ExtendedVariant,
     cfg: ImportPathConfig,
 ) -> Option<ast::Pat> {
+    let db = ctx.db();
     match var {
         ExtendedVariant::Variant(var) => {
             let edition = module.krate().edition(db);
             let path = mod_path_to_ast(&module.find_path(db, ModuleDef::from(var), cfg)?, edition);
-            // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though
-            Some(match var.source(db)?.value.kind() {
-                ast::StructKind::Tuple(field_list) => {
-                    let pats =
-                        iter::repeat(make::wildcard_pat().into()).take(field_list.fields().count());
+            let fields = var.fields(db);
+            let pat = match var.kind(db) {
+                hir::StructKind::Tuple => {
+                    let mut name_generator = suggest_name::NameGenerator::new();
+                    let pats = fields.into_iter().map(|f| {
+                        let name = name_generator.for_type(&f.ty(db), db, edition);
+                        match name {
+                            Some(name) => make::ext::simple_ident_pat(make::name(&name)).into(),
+                            None => make::wildcard_pat().into(),
+                        }
+                    });
                     make::tuple_struct_pat(path, pats).into()
                 }
-                ast::StructKind::Record(field_list) => {
-                    let pats = field_list.fields().map(|f| {
-                        make::ext::simple_ident_pat(
-                            f.name().expect("Record field must have a name"),
-                        )
-                        .into()
-                    });
+                hir::StructKind::Record => {
+                    let pats = fields
+                        .into_iter()
+                        .map(|f| make::name(f.name(db).as_str()))
+                        .map(|name| make::ext::simple_ident_pat(name).into());
                     make::record_pat(path, pats).into()
                 }
-                ast::StructKind::Unit => make::path_pat(path),
-            })
+                hir::StructKind::Unit => make::path_pat(path),
+            };
+            Some(pat)
         }
         ExtendedVariant::True => Some(ast::Pat::from(make::literal_pat("true"))),
         ExtendedVariant::False => Some(ast::Pat::from(make::literal_pat("false"))),
@@ -1976,4 +1981,81 @@
 }"#,
         )
     }
+
+    #[test]
+    fn suggest_name_for_tuple_struct_patterns() {
+        // single tuple struct
+        check_assist(
+            add_missing_match_arms,
+            r#"
+struct S;
+
+pub enum E {
+    A
+    B(S),
+}
+
+fn f() {
+    let value = E::A;
+    match value {
+        $0
+    }
+}
+"#,
+            r#"
+struct S;
+
+pub enum E {
+    A
+    B(S),
+}
+
+fn f() {
+    let value = E::A;
+    match value {
+        $0E::A => todo!(),
+        E::B(s) => todo!(),
+    }
+}
+"#,
+        );
+
+        // multiple tuple struct patterns
+        check_assist(
+            add_missing_match_arms,
+            r#"
+struct S1;
+struct S2;
+
+pub enum E {
+    A
+    B(S1, S2),
+}
+
+fn f() {
+    let value = E::A;
+    match value {
+        $0
+    }
+}
+"#,
+            r#"
+struct S1;
+struct S2;
+
+pub enum E {
+    A
+    B(S1, S2),
+}
+
+fn f() {
+    let value = E::A;
+    match value {
+        $0E::A => todo!(),
+        E::B(s1, s2) => todo!(),
+    }
+}
+"#,
+        );
+    }
 }
diff --git a/crates/ide-assists/src/handlers/explicit_enum_discriminant.rs b/crates/ide-assists/src/handlers/explicit_enum_discriminant.rs
new file mode 100644
index 0000000..fafc344
--- /dev/null
+++ b/crates/ide-assists/src/handlers/explicit_enum_discriminant.rs
@@ -0,0 +1,206 @@
+use hir::Semantics;
+use ide_db::{
+    assists::{AssistId, AssistKind},
+    source_change::SourceChangeBuilder,
+    RootDatabase,
+};
+use syntax::{ast, AstNode};
+
+use crate::{AssistContext, Assists};
+
+// Assist: explicit_enum_discriminant
+//
+// Adds explicit discriminant to all enum variants.
+//
+// ```
+// enum TheEnum$0 {
+//     Foo,
+//     Bar,
+//     Baz = 42,
+//     Quux,
+// }
+// ```
+// ->
+// ```
+// enum TheEnum {
+//     Foo = 0,
+//     Bar = 1,
+//     Baz = 42,
+//     Quux = 43,
+// }
+// ```
+pub(crate) fn explicit_enum_discriminant(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    let enum_node = ctx.find_node_at_offset::<ast::Enum>()?;
+    let enum_def = ctx.sema.to_def(&enum_node)?;
+
+    let is_data_carrying = enum_def.is_data_carrying(ctx.db());
+    let has_primitive_repr = enum_def.repr(ctx.db()).and_then(|repr| repr.int).is_some();
+
+    // Data carrying enums without a primitive repr have no stable discriminants.
+    if is_data_carrying && !has_primitive_repr {
+        return None;
+    }
+
+    let variant_list = enum_node.variant_list()?;
+
+    // Don't offer the assist if the enum has no variants or if all variants already have an
+    // explicit discriminant.
+    if variant_list.variants().all(|variant_node| variant_node.expr().is_some()) {
+        return None;
+    }
+
+    acc.add(
+        AssistId("explicit_enum_discriminant", AssistKind::RefactorRewrite),
+        "Add explicit enum discriminants",
+        enum_node.syntax().text_range(),
+        |builder| {
+            for variant_node in variant_list.variants() {
+                add_variant_discriminant(&ctx.sema, builder, &variant_node);
+            }
+        },
+    );
+
+    Some(())
+}
+
+fn add_variant_discriminant(
+    sema: &Semantics<'_, RootDatabase>,
+    builder: &mut SourceChangeBuilder,
+    variant_node: &ast::Variant,
+) {
+    if variant_node.expr().is_some() {
+        return;
+    }
+
+    let Some(variant_def) = sema.to_def(variant_node) else {
+        return;
+    };
+    let Ok(discriminant) = variant_def.eval(sema.db) else {
+        return;
+    };
+
+    let variant_range = variant_node.syntax().text_range();
+
+    builder.insert(variant_range.end(), format!(" = {discriminant}"));
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tests::{check_assist, check_assist_not_applicable};
+
+    use super::explicit_enum_discriminant;
+
+    #[test]
+    fn non_primitive_repr_non_data_bearing_add_discriminant() {
+        check_assist(
+            explicit_enum_discriminant,
+            r#"
+enum TheEnum$0 {
+    Foo,
+    Bar,
+    Baz = 42,
+    Quux,
+    FooBar = -5,
+    FooBaz,
+}
+"#,
+            r#"
+enum TheEnum {
+    Foo = 0,
+    Bar = 1,
+    Baz = 42,
+    Quux = 43,
+    FooBar = -5,
+    FooBaz = -4,
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn primitive_repr_data_bearing_add_discriminant() {
+        check_assist(
+            explicit_enum_discriminant,
+            r#"
+#[repr(u8)]
+$0enum TheEnum {
+    Foo { x: u32 },
+    Bar,
+    Baz(String),
+    Quux,
+}
+"#,
+            r#"
+#[repr(u8)]
+enum TheEnum {
+    Foo { x: u32 } = 0,
+    Bar = 1,
+    Baz(String) = 2,
+    Quux = 3,
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn non_primitive_repr_data_bearing_not_applicable() {
+        check_assist_not_applicable(
+            explicit_enum_discriminant,
+            r#"
+enum TheEnum$0 {
+    Foo,
+    Bar(u16),
+    Baz,
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn primitive_repr_non_data_bearing_add_discriminant() {
+        check_assist(
+            explicit_enum_discriminant,
+            r#"
+#[repr(i64)]
+enum TheEnum {
+    Foo = 1 << 63,
+    Bar,
+    Baz$0 = 0x7fff_ffff_ffff_fffe,
+    Quux,
+}
+"#,
+            r#"
+#[repr(i64)]
+enum TheEnum {
+    Foo = 1 << 63,
+    Bar = -9223372036854775807,
+    Baz = 0x7fff_ffff_ffff_fffe,
+    Quux = 9223372036854775807,
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn discriminants_already_explicit_not_applicable() {
+        check_assist_not_applicable(
+            explicit_enum_discriminant,
+            r#"
+enum TheEnum$0 {
+    Foo = 0,
+    Bar = 4,
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn empty_enum_not_applicable() {
+        check_assist_not_applicable(
+            explicit_enum_discriminant,
+            r#"
+enum TheEnum$0 {}
+"#,
+        );
+    }
+}
diff --git a/crates/ide-assists/src/handlers/extract_type_alias.rs b/crates/ide-assists/src/handlers/extract_type_alias.rs
index dcf16e8..1eaf316 100644
--- a/crates/ide-assists/src/handlers/extract_type_alias.rs
+++ b/crates/ide-assists/src/handlers/extract_type_alias.rs
@@ -2,7 +2,7 @@
 use ide_db::syntax_helpers::node_ext::walk_ty;
 use syntax::{
     ast::{self, edit::IndentLevel, make, AstNode, HasGenericArgs, HasGenericParams, HasName},
-    ted,
+    syntax_editor,
 };
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -43,9 +43,8 @@
         AssistId("extract_type_alias", AssistKind::RefactorExtract),
         "Extract type as type alias",
         target,
-        |edit| {
-            let node = edit.make_syntax_mut(node.clone());
-            let target_ty = edit.make_mut(ty.clone());
+        |builder| {
+            let mut edit = builder.make_editor(node);
 
             let mut known_generics = match item.generic_param_list() {
                 Some(it) => it.generic_params().collect(),
@@ -67,25 +66,28 @@
                 .map_or(String::new(), |it| it.to_generic_args().to_string());
             // FIXME: replace with a `ast::make` constructor
             let new_ty = make::ty(&format!("Type{ty_args}")).clone_for_update();
-            ted::replace(target_ty.syntax(), new_ty.syntax());
+            edit.replace(ty.syntax(), new_ty.syntax());
 
             // Insert new alias
-            let indent = IndentLevel::from_node(&node);
             let ty_alias = make::ty_alias("Type", generic_params, None, None, Some((ty, None)))
                 .clone_for_update();
-            ted::insert_all(
-                ted::Position::before(node),
+
+            if let Some(cap) = ctx.config.snippet_cap {
+                if let Some(name) = ty_alias.name() {
+                    edit.add_annotation(name.syntax(), builder.make_tabstop_before(cap));
+                }
+            }
+
+            let indent = IndentLevel::from_node(node);
+            edit.insert_all(
+                syntax_editor::Position::before(node),
                 vec![
                     ty_alias.syntax().clone().into(),
                     make::tokens::whitespace(&format!("\n\n{indent}")).into(),
                 ],
             );
 
-            if let Some(cap) = ctx.config.snippet_cap {
-                if let Some(name) = ty_alias.name() {
-                    edit.add_tabstop_before(cap, name);
-                }
-            }
+            builder.add_file_edits(ctx.file_id(), edit);
         },
     )
 }
diff --git a/crates/ide-assists/src/handlers/extract_variable.rs b/crates/ide-assists/src/handlers/extract_variable.rs
index 5ae75bb..a43a4b5 100644
--- a/crates/ide-assists/src/handlers/extract_variable.rs
+++ b/crates/ide-assists/src/handlers/extract_variable.rs
@@ -1,4 +1,5 @@
 use hir::TypeInfo;
+use ide_db::syntax_helpers::suggest_name;
 use syntax::{
     ast::{self, edit::IndentLevel, edit_in_place::Indent, make, AstNode, HasName},
     ted, NodeOrToken,
@@ -6,7 +7,7 @@
     SyntaxNode, T,
 };
 
-use crate::{utils::suggest_name, AssistContext, AssistId, AssistKind, Assists};
+use crate::{AssistContext, AssistId, AssistKind, Assists};
 
 // Assist: extract_variable
 //
diff --git a/crates/ide-assists/src/handlers/flip_comma.rs b/crates/ide-assists/src/handlers/flip_comma.rs
index f40f271..af2c2c7 100644
--- a/crates/ide-assists/src/handlers/flip_comma.rs
+++ b/crates/ide-assists/src/handlers/flip_comma.rs
@@ -1,4 +1,8 @@
-use syntax::{algo::non_trivia_sibling, Direction, SyntaxKind, T};
+use ide_db::base_db::SourceDatabase;
+use syntax::TextSize;
+use syntax::{
+    algo::non_trivia_sibling, ast, AstNode, Direction, SyntaxKind, SyntaxToken, TextRange, T,
+};
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
 
@@ -21,6 +25,8 @@
     let comma = ctx.find_token_syntax_at_offset(T![,])?;
     let prev = non_trivia_sibling(comma.clone().into(), Direction::Prev)?;
     let next = non_trivia_sibling(comma.clone().into(), Direction::Next)?;
+    let (mut prev_text, mut next_text) = (prev.to_string(), next.to_string());
+    let (mut prev_range, mut next_range) = (prev.text_range(), next.text_range());
 
     // Don't apply a "flip" in case of a last comma
     // that typically comes before punctuation
@@ -34,17 +40,55 @@
         return None;
     }
 
+    if let Some(parent) = comma.parent().and_then(ast::TokenTree::cast) {
+        // An attribute. It often contains a path followed by a token tree (e.g. `align(2)`), so we have
+        // to be smarter.
+        let prev_start =
+            match comma.siblings_with_tokens(Direction::Prev).skip(1).find(|it| it.kind() == T![,])
+            {
+                Some(it) => position_after_token(it.as_token().unwrap()),
+                None => position_after_token(&parent.left_delimiter_token()?),
+            };
+        let prev_end = prev.text_range().end();
+        let next_start = next.text_range().start();
+        let next_end =
+            match comma.siblings_with_tokens(Direction::Next).skip(1).find(|it| it.kind() == T![,])
+            {
+                Some(it) => position_before_token(it.as_token().unwrap()),
+                None => position_before_token(&parent.right_delimiter_token()?),
+            };
+        prev_range = TextRange::new(prev_start, prev_end);
+        next_range = TextRange::new(next_start, next_end);
+        let file_text = ctx.db().file_text(ctx.file_id().file_id());
+        prev_text = file_text[prev_range].to_owned();
+        next_text = file_text[next_range].to_owned();
+    }
+
     acc.add(
         AssistId("flip_comma", AssistKind::RefactorRewrite),
         "Flip comma",
         comma.text_range(),
         |edit| {
-            edit.replace(prev.text_range(), next.to_string());
-            edit.replace(next.text_range(), prev.to_string());
+            edit.replace(prev_range, next_text);
+            edit.replace(next_range, prev_text);
         },
     )
 }
 
+fn position_before_token(token: &SyntaxToken) -> TextSize {
+    match non_trivia_sibling(token.clone().into(), Direction::Prev) {
+        Some(prev_token) => prev_token.text_range().end(),
+        None => token.text_range().start(),
+    }
+}
+
+fn position_after_token(token: &SyntaxToken) -> TextSize {
+    match non_trivia_sibling(token.clone().into(), Direction::Next) {
+        Some(prev_token) => prev_token.text_range().start(),
+        None => token.text_range().end(),
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
@@ -89,4 +133,18 @@
         // See https://github.com/rust-lang/rust-analyzer/issues/7693
         check_assist_not_applicable(flip_comma, r#"bar!(a,$0 b)"#);
     }
+
+    #[test]
+    fn flip_comma_attribute() {
+        check_assist(
+            flip_comma,
+            r#"#[repr(align(2),$0 C)] struct Foo;"#,
+            r#"#[repr(C, align(2))] struct Foo;"#,
+        );
+        check_assist(
+            flip_comma,
+            r#"#[foo(bar, baz(1 + 1),$0 qux, other)] struct Foo;"#,
+            r#"#[foo(bar, qux, baz(1 + 1), other)] struct Foo;"#,
+        );
+    }
 }
diff --git a/crates/ide-assists/src/handlers/generate_delegate_trait.rs b/crates/ide-assists/src/handlers/generate_delegate_trait.rs
index bf4ce5c..66bf9b0 100644
--- a/crates/ide-assists/src/handlers/generate_delegate_trait.rs
+++ b/crates/ide-assists/src/handlers/generate_delegate_trait.rs
@@ -2,13 +2,14 @@
 
 use crate::{
     assist_context::{AssistContext, Assists},
-    utils::{convert_param_list_to_arg_list, suggest_name},
+    utils::convert_param_list_to_arg_list,
 };
 use either::Either;
 use hir::{db::HirDatabase, HasVisibility};
 use ide_db::{
     assists::{AssistId, GroupLabel},
     path_transform::PathTransform,
+    syntax_helpers::suggest_name,
     FxHashMap, FxHashSet,
 };
 use itertools::Itertools;
@@ -281,8 +282,11 @@
                 ai.assoc_items()
                     .filter(|item| matches!(item, AssocItem::MacroCall(_)).not())
                     .for_each(|item| {
-                        let assoc =
-                            process_assoc_item(item, qualified_path_type.clone(), field_name);
+                        let assoc = process_assoc_item(
+                            item.clone_for_update(),
+                            qualified_path_type.clone(),
+                            field_name,
+                        );
                         if let Some(assoc) = assoc {
                             delegate_assoc_items.add_item(assoc);
                         }
@@ -583,7 +587,7 @@
 
             for old_strukt_param in old_strukt_params.generic_params() {
                 // Get old name from `strukt`
-                let mut name = SmolStr::from(match &old_strukt_param {
+                let name = SmolStr::from(match &old_strukt_param {
                     ast::GenericParam::ConstParam(c) => c.name()?.to_string(),
                     ast::GenericParam::LifetimeParam(l) => {
                         l.lifetime()?.lifetime_ident_token()?.to_string()
@@ -592,8 +596,19 @@
                 });
 
                 // The new name cannot be conflicted with generics in trait, and the renamed names.
-                name = suggest_name::for_unique_generic_name(&name, old_impl_params);
-                name = suggest_name::for_unique_generic_name(&name, &params);
+                let param_list_to_names = |param_list: &GenericParamList| {
+                    param_list.generic_params().flat_map(|param| match param {
+                        ast::GenericParam::TypeParam(t) => t.name().map(|name| name.to_string()),
+                        p => Some(p.to_string()),
+                    })
+                };
+                let existing_names = param_list_to_names(old_impl_params)
+                    .chain(param_list_to_names(&params))
+                    .collect_vec();
+                let mut name_generator = suggest_name::NameGenerator::new_with_names(
+                    existing_names.iter().map(|s| s.as_str()),
+                );
+                let name = name_generator.suggest_name(&name);
                 match old_strukt_param {
                     ast::GenericParam::ConstParam(c) => {
                         if let Some(const_ty) = c.ty() {
@@ -1212,9 +1227,9 @@
     b : B<T>,
 }
 
-impl<T0> Trait<T0> for S<T0> {
-    fn f(&self, a: T0) -> T0 {
-        <B<T0> as Trait<T0>>::f(&self.b, a)
+impl<T1> Trait<T1> for S<T1> {
+    fn f(&self, a: T1) -> T1 {
+        <B<T1> as Trait<T1>>::f(&self.b, a)
     }
 }
 "#,
@@ -1526,12 +1541,12 @@
     b : B<T, T1>,
 }
 
-impl<T, T2, T10> Trait<T> for S<T2, T10>
+impl<T, T2, T3> Trait<T> for S<T2, T3>
 where
-    T10: AnotherTrait
+    T3: AnotherTrait
 {
     fn f(&self, a: T) -> T {
-        <B<T2, T10> as Trait<T>>::f(&self.b, a)
+        <B<T2, T3> as Trait<T>>::f(&self.b, a)
     }
 }"#,
         );
@@ -1588,12 +1603,12 @@
     b : B<T>,
 }
 
-impl<T, T0> Trait<T> for S<T0>
+impl<T, T2> Trait<T> for S<T2>
 where
-    T0: AnotherTrait
+    T2: AnotherTrait
 {
     fn f(&self, a: T) -> T {
-        <B<T0> as Trait<T>>::f(&self.b, a)
+        <B<T2> as Trait<T>>::f(&self.b, a)
     }
 }"#,
         );
@@ -1785,4 +1800,40 @@
 "#,
         );
     }
+
+    #[test]
+    fn assoc_items_attributes_mutably_cloned() {
+        check_assist(
+            generate_delegate_trait,
+            r#"
+pub struct A;
+pub trait C<D> {
+    #[allow(clippy::dead_code)]
+    fn a_funk(&self) -> &D;
+}
+
+pub struct B<T: C<A>> {
+    has_dr$0ain: T,
+}
+"#,
+            r#"
+pub struct A;
+pub trait C<D> {
+    #[allow(clippy::dead_code)]
+    fn a_funk(&self) -> &D;
+}
+
+pub struct B<T: C<A>> {
+    has_drain: T,
+}
+
+impl<D, T: C<A>> C<D> for B<T> {
+    #[allow(clippy::dead_code)]
+    fn a_funk(&self) -> &D {
+        <T as C<D>>::a_funk(&self.has_drain)
+    }
+}
+"#,
+        )
+    }
 }
diff --git a/crates/ide-assists/src/handlers/generate_impl.rs b/crates/ide-assists/src/handlers/generate_impl.rs
index 821783c..7b7dac9 100644
--- a/crates/ide-assists/src/handlers/generate_impl.rs
+++ b/crates/ide-assists/src/handlers/generate_impl.rs
@@ -1,10 +1,22 @@
 use syntax::{
-    ast::{self, make, AstNode, HasName},
+    ast::{self, edit_in_place::Indent, make, AstNode, HasName},
     ted,
 };
 
 use crate::{utils, AssistContext, AssistId, AssistKind, Assists};
 
+fn insert_impl(impl_: ast::Impl, nominal: &ast::Adt) {
+    let indent = nominal.indent_level();
+    ted::insert_all_raw(
+        ted::Position::after(nominal.syntax()),
+        vec![
+            // Add a blank line after the ADT, and indentation for the impl to match the ADT
+            make::tokens::whitespace(&format!("\n\n{indent}")).into(),
+            impl_.syntax().clone().into(),
+        ],
+    );
+}
+
 // Assist: generate_impl
 //
 // Adds a new inherent impl for a type.
@@ -46,12 +58,7 @@
                 }
             }
 
-            // Add the impl after the adt
-            let nominal = edit.make_mut(nominal);
-            ted::insert_all_raw(
-                ted::Position::after(nominal.syntax()),
-                vec![make::tokens::blank_line().into(), impl_.syntax().clone().into()],
-            );
+            insert_impl(impl_, &edit.make_mut(nominal));
         },
     )
 }
@@ -97,12 +104,7 @@
                 }
             }
 
-            // Add the impl after the adt
-            let nominal = edit.make_mut(nominal);
-            ted::insert_all_raw(
-                ted::Position::after(nominal.syntax()),
-                vec![make::tokens::blank_line().into(), impl_.syntax().clone().into()],
-            );
+            insert_impl(impl_, &edit.make_mut(nominal));
         },
     )
 }
@@ -418,4 +420,65 @@
             "/// Has a lifetime parameter\nstruct Foo<'a, T: Foo<'a>> {}",
         );
     }
+
+    #[test]
+    fn add_impl_with_indent() {
+        check_assist(
+            generate_impl,
+            r#"
+                mod foo {
+                    struct Bar$0 {}
+                }
+            "#,
+            r#"
+                mod foo {
+                    struct Bar {}
+
+                    impl Bar {$0}
+                }
+            "#,
+        );
+    }
+
+    #[test]
+    fn add_impl_with_multiple_indent() {
+        check_assist(
+            generate_impl,
+            r#"
+                mod foo {
+                    fn bar() {
+                        struct Baz$0 {}
+                    }
+                }
+            "#,
+            r#"
+                mod foo {
+                    fn bar() {
+                        struct Baz {}
+
+                        impl Baz {$0}
+                    }
+                }
+            "#,
+        );
+    }
+
+    #[test]
+    fn add_trait_impl_with_indent() {
+        check_assist(
+            generate_trait_impl,
+            r#"
+                mod foo {
+                    struct Bar$0 {}
+                }
+            "#,
+            r#"
+                mod foo {
+                    struct Bar {}
+
+                    impl ${0:_} for Bar {}
+                }
+            "#,
+        );
+    }
 }
diff --git a/crates/ide-assists/src/handlers/inline_call.rs b/crates/ide-assists/src/handlers/inline_call.rs
index 5bd204d..9e09f19 100644
--- a/crates/ide-assists/src/handlers/inline_call.rs
+++ b/crates/ide-assists/src/handlers/inline_call.rs
@@ -2,14 +2,18 @@
 
 use ast::make;
 use either::Either;
-use hir::{db::HirDatabase, sym, FileRange, PathResolution, Semantics, TypeInfo};
+use hir::{
+    db::{ExpandDatabase, HirDatabase},
+    sym, FileRange, PathResolution, Semantics, TypeInfo,
+};
 use ide_db::{
+    base_db::CrateId,
     defs::Definition,
     imports::insert_use::remove_path_if_in_use_stmt,
     path_transform::PathTransform,
     search::{FileReference, FileReferenceNode, SearchScope},
     source_change::SourceChangeBuilder,
-    syntax_helpers::{insert_whitespace_into_node::insert_ws_into, node_ext::expr_as_name_ref},
+    syntax_helpers::{node_ext::expr_as_name_ref, prettify_macro_expansion},
     EditionedFileId, RootDatabase,
 };
 use itertools::{izip, Itertools};
@@ -102,12 +106,13 @@
             let mut remove_def = true;
             let mut inline_refs_for_file = |file_id, refs: Vec<FileReference>| {
                 builder.edit_file(file_id);
+                let call_krate = ctx.sema.file_to_module_def(file_id).map(|it| it.krate());
                 let count = refs.len();
                 // The collects are required as we are otherwise iterating while mutating 🙅‍♀️🙅‍♂️
                 let (name_refs, name_refs_use) = split_refs_and_uses(builder, refs, Some);
                 let call_infos: Vec<_> = name_refs
                     .into_iter()
-                    .filter_map(CallInfo::from_name_ref)
+                    .filter_map(|it| CallInfo::from_name_ref(it, call_krate?.into()))
                     // FIXME: do not handle callsites in macros' parameters, because
                     // directly inlining into macros may cause errors.
                     .filter(|call_info| !ctx.sema.hir_file_for(call_info.node.syntax()).is_macro())
@@ -185,7 +190,10 @@
 // ```
 pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     let name_ref: ast::NameRef = ctx.find_node_at_offset()?;
-    let call_info = CallInfo::from_name_ref(name_ref.clone())?;
+    let call_info = CallInfo::from_name_ref(
+        name_ref.clone(),
+        ctx.sema.file_to_module_def(ctx.file_id())?.krate().into(),
+    )?;
     let (function, label) = match &call_info.node {
         ast::CallableExpr::Call(call) => {
             let path = match call.expr()? {
@@ -243,10 +251,11 @@
     node: ast::CallableExpr,
     arguments: Vec<ast::Expr>,
     generic_arg_list: Option<ast::GenericArgList>,
+    krate: CrateId,
 }
 
 impl CallInfo {
-    fn from_name_ref(name_ref: ast::NameRef) -> Option<CallInfo> {
+    fn from_name_ref(name_ref: ast::NameRef, krate: CrateId) -> Option<CallInfo> {
         let parent = name_ref.syntax().parent()?;
         if let Some(call) = ast::MethodCallExpr::cast(parent.clone()) {
             let receiver = call.receiver()?;
@@ -256,6 +265,7 @@
                 generic_arg_list: call.generic_arg_list(),
                 node: ast::CallableExpr::MethodCall(call),
                 arguments,
+                krate,
             })
         } else if let Some(segment) = ast::PathSegment::cast(parent) {
             let path = segment.syntax().parent().and_then(ast::Path::cast)?;
@@ -266,6 +276,7 @@
                 arguments: call.arg_list()?.args().collect(),
                 node: ast::CallableExpr::Call(call),
                 generic_arg_list: segment.generic_arg_list(),
+                krate,
             })
         } else {
             None
@@ -307,11 +318,15 @@
     function: hir::Function,
     fn_body: &ast::BlockExpr,
     params: &[(ast::Pat, Option<ast::Type>, hir::Param)],
-    CallInfo { node, arguments, generic_arg_list }: &CallInfo,
+    CallInfo { node, arguments, generic_arg_list, krate }: &CallInfo,
 ) -> ast::Expr {
-    let mut body = if sema.hir_file_for(fn_body.syntax()).is_macro() {
+    let file_id = sema.hir_file_for(fn_body.syntax());
+    let mut body = if let Some(macro_file) = file_id.macro_file() {
         cov_mark::hit!(inline_call_defined_in_macro);
-        if let Some(body) = ast::BlockExpr::cast(insert_ws_into(fn_body.syntax().clone())) {
+        let span_map = sema.db.expansion_span_map(macro_file);
+        let body_prettified =
+            prettify_macro_expansion(sema.db, fn_body.syntax().clone(), &span_map, *krate);
+        if let Some(body) = ast::BlockExpr::cast(body_prettified) {
             body
         } else {
             fn_body.clone_for_update()
@@ -420,8 +435,16 @@
 
         let mut insert_let_stmt = || {
             let param_ty = param_ty.clone().map(|param_ty| {
-                if sema.hir_file_for(param_ty.syntax()).is_macro() {
-                    ast::Type::cast(insert_ws_into(param_ty.syntax().clone())).unwrap_or(param_ty)
+                let file_id = sema.hir_file_for(param_ty.syntax());
+                if let Some(macro_file) = file_id.macro_file() {
+                    let span_map = sema.db.expansion_span_map(macro_file);
+                    let param_ty_prettified = prettify_macro_expansion(
+                        sema.db,
+                        param_ty.syntax().clone(),
+                        &span_map,
+                        *krate,
+                    );
+                    ast::Type::cast(param_ty_prettified).unwrap_or(param_ty)
                 } else {
                     param_ty
                 }
@@ -1020,6 +1043,7 @@
         check_assist(
             inline_call,
             r#"
+//- minicore: sized
 fn foo(x: *const u32) -> u32 {
     x as u32
 }
diff --git a/crates/ide-assists/src/handlers/inline_const_as_literal.rs b/crates/ide-assists/src/handlers/inline_const_as_literal.rs
index f1c2acd..6b504a9 100644
--- a/crates/ide-assists/src/handlers/inline_const_as_literal.rs
+++ b/crates/ide-assists/src/handlers/inline_const_as_literal.rs
@@ -53,10 +53,7 @@
             | ast::Expr::BinExpr(_)
             | ast::Expr::CallExpr(_) => {
                 let edition = ctx.sema.scope(variable.syntax())?.krate().edition(ctx.db());
-                match konst.render_eval(ctx.sema.db, edition) {
-                    Ok(result) => result,
-                    Err(_) => return None,
-                }
+                konst.eval(ctx.sema.db, edition).ok()?
             }
             _ => return None,
         };
@@ -127,12 +124,14 @@
         ("u64", "0", NUMBER),
         ("u128", "0", NUMBER),
         ("usize", "0", NUMBER),
+        ("usize", "16", NUMBER),
         ("i8", "0", NUMBER),
         ("i16", "0", NUMBER),
         ("i32", "0", NUMBER),
         ("i64", "0", NUMBER),
         ("i128", "0", NUMBER),
         ("isize", "0", NUMBER),
+        ("isize", "16", NUMBER),
         ("bool", "false", BOOL),
         ("&str", "\"str\"", STR),
         ("char", "'c'", CHAR),
diff --git a/crates/ide-assists/src/handlers/inline_local_variable.rs b/crates/ide-assists/src/handlers/inline_local_variable.rs
index 6a1f7f2..b9fc075 100644
--- a/crates/ide-assists/src/handlers/inline_local_variable.rs
+++ b/crates/ide-assists/src/handlers/inline_local_variable.rs
@@ -333,7 +333,8 @@
         check_assist(
             inline_local_variable,
             r"
-fn bar(a: usize): usize { a }
+//- minicore: sized
+fn bar(a: usize) -> usize { a }
 fn foo() {
     let a$0 = bar(1) as u64;
     a + 1;
@@ -347,7 +348,7 @@
     bar(a);
 }",
             r"
-fn bar(a: usize): usize { a }
+fn bar(a: usize) -> usize { a }
 fn foo() {
     (bar(1) as u64) + 1;
     if (bar(1) as u64) > 10 {
diff --git a/crates/ide-assists/src/handlers/inline_macro.rs b/crates/ide-assists/src/handlers/inline_macro.rs
index 4708be6..d558ec3 100644
--- a/crates/ide-assists/src/handlers/inline_macro.rs
+++ b/crates/ide-assists/src/handlers/inline_macro.rs
@@ -1,4 +1,5 @@
-use ide_db::syntax_helpers::insert_whitespace_into_node::insert_ws_into;
+use hir::db::ExpandDatabase;
+use ide_db::syntax_helpers::prettify_macro_expansion;
 use syntax::ast::{self, AstNode};
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -36,7 +37,15 @@
 // ```
 pub(crate) fn inline_macro(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     let unexpanded = ctx.find_node_at_offset::<ast::MacroCall>()?;
-    let expanded = insert_ws_into(ctx.sema.expand(&unexpanded)?.clone_for_update());
+    let macro_call = ctx.sema.to_def(&unexpanded)?;
+    let expanded = ctx.sema.parse_or_expand(macro_call.as_file());
+    let span_map = ctx.sema.db.expansion_span_map(macro_call.as_macro_file());
+    let expanded = prettify_macro_expansion(
+        ctx.db(),
+        expanded,
+        &span_map,
+        ctx.sema.file_to_module_def(ctx.file_id())?.krate().into(),
+    );
     let text_range = unexpanded.syntax().text_range();
 
     acc.add(
@@ -298,4 +307,73 @@
 "#,
         );
     }
+
+    #[test]
+    fn dollar_crate() {
+        check_assist(
+            inline_macro,
+            r#"
+pub struct Foo;
+#[macro_export]
+macro_rules! m {
+    () => { $crate::Foo };
+}
+fn bar() {
+    m$0!();
+}
+"#,
+            r#"
+pub struct Foo;
+#[macro_export]
+macro_rules! m {
+    () => { $crate::Foo };
+}
+fn bar() {
+    crate::Foo;
+}
+"#,
+        );
+        check_assist(
+            inline_macro,
+            r#"
+//- /a.rs crate:a
+pub struct Foo;
+#[macro_export]
+macro_rules! m {
+    () => { $crate::Foo };
+}
+//- /b.rs crate:b deps:a
+fn bar() {
+    a::m$0!();
+}
+"#,
+            r#"
+fn bar() {
+    a::Foo;
+}
+"#,
+        );
+        check_assist(
+            inline_macro,
+            r#"
+//- /a.rs crate:a
+pub struct Foo;
+#[macro_export]
+macro_rules! m {
+    () => { $crate::Foo };
+}
+//- /b.rs crate:b deps:a
+pub use a::m;
+//- /c.rs crate:c deps:b
+fn bar() {
+    b::m$0!();
+}
+"#,
+            r#"
+fn bar() {
+    a::Foo;
+}
+"#,
+        );
+    }
 }
diff --git a/crates/ide-assists/src/handlers/inline_type_alias.rs b/crates/ide-assists/src/handlers/inline_type_alias.rs
index f6624d6..66dffde 100644
--- a/crates/ide-assists/src/handlers/inline_type_alias.rs
+++ b/crates/ide-assists/src/handlers/inline_type_alias.rs
@@ -43,6 +43,7 @@
 // fn foo() {
 //     let _: i32 = 3;
 // }
+// ```
 pub(crate) fn inline_type_alias_uses(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     let name = ctx.find_node_at_offset::<ast::Name>()?;
     let ast_alias = name.syntax().parent().and_then(ast::TypeAlias::cast)?;
diff --git a/crates/ide-assists/src/handlers/introduce_named_generic.rs b/crates/ide-assists/src/handlers/introduce_named_generic.rs
index 543b7f7..bf6ac17 100644
--- a/crates/ide-assists/src/handlers/introduce_named_generic.rs
+++ b/crates/ide-assists/src/handlers/introduce_named_generic.rs
@@ -1,9 +1,11 @@
+use ide_db::syntax_helpers::suggest_name;
+use itertools::Itertools;
 use syntax::{
-    ast::{self, edit_in_place::GenericParamsOwnerEdit, make, AstNode, HasGenericParams},
+    ast::{self, edit_in_place::GenericParamsOwnerEdit, make, AstNode, HasGenericParams, HasName},
     ted,
 };
 
-use crate::{utils::suggest_name, AssistContext, AssistId, AssistKind, Assists};
+use crate::{AssistContext, AssistId, AssistKind, Assists};
 
 // Assist: introduce_named_generic
 //
@@ -32,8 +34,18 @@
             let impl_trait_type = edit.make_mut(impl_trait_type);
             let fn_ = edit.make_mut(fn_);
             let fn_generic_param_list = fn_.get_or_create_generic_param_list();
-            let type_param_name =
-                suggest_name::for_impl_trait_as_generic(&impl_trait_type, &fn_generic_param_list);
+
+            let existing_names = fn_generic_param_list
+                .generic_params()
+                .flat_map(|param| match param {
+                    ast::GenericParam::TypeParam(t) => t.name().map(|name| name.to_string()),
+                    p => Some(p.to_string()),
+                })
+                .collect_vec();
+            let type_param_name = suggest_name::NameGenerator::new_with_names(
+                existing_names.iter().map(|s| s.as_str()),
+            )
+            .for_impl_trait_as_generic(&impl_trait_type);
 
             let type_param = make::type_param(make::name(&type_param_name), Some(type_bound_list))
                 .clone_for_update();
@@ -115,7 +127,7 @@
         check_assist(
             introduce_named_generic,
             r#"fn foo<B>(bar: $0impl Bar) {}"#,
-            r#"fn foo<B, $0B0: Bar>(bar: B0) {}"#,
+            r#"fn foo<B, $0B1: Bar>(bar: B1) {}"#,
         );
     }
 
@@ -124,7 +136,7 @@
         check_assist(
             introduce_named_generic,
             r#"fn foo<B, B0, B1, B3>(bar: $0impl Bar) {}"#,
-            r#"fn foo<B, B0, B1, B3, $0B2: Bar>(bar: B2) {}"#,
+            r#"fn foo<B, B0, B1, B3, $0B4: Bar>(bar: B4) {}"#,
         );
     }
 
diff --git a/crates/ide-assists/src/handlers/remove_unused_imports.rs b/crates/ide-assists/src/handlers/remove_unused_imports.rs
index d4fdc07..c6f99d6 100644
--- a/crates/ide-assists/src/handlers/remove_unused_imports.rs
+++ b/crates/ide-assists/src/handlers/remove_unused_imports.rs
@@ -6,7 +6,10 @@
     search::{FileReference, ReferenceCategory, SearchScope},
     FxHashMap, RootDatabase,
 };
-use syntax::{ast, AstNode};
+use syntax::{
+    ast::{self, Rename},
+    AstNode,
+};
 use text_edit::TextRange;
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -100,19 +103,19 @@
                         hir::ScopeDef::ModuleDef(d) => Some(Definition::from(*d)),
                         _ => None,
                     })
-                    .any(|d| used_once_in_scope(ctx, d, scope))
+                    .any(|d| used_once_in_scope(ctx, d, u.rename(), scope))
                 {
                     return Some(u);
                 }
             } else if let Definition::Trait(ref t) = def {
                 // If the trait or any item is used.
-                if !std::iter::once(def)
-                    .chain(t.items(ctx.db()).into_iter().map(Definition::from))
-                    .any(|d| used_once_in_scope(ctx, d, scope))
+                if !std::iter::once((def, u.rename()))
+                    .chain(t.items(ctx.db()).into_iter().map(|item| (item.into(), None)))
+                    .any(|(d, rename)| used_once_in_scope(ctx, d, rename, scope))
                 {
                     return Some(u);
                 }
-            } else if !used_once_in_scope(ctx, def, scope) {
+            } else if !used_once_in_scope(ctx, def, u.rename(), scope) {
                 return Some(u);
             }
 
@@ -138,7 +141,12 @@
     }
 }
 
-fn used_once_in_scope(ctx: &AssistContext<'_>, def: Definition, scopes: &Vec<SearchScope>) -> bool {
+fn used_once_in_scope(
+    ctx: &AssistContext<'_>,
+    def: Definition,
+    rename: Option<Rename>,
+    scopes: &Vec<SearchScope>,
+) -> bool {
     let mut found = false;
 
     for scope in scopes {
@@ -151,7 +159,10 @@
                 false
             }
         };
-        def.usages(&ctx.sema).in_scope(scope).search(&mut search_non_import);
+        def.usages(&ctx.sema)
+            .in_scope(scope)
+            .with_rename(rename.as_ref())
+            .search(&mut search_non_import);
         if found {
             break;
         }
@@ -330,7 +341,7 @@
     }
 
     #[test]
-    fn ranamed_trait_item_use_is_use() {
+    fn renamed_trait_item_use_is_use() {
         check_assist_not_applicable(
             remove_unused_imports,
             r#"
@@ -356,7 +367,7 @@
     }
 
     #[test]
-    fn ranamed_underscore_trait_item_use_is_use() {
+    fn renamed_underscore_trait_item_use_is_use() {
         check_assist_not_applicable(
             remove_unused_imports,
             r#"
@@ -945,4 +956,60 @@
 "#,
         );
     }
+
+    #[test]
+    fn use_as_alias() {
+        check_assist_not_applicable(
+            remove_unused_imports,
+            r#"
+mod foo {
+    pub struct Foo {}
+}
+
+use foo::Foo as Bar$0;
+
+fn test(_: Bar) {}
+"#,
+        );
+
+        check_assist(
+            remove_unused_imports,
+            r#"
+mod foo {
+    pub struct Foo {}
+    pub struct Bar {}
+    pub struct Qux {}
+    pub trait Quux {
+        fn quxx(&self) {}
+    }
+    impl<T> Quxx for T {}
+}
+
+use foo::{Foo as Bar, Bar as Baz, Qux as _, Quxx as _}$0;
+
+fn test(_: Bar) {
+    let a = ();
+    a.quxx();
+}
+"#,
+            r#"
+mod foo {
+    pub struct Foo {}
+    pub struct Bar {}
+    pub struct Qux {}
+    pub trait Quux {
+        fn quxx(&self) {}
+    }
+    impl<T> Quxx for T {}
+}
+
+use foo::{Foo as Bar, Quxx as _};
+
+fn test(_: Bar) {
+    let a = ();
+    a.quxx();
+}
+"#,
+        );
+    }
 }
diff --git a/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs b/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs
index 59bb0c4..a856da0 100644
--- a/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs
+++ b/crates/ide-assists/src/handlers/replace_is_method_with_if_let_method.rs
@@ -1,9 +1,10 @@
+use ide_db::syntax_helpers::suggest_name;
 use syntax::{
     ast::{self, make, AstNode},
     ted,
 };
 
-use crate::{utils::suggest_name, AssistContext, AssistId, AssistKind, Assists};
+use crate::{AssistContext, AssistId, AssistKind, Assists};
 
 // Assist: replace_is_some_with_if_let_some
 //
diff --git a/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
index 65330b3..1101c20 100644
--- a/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ide-assists/src/handlers/replace_qualified_name_with_use.rs
@@ -29,7 +29,7 @@
     acc: &mut Assists,
     ctx: &AssistContext<'_>,
 ) -> Option<()> {
-    let original_path: ast::Path = ctx.find_node_at_offset()?;
+    let mut original_path: ast::Path = ctx.find_node_at_offset()?;
     // We don't want to mess with use statements
     if original_path.syntax().ancestors().find_map(ast::UseTree::cast).is_some() {
         cov_mark::hit!(not_applicable_in_use);
@@ -37,8 +37,7 @@
     }
 
     if original_path.qualifier().is_none() {
-        cov_mark::hit!(dont_import_trivial_paths);
-        return None;
+        original_path = original_path.parent_path()?;
     }
 
     // only offer replacement for non assoc items
@@ -237,12 +236,6 @@
     }
 
     #[test]
-    fn dont_import_trivial_paths() {
-        cov_mark::check!(dont_import_trivial_paths);
-        check_assist_not_applicable(replace_qualified_name_with_use, r"impl foo$0 for () {}");
-    }
-
-    #[test]
     fn test_replace_not_applicable_in_use() {
         cov_mark::check!(not_applicable_in_use);
         check_assist_not_applicable(replace_qualified_name_with_use, r"use std::fmt$0;");
@@ -272,6 +265,29 @@
     }
 
     #[test]
+    fn assist_runs_on_first_segment() {
+        check_assist(
+            replace_qualified_name_with_use,
+            r"
+mod std { pub mod fmt { pub trait Debug {} } }
+fn main() {
+    $0std::fmt::Debug;
+    let x: std::fmt::Debug = std::fmt::Debug;
+}
+    ",
+            r"
+use std::fmt;
+
+mod std { pub mod fmt { pub trait Debug {} } }
+fn main() {
+    fmt::Debug;
+    let x: fmt::Debug = fmt::Debug;
+}
+    ",
+        );
+    }
+
+    #[test]
     fn does_not_replace_in_submodules() {
         check_assist(
             replace_qualified_name_with_use,
diff --git a/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs b/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs
index eedb2ea..e452b5f 100644
--- a/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs
+++ b/crates/ide-assists/src/handlers/toggle_macro_delimiter.rs
@@ -64,12 +64,9 @@
     acc.add(
         AssistId("toggle_macro_delimiter", AssistKind::Refactor),
         match token {
-            MacroDelims::LPar => "Replace delimiters with braces",
-            MacroDelims::RPar => "Replace delimiters with braces",
-            MacroDelims::LBra => "Replace delimiters with parentheses",
-            MacroDelims::RBra => "Replace delimiters with parentheses",
-            MacroDelims::LCur => "Replace delimiters with brackets",
-            MacroDelims::RCur => "Replace delimiters with brackets",
+            MacroDelims::LPar | MacroDelims::RPar => "Replace delimiters with braces",
+            MacroDelims::LBra | MacroDelims::RBra => "Replace delimiters with parentheses",
+            MacroDelims::LCur | MacroDelims::RCur => "Replace delimiters with brackets",
         },
         token_tree.syntax().text_range(),
         |builder| {
diff --git a/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs b/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
index b68ed00..8f0e9b4 100644
--- a/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
+++ b/crates/ide-assists/src/handlers/wrap_return_type_in_result.rs
@@ -1,12 +1,14 @@
 use std::iter;
 
+use hir::HasSource;
 use ide_db::{
     famous_defs::FamousDefs,
     syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
 };
+use itertools::Itertools;
 use syntax::{
-    ast::{self, make, Expr},
-    match_ast, ted, AstNode,
+    ast::{self, make, Expr, HasGenericParams},
+    match_ast, ted, AstNode, ToSmolStr,
 };
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -39,25 +41,22 @@
     };
 
     let type_ref = &ret_type.ty()?;
-    let ty = ctx.sema.resolve_type(type_ref)?.as_adt();
-    let result_enum =
+    let core_result =
         FamousDefs(&ctx.sema, ctx.sema.scope(type_ref.syntax())?.krate()).core_result_Result()?;
 
-    if matches!(ty, Some(hir::Adt::Enum(ret_type)) if ret_type == result_enum) {
+    let ty = ctx.sema.resolve_type(type_ref)?.as_adt();
+    if matches!(ty, Some(hir::Adt::Enum(ret_type)) if ret_type == core_result) {
+        // The return type is already wrapped in a Result
         cov_mark::hit!(wrap_return_type_in_result_simple_return_type_already_result);
         return None;
     }
 
-    let new_result_ty =
-        make::ext::ty_result(type_ref.clone(), make::ty_placeholder()).clone_for_update();
-    let generic_args = new_result_ty.syntax().descendants().find_map(ast::GenericArgList::cast)?;
-    let last_genarg = generic_args.generic_args().last()?;
-
     acc.add(
         AssistId("wrap_return_type_in_result", AssistKind::RefactorRewrite),
         "Wrap return type in Result",
         type_ref.syntax().text_range(),
         |edit| {
+            let new_result_ty = result_type(ctx, &core_result, type_ref).clone_for_update();
             let body = edit.make_mut(ast::Expr::BlockExpr(body));
 
             let mut exprs_to_wrap = Vec::new();
@@ -81,16 +80,72 @@
             }
 
             let old_result_ty = edit.make_mut(type_ref.clone());
-
             ted::replace(old_result_ty.syntax(), new_result_ty.syntax());
 
-            if let Some(cap) = ctx.config.snippet_cap {
-                edit.add_placeholder_snippet(cap, last_genarg);
+            // Add a placeholder snippet at the first generic argument that doesn't equal the return type.
+            // This is normally the error type, but that may not be the case when we inserted a type alias.
+            let args = new_result_ty.syntax().descendants().find_map(ast::GenericArgList::cast);
+            let error_type_arg = args.and_then(|list| {
+                list.generic_args().find(|arg| match arg {
+                    ast::GenericArg::TypeArg(_) => arg.syntax().text() != type_ref.syntax().text(),
+                    ast::GenericArg::LifetimeArg(_) => false,
+                    _ => true,
+                })
+            });
+            if let Some(error_type_arg) = error_type_arg {
+                if let Some(cap) = ctx.config.snippet_cap {
+                    edit.add_placeholder_snippet(cap, error_type_arg);
+                }
             }
         },
     )
 }
 
+fn result_type(
+    ctx: &AssistContext<'_>,
+    core_result: &hir::Enum,
+    ret_type: &ast::Type,
+) -> ast::Type {
+    // Try to find a Result<T, ...> type alias in the current scope (shadowing the default).
+    let result_path = hir::ModPath::from_segments(
+        hir::PathKind::Plain,
+        iter::once(hir::Name::new_symbol_root(hir::sym::Result.clone())),
+    );
+    let alias = ctx.sema.resolve_mod_path(ret_type.syntax(), &result_path).and_then(|def| {
+        def.filter_map(|def| match def.as_module_def()? {
+            hir::ModuleDef::TypeAlias(alias) => {
+                let enum_ty = alias.ty(ctx.db()).as_adt()?.as_enum()?;
+                (&enum_ty == core_result).then_some(alias)
+            }
+            _ => None,
+        })
+        .find_map(|alias| {
+            let mut inserted_ret_type = false;
+            let generic_params = alias
+                .source(ctx.db())?
+                .value
+                .generic_param_list()?
+                .generic_params()
+                .map(|param| match param {
+                    // Replace the very first type parameter with the functions return type.
+                    ast::GenericParam::TypeParam(_) if !inserted_ret_type => {
+                        inserted_ret_type = true;
+                        ret_type.to_smolstr()
+                    }
+                    ast::GenericParam::LifetimeParam(_) => make::lifetime("'_").to_smolstr(),
+                    _ => make::ty_placeholder().to_smolstr(),
+                })
+                .join(", ");
+
+            let name = alias.name(ctx.db());
+            let name = name.as_str();
+            Some(make::ty(&format!("{name}<{generic_params}>")))
+        })
+    });
+    // If there is no applicable alias in scope use the default Result type.
+    alias.unwrap_or_else(|| make::ext::ty_result(ret_type.clone(), make::ty_placeholder()))
+}
+
 fn tail_cb_impl(acc: &mut Vec<ast::Expr>, e: &ast::Expr) {
     match e {
         Expr::BreakExpr(break_expr) => {
@@ -998,4 +1053,216 @@
 "#,
         );
     }
+
+    #[test]
+    fn wrap_return_type_in_local_result_type() {
+        check_assist(
+            wrap_return_type_in_result,
+            r#"
+//- minicore: result
+type Result<T> = core::result::Result<T, ()>;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+type Result<T> = core::result::Result<T, ()>;
+
+fn foo() -> Result<i32> {
+    return Ok(42i32);
+}
+"#,
+        );
+
+        check_assist(
+            wrap_return_type_in_result,
+            r#"
+//- minicore: result
+type Result2<T> = core::result::Result<T, ()>;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+type Result2<T> = core::result::Result<T, ()>;
+
+fn foo() -> Result<i32, ${0:_}> {
+    return Ok(42i32);
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_imported_local_result_type() {
+        check_assist(
+            wrap_return_type_in_result,
+            r#"
+//- minicore: result
+mod some_module {
+    pub type Result<T> = core::result::Result<T, ()>;
+}
+
+use some_module::Result;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+mod some_module {
+    pub type Result<T> = core::result::Result<T, ()>;
+}
+
+use some_module::Result;
+
+fn foo() -> Result<i32> {
+    return Ok(42i32);
+}
+"#,
+        );
+
+        check_assist(
+            wrap_return_type_in_result,
+            r#"
+//- minicore: result
+mod some_module {
+    pub type Result<T> = core::result::Result<T, ()>;
+}
+
+use some_module::*;
+
+fn foo() -> i3$02 {
+    return 42i32;
+}
+"#,
+            r#"
+mod some_module {
+    pub type Result<T> = core::result::Result<T, ()>;
+}
+
+use some_module::*;
+
+fn foo() -> Result<i32> {
+    return Ok(42i32);
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_local_result_type_from_function_body() {
+        check_assist(
+            wrap_return_type_in_result,
+            r#"
+//- minicore: result
+fn foo() -> i3$02 {
+    type Result<T> = core::result::Result<T, ()>;
+    0
+}
+"#,
+            r#"
+fn foo() -> Result<i32, ${0:_}> {
+    type Result<T> = core::result::Result<T, ()>;
+    Ok(0)
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_local_result_type_already_using_alias() {
+        check_assist_not_applicable(
+            wrap_return_type_in_result,
+            r#"
+//- minicore: result
+pub type Result<T> = core::result::Result<T, ()>;
+
+fn foo() -> Result<i3$02> {
+    return Ok(42i32);
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn wrap_return_type_in_local_result_type_multiple_generics() {
+        check_assist(
+            wrap_return_type_in_result,
+            r#"
+//- minicore: result
+type Result<T, E> = core::result::Result<T, E>;
+
+fn foo() -> i3$02 {
+    0
+}
+"#,
+            r#"
+type Result<T, E> = core::result::Result<T, E>;
+
+fn foo() -> Result<i32, ${0:_}> {
+    Ok(0)
+}
+"#,
+        );
+
+        check_assist(
+            wrap_return_type_in_result,
+            r#"
+//- minicore: result
+type Result<T, E> = core::result::Result<Foo<T, E>, ()>;
+
+fn foo() -> i3$02 {
+    0
+}
+            "#,
+            r#"
+type Result<T, E> = core::result::Result<Foo<T, E>, ()>;
+
+fn foo() -> Result<i32, ${0:_}> {
+    Ok(0)
+}
+            "#,
+        );
+
+        check_assist(
+            wrap_return_type_in_result,
+            r#"
+//- minicore: result
+type Result<'a, T, E> = core::result::Result<Foo<T, E>, &'a ()>;
+
+fn foo() -> i3$02 {
+    0
+}
+            "#,
+            r#"
+type Result<'a, T, E> = core::result::Result<Foo<T, E>, &'a ()>;
+
+fn foo() -> Result<'_, i32, ${0:_}> {
+    Ok(0)
+}
+            "#,
+        );
+
+        check_assist(
+            wrap_return_type_in_result,
+            r#"
+//- minicore: result
+type Result<T, const N: usize> = core::result::Result<Foo<T>, Bar<N>>;
+
+fn foo() -> i3$02 {
+    0
+}
+            "#,
+            r#"
+type Result<T, const N: usize> = core::result::Result<Foo<T>, Bar<N>>;
+
+fn foo() -> Result<i32, ${0:_}> {
+    Ok(0)
+}
+            "#,
+        );
+    }
 }
diff --git a/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs b/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs
index 0fa46ef..149cb4c 100644
--- a/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs
+++ b/crates/ide-assists/src/handlers/wrap_unwrap_cfg_attr.rs
@@ -25,6 +25,7 @@
 // struct S {
 //    field: i32
 // }
+// ```
 
 enum WrapUnwrapOption {
     WrapDerive { derive: TextRange, attr: ast::Attr },
diff --git a/crates/ide-assists/src/lib.rs b/crates/ide-assists/src/lib.rs
index c88cb3d..c98655b 100644
--- a/crates/ide-assists/src/lib.rs
+++ b/crates/ide-assists/src/lib.rs
@@ -58,6 +58,8 @@
 //! See also this post:
 //! <https://rust-analyzer.github.io/blog/2020/09/28/how-to-make-a-light-bulb.html>
 
+#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
+
 mod assist_config;
 mod assist_context;
 #[cfg(test)]
@@ -136,6 +138,7 @@
     mod destructure_tuple_binding;
     mod desugar_doc_comment;
     mod expand_glob_import;
+    mod explicit_enum_discriminant;
     mod extract_expressions_from_format_string;
     mod extract_function;
     mod extract_module;
@@ -266,6 +269,7 @@
             destructure_tuple_binding::destructure_tuple_binding,
             destructure_struct_binding::destructure_struct_binding,
             expand_glob_import::expand_glob_import,
+            explicit_enum_discriminant::explicit_enum_discriminant,
             extract_expressions_from_format_string::extract_expressions_from_format_string,
             extract_struct_from_enum_variant::extract_struct_from_enum_variant,
             extract_type_alias::extract_type_alias,
diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs
index dce7bbf..48e12a8 100644
--- a/crates/ide-assists/src/tests/generated.rs
+++ b/crates/ide-assists/src/tests/generated.rs
@@ -910,6 +910,29 @@
 }
 
 #[test]
+fn doctest_explicit_enum_discriminant() {
+    check_doc_test(
+        "explicit_enum_discriminant",
+        r#####"
+enum TheEnum$0 {
+    Foo,
+    Bar,
+    Baz = 42,
+    Quux,
+}
+"#####,
+        r#####"
+enum TheEnum {
+    Foo = 0,
+    Bar = 1,
+    Baz = 42,
+    Quux = 43,
+}
+"#####,
+    )
+}
+
+#[test]
 fn doctest_extract_expressions_from_format_string() {
     check_doc_test(
         "extract_expressions_from_format_string",
diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs
index b8a6f3b..0830017 100644
--- a/crates/ide-assists/src/utils.rs
+++ b/crates/ide-assists/src/utils.rs
@@ -1,10 +1,13 @@
 //! Assorted functions shared by several assists.
 
 pub(crate) use gen_trait_fn_body::gen_trait_fn_body;
-use hir::{db::HirDatabase, HasAttrs as HirHasAttrs, HirDisplay, InFile, Semantics};
+use hir::{
+    db::{ExpandDatabase, HirDatabase},
+    HasAttrs as HirHasAttrs, HirDisplay, InFile, Semantics,
+};
 use ide_db::{
     famous_defs::FamousDefs, path_transform::PathTransform,
-    syntax_helpers::insert_whitespace_into_node::insert_ws_into, RootDatabase,
+    syntax_helpers::prettify_macro_expansion, RootDatabase,
 };
 use stdx::format_to;
 use syntax::{
@@ -23,7 +26,6 @@
 
 mod gen_trait_fn_body;
 pub(crate) mod ref_field_expr;
-pub(crate) mod suggest_name;
 
 pub(crate) fn unwrap_trivial_block(block_expr: ast::BlockExpr) -> ast::Expr {
     extract_trivial_expression(&block_expr)
@@ -179,10 +181,15 @@
     let new_indent_level = IndentLevel::from_node(impl_.syntax()) + 1;
     let items = original_items.iter().map(|InFile { file_id, value: original_item }| {
         let cloned_item = {
-            if file_id.is_macro() {
-                if let Some(formatted) =
-                    ast::AssocItem::cast(insert_ws_into(original_item.syntax().clone()))
-                {
+            if let Some(macro_file) = file_id.macro_file() {
+                let span_map = sema.db.expansion_span_map(macro_file);
+                let item_prettified = prettify_macro_expansion(
+                    sema.db,
+                    original_item.syntax().clone(),
+                    &span_map,
+                    target_scope.krate().into(),
+                );
+                if let Some(formatted) = ast::AssocItem::cast(item_prettified) {
                     return formatted;
                 } else {
                     stdx::never!("formatted `AssocItem` could not be cast back to `AssocItem`");
diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs
index b537150..414627f 100644
--- a/crates/ide-completion/src/completions.rs
+++ b/crates/ide-completion/src/completions.rs
@@ -617,6 +617,16 @@
         }
         self.add_opt(render_struct_pat(RenderContext::new(ctx), pattern_ctx, strukt, local_name));
     }
+
+    pub(crate) fn suggest_name(&mut self, ctx: &CompletionContext<'_>, name: &str) {
+        let item = CompletionItem::new(
+            CompletionItemKind::Binding,
+            ctx.source_range(),
+            SmolStr::from(name),
+            ctx.edition,
+        );
+        item.add_to(self, ctx.db);
+    }
 }
 
 /// Calls the callback for each variant of the provided enum with the path to the variant.
diff --git a/crates/ide-completion/src/completions/attribute.rs b/crates/ide-completion/src/completions/attribute.rs
index 9821fb4..d0b489c 100644
--- a/crates/ide-completion/src/completions/attribute.rs
+++ b/crates/ide-completion/src/completions/attribute.rs
@@ -56,7 +56,7 @@
             &parse_tt_as_comma_sep_paths(tt, ctx.edition)?,
             FEATURES,
         ),
-        "allow" | "warn" | "deny" | "forbid" => {
+        "allow" | "expect" | "deny" | "forbid" | "warn" => {
             let existing_lints = parse_tt_as_comma_sep_paths(tt, ctx.edition)?;
 
             let lints: Vec<Lint> = CLIPPY_LINT_GROUPS
@@ -222,7 +222,7 @@
     [@ {} {$($tt:tt)*}] => { &[$($tt)*] as _ };
     // starting matcher
     [$($tt:tt),*] => {
-        attrs!(@ { $($tt)* } { "allow", "cfg", "cfg_attr", "deny", "forbid", "warn" })
+        attrs!(@ { $($tt)* } { "allow", "cfg", "cfg_attr", "deny", "expect", "forbid", "warn" })
     };
 }
 
@@ -303,6 +303,7 @@
     attr(r#"doc = "…""#, Some("doc"), Some(r#"doc = "${0:docs}""#)),
     attr(r#"doc(alias = "…")"#, Some("docalias"), Some(r#"doc(alias = "${0:docs}")"#)),
     attr(r#"doc(hidden)"#, Some("dochidden"), Some(r#"doc(hidden)"#)),
+    attr("expect(…)", Some("expect"), Some("expect(${0:lint})")),
     attr(
         r#"export_name = "…""#,
         Some("export_name"),
diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs
index d55bc3e..f2c360a 100644
--- a/crates/ide-completion/src/completions/dot.rs
+++ b/crates/ide-completion/src/completions/dot.rs
@@ -600,7 +600,7 @@
 struct A {}
 trait Trait { fn the_method(&self); }
 impl Trait for A {}
-fn foo(a: A) { a.the_method()$0 }
+fn foo(a: A) { a.the_method();$0 }
 "#,
         );
     }
diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs
index fc6e1eb..672e179 100644
--- a/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -31,14 +31,14 @@
 //! }
 //! ```
 
-use hir::HasAttrs;
+use hir::{db::ExpandDatabase, HasAttrs, MacroFileId, Name};
 use ide_db::{
     documentation::HasDocs, path_transform::PathTransform,
-    syntax_helpers::insert_whitespace_into_node, traits::get_missing_assoc_items, SymbolKind,
+    syntax_helpers::prettify_macro_expansion, traits::get_missing_assoc_items, SymbolKind,
 };
 use syntax::{
-    ast::{self, edit_in_place::AttrsOwnerEdit, HasTypeBounds},
-    format_smolstr, AstNode, SmolStr, SyntaxElement, SyntaxKind, TextRange, ToSmolStr, T,
+    ast::{self, edit_in_place::AttrsOwnerEdit, make, HasGenericArgs, HasTypeBounds},
+    format_smolstr, ted, AstNode, SmolStr, SyntaxElement, SyntaxKind, TextRange, ToSmolStr, T,
 };
 use text_edit::TextEdit;
 
@@ -178,12 +178,36 @@
     func: hir::Function,
     impl_def: hir::Impl,
 ) {
-    let fn_name = func.name(ctx.db);
+    let fn_name = &func.name(ctx.db);
+    let sugar: &[_] = if func.is_async(ctx.db) {
+        &[AsyncSugaring::Async, AsyncSugaring::Desugar]
+    } else if func.returns_impl_future(ctx.db) {
+        &[AsyncSugaring::Plain, AsyncSugaring::Resugar]
+    } else {
+        &[AsyncSugaring::Plain]
+    };
+    for &sugaring in sugar {
+        add_function_impl_(acc, ctx, replacement_range, func, impl_def, fn_name, sugaring);
+    }
+}
 
-    let is_async = func.is_async(ctx.db);
+fn add_function_impl_(
+    acc: &mut Completions,
+    ctx: &CompletionContext<'_>,
+    replacement_range: TextRange,
+    func: hir::Function,
+    impl_def: hir::Impl,
+    fn_name: &Name,
+    async_sugaring: AsyncSugaring,
+) {
+    let async_ = if let AsyncSugaring::Async | AsyncSugaring::Resugar = async_sugaring {
+        "async "
+    } else {
+        ""
+    };
     let label = format_smolstr!(
         "{}fn {}({})",
-        if is_async { "async " } else { "" },
+        async_,
         fn_name.display(ctx.db, ctx.edition),
         if func.assoc_fn_params(ctx.db).is_empty() { "" } else { ".." }
     );
@@ -195,23 +219,16 @@
     });
 
     let mut item = CompletionItem::new(completion_kind, replacement_range, label, ctx.edition);
-    item.lookup_by(format!(
-        "{}fn {}",
-        if is_async { "async " } else { "" },
-        fn_name.display(ctx.db, ctx.edition)
-    ))
-    .set_documentation(func.docs(ctx.db))
-    .set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() });
+    item.lookup_by(format!("{}fn {}", async_, fn_name.display(ctx.db, ctx.edition)))
+        .set_documentation(func.docs(ctx.db))
+        .set_relevance(CompletionRelevance { exact_name_match: true, ..Default::default() });
 
     if let Some(source) = ctx.sema.source(func) {
-        let assoc_item = ast::AssocItem::Fn(source.value);
-        if let Some(transformed_item) = get_transformed_assoc_item(ctx, assoc_item, impl_def) {
-            let transformed_fn = match transformed_item {
-                ast::AssocItem::Fn(func) => func,
-                _ => unreachable!(),
-            };
-
-            let function_decl = function_declaration(&transformed_fn, source.file_id.is_macro());
+        if let Some(transformed_fn) =
+            get_transformed_fn(ctx, source.value, impl_def, async_sugaring)
+        {
+            let function_decl =
+                function_declaration(ctx, &transformed_fn, source.file_id.macro_file());
             match ctx.config.snippet_cap {
                 Some(cap) => {
                     let snippet = format!("{function_decl} {{\n    $0\n}}");
@@ -227,6 +244,14 @@
     }
 }
 
+#[derive(Copy, Clone)]
+enum AsyncSugaring {
+    Desugar,
+    Resugar,
+    Async,
+    Plain,
+}
+
 /// Transform a relevant associated item to inline generics from the impl, remove attrs and docs, etc.
 fn get_transformed_assoc_item(
     ctx: &CompletionContext<'_>,
@@ -251,6 +276,82 @@
     Some(assoc_item)
 }
 
+/// Transform a relevant associated item to inline generics from the impl, remove attrs and docs, etc.
+fn get_transformed_fn(
+    ctx: &CompletionContext<'_>,
+    fn_: ast::Fn,
+    impl_def: hir::Impl,
+    async_: AsyncSugaring,
+) -> Option<ast::Fn> {
+    let trait_ = impl_def.trait_(ctx.db)?;
+    let source_scope = &ctx.sema.scope(fn_.syntax())?;
+    let target_scope = &ctx.sema.scope(ctx.sema.source(impl_def)?.syntax().value)?;
+    let transform = PathTransform::trait_impl(
+        target_scope,
+        source_scope,
+        trait_,
+        ctx.sema.source(impl_def)?.value,
+    );
+
+    let fn_ = fn_.clone_for_update();
+    // FIXME: Paths in nested macros are not handled well. See
+    // `macro_generated_assoc_item2` test.
+    transform.apply(fn_.syntax());
+    fn_.remove_attrs_and_docs();
+    match async_ {
+        AsyncSugaring::Desugar => {
+            match fn_.ret_type() {
+                Some(ret_ty) => {
+                    let ty = ret_ty.ty()?;
+                    ted::replace(
+                        ty.syntax(),
+                        make::ty(&format!("impl Future<Output = {ty}>"))
+                            .syntax()
+                            .clone_for_update(),
+                    );
+                }
+                None => ted::append_child(
+                    fn_.param_list()?.syntax(),
+                    make::ret_type(make::ty("impl Future<Output = ()>"))
+                        .syntax()
+                        .clone_for_update(),
+                ),
+            }
+            fn_.async_token().unwrap().detach();
+        }
+        AsyncSugaring::Resugar => {
+            let ty = fn_.ret_type()?.ty()?;
+            match &ty {
+                // best effort guessing here
+                ast::Type::ImplTraitType(t) => {
+                    let output = t.type_bound_list()?.bounds().find_map(|b| match b.ty()? {
+                        ast::Type::PathType(p) => {
+                            let p = p.path()?.segment()?;
+                            if p.name_ref()?.text() != "Future" {
+                                return None;
+                            }
+                            match p.generic_arg_list()?.generic_args().next()? {
+                                ast::GenericArg::AssocTypeArg(a)
+                                    if a.name_ref()?.text() == "Output" =>
+                                {
+                                    a.ty()
+                                }
+                                _ => None,
+                            }
+                        }
+                        _ => None,
+                    })?;
+                    ted::replace(ty.syntax(), output.syntax());
+                }
+                _ => (),
+            }
+            ted::prepend_child(fn_.syntax(), make::token(T![async]));
+        }
+        AsyncSugaring::Async | AsyncSugaring::Plain => (),
+    }
+    Some(fn_)
+}
+
 fn add_type_alias_impl(
     acc: &mut Completions,
     ctx: &CompletionContext<'_>,
@@ -266,7 +367,7 @@
         CompletionItem::new(SymbolKind::TypeAlias, replacement_range, label, ctx.edition);
     item.lookup_by(format!("type {alias_name}"))
         .set_documentation(type_alias.docs(ctx.db))
-        .set_relevance(CompletionRelevance { is_item_from_trait: true, ..Default::default() });
+        .set_relevance(CompletionRelevance { exact_name_match: true, ..Default::default() });
 
     if let Some(source) = ctx.sema.source(type_alias) {
         let assoc_item = ast::AssocItem::TypeAlias(source.value);
@@ -332,7 +433,8 @@
                     _ => unreachable!(),
                 };
 
-                let label = make_const_compl_syntax(&transformed_const, source.file_id.is_macro());
+                let label =
+                    make_const_compl_syntax(ctx, &transformed_const, source.file_id.macro_file());
                 let replacement = format!("{label} ");
 
                 let mut item =
@@ -340,7 +442,7 @@
                 item.lookup_by(format_smolstr!("const {const_name}"))
                     .set_documentation(const_.docs(ctx.db))
                     .set_relevance(CompletionRelevance {
-                        is_item_from_trait: true,
+                        exact_name_match: true,
                         ..Default::default()
                     });
                 match ctx.config.snippet_cap {
@@ -356,9 +458,14 @@
     }
 }
 
-fn make_const_compl_syntax(const_: &ast::Const, needs_whitespace: bool) -> SmolStr {
-    let const_ = if needs_whitespace {
-        insert_whitespace_into_node::insert_ws_into(const_.syntax().clone())
+fn make_const_compl_syntax(
+    ctx: &CompletionContext<'_>,
+    const_: &ast::Const,
+    macro_file: Option<MacroFileId>,
+) -> SmolStr {
+    let const_ = if let Some(macro_file) = macro_file {
+        let span_map = ctx.db.expansion_span_map(macro_file);
+        prettify_macro_expansion(ctx.db, const_.syntax().clone(), &span_map, ctx.krate.into())
     } else {
         const_.syntax().clone()
     };
@@ -379,9 +486,14 @@
     format_smolstr!("{} =", syntax.trim_end())
 }
 
-fn function_declaration(node: &ast::Fn, needs_whitespace: bool) -> String {
-    let node = if needs_whitespace {
-        insert_whitespace_into_node::insert_ws_into(node.syntax().clone())
+fn function_declaration(
+    ctx: &CompletionContext<'_>,
+    node: &ast::Fn,
+    macro_file: Option<MacroFileId>,
+) -> String {
+    let node = if let Some(macro_file) = macro_file {
+        let span_map = ctx.db.expansion_span_map(macro_file);
+        prettify_macro_expansion(ctx.db, node.syntax().clone(), &span_map, ctx.krate.into())
     } else {
         node.syntax().clone()
     };
@@ -1404,4 +1516,132 @@
 "#,
         );
     }
+
+    #[test]
+    fn impl_fut() {
+        check_edit(
+            "fn foo",
+            r#"
+//- minicore: future, send, sized
+use core::future::Future;
+
+trait DesugaredAsyncTrait {
+    fn foo(&self) -> impl Future<Output = usize> + Send;
+}
+
+impl DesugaredAsyncTrait for () {
+    $0
+}
+"#,
+            r#"
+use core::future::Future;
+
+trait DesugaredAsyncTrait {
+    fn foo(&self) -> impl Future<Output = usize> + Send;
+}
+
+impl DesugaredAsyncTrait for () {
+    fn foo(&self) -> impl Future<Output = usize> + Send {
+    $0
+}
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn impl_fut_resugared() {
+        check_edit(
+            "async fn foo",
+            r#"
+//- minicore: future, send, sized
+use core::future::Future;
+
+trait DesugaredAsyncTrait {
+    fn foo(&self) -> impl Future<Output = usize> + Send;
+}
+
+impl DesugaredAsyncTrait for () {
+    $0
+}
+"#,
+            r#"
+use core::future::Future;
+
+trait DesugaredAsyncTrait {
+    fn foo(&self) -> impl Future<Output = usize> + Send;
+}
+
+impl DesugaredAsyncTrait for () {
+    async fn foo(&self) -> usize {
+    $0
+}
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn async_desugared() {
+        check_edit(
+            "fn foo",
+            r#"
+//- minicore: future, send, sized
+use core::future::Future;
+
+trait DesugaredAsyncTrait {
+    async fn foo(&self) -> usize;
+}
+
+impl DesugaredAsyncTrait for () {
+    $0
+}
+"#,
+            r#"
+use core::future::Future;
+
+trait DesugaredAsyncTrait {
+    async fn foo(&self) -> usize;
+}
+
+impl DesugaredAsyncTrait for () {
+     fn foo(&self) -> impl Future<Output = usize> {
+    $0
+}
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn async_() {
+        check_edit(
+            "async fn foo",
+            r#"
+//- minicore: future, send, sized
+use core::future::Future;
+
+trait DesugaredAsyncTrait {
+    async fn foo(&self) -> usize;
+}
+
+impl DesugaredAsyncTrait for () {
+    $0
+}
+"#,
+            r#"
+use core::future::Future;
+
+trait DesugaredAsyncTrait {
+    async fn foo(&self) -> usize;
+}
+
+impl DesugaredAsyncTrait for () {
+    async fn foo(&self) -> usize {
+    $0
+}
+}
+"#,
+        );
+    }
 }
diff --git a/crates/ide-completion/src/completions/keyword.rs b/crates/ide-completion/src/completions/keyword.rs
index 3f50cd5..0acb878 100644
--- a/crates/ide-completion/src/completions/keyword.rs
+++ b/crates/ide-completion/src/completions/keyword.rs
@@ -151,6 +151,68 @@
     }
 
     #[test]
+    fn for_in_impl() {
+        check_edit(
+            "for",
+            r#"
+struct X;
+impl X $0 {}
+"#,
+            r#"
+struct X;
+impl X for $0 {}
+"#,
+        );
+        check_edit(
+            "for",
+            r#"
+fn foo() {
+    struct X;
+    impl X $0 {}
+}
+"#,
+            r#"
+fn foo() {
+    struct X;
+    impl X for $0 {}
+}
+"#,
+        );
+        check_edit(
+            "for",
+            r#"
+fn foo() {
+    struct X;
+    impl X $0
+}
+"#,
+            r#"
+fn foo() {
+    struct X;
+    impl X for $0
+}
+"#,
+        );
+        check_edit(
+            "for",
+            r#"
+fn foo() {
+    struct X;
+    impl X { fn bar() { $0 } }
+}
+"#,
+            r#"
+fn foo() {
+    struct X;
+    impl X { fn bar() { for $1 in $2 {
+    $0
+} } }
+}
+"#,
+        );
+    }
+
+    #[test]
     fn let_semi() {
         cov_mark::check!(let_semi);
         check_edit(
diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs
index 60cfb7e..8f38e02 100644
--- a/crates/ide-completion/src/completions/pattern.rs
+++ b/crates/ide-completion/src/completions/pattern.rs
@@ -1,6 +1,7 @@
 //! Completes constants and paths in unqualified patterns.
 
 use hir::{db::DefDatabase, AssocItem, ScopeDef};
+use ide_db::syntax_helpers::suggest_name;
 use syntax::ast::Pat;
 
 use crate::{
@@ -45,6 +46,19 @@
         return;
     }
 
+    // Suggest name only in let-stmt and fn param
+    if pattern_ctx.should_suggest_name {
+        let mut name_generator = suggest_name::NameGenerator::new();
+        if let Some(suggested) = ctx
+            .expected_type
+            .as_ref()
+            .map(|ty| ty.strip_references())
+            .and_then(|ty| name_generator.for_type(&ty, ctx.db, ctx.edition))
+        {
+            acc.suggest_name(ctx, &suggested);
+        }
+    }
+
     let refutable = pattern_ctx.refutability == PatternRefutability::Refutable;
     let single_variant_enum = |enum_: hir::Enum| ctx.db.enum_data(enum_.into()).variants.len() == 1;
 
diff --git a/crates/ide-completion/src/completions/postfix.rs b/crates/ide-completion/src/completions/postfix.rs
index a632f14..d3579fd 100644
--- a/crates/ide-completion/src/completions/postfix.rs
+++ b/crates/ide-completion/src/completions/postfix.rs
@@ -294,6 +294,18 @@
 
     let mut new_element_opt = initial_element.clone();
 
+    while let Some(parent_deref_element) =
+        resulting_element.syntax().parent().and_then(ast::PrefixExpr::cast)
+    {
+        if parent_deref_element.op_kind() != Some(ast::UnaryOp::Deref) {
+            break;
+        }
+
+        resulting_element = ast::Expr::from(parent_deref_element);
+
+        new_element_opt = make::expr_prefix(syntax::T![*], new_element_opt);
+    }
+
     if let Some(first_ref_expr) = resulting_element.syntax().parent().and_then(ast::RefExpr::cast) {
         if let Some(expr) = first_ref_expr.expr() {
             resulting_element = expr;
@@ -302,9 +314,10 @@
         while let Some(parent_ref_element) =
             resulting_element.syntax().parent().and_then(ast::RefExpr::cast)
         {
+            let exclusive = parent_ref_element.mut_token().is_some();
             resulting_element = ast::Expr::from(parent_ref_element);
 
-            new_element_opt = make::expr_ref(new_element_opt, false);
+            new_element_opt = make::expr_ref(new_element_opt, exclusive);
         }
     } else {
         // If we do not find any ref expressions, restore
@@ -855,4 +868,42 @@
             expect![[r#""#]],
         );
     }
+
+    #[test]
+    fn mut_ref_consuming() {
+        check_edit(
+            "call",
+            r#"
+fn main() {
+    let mut x = &mut 2;
+    &mut x.$0;
+}
+"#,
+            r#"
+fn main() {
+    let mut x = &mut 2;
+    ${1}(&mut x);
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn deref_consuming() {
+        check_edit(
+            "call",
+            r#"
+fn main() {
+    let mut x = &mut 2;
+    &mut *x.$0;
+}
+"#,
+            r#"
+fn main() {
+    let mut x = &mut 2;
+    ${1}(&mut *x);
+}
+"#,
+        );
+    }
 }
diff --git a/crates/ide-completion/src/config.rs b/crates/ide-completion/src/config.rs
index d885b82..0d403f4 100644
--- a/crates/ide-completion/src/config.rs
+++ b/crates/ide-completion/src/config.rs
@@ -19,6 +19,7 @@
     pub term_search_fuel: u64,
     pub full_function_signatures: bool,
     pub callable: Option<CallableSnippets>,
+    pub add_semicolon_to_unit: bool,
     pub snippet_cap: Option<SnippetCap>,
     pub insert_use: InsertUseConfig,
     pub prefer_no_std: bool,
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index bcd9df9..192f1b4 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -4,7 +4,7 @@
 #[cfg(test)]
 mod tests;
 
-use std::iter;
+use std::{iter, ops::ControlFlow};
 
 use hir::{
     HasAttrs, Local, Name, PathResolution, ScopeDef, Semantics, SemanticsScope, Type, TypeInfo,
@@ -15,7 +15,7 @@
 };
 use syntax::{
     ast::{self, AttrKind, NameOrNameRef},
-    AstNode, Edition, SmolStr,
+    match_ast, AstNode, Edition, SmolStr,
     SyntaxKind::{self, *},
     SyntaxToken, TextRange, TextSize, T,
 };
@@ -26,7 +26,7 @@
     CompletionConfig,
 };
 
-const COMPLETION_MARKER: &str = "intellijRulezz";
+const COMPLETION_MARKER: &str = "raCompletionMarker";
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub(crate) enum PatternRefutability {
@@ -264,6 +264,7 @@
     pub(crate) refutability: PatternRefutability,
     pub(crate) param_ctx: Option<ParamContext>,
     pub(crate) has_type_ascription: bool,
+    pub(crate) should_suggest_name: bool,
     pub(crate) parent_pat: Option<ast::Pat>,
     pub(crate) ref_token: Option<SyntaxToken>,
     pub(crate) mut_token: Option<SyntaxToken>,
@@ -456,6 +457,16 @@
     ///
     /// Here depth will be 2
     pub(crate) depth_from_crate_root: usize,
+
+    /// Whether and how to complete semicolon for unit-returning functions.
+    pub(crate) complete_semicolon: CompleteSemicolon,
+}
+
+#[derive(Debug)]
+pub(crate) enum CompleteSemicolon {
+    DoNotComplete,
+    CompleteSemi,
+    CompleteComma,
 }
 
 impl CompletionContext<'_> {
@@ -734,6 +745,53 @@
 
         let depth_from_crate_root = iter::successors(module.parent(db), |m| m.parent(db)).count();
 
+        let complete_semicolon = if config.add_semicolon_to_unit {
+            let inside_closure_ret = token.parent_ancestors().try_for_each(|ancestor| {
+                match_ast! {
+                    match ancestor {
+                        ast::BlockExpr(_) => ControlFlow::Break(false),
+                        ast::ClosureExpr(_) => ControlFlow::Break(true),
+                        _ => ControlFlow::Continue(())
+                    }
+                }
+            });
+
+            if inside_closure_ret == ControlFlow::Break(true) {
+                CompleteSemicolon::DoNotComplete
+            } else {
+                let next_non_trivia_token =
+                    std::iter::successors(token.next_token(), |it| it.next_token())
+                        .find(|it| !it.kind().is_trivia());
+                let in_match_arm = token.parent_ancestors().try_for_each(|ancestor| {
+                    if ast::MatchArm::can_cast(ancestor.kind()) {
+                        ControlFlow::Break(true)
+                    } else if matches!(
+                        ancestor.kind(),
+                        SyntaxKind::EXPR_STMT | SyntaxKind::BLOCK_EXPR
+                    ) {
+                        ControlFlow::Break(false)
+                    } else {
+                        ControlFlow::Continue(())
+                    }
+                });
+                // FIXME: This will assume expr macros are not inside match, we need to somehow go to the "parent" of the root node.
+                let in_match_arm = match in_match_arm {
+                    ControlFlow::Continue(()) => false,
+                    ControlFlow::Break(it) => it,
+                };
+                let complete_token = if in_match_arm { T![,] } else { T![;] };
+                if next_non_trivia_token.map(|it| it.kind()) == Some(complete_token) {
+                    CompleteSemicolon::DoNotComplete
+                } else if in_match_arm {
+                    CompleteSemicolon::CompleteComma
+                } else {
+                    CompleteSemicolon::CompleteSemi
+                }
+            }
+        } else {
+            CompleteSemicolon::DoNotComplete
+        };
+
         let ctx = CompletionContext {
             sema,
             scope,
@@ -751,6 +809,7 @@
             qualifier_ctx,
             locals,
             depth_from_crate_root,
+            complete_semicolon,
         };
         Some((ctx, analysis))
     }
diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs
index ed35939..1f9e3ed 100644
--- a/crates/ide-completion/src/context/analysis.rs
+++ b/crates/ide-completion/src/context/analysis.rs
@@ -1132,10 +1132,18 @@
             ast::PathType(it) => make_path_kind_type(it.into()),
             ast::PathExpr(it) => {
                 if let Some(p) = it.syntax().parent() {
-                    if ast::ExprStmt::can_cast(p.kind()) {
-                        if let Some(kind) = inbetween_body_and_decl_check(p) {
-                            return Some(make_res(NameRefKind::Keyword(kind)));
-                        }
+                    let p_kind = p.kind();
+                    // The syntax node of interest, for which we want to check whether
+                    // it is sandwiched between an item decl signature and its body.
+                    let probe = if ast::ExprStmt::can_cast(p_kind) {
+                        Some(p)
+                    } else if ast::StmtList::can_cast(p_kind) {
+                        Some(it.syntax().clone())
+                    } else {
+                        None
+                    };
+                    if let Some(kind) = probe.and_then(inbetween_body_and_decl_check) {
+                        return Some(make_res(NameRefKind::Keyword(kind)));
                     }
                 }
 
@@ -1199,7 +1207,13 @@
                     }
                 }
             },
-            ast::RecordExpr(it) => make_path_kind_expr(it.into()),
+            ast::RecordExpr(it) => {
+                // A record expression in this position is usually a result of parsing recovery, so check that
+                if let Some(kind) = inbetween_body_and_decl_check(it.syntax().clone()) {
+                    return Some(make_res(NameRefKind::Keyword(kind)));
+                }
+                make_path_kind_expr(it.into())
+            },
             _ => return None,
         }
     };
@@ -1416,10 +1430,23 @@
         _ => (None, None),
     };
 
+    // Only suggest name in let-stmt or fn param
+    let should_suggest_name = matches!(
+            &pat,
+            ast::Pat::IdentPat(it)
+                if it.syntax()
+                .parent()
+                .map_or(false, |node| {
+                    let kind = node.kind();
+                    ast::LetStmt::can_cast(kind) || ast::Param::can_cast(kind)
+                })
+    );
+
     PatternContext {
         refutability,
         param_ctx,
         has_type_ascription,
+        should_suggest_name,
         parent_pat: pat.syntax().parent().and_then(ast::Pat::cast),
         mut_token,
         ref_token,
diff --git a/crates/ide-completion/src/item.rs b/crates/ide-completion/src/item.rs
index a30a115..8c97ebd 100644
--- a/crates/ide-completion/src/item.rs
+++ b/crates/ide-completion/src/item.rs
@@ -19,8 +19,10 @@
 };
 
 /// `CompletionItem` describes a single completion entity which expands to 1 or more entries in the
-/// editor pop-up. It is basically a POD with various properties. To construct a
-/// [`CompletionItem`], use [`Builder::new`] method and the [`Builder`] struct.
+/// editor pop-up.
+///
+/// It is basically a POD with various properties. To construct a [`CompletionItem`],
+/// use [`Builder::new`] method and the [`Builder`] struct.
 #[derive(Clone)]
 #[non_exhaustive]
 pub struct CompletionItem {
@@ -129,7 +131,8 @@
 
 #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)]
 pub struct CompletionRelevance {
-    /// This is set in cases like these:
+    /// This is set when the identifier being completed matches up with the name that is expected,
+    /// like in a function argument.
     ///
     /// ```
     /// fn f(spam: String) {}
@@ -139,9 +142,9 @@
     /// }
     /// ```
     pub exact_name_match: bool,
-    /// See CompletionRelevanceTypeMatch doc comments for cases where this is set.
+    /// See [`CompletionRelevanceTypeMatch`].
     pub type_match: Option<CompletionRelevanceTypeMatch>,
-    /// This is set in cases like these:
+    /// Set for local variables.
     ///
     /// ```
     /// fn foo(a: u32) {
@@ -150,25 +153,26 @@
     /// }
     /// ```
     pub is_local: bool,
-    /// This is set when trait items are completed in an impl of that trait.
-    pub is_item_from_trait: bool,
-    /// This is set for when trait items are from traits with `#[doc(notable_trait)]`
-    pub is_item_from_notable_trait: bool,
-    /// This is set when an import is suggested whose name is already imported.
+    /// Populated when the completion item comes from a trait (impl).
+    pub trait_: Option<CompletionRelevanceTraitInfo>,
+    /// This is set when an import is suggested in a use item whose name is already imported.
     pub is_name_already_imported: bool,
     /// This is set for completions that will insert a `use` item.
     pub requires_import: bool,
-    /// Set for method completions of the `core::ops` and `core::cmp` family.
-    pub is_op_method: bool,
     /// Set for item completions that are private but in the workspace.
     pub is_private_editable: bool,
     /// Set for postfix snippet item completions
     pub postfix_match: Option<CompletionRelevancePostfixMatch>,
-    /// This is set for type inference results
-    pub is_definite: bool,
     /// This is set for items that are function (associated or method)
     pub function: Option<CompletionRelevanceFn>,
 }
+#[derive(Debug, Clone, Copy, Eq, PartialEq)]
+pub struct CompletionRelevanceTraitInfo {
+    /// The trait this item is from is a `#[doc(notable_trait)]`
+    pub notable_trait: bool,
+    /// Set for method completions of the `core::ops` and `core::cmp` family.
+    pub is_op_method: bool,
+}
 
 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
 pub enum CompletionRelevanceTypeMatch {
@@ -182,7 +186,7 @@
     /// }
     /// ```
     CouldUnify,
-    /// This is set in cases like these:
+    /// This is set in cases where the type matches the expected type, like:
     ///
     /// ```
     /// fn f(spam: String) {}
@@ -238,90 +242,82 @@
     /// See is_relevant if you need to make some judgement about score
     /// in an absolute sense.
     pub fn score(self) -> u32 {
-        let mut score = 0;
+        let mut score = !0 / 2;
         let CompletionRelevance {
             exact_name_match,
             type_match,
             is_local,
-            is_item_from_trait,
             is_name_already_imported,
             requires_import,
-            is_op_method,
             is_private_editable,
             postfix_match,
-            is_definite,
-            is_item_from_notable_trait,
+            trait_,
             function,
         } = self;
 
+        // only applicable for completions within use items
+        // lower rank for conflicting import names
+        if is_name_already_imported {
+            score -= 1;
+        }
+        // slightly prefer locals
+        if is_local {
+            score += 1;
+        }
+
         // lower rank private things
         if !is_private_editable {
             score += 1;
         }
-        // lower rank trait op methods
-        if !is_op_method {
-            score += 10;
+
+        if let Some(trait_) = trait_ {
+            // lower rank trait methods unless its notable
+            if !trait_.notable_trait {
+                score -= 5;
+            }
+            // lower rank trait op methods
+            if trait_.is_op_method {
+                score -= 5;
+            }
         }
-        // lower rank for conflicting import names
-        if !is_name_already_imported {
-            score += 1;
-        }
-        // lower rank for items that don't need an import
-        if !requires_import {
-            score += 1;
+        // lower rank for items that need an import
+        if requires_import {
+            score -= 1;
         }
         if exact_name_match {
-            score += 10;
+            score += 20;
         }
-        score += match postfix_match {
-            Some(CompletionRelevancePostfixMatch::Exact) => 100,
-            Some(CompletionRelevancePostfixMatch::NonExact) => 0,
-            None => 3,
+        match postfix_match {
+            Some(CompletionRelevancePostfixMatch::Exact) => score += 100,
+            Some(CompletionRelevancePostfixMatch::NonExact) => score -= 5,
+            None => (),
         };
         score += match type_match {
-            Some(CompletionRelevanceTypeMatch::Exact) => 8,
-            Some(CompletionRelevanceTypeMatch::CouldUnify) => 3,
+            Some(CompletionRelevanceTypeMatch::Exact) => 18,
+            Some(CompletionRelevanceTypeMatch::CouldUnify) => 5,
             None => 0,
         };
-        // slightly prefer locals
-        if is_local {
-            score += 1;
-        }
-        if is_item_from_trait {
-            score += 1;
-        }
-        if is_item_from_notable_trait {
-            score += 1;
-        }
-        if is_definite {
-            score += 10;
-        }
+        if let Some(function) = function {
+            let mut fn_score = match function.return_type {
+                CompletionRelevanceReturnType::DirectConstructor => 15,
+                CompletionRelevanceReturnType::Builder => 10,
+                CompletionRelevanceReturnType::Constructor => 5,
+                CompletionRelevanceReturnType::Other => 0u32,
+            };
 
-        score += function
-            .map(|asf| {
-                let mut fn_score = match asf.return_type {
-                    CompletionRelevanceReturnType::DirectConstructor => 15,
-                    CompletionRelevanceReturnType::Builder => 10,
-                    CompletionRelevanceReturnType::Constructor => 5,
-                    CompletionRelevanceReturnType::Other => 0,
-                };
+            // When a fn is bumped due to return type:
+            // Bump Constructor or Builder methods with no arguments,
+            // over them than with self arguments
+            if function.has_params {
+                // bump associated functions
+                fn_score = fn_score.saturating_sub(1);
+            } else if function.has_self_param {
+                // downgrade methods (below Constructor)
+                fn_score = fn_score.min(1);
+            }
 
-                // When a fn is bumped due to return type:
-                // Bump Constructor or Builder methods with no arguments,
-                // over them than with self arguments
-                if fn_score > 0 {
-                    if !asf.has_params {
-                        // bump associated functions
-                        fn_score += 1;
-                    } else if asf.has_self_param {
-                        // downgrade methods (below Constructor)
-                        fn_score = 1;
-                    }
-                }
-
-                fn_score
-            })
-            .unwrap_or_default();
+            score += fn_score;
+        };
 
         score
     }
@@ -364,6 +360,7 @@
                 SymbolKind::Field => "fd",
                 SymbolKind::Function => "fn",
                 SymbolKind::Impl => "im",
+                SymbolKind::InlineAsmRegOrRegClass => "ar",
                 SymbolKind::Label => "lb",
                 SymbolKind::LifetimeParam => "lt",
                 SymbolKind::Local => "lc",
@@ -701,8 +698,21 @@
         // that any items in the same vec have the same score.
         let expected_relevance_order = vec![
             vec![],
-            vec![Cr { is_op_method: true, is_private_editable: true, ..default }],
-            vec![Cr { is_op_method: true, ..default }],
+            vec![Cr {
+                trait_: Some(crate::item::CompletionRelevanceTraitInfo {
+                    notable_trait: false,
+                    is_op_method: true,
+                }),
+                is_private_editable: true,
+                ..default
+            }],
+            vec![Cr {
+                trait_: Some(crate::item::CompletionRelevanceTraitInfo {
+                    notable_trait: false,
+                    is_op_method: true,
+                }),
+                ..default
+            }],
             vec![Cr { postfix_match: Some(CompletionRelevancePostfixMatch::NonExact), ..default }],
             vec![Cr { is_private_editable: true, ..default }],
             vec![default],
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs
index ff5ec3a..f2e9de9 100644
--- a/crates/ide-completion/src/render.rs
+++ b/crates/ide-completion/src/render.rs
@@ -249,7 +249,11 @@
         ty_string,
         ctx.edition,
     );
-    builder.set_relevance(CompletionRelevance { is_definite: true, ..Default::default() });
+    builder.set_relevance(CompletionRelevance {
+        type_match: Some(CompletionRelevanceTypeMatch::Exact),
+        exact_name_match: true,
+        ..Default::default()
+    });
     builder.build(ctx.db)
 }
 
@@ -756,7 +760,7 @@
                     relevance.postfix_match == Some(CompletionRelevancePostfixMatch::Exact),
                     "snippet",
                 ),
-                (relevance.is_op_method, "op_method"),
+                (relevance.trait_.map_or(false, |it| it.is_op_method), "op_method"),
                 (relevance.requires_import, "requires_import"),
             ]
             .into_iter()
@@ -1181,7 +1185,7 @@
                         label: "main()",
                         source_range: 68..70,
                         delete: 68..70,
-                        insert: "main()$0",
+                        insert: "main();$0",
                         kind: SymbolKind(
                             Function,
                         ),
@@ -1240,7 +1244,7 @@
                         label: "main()",
                         source_range: 75..76,
                         delete: 75..76,
-                        insert: "main()$0",
+                        insert: "main();$0",
                         kind: SymbolKind(
                             Function,
                         ),
@@ -1272,14 +1276,11 @@
                                 Exact,
                             ),
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: false,
+                            trait_: None,
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: None,
                         },
                         trigger_call_info: true,
@@ -1300,14 +1301,11 @@
                                 Exact,
                             ),
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: false,
+                            trait_: None,
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: None,
                         },
                         trigger_call_info: true,
@@ -1333,7 +1331,7 @@
                         label: "main()",
                         source_range: 56..59,
                         delete: 56..59,
-                        insert: "main()$0",
+                        insert: "main();$0",
                         kind: SymbolKind(
                             Function,
                         ),
@@ -1344,7 +1342,7 @@
                         label: "something_deprecated()",
                         source_range: 56..59,
                         delete: 56..59,
-                        insert: "something_deprecated()$0",
+                        insert: "something_deprecated();$0",
                         kind: SymbolKind(
                             Function,
                         ),
@@ -1380,14 +1378,11 @@
                                 CouldUnify,
                             ),
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: false,
+                            trait_: None,
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: None,
                         },
                     },
@@ -1418,7 +1413,7 @@
                         label: "bar()",
                         source_range: 94..94,
                         delete: 94..94,
-                        insert: "bar()$0",
+                        insert: "bar();$0",
                         kind: SymbolKind(
                             Method,
                         ),
@@ -1431,14 +1426,11 @@
                             exact_name_match: false,
                             type_match: None,
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: false,
+                            trait_: None,
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: Some(
                                 CompletionRelevanceFn {
                                     has_params: true,
@@ -1548,7 +1540,7 @@
                         label: "the_method()",
                         source_range: 81..81,
                         delete: 81..81,
-                        insert: "the_method()$0",
+                        insert: "the_method();$0",
                         kind: SymbolKind(
                             Method,
                         ),
@@ -1558,14 +1550,11 @@
                             exact_name_match: false,
                             type_match: None,
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: false,
+                            trait_: None,
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: Some(
                                 CompletionRelevanceFn {
                                     has_params: true,
@@ -1774,14 +1763,11 @@
                                 Exact,
                             ),
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: false,
+                            trait_: None,
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: None,
                         },
                     },
@@ -2492,14 +2478,11 @@
                             exact_name_match: false,
                             type_match: None,
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: false,
+                            trait_: None,
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: Some(
                                 CompletionRelevanceFn {
                                     has_params: true,
@@ -2574,14 +2557,11 @@
                                 Exact,
                             ),
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: false,
+                            trait_: None,
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: None,
                         },
                     },
@@ -2624,14 +2604,11 @@
                             exact_name_match: false,
                             type_match: None,
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: false,
+                            trait_: None,
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: Some(
                                 CompletionRelevanceFn {
                                     has_params: false,
@@ -2812,7 +2789,7 @@
             r#"
 mod m { pub fn r#type {} }
 fn main() {
-    m::r#type()$0
+    m::r#type();$0
 }
 "#,
         )
@@ -2986,7 +2963,7 @@
                         label: "flush()",
                         source_range: 193..193,
                         delete: 193..193,
-                        insert: "flush()$0",
+                        insert: "flush();$0",
                         kind: SymbolKind(
                             Method,
                         ),
@@ -2996,14 +2973,16 @@
                             exact_name_match: false,
                             type_match: None,
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: true,
+                            trait_: Some(
+                                CompletionRelevanceTraitInfo {
+                                    notable_trait: true,
+                                    is_op_method: false,
+                                },
+                            ),
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: None,
                         },
                     },
@@ -3011,7 +2990,7 @@
                         label: "write()",
                         source_range: 193..193,
                         delete: 193..193,
-                        insert: "write()$0",
+                        insert: "write();$0",
                         kind: SymbolKind(
                             Method,
                         ),
@@ -3021,14 +3000,16 @@
                             exact_name_match: false,
                             type_match: None,
                             is_local: false,
-                            is_item_from_trait: false,
-                            is_item_from_notable_trait: true,
+                            trait_: Some(
+                                CompletionRelevanceTraitInfo {
+                                    notable_trait: true,
+                                    is_op_method: false,
+                                },
+                            ),
                             is_name_already_imported: false,
                             requires_import: false,
-                            is_op_method: false,
                             is_private_editable: false,
                             postfix_match: None,
-                            is_definite: false,
                             function: None,
                         },
                     },
diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs
index 74092b5..a859d79 100644
--- a/crates/ide-completion/src/render/function.rs
+++ b/crates/ide-completion/src/render/function.rs
@@ -7,10 +7,12 @@
 use syntax::{format_smolstr, AstNode, Edition, SmolStr, ToSmolStr};
 
 use crate::{
-    context::{CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind},
+    context::{
+        CompleteSemicolon, CompletionContext, DotAccess, DotAccessKind, PathCompletionCtx, PathKind,
+    },
     item::{
         Builder, CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevanceFn,
-        CompletionRelevanceReturnType,
+        CompletionRelevanceReturnType, CompletionRelevanceTraitInfo,
     },
     render::{
         compute_exact_name_match, compute_ref_match, compute_type_match, match_types, RenderContext,
@@ -88,11 +90,13 @@
     let ret_type = func.ret_type(db);
     let assoc_item = func.as_assoc_item(db);
 
-    let trait_ = assoc_item.and_then(|trait_| trait_.container_or_implemented_trait(db));
-    let is_op_method = trait_.map_or(false, |trait_| completion.is_ops_trait(trait_));
-
-    let is_item_from_notable_trait =
-        trait_.map_or(false, |trait_| completion.is_doc_notable_trait(trait_));
+    let trait_info =
+        assoc_item.and_then(|trait_| trait_.container_or_implemented_trait(db)).map(|trait_| {
+            CompletionRelevanceTraitInfo {
+                notable_trait: completion.is_doc_notable_trait(trait_),
+                is_op_method: completion.is_ops_trait(trait_),
+            }
+        });
 
     let (has_dot_receiver, has_call_parens, cap) = match func_kind {
         FuncKind::Function(&PathCompletionCtx {
@@ -129,8 +133,7 @@
         },
         exact_name_match: compute_exact_name_match(completion, &call),
         function,
-        is_op_method,
-        is_item_from_notable_trait,
+        trait_: trait_info,
         ..ctx.completion_relevance()
     });
 
@@ -159,7 +162,16 @@
         .lookup_by(name.unescaped().display(db).to_smolstr());
 
     if let Some((cap, (self_param, params))) = complete_call_parens {
-        add_call_parens(&mut item, completion, cap, call, escaped_call, self_param, params);
+        add_call_parens(
+            &mut item,
+            completion,
+            cap,
+            call,
+            escaped_call,
+            self_param,
+            params,
+            &ret_type,
+        );
     }
 
     match ctx.import_to_add {
@@ -216,10 +228,11 @@
     escaped_name: SmolStr,
     self_param: Option<hir::SelfParam>,
     params: Vec<hir::Param>,
+    ret_type: &hir::Type,
 ) -> &'b mut Builder {
     cov_mark::hit!(inserts_parens_for_function_calls);
 
-    let (snippet, label_suffix) = if self_param.is_none() && params.is_empty() {
+    let (mut snippet, label_suffix) = if self_param.is_none() && params.is_empty() {
         (format!("{escaped_name}()$0"), "()")
     } else {
         builder.trigger_call_info();
@@ -264,6 +277,24 @@
 
         (snippet, "(…)")
     };
+    if ret_type.is_unit() {
+        match ctx.complete_semicolon {
+            CompleteSemicolon::DoNotComplete => {}
+            CompleteSemicolon::CompleteSemi | CompleteSemicolon::CompleteComma => {
+                cov_mark::hit!(complete_semicolon);
+                let ch = if matches!(ctx.complete_semicolon, CompleteSemicolon::CompleteComma) {
+                    ','
+                } else {
+                    ';'
+                };
+                if snippet.ends_with("$0") {
+                    snippet.insert(snippet.len() - "$0".len(), ch);
+                } else {
+                    snippet.push(ch);
+                }
+            }
+        }
+    }
     builder.label(SmolStr::from_iter([&name, label_suffix])).insert_snippet(cap, snippet)
 }
 
@@ -392,7 +423,7 @@
 "#,
             r#"
 fn no_args() {}
-fn main() { no_args()$0 }
+fn main() { no_args();$0 }
 "#,
         );
 
@@ -404,7 +435,7 @@
 "#,
             r#"
 fn with_args(x: i32, y: String) {}
-fn main() { with_args(${1:x}, ${2:y})$0 }
+fn main() { with_args(${1:x}, ${2:y});$0 }
 "#,
         );
 
@@ -413,14 +444,14 @@
             r#"
 struct S;
 impl S {
-    fn foo(&self) {}
+    fn foo(&self) -> i32 { 0 }
 }
 fn bar(s: &S) { s.f$0 }
 "#,
             r#"
 struct S;
 impl S {
-    fn foo(&self) {}
+    fn foo(&self) -> i32 { 0 }
 }
 fn bar(s: &S) { s.foo()$0 }
 "#,
@@ -443,7 +474,7 @@
     fn foo(&self, x: i32) {}
 }
 fn bar(s: &S) {
-    s.foo(${1:x})$0
+    s.foo(${1:x});$0
 }
 "#,
         );
@@ -462,7 +493,7 @@
 struct S {}
 impl S {
     fn foo(&self, x: i32) {
-        self.foo(${1:x})$0
+        self.foo(${1:x});$0
     }
 }
 "#,
@@ -485,7 +516,7 @@
 impl S {
     fn foo(&self) {}
 }
-fn main() { S::foo(${1:&self})$0 }
+fn main() { S::foo(${1:&self});$0 }
 "#,
         );
     }
@@ -502,7 +533,7 @@
 "#,
             r#"
 fn with_args(x: i32, y: String) {}
-fn main() { with_args($0) }
+fn main() { with_args($0); }
 "#,
         );
     }
@@ -517,7 +548,7 @@
 "#,
             r#"
 fn foo(_foo: i32, ___bar: bool, ho_ge_: String) {}
-fn main() { foo(${1:foo}, ${2:bar}, ${3:ho_ge_})$0 }
+fn main() { foo(${1:foo}, ${2:bar}, ${3:ho_ge_});$0 }
 "#,
         );
     }
@@ -539,7 +570,7 @@
 fn ref_arg(x: &Foo) {}
 fn main() {
     let x = Foo {};
-    ref_arg(${1:&x})$0
+    ref_arg(${1:&x});$0
 }
 "#,
         );
@@ -562,7 +593,7 @@
 fn ref_arg(x: &mut Foo) {}
 fn main() {
     let x = Foo {};
-    ref_arg(${1:&mut x})$0
+    ref_arg(${1:&mut x});$0
 }
 "#,
         );
@@ -595,7 +626,7 @@
 fn main() {
     let x = Foo {};
     let y = Bar {};
-    y.apply_foo(${1:&x})$0
+    y.apply_foo(${1:&x});$0
 }
 "#,
         );
@@ -616,7 +647,7 @@
 fn take_mutably(mut x: &i32) {}
 
 fn main() {
-    take_mutably(${1:x})$0
+    take_mutably(${1:x});$0
 }
 "#,
         );
@@ -649,7 +680,7 @@
 }
 
 fn main() {
-  qux(${1:foo})$0
+  qux(${1:foo});$0
 }
 "#,
         );
@@ -738,4 +769,134 @@
 "#,
         );
     }
+
+    #[test]
+    fn complete_semicolon_for_unit() {
+        cov_mark::check!(complete_semicolon);
+        check_edit(
+            r#"foo"#,
+            r#"
+fn foo() {}
+fn bar() {
+    foo$0
+}
+"#,
+            r#"
+fn foo() {}
+fn bar() {
+    foo();$0
+}
+"#,
+        );
+        check_edit(
+            r#"foo"#,
+            r#"
+fn foo(a: i32) {}
+fn bar() {
+    foo$0
+}
+"#,
+            r#"
+fn foo(a: i32) {}
+fn bar() {
+    foo(${1:a});$0
+}
+"#,
+        );
+        check_edit(
+            r#"foo"#,
+            r#"
+fn foo(a: i32) {}
+fn bar() {
+    foo$0;
+}
+"#,
+            r#"
+fn foo(a: i32) {}
+fn bar() {
+    foo(${1:a})$0;
+}
+"#,
+        );
+        check_edit_with_config(
+            CompletionConfig { add_semicolon_to_unit: false, ..TEST_CONFIG },
+            r#"foo"#,
+            r#"
+fn foo(a: i32) {}
+fn bar() {
+    foo$0
+}
+"#,
+            r#"
+fn foo(a: i32) {}
+fn bar() {
+    foo(${1:a})$0
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn complete_comma_for_unit_match_arm() {
+        cov_mark::check!(complete_semicolon);
+        check_edit(
+            r#"foo"#,
+            r#"
+fn foo() {}
+fn bar() {
+    match Some(false) {
+        v => fo$0
+    }
+}
+"#,
+            r#"
+fn foo() {}
+fn bar() {
+    match Some(false) {
+        v => foo(),$0
+    }
+}
+"#,
+        );
+        check_edit(
+            r#"foo"#,
+            r#"
+fn foo() {}
+fn bar() {
+    match Some(false) {
+        v => fo$0,
+    }
+}
+"#,
+            r#"
+fn foo() {}
+fn bar() {
+    match Some(false) {
+        v => foo()$0,
+    }
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn no_semicolon_in_closure_ret() {
+        check_edit(
+            r#"foo"#,
+            r#"
+fn foo() {}
+fn baz(_: impl FnOnce()) {}
+fn bar() {
+    baz(|| fo$0);
+}
+"#,
+            r#"
+fn foo() {}
+fn baz(_: impl FnOnce()) {}
+fn bar() {
+    baz(|| foo()$0);
+}
+"#,
+        );
+    }
 }
diff --git a/crates/ide-completion/src/tests.rs b/crates/ide-completion/src/tests.rs
index 04ba7e1..9d77d97 100644
--- a/crates/ide-completion/src/tests.rs
+++ b/crates/ide-completion/src/tests.rs
@@ -70,6 +70,7 @@
     term_search_fuel: 200,
     full_function_signatures: false,
     callable: Some(CallableSnippets::FillArguments),
+    add_semicolon_to_unit: true,
     snippet_cap: SnippetCap::new(true),
     insert_use: InsertUseConfig {
         granularity: ImportGranularity::Crate,
diff --git a/crates/ide-completion/src/tests/attribute.rs b/crates/ide-completion/src/tests/attribute.rs
index 351abe9..1bbe097 100644
--- a/crates/ide-completion/src/tests/attribute.rs
+++ b/crates/ide-completion/src/tests/attribute.rs
@@ -26,6 +26,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at no_mangle
@@ -75,6 +76,7 @@
             at cfg(…)
             at cfg_attr(…)
             at deny(…)
+            at expect(…)
             at forbid(…)
             at warn(…)
             kw crate::
@@ -97,6 +99,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at feature(…)
             at forbid(…)
             at must_use
@@ -127,6 +130,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at macro_use
             at must_use
@@ -149,6 +153,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at no_implicit_prelude
@@ -174,6 +179,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at macro_export
             at macro_use
@@ -199,6 +205,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at no_mangle
@@ -222,6 +229,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at macro_use
             at must_use
@@ -246,6 +254,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at no_mangle
@@ -269,6 +278,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at no_mangle
@@ -299,6 +309,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at no_mangle
@@ -326,6 +337,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at no_mangle
@@ -351,6 +363,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at no_mangle
@@ -374,6 +387,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at export_name = "…"
             at forbid(…)
             at global_allocator
@@ -402,6 +416,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at must_use
@@ -427,6 +442,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at no_mangle
@@ -446,6 +462,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at must_use
             at no_mangle
@@ -469,6 +486,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at link
             at must_use
@@ -489,6 +507,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at forbid(…)
             at link
             at must_use
@@ -509,6 +528,7 @@
             at cfg(…)
             at cfg_attr(…)
             at deny(…)
+            at expect(…)
             at forbid(…)
             at non_exhaustive
             at warn(…)
@@ -532,6 +552,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at export_name = "…"
             at forbid(…)
             at ignore = "…"
@@ -572,6 +593,7 @@
             at doc = "…"
             at doc(alias = "…")
             at doc(hidden)
+            at expect(…)
             at export_name = "…"
             at forbid(…)
             at global_allocator
diff --git a/crates/ide-completion/src/tests/flyimport.rs b/crates/ide-completion/src/tests/flyimport.rs
index 8350fdc..0b53206 100644
--- a/crates/ide-completion/src/tests/flyimport.rs
+++ b/crates/ide-completion/src/tests/flyimport.rs
@@ -53,7 +53,7 @@
 use dep::io::stdin;
 
 fn main() {
-    stdin()$0
+    stdin();$0
 }
 "#,
     );
@@ -274,7 +274,7 @@
 use dep::test_mod::TestTrait;
 
 fn main() {
-    dep::test_mod::TestStruct::weird_function()$0
+    dep::test_mod::TestStruct::weird_function();$0
 }
 "#,
     );
@@ -368,7 +368,7 @@
 
 fn main() {
     let test_struct = dep::test_mod::TestStruct {};
-    test_struct.random_method()$0
+    test_struct.random_method();$0
 }
 "#,
     );
@@ -419,7 +419,7 @@
 
 fn main() {
     let t = fundamental::Box(TestStruct);
-    t.some_method()$0
+    t.some_method();$0
 }
 "#,
     );
@@ -466,7 +466,7 @@
 
 fn main() {
     let t = &TestStruct;
-    t.some_method()$0
+    t.some_method();$0
 }
 "#,
     );
@@ -507,7 +507,7 @@
 use foo::{NotInScope, Wrapper};
 
 fn completion<T: Wrapper>(whatever: T) {
-    whatever.inner().not_in_scope()$0
+    whatever.inner().not_in_scope();$0
 }
 "#,
     );
@@ -579,7 +579,7 @@
 use dep::test_mod::TestTrait;
 
 fn main() {
-    dep::test_mod::TestAlias::random_method()$0
+    dep::test_mod::TestAlias::random_method();$0
 }
 "#,
     );
@@ -702,7 +702,7 @@
 use dep::test_mod::TestTrait;
 
 fn main() {
-    dep::test_mod::TestStruct::another_function()$0
+    dep::test_mod::TestStruct::another_function();$0
 }
 "#,
     );
diff --git a/crates/ide-completion/src/tests/item_list.rs b/crates/ide-completion/src/tests/item_list.rs
index 8aad7bf..532d492 100644
--- a/crates/ide-completion/src/tests/item_list.rs
+++ b/crates/ide-completion/src/tests/item_list.rs
@@ -313,6 +313,7 @@
             ct const CONST1: () =
             fn async fn function2()
             fn fn function1()
+            fn fn function2()
             ma makro!(…)            macro_rules! makro
             md module
             ta type Type1 =
diff --git a/crates/ide-completion/src/tests/pattern.rs b/crates/ide-completion/src/tests/pattern.rs
index 6a0b67e..bd3e7c7 100644
--- a/crates/ide-completion/src/tests/pattern.rs
+++ b/crates/ide-completion/src/tests/pattern.rs
@@ -198,6 +198,7 @@
             st Unit
             bn Record {…} Record { field$1 }$0
             bn Tuple(…)   Tuple($1)$0
+            bn tuple
             kw mut
             kw ref
         "#]],
@@ -850,3 +851,75 @@
 "#,
     );
 }
+
+#[test]
+fn suggest_name_for_pattern() {
+    check_edit(
+        "s1",
+        r#"
+struct S1;
+
+fn foo() {
+    let $0 = S1;
+}
+"#,
+        r#"
+struct S1;
+
+fn foo() {
+    let s1 = S1;
+}
+"#,
+    );
+
+    check_edit(
+        "s1",
+        r#"
+struct S1;
+
+fn foo(s$0: S1) {
+}
+"#,
+        r#"
+struct S1;
+
+fn foo(s1: S1) {
+}
+"#,
+    );
+
+    // Tests for &adt
+    check_edit(
+        "s1",
+        r#"
+struct S1;
+
+fn foo() {
+    let $0 = &S1;
+}
+"#,
+        r#"
+struct S1;
+
+fn foo() {
+    let s1 = &S1;
+}
+"#,
+    );
+
+    // Do not suggest reserved keywords
+    check_empty(
+        r#"
+struct Struct;
+
+fn foo() {
+    let $0 = Struct;
+}
+"#,
+        expect![[r#"
+            st Struct
+            kw mut
+            kw ref
+        "#]],
+    );
+}
diff --git a/crates/ide-completion/src/tests/raw_identifiers.rs b/crates/ide-completion/src/tests/raw_identifiers.rs
index bc63018..d81b3d6 100644
--- a/crates/ide-completion/src/tests/raw_identifiers.rs
+++ b/crates/ide-completion/src/tests/raw_identifiers.rs
@@ -30,7 +30,7 @@
 "#,
         expect![[r#"
             fn foo() {
-                a::dyn()$0
+                a::dyn();$0
         "#]],
     );
 
@@ -45,7 +45,7 @@
 "#,
         expect![[r#"
             fn foo() {
-                a::dyn()$0
+                a::dyn();$0
         "#]],
     );
 }
@@ -63,7 +63,7 @@
 "#,
         expect![[r#"
             fn foo() {
-                a::r#dyn()$0
+                a::r#dyn();$0
         "#]],
     );
 
@@ -78,7 +78,7 @@
 "#,
         expect![[r#"
             fn foo() {
-                a::r#dyn()$0
+                a::r#dyn();$0
         "#]],
     );
 }
diff --git a/crates/ide-completion/src/tests/special.rs b/crates/ide-completion/src/tests/special.rs
index 2ae7d37..508f624 100644
--- a/crates/ide-completion/src/tests/special.rs
+++ b/crates/ide-completion/src/tests/special.rs
@@ -63,7 +63,7 @@
 "#,
         r#"
 fn main() {
-    _alpha()$0
+    _alpha();$0
 }
 fn _alpha() {}
 "#,
diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs
index 5d4b199..099f26e 100644
--- a/crates/ide-db/src/defs.rs
+++ b/crates/ide-db/src/defs.rs
@@ -10,8 +10,8 @@
 use hir::{
     Adt, AsAssocItem, AsExternAssocItem, AssocItem, AttributeTemplate, BuiltinAttr, BuiltinType,
     Const, Crate, DefWithBody, DeriveHelper, DocLinkDef, ExternAssocItem, ExternCrateDecl, Field,
-    Function, GenericParam, HasVisibility, HirDisplay, Impl, Label, Local, Macro, Module,
-    ModuleDef, Name, PathResolution, Semantics, Static, StaticLifetime, ToolModule, Trait,
+    Function, GenericParam, HasVisibility, HirDisplay, Impl, InlineAsmOperand, Label, Local, Macro,
+    Module, ModuleDef, Name, PathResolution, Semantics, Static, StaticLifetime, ToolModule, Trait,
     TraitAlias, TupleField, TypeAlias, Variant, VariantDef, Visibility,
 };
 use span::Edition;
@@ -50,6 +50,8 @@
     BuiltinAttr(BuiltinAttr),
     ToolModule(ToolModule),
     ExternCrateDecl(ExternCrateDecl),
+    InlineAsmRegOrRegClass(()),
+    InlineAsmOperand(InlineAsmOperand),
 }
 
 impl Definition {
@@ -83,11 +85,13 @@
             Definition::Label(it) => it.module(db),
             Definition::ExternCrateDecl(it) => it.module(db),
             Definition::DeriveHelper(it) => it.derive().module(db),
+            Definition::InlineAsmOperand(it) => it.parent(db).module(db),
             Definition::BuiltinAttr(_)
             | Definition::BuiltinType(_)
             | Definition::BuiltinLifetime(_)
             | Definition::TupleField(_)
-            | Definition::ToolModule(_) => return None,
+            | Definition::ToolModule(_)
+            | Definition::InlineAsmRegOrRegClass(_) => return None,
         };
         Some(module)
     }
@@ -121,7 +125,9 @@
             | Definition::Local(_)
             | Definition::GenericParam(_)
             | Definition::Label(_)
-            | Definition::DeriveHelper(_) => return None,
+            | Definition::DeriveHelper(_)
+            | Definition::InlineAsmRegOrRegClass(_)
+            | Definition::InlineAsmOperand(_) => return None,
         };
         Some(vis)
     }
@@ -150,6 +156,8 @@
             Definition::ToolModule(_) => return None,  // FIXME
             Definition::DeriveHelper(it) => it.name(db),
             Definition::ExternCrateDecl(it) => return it.alias_or_name(db),
+            Definition::InlineAsmRegOrRegClass(_) => return None,
+            Definition::InlineAsmOperand(op) => return op.name(db),
         };
         Some(name)
     }
@@ -212,6 +220,7 @@
             Definition::ToolModule(_) => None,
             Definition::DeriveHelper(_) => None,
             Definition::TupleField(_) => None,
+            Definition::InlineAsmRegOrRegClass(_) | Definition::InlineAsmOperand(_) => None,
         };
 
         docs.or_else(|| {
@@ -268,6 +277,9 @@
             Definition::DeriveHelper(it) => {
                 format!("derive_helper {}", it.name(db).display(db, edition))
             }
+            // FIXME
+            Definition::InlineAsmRegOrRegClass(_) => "inline_asm_reg_or_reg_class".to_owned(),
+            Definition::InlineAsmOperand(_) => "inline_asm_reg_operand".to_owned(),
         }
     }
 }
@@ -429,7 +441,6 @@
         let _p = tracing::info_span!("NameClass::classify").entered();
 
         let parent = name.syntax().parent()?;
-
         let definition = match_ast! {
             match parent {
                 ast::Item(it) => classify_item(sema, it)?,
@@ -440,6 +451,7 @@
                 ast::Variant(it) => Definition::Variant(sema.to_def(&it)?),
                 ast::TypeParam(it) => Definition::GenericParam(sema.to_def(&it)?.into()),
                 ast::ConstParam(it) => Definition::GenericParam(sema.to_def(&it)?.into()),
+                ast::AsmOperandNamed(it) => Definition::InlineAsmOperand(sema.to_def(&it)?),
                 _ => return None,
             }
         };
@@ -699,6 +711,9 @@
                         NameRefClass::ExternCrateShorthand { krate, decl: extern_crate }
                     })
                 },
+                ast::AsmRegSpec(_) => {
+                    Some(NameRefClass::Definition(Definition::InlineAsmRegOrRegClass(())))
+                },
                 _ => None
             }
         }
@@ -753,6 +768,18 @@
     }
 }
 
+impl From<InlineAsmOperand> for Definition {
+    fn from(value: InlineAsmOperand) -> Self {
+        Definition::InlineAsmOperand(value)
+    }
+}
+
+impl From<Either<PathResolution, InlineAsmOperand>> for Definition {
+    fn from(value: Either<PathResolution, InlineAsmOperand>) -> Self {
+        value.either(Definition::from, Definition::from)
+    }
+}
+
 impl AsAssocItem for Definition {
     fn as_assoc_item(self, db: &dyn hir::db::HirDatabase) -> Option<AssocItem> {
         match self {
diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs
index 3cf2998..a45ff9a 100644
--- a/crates/ide-db/src/lib.rs
+++ b/crates/ide-db/src/lib.rs
@@ -36,8 +36,9 @@
 pub mod syntax_helpers {
     pub mod format_string;
     pub mod format_string_exprs;
-    pub mod insert_whitespace_into_node;
+    pub use hir::prettify_macro_expansion;
     pub mod node_ext;
+    pub mod suggest_name;
 
     pub use parser::LexedStr;
 }
@@ -223,6 +224,7 @@
     Function,
     Method,
     Impl,
+    InlineAsmRegOrRegClass,
     Label,
     LifetimeParam,
     Local,
diff --git a/crates/ide-db/src/rename.rs b/crates/ide-db/src/rename.rs
index 262eefe..f1404ed 100644
--- a/crates/ide-db/src/rename.rs
+++ b/crates/ide-db/src/rename.rs
@@ -200,12 +200,14 @@
                         .and_then(syn_ctx_is_root)
                 }
             }
+            Definition::InlineAsmOperand(it) => name_range(it, sema).and_then(syn_ctx_is_root),
             Definition::BuiltinType(_)
             | Definition::BuiltinLifetime(_)
             | Definition::BuiltinAttr(_)
             | Definition::SelfType(_)
             | Definition::ToolModule(_)
-            | Definition::TupleField(_) => return None,
+            | Definition::TupleField(_)
+            | Definition::InlineAsmRegOrRegClass(_) => return None,
             // FIXME: This should be doable in theory
             Definition::DeriveHelper(_) => return None,
         };
diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs
index 12ce5a4..4166b08 100644
--- a/crates/ide-db/src/search.rs
+++ b/crates/ide-db/src/search.rs
@@ -8,17 +8,18 @@
 use std::{cell::LazyCell, cmp::Reverse};
 
 use base_db::{salsa::Database, SourceDatabase, SourceRootDatabase};
+use either::Either;
 use hir::{
     sym, Adt, AsAssocItem, DefWithBody, FileRange, FileRangeWrapper, HasAttrs, HasContainer,
-    HasSource, HirFileIdExt, InFile, InFileWrapper, InRealFile, ItemContainer, ModuleSource,
-    PathResolution, Semantics, Visibility,
+    HasSource, HirFileIdExt, InFile, InFileWrapper, InRealFile, InlineAsmOperand, ItemContainer,
+    ModuleSource, PathResolution, Semantics, Visibility,
 };
 use memchr::memmem::Finder;
 use parser::SyntaxKind;
 use rustc_hash::{FxHashMap, FxHashSet};
 use span::EditionedFileId;
 use syntax::{
-    ast::{self, HasName},
+    ast::{self, HasName, Rename},
     match_ast, AstNode, AstToken, SmolStr, SyntaxElement, SyntaxNode, TextRange, TextSize,
     ToSmolStr,
 };
@@ -318,6 +319,23 @@
             };
         }
 
+        if let Definition::InlineAsmOperand(op) = self {
+            let def = match op.parent(db) {
+                DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()),
+                DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()),
+                DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()),
+                DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()),
+                // FIXME: implement
+                DefWithBody::InTypeConst(_) => return SearchScope::empty(),
+            };
+            return match def {
+                Some(def) => SearchScope::file_range(
+                    def.as_ref().original_file_range_with_macro_call_body(db),
+                ),
+                None => SearchScope::single_file(file_id),
+            };
+        }
+
         if let Definition::SelfType(impl_) = self {
             return match impl_.source(db).map(|src| src.syntax().cloned()) {
                 Some(def) => SearchScope::file_range(
@@ -387,6 +405,7 @@
     pub fn usages<'a>(self, sema: &'a Semantics<'_, RootDatabase>) -> FindUsages<'a> {
         FindUsages {
             def: self,
+            rename: None,
             assoc_item_container: self.as_assoc_item(sema.db).map(|a| a.container(sema.db)),
             sema,
             scope: None,
@@ -399,6 +418,7 @@
 #[derive(Clone)]
 pub struct FindUsages<'a> {
     def: Definition,
+    rename: Option<&'a Rename>,
     sema: &'a Semantics<'a, RootDatabase>,
     scope: Option<&'a SearchScope>,
     /// The container of our definition should it be an assoc item
@@ -429,6 +449,14 @@
         self
     }
 
+    // FIXME: This is just a temporary fix for not handling import aliases like
+    // `use Foo as Bar`. We need to support them in a proper way.
+    // See issue #14079
+    pub fn with_rename(mut self, rename: Option<&'a Rename>) -> Self {
+        self.rename = rename;
+        self
+    }
+
     pub fn at_least_one(&self) -> bool {
         let mut found = false;
         self.search(&mut |_, _| {
@@ -866,9 +894,16 @@
             }
         };
 
-        let name = match self.def {
+        let name = match (self.rename, self.def) {
+            (Some(rename), _) => {
+                if rename.underscore_token().is_some() {
+                    None
+                } else {
+                    rename.name().map(|n| n.to_smolstr())
+                }
+            }
             // special case crate modules as these do not have a proper name
-            Definition::Module(module) if module.is_crate_root() => {
+            (_, Definition::Module(module)) if module.is_crate_root() => {
                 // FIXME: This assumes the crate name is always equal to its display name when it
                 // really isn't
                 // we should instead look at the dependency edge name and recursively search our way
@@ -908,7 +943,6 @@
         let finder = &Finder::new(name);
         let include_self_kw_refs =
             self.include_self_kw_refs.as_ref().map(|ty| (ty, Finder::new("Self")));
-
         for (text, file_id, search_range) in Self::scope_files(sema.db, &search_scope) {
             self.sema.db.unwind_if_cancelled();
             let tree = LazyCell::new(move || sema.parse(file_id).syntax().clone());
@@ -917,7 +951,7 @@
             for offset in Self::match_indices(&text, finder, search_range) {
                 tree.token_at_offset(offset).for_each(|token| {
                     let Some(str_token) = ast::String::cast(token.clone()) else { return };
-                    if let Some((range, nameres)) =
+                    if let Some((range, Some(nameres))) =
                         sema.check_for_format_args_template(token, offset)
                     {
                         if self.found_format_args_ref(file_id, range, str_token, nameres, sink) {}
@@ -1087,19 +1121,19 @@
         file_id: EditionedFileId,
         range: TextRange,
         token: ast::String,
-        res: Option<PathResolution>,
+        res: Either<PathResolution, InlineAsmOperand>,
         sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
     ) -> bool {
-        match res.map(Definition::from) {
-            Some(def) if def == self.def => {
-                let reference = FileReference {
-                    range,
-                    name: FileReferenceNode::FormatStringEntry(token, range),
-                    category: ReferenceCategory::READ,
-                };
-                sink(file_id, reference)
-            }
-            _ => false,
+        let def = res.either(Definition::from, Definition::from);
+        if def == self.def {
+            let reference = FileReference {
+                range,
+                name: FileReferenceNode::FormatStringEntry(token, range),
+                category: ReferenceCategory::READ,
+            };
+            sink(file_id, reference)
+        } else {
+            false
         }
     }
 
diff --git a/crates/ide-db/src/source_change.rs b/crates/ide-db/src/source_change.rs
index a83f847..73073e9 100644
--- a/crates/ide-db/src/source_change.rs
+++ b/crates/ide-db/src/source_change.rs
@@ -9,10 +9,13 @@
 use base_db::AnchoredPathBuf;
 use itertools::Itertools;
 use nohash_hasher::IntMap;
+use rustc_hash::FxHashMap;
 use span::FileId;
 use stdx::never;
 use syntax::{
-    algo, AstNode, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextSize,
+    algo,
+    syntax_editor::{SyntaxAnnotation, SyntaxEditor},
+    AstNode, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange, TextSize,
 };
 use text_edit::{TextEdit, TextEditBuilder};
 
@@ -197,6 +200,11 @@
     pub source_change: SourceChange,
     pub command: Option<Command>,
 
+    /// Keeps track of all edits performed on each file
+    pub file_editors: FxHashMap<FileId, SyntaxEditor>,
+    /// Keeps track of which annotations correspond to which snippets
+    pub snippet_annotations: Vec<(AnnotationSnippet, SyntaxAnnotation)>,
+
     /// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin.
     pub mutated_tree: Option<TreeMutator>,
     /// Keeps track of where to place snippets
@@ -238,6 +246,8 @@
             file_id: file_id.into(),
             source_change: SourceChange::default(),
             command: None,
+            file_editors: FxHashMap::default(),
+            snippet_annotations: vec![],
             mutated_tree: None,
             snippet_builder: None,
         }
@@ -248,7 +258,75 @@
         self.file_id = file_id.into();
     }
 
+    pub fn make_editor(&self, node: &SyntaxNode) -> SyntaxEditor {
+        SyntaxEditor::new(node.ancestors().last().unwrap_or_else(|| node.clone()))
+    }
+
+    pub fn add_file_edits(&mut self, file_id: impl Into<FileId>, edit: SyntaxEditor) {
+        match self.file_editors.entry(file_id.into()) {
+            Entry::Occupied(mut entry) => entry.get_mut().merge(edit),
+            Entry::Vacant(entry) => {
+                entry.insert(edit);
+            }
+        }
+    }
+
+    pub fn make_placeholder_snippet(&mut self, _cap: SnippetCap) -> SyntaxAnnotation {
+        self.add_snippet_annotation(AnnotationSnippet::Over)
+    }
+
+    pub fn make_tabstop_before(&mut self, _cap: SnippetCap) -> SyntaxAnnotation {
+        self.add_snippet_annotation(AnnotationSnippet::Before)
+    }
+
+    pub fn make_tabstop_after(&mut self, _cap: SnippetCap) -> SyntaxAnnotation {
+        self.add_snippet_annotation(AnnotationSnippet::After)
+    }
+
     fn commit(&mut self) {
+        // Apply syntax editor edits
+        for (file_id, editor) in mem::take(&mut self.file_editors) {
+            let edit_result = editor.finish();
+            let mut snippet_edit = vec![];
+
+            // Find snippet edits
+            for (kind, annotation) in &self.snippet_annotations {
+                let elements = edit_result.find_annotation(*annotation);
+
+                let snippet = match (kind, elements) {
+                    (AnnotationSnippet::Before, [element]) => {
+                        Snippet::Tabstop(element.text_range().start())
+                    }
+                    (AnnotationSnippet::After, [element]) => {
+                        Snippet::Tabstop(element.text_range().end())
+                    }
+                    (AnnotationSnippet::Over, [element]) => {
+                        Snippet::Placeholder(element.text_range())
+                    }
+                    (AnnotationSnippet::Over, elements) if !elements.is_empty() => {
+                        Snippet::PlaceholderGroup(
+                            elements.iter().map(|it| it.text_range()).collect(),
+                        )
+                    }
+                    _ => continue,
+                };
+
+                snippet_edit.push(snippet);
+            }
+
+            let mut edit = TextEdit::builder();
+            algo::diff(edit_result.old_root(), edit_result.new_root()).into_text_edit(&mut edit);
+            let edit = edit.finish();
+
+            let snippet_edit =
+                if !snippet_edit.is_empty() { Some(SnippetEdit::new(snippet_edit)) } else { None };
+
+            if !edit.is_empty() || snippet_edit.is_some() {
+                self.source_change.insert_source_and_snippet_edit(file_id, edit, snippet_edit);
+            }
+        }
+
+        // Apply mutable edits
         let snippet_edit = self.snippet_builder.take().map(|builder| {
             SnippetEdit::new(
                 builder.places.into_iter().flat_map(PlaceSnippet::finalize_position).collect(),
@@ -369,6 +447,13 @@
         self.source_change.is_snippet = true;
     }
 
+    fn add_snippet_annotation(&mut self, kind: AnnotationSnippet) -> SyntaxAnnotation {
+        let annotation = SyntaxAnnotation::new();
+        self.snippet_annotations.push((kind, annotation));
+        self.source_change.is_snippet = true;
+        annotation
+    }
+
     pub fn finish(mut self) -> SourceChange {
         self.commit();
 
@@ -416,6 +501,15 @@
     PlaceholderGroup(Vec<TextRange>),
 }
 
+pub enum AnnotationSnippet {
+    /// Place a tabstop before an element
+    Before,
+    /// Place a tabstop before an element
+    After,
+    /// Place a placeholder snippet in place of the element(s)
+    Over,
+}
+
 enum PlaceSnippet {
     /// Place a tabstop before an element
     Before(SyntaxElement),
diff --git a/crates/ide-assists/src/utils/suggest_name.rs b/crates/ide-db/src/syntax_helpers/suggest_name.rs
similarity index 69%
rename from crates/ide-assists/src/utils/suggest_name.rs
rename to crates/ide-db/src/syntax_helpers/suggest_name.rs
index 3130ef0..2679cbe 100644
--- a/crates/ide-assists/src/utils/suggest_name.rs
+++ b/crates/ide-db/src/syntax_helpers/suggest_name.rs
@@ -1,14 +1,18 @@
 //! This module contains functions to suggest names for expressions, functions and other items
 
+use std::{collections::hash_map::Entry, str::FromStr};
+
 use hir::Semantics;
-use ide_db::{FxHashSet, RootDatabase};
 use itertools::Itertools;
+use rustc_hash::FxHashMap;
 use stdx::to_lower_snake_case;
 use syntax::{
     ast::{self, HasName},
-    match_ast, AstNode, Edition, SmolStr,
+    match_ast, AstNode, Edition, SmolStr, SmolStrBuilder,
 };
 
+use crate::RootDatabase;
+
 /// Trait names, that will be ignored when in `impl Trait` and `dyn Trait`
 const USELESS_TRAITS: &[&str] = &["Send", "Sync", "Copy", "Clone", "Eq", "PartialEq"];
 
@@ -16,7 +20,9 @@
 ///
 /// **NOTE**: they all must be snake lower case
 const USELESS_NAMES: &[&str] =
-    &["new", "default", "option", "some", "none", "ok", "err", "str", "string"];
+    &["new", "default", "option", "some", "none", "ok", "err", "str", "string", "from", "into"];
+
+const USELESS_NAME_PREFIXES: &[&str] = &["from_", "with_", "into_"];
 
 /// Generic types replaced by their first argument
 ///
@@ -58,59 +64,131 @@
     "into_future",
 ];
 
-/// Suggest a unique name for generic parameter.
+/// Generator for new names
 ///
-/// `existing_params` is used to check if the name conflicts with existing
-/// generic parameters.
+/// The generator keeps track of existing names and suggests new names that do
+/// not conflict with existing names.
 ///
-/// The function checks if the name conflicts with existing generic parameters.
-/// If so, it will try to resolve the conflict by adding a number suffix, e.g.
-/// `T`, `T0`, `T1`, ...
-pub(crate) fn for_unique_generic_name(
-    name: &str,
-    existing_params: &ast::GenericParamList,
-) -> SmolStr {
-    let param_names = existing_params
-        .generic_params()
-        .map(|param| match param {
-            ast::GenericParam::TypeParam(t) => t.name().unwrap().to_string(),
-            p => p.to_string(),
-        })
-        .collect::<FxHashSet<_>>();
-    let mut name = name.to_owned();
-    let base_len = name.len();
-    let mut count = 0;
-    while param_names.contains(&name) {
-        name.truncate(base_len);
-        name.push_str(&count.to_string());
-        count += 1;
-    }
-
-    name.into()
+/// The generator will try to resolve conflicts by adding a numeric suffix to
+/// the name, e.g. `a`, `a1`, `a2`, ...
+///
+/// # Examples
+/// ```rust
+/// let mut generator = NameGenerator::new();
+/// assert_eq!(generator.suggest_name("a"), "a");
+/// assert_eq!(generator.suggest_name("a"), "a1");
+///
+/// assert_eq!(generator.suggest_name("b2"), "b2");
+/// assert_eq!(generator.suggest_name("b"), "b3");
+/// ```
+#[derive(Debug, Default)]
+pub struct NameGenerator {
+    pool: FxHashMap<SmolStr, usize>,
 }
 
-/// Suggest name of impl trait type
-///
-/// `existing_params` is used to check if the name conflicts with existing
-/// generic parameters.
-///
-/// # Current implementation
-///
-/// In current implementation, the function tries to get the name from the first
-/// character of the name for the first type bound.
-///
-/// If the name conflicts with existing generic parameters, it will try to
-/// resolve the conflict with `for_unique_generic_name`.
-pub(crate) fn for_impl_trait_as_generic(
-    ty: &ast::ImplTraitType,
-    existing_params: &ast::GenericParamList,
-) -> SmolStr {
-    let c = ty
-        .type_bound_list()
-        .and_then(|bounds| bounds.syntax().text().char_at(0.into()))
-        .unwrap_or('T');
+impl NameGenerator {
+    /// Create a new empty generator
+    pub fn new() -> Self {
+        Self { pool: FxHashMap::default() }
+    }
 
-    for_unique_generic_name(c.encode_utf8(&mut [0; 4]), existing_params)
+    /// Create a new generator with existing names. When suggesting a name, it will
+    /// avoid conflicts with existing names.
+    pub fn new_with_names<'a>(existing_names: impl Iterator<Item = &'a str>) -> Self {
+        let mut generator = Self::new();
+        existing_names.for_each(|name| generator.insert(name));
+        generator
+    }
+
+    /// Suggest a name without conflicts. If the name conflicts with existing names,
+    /// it will try to resolve the conflict by adding a numeric suffix.
+    pub fn suggest_name(&mut self, name: &str) -> SmolStr {
+        let (prefix, suffix) = Self::split_numeric_suffix(name);
+        let prefix = SmolStr::new(prefix);
+        let suffix = suffix.unwrap_or(0);
+
+        match self.pool.entry(prefix.clone()) {
+            Entry::Vacant(entry) => {
+                entry.insert(suffix);
+                SmolStr::from_str(name).unwrap()
+            }
+            Entry::Occupied(mut entry) => {
+                let count = entry.get_mut();
+                *count = (*count + 1).max(suffix);
+
+                let mut new_name = SmolStrBuilder::new();
+                new_name.push_str(&prefix);
+                new_name.push_str(count.to_string().as_str());
+                new_name.finish()
+            }
+        }
+    }
+
+    /// Suggest a name for given type.
+    ///
+    /// The function will strip references first, and suggest name from the inner type.
+    ///
+    /// - If `ty` is an ADT, it will suggest the name of the ADT.
+    ///   + If `ty` is wrapped in `Box`, `Option` or `Result`, it will suggest the name from the inner type.
+    /// - If `ty` is a trait, it will suggest the name of the trait.
+    /// - If `ty` is an `impl Trait`, it will suggest the name of the first trait.
+    ///
+    /// If the suggested name conflicts with reserved keywords, it will return `None`.
+    pub fn for_type(
+        &mut self,
+        ty: &hir::Type,
+        db: &RootDatabase,
+        edition: Edition,
+    ) -> Option<SmolStr> {
+        let name = name_of_type(ty, db, edition)?;
+        Some(self.suggest_name(&name))
+    }
+
+    /// Suggest name of impl trait type
+    ///
+    /// # Current implementation
+    ///
+    /// In current implementation, the function tries to get the name from the first
+    /// character of the name for the first type bound.
+    ///
+    /// If the name conflicts with existing generic parameters, it will try to
+    /// resolve the conflict with `for_unique_generic_name`.
+    pub fn for_impl_trait_as_generic(&mut self, ty: &ast::ImplTraitType) -> SmolStr {
+        let c = ty
+            .type_bound_list()
+            .and_then(|bounds| bounds.syntax().text().char_at(0.into()))
+            .unwrap_or('T');
+
+        self.suggest_name(&c.to_string())
+    }
+
+    /// Insert a name into the pool
+    fn insert(&mut self, name: &str) {
+        let (prefix, suffix) = Self::split_numeric_suffix(name);
+        let prefix = SmolStr::new(prefix);
+        let suffix = suffix.unwrap_or(0);
+
+        match self.pool.entry(prefix) {
+            Entry::Vacant(entry) => {
+                entry.insert(suffix);
+            }
+            Entry::Occupied(mut entry) => {
+                let count = entry.get_mut();
+                *count = (*count).max(suffix);
+            }
+        }
+    }
+
+    /// Remove the numeric suffix from the name
+    ///
+    /// # Examples
+    /// `a1b2c3` -> `a1b2c`
+    fn split_numeric_suffix(name: &str) -> (&str, Option<usize>) {
+        let pos =
+            name.rfind(|c: char| !c.is_numeric()).expect("Name cannot be empty or all-numeric");
+        let (prefix, suffix) = name.split_at(pos + 1);
+        (prefix, suffix.parse().ok())
+    }
 }
 
 /// Suggest name of variable for given expression
@@ -132,7 +210,7 @@
 ///
 /// Currently it sticks to the first name found.
 // FIXME: Microoptimize and return a `SmolStr` here.
-pub(crate) fn for_variable(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> String {
+pub fn for_variable(expr: &ast::Expr, sema: &Semantics<'_, RootDatabase>) -> String {
     // `from_param` does not benefit from stripping
     // it need the largest context possible
     // so we check firstmost
@@ -175,6 +253,10 @@
         return None;
     }
 
+    if USELESS_NAME_PREFIXES.iter().any(|prefix| name.starts_with(prefix)) {
+        return None;
+    }
+
     if !is_valid_name(&name) {
         return None;
     }
@@ -184,7 +266,7 @@
 
 fn is_valid_name(name: &str) -> bool {
     matches!(
-        ide_db::syntax_helpers::LexedStr::single_token(syntax::Edition::CURRENT_FIXME, name),
+        super::LexedStr::single_token(syntax::Edition::CURRENT_FIXME, name),
         Some((syntax::SyntaxKind::IDENT, _error))
     )
 }
@@ -818,4 +900,117 @@
             "some_field",
         );
     }
+
+    #[test]
+    fn from_and_to_func() {
+        check(
+            r#"
+//- minicore: from
+struct Foo;
+struct Bar;
+
+impl From<Foo> for Bar {
+    fn from(_: Foo) -> Self {
+        Bar;
+    }
+}
+
+fn f(_: Bar) {}
+
+fn main() {
+    let foo = Foo {};
+    f($0Bar::from(foo)$0);
+}
+"#,
+            "bar",
+        );
+
+        check(
+            r#"
+//- minicore: from
+struct Foo;
+struct Bar;
+
+impl From<Foo> for Bar {
+    fn from(_: Foo) -> Self {
+        Bar;
+    }
+}
+
+fn f(_: Bar) {}
+
+fn main() {
+    let foo = Foo {};
+    f($0Into::<Bar>::into(foo)$0);
+}
+"#,
+            "bar",
+        );
+    }
+
+    #[test]
+    fn useless_name_prefix() {
+        check(
+            r#"
+struct Foo;
+struct Bar;
+
+impl Bar {
+    fn from_foo(_: Foo) -> Self {
+        Foo {}
+    }
+}
+
+fn main() {
+    let foo = Foo {};
+    let _ = $0Bar::from_foo(foo)$0;
+}
+"#,
+            "bar",
+        );
+
+        check(
+            r#"
+struct Foo;
+struct Bar;
+
+impl Bar {
+    fn with_foo(_: Foo) -> Self {
+        Bar {}
+    }
+}
+
+fn main() {
+    let foo = Foo {};
+    let _ = $0Bar::with_foo(foo)$0;
+}
+"#,
+            "bar",
+        );
+    }
+
+    #[test]
+    fn conflicts_with_existing_names() {
+        let mut generator = NameGenerator::new();
+        assert_eq!(generator.suggest_name("a"), "a");
+        assert_eq!(generator.suggest_name("a"), "a1");
+        assert_eq!(generator.suggest_name("a"), "a2");
+        assert_eq!(generator.suggest_name("a"), "a3");
+
+        assert_eq!(generator.suggest_name("b"), "b");
+        assert_eq!(generator.suggest_name("b2"), "b2");
+        assert_eq!(generator.suggest_name("b"), "b3");
+        assert_eq!(generator.suggest_name("b"), "b4");
+        assert_eq!(generator.suggest_name("b3"), "b5");
+
+        // ---------
+        let mut generator = NameGenerator::new_with_names(["a", "b", "b2", "c4"].into_iter());
+        assert_eq!(generator.suggest_name("a"), "a1");
+        assert_eq!(generator.suggest_name("a"), "a2");
+
+        assert_eq!(generator.suggest_name("b"), "b3");
+        assert_eq!(generator.suggest_name("b2"), "b4");
+
+        assert_eq!(generator.suggest_name("c"), "c5");
+    }
 }
diff --git a/crates/ide-diagnostics/src/handlers/incorrect_case.rs b/crates/ide-diagnostics/src/handlers/incorrect_case.rs
index 18a95f0..83a1eb4 100644
--- a/crates/ide-diagnostics/src/handlers/incorrect_case.rs
+++ b/crates/ide-diagnostics/src/handlers/incorrect_case.rs
@@ -370,6 +370,23 @@
     }
 
     #[test]
+    fn external_macro() {
+        check_diagnostics(
+            r#"
+//- /library.rs library crate:library
+#[macro_export]
+macro_rules! trigger_lint {
+    () => { let FOO: () };
+}
+//- /user.rs crate:user deps:library
+fn foo() {
+    library::trigger_lint!();
+}
+    "#,
+        );
+    }
+
+    #[test]
     fn complex_ignore() {
         check_diagnostics(
             r#"
@@ -419,6 +436,64 @@
     }
 
     #[test]
+    fn ignores_no_mangle_items() {
+        cov_mark::check!(extern_func_no_mangle_ignored);
+        check_diagnostics(
+            r#"
+#[no_mangle]
+extern "C" fn NonSnakeCaseName(some_var: u8) -> u8;
+            "#,
+        );
+    }
+
+    #[test]
+    fn ignores_no_mangle_items_with_no_abi() {
+        cov_mark::check!(extern_func_no_mangle_ignored);
+        check_diagnostics(
+            r#"
+#[no_mangle]
+extern fn NonSnakeCaseName(some_var: u8) -> u8;
+            "#,
+        );
+    }
+
+    #[test]
+    fn no_mangle_items_with_rust_abi() {
+        check_diagnostics(
+            r#"
+#[no_mangle]
+extern "Rust" fn NonSnakeCaseName(some_var: u8) -> u8;
+              // ^^^^^^^^^^^^^^^^ 💡 warn: Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
+            "#,
+        );
+    }
+
+    #[test]
+    fn no_mangle_items_non_extern() {
+        check_diagnostics(
+            r#"
+#[no_mangle]
+fn NonSnakeCaseName(some_var: u8) -> u8;
+// ^^^^^^^^^^^^^^^^ 💡 warn: Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
+            "#,
+        );
+    }
+
+    #[test]
+    fn extern_fn_name() {
+        check_diagnostics(
+            r#"
+extern "C" fn NonSnakeCaseName(some_var: u8) -> u8;
+           // ^^^^^^^^^^^^^^^^ 💡 warn: Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
+extern "Rust" fn NonSnakeCaseName(some_var: u8) -> u8;
+              // ^^^^^^^^^^^^^^^^ 💡 warn: Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
+extern fn NonSnakeCaseName(some_var: u8) -> u8;
+       // ^^^^^^^^^^^^^^^^ 💡 warn: Function `NonSnakeCaseName` should have snake_case name, e.g. `non_snake_case_name`
+            "#,
+        );
+    }
+
+    #[test]
     fn ignores_extern_items() {
         cov_mark::check!(extern_func_incorrect_case_ignored);
         cov_mark::check!(extern_static_incorrect_case_ignored);
@@ -593,7 +668,7 @@
 }
 
 mod F {
-  //^ 💡 warn: Module `F` should have snake_case name, e.g. `f`
+  //^ 💡 error: Module `F` should have snake_case name, e.g. `f`
     #![deny(non_snake_case)]
     fn CheckItWorksWithModAttr() {}
      //^^^^^^^^^^^^^^^^^^^^^^^ 💡 error: Function `CheckItWorksWithModAttr` should have snake_case name, e.g. `check_it_works_with_mod_attr`
@@ -856,4 +931,104 @@
 "#,
         );
     }
+
+    #[test]
+    fn override_lint_level() {
+        check_diagnostics(
+            r#"
+#[warn(nonstandard_style)]
+fn foo() {
+    let BAR;
+     // ^^^ 💡 warn: Variable `BAR` should have snake_case name, e.g. `bar`
+    #[allow(non_snake_case)]
+    let FOO;
+}
+
+#[warn(nonstandard_style)]
+fn foo() {
+    let BAR;
+     // ^^^ 💡 warn: Variable `BAR` should have snake_case name, e.g. `bar`
+    #[expect(non_snake_case)]
+    let FOO;
+    #[allow(non_snake_case)]
+    struct qux;
+        // ^^^ 💡 warn: Structure `qux` should have CamelCase name, e.g. `Qux`
+
+    fn BAZ() {
+    // ^^^ 💡 error: Function `BAZ` should have snake_case name, e.g. `baz`
+        #![forbid(bad_style)]
+    }
+}
+        "#,
+        );
+    }
+
+    #[test]
+    fn different_files() {
+        check_diagnostics(
+            r#"
+//- /lib.rs
+#![expect(nonstandard_style)]
+
+mod BAD_CASE;
+
+fn BAD_CASE() {}
+
+//- /BAD_CASE.rs
+mod OtherBadCase;
+ // ^^^^^^^^^^^^ 💡 error: Module `OtherBadCase` should have snake_case name, e.g. `other_bad_case`
+
+//- /BAD_CASE/OtherBadCase.rs
+#![deny(non_snake_case)]
+
+fn FOO() {}
+// ^^^ 💡 error: Function `FOO` should have snake_case name, e.g. `foo`
+
+#[allow(bad_style)]
+mod FINE_WITH_BAD_CASE;
+
+//- /BAD_CASE/OtherBadCase/FINE_WITH_BAD_CASE.rs
+struct QUX;
+const foo: i32 = 0;
+fn BAR() {
+    let BAZ;
+}
+        "#,
+        );
+    }
+
+    #[test]
+    fn cfged_lint_attrs() {
+        check_diagnostics(
+            r#"
+//- /lib.rs cfg:feature=cool_feature
+#[cfg_attr(any(), allow(non_snake_case))]
+fn FOO() {}
+// ^^^ 💡 warn: Function `FOO` should have snake_case name, e.g. `foo`
+
+#[cfg_attr(non_existent, allow(non_snake_case))]
+fn BAR() {}
+// ^^^ 💡 warn: Function `BAR` should have snake_case name, e.g. `bar`
+
+#[cfg_attr(feature = "cool_feature", allow(non_snake_case))]
+fn BAZ() {}
+
+#[cfg_attr(feature = "cool_feature", cfg_attr ( all ( ) , allow ( non_snake_case ) ) ) ]
+fn QUX() {}
+        "#,
+        );
+    }
+
+    #[test]
+    fn allow_with_comment() {
+        check_diagnostics(
+            r#"
+#[allow(
+    // Yo, sup
+    non_snake_case
+)]
+fn foo(_HelloWorld: ()) {}
+        "#,
+        );
+    }
 }
diff --git a/crates/ide-diagnostics/src/handlers/invalid_cast.rs b/crates/ide-diagnostics/src/handlers/invalid_cast.rs
new file mode 100644
index 0000000..ad4baf5
--- /dev/null
+++ b/crates/ide-diagnostics/src/handlers/invalid_cast.rs
@@ -0,0 +1,1114 @@
+use hir::{CastError, ClosureStyle, HirDisplay};
+
+use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext};
+
+macro_rules! format_ty {
+    ($ctx:expr, $fmt:literal, $($arg:expr),* $(,)?) => {{
+        std::format!(
+            $fmt,
+            $(
+                $arg
+                    .display($ctx.sema.db, $ctx.edition)
+                    .with_closure_style(ClosureStyle::ClosureWithId)
+            ),*
+        )
+    }}
+}
+
+// Diagnostic: invalid-cast
+//
+// This diagnostic is triggered if the code contains an illegal cast
+pub(crate) fn invalid_cast(ctx: &DiagnosticsContext<'_>, d: &hir::InvalidCast) -> Diagnostic {
+    let display_range = ctx.sema.diagnostics_display_range(d.expr.map(|it| it.into()));
+    let (code, message) = match d.error {
+        CastError::CastToBool => (
+            DiagnosticCode::RustcHardError("E0054"),
+            format_ty!(ctx, "cannot cast `{}` as `bool`", d.expr_ty),
+        ),
+        CastError::CastToChar => (
+            DiagnosticCode::RustcHardError("E0604"),
+            format_ty!(ctx, "only `u8` can be cast as `char`, not {}", d.expr_ty),
+        ),
+        CastError::DifferingKinds => (
+            DiagnosticCode::RustcHardError("E0606"),
+            format_ty!(
+                ctx,
+                "casting `{}` as `{}` is invalid: vtable kinds may not match",
+                d.expr_ty,
+                d.cast_ty
+            ),
+        ),
+        CastError::SizedUnsizedCast => (
+            DiagnosticCode::RustcHardError("E0607"),
+            format_ty!(
+                ctx,
+                "cannot cast thin pointer `{}` to fat pointer `{}`",
+                d.expr_ty,
+                d.cast_ty
+            ),
+        ),
+        CastError::Unknown | CastError::IllegalCast => (
+            DiagnosticCode::RustcHardError("E0606"),
+            format_ty!(ctx, "casting `{}` as `{}` is invalid", d.expr_ty, d.cast_ty),
+        ),
+        CastError::IntToFatCast => (
+            DiagnosticCode::RustcHardError("E0606"),
+            format_ty!(ctx, "cannot cast `{}` to a fat pointer `{}`", d.expr_ty, d.cast_ty),
+        ),
+        CastError::NeedDeref => (
+            DiagnosticCode::RustcHardError("E0606"),
+            format_ty!(
+                ctx,
+                "casting `{}` as `{}` is invalid: needs defererence or removal of unneeded borrow",
+                d.expr_ty,
+                d.cast_ty
+            ),
+        ),
+        CastError::NeedViaPtr => (
+            DiagnosticCode::RustcHardError("E0606"),
+            format_ty!(
+                ctx,
+                "casting `{}` as `{}` is invalid: needs casting through a raw pointer first",
+                d.expr_ty,
+                d.cast_ty
+            ),
+        ),
+        CastError::NeedViaThinPtr => (
+            DiagnosticCode::RustcHardError("E0606"),
+            format_ty!(
+                ctx,
+                "casting `{}` as `{}` is invalid: needs casting through a thin pointer first",
+                d.expr_ty,
+                d.cast_ty
+            ),
+        ),
+        CastError::NeedViaInt => (
+            DiagnosticCode::RustcHardError("E0606"),
+            format_ty!(
+                ctx,
+                "casting `{}` as `{}` is invalid: needs casting through an integer first",
+                d.expr_ty,
+                d.cast_ty
+            ),
+        ),
+        CastError::NonScalar => (
+            DiagnosticCode::RustcHardError("E0605"),
+            format_ty!(ctx, "non-primitive cast: `{}` as `{}`", d.expr_ty, d.cast_ty),
+        ),
+        CastError::UnknownCastPtrKind | CastError::UnknownExprPtrKind => (
+            DiagnosticCode::RustcHardError("E0641"),
+            "cannot cast to a pointer of an unknown kind".to_owned(),
+        ),
+    };
+    Diagnostic::new(code, message, display_range)
+}
+
+// Diagnostic: cast-to-unsized
+//
+// This diagnostic is triggered when casting to an unsized type
+pub(crate) fn cast_to_unsized(ctx: &DiagnosticsContext<'_>, d: &hir::CastToUnsized) -> Diagnostic {
+    let display_range = ctx.sema.diagnostics_display_range(d.expr.map(|it| it.into()));
+    Diagnostic::new(
+        DiagnosticCode::RustcHardError("E0620"),
+        format_ty!(ctx, "cast to unsized type: `{}`", d.cast_ty),
+        display_range,
+    )
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::tests::{check_diagnostics, check_diagnostics_with_disabled};
+
+    #[test]
+    fn cast_as_bool() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn main() {
+    let u = 5 as bool;
+          //^^^^^^^^^ error: cannot cast `i32` as `bool`
+
+    let t = (1 + 2) as bool;
+          //^^^^^^^^^^^^^^^ error: cannot cast `i32` as `bool`
+
+    let _ = 5_u32 as bool;
+          //^^^^^^^^^^^^^ error: cannot cast `u32` as `bool`
+
+    let _ = 64.0_f64 as bool;
+          //^^^^^^^^^^^^^^^^ error: cannot cast `f64` as `bool`
+
+    enum IntEnum {
+        Zero,
+        One,
+        Two
+    }
+    let _ = IntEnum::One as bool;
+          //^^^^^^^^^^^^^^^^^^^^ error: cannot cast `IntEnum` as `bool`
+
+    fn uwu(_: u8) -> i32 {
+        5
+    }
+
+    unsafe fn owo() {}
+
+    let _ = uwu as bool;
+          //^^^^^^^^^^^ error: cannot cast `fn uwu(u8) -> i32` as `bool`
+    let _ = owo as bool;
+          //^^^^^^^^^^^ error: cannot cast `unsafe fn owo()` as `bool`
+
+    let _ = uwu as fn(u8) -> i32 as bool;
+          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot cast `fn(u8) -> i32` as `bool`
+    let _ = 'x' as bool;
+          //^^^^^^^^^^^ error: cannot cast `char` as `bool`
+
+    let ptr = 1 as *const ();
+
+    let _ = ptr as bool;
+          //^^^^^^^^^^^ error: cannot cast `*const ()` as `bool`
+    let v = "hello" as bool;
+          //^^^^^^^^^^^^^^^ error: casting `&str` as `bool` is invalid: needs casting through a raw pointer first
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn cast_pointee_projection() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+trait Tag<'a> {
+    type Type: ?Sized;
+}
+
+trait IntoRaw: for<'a> Tag<'a> {
+    fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type;
+}
+
+impl<T: for<'a> Tag<'a>> IntoRaw for T {
+    fn into_raw(this: *const <Self as Tag<'_>>::Type) -> *mut <Self as Tag<'_>>::Type {
+        this as *mut T::Type
+    }
+}
+
+fn main() {}
+"#,
+        );
+    }
+
+    #[test]
+    fn cast_region_to_int() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn main() {
+    let x: isize = 3;
+    let _ = &x as *const isize as usize;
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn cast_to_bare_fn() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn foo(_x: isize) { }
+
+fn main() {
+    let v: u64 = 5;
+    let x = foo as extern "C" fn() -> isize;
+          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `fn foo(isize)` as `fn() -> isize`
+    let y = v as extern "Rust" fn(isize) -> (isize, isize);
+          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `u64` as `fn(isize) -> (isize, isize)`
+    y(x());
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn cast_to_unit() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn main() {
+    let _ = 0u32 as ();
+          //^^^^^^^^^^ error: non-primitive cast: `u32` as `()`
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn cast_to_slice() {
+        check_diagnostics_with_disabled(
+            r#"
+//- minicore: sized
+fn as_bytes(_: &str) -> &[u8] {
+    loop {}
+}
+
+fn main() {
+    as_bytes("example") as [char];
+  //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cast to unsized type: `[char]`
+
+    let arr: &[u8] = &[0, 2, 3];
+    arr as [char];
+  //^^^^^^^^^^^^^ error: cast to unsized type: `[char]`
+}
+"#,
+            &["E0308"],
+        );
+    }
+
+    #[test]
+    fn cast() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn null_mut<T: ?Sized>() -> *mut T {
+    loop {}
+}
+
+pub fn main() {
+    let i: isize = 'Q' as isize;
+    let _u: u32 = i as u32;
+
+    // Test that `_` is correctly inferred.
+    let x = &"hello";
+    let mut y = x as *const _;
+    y = null_mut();
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn dyn_tail_need_normalization() {
+        check_diagnostics(
+            r#"
+//- minicore: dispatch_from_dyn
+trait Trait {
+    type Associated;
+}
+
+impl Trait for i32 {
+    type Associated = i64;
+}
+
+trait Generic<T> {}
+
+type TraitObject = dyn Generic<<i32 as Trait>::Associated>;
+
+struct Wrap(TraitObject);
+
+fn cast(x: *mut TraitObject) {
+    x as *mut Wrap;
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn enum_to_numeric_cast() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+pub enum UnitOnly {
+    Foo,
+    Bar,
+    Baz,
+}
+
+pub enum Fieldless {
+    Tuple(),
+    Struct{},
+    Unit,
+}
+
+pub enum NotUnitOnlyOrFieldless {
+    Foo,
+    Bar(u8),
+    Baz
+}
+
+fn main() {
+    let unit_only = UnitOnly::Foo;
+
+    let _ = unit_only as isize;
+    let _ = unit_only as i32;
+    let _ = unit_only as usize;
+    let _ = unit_only as u32;
+
+
+    let fieldless = Fieldless::Struct{};
+
+    let _ = fieldless as isize;
+    let _ = fieldless as i32;
+    let _ = fieldless as usize;
+    let _ = fieldless as u32;
+
+
+    let not_unit_only_or_fieldless = NotUnitOnlyOrFieldless::Foo;
+
+    let _ = not_unit_only_or_fieldless as isize;
+          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `NotUnitOnlyOrFieldless` as `isize`
+    let _ = not_unit_only_or_fieldless as i32;
+          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `NotUnitOnlyOrFieldless` as `i32`
+    let _ = not_unit_only_or_fieldless as usize;
+          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `NotUnitOnlyOrFieldless` as `usize`
+    let _ = not_unit_only_or_fieldless as u32;
+          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `NotUnitOnlyOrFieldless` as `u32`
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn fat_ptr_cast() {
+        check_diagnostics_with_disabled(
+            r#"
+//- minicore: sized
+trait Foo {
+    fn foo(&self) {} //~ WARN method `foo` is never used
+}
+
+struct Bar;
+
+impl Foo for Bar {}
+
+fn to_raw<T>(_: *mut T) -> *mut () {
+    loop {}
+}
+
+fn main() {
+    // Test we can turn a fat pointer to array back into a thin pointer.
+    let a: *const [i32] = &[1, 2, 3];
+    let b = a as *const [i32; 2];
+
+    // Test conversion to an address (usize).
+    let a: *const [i32; 3] = &[1, 2, 3];
+    let b: *const [i32] = a;
+
+    // And conversion to a void pointer/address for trait objects too.
+    let a: *mut dyn Foo = &mut Bar;
+    let b = a as *mut () as usize;
+    let c = a as *const () as usize;
+    let d = to_raw(a) as usize;
+}
+"#,
+            &["E0308"],
+        );
+
+        check_diagnostics_with_disabled(
+            r#"
+//- minicore: sized
+trait Trait {}
+
+struct Box<T: ?Sized>;
+
+impl<T: ?Sized> Box<T> {
+    fn new(_: T) -> Self {
+        loop {}
+    }
+}
+
+fn as_ptr(_: &[i32]) -> *const i32 {
+    loop {}
+}
+
+fn main() {
+    let a: &[i32] = &[1, 2, 3];
+    let b: Box<[i32]> = Box::new([1, 2, 3]);
+    let p = a as *const [i32];
+    let q = as_ptr(a);
+
+    a as usize;
+  //^^^^^^^^^^ error: casting `&[i32]` as `usize` is invalid: needs casting through a raw pointer first
+    a as isize;
+  //^^^^^^^^^^ error: casting `&[i32]` as `isize` is invalid: needs casting through a raw pointer first
+    a as i16;
+  //^^^^^^^^ error: casting `&[i32]` as `i16` is invalid: needs casting through a raw pointer first
+    a as u32;
+  //^^^^^^^^ error: casting `&[i32]` as `u32` is invalid: needs casting through a raw pointer first
+    b as usize;
+  //^^^^^^^^^^ error: non-primitive cast: `Box<[i32]>` as `usize`
+    p as usize;
+  //^^^^^^^^^^ error: casting `*const [i32]` as `usize` is invalid: needs casting through a thin pointer first
+    q as *const [i32];
+  //^^^^^^^^^^^^^^^^^ error: cannot cast thin pointer `*const i32` to fat pointer `*const [i32]`
+
+    let t: *mut (dyn Trait + 'static) = 0 as *mut _;
+                                      //^^^^^^^^^^^ error: cannot cast `usize` to a fat pointer `*mut _`
+    let mut fail: *const str = 0 as *const str;
+                             //^^^^^^^^^^^^^^^ error: cannot cast `usize` to a fat pointer `*const str`
+    let mut fail2: *const str = 0isize as *const str;
+                              //^^^^^^^^^^^^^^^^^^^^ error: cannot cast `isize` to a fat pointer `*const str`
+}
+
+fn foo<T: ?Sized>() {
+    let s = 0 as *const T;
+          //^^^^^^^^^^^^^ error: cannot cast `usize` to a fat pointer `*const T`
+}
+"#,
+            &["E0308", "unused_variables"],
+        );
+    }
+
+    #[test]
+    fn order_dependent_cast_inference() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn main() {
+    let x = &"hello";
+    let mut y = 0 as *const _;
+              //^^^^^^^^^^^^^ error: cannot cast to a pointer of an unknown kind
+    y = x as *const _;
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn ptr_to_ptr_different_regions() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+struct Foo<'a> { a: &'a () }
+
+fn extend_lifetime_very_very_safely<'a>(v: *const Foo<'a>) -> *const Foo<'static> {
+    // This should pass because raw pointer casts can do anything they want.
+    v as *const Foo<'static>
+}
+
+trait Trait {}
+
+fn assert_static<'a>(ptr: *mut (dyn Trait + 'a)) -> *mut (dyn Trait + 'static) {
+    ptr as _
+}
+
+fn main() {
+    let unit = ();
+    let foo = Foo { a: &unit };
+    let _long: *const Foo<'static> = extend_lifetime_very_very_safely(&foo);
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn ptr_to_trait_obj_add_auto() {
+        check_diagnostics(
+            r#"
+//- minicore: pointee
+trait Trait<'a> {}
+
+fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) {
+    x as _
+}
+
+// (to test diagnostic list formatting)
+fn add_multiple_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send + Sync + Unpin) {
+    x as _
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn ptr_to_trait_obj_add_super_auto() {
+        check_diagnostics(
+            r#"
+//- minicore: pointee
+trait Trait: Send {}
+impl Trait for () {}
+
+fn main() {
+    // This is OK: `Trait` has `Send` super trait.
+    &() as *const dyn Trait as *const (dyn Trait + Send);
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn ptr_to_trait_obj_ok() {
+        check_diagnostics(
+            r#"
+//- minicore: pointee
+trait Trait<'a> {}
+
+fn remove_auto<'a>(x: *mut (dyn Trait<'a> + Send)) -> *mut dyn Trait<'a> {
+    x as _
+}
+
+fn cast_inherent_lt<'a, 'b>(x: *mut (dyn Trait<'static> + 'a)) -> *mut (dyn Trait<'static> + 'b) {
+    x as _
+}
+
+fn unprincipled<'a, 'b>(x: *mut (dyn Send + 'a)) -> *mut (dyn Sync + 'b) {
+    x as _
+}
+"#,
+        );
+    }
+
+    #[ignore = "issue #18047"]
+    #[test]
+    fn ptr_to_trait_obj_wrap_upcast() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+trait Super {}
+trait Sub: Super {}
+
+struct Wrapper<T: ?Sized>(T);
+
+// This cast should not compile.
+// Upcasting can't work here, because we are also changing the type (`Wrapper`),
+// and reinterpreting would be confusing/surprising.
+// See <https://github.com/rust-lang/rust/pull/120248#discussion_r1487739518>
+fn cast(ptr: *const dyn Sub) -> *const Wrapper<dyn Super> {
+    ptr as _
+  //^^^^^^^^ error: casting `*const dyn Sub` as `*const Wrapper<dyn Super>` is invalid: vtable kinds may not match
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn supported_cast() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+pub fn main() {
+    struct String;
+
+    let f = 1_usize as *const String;
+
+    let _ = f as isize;
+    let _ = f as usize;
+    let _ = f as i8;
+    let _ = f as i16;
+    let _ = f as i32;
+    let _ = f as i64;
+    let _ = f as u8;
+    let _ = f as u16;
+    let _ = f as u32;
+    let _ = f as u64;
+
+    let _ = 1 as isize;
+    let _ = 1 as usize;
+    let _ = 1 as *const String;
+    let _ = 1 as i8;
+    let _ = 1 as i16;
+    let _ = 1 as i32;
+    let _ = 1 as i64;
+    let _ = 1 as u8;
+    let _ = 1 as u16;
+    let _ = 1 as u32;
+    let _ = 1 as u64;
+    let _ = 1 as f32;
+    let _ = 1 as f64;
+
+    let _ = 1_usize as isize;
+    let _ = 1_usize as usize;
+    let _ = 1_usize as *const String;
+    let _ = 1_usize as i8;
+    let _ = 1_usize as i16;
+    let _ = 1_usize as i32;
+    let _ = 1_usize as i64;
+    let _ = 1_usize as u8;
+    let _ = 1_usize as u16;
+    let _ = 1_usize as u32;
+    let _ = 1_usize as u64;
+    let _ = 1_usize as f32;
+    let _ = 1_usize as f64;
+
+    let _ = 1i8 as isize;
+    let _ = 1i8 as usize;
+    let _ = 1i8 as *const String;
+    let _ = 1i8 as i8;
+    let _ = 1i8 as i16;
+    let _ = 1i8 as i32;
+    let _ = 1i8 as i64;
+    let _ = 1i8 as u8;
+    let _ = 1i8 as u16;
+    let _ = 1i8 as u32;
+    let _ = 1i8 as u64;
+    let _ = 1i8 as f32;
+    let _ = 1i8 as f64;
+
+    let _ = 1u8 as isize;
+    let _ = 1u8 as usize;
+    let _ = 1u8 as *const String;
+    let _ = 1u8 as i8;
+    let _ = 1u8 as i16;
+    let _ = 1u8 as i32;
+    let _ = 1u8 as i64;
+    let _ = 1u8 as u8;
+    let _ = 1u8 as u16;
+    let _ = 1u8 as u32;
+    let _ = 1u8 as u64;
+    let _ = 1u8 as f32;
+    let _ = 1u8 as f64;
+
+    let _ = 1i16 as isize;
+    let _ = 1i16 as usize;
+    let _ = 1i16 as *const String;
+    let _ = 1i16 as i8;
+    let _ = 1i16 as i16;
+    let _ = 1i16 as i32;
+    let _ = 1i16 as i64;
+    let _ = 1i16 as u8;
+    let _ = 1i16 as u16;
+    let _ = 1i16 as u32;
+    let _ = 1i16 as u64;
+    let _ = 1i16 as f32;
+    let _ = 1i16 as f64;
+
+    let _ = 1u16 as isize;
+    let _ = 1u16 as usize;
+    let _ = 1u16 as *const String;
+    let _ = 1u16 as i8;
+    let _ = 1u16 as i16;
+    let _ = 1u16 as i32;
+    let _ = 1u16 as i64;
+    let _ = 1u16 as u8;
+    let _ = 1u16 as u16;
+    let _ = 1u16 as u32;
+    let _ = 1u16 as u64;
+    let _ = 1u16 as f32;
+    let _ = 1u16 as f64;
+
+    let _ = 1i32 as isize;
+    let _ = 1i32 as usize;
+    let _ = 1i32 as *const String;
+    let _ = 1i32 as i8;
+    let _ = 1i32 as i16;
+    let _ = 1i32 as i32;
+    let _ = 1i32 as i64;
+    let _ = 1i32 as u8;
+    let _ = 1i32 as u16;
+    let _ = 1i32 as u32;
+    let _ = 1i32 as u64;
+    let _ = 1i32 as f32;
+    let _ = 1i32 as f64;
+
+    let _ = 1u32 as isize;
+    let _ = 1u32 as usize;
+    let _ = 1u32 as *const String;
+    let _ = 1u32 as i8;
+    let _ = 1u32 as i16;
+    let _ = 1u32 as i32;
+    let _ = 1u32 as i64;
+    let _ = 1u32 as u8;
+    let _ = 1u32 as u16;
+    let _ = 1u32 as u32;
+    let _ = 1u32 as u64;
+    let _ = 1u32 as f32;
+    let _ = 1u32 as f64;
+
+    let _ = 1i64 as isize;
+    let _ = 1i64 as usize;
+    let _ = 1i64 as *const String;
+    let _ = 1i64 as i8;
+    let _ = 1i64 as i16;
+    let _ = 1i64 as i32;
+    let _ = 1i64 as i64;
+    let _ = 1i64 as u8;
+    let _ = 1i64 as u16;
+    let _ = 1i64 as u32;
+    let _ = 1i64 as u64;
+    let _ = 1i64 as f32;
+    let _ = 1i64 as f64;
+
+    let _ = 1u64 as isize;
+    let _ = 1u64 as usize;
+    let _ = 1u64 as *const String;
+    let _ = 1u64 as i8;
+    let _ = 1u64 as i16;
+    let _ = 1u64 as i32;
+    let _ = 1u64 as i64;
+    let _ = 1u64 as u8;
+    let _ = 1u64 as u16;
+    let _ = 1u64 as u32;
+    let _ = 1u64 as u64;
+    let _ = 1u64 as f32;
+    let _ = 1u64 as f64;
+
+    let _ = 1u64 as isize;
+    let _ = 1u64 as usize;
+    let _ = 1u64 as *const String;
+    let _ = 1u64 as i8;
+    let _ = 1u64 as i16;
+    let _ = 1u64 as i32;
+    let _ = 1u64 as i64;
+    let _ = 1u64 as u8;
+    let _ = 1u64 as u16;
+    let _ = 1u64 as u32;
+    let _ = 1u64 as u64;
+    let _ = 1u64 as f32;
+    let _ = 1u64 as f64;
+
+    let _ = true as isize;
+    let _ = true as usize;
+    let _ = true as i8;
+    let _ = true as i16;
+    let _ = true as i32;
+    let _ = true as i64;
+    let _ = true as u8;
+    let _ = true as u16;
+    let _ = true as u32;
+    let _ = true as u64;
+
+    let _ = 1f32 as isize;
+    let _ = 1f32 as usize;
+    let _ = 1f32 as i8;
+    let _ = 1f32 as i16;
+    let _ = 1f32 as i32;
+    let _ = 1f32 as i64;
+    let _ = 1f32 as u8;
+    let _ = 1f32 as u16;
+    let _ = 1f32 as u32;
+    let _ = 1f32 as u64;
+    let _ = 1f32 as f32;
+    let _ = 1f32 as f64;
+
+    let _ = 1f64 as isize;
+    let _ = 1f64 as usize;
+    let _ = 1f64 as i8;
+    let _ = 1f64 as i16;
+    let _ = 1f64 as i32;
+    let _ = 1f64 as i64;
+    let _ = 1f64 as u8;
+    let _ = 1f64 as u16;
+    let _ = 1f64 as u32;
+    let _ = 1f64 as u64;
+    let _ = 1f64 as f32;
+    let _ = 1f64 as f64;
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn unsized_struct_cast() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+pub struct Data([u8]);
+
+fn foo(x: &[u8]) {
+    let _: *const Data = x as *const Data;
+                       //^^^^^^^^^^^^^^^^ error: casting `&[u8]` as `*const Data` is invalid
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn unsupported_cast() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+struct A;
+
+fn main() {
+    let _ = 1.0 as *const A;
+          //^^^^^^^^^^^^^^^ error: casting `f64` as `*const A` is invalid
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn issue_17897() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn main() {
+    _ = ((), ()) as ();
+      //^^^^^^^^^^^^^^ error: non-primitive cast: `((), ())` as `()`
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn rustc_issue_10991() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn main() {
+    let nil = ();
+    let _t = nil as usize;
+           //^^^^^^^^^^^^ error: non-primitive cast: `()` as `usize`
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn rustc_issue_17444() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+enum Test {
+    Foo = 0
+}
+
+fn main() {
+    let _x = Test::Foo as *const isize;
+           //^^^^^^^^^^^^^^^^^^^^^^^^^ error: casting `Test` as `*const isize` is invalid
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn rustc_issue_43825() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn main() {
+    let error = error;
+              //^^^^^ error: no such value in this scope
+
+    0 as f32;
+    0.0 as u32;
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn rustc_issue_84213() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+struct Something {
+    pub field: u32,
+}
+
+fn main() {
+    let mut something = Something { field: 1337 };
+    let _ = something.field;
+
+    let _pointer_to_something = something as *const Something;
+                              //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `Something` as `*const Something`
+
+    let _mut_pointer_to_something = something as *mut Something;
+                                  //^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `Something` as `*mut Something`
+}
+"#,
+        );
+
+        // Fixed
+        check_diagnostics(
+            r#"
+//- minicore: sized
+struct Something {
+    pub field: u32,
+}
+
+fn main() {
+    let mut something = Something { field: 1337 };
+    let _ = something.field;
+
+    let _pointer_to_something = &something as *const Something;
+
+    let _mut_pointer_to_something = &mut something as *mut Something;
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn rustc_issue_88621() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+#[repr(u8)]
+enum Kind2 {
+    Foo() = 1,
+    Bar{} = 2,
+    Baz = 3,
+}
+
+fn main() {
+    let _ = Kind2::Foo() as u8;
+          //^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `Kind2` as `u8`
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn rustc_issue_89497() {
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn main() {
+    let pointer: usize = &1_i32 as *const i32 as usize;
+    let _reference: &'static i32 = unsafe { pointer as *const i32 as &'static i32 };
+                                          //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: non-primitive cast: `*const i32` as `&i32`
+}
+"#,
+        );
+
+        // Fixed
+        check_diagnostics(
+            r#"
+//- minicore: sized
+fn main() {
+    let pointer: usize = &1_i32 as *const i32 as usize;
+    let _reference: &'static i32 = unsafe { &*(pointer as *const i32) };
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn rustc_issue_106883() {
+        check_diagnostics_with_disabled(
+            r#"
+//- minicore: sized, deref
+use core::ops::Deref;
+
+struct Foo;
+
+impl Deref for Foo {
+    type Target = [u8];
+
+    fn deref(&self) -> &Self::Target {
+        &[]
+    }
+}
+
+fn main() {
+    let _ = "foo" as bool;
+          //^^^^^^^^^^^^^ error: casting `&str` as `bool` is invalid: needs casting through a raw pointer first
+
+    let _ = Foo as bool;
+          //^^^^^^^^^^^ error: non-primitive cast: `Foo` as `bool`
+}
+
+fn _slice(bar: &[i32]) -> bool {
+    bar as bool
+  //^^^^^^^^^^^ error: casting `&[i32]` as `bool` is invalid: needs casting through a raw pointer first
+}
+"#,
+            &["E0308"],
+        );
+    }
+
+    #[test]
+    fn trait_upcasting() {
+        check_diagnostics(
+            r#"
+//- minicore: coerce_unsized, dispatch_from_dyn
+#![feature(trait_upcasting)]
+trait Foo {}
+trait Bar: Foo {}
+
+impl dyn Bar {
+    fn bar(&self) {
+        _ = self as &dyn Foo;
+    }
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn issue_18047() {
+        check_diagnostics(
+            r#"
+//- minicore: coerce_unsized, dispatch_from_dyn
+trait LocalFrom<T> {
+    fn from(_: T) -> Self;
+}
+trait LocalInto<T> {
+    fn into(self) -> T;
+}
+
+impl<T, U> LocalInto<U> for T
+where
+    U: LocalFrom<T>,
+{
+    fn into(self) -> U {
+        U::from(self)
+    }
+}
+
+impl<T> LocalFrom<T> for T {
+    fn from(t: T) -> T {
+        t
+    }
+}
+
+trait Foo {
+    type ErrorType;
+    type Assoc;
+}
+
+trait Bar {
+    type ErrorType;
+}
+
+struct ErrorLike;
+
+impl<E> LocalFrom<E> for ErrorLike
+where
+    E: Trait + 'static,
+{
+    fn from(_: E) -> Self {
+        loop {}
+    }
+}
+
+trait Baz {
+    type Assoc: Bar;
+    type Error: LocalInto<ErrorLike>;
+}
+
+impl<T, U> Baz for T
+where
+    T: Foo<Assoc = U>,
+    T::ErrorType: LocalInto<ErrorLike>,
+    U: Bar,
+    <U as Bar>::ErrorType: LocalInto<ErrorLike>,
+{
+    type Assoc = U;
+    type Error = T::ErrorType;
+}
+struct S;
+trait Trait {}
+impl Trait for S {}
+
+fn test<T>()
+where
+    T: Baz,
+    T::Assoc: 'static,
+{
+    let _ = &S as &dyn Trait;
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn cast_literal_to_char() {
+        check_diagnostics(
+            r#"
+fn foo() {
+    0 as char;
+}
+            "#,
+        );
+    }
+}
diff --git a/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
index af8ac60..5b43f4b 100644
--- a/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
+++ b/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
@@ -11,9 +11,14 @@
 //
 // This diagnostic is triggered if an operation marked as `unsafe` is used outside of an `unsafe` function or block.
 pub(crate) fn missing_unsafe(ctx: &DiagnosticsContext<'_>, d: &hir::MissingUnsafe) -> Diagnostic {
+    let code = if d.only_lint {
+        DiagnosticCode::RustcLint("unsafe_op_in_unsafe_fn")
+    } else {
+        DiagnosticCode::RustcHardError("E0133")
+    };
     Diagnostic::new_with_syntax_node_ptr(
         ctx,
-        DiagnosticCode::RustcHardError("E0133"),
+        code,
         "this operation is unsafe and requires an unsafe function or block",
         d.expr.map(|it| it.into()),
     )
@@ -99,8 +104,9 @@
     fn missing_unsafe_diagnostic_with_raw_ptr() {
         check_diagnostics(
             r#"
+//- minicore: sized
 fn main() {
-    let x = &5 as *const usize;
+    let x = &5_usize as *const usize;
     unsafe { let _y = *x; }
     let _z = *x;
 }          //^^💡 error: this operation is unsafe and requires an unsafe function or block
@@ -112,17 +118,18 @@
     fn missing_unsafe_diagnostic_with_unsafe_call() {
         check_diagnostics(
             r#"
+//- minicore: sized
 struct HasUnsafe;
 
 impl HasUnsafe {
     unsafe fn unsafe_fn(&self) {
-        let x = &5 as *const usize;
+        let x = &5_usize as *const usize;
         let _y = *x;
     }
 }
 
 unsafe fn unsafe_fn() {
-    let x = &5 as *const usize;
+    let x = &5_usize as *const usize;
     let _y = *x;
 }
 
@@ -164,6 +171,56 @@
     }
 
     #[test]
+    fn missing_unsafe_diagnostic_with_extern_static() {
+        check_diagnostics(
+            r#"
+//- minicore: copy
+
+extern "C" {
+    static EXTERN: i32;
+    static mut EXTERN_MUT: i32;
+}
+
+fn main() {
+    let _x = EXTERN;
+           //^^^^^^💡 error: this operation is unsafe and requires an unsafe function or block
+    let _x = EXTERN_MUT;
+           //^^^^^^^^^^💡 error: this operation is unsafe and requires an unsafe function or block
+    unsafe {
+        let _x = EXTERN;
+        let _x = EXTERN_MUT;
+    }
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn no_unsafe_diagnostic_with_addr_of_static() {
+        check_diagnostics(
+            r#"
+//- minicore: copy, addr_of
+
+use core::ptr::{addr_of, addr_of_mut};
+
+extern "C" {
+    static EXTERN: i32;
+    static mut EXTERN_MUT: i32;
+}
+static mut STATIC_MUT: i32 = 0;
+
+fn main() {
+    let _x = addr_of!(EXTERN);
+    let _x = addr_of!(EXTERN_MUT);
+    let _x = addr_of!(STATIC_MUT);
+    let _x = addr_of_mut!(EXTERN_MUT);
+    let _x = addr_of_mut!(STATIC_MUT);
+}
+"#,
+        );
+    }
+
+    #[test]
     fn no_missing_unsafe_diagnostic_with_safe_intrinsic() {
         check_diagnostics(
             r#"
@@ -200,14 +257,15 @@
     fn add_unsafe_block_when_dereferencing_a_raw_pointer() {
         check_fix(
             r#"
+//- minicore: sized
 fn main() {
-    let x = &5 as *const usize;
+    let x = &5_usize as *const usize;
     let _z = *x$0;
 }
 "#,
             r#"
 fn main() {
-    let x = &5 as *const usize;
+    let x = &5_usize as *const usize;
     let _z = unsafe { *x };
 }
 "#,
@@ -218,8 +276,9 @@
     fn add_unsafe_block_when_calling_unsafe_function() {
         check_fix(
             r#"
+//- minicore: sized
 unsafe fn func() {
-    let x = &5 as *const usize;
+    let x = &5_usize as *const usize;
     let z = *x;
 }
 fn main() {
@@ -228,7 +287,7 @@
 "#,
             r#"
 unsafe fn func() {
-    let x = &5 as *const usize;
+    let x = &5_usize as *const usize;
     let z = *x;
 }
 fn main() {
@@ -242,6 +301,7 @@
     fn add_unsafe_block_when_calling_unsafe_method() {
         check_fix(
             r#"
+//- minicore: sized
 struct S(usize);
 impl S {
     unsafe fn func(&self) {
@@ -511,4 +571,28 @@
             "#,
         )
     }
+
+    #[test]
+    fn unsafe_op_in_unsafe_fn_allowed_by_default() {
+        check_diagnostics(
+            r#"
+unsafe fn foo(p: *mut i32) {
+    *p = 123;
+}
+            "#,
+        )
+    }
+
+    #[test]
+    fn unsafe_op_in_unsafe_fn() {
+        check_diagnostics(
+            r#"
+#![warn(unsafe_op_in_unsafe_fn)]
+unsafe fn foo(p: *mut i32) {
+    *p = 123;
+  //^^💡 warn: this operation is unsafe and requires an unsafe function or block
+}
+            "#,
+        )
+    }
 }
diff --git a/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs b/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
index 06c6b0f..a9ff06f 100644
--- a/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
+++ b/crates/ide-diagnostics/src/handlers/moved_out_of_ref.rs
@@ -190,4 +190,16 @@
 "#,
         );
     }
+
+    #[test]
+    fn regression_16564() {
+        check_diagnostics(
+            r#"
+//- minicore: copy
+fn test() {
+    let _x = (&(&mut (),)).0 as *const ();
+}
+            "#,
+        )
+    }
 }
diff --git a/crates/ide-diagnostics/src/handlers/mutability_errors.rs b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
index e4b1f3c..9554279 100644
--- a/crates/ide-diagnostics/src/handlers/mutability_errors.rs
+++ b/crates/ide-diagnostics/src/handlers/mutability_errors.rs
@@ -824,13 +824,13 @@
 
     #[test]
     fn or_pattern() {
+        // FIXME: `None` is inferred as unknown here for some reason
         check_diagnostics(
             r#"
 //- minicore: option
 fn f(_: i32) {}
 fn main() {
     let ((Some(mut x), None) | (_, Some(mut x))) = (None, Some(7)) else { return };
-             //^^^^^ 💡 warn: variable does not need to be mutable
     f(x);
 }
 "#,
diff --git a/crates/ide-diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs b/crates/ide-diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs
index 87932bf..1864720 100644
--- a/crates/ide-diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs
+++ b/crates/ide-diagnostics/src/handlers/replace_filter_map_next_with_find_map.rs
@@ -84,7 +84,7 @@
     fn replace_filter_map_next_dont_work_for_not_sized_issues_16596() {
         check_diagnostics(
             r#"
-//- minicore: iterators
+//- minicore: iterators, dispatch_from_dyn
 fn foo() {
     let mut j = [0].into_iter();
     let i: &mut dyn Iterator<Item = i32>  = &mut j;
diff --git a/crates/ide-diagnostics/src/handlers/typed_hole.rs b/crates/ide-diagnostics/src/handlers/typed_hole.rs
index b5c242e..6994a7e 100644
--- a/crates/ide-diagnostics/src/handlers/typed_hole.rs
+++ b/crates/ide-diagnostics/src/handlers/typed_hole.rs
@@ -402,4 +402,26 @@
             ],
         );
     }
+
+    #[test]
+    fn underscore_in_asm() {
+        check_diagnostics(
+            r#"
+//- minicore: asm
+fn rdtscp() -> u64 {
+    let hi: u64;
+    let lo: u64;
+    unsafe {
+        core::arch::asm!(
+            "rdtscp",
+            out("rdx") hi,
+            out("rax") lo,
+            out("rcx") _,
+            options(nomem, nostack, preserves_flags)
+        );
+    }
+    (hi << 32) | lo
+}"#,
+        );
+    }
 }
diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs
index 9b50a43..45c723d 100644
--- a/crates/ide-diagnostics/src/lib.rs
+++ b/crates/ide-diagnostics/src/lib.rs
@@ -30,6 +30,7 @@
     pub(crate) mod inactive_code;
     pub(crate) mod incoherent_impl;
     pub(crate) mod incorrect_case;
+    pub(crate) mod invalid_cast;
     pub(crate) mod invalid_derive_target;
     pub(crate) mod macro_error;
     pub(crate) mod malformed_derive;
@@ -75,9 +76,10 @@
 #[cfg(test)]
 mod tests;
 
-use std::sync::LazyLock;
+use std::{collections::hash_map, iter, sync::LazyLock};
 
-use hir::{diagnostics::AnyDiagnostic, InFile, Semantics};
+use either::Either;
+use hir::{db::ExpandDatabase, diagnostics::AnyDiagnostic, Crate, HirFileId, InFile, Semantics};
 use ide_db::{
     assists::{Assist, AssistId, AssistKind, AssistResolveStrategy},
     base_db::SourceDatabase,
@@ -88,10 +90,10 @@
     syntax_helpers::node_ext::parse_tt_as_comma_sep_paths,
     EditionedFileId, FileId, FileRange, FxHashMap, FxHashSet, RootDatabase, SnippetCap,
 };
-use stdx::never;
+use itertools::Itertools;
 use syntax::{
-    ast::{self, AstNode},
-    AstPtr, Edition, SyntaxNode, SyntaxNodePtr, TextRange,
+    ast::{self, AstNode, HasAttrs},
+    AstPtr, Edition, NodeOrToken, SmolStr, SyntaxKind, SyntaxNode, SyntaxNodePtr, TextRange, T,
 };
 
 // FIXME: Make this an enum
@@ -390,6 +392,7 @@
     for diag in diags {
         let d = match diag {
             AnyDiagnostic::AwaitOutsideOfAsync(d) => handlers::await_outside_of_async::await_outside_of_async(&ctx, &d),
+            AnyDiagnostic::CastToUnsized(d) => handlers::invalid_cast::cast_to_unsized(&ctx, &d),
             AnyDiagnostic::ExpectedFunction(d) => handlers::expected_function::expected_function(&ctx, &d),
             AnyDiagnostic::InactiveCode(d) => match handlers::inactive_code::inactive_code(&ctx, &d) {
                 Some(it) => it,
@@ -397,6 +400,7 @@
             }
             AnyDiagnostic::IncoherentImpl(d) => handlers::incoherent_impl::incoherent_impl(&ctx, &d),
             AnyDiagnostic::IncorrectCase(d) => handlers::incorrect_case::incorrect_case(&ctx, &d),
+            AnyDiagnostic::InvalidCast(d) => handlers::invalid_cast::invalid_cast(&ctx, &d),
             AnyDiagnostic::InvalidDeriveTarget(d) => handlers::invalid_derive_target::invalid_derive_target(&ctx, &d),
             AnyDiagnostic::MacroDefError(d) => handlers::macro_error::macro_def_error(&ctx, &d),
             AnyDiagnostic::MacroError(d) => handlers::macro_error::macro_error(&ctx, &d),
@@ -473,8 +477,9 @@
             || ctx.config.disable_experimental && d.experimental)
     });
 
-    let mut diagnostics_of_range = res
+    let mut lints = res
         .iter_mut()
+        .filter(|it| matches!(it.code, DiagnosticCode::Clippy(_) | DiagnosticCode::RustcLint(_)))
         .filter_map(|it| {
             Some((
                 it.main_node.map(|ptr| {
@@ -483,27 +488,31 @@
                 it,
             ))
         })
-        .collect::<FxHashMap<_, _>>();
+        .collect::<Vec<_>>();
 
-    if diagnostics_of_range.is_empty() {
-        return res;
-    }
-
-    let mut rustc_stack: FxHashMap<String, Vec<Severity>> = FxHashMap::default();
-    let mut clippy_stack: FxHashMap<String, Vec<Severity>> = FxHashMap::default();
-
-    // FIXME: This becomes quite expensive for big files
-    handle_lint_attributes(
+    // The edition isn't accurate (each diagnostics may have its own edition due to macros),
+    // but it's okay as it's only being used for error recovery.
+    handle_lints(
         &ctx.sema,
-        parse.syntax(),
-        &mut rustc_stack,
-        &mut clippy_stack,
-        &mut diagnostics_of_range,
-        ctx.edition,
+        &mut FxHashMap::default(),
+        &mut lints,
+        &mut Vec::new(),
+        file_id.edition(),
     );
 
     res.retain(|d| d.severity != Severity::Allow);
 
+    res.retain_mut(|diag| {
+        if let Some(node) = diag
+            .main_node
+            .map(|ptr| ptr.map(|node| node.to_node(&ctx.sema.parse_or_expand(ptr.file_id))))
+        {
+            handle_diag_from_macros(&ctx.sema, diag, &node)
+        } else {
+            true
+        }
+    });
+
     res
 }
 
@@ -520,6 +529,35 @@
     res
 }
 
+/// Returns whether to keep this diagnostic (or remove it).
+fn handle_diag_from_macros(
+    sema: &Semantics<'_, RootDatabase>,
+    diag: &mut Diagnostic,
+    node: &InFile<SyntaxNode>,
+) -> bool {
+    let Some(macro_file) = node.file_id.macro_file() else { return true };
+    let span_map = sema.db.expansion_span_map(macro_file);
+    let mut spans = span_map.spans_for_range(node.text_range());
+    if spans.any(|span| {
+        sema.db.lookup_intern_syntax_context(span.ctx).outer_expn.is_some_and(|expansion| {
+            let macro_call =
+                sema.db.lookup_intern_macro_call(expansion.as_macro_file().macro_call_id);
+            !Crate::from(macro_call.def.krate).origin(sema.db).is_local()
+        })
+    }) {
+        // Disable suggestions for external macros, they'll change library code and it's just bad.
+        diag.fixes = None;
+
+        // All Clippy lints report in macros, see https://github.com/rust-lang/rust-clippy/blob/903293b199364/declare_clippy_lint/src/lib.rs#L172.
+        if let DiagnosticCode::RustcLint(lint) = diag.code {
+            if !LINTS_TO_REPORT_IN_EXTERNAL_MACROS.contains(lint) {
+                return false;
+            }
+        };
+    }
+    true
+}
+
 // `__RA_EVERY_LINT` is a fake lint group to allow every lint in proc macros
 
 static RUSTC_LINT_GROUPS_DICT: LazyLock<FxHashMap<&str, Vec<&str>>> =
@@ -528,153 +566,347 @@
 static CLIPPY_LINT_GROUPS_DICT: LazyLock<FxHashMap<&str, Vec<&str>>> =
     LazyLock::new(|| build_group_dict(CLIPPY_LINT_GROUPS, &["__RA_EVERY_LINT"], "clippy::"));
 
+// FIXME: Autogenerate this instead of enumerating by hand.
+static LINTS_TO_REPORT_IN_EXTERNAL_MACROS: LazyLock<FxHashSet<&str>> =
+    LazyLock::new(|| FxHashSet::from_iter([]));
+
 fn build_group_dict(
     lint_group: &'static [LintGroup],
     all_groups: &'static [&'static str],
     prefix: &'static str,
 ) -> FxHashMap<&'static str, Vec<&'static str>> {
-    let mut r: FxHashMap<&str, Vec<&str>> = FxHashMap::default();
+    let mut map_with_prefixes: FxHashMap<&str, Vec<&str>> = FxHashMap::default();
     for g in lint_group {
-        for child in g.children {
-            r.entry(child.strip_prefix(prefix).unwrap())
-                .or_default()
-                .push(g.lint.label.strip_prefix(prefix).unwrap());
+        let mut add_children = |label: &'static str| {
+            for child in g.children {
+                map_with_prefixes.entry(child).or_default().push(label);
+            }
+        };
+        add_children(g.lint.label);
+
+        if g.lint.label == "nonstandard_style" {
+            // Also add `bad_style`, which for some reason isn't listed in the groups.
+            add_children("bad_style");
         }
     }
-    for (lint, groups) in r.iter_mut() {
+    for (lint, groups) in map_with_prefixes.iter_mut() {
         groups.push(lint);
         groups.extend_from_slice(all_groups);
     }
-    r
+    map_with_prefixes.into_iter().map(|(k, v)| (k.strip_prefix(prefix).unwrap(), v)).collect()
 }
 
-fn handle_lint_attributes(
+/// Thd default severity for lints that are not warn by default.
+// FIXME: Autogenerate this instead of write manually.
+static LINTS_DEFAULT_SEVERITY: LazyLock<FxHashMap<&str, Severity>> =
+    LazyLock::new(|| FxHashMap::from_iter([("unsafe_op_in_unsafe_fn", Severity::Allow)]));
+
+fn handle_lints(
     sema: &Semantics<'_, RootDatabase>,
-    root: &SyntaxNode,
-    rustc_stack: &mut FxHashMap<String, Vec<Severity>>,
-    clippy_stack: &mut FxHashMap<String, Vec<Severity>>,
-    diagnostics_of_range: &mut FxHashMap<InFile<SyntaxNode>, &mut Diagnostic>,
+    cache: &mut FxHashMap<HirFileId, FxHashMap<SmolStr, SeverityAttr>>,
+    diagnostics: &mut [(InFile<SyntaxNode>, &mut Diagnostic)],
+    cache_stack: &mut Vec<HirFileId>,
     edition: Edition,
 ) {
-    let _g = tracing::info_span!("handle_lint_attributes").entered();
-    let file_id = sema.hir_file_for(root);
-    let preorder = root.preorder();
-    for ev in preorder {
-        match ev {
-            syntax::WalkEvent::Enter(node) => {
-                for attr in node.children().filter_map(ast::Attr::cast) {
-                    parse_lint_attribute(
-                        attr,
-                        rustc_stack,
-                        clippy_stack,
-                        |stack, severity| {
-                            stack.push(severity);
-                        },
-                        edition,
-                    );
-                }
-                if let Some(it) =
-                    diagnostics_of_range.get_mut(&InFile { file_id, value: node.clone() })
-                {
-                    const EMPTY_LINTS: &[&str] = &[];
-                    let (names, stack) = match it.code {
-                        DiagnosticCode::RustcLint(name) => (
-                            RUSTC_LINT_GROUPS_DICT.get(name).map_or(EMPTY_LINTS, |it| &**it),
-                            &mut *rustc_stack,
-                        ),
-                        DiagnosticCode::Clippy(name) => (
-                            CLIPPY_LINT_GROUPS_DICT.get(name).map_or(EMPTY_LINTS, |it| &**it),
-                            &mut *clippy_stack,
-                        ),
-                        _ => continue,
-                    };
-                    for &name in names {
-                        if let Some(s) = stack.get(name).and_then(|it| it.last()) {
-                            it.severity = *s;
-                        }
-                    }
-                }
-                if let Some(item) = ast::Item::cast(node.clone()) {
-                    if let Some(me) = sema.expand_attr_macro(&item) {
-                        for stack in [&mut *rustc_stack, &mut *clippy_stack] {
-                            stack
-                                .entry("__RA_EVERY_LINT".to_owned())
-                                .or_default()
-                                .push(Severity::Allow);
-                        }
-                        handle_lint_attributes(
-                            sema,
-                            &me,
-                            rustc_stack,
-                            clippy_stack,
-                            diagnostics_of_range,
-                            edition,
-                        );
-                        for stack in [&mut *rustc_stack, &mut *clippy_stack] {
-                            stack.entry("__RA_EVERY_LINT".to_owned()).or_default().pop();
-                        }
-                    }
-                }
-                if let Some(mc) = ast::MacroCall::cast(node) {
-                    if let Some(me) = sema.expand(&mc) {
-                        handle_lint_attributes(
-                            sema,
-                            &me,
-                            rustc_stack,
-                            clippy_stack,
-                            diagnostics_of_range,
-                            edition,
-                        );
-                    }
-                }
-            }
-            syntax::WalkEvent::Leave(node) => {
-                for attr in node.children().filter_map(ast::Attr::cast) {
-                    parse_lint_attribute(
-                        attr,
-                        rustc_stack,
-                        clippy_stack,
-                        |stack, severity| {
-                            if stack.pop() != Some(severity) {
-                                never!("Mismatched serevity in walking lint attributes");
-                            }
-                        },
-                        edition,
-                    );
-                }
-            }
+    for (node, diag) in diagnostics {
+        let lint = match diag.code {
+            DiagnosticCode::RustcLint(lint) | DiagnosticCode::Clippy(lint) => lint,
+            _ => panic!("non-lint passed to `handle_lints()`"),
+        };
+        if let Some(&default_severity) = LINTS_DEFAULT_SEVERITY.get(lint) {
+            diag.severity = default_severity;
+        }
+
+        let mut diag_severity = fill_lint_attrs(sema, node, cache, cache_stack, diag, edition);
+
+        if let outline_diag_severity @ Some(_) =
+            find_outline_mod_lint_severity(sema, node, diag, edition)
+        {
+            diag_severity = outline_diag_severity;
+        }
+
+        if let Some(diag_severity) = diag_severity {
+            diag.severity = diag_severity;
         }
     }
 }
 
-fn parse_lint_attribute(
-    attr: ast::Attr,
-    rustc_stack: &mut FxHashMap<String, Vec<Severity>>,
-    clippy_stack: &mut FxHashMap<String, Vec<Severity>>,
-    job: impl Fn(&mut Vec<Severity>, Severity),
+fn find_outline_mod_lint_severity(
+    sema: &Semantics<'_, RootDatabase>,
+    node: &InFile<SyntaxNode>,
+    diag: &Diagnostic,
     edition: Edition,
-) {
-    let Some((tag, args_tt)) = attr.as_simple_call() else {
-        return;
-    };
-    let severity = match tag.as_str() {
-        "allow" => Severity::Allow,
-        "warn" => Severity::Warning,
-        "forbid" | "deny" => Severity::Error,
-        _ => return,
-    };
-    for lint in parse_tt_as_comma_sep_paths(args_tt, edition).into_iter().flatten() {
-        if let Some(lint) = lint.as_single_name_ref() {
-            job(rustc_stack.entry(lint.to_string()).or_default(), severity);
+) -> Option<Severity> {
+    let mod_node = node.value.ancestors().find_map(ast::Module::cast)?;
+    if mod_node.item_list().is_some() {
+        // Inline modules will be handled by `fill_lint_attrs()`.
+        return None;
+    }
+
+    let mod_def = sema.to_module_def(&mod_node)?;
+    let module_source_file = sema.module_definition_node(mod_def);
+    let mut result = None;
+    let lint_groups = lint_groups(&diag.code);
+    lint_attrs(
+        sema,
+        ast::AnyHasAttrs::cast(module_source_file.value).expect("SourceFile always has attrs"),
+        edition,
+    )
+    .for_each(|(lint, severity)| {
+        if lint_groups.contains(&&*lint) {
+            result = Some(severity);
         }
-        if let Some(tool) = lint.qualifier().and_then(|it| it.as_single_name_ref()) {
-            if let Some(name_ref) = &lint.segment().and_then(|it| it.name_ref()) {
-                if tool.to_string() == "clippy" {
-                    job(clippy_stack.entry(name_ref.to_string()).or_default(), severity);
+    });
+    result
+}
+
+#[derive(Debug, Clone, Copy)]
+struct SeverityAttr {
+    severity: Severity,
+    /// This field counts how far we are from the main node. Bigger values mean more far.
+    ///
+    /// Note this isn't accurate: there can be gaps between values (created when merging severity maps).
+    /// The important thing is that if an attr is closer to the main node, it will have smaller value.
+    ///
+    /// This is necessary even though we take care to never overwrite a value from deeper nesting
+    /// because of lint groups. For example, in the following code:
+    /// ```
+    /// #[warn(non_snake_case)]
+    /// mod foo {
+    ///     #[allow(nonstandard_style)]
+    ///     mod bar;
+    /// }
+    /// ```
+    /// We want to not warn on non snake case inside `bar`. If we are traversing this for the first
+    /// time, everything will be fine, because we will set `diag_severity` on the first matching group
+    /// and never overwrite it since then. But if `bar` is cached, the cache will contain both
+    /// `#[warn(non_snake_case)]` and `#[allow(nonstandard_style)]`, and without this field, we have
+    /// no way of differentiating between the two.
+    depth: u32,
+}
+
+fn fill_lint_attrs(
+    sema: &Semantics<'_, RootDatabase>,
+    node: &InFile<SyntaxNode>,
+    cache: &mut FxHashMap<HirFileId, FxHashMap<SmolStr, SeverityAttr>>,
+    cache_stack: &mut Vec<HirFileId>,
+    diag: &Diagnostic,
+    edition: Edition,
+) -> Option<Severity> {
+    let mut collected_lint_attrs = FxHashMap::<SmolStr, SeverityAttr>::default();
+    let mut diag_severity = None;
+
+    let mut ancestors = node.value.ancestors().peekable();
+    let mut depth = 0;
+    loop {
+        let ancestor = ancestors.next().expect("we always return from top-level nodes");
+        depth += 1;
+
+        if ancestors.peek().is_none() {
+            // We don't want to insert too many nodes into cache, but top level nodes (aka. outline modules
+            // or macro expansions) need to touch the database so they seem like a good fit to cache.
+
+            if let Some(cached) = cache.get_mut(&node.file_id) {
+                // This node (and everything above it) is already cached; the attribute is either here or nowhere.
+
+                // Workaround for the borrow checker.
+                let cached = std::mem::take(cached);
+
+                cached.iter().for_each(|(lint, severity)| {
+                    for item in &*cache_stack {
+                        let node_cache_entry = cache
+                            .get_mut(item)
+                            .expect("we always insert cached nodes into the cache map");
+                        let lint_cache_entry = node_cache_entry.entry(lint.clone());
+                        if let hash_map::Entry::Vacant(lint_cache_entry) = lint_cache_entry {
+                            // Do not overwrite existing lint attributes, as we go bottom to top and bottom attrs
+                            // overwrite top attrs.
+                            lint_cache_entry.insert(SeverityAttr {
+                                severity: severity.severity,
+                                depth: severity.depth + depth,
+                            });
+                        }
+                    }
+                });
+
+                let all_matching_groups = lint_groups(&diag.code)
+                    .iter()
+                    .filter_map(|lint_group| cached.get(&**lint_group));
+                let cached_severity =
+                    all_matching_groups.min_by_key(|it| it.depth).map(|it| it.severity);
+
+                cache.insert(node.file_id, cached);
+
+                return diag_severity.or(cached_severity);
+            }
+
+            // Insert this node's descendants' attributes into any outline descendant, but not including this node.
+            // This must come before inserting this node's own attributes to preserve order.
+            collected_lint_attrs.drain().for_each(|(lint, severity)| {
+                if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) {
+                    diag_severity = Some(severity.severity);
+                }
+
+                for item in &*cache_stack {
+                    let node_cache_entry = cache
+                        .get_mut(item)
+                        .expect("we always insert cached nodes into the cache map");
+                    let lint_cache_entry = node_cache_entry.entry(lint.clone());
+                    if let hash_map::Entry::Vacant(lint_cache_entry) = lint_cache_entry {
+                        // Do not overwrite existing lint attributes, as we go bottom to top and bottom attrs
+                        // overwrite top attrs.
+                        lint_cache_entry.insert(severity);
+                    }
+                }
+            });
+
+            cache_stack.push(node.file_id);
+            cache.insert(node.file_id, FxHashMap::default());
+
+            if let Some(ancestor) = ast::AnyHasAttrs::cast(ancestor) {
+                // Insert this node's attributes into any outline descendant, including this node.
+                lint_attrs(sema, ancestor, edition).for_each(|(lint, severity)| {
+                    if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) {
+                        diag_severity = Some(severity);
+                    }
+
+                    for item in &*cache_stack {
+                        let node_cache_entry = cache
+                            .get_mut(item)
+                            .expect("we always insert cached nodes into the cache map");
+                        let lint_cache_entry = node_cache_entry.entry(lint.clone());
+                        if let hash_map::Entry::Vacant(lint_cache_entry) = lint_cache_entry {
+                            // Do not overwrite existing lint attributes, as we go bottom to top and bottom attrs
+                            // overwrite top attrs.
+                            lint_cache_entry.insert(SeverityAttr { severity, depth });
+                        }
+                    }
+                });
+            }
+
+            let parent_node = sema.find_parent_file(node.file_id);
+            if let Some(parent_node) = parent_node {
+                let parent_severity =
+                    fill_lint_attrs(sema, &parent_node, cache, cache_stack, diag, edition);
+                if diag_severity.is_none() {
+                    diag_severity = parent_severity;
+                }
+            }
+            cache_stack.pop();
+            return diag_severity;
+        } else if let Some(ancestor) = ast::AnyHasAttrs::cast(ancestor) {
+            lint_attrs(sema, ancestor, edition).for_each(|(lint, severity)| {
+                if diag_severity.is_none() && lint_groups(&diag.code).contains(&&*lint) {
+                    diag_severity = Some(severity);
+                }
+
+                let lint_cache_entry = collected_lint_attrs.entry(lint);
+                if let hash_map::Entry::Vacant(lint_cache_entry) = lint_cache_entry {
+                    // Do not overwrite existing lint attributes, as we go bottom to top and bottom attrs
+                    // overwrite top attrs.
+                    lint_cache_entry.insert(SeverityAttr { severity, depth });
+                }
+            });
+        }
+    }
+}
+
+fn lint_attrs<'a>(
+    sema: &'a Semantics<'a, RootDatabase>,
+    ancestor: ast::AnyHasAttrs,
+    edition: Edition,
+) -> impl Iterator<Item = (SmolStr, Severity)> + 'a {
+    ancestor
+        .attrs_including_inner()
+        .filter_map(|attr| {
+            attr.as_simple_call().and_then(|(name, value)| match &*name {
+                "allow" | "expect" => Some(Either::Left(iter::once((Severity::Allow, value)))),
+                "warn" => Some(Either::Left(iter::once((Severity::Warning, value)))),
+                "forbid" | "deny" => Some(Either::Left(iter::once((Severity::Error, value)))),
+                "cfg_attr" => {
+                    let mut lint_attrs = Vec::new();
+                    cfg_attr_lint_attrs(sema, &value, &mut lint_attrs);
+                    Some(Either::Right(lint_attrs.into_iter()))
+                }
+                _ => None,
+            })
+        })
+        .flatten()
+        .flat_map(move |(severity, lints)| {
+            parse_tt_as_comma_sep_paths(lints, edition).into_iter().flat_map(move |lints| {
+                // Rejoin the idents with `::`, so we have no spaces in between.
+                lints.into_iter().map(move |lint| {
+                    (
+                        lint.segments().filter_map(|segment| segment.name_ref()).join("::").into(),
+                        severity,
+                    )
+                })
+            })
+        })
+}
+
+fn cfg_attr_lint_attrs(
+    sema: &Semantics<'_, RootDatabase>,
+    value: &ast::TokenTree,
+    lint_attrs: &mut Vec<(Severity, ast::TokenTree)>,
+) {
+    let prev_len = lint_attrs.len();
+
+    let mut iter = value.token_trees_and_tokens().filter(|it| match it {
+        NodeOrToken::Node(_) => true,
+        NodeOrToken::Token(it) => !it.kind().is_trivia(),
+    });
+
+    // Skip the condition.
+    for value in &mut iter {
+        if value.as_token().is_some_and(|it| it.kind() == T![,]) {
+            break;
+        }
+    }
+
+    while let Some(value) = iter.next() {
+        if let Some(token) = value.as_token() {
+            if token.kind() == SyntaxKind::IDENT {
+                let severity = match token.text() {
+                    "allow" | "expect" => Some(Severity::Allow),
+                    "warn" => Some(Severity::Warning),
+                    "forbid" | "deny" => Some(Severity::Error),
+                    "cfg_attr" => {
+                        if let Some(NodeOrToken::Node(value)) = iter.next() {
+                            cfg_attr_lint_attrs(sema, &value, lint_attrs);
+                        }
+                        None
+                    }
+                    _ => None,
+                };
+                if let Some(severity) = severity {
+                    let lints = iter.next();
+                    if let Some(NodeOrToken::Node(lints)) = lints {
+                        lint_attrs.push((severity, lints));
+                    }
                 }
             }
         }
     }
+
+    if prev_len != lint_attrs.len() {
+        if let Some(false) | None = sema.check_cfg_attr(value) {
+            // Discard the attributes when the condition is false.
+            lint_attrs.truncate(prev_len);
+        }
+    }
+}
+
+fn lint_groups(lint: &DiagnosticCode) -> &'static [&'static str] {
+    match lint {
+        DiagnosticCode::RustcLint(name) => {
+            RUSTC_LINT_GROUPS_DICT.get(name).map(|it| &**it).unwrap_or_default()
+        }
+        DiagnosticCode::Clippy(name) => {
+            CLIPPY_LINT_GROUPS_DICT.get(name).map(|it| &**it).unwrap_or_default()
+        }
+        _ => &[],
+    }
 }
 
 fn fix(id: &'static str, label: &str, source_change: SourceChange, target: TextRange) -> Assist {
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index 925ae62..ea16a11 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -219,7 +219,9 @@
         | Definition::Local(_)
         | Definition::GenericParam(_)
         | Definition::Label(_)
-        | Definition::DeriveHelper(_) => None,
+        | Definition::DeriveHelper(_)
+        | Definition::InlineAsmRegOrRegClass(_)
+        | Definition::InlineAsmOperand(_) => None,
     }
     .map(Definition::from)
 }
@@ -672,7 +674,9 @@
         | Definition::BuiltinAttr(_)
         | Definition::BuiltinLifetime(_)
         | Definition::ToolModule(_)
-        | Definition::DeriveHelper(_) => return None,
+        | Definition::DeriveHelper(_)
+        | Definition::InlineAsmRegOrRegClass(_)
+        | Definition::InlineAsmOperand(_) => return None,
     };
 
     Some((def, res, None))
diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs
index a939ed2..79fdf75 100644
--- a/crates/ide/src/expand_macro.rs
+++ b/crates/ide/src/expand_macro.rs
@@ -1,9 +1,10 @@
+use hir::db::ExpandDatabase;
 use hir::{InFile, MacroFileIdExt, Semantics};
+use ide_db::base_db::CrateId;
 use ide_db::{
-    helpers::pick_best_token, syntax_helpers::insert_whitespace_into_node::insert_ws_into, FileId,
-    RootDatabase,
+    helpers::pick_best_token, syntax_helpers::prettify_macro_expansion, FileId, RootDatabase,
 };
-use span::Edition;
+use span::{Edition, SpanMap, SyntaxContextId, TextRange, TextSize};
 use syntax::{ast, ted, AstNode, NodeOrToken, SyntaxKind, SyntaxNode, T};
 
 use crate::FilePosition;
@@ -27,6 +28,7 @@
 pub(crate) fn expand_macro(db: &RootDatabase, position: FilePosition) -> Option<ExpandedMacro> {
     let sema = Semantics::new(db);
     let file = sema.parse_guess_edition(position.file_id);
+    let krate = sema.file_to_module_def(position.file_id)?.krate().into();
 
     let tok = pick_best_token(file.syntax().token_at_offset(position.offset), |kind| match kind {
         SyntaxKind::IDENT => 1,
@@ -61,8 +63,17 @@
             .take_while(|it| it != &token)
             .filter(|it| it.kind() == T![,])
             .count();
-        let expansion =
-            format(db, SyntaxKind::MACRO_ITEMS, position.file_id, expansions.get(idx).cloned()?);
+        let expansion = expansions.get(idx)?.clone();
+        let expansion_file_id = sema.hir_file_for(&expansion).macro_file()?;
+        let expansion_span_map = db.expansion_span_map(expansion_file_id);
+        let expansion = format(
+            db,
+            SyntaxKind::MACRO_ITEMS,
+            position.file_id,
+            expansion,
+            &expansion_span_map,
+            krate,
+        );
         Some(ExpandedMacro { name, expansion })
     });
 
@@ -71,6 +82,7 @@
     }
 
     let mut anc = tok.parent_ancestors();
+    let mut span_map = SpanMap::empty();
     let (name, expanded, kind) = loop {
         let node = anc.next()?;
 
@@ -85,7 +97,7 @@
                                 .unwrap_or(Edition::CURRENT),
                         )
                         .to_string(),
-                    expand_macro_recur(&sema, &item)?,
+                    expand_macro_recur(&sema, &item, &mut span_map, TextSize::new(0))?,
                     SyntaxKind::MACRO_ITEMS,
                 );
             }
@@ -95,14 +107,23 @@
             name.push('!');
             let syntax_kind =
                 mac.syntax().parent().map(|it| it.kind()).unwrap_or(SyntaxKind::MACRO_ITEMS);
-            break (name, expand_macro_recur(&sema, &ast::Item::MacroCall(mac))?, syntax_kind);
+            break (
+                name,
+                expand_macro_recur(
+                    &sema,
+                    &ast::Item::MacroCall(mac),
+                    &mut span_map,
+                    TextSize::new(0),
+                )?,
+                syntax_kind,
+            );
         }
     };
 
     // FIXME:
     // macro expansion may lose all white space information
     // But we hope someday we can use ra_fmt for that
-    let expansion = format(db, kind, position.file_id, expanded);
+    let expansion = format(db, kind, position.file_id, expanded, &span_map, krate);
 
     Some(ExpandedMacro { name, expansion })
 }
@@ -110,6 +131,8 @@
 fn expand_macro_recur(
     sema: &Semantics<'_, RootDatabase>,
     macro_call: &ast::Item,
+    result_span_map: &mut SpanMap<SyntaxContextId>,
+    offset_in_original_node: TextSize,
 ) -> Option<SyntaxNode> {
     let expanded = match macro_call {
         item @ ast::Item::MacroCall(macro_call) => sema
@@ -118,29 +141,60 @@
             .clone_for_update(),
         item => sema.expand_attr_macro(item)?.clone_for_update(),
     };
-    expand(sema, expanded)
+    let file_id =
+        sema.hir_file_for(&expanded).macro_file().expect("expansion must produce a macro file");
+    let expansion_span_map = sema.db.expansion_span_map(file_id);
+    result_span_map.merge(
+        TextRange::at(offset_in_original_node, macro_call.syntax().text_range().len()),
+        expanded.text_range().len(),
+        &expansion_span_map,
+    );
+    Some(expand(sema, expanded, result_span_map, u32::from(offset_in_original_node) as i32))
 }
 
-fn expand(sema: &Semantics<'_, RootDatabase>, expanded: SyntaxNode) -> Option<SyntaxNode> {
+fn expand(
+    sema: &Semantics<'_, RootDatabase>,
+    expanded: SyntaxNode,
+    result_span_map: &mut SpanMap<SyntaxContextId>,
+    mut offset_in_original_node: i32,
+) -> SyntaxNode {
     let children = expanded.descendants().filter_map(ast::Item::cast);
     let mut replacements = Vec::new();
 
     for child in children {
-        if let Some(new_node) = expand_macro_recur(sema, &child) {
+        if let Some(new_node) = expand_macro_recur(
+            sema,
+            &child,
+            result_span_map,
+            TextSize::new(
+                (offset_in_original_node + (u32::from(child.syntax().text_range().start()) as i32))
+                    as u32,
+            ),
+        ) {
+            offset_in_original_node = offset_in_original_node
+                + (u32::from(new_node.text_range().len()) as i32)
+                - (u32::from(child.syntax().text_range().len()) as i32);
             // check if the whole original syntax is replaced
             if expanded == *child.syntax() {
-                return Some(new_node);
+                return new_node;
             }
             replacements.push((child, new_node));
         }
     }
 
     replacements.into_iter().rev().for_each(|(old, new)| ted::replace(old.syntax(), new));
-    Some(expanded)
+    expanded
 }
 
-fn format(db: &RootDatabase, kind: SyntaxKind, file_id: FileId, expanded: SyntaxNode) -> String {
-    let expansion = insert_ws_into(expanded).to_string();
+fn format(
+    db: &RootDatabase,
+    kind: SyntaxKind,
+    file_id: FileId,
+    expanded: SyntaxNode,
+    span_map: &SpanMap<SyntaxContextId>,
+    krate: CrateId,
+) -> String {
+    let expansion = prettify_macro_expansion(db, expanded, span_map, krate).to_string();
 
     _format(db, kind, file_id, &expansion).unwrap_or(expansion)
 }
@@ -498,7 +552,7 @@
 "#,
             expect![[r#"
                 Clone
-                impl < >$crate::clone::Clone for Foo< >where {
+                impl < >core::clone::Clone for Foo< >where {
                     fn clone(&self) -> Self {
                         match self {
                             Foo{}
@@ -524,7 +578,7 @@
 "#,
             expect![[r#"
                 Copy
-                impl < >$crate::marker::Copy for Foo< >where{}"#]],
+                impl < >core::marker::Copy for Foo< >where{}"#]],
         );
     }
 
@@ -539,7 +593,7 @@
 "#,
             expect![[r#"
                 Copy
-                impl < >$crate::marker::Copy for Foo< >where{}"#]],
+                impl < >core::marker::Copy for Foo< >where{}"#]],
         );
         check(
             r#"
@@ -550,7 +604,7 @@
 "#,
             expect![[r#"
                 Clone
-                impl < >$crate::clone::Clone for Foo< >where {
+                impl < >core::clone::Clone for Foo< >where {
                     fn clone(&self) -> Self {
                         match self {
                             Foo{}
@@ -563,4 +617,44 @@
                     }"#]],
         );
     }
+
+    #[test]
+    fn dollar_crate() {
+        check(
+            r#"
+//- /a.rs crate:a
+pub struct Foo;
+#[macro_export]
+macro_rules! m {
+    ( $i:ident ) => { $crate::Foo; $crate::Foo; $i::Foo; };
+}
+//- /b.rs crate:b deps:a
+pub struct Foo;
+#[macro_export]
+macro_rules! m {
+    () => { a::m!($crate); $crate::Foo; $crate::Foo; };
+}
+//- /c.rs crate:c deps:b,a
+pub struct Foo;
+#[macro_export]
+macro_rules! m {
+    () => { b::m!(); $crate::Foo; $crate::Foo; };
+}
+fn bar() {
+    m$0!();
+}
+"#,
+            expect![[r#"
+m!
+a::Foo;
+a::Foo;
+b::Foo;
+;
+b::Foo;
+b::Foo;
+;
+crate::Foo;
+crate::Foo;"#]],
+        );
+    }
 }
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 971cd3e..8836166 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -2750,4 +2750,36 @@
         "#,
         );
     }
+
+    #[test]
+    fn issue_18138() {
+        check(
+            r#"
+mod foo {
+    macro_rules! x {
+        () => {
+            pub struct Foo;
+                    // ^^^
+        };
+    }
+    pub(crate) use x as m;
+}
+
+mod bar {
+    use crate::m;
+
+    m!();
+ // ^^^^^
+
+    fn qux() {
+        Foo$0;
+    }
+}
+
+mod m {}
+
+use foo::m;
+"#,
+        );
+    }
 }
diff --git a/crates/ide/src/highlight_related.rs b/crates/ide/src/highlight_related.rs
index 5348e85..4c8e3fc 100644
--- a/crates/ide/src/highlight_related.rs
+++ b/crates/ide/src/highlight_related.rs
@@ -2007,4 +2007,34 @@
 "#,
         )
     }
+
+    #[test]
+    fn asm() {
+        check(
+            r#"
+//- minicore: asm
+#[inline]
+pub unsafe fn bootstrap() -> ! {
+    builtin#asm(
+        "blabla",
+        "mrs {tmp}, CONTROL",
+           // ^^^ read
+        "blabla",
+        "bics {tmp}, {spsel}",
+            // ^^^ read
+        "blabla",
+        "msr CONTROL, {tmp}",
+                    // ^^^ read
+        "blabla",
+        tmp$0 = inout(reg) 0,
+     // ^^^
+        aaa = in(reg) 2,
+        aaa = in(reg) msp,
+        aaa = in(reg) rv,
+        options(noreturn, nomem, nostack),
+    );
+}
+"#,
+        )
+    }
 }
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index 3e41b42..83adf65 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -3,8 +3,9 @@
 
 use either::Either;
 use hir::{
-    Adt, AsAssocItem, AsExternAssocItem, CaptureKind, HasCrate, HasSource, HirDisplay, Layout,
-    LayoutError, Name, Semantics, Trait, Type, TypeInfo,
+    db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind, HasCrate, HasSource,
+    HirDisplay, Layout, LayoutError, MethodViolationCode, Name, ObjectSafetyViolation, Semantics,
+    Trait, Type, TypeInfo,
 };
 use ide_db::{
     base_db::SourceDatabase,
@@ -12,7 +13,7 @@
     documentation::HasDocs,
     famous_defs::FamousDefs,
     generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
-    syntax_helpers::insert_whitespace_into_node,
+    syntax_helpers::prettify_macro_expansion,
     RootDatabase,
 };
 use itertools::Itertools;
@@ -328,7 +329,7 @@
     }
     let (is_clippy, lints) = match &*path {
         "feature" => (false, FEATURES),
-        "allow" | "deny" | "forbid" | "warn" => {
+        "allow" | "deny" | "expect" | "forbid" | "warn" => {
             let is_clippy = algo::non_trivia_sibling(token.clone().into(), Direction::Prev)
                 .filter(|t| t.kind() == T![:])
                 .and_then(|t| algo::non_trivia_sibling(t, Direction::Prev))
@@ -475,8 +476,9 @@
                 Err(_) => {
                     let source = it.source(db)?;
                     let mut body = source.value.body()?.syntax().clone();
-                    if source.file_id.is_macro() {
-                        body = insert_whitespace_into_node::insert_ws_into(body);
+                    if let Some(macro_file) = source.file_id.macro_file() {
+                        let span_map = db.expansion_span_map(macro_file);
+                        body = prettify_macro_expansion(db, body, &span_map, it.krate(db).into());
                     }
                     Some(body.to_string())
                 }
@@ -485,8 +487,9 @@
         Definition::Static(it) => {
             let source = it.source(db)?;
             let mut body = source.value.body()?.syntax().clone();
-            if source.file_id.is_macro() {
-                body = insert_whitespace_into_node::insert_ws_into(body);
+            if let Some(macro_file) = source.file_id.macro_file() {
+                let span_map = db.expansion_span_map(macro_file);
+                body = prettify_macro_expansion(db, body, &span_map, it.krate(db).into());
             }
             Some(body.to_string())
         }
@@ -526,6 +529,14 @@
         _ => None,
     };
 
+    let object_safety_info = if let Definition::Trait(it) = def {
+        let mut object_safety_info = String::new();
+        render_object_safety(db, &mut object_safety_info, it.object_safety(db));
+        Some(object_safety_info)
+    } else {
+        None
+    };
+
     let mut desc = String::new();
     if let Some(notable_traits) = render_notable_trait_comment(db, notable_traits, edition) {
         desc.push_str(&notable_traits);
@@ -535,6 +546,10 @@
         desc.push_str(&layout_info);
         desc.push('\n');
     }
+    if let Some(object_safety_info) = object_safety_info {
+        desc.push_str(&object_safety_info);
+        desc.push('\n');
+    }
     desc.push_str(&label);
     if let Some(value) = value {
         desc.push_str(" = ");
@@ -964,3 +979,62 @@
         _ => KeywordHint::new(token.text().to_owned(), format!("{}_keyword", token.text())),
     }
 }
+
+fn render_object_safety(
+    db: &RootDatabase,
+    buf: &mut String,
+    safety: Option<ObjectSafetyViolation>,
+) {
+    let Some(osv) = safety else {
+        buf.push_str("// Object Safety: Yes");
+        return;
+    };
+    buf.push_str("// Object Safety: No\n// - Reason: ");
+    match osv {
+        ObjectSafetyViolation::SizedSelf => {
+            buf.push_str("has a `Self: Sized` bound");
+        }
+        ObjectSafetyViolation::SelfReferential => {
+            buf.push_str("has a bound that references `Self`");
+        }
+        ObjectSafetyViolation::Method(func, mvc) => {
+            let name = hir::Function::from(func).name(db);
+            format_to!(
+                buf,
+                "has a method `{}` that is non dispatchable because of:\n//   - ",
+                name.as_str()
+            );
+            let desc = match mvc {
+                MethodViolationCode::StaticMethod => "missing a receiver",
+                MethodViolationCode::ReferencesSelfInput => "a parameter references `Self`",
+                MethodViolationCode::ReferencesSelfOutput => "the return type references `Self`",
+                MethodViolationCode::ReferencesImplTraitInTrait => {
+                    "the return type contains `impl Trait`"
+                }
+                MethodViolationCode::AsyncFn => "being async",
+                MethodViolationCode::WhereClauseReferencesSelf => {
+                    "a where clause references `Self`"
+                }
+                MethodViolationCode::Generic => "a non-lifetime generic parameter",
+                MethodViolationCode::UndispatchableReceiver => "a non-dispatchable receiver type",
+            };
+            buf.push_str(desc);
+        }
+        ObjectSafetyViolation::AssocConst(const_) => {
+            let name = hir::Const::from(const_).name(db);
+            if let Some(name) = name {
+                format_to!(buf, "has an associated constant `{}`", name.as_str());
+            } else {
+                buf.push_str("has an associated constant");
+            }
+        }
+        ObjectSafetyViolation::GAT(alias) => {
+            let name = hir::TypeAlias::from(alias).name(db);
+            format_to!(buf, "has a generic associated type `{}`", name.as_str());
+        }
+        ObjectSafetyViolation::HasNonSafeSuperTrait(super_trait) => {
+            let name = hir::Trait::from(super_trait).name(db);
+            format_to!(buf, "has a object unsafe supertrait `{}`", name.as_str());
+        }
+    }
+}
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index 9585bdb..cca62d2 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -182,13 +182,26 @@
 
 fn check_actions(ra_fixture: &str, expect: Expect) {
     let (analysis, file_id, position) = fixture::range_or_position(ra_fixture);
-    let hover = analysis
+    let mut hover = analysis
         .hover(
             &HoverConfig { links_in_hover: true, ..HOVER_BASE_CONFIG },
             FileRange { file_id, range: position.range_or_empty() },
         )
         .unwrap()
         .unwrap();
+    // stub out ranges into minicore as they can change every now and then
+    hover.info.actions.iter_mut().for_each(|action| match action {
+        super::HoverAction::GoToType(act) => act.iter_mut().for_each(|data| {
+            if data.nav.file_id == file_id {
+                return;
+            }
+            data.nav.full_range = TextRange::empty(span::TextSize::new(!0));
+            if let Some(range) = &mut data.nav.focus_range {
+                *range = TextRange::empty(span::TextSize::new(!0));
+            }
+        }),
+        _ => (),
+    });
     expect.assert_debug_eq(&hover.info.actions)
 }
 
@@ -200,10 +213,23 @@
 
 fn check_hover_range_actions(ra_fixture: &str, expect: Expect) {
     let (analysis, range) = fixture::range(ra_fixture);
-    let hover = analysis
+    let mut hover = analysis
         .hover(&HoverConfig { links_in_hover: true, ..HOVER_BASE_CONFIG }, range)
         .unwrap()
         .unwrap();
+    // stub out ranges into minicore as they can change every now and then
+    hover.info.actions.iter_mut().for_each(|action| match action {
+        super::HoverAction::GoToType(act) => act.iter_mut().for_each(|data| {
+            if data.nav.file_id == range.file_id {
+                return;
+            }
+            data.nav.full_range = TextRange::empty(span::TextSize::new(!0));
+            if let Some(range) = &mut data.nav.focus_range {
+                *range = TextRange::empty(span::TextSize::new(!0));
+            }
+        }),
+        _ => (),
+    });
     expect.assert_debug_eq(&hover.info.actions);
 }
 
@@ -483,8 +509,8 @@
                                 file_id: FileId(
                                     1,
                                 ),
-                                full_range: 632..867,
-                                focus_range: 693..699,
+                                full_range: 4294967295..4294967295,
+                                focus_range: 4294967295..4294967295,
                                 name: "FnOnce",
                                 kind: Trait,
                                 container_name: "function",
@@ -1471,6 +1497,24 @@
 }
 
 #[test]
+fn hover_unsigned_max_const() {
+    check(
+        r#"const $0A: u128 = -1_i128 as u128;"#,
+        expect![[r#"
+            *A*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            const A: u128 = 340282366920938463463374607431768211455 (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)
+            ```
+        "#]],
+    );
+}
+
+#[test]
 fn hover_eval_complex_constants() {
     check(
         r#"
@@ -3104,26 +3148,26 @@
 fn main() { let s$0t = S{ f1:0 }; }
 "#,
         expect![[r#"
-                [
-                    GoToType(
-                        [
-                            HoverGotoTypeData {
-                                mod_path: "test::S",
-                                nav: NavigationTarget {
-                                    file_id: FileId(
-                                        0,
-                                    ),
-                                    full_range: 0..19,
-                                    focus_range: 7..8,
-                                    name: "S",
-                                    kind: Struct,
-                                    description: "struct S",
-                                },
+            [
+                GoToType(
+                    [
+                        HoverGotoTypeData {
+                            mod_path: "test::S",
+                            nav: NavigationTarget {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                full_range: 0..19,
+                                focus_range: 7..8,
+                                name: "S",
+                                kind: Struct,
+                                description: "struct S",
                             },
-                        ],
-                    ),
-                ]
-            "#]],
+                        },
+                    ],
+                ),
+            ]
+        "#]],
     );
 }
 
@@ -3616,8 +3660,8 @@
                                 file_id: FileId(
                                     1,
                                 ),
-                                full_range: 21..69,
-                                focus_range: 60..66,
+                                full_range: 4294967295..4294967295,
+                                focus_range: 4294967295..4294967295,
                                 name: "Future",
                                 kind: Trait,
                                 container_name: "future",
@@ -5442,7 +5486,7 @@
 fn hover_const_eval_dyn_trait() {
     check(
         r#"
-//- minicore: fmt, coerce_unsized, builtin_impls
+//- minicore: fmt, coerce_unsized, builtin_impls, dispatch_from_dyn
 use core::fmt::Debug;
 
 const FOO$0: &dyn Debug = &2i32;
@@ -6292,7 +6336,19 @@
 
                 arithmetic operation overflows
             "#]],
-    )
+    );
+    check(
+        r#"#![expect(arithmetic_overflow$0)]"#,
+        expect![[r#"
+                *arithmetic_overflow*
+                ```
+                arithmetic_overflow
+                ```
+                ___
+
+                arithmetic operation overflows
+            "#]],
+    );
 }
 
 #[test]
@@ -6308,7 +6364,19 @@
 
                 Checks for `foo = bar; bar = foo` sequences.
             "#]],
-    )
+    );
+    check(
+        r#"#![expect(clippy::almost_swapped$0)]"#,
+        expect![[r#"
+                *almost_swapped*
+                ```
+                clippy::almost_swapped
+                ```
+                ___
+
+                Checks for `foo = bar; bar = foo` sequences.
+            "#]],
+    );
 }
 
 #[test]
@@ -7107,6 +7175,7 @@
             ```
 
             ```rust
+            // Object Safety: Yes
             trait T {}
             ```
         "#]],
@@ -7126,6 +7195,7 @@
             ```
 
             ```rust
+            // Object Safety: Yes
             trait T {}
             ```
         "#]],
@@ -7149,6 +7219,9 @@
             ```
 
             ```rust
+            // Object Safety: No
+            // - Reason: has a method `func` that is non dispatchable because of:
+            //   - missing a receiver
             trait T { /* … */ }
             ```
         "#]],
@@ -7172,6 +7245,9 @@
             ```
 
             ```rust
+            // Object Safety: No
+            // - Reason: has a method `func` that is non dispatchable because of:
+            //   - missing a receiver
             trait T {
                 fn func();
                 const FLAG: i32;
@@ -7199,6 +7275,9 @@
             ```
 
             ```rust
+            // Object Safety: No
+            // - Reason: has a method `func` that is non dispatchable because of:
+            //   - missing a receiver
             trait T {
                 fn func();
                 const FLAG: i32;
@@ -7226,6 +7305,9 @@
             ```
 
             ```rust
+            // Object Safety: No
+            // - Reason: has a method `func` that is non dispatchable because of:
+            //   - missing a receiver
             trait T {
                 fn func();
                 const FLAG: i32;
@@ -8465,8 +8547,8 @@
                                 file_id: FileId(
                                     1,
                                 ),
-                                full_range: 7800..8042,
-                                focus_range: 7865..7871,
+                                full_range: 4294967295..4294967295,
+                                focus_range: 4294967295..4294967295,
                                 name: "Future",
                                 kind: Trait,
                                 container_name: "future",
@@ -8479,8 +8561,8 @@
                                 file_id: FileId(
                                     1,
                                 ),
-                                full_range: 8672..9171,
-                                focus_range: 8749..8757,
+                                full_range: 4294967295..4294967295,
+                                focus_range: 4294967295..4294967295,
                                 name: "Iterator",
                                 kind: Trait,
                                 container_name: "iterator",
@@ -8702,3 +8784,181 @@
         "#]],
     );
 }
+
+#[test]
+fn test_hover_function_with_pat_param() {
+    check(
+        r#"fn test_1$0((start_range, end_range): (u32, u32), a: i32) {}"#,
+        expect![[r#"
+            *test_1*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_1((start_range, end_range): (u32, u32), a: i32)
+            ```
+        "#]],
+    );
+
+    // Test case with tuple pattern and mutable parameters
+    check(
+        r#"fn test_2$0((mut x, y): (i32, i32)) {}"#,
+        expect![[r#"
+            *test_2*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_2((mut x, y): (i32, i32))
+            ```
+        "#]],
+    );
+
+    // Test case with a pattern in a reference type
+    check(
+        r#"fn test_3$0(&(a, b): &(i32, i32)) {}"#,
+        expect![[r#"
+            *test_3*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_3(&(a, b): &(i32, i32))
+            ```
+        "#]],
+    );
+
+    // Test case with complex pattern (struct destructuring)
+    check(
+        r#"struct Point { x: i32, y: i32 } fn test_4$0(Point { x, y }: Point) {}"#,
+        expect![[r#"
+            *test_4*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_4(Point { x, y }: Point)
+            ```
+        "#]],
+    );
+
+    // Test case with a nested pattern
+    check(
+        r#"fn test_5$0(((a, b), c): ((i32, i32), i32)) {}"#,
+        expect![[r#"
+            *test_5*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_5(((a, b), c): ((i32, i32), i32))
+            ```
+        "#]],
+    );
+
+    // Test case with an unused variable in the pattern
+    check(
+        r#"fn test_6$0((_, y): (i32, i64)) {}"#,
+        expect![[r#"
+            *test_6*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_6((_, y): (i32, i64))
+            ```
+        "#]],
+    );
+
+    // Test case with a complex pattern involving both tuple and struct
+    check(
+        r#"struct Foo { a: i32, b: i32 } fn test_7$0((x, Foo { a, b }): (i32, Foo)) {}"#,
+        expect![[r#"
+            *test_7*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_7((x, Foo { a, b }): (i32, Foo))
+            ```
+        "#]],
+    );
+
+    // Test case with Enum and Or pattern
+    check(
+        r#"enum MyEnum { A(i32), B(i32) } fn test_8$0((MyEnum::A(x) | MyEnum::B(x)): MyEnum) {}"#,
+        expect![[r#"
+            *test_8*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_8((MyEnum::A(x) | MyEnum::B(x)): MyEnum)
+            ```
+        "#]],
+    );
+
+    // Test case with a pattern as a function parameter
+    check(
+        r#"struct Foo { a: i32, b: i32 } fn test_9$0(Foo { a, b }: Foo) {}"#,
+        expect![[r#"
+            *test_9*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_9(Foo { a, b }: Foo)
+            ```
+        "#]],
+    );
+
+    // Test case with a pattern as a function parameter with a different name
+    check(
+        r#"struct Foo { a: i32, b: i32 } fn test_10$0(Foo { a, b: b1 }: Foo) {}"#,
+        expect![[r#"
+            *test_10*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_10(Foo { a, b: b1 }: Foo)
+            ```
+        "#]],
+    );
+
+    // Test case with a pattern as a function parameter with annotations
+    check(
+        r#"struct Foo { a: i32, b: i32 } fn test_10$0(Foo { a, b: mut b }: Foo) {}"#,
+        expect![[r#"
+            *test_10*
+
+            ```rust
+            test
+            ```
+
+            ```rust
+            fn test_10(Foo { a, b: mut b }: Foo)
+            ```
+        "#]],
+    );
+}
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 6a5d5e2..97e7123 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -14,8 +14,8 @@
 use span::{Edition, EditionedFileId};
 use stdx::never;
 use syntax::{
-    ast::{self, AstNode},
-    match_ast, NodeOrToken, SyntaxNode, TextRange, TextSize,
+    ast::{self, AstNode, HasGenericParams},
+    format_smolstr, match_ast, SmolStr, SyntaxNode, TextRange, TextSize, WalkEvent,
 };
 use text_edit::TextEdit;
 
@@ -29,13 +29,230 @@
 mod closure_captures;
 mod closure_ret;
 mod discriminant;
-mod fn_lifetime_fn;
 mod generic_param;
 mod implicit_drop;
 mod implicit_static;
+mod lifetime;
 mod param_name;
 mod range_exclusive;
 
+// Feature: Inlay Hints
+//
+// rust-analyzer shows additional information inline with the source code.
+// Editors usually render this using read-only virtual text snippets interspersed with code.
+//
+// rust-analyzer by default shows hints for
+//
+// * types of local variables
+// * names of function arguments
+// * names of const generic parameters
+// * types of chained expressions
+//
+// Optionally, one can enable additional hints for
+//
+// * return types of closure expressions
+// * elided lifetimes
+// * compiler inserted reborrows
+// * names of generic type and lifetime parameters
+//
+// Note: inlay hints for function argument names are heuristically omitted to reduce noise and will not appear if
+// any of the
+// link:https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L92-L99[following criteria]
+// are met:
+//
+// * the parameter name is a suffix of the function's name
+// * the argument is a qualified constructing or call expression where the qualifier is an ADT
+// * exact argument<->parameter match(ignoring leading underscore) or parameter is a prefix/suffix
+//   of argument with _ splitting it off
+// * the parameter name starts with `ra_fixture`
+// * the parameter name is a
+// link:https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L200[well known name]
+// in a unary function
+// * the parameter name is a
+// link:https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L201[single character]
+// in a unary function
+//
+// image::https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png[]
+pub(crate) fn inlay_hints(
+    db: &RootDatabase,
+    file_id: FileId,
+    range_limit: Option<TextRange>,
+    config: &InlayHintsConfig,
+) -> Vec<InlayHint> {
+    let _p = tracing::info_span!("inlay_hints").entered();
+    let sema = Semantics::new(db);
+    let file_id = sema
+        .attach_first_edition(file_id)
+        .unwrap_or_else(|| EditionedFileId::current_edition(file_id));
+    let file = sema.parse(file_id);
+    let file = file.syntax();
+
+    let mut acc = Vec::new();
+
+    let Some(scope) = sema.scope(file) else {
+        return acc;
+    };
+    let famous_defs = FamousDefs(&sema, scope.krate());
+
+    let ctx = &mut InlayHintCtx::default();
+    let mut hints = |event| {
+        if let Some(node) = handle_event(ctx, event) {
+            hints(&mut acc, ctx, &famous_defs, config, file_id, node);
+        }
+    };
+    let mut preorder = file.preorder();
+    while let Some(event) = preorder.next() {
+        // FIXME: This can miss some hints that require the parent of the range to calculate
+        if matches!((&event, range_limit), (WalkEvent::Enter(node), Some(range)) if range.intersect(node.text_range()).is_none())
+        {
+            preorder.skip_subtree();
+            continue;
+        }
+        hints(event);
+    }
+    acc
+}
+
+#[derive(Default)]
+struct InlayHintCtx {
+    lifetime_stacks: Vec<Vec<SmolStr>>,
+}
+
+pub(crate) fn inlay_hints_resolve(
+    db: &RootDatabase,
+    file_id: FileId,
+    resolve_range: TextRange,
+    hash: u64,
+    config: &InlayHintsConfig,
+    hasher: impl Fn(&InlayHint) -> u64,
+) -> Option<InlayHint> {
+    let _p = tracing::info_span!("inlay_hints_resolve").entered();
+    let sema = Semantics::new(db);
+    let file_id = sema
+        .attach_first_edition(file_id)
+        .unwrap_or_else(|| EditionedFileId::current_edition(file_id));
+    let file = sema.parse(file_id);
+    let file = file.syntax();
+
+    let scope = sema.scope(file)?;
+    let famous_defs = FamousDefs(&sema, scope.krate());
+    let mut acc = Vec::new();
+
+    let ctx = &mut InlayHintCtx::default();
+    let mut hints = |event| {
+        if let Some(node) = handle_event(ctx, event) {
+            hints(&mut acc, ctx, &famous_defs, config, file_id, node);
+        }
+    };
+
+    let mut preorder = file.preorder();
+    while let Some(event) = preorder.next() {
+        // FIXME: This can miss some hints that require the parent of the range to calculate
+        if matches!(&event, WalkEvent::Enter(node) if resolve_range.intersect(node.text_range()).is_none())
+        {
+            preorder.skip_subtree();
+            continue;
+        }
+        hints(event);
+    }
+    acc.into_iter().find(|hint| hasher(hint) == hash)
+}
+
+fn handle_event(ctx: &mut InlayHintCtx, node: WalkEvent<SyntaxNode>) -> Option<SyntaxNode> {
+    match node {
+        WalkEvent::Enter(node) => {
+            if let Some(node) = ast::AnyHasGenericParams::cast(node.clone()) {
+                let params = node
+                    .generic_param_list()
+                    .map(|it| {
+                        it.lifetime_params()
+                            .filter_map(|it| {
+                                it.lifetime().map(|it| format_smolstr!("{}", &it.text()[1..]))
+                            })
+                            .collect()
+                    })
+                    .unwrap_or_default();
+                ctx.lifetime_stacks.push(params);
+            }
+            Some(node)
+        }
+        WalkEvent::Leave(n) => {
+            if ast::AnyHasGenericParams::can_cast(n.kind()) {
+                ctx.lifetime_stacks.pop();
+            }
+            None
+        }
+    }
+}
+
+// FIXME: At some point when our hir infra is fleshed out enough we should flip this and traverse the
+// HIR instead of the syntax tree.
+fn hints(
+    hints: &mut Vec<InlayHint>,
+    ctx: &mut InlayHintCtx,
+    famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>,
+    config: &InlayHintsConfig,
+    file_id: EditionedFileId,
+    node: SyntaxNode,
+) {
+    closing_brace::hints(hints, sema, config, file_id, node.clone());
+    if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) {
+        generic_param::hints(hints, sema, config, any_has_generic_args);
+    }
+
+    match_ast! {
+        match node {
+            ast::Expr(expr) => {
+                chaining::hints(hints, famous_defs, config, file_id, &expr);
+                adjustment::hints(hints, famous_defs, config, file_id, &expr);
+                match expr {
+                    ast::Expr::CallExpr(it) => param_name::hints(hints, famous_defs, config, file_id, ast::Expr::from(it)),
+                    ast::Expr::MethodCallExpr(it) => {
+                        param_name::hints(hints, famous_defs, config, file_id, ast::Expr::from(it))
+                    }
+                    ast::Expr::ClosureExpr(it) => {
+                        closure_captures::hints(hints, famous_defs, config, file_id, it.clone());
+                        closure_ret::hints(hints, famous_defs, config, file_id, it)
+                    },
+                    ast::Expr::RangeExpr(it) => range_exclusive::hints(hints, famous_defs, config, file_id,  it),
+                    _ => Some(()),
+                }
+            },
+            ast::Pat(it) => {
+                binding_mode::hints(hints, famous_defs, config, file_id,  &it);
+                match it {
+                    ast::Pat::IdentPat(it) => {
+                        bind_pat::hints(hints, famous_defs, config, file_id, &it);
+                    }
+                    ast::Pat::RangePat(it) => {
+                        range_exclusive::hints(hints, famous_defs, config, file_id, it);
+                    }
+                    _ => {}
+                }
+                Some(())
+            },
+            ast::Item(it) => match it {
+                ast::Item::Fn(it) => {
+                    implicit_drop::hints(hints, famous_defs, config, file_id, &it);
+                    lifetime::fn_hints(hints, ctx, famous_defs, config, file_id, it)
+                },
+                // static type elisions
+                ast::Item::Static(it) => implicit_static::hints(hints, famous_defs, config, file_id, Either::Left(it)),
+                ast::Item::Const(it) => implicit_static::hints(hints, famous_defs, config, file_id, Either::Right(it)),
+                ast::Item::Enum(it) => discriminant::enum_hints(hints, famous_defs, config, file_id, it),
+                _ => None,
+            },
+            // FIXME: trait object type elisions
+            ast::Type(ty) => match ty {
+                ast::Type::FnPtrType(ptr) => lifetime::fn_ptr_hints(hints, ctx, famous_defs, config, file_id, ptr),
+                ast::Type::PathType(path) => lifetime::fn_path_hints(hints, ctx, famous_defs, config, file_id, path),
+                _ => Some(()),
+            },
+            _ => Some(()),
+        }
+    };
+}
+
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct InlayHintsConfig {
     pub render_colons: bool,
@@ -162,6 +379,9 @@
     pub label: InlayHintLabel,
     /// Text edit to apply when "accepting" this inlay hint.
     pub text_edit: Option<TextEdit>,
+    /// Range to recompute inlay hints when trying to resolve for this hint. If this is none, the
+    /// hint does not support resolving.
+    pub resolve_parent: Option<TextRange>,
 }
 
 impl std::hash::Hash for InlayHint {
@@ -186,6 +406,7 @@
             position: InlayHintPosition::After,
             pad_left: false,
             pad_right: false,
+            resolve_parent: None,
         }
     }
 
@@ -198,11 +419,12 @@
             position: InlayHintPosition::Before,
             pad_left: false,
             pad_right: false,
+            resolve_parent: None,
         }
     }
 
-    pub fn needs_resolve(&self) -> bool {
-        self.text_edit.is_some() || self.label.needs_resolve()
+    pub fn needs_resolve(&self) -> Option<TextRange> {
+        self.resolve_parent.filter(|_| self.text_edit.is_some() || self.label.needs_resolve())
     }
 }
 
@@ -355,11 +577,14 @@
 
 impl InlayHintLabelBuilder<'_> {
     fn make_new_part(&mut self) {
-        self.result.parts.push(InlayHintLabelPart {
-            text: take(&mut self.last_part),
-            linked_location: self.location.take(),
-            tooltip: None,
-        });
+        let text = take(&mut self.last_part);
+        if !text.is_empty() {
+            self.result.parts.push(InlayHintLabelPart {
+                text,
+                linked_location: self.location.take(),
+                tooltip: None,
+            });
+        }
     }
 
     fn finish(mut self) -> InlayHintLabel {
@@ -434,190 +659,6 @@
     Some(r)
 }
 
-fn ty_to_text_edit(
-    sema: &Semantics<'_, RootDatabase>,
-    node_for_hint: &SyntaxNode,
-    ty: &hir::Type,
-    offset_to_insert: TextSize,
-    prefix: String,
-) -> Option<TextEdit> {
-    let scope = sema.scope(node_for_hint)?;
-    // FIXME: Limit the length and bail out on excess somehow?
-    let rendered = ty.display_source_code(scope.db, scope.module().into(), false).ok()?;
-
-    let mut builder = TextEdit::builder();
-    builder.insert(offset_to_insert, prefix);
-    builder.insert(offset_to_insert, rendered);
-    Some(builder.finish())
-}
-
-// Feature: Inlay Hints
-//
-// rust-analyzer shows additional information inline with the source code.
-// Editors usually render this using read-only virtual text snippets interspersed with code.
-//
-// rust-analyzer by default shows hints for
-//
-// * types of local variables
-// * names of function arguments
-// * names of const generic parameters
-// * types of chained expressions
-//
-// Optionally, one can enable additional hints for
-//
-// * return types of closure expressions
-// * elided lifetimes
-// * compiler inserted reborrows
-// * names of generic type and lifetime parameters
-//
-// Note: inlay hints for function argument names are heuristically omitted to reduce noise and will not appear if
-// any of the
-// link:https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L92-L99[following criteria]
-// are met:
-//
-// * the parameter name is a suffix of the function's name
-// * the argument is a qualified constructing or call expression where the qualifier is an ADT
-// * exact argument<->parameter match(ignoring leading underscore) or parameter is a prefix/suffix
-//   of argument with _ splitting it off
-// * the parameter name starts with `ra_fixture`
-// * the parameter name is a
-// link:https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L200[well known name]
-// in a unary function
-// * the parameter name is a
-// link:https://github.com/rust-lang/rust-analyzer/blob/6b8b8ff4c56118ddee6c531cde06add1aad4a6af/crates/ide/src/inlay_hints/param_name.rs#L201[single character]
-// in a unary function
-//
-// image::https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png[]
-pub(crate) fn inlay_hints(
-    db: &RootDatabase,
-    file_id: FileId,
-    range_limit: Option<TextRange>,
-    config: &InlayHintsConfig,
-) -> Vec<InlayHint> {
-    let _p = tracing::info_span!("inlay_hints").entered();
-    let sema = Semantics::new(db);
-    let file_id = sema
-        .attach_first_edition(file_id)
-        .unwrap_or_else(|| EditionedFileId::current_edition(file_id));
-    let file = sema.parse(file_id);
-    let file = file.syntax();
-
-    let mut acc = Vec::new();
-
-    if let Some(scope) = sema.scope(file) {
-        let famous_defs = FamousDefs(&sema, scope.krate());
-
-        let hints = |node| hints(&mut acc, &famous_defs, config, file_id, node);
-        match range_limit {
-            Some(range) => match file.covering_element(range) {
-                NodeOrToken::Token(_) => return acc,
-                NodeOrToken::Node(n) => n
-                    .descendants()
-                    .filter(|descendant| range.intersect(descendant.text_range()).is_some())
-                    .for_each(hints),
-            },
-            None => file.descendants().for_each(hints),
-        };
-    }
-
-    acc
-}
-
-pub(crate) fn inlay_hints_resolve(
-    db: &RootDatabase,
-    file_id: FileId,
-    position: TextSize,
-    hash: u64,
-    config: &InlayHintsConfig,
-    hasher: impl Fn(&InlayHint) -> u64,
-) -> Option<InlayHint> {
-    let _p = tracing::info_span!("inlay_hints_resolve").entered();
-    let sema = Semantics::new(db);
-    let file_id = sema
-        .attach_first_edition(file_id)
-        .unwrap_or_else(|| EditionedFileId::current_edition(file_id));
-    let file = sema.parse(file_id);
-    let file = file.syntax();
-
-    let scope = sema.scope(file)?;
-    let famous_defs = FamousDefs(&sema, scope.krate());
-    let mut acc = Vec::new();
-
-    let hints = |node| hints(&mut acc, &famous_defs, config, file_id, node);
-    let token = file.token_at_offset(position).left_biased()?;
-    if let Some(parent_block) = token.parent_ancestors().find_map(ast::BlockExpr::cast) {
-        parent_block.syntax().descendants().for_each(hints)
-    } else if let Some(parent_item) = token.parent_ancestors().find_map(ast::Item::cast) {
-        parent_item.syntax().descendants().for_each(hints)
-    } else {
-        return None;
-    }
-
-    acc.into_iter().find(|hint| hasher(hint) == hash)
-}
-
-fn hints(
-    hints: &mut Vec<InlayHint>,
-    famous_defs @ FamousDefs(sema, _): &FamousDefs<'_, '_>,
-    config: &InlayHintsConfig,
-    file_id: EditionedFileId,
-    node: SyntaxNode,
-) {
-    closing_brace::hints(hints, sema, config, file_id, node.clone());
-    if let Some(any_has_generic_args) = ast::AnyHasGenericArgs::cast(node.clone()) {
-        generic_param::hints(hints, sema, config, any_has_generic_args);
-    }
-    match_ast! {
-        match node {
-            ast::Expr(expr) => {
-                chaining::hints(hints, famous_defs, config, file_id, &expr);
-                adjustment::hints(hints, sema, config, file_id, &expr);
-                match expr {
-                    ast::Expr::CallExpr(it) => param_name::hints(hints, sema, config, ast::Expr::from(it)),
-                    ast::Expr::MethodCallExpr(it) => {
-                        param_name::hints(hints, sema, config, ast::Expr::from(it))
-                    }
-                    ast::Expr::ClosureExpr(it) => {
-                        closure_captures::hints(hints, famous_defs, config, file_id, it.clone());
-                        closure_ret::hints(hints, famous_defs, config, file_id, it)
-                    },
-                    ast::Expr::RangeExpr(it) => range_exclusive::hints(hints, config, it),
-                    _ => None,
-                }
-            },
-            ast::Pat(it) => {
-                binding_mode::hints(hints, sema, config, &it);
-                match it {
-                    ast::Pat::IdentPat(it) => {
-                        bind_pat::hints(hints, famous_defs, config, file_id, &it);
-                    }
-                    ast::Pat::RangePat(it) => {
-                        range_exclusive::hints(hints, config, it);
-                    }
-                    _ => {}
-                }
-                Some(())
-            },
-            ast::Item(it) => match it {
-                // FIXME: record impl lifetimes so they aren't being reused in assoc item lifetime inlay hints
-                ast::Item::Impl(_) => None,
-                ast::Item::Fn(it) => {
-                    implicit_drop::hints(hints, sema, config, file_id, &it);
-                    fn_lifetime_fn::hints(hints, config, it)
-                },
-                // static type elisions
-                ast::Item::Static(it) => implicit_static::hints(hints, config, Either::Left(it)),
-                ast::Item::Const(it) => implicit_static::hints(hints, config, Either::Right(it)),
-                ast::Item::Enum(it) => discriminant::enum_hints(hints, famous_defs, config, file_id, it),
-                _ => None,
-            },
-            // FIXME: fn-ptr type, dyn fn type, and trait object type elisions
-            ast::Type(_) => None,
-            _ => None,
-        }
-    };
-}
-
 /// Checks if the type is an Iterator from std::iter and returns the iterator trait and the item type of the concrete iterator.
 fn hint_iterator(
     sema: &Semantics<'_, RootDatabase>,
@@ -653,6 +694,23 @@
     None
 }
 
+fn ty_to_text_edit(
+    sema: &Semantics<'_, RootDatabase>,
+    node_for_hint: &SyntaxNode,
+    ty: &hir::Type,
+    offset_to_insert: TextSize,
+    prefix: String,
+) -> Option<TextEdit> {
+    let scope = sema.scope(node_for_hint)?;
+    // FIXME: Limit the length and bail out on excess somehow?
+    let rendered = ty.display_source_code(scope.db, scope.module().into(), false).ok()?;
+
+    let mut builder = TextEdit::builder();
+    builder.insert(offset_to_insert, prefix);
+    builder.insert(offset_to_insert, rendered);
+    Some(builder.finish())
+}
+
 fn closure_has_block_body(closure: &ast::ClosureExpr) -> bool {
     matches!(closure.body(), Some(ast::Expr::BlockExpr(_)))
 }
diff --git a/crates/ide/src/inlay_hints/adjustment.rs b/crates/ide/src/inlay_hints/adjustment.rs
index 756198d..c37c469 100644
--- a/crates/ide/src/inlay_hints/adjustment.rs
+++ b/crates/ide/src/inlay_hints/adjustment.rs
@@ -6,9 +6,8 @@
 use either::Either;
 use hir::{
     Adjust, Adjustment, AutoBorrow, HirDisplay, Mutability, OverloadedDeref, PointerCast, Safety,
-    Semantics,
 };
-use ide_db::RootDatabase;
+use ide_db::famous_defs::FamousDefs;
 
 use span::EditionedFileId;
 use stdx::never;
@@ -24,7 +23,7 @@
 
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
-    sema: &Semantics<'_, RootDatabase>,
+    FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
     file_id: EditionedFileId,
     expr: &ast::Expr,
@@ -156,6 +155,7 @@
             kind: InlayKind::Adjustment,
             label,
             text_edit: None,
+            resolve_parent: Some(expr.syntax().text_range()),
         });
     }
     if !postfix && needs_inner_parens {
@@ -288,7 +288,7 @@
         check_with_config(
             InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG },
             r#"
-//- minicore: coerce_unsized, fn, eq, index
+//- minicore: coerce_unsized, fn, eq, index, dispatch_from_dyn
 fn main() {
     let _: u32         = loop {};
                        //^^^^^^^<never-to-any>
@@ -313,6 +313,7 @@
                        //^^^^^^^^^^^^<safe-fn-pointer-to-unsafe-fn-pointer>
                        //^^^^^^^^^^^^(
                        //^^^^^^^^^^^^)
+                       //^^^^<fn-item-to-fn-pointer>
     let _: fn()        = || {};
                        //^^^^^<closure-to-fn-pointer>
     let _: unsafe fn() = || {};
@@ -321,6 +322,8 @@
                        //^^^^^^^^^^^^^^^^^^^^^<mut-ptr-to-const-ptr>
                        //^^^^^^^^^^^^^^^^^^^^^(
                        //^^^^^^^^^^^^^^^^^^^^^)
+                       //^^^^^^^^^&raw mut $
+                       //^^^^^^^^^*
     let _: &mut [_]    = &mut [0; 0];
                        //^^^^^^^^^^^<unsize>
                        //^^^^^^^^^^^&mut $
@@ -428,7 +431,7 @@
                 ..DISABLED_CONFIG
             },
             r#"
-//- minicore: coerce_unsized, fn, eq, index
+//- minicore: coerce_unsized, fn, eq, index, dispatch_from_dyn
 fn main() {
 
     Struct.consume();
diff --git a/crates/ide/src/inlay_hints/bind_pat.rs b/crates/ide/src/inlay_hints/bind_pat.rs
index 82b0a6f..7a808fb 100644
--- a/crates/ide/src/inlay_hints/bind_pat.rs
+++ b/crates/ide/src/inlay_hints/bind_pat.rs
@@ -110,6 +110,7 @@
         position: InlayHintPosition::After,
         pad_left: !render_colons,
         pad_right: false,
+        resolve_parent: Some(pat.syntax().text_range()),
     });
 
     Some(())
diff --git a/crates/ide/src/inlay_hints/binding_mode.rs b/crates/ide/src/inlay_hints/binding_mode.rs
index f27390e..d1c0677 100644
--- a/crates/ide/src/inlay_hints/binding_mode.rs
+++ b/crates/ide/src/inlay_hints/binding_mode.rs
@@ -2,17 +2,19 @@
 //! ```no_run
 //! let /* & */ (/* ref */ x,) = &(0,);
 //! ```
-use hir::{Mutability, Semantics};
-use ide_db::RootDatabase;
+use hir::Mutability;
+use ide_db::famous_defs::FamousDefs;
 
+use span::EditionedFileId;
 use syntax::ast::{self, AstNode};
 
 use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind};
 
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
-    sema: &Semantics<'_, RootDatabase>,
+    FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
+    _file_id: EditionedFileId,
     pat: &ast::Pat,
 ) -> Option<()> {
     if !config.binding_mode_hints {
@@ -57,6 +59,7 @@
             position: InlayHintPosition::Before,
             pad_left: false,
             pad_right: mut_reference,
+            resolve_parent: Some(pat.syntax().text_range()),
         });
     });
     match pat {
@@ -75,6 +78,7 @@
                 position: InlayHintPosition::Before,
                 pad_left: false,
                 pad_right: true,
+                resolve_parent: Some(pat.syntax().text_range()),
             });
         }
         ast::Pat::OrPat(pat) if !pattern_adjustments.is_empty() && outer_paren_pat.is_none() => {
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index 35f4d46..58d8f97 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -67,6 +67,7 @@
                 position: InlayHintPosition::After,
                 pad_left: true,
                 pad_right: false,
+                resolve_parent: Some(expr.syntax().text_range()),
             });
         }
     }
@@ -139,7 +140,6 @@
                     (
                         147..172,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
@@ -152,13 +152,11 @@
                                 ),
                                 tooltip: "",
                             },
-                            "",
                         ],
                     ),
                     (
                         147..154,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "A",
                                 linked_location: Some(
@@ -171,7 +169,6 @@
                                 ),
                                 tooltip: "",
                             },
-                            "",
                         ],
                     ),
                 ]
@@ -222,7 +219,6 @@
                     (
                         143..190,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "C",
                                 linked_location: Some(
@@ -235,13 +231,11 @@
                                 ),
                                 tooltip: "",
                             },
-                            "",
                         ],
                     ),
                     (
                         143..179,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
@@ -254,7 +248,6 @@
                                 ),
                                 tooltip: "",
                             },
-                            "",
                         ],
                     ),
                 ]
@@ -289,7 +282,6 @@
                     (
                         143..190,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "C",
                                 linked_location: Some(
@@ -302,13 +294,11 @@
                                 ),
                                 tooltip: "",
                             },
-                            "",
                         ],
                     ),
                     (
                         143..179,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
@@ -321,7 +311,6 @@
                                 ),
                                 tooltip: "",
                             },
-                            "",
                         ],
                     ),
                 ]
@@ -357,7 +346,6 @@
                     (
                         246..283,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "B",
                                 linked_location: Some(
@@ -389,7 +377,6 @@
                     (
                         246..265,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "A",
                                 linked_location: Some(
@@ -562,7 +549,6 @@
                                 ),
                                 tooltip: "",
                             },
-                            "",
                         ],
                     ),
                 ]
@@ -597,7 +583,6 @@
                     (
                         124..130,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "Struct",
                                 linked_location: Some(
@@ -610,13 +595,11 @@
                                 ),
                                 tooltip: "",
                             },
-                            "",
                         ],
                     ),
                     (
                         145..185,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "Struct",
                                 linked_location: Some(
@@ -629,13 +612,11 @@
                                 ),
                                 tooltip: "",
                             },
-                            "",
                         ],
                     ),
                     (
                         145..168,
                         [
-                            "",
                             InlayHintLabelPart {
                                 text: "Struct",
                                 linked_location: Some(
@@ -648,7 +629,6 @@
                                 ),
                                 tooltip: "",
                             },
-                            "",
                         ],
                     ),
                     (
diff --git a/crates/ide/src/inlay_hints/closing_brace.rs b/crates/ide/src/inlay_hints/closing_brace.rs
index d78fd64..90b8be6 100644
--- a/crates/ide/src/inlay_hints/closing_brace.rs
+++ b/crates/ide/src/inlay_hints/closing_brace.rs
@@ -18,12 +18,13 @@
     sema: &Semantics<'_, RootDatabase>,
     config: &InlayHintsConfig,
     file_id: EditionedFileId,
-    mut node: SyntaxNode,
+    original_node: SyntaxNode,
 ) -> Option<()> {
     let min_lines = config.closing_brace_hints_min_lines?;
 
     let name = |it: ast::Name| it.syntax().text_range();
 
+    let mut node = original_node.clone();
     let mut closing_token;
     let (label, name_range) = if let Some(item_list) = ast::AssocItemList::cast(node.clone()) {
         closing_token = item_list.r_curly_token()?;
@@ -77,7 +78,7 @@
         }
         closing_token = block.r_curly_token()?;
 
-        let lifetime = label.lifetime().map_or_else(String::new, |it| it.to_string());
+        let lifetime = label.lifetime()?.to_string();
 
         (lifetime, Some(label.syntax().text_range()))
     } else if let Some(block) = ast::BlockExpr::cast(node.clone()) {
@@ -145,6 +146,7 @@
         position: InlayHintPosition::After,
         pad_left: true,
         pad_right: false,
+        resolve_parent: Some(original_node.text_range()),
     });
 
     None
diff --git a/crates/ide/src/inlay_hints/closure_captures.rs b/crates/ide/src/inlay_hints/closure_captures.rs
index e87e10d..f399bd0 100644
--- a/crates/ide/src/inlay_hints/closure_captures.rs
+++ b/crates/ide/src/inlay_hints/closure_captures.rs
@@ -3,7 +3,7 @@
 //! Tests live in [`bind_pat`][super::bind_pat] module.
 use ide_db::famous_defs::FamousDefs;
 use span::EditionedFileId;
-use stdx::TupleExt;
+use stdx::{never, TupleExt};
 use syntax::ast::{self, AstNode};
 use text_edit::{TextRange, TextSize};
 
@@ -40,6 +40,7 @@
                 position: InlayHintPosition::After,
                 pad_left: false,
                 pad_right: false,
+                resolve_parent: Some(closure.syntax().text_range()),
             });
             range
         }
@@ -52,6 +53,7 @@
         position: InlayHintPosition::After,
         pad_left: false,
         pad_right: false,
+        resolve_parent: None,
     });
     let last = captures.len() - 1;
     for (idx, capture) in captures.into_iter().enumerate() {
@@ -61,17 +63,21 @@
         // force cache the source file, otherwise sema lookup will potentially panic
         _ = sema.parse_or_expand(source.file());
 
+        let label = format!(
+            "{}{}",
+            match capture.kind() {
+                hir::CaptureKind::SharedRef => "&",
+                hir::CaptureKind::UniqueSharedRef => "&unique ",
+                hir::CaptureKind::MutableRef => "&mut ",
+                hir::CaptureKind::Move => "",
+            },
+            capture.display_place(sema.db)
+        );
+        if never!(label.is_empty()) {
+            continue;
+        }
         let label = InlayHintLabel::simple(
-            format!(
-                "{}{}",
-                match capture.kind() {
-                    hir::CaptureKind::SharedRef => "&",
-                    hir::CaptureKind::UniqueSharedRef => "&unique ",
-                    hir::CaptureKind::MutableRef => "&mut ",
-                    hir::CaptureKind::Move => "",
-                },
-                capture.display_place(sema.db)
-            ),
+            label,
             None,
             source.name().and_then(|name| {
                 name.syntax().original_file_range_opt(sema.db).map(TupleExt::head).map(Into::into)
@@ -85,6 +91,7 @@
             position: InlayHintPosition::After,
             pad_left: false,
             pad_right: false,
+            resolve_parent: Some(closure.syntax().text_range()),
         });
 
         if idx != last {
@@ -96,6 +103,7 @@
                 position: InlayHintPosition::After,
                 pad_left: false,
                 pad_right: false,
+                resolve_parent: None,
             });
         }
     }
@@ -107,6 +115,7 @@
         position: InlayHintPosition::After,
         pad_left: false,
         pad_right: true,
+        resolve_parent: None,
     });
 
     Some(())
diff --git a/crates/ide/src/inlay_hints/closure_ret.rs b/crates/ide/src/inlay_hints/closure_ret.rs
index 325c204..6827540 100644
--- a/crates/ide/src/inlay_hints/closure_ret.rs
+++ b/crates/ide/src/inlay_hints/closure_ret.rs
@@ -72,6 +72,7 @@
         position: InlayHintPosition::After,
         pad_left: false,
         pad_right: false,
+        resolve_parent: Some(closure.syntax().text_range()),
     });
     Some(())
 }
diff --git a/crates/ide/src/inlay_hints/discriminant.rs b/crates/ide/src/inlay_hints/discriminant.rs
index eca0ebe..35b6287 100644
--- a/crates/ide/src/inlay_hints/discriminant.rs
+++ b/crates/ide/src/inlay_hints/discriminant.rs
@@ -35,7 +35,7 @@
         return None;
     }
     for variant in enum_.variant_list()?.variants() {
-        variant_hints(acc, sema, &variant);
+        variant_hints(acc, sema, &enum_, &variant);
     }
     Some(())
 }
@@ -43,6 +43,7 @@
 fn variant_hints(
     acc: &mut Vec<InlayHint>,
     sema: &Semantics<'_, RootDatabase>,
+    enum_: &ast::Enum,
     variant: &ast::Variant,
 ) -> Option<()> {
     if variant.expr().is_some() {
@@ -90,6 +91,7 @@
         position: InlayHintPosition::After,
         pad_left: false,
         pad_right: false,
+        resolve_parent: Some(enum_.syntax().text_range()),
     });
 
     Some(())
diff --git a/crates/ide/src/inlay_hints/fn_lifetime_fn.rs b/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
deleted file mode 100644
index d366675..0000000
--- a/crates/ide/src/inlay_hints/fn_lifetime_fn.rs
+++ /dev/null
@@ -1,332 +0,0 @@
-//! Implementation of "lifetime elision" inlay hints:
-//! ```no_run
-//! fn example/* <'0> */(a: &/* '0 */()) {}
-//! ```
-use ide_db::{syntax_helpers::node_ext::walk_ty, FxHashMap};
-use itertools::Itertools;
-use syntax::{
-    ast::{self, AstNode, HasGenericParams, HasName},
-    SyntaxToken,
-};
-use syntax::{format_smolstr, SmolStr};
-
-use crate::{InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind, LifetimeElisionHints};
-
-pub(super) fn hints(
-    acc: &mut Vec<InlayHint>,
-    config: &InlayHintsConfig,
-    func: ast::Fn,
-) -> Option<()> {
-    if config.lifetime_elision_hints == LifetimeElisionHints::Never {
-        return None;
-    }
-
-    let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint {
-        range: t.text_range(),
-        kind: InlayKind::Lifetime,
-        label: label.into(),
-        text_edit: None,
-        position: InlayHintPosition::After,
-        pad_left: false,
-        pad_right: true,
-    };
-
-    let param_list = func.param_list()?;
-    let generic_param_list = func.generic_param_list();
-    let ret_type = func.ret_type();
-    let self_param = param_list.self_param().filter(|it| it.amp_token().is_some());
-
-    let is_elided = |lt: &Option<ast::Lifetime>| match lt {
-        Some(lt) => matches!(lt.text().as_str(), "'_"),
-        None => true,
-    };
-
-    let potential_lt_refs = {
-        let mut acc: Vec<_> = vec![];
-        if let Some(self_param) = &self_param {
-            let lifetime = self_param.lifetime();
-            let is_elided = is_elided(&lifetime);
-            acc.push((None, self_param.amp_token(), lifetime, is_elided));
-        }
-        param_list.params().filter_map(|it| Some((it.pat(), it.ty()?))).for_each(|(pat, ty)| {
-            // FIXME: check path types
-            walk_ty(&ty, &mut |ty| match ty {
-                ast::Type::RefType(r) => {
-                    let lifetime = r.lifetime();
-                    let is_elided = is_elided(&lifetime);
-                    acc.push((
-                        pat.as_ref().and_then(|it| match it {
-                            ast::Pat::IdentPat(p) => p.name(),
-                            _ => None,
-                        }),
-                        r.amp_token(),
-                        lifetime,
-                        is_elided,
-                    ));
-                    false
-                }
-                ast::Type::FnPtrType(_) => true,
-                ast::Type::PathType(t) => {
-                    t.path().and_then(|it| it.segment()).and_then(|it| it.param_list()).is_some()
-                }
-                _ => false,
-            })
-        });
-        acc
-    };
-
-    // allocate names
-    let mut gen_idx_name = {
-        let mut gen = (0u8..).map(|idx| match idx {
-            idx if idx < 10 => SmolStr::from_iter(['\'', (idx + 48) as char]),
-            idx => format_smolstr!("'{idx}"),
-        });
-        move || gen.next().unwrap_or_default()
-    };
-    let mut allocated_lifetimes = vec![];
-
-    let mut used_names: FxHashMap<SmolStr, usize> =
-        match config.param_names_for_lifetime_elision_hints {
-            true => generic_param_list
-                .iter()
-                .flat_map(|gpl| gpl.lifetime_params())
-                .filter_map(|param| param.lifetime())
-                .filter_map(|lt| Some((SmolStr::from(lt.text().as_str().get(1..)?), 0)))
-                .collect(),
-            false => Default::default(),
-        };
-    {
-        let mut potential_lt_refs = potential_lt_refs.iter().filter(|&&(.., is_elided)| is_elided);
-        if self_param.is_some() && potential_lt_refs.next().is_some() {
-            allocated_lifetimes.push(if config.param_names_for_lifetime_elision_hints {
-                // self can't be used as a lifetime, so no need to check for collisions
-                "'self".into()
-            } else {
-                gen_idx_name()
-            });
-        }
-        potential_lt_refs.for_each(|(name, ..)| {
-            let name = match name {
-                Some(it) if config.param_names_for_lifetime_elision_hints => {
-                    if let Some(c) = used_names.get_mut(it.text().as_str()) {
-                        *c += 1;
-                        SmolStr::from(format!("'{text}{c}", text = it.text().as_str()))
-                    } else {
-                        used_names.insert(it.text().as_str().into(), 0);
-                        SmolStr::from_iter(["\'", it.text().as_str()])
-                    }
-                }
-                _ => gen_idx_name(),
-            };
-            allocated_lifetimes.push(name);
-        });
-    }
-
-    // fetch output lifetime if elision rule applies
-    let output = match potential_lt_refs.as_slice() {
-        [(_, _, lifetime, _), ..] if self_param.is_some() || potential_lt_refs.len() == 1 => {
-            match lifetime {
-                Some(lt) => match lt.text().as_str() {
-                    "'_" => allocated_lifetimes.first().cloned(),
-                    "'static" => None,
-                    name => Some(name.into()),
-                },
-                None => allocated_lifetimes.first().cloned(),
-            }
-        }
-        [..] => None,
-    };
-
-    if allocated_lifetimes.is_empty() && output.is_none() {
-        return None;
-    }
-
-    // apply hints
-    // apply output if required
-    let mut is_trivial = true;
-    if let (Some(output_lt), Some(r)) = (&output, ret_type) {
-        if let Some(ty) = r.ty() {
-            walk_ty(&ty, &mut |ty| match ty {
-                ast::Type::RefType(ty) if ty.lifetime().is_none() => {
-                    if let Some(amp) = ty.amp_token() {
-                        is_trivial = false;
-                        acc.push(mk_lt_hint(amp, output_lt.to_string()));
-                    }
-                    false
-                }
-                ast::Type::FnPtrType(_) => true,
-                ast::Type::PathType(t) => {
-                    t.path().and_then(|it| it.segment()).and_then(|it| it.param_list()).is_some()
-                }
-                _ => false,
-            })
-        }
-    }
-
-    if config.lifetime_elision_hints == LifetimeElisionHints::SkipTrivial && is_trivial {
-        return None;
-    }
-
-    let mut a = allocated_lifetimes.iter();
-    for (_, amp_token, _, is_elided) in potential_lt_refs {
-        if is_elided {
-            let t = amp_token?;
-            let lt = a.next()?;
-            acc.push(mk_lt_hint(t, lt.to_string()));
-        }
-    }
-
-    // generate generic param list things
-    match (generic_param_list, allocated_lifetimes.as_slice()) {
-        (_, []) => (),
-        (Some(gpl), allocated_lifetimes) => {
-            let angle_tok = gpl.l_angle_token()?;
-            let is_empty = gpl.generic_params().next().is_none();
-            acc.push(InlayHint {
-                range: angle_tok.text_range(),
-                kind: InlayKind::Lifetime,
-                label: format!(
-                    "{}{}",
-                    allocated_lifetimes.iter().format(", "),
-                    if is_empty { "" } else { ", " }
-                )
-                .into(),
-                text_edit: None,
-                position: InlayHintPosition::After,
-                pad_left: false,
-                pad_right: true,
-            });
-        }
-        (None, allocated_lifetimes) => acc.push(InlayHint {
-            range: func.name()?.syntax().text_range(),
-            kind: InlayKind::GenericParamList,
-            label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(),
-            text_edit: None,
-            position: InlayHintPosition::After,
-            pad_left: false,
-            pad_right: false,
-        }),
-    }
-    Some(())
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::{
-        inlay_hints::tests::{check, check_with_config, TEST_CONFIG},
-        InlayHintsConfig, LifetimeElisionHints,
-    };
-
-    #[test]
-    fn hints_lifetimes() {
-        check(
-            r#"
-fn empty() {}
-
-fn no_gpl(a: &()) {}
- //^^^^^^<'0>
-          // ^'0
-fn empty_gpl<>(a: &()) {}
-      //    ^'0   ^'0
-fn partial<'b>(a: &(), b: &'b ()) {}
-//        ^'0, $  ^'0
-fn partial<'a>(a: &'a (), b: &()) {}
-//        ^'0, $             ^'0
-
-fn single_ret(a: &()) -> &() {}
-// ^^^^^^^^^^<'0>
-              // ^'0     ^'0
-fn full_mul(a: &(), b: &()) {}
-// ^^^^^^^^<'0, '1>
-            // ^'0     ^'1
-
-fn foo<'c>(a: &'c ()) -> &() {}
-                      // ^'c
-
-fn nested_in(a: &   &X< &()>) {}
-// ^^^^^^^^^<'0, '1, '2>
-              //^'0 ^'1 ^'2
-fn nested_out(a: &()) -> &   &X< &()>{}
-// ^^^^^^^^^^<'0>
-               //^'0     ^'0 ^'0 ^'0
-
-impl () {
-    fn foo(&self) {}
-    // ^^^<'0>
-        // ^'0
-    fn foo(&self) -> &() {}
-    // ^^^<'0>
-        // ^'0       ^'0
-    fn foo(&self, a: &()) -> &() {}
-    // ^^^<'0, '1>
-        // ^'0       ^'1     ^'0
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn hints_lifetimes_named() {
-        check_with_config(
-            InlayHintsConfig { param_names_for_lifetime_elision_hints: true, ..TEST_CONFIG },
-            r#"
-fn nested_in<'named>(named: &        &X<      &()>) {}
-//          ^'named1, 'named2, 'named3, $
-                          //^'named1 ^'named2 ^'named3
-"#,
-        );
-    }
-
-    #[test]
-    fn hints_lifetimes_trivial_skip() {
-        check_with_config(
-            InlayHintsConfig {
-                lifetime_elision_hints: LifetimeElisionHints::SkipTrivial,
-                ..TEST_CONFIG
-            },
-            r#"
-fn no_gpl(a: &()) {}
-fn empty_gpl<>(a: &()) {}
-fn partial<'b>(a: &(), b: &'b ()) {}
-fn partial<'a>(a: &'a (), b: &()) {}
-
-fn single_ret(a: &()) -> &() {}
-// ^^^^^^^^^^<'0>
-              // ^'0     ^'0
-fn full_mul(a: &(), b: &()) {}
-
-fn foo<'c>(a: &'c ()) -> &() {}
-                      // ^'c
-
-fn nested_in(a: &   &X< &()>) {}
-fn nested_out(a: &()) -> &   &X< &()>{}
-// ^^^^^^^^^^<'0>
-               //^'0     ^'0 ^'0 ^'0
-
-impl () {
-    fn foo(&self) {}
-    fn foo(&self) -> &() {}
-    // ^^^<'0>
-        // ^'0       ^'0
-    fn foo(&self, a: &()) -> &() {}
-    // ^^^<'0, '1>
-        // ^'0       ^'1     ^'0
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn hints_lifetimes_skip_fn_likes() {
-        check_with_config(
-            InlayHintsConfig {
-                lifetime_elision_hints: LifetimeElisionHints::Always,
-                ..TEST_CONFIG
-            },
-            r#"
-fn fn_ptr(a: fn(&()) -> &()) {}
-fn fn_trait<>(a: impl Fn(&()) -> &()) {}
-"#,
-        );
-    }
-}
diff --git a/crates/ide/src/inlay_hints/generic_param.rs b/crates/ide/src/inlay_hints/generic_param.rs
index b60a80a..ed7ebc3 100644
--- a/crates/ide/src/inlay_hints/generic_param.rs
+++ b/crates/ide/src/inlay_hints/generic_param.rs
@@ -92,6 +92,7 @@
             kind: InlayKind::GenericParameter,
             label,
             text_edit: None,
+            resolve_parent: Some(node.syntax().text_range()),
         })
     });
 
diff --git a/crates/ide/src/inlay_hints/implicit_drop.rs b/crates/ide/src/inlay_hints/implicit_drop.rs
index b4695a2..dd4b3ef 100644
--- a/crates/ide/src/inlay_hints/implicit_drop.rs
+++ b/crates/ide/src/inlay_hints/implicit_drop.rs
@@ -8,9 +8,9 @@
 use hir::{
     db::{DefDatabase as _, HirDatabase as _},
     mir::{MirSpan, TerminatorKind},
-    ChalkTyInterner, DefWithBody, Semantics,
+    ChalkTyInterner, DefWithBody,
 };
-use ide_db::{FileRange, RootDatabase};
+use ide_db::{famous_defs::FamousDefs, FileRange};
 
 use span::EditionedFileId;
 use syntax::{
@@ -22,16 +22,16 @@
 
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
-    sema: &Semantics<'_, RootDatabase>,
+    FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
     file_id: EditionedFileId,
-    def: &ast::Fn,
+    node: &ast::Fn,
 ) -> Option<()> {
     if !config.implicit_drop_hints {
         return None;
     }
 
-    let def = sema.to_def(def)?;
+    let def = sema.to_def(node)?;
     let def: DefWithBody = def.into();
 
     let (hir, source_map) = sema.db.body_with_source_map(def.into());
@@ -121,6 +121,7 @@
                 kind: InlayKind::Drop,
                 label,
                 text_edit: None,
+                resolve_parent: Some(node.syntax().text_range()),
             })
         }
     }
diff --git a/crates/ide/src/inlay_hints/implicit_static.rs b/crates/ide/src/inlay_hints/implicit_static.rs
index 42223dd..8d42247 100644
--- a/crates/ide/src/inlay_hints/implicit_static.rs
+++ b/crates/ide/src/inlay_hints/implicit_static.rs
@@ -3,6 +3,8 @@
 //! static S: &/* 'static */str = "";
 //! ```
 use either::Either;
+use ide_db::famous_defs::FamousDefs;
+use span::EditionedFileId;
 use syntax::{
     ast::{self, AstNode},
     SyntaxKind,
@@ -12,7 +14,9 @@
 
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
+    FamousDefs(_sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
+    _file_id: EditionedFileId,
     statik_or_const: Either<ast::Static, ast::Const>,
 ) -> Option<()> {
     if config.lifetime_elision_hints != LifetimeElisionHints::Always {
@@ -38,6 +42,7 @@
                 position: InlayHintPosition::After,
                 pad_left: false,
                 pad_right: true,
+                resolve_parent: None,
             });
         }
     }
diff --git a/crates/ide/src/inlay_hints/lifetime.rs b/crates/ide/src/inlay_hints/lifetime.rs
new file mode 100644
index 0000000..2163c95
--- /dev/null
+++ b/crates/ide/src/inlay_hints/lifetime.rs
@@ -0,0 +1,566 @@
+//! Implementation of "lifetime elision" inlay hints:
+//! ```no_run
+//! fn example/* <'0> */(a: &/* '0 */()) {}
+//! ```
+use std::iter;
+
+use ide_db::{famous_defs::FamousDefs, syntax_helpers::node_ext::walk_ty, FxHashMap};
+use itertools::Itertools;
+use span::EditionedFileId;
+use syntax::{
+    ast::{self, AstNode, HasGenericParams, HasName},
+    SyntaxKind, SyntaxToken,
+};
+use syntax::{format_smolstr, SmolStr};
+
+use crate::{
+    inlay_hints::InlayHintCtx, InlayHint, InlayHintPosition, InlayHintsConfig, InlayKind,
+    LifetimeElisionHints,
+};
+
+pub(super) fn fn_hints(
+    acc: &mut Vec<InlayHint>,
+    ctx: &mut InlayHintCtx,
+    fd: &FamousDefs<'_, '_>,
+    config: &InlayHintsConfig,
+    file_id: EditionedFileId,
+    func: ast::Fn,
+) -> Option<()> {
+    if config.lifetime_elision_hints == LifetimeElisionHints::Never {
+        return None;
+    }
+
+    let param_list = func.param_list()?;
+    let generic_param_list = func.generic_param_list();
+    let ret_type = func.ret_type();
+    let self_param = param_list.self_param().filter(|it| it.amp_token().is_some());
+    let gpl_append_range = func.name()?.syntax().text_range();
+    hints_(
+        acc,
+        ctx,
+        fd,
+        config,
+        file_id,
+        param_list,
+        generic_param_list,
+        ret_type,
+        self_param,
+        |acc, allocated_lifetimes| {
+            acc.push(InlayHint {
+                range: gpl_append_range,
+                kind: InlayKind::GenericParamList,
+                label: format!("<{}>", allocated_lifetimes.iter().format(", "),).into(),
+                text_edit: None,
+                position: InlayHintPosition::After,
+                pad_left: false,
+                pad_right: false,
+                resolve_parent: None,
+            })
+        },
+        true,
+    )
+}
+
+pub(super) fn fn_ptr_hints(
+    acc: &mut Vec<InlayHint>,
+    ctx: &mut InlayHintCtx,
+    fd: &FamousDefs<'_, '_>,
+    config: &InlayHintsConfig,
+    file_id: EditionedFileId,
+    func: ast::FnPtrType,
+) -> Option<()> {
+    if config.lifetime_elision_hints == LifetimeElisionHints::Never {
+        return None;
+    }
+
+    let parent_for_type = func
+        .syntax()
+        .ancestors()
+        .skip(1)
+        .take_while(|it| matches!(it.kind(), SyntaxKind::PAREN_TYPE | SyntaxKind::FOR_TYPE))
+        .find_map(ast::ForType::cast);
+
+    let param_list = func.param_list()?;
+    let generic_param_list = parent_for_type.as_ref().and_then(|it| it.generic_param_list());
+    let ret_type = func.ret_type();
+    let for_kw = parent_for_type.as_ref().and_then(|it| it.for_token());
+    hints_(
+        acc,
+        ctx,
+        fd,
+        config,
+        file_id,
+        param_list,
+        generic_param_list,
+        ret_type,
+        None,
+        |acc, allocated_lifetimes| {
+            let has_for = for_kw.is_some();
+            let for_ = if has_for { "" } else { "for" };
+            acc.push(InlayHint {
+                range: for_kw.map_or_else(
+                    || func.syntax().first_token().unwrap().text_range(),
+                    |it| it.text_range(),
+                ),
+                kind: InlayKind::GenericParamList,
+                label: format!("{for_}<{}>", allocated_lifetimes.iter().format(", "),).into(),
+                text_edit: None,
+                position: if has_for {
+                    InlayHintPosition::After
+                } else {
+                    InlayHintPosition::Before
+                },
+                pad_left: false,
+                pad_right: true,
+                resolve_parent: None,
+            });
+        },
+        false,
+    )
+}
+
+pub(super) fn fn_path_hints(
+    acc: &mut Vec<InlayHint>,
+    ctx: &mut InlayHintCtx,
+    fd: &FamousDefs<'_, '_>,
+    config: &InlayHintsConfig,
+    file_id: EditionedFileId,
+    func: ast::PathType,
+) -> Option<()> {
+    if config.lifetime_elision_hints == LifetimeElisionHints::Never {
+        return None;
+    }
+
+    // FIXME: Support general path types
+    let (param_list, ret_type) = func.path().as_ref().and_then(path_as_fn)?;
+    let parent_for_type = func
+        .syntax()
+        .ancestors()
+        .skip(1)
+        .take_while(|it| matches!(it.kind(), SyntaxKind::PAREN_TYPE | SyntaxKind::FOR_TYPE))
+        .find_map(ast::ForType::cast);
+
+    let generic_param_list = parent_for_type.as_ref().and_then(|it| it.generic_param_list());
+    let for_kw = parent_for_type.as_ref().and_then(|it| it.for_token());
+    hints_(
+        acc,
+        ctx,
+        fd,
+        config,
+        file_id,
+        param_list,
+        generic_param_list,
+        ret_type,
+        None,
+        |acc, allocated_lifetimes| {
+            let has_for = for_kw.is_some();
+            let for_ = if has_for { "" } else { "for" };
+            acc.push(InlayHint {
+                range: for_kw.map_or_else(
+                    || func.syntax().first_token().unwrap().text_range(),
+                    |it| it.text_range(),
+                ),
+                kind: InlayKind::GenericParamList,
+                label: format!("{for_}<{}>", allocated_lifetimes.iter().format(", "),).into(),
+                text_edit: None,
+                position: if has_for {
+                    InlayHintPosition::After
+                } else {
+                    InlayHintPosition::Before
+                },
+                pad_left: false,
+                pad_right: true,
+                resolve_parent: None,
+            });
+        },
+        false,
+    )
+}
+
+fn path_as_fn(path: &ast::Path) -> Option<(ast::ParamList, Option<ast::RetType>)> {
+    path.segment().and_then(|it| it.param_list().zip(Some(it.ret_type())))
+}
+
+fn hints_(
+    acc: &mut Vec<InlayHint>,
+    ctx: &mut InlayHintCtx,
+    FamousDefs(_, _): &FamousDefs<'_, '_>,
+    config: &InlayHintsConfig,
+    _file_id: EditionedFileId,
+    param_list: ast::ParamList,
+    generic_param_list: Option<ast::GenericParamList>,
+    ret_type: Option<ast::RetType>,
+    self_param: Option<ast::SelfParam>,
+    on_missing_gpl: impl FnOnce(&mut Vec<InlayHint>, &[SmolStr]),
+    mut is_trivial: bool,
+) -> Option<()> {
+    let is_elided = |lt: &Option<ast::Lifetime>| match lt {
+        Some(lt) => matches!(lt.text().as_str(), "'_"),
+        None => true,
+    };
+
+    let mk_lt_hint = |t: SyntaxToken, label: String| InlayHint {
+        range: t.text_range(),
+        kind: InlayKind::Lifetime,
+        label: label.into(),
+        text_edit: None,
+        position: InlayHintPosition::After,
+        pad_left: false,
+        pad_right: true,
+        resolve_parent: None,
+    };
+
+    let potential_lt_refs = {
+        let mut acc: Vec<_> = vec![];
+        if let Some(self_param) = &self_param {
+            let lifetime = self_param.lifetime();
+            let is_elided = is_elided(&lifetime);
+            acc.push((None, self_param.amp_token(), lifetime, is_elided));
+        }
+        param_list
+            .params()
+            .filter_map(|it| {
+                Some((
+                    it.pat().and_then(|it| match it {
+                        ast::Pat::IdentPat(p) => p.name(),
+                        _ => None,
+                    }),
+                    it.ty()?,
+                ))
+            })
+            .for_each(|(name, ty)| {
+                // FIXME: check path types
+                walk_ty(&ty, &mut |ty| match ty {
+                    ast::Type::RefType(r) => {
+                        let lifetime = r.lifetime();
+                        let is_elided = is_elided(&lifetime);
+                        acc.push((name.clone(), r.amp_token(), lifetime, is_elided));
+                        false
+                    }
+                    ast::Type::FnPtrType(_) => {
+                        is_trivial = false;
+                        true
+                    }
+                    ast::Type::PathType(t) => {
+                        if t.path()
+                            .and_then(|it| it.segment())
+                            .and_then(|it| it.param_list())
+                            .is_some()
+                        {
+                            is_trivial = false;
+                            true
+                        } else {
+                            false
+                        }
+                    }
+                    _ => false,
+                })
+            });
+        acc
+    };
+
+    let mut used_names: FxHashMap<SmolStr, usize> =
+        ctx.lifetime_stacks.iter().flat_map(|it| it.iter()).cloned().zip(iter::repeat(0)).collect();
+    // allocate names
+    let mut gen_idx_name = {
+        let mut gen = (0u8..).map(|idx| match idx {
+            idx if idx < 10 => SmolStr::from_iter(['\'', (idx + 48) as char]),
+            idx => format_smolstr!("'{idx}"),
+        });
+        let ctx = &*ctx;
+        move || {
+            gen.by_ref()
+                .find(|s| ctx.lifetime_stacks.iter().flat_map(|it| it.iter()).all(|n| n != s))
+                .unwrap_or_default()
+        }
+    };
+    let mut allocated_lifetimes = vec![];
+
+    {
+        let mut potential_lt_refs = potential_lt_refs.iter().filter(|&&(.., is_elided)| is_elided);
+        if self_param.is_some() && potential_lt_refs.next().is_some() {
+            allocated_lifetimes.push(if config.param_names_for_lifetime_elision_hints {
+                // self can't be used as a lifetime, so no need to check for collisions
+                "'self".into()
+            } else {
+                gen_idx_name()
+            });
+        }
+        potential_lt_refs.for_each(|(name, ..)| {
+            let name = match name {
+                Some(it) if config.param_names_for_lifetime_elision_hints => {
+                    if let Some(c) = used_names.get_mut(it.text().as_str()) {
+                        *c += 1;
+                        format_smolstr!("'{}{c}", it.text().as_str())
+                    } else {
+                        used_names.insert(it.text().as_str().into(), 0);
+                        format_smolstr!("'{}", it.text().as_str())
+                    }
+                }
+                _ => gen_idx_name(),
+            };
+            allocated_lifetimes.push(name);
+        });
+    }
+
+    // fetch output lifetime if elision rule applies
+    let output = match potential_lt_refs.as_slice() {
+        [(_, _, lifetime, _), ..] if self_param.is_some() || potential_lt_refs.len() == 1 => {
+            match lifetime {
+                Some(lt) => match lt.text().as_str() {
+                    "'_" => allocated_lifetimes.first().cloned(),
+                    "'static" => None,
+                    name => Some(name.into()),
+                },
+                None => allocated_lifetimes.first().cloned(),
+            }
+        }
+        [..] => None,
+    };
+
+    if allocated_lifetimes.is_empty() && output.is_none() {
+        return None;
+    }
+
+    // apply hints
+    // apply output if required
+    if let (Some(output_lt), Some(r)) = (&output, ret_type) {
+        if let Some(ty) = r.ty() {
+            walk_ty(&ty, &mut |ty| match ty {
+                ast::Type::RefType(ty) if ty.lifetime().is_none() => {
+                    if let Some(amp) = ty.amp_token() {
+                        is_trivial = false;
+                        acc.push(mk_lt_hint(amp, output_lt.to_string()));
+                    }
+                    false
+                }
+                ast::Type::FnPtrType(_) => {
+                    is_trivial = false;
+                    true
+                }
+                ast::Type::PathType(t) => {
+                    if t.path().and_then(|it| it.segment()).and_then(|it| it.param_list()).is_some()
+                    {
+                        is_trivial = false;
+                        true
+                    } else {
+                        false
+                    }
+                }
+                _ => false,
+            })
+        }
+    }
+
+    if config.lifetime_elision_hints == LifetimeElisionHints::SkipTrivial && is_trivial {
+        return None;
+    }
+
+    let mut a = allocated_lifetimes.iter();
+    for (_, amp_token, _, is_elided) in potential_lt_refs {
+        if is_elided {
+            let t = amp_token?;
+            let lt = a.next()?;
+            acc.push(mk_lt_hint(t, lt.to_string()));
+        }
+    }
+
+    // generate generic param list things
+    match (generic_param_list, allocated_lifetimes.as_slice()) {
+        (_, []) => (),
+        (Some(gpl), allocated_lifetimes) => {
+            let angle_tok = gpl.l_angle_token()?;
+            let is_empty = gpl.generic_params().next().is_none();
+            acc.push(InlayHint {
+                range: angle_tok.text_range(),
+                kind: InlayKind::Lifetime,
+                label: format!(
+                    "{}{}",
+                    allocated_lifetimes.iter().format(", "),
+                    if is_empty { "" } else { ", " }
+                )
+                .into(),
+                text_edit: None,
+                position: InlayHintPosition::After,
+                pad_left: false,
+                pad_right: true,
+                resolve_parent: None,
+            });
+        }
+        (None, allocated_lifetimes) => on_missing_gpl(acc, allocated_lifetimes),
+    }
+    if let Some(stack) = ctx.lifetime_stacks.last_mut() {
+        stack.extend(allocated_lifetimes);
+    }
+    Some(())
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        inlay_hints::tests::{check, check_with_config, TEST_CONFIG},
+        InlayHintsConfig, LifetimeElisionHints,
+    };
+
+    #[test]
+    fn hints_lifetimes() {
+        check(
+            r#"
+fn empty() {}
+
+fn no_gpl(a: &()) {}
+ //^^^^^^<'0>
+          // ^'0
+fn empty_gpl<>(a: &()) {}
+      //    ^'0   ^'0
+fn partial<'b>(a: &(), b: &'b ()) {}
+//        ^'0, $  ^'0
+fn partial<'a>(a: &'a (), b: &()) {}
+//        ^'0, $             ^'0
+
+fn single_ret(a: &()) -> &() {}
+// ^^^^^^^^^^<'0>
+              // ^'0     ^'0
+fn full_mul(a: &(), b: &()) {}
+// ^^^^^^^^<'0, '1>
+            // ^'0     ^'1
+
+fn foo<'c>(a: &'c ()) -> &() {}
+                      // ^'c
+
+fn nested_in(a: &   &X< &()>) {}
+// ^^^^^^^^^<'0, '1, '2>
+              //^'0 ^'1 ^'2
+fn nested_out(a: &()) -> &   &X< &()>{}
+// ^^^^^^^^^^<'0>
+               //^'0     ^'0 ^'0 ^'0
+
+impl () {
+    fn foo(&self) {}
+    // ^^^<'0>
+        // ^'0
+    fn foo(&self) -> &() {}
+    // ^^^<'0>
+        // ^'0       ^'0
+    fn foo(&self, a: &()) -> &() {}
+    // ^^^<'0, '1>
+        // ^'0       ^'1     ^'0
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn hints_lifetimes_named() {
+        check_with_config(
+            InlayHintsConfig { param_names_for_lifetime_elision_hints: true, ..TEST_CONFIG },
+            r#"
+fn nested_in<'named>(named: &        &X<      &()>) {}
+//          ^'named1, 'named2, 'named3, $
+                          //^'named1 ^'named2 ^'named3
+"#,
+        );
+    }
+
+    #[test]
+    fn hints_lifetimes_trivial_skip() {
+        check_with_config(
+            InlayHintsConfig {
+                lifetime_elision_hints: LifetimeElisionHints::SkipTrivial,
+                ..TEST_CONFIG
+            },
+            r#"
+fn no_gpl(a: &()) {}
+fn empty_gpl<>(a: &()) {}
+fn partial<'b>(a: &(), b: &'b ()) {}
+fn partial<'a>(a: &'a (), b: &()) {}
+
+fn single_ret(a: &()) -> &() {}
+// ^^^^^^^^^^<'0>
+              // ^'0     ^'0
+fn full_mul(a: &(), b: &()) {}
+
+fn foo<'c>(a: &'c ()) -> &() {}
+                      // ^'c
+
+fn nested_in(a: &   &X< &()>) {}
+fn nested_out(a: &()) -> &   &X< &()>{}
+// ^^^^^^^^^^<'0>
+               //^'0     ^'0 ^'0 ^'0
+
+impl () {
+    fn foo(&self) {}
+    fn foo(&self) -> &() {}
+    // ^^^<'0>
+        // ^'0       ^'0
+    fn foo(&self, a: &()) -> &() {}
+    // ^^^<'0, '1>
+        // ^'0       ^'1     ^'0
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn no_collide() {
+        check_with_config(
+            InlayHintsConfig {
+                lifetime_elision_hints: LifetimeElisionHints::Always,
+                param_names_for_lifetime_elision_hints: true,
+                ..TEST_CONFIG
+            },
+            r#"
+impl<'foo> {
+    fn foo(foo: &()) {}
+    // ^^^ <'foo1>
+             // ^ 'foo1
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn hints_lifetimes_fn_ptr() {
+        check_with_config(
+            InlayHintsConfig {
+                lifetime_elision_hints: LifetimeElisionHints::Always,
+                ..TEST_CONFIG
+            },
+            r#"
+fn fn_ptr(a: fn(&()) -> &fn(&()) -> &()) {}
+           //^^ for<'0>
+              //^'0
+                      //^'0
+                       //^^ for<'1>
+                          //^'1
+                                  //^'1
+fn fn_ptr2(a: for<'a> fn(&()) -> &()) {}
+               //^'0, $
+                       //^'0
+                               //^'0
+fn fn_trait(a: &impl Fn(&()) -> &()) {}
+// ^^^^^^^^<'0>
+            // ^'0
+                  // ^^ for<'1>
+                      //^'1
+                             // ^'1
+"#,
+        );
+    }
+
+    #[test]
+    fn hints_in_non_gen_defs() {
+        check_with_config(
+            InlayHintsConfig {
+                lifetime_elision_hints: LifetimeElisionHints::Always,
+                ..TEST_CONFIG
+            },
+            r#"
+const _: fn(&()) -> &();
+       //^^ for<'0>
+          //^'0
+                  //^'0
+"#,
+        );
+    }
+}
diff --git a/crates/ide/src/inlay_hints/param_name.rs b/crates/ide/src/inlay_hints/param_name.rs
index 0f3142e..28b0fa6 100644
--- a/crates/ide/src/inlay_hints/param_name.rs
+++ b/crates/ide/src/inlay_hints/param_name.rs
@@ -7,8 +7,9 @@
 
 use either::Either;
 use hir::{Callable, Semantics};
-use ide_db::RootDatabase;
+use ide_db::{famous_defs::FamousDefs, RootDatabase};
 
+use span::EditionedFileId;
 use stdx::to_lower_snake_case;
 use syntax::{
     ast::{self, AstNode, HasArgList, HasName, UnaryOp},
@@ -19,8 +20,9 @@
 
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
-    sema: &Semantics<'_, RootDatabase>,
+    FamousDefs(sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
+    _file_id: EditionedFileId,
     expr: ast::Expr,
 ) -> Option<()> {
     if !config.parameter_hints {
@@ -60,6 +62,7 @@
                 position: InlayHintPosition::Before,
                 pad_left: false,
                 pad_right: true,
+                resolve_parent: Some(expr.syntax().text_range()),
             }
         });
 
diff --git a/crates/ide/src/inlay_hints/range_exclusive.rs b/crates/ide/src/inlay_hints/range_exclusive.rs
index bfb9283..de9b0e9 100644
--- a/crates/ide/src/inlay_hints/range_exclusive.rs
+++ b/crates/ide/src/inlay_hints/range_exclusive.rs
@@ -3,13 +3,17 @@
 //! for i in 0../* < */10 {}
 //! if let ../* < */100 = 50 {}
 //! ```
+use ide_db::famous_defs::FamousDefs;
+use span::EditionedFileId;
 use syntax::{ast, SyntaxToken, T};
 
 use crate::{InlayHint, InlayHintsConfig};
 
 pub(super) fn hints(
     acc: &mut Vec<InlayHint>,
+    FamousDefs(_sema, _): &FamousDefs<'_, '_>,
     config: &InlayHintsConfig,
+    _file_id: EditionedFileId,
     range: impl ast::RangeItem,
 ) -> Option<()> {
     (config.range_exclusive_hints && range.end().is_some())
@@ -30,6 +34,7 @@
         kind: crate::InlayKind::RangeExclusive,
         label: crate::InlayHintLabel::from("<"),
         text_edit: None,
+        resolve_parent: None,
     }
 }
 
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index ba0aaae..547286c 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -57,7 +57,7 @@
 mod view_memory_layout;
 mod view_mir;
 
-use std::panic::UnwindSafe;
+use std::{iter, panic::UnwindSafe};
 
 use cfg::CfgOptions;
 use fetch_crates::CrateInfo;
@@ -65,7 +65,8 @@
 use ide_db::{
     base_db::{
         salsa::{self, ParallelDatabase},
-        CrateOrigin, Env, FileLoader, FileSet, SourceDatabase, SourceRootDatabase, VfsPath,
+        CrateOrigin, CrateWorkspaceData, Env, FileLoader, FileSet, SourceDatabase,
+        SourceRootDatabase, VfsPath,
     },
     prime_caches, symbol_index, FxHashMap, FxIndexSet, LineIndexDatabase,
 };
@@ -256,9 +257,16 @@
             CrateOrigin::Local { repo: None, name: None },
         );
         change.change_file(file_id, Some(text));
-        change.set_crate_graph(crate_graph);
-        change.set_target_data_layouts(vec![Err("fixture has no layout".into())]);
-        change.set_toolchains(vec![None]);
+        let ws_data = crate_graph
+            .iter()
+            .zip(iter::repeat(Arc::new(CrateWorkspaceData {
+                proc_macro_cwd: None,
+                data_layout: Err("fixture has no layout".into()),
+                toolchain: None,
+            })))
+            .collect();
+        change.set_crate_graph(crate_graph, ws_data);
+
         host.apply_change(change);
         (host.analysis(), file_id)
     }
@@ -439,12 +447,12 @@
         &self,
         config: &InlayHintsConfig,
         file_id: FileId,
-        position: TextSize,
+        resolve_range: TextRange,
         hash: u64,
         hasher: impl Fn(&InlayHint) -> u64 + Send + UnwindSafe,
     ) -> Cancellable<Option<InlayHint>> {
         self.with_db(|db| {
-            inlay_hints::inlay_hints_resolve(db, file_id, position, hash, config, hasher)
+            inlay_hints::inlay_hints_resolve(db, file_id, resolve_range, hash, config, hasher)
         })
     }
 
diff --git a/crates/ide/src/moniker.rs b/crates/ide/src/moniker.rs
index 4be1b57..14781b2 100644
--- a/crates/ide/src/moniker.rs
+++ b/crates/ide/src/moniker.rs
@@ -223,11 +223,12 @@
                 Variable
             }
         }
-        Definition::Label(..) => Variable, // For lack of a better variant
+        Definition::Label(..) | Definition::InlineAsmOperand(_) => Variable, // For lack of a better variant
         Definition::DeriveHelper(..) => Attribute,
         Definition::BuiltinAttr(..) => Attribute,
         Definition::ToolModule(..) => Module,
         Definition::ExternCrateDecl(..) => Module,
+        Definition::InlineAsmRegOrRegClass(..) => Module,
     }
 }
 
@@ -320,7 +321,9 @@
         | Definition::DeriveHelper(_)
         | Definition::BuiltinLifetime(_)
         | Definition::BuiltinAttr(_)
-        | Definition::ToolModule(_) => return None,
+        | Definition::ToolModule(_)
+        | Definition::InlineAsmRegOrRegClass(_)
+        | Definition::InlineAsmOperand(_) => return None,
 
         Definition::Local(local) => {
             if !local.is_param(db) {
diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs
index 9ace9fd..9bc7bf4 100644
--- a/crates/ide/src/navigation_target.rs
+++ b/crates/ide/src/navigation_target.rs
@@ -237,11 +237,13 @@
             Definition::Trait(it) => it.try_to_nav(db),
             Definition::TraitAlias(it) => it.try_to_nav(db),
             Definition::TypeAlias(it) => it.try_to_nav(db),
-            Definition::ExternCrateDecl(it) => Some(it.try_to_nav(db)?),
+            Definition::ExternCrateDecl(it) => it.try_to_nav(db),
+            Definition::InlineAsmOperand(it) => it.try_to_nav(db),
             Definition::BuiltinLifetime(_)
             | Definition::BuiltinType(_)
             | Definition::TupleField(_)
             | Definition::ToolModule(_)
+            | Definition::InlineAsmRegOrRegClass(_)
             | Definition::BuiltinAttr(_) => None,
             // FIXME: The focus range should be set to the helper declaration
             Definition::DeriveHelper(it) => it.derive().try_to_nav(db),
@@ -693,6 +695,31 @@
     }
 }
 
+impl TryToNav for hir::InlineAsmOperand {
+    fn try_to_nav(&self, db: &RootDatabase) -> Option<UpmappingResult<NavigationTarget>> {
+        let InFile { file_id, value } = &self.source(db)?;
+        let file_id = *file_id;
+        Some(orig_range_with_focus(db, file_id, value.syntax(), value.name()).map(
+            |(FileRange { file_id, range: full_range }, focus_range)| {
+                let edition = self.parent(db).module(db).krate().edition(db);
+                NavigationTarget {
+                    file_id,
+                    name: self
+                        .name(db)
+                        .map_or_else(|| "_".into(), |it| it.display(db, edition).to_smolstr()),
+                    alias: None,
+                    kind: Some(SymbolKind::Local),
+                    full_range,
+                    focus_range,
+                    container_name: None,
+                    description: None,
+                    docs: None,
+                }
+            },
+        ))
+    }
+}
+
 #[derive(Debug)]
 pub struct UpmappingResult<T> {
     /// The macro call site.
diff --git a/crates/ide/src/rename.rs b/crates/ide/src/rename.rs
index 42b7472..e46cb5a 100644
--- a/crates/ide/src/rename.rs
+++ b/crates/ide/src/rename.rs
@@ -2976,6 +2976,62 @@
     }
 
     #[test]
+    fn asm_operand() {
+        check(
+            "bose",
+            r#"
+//- minicore: asm
+fn test() {
+    core::arch::asm!(
+        "push {base}",
+        base$0 = const 0
+    );
+}
+"#,
+            r#"
+fn test() {
+    core::arch::asm!(
+        "push {bose}",
+        bose = const 0
+    );
+}
+"#,
+        );
+    }
+
+    #[test]
+    fn asm_operand2() {
+        check(
+            "bose",
+            r#"
+//- minicore: asm
+fn test() {
+    core::arch::asm!(
+        "push {base$0}",
+        "push {base}",
+        boo = const 0,
+        virtual_free = sym VIRTUAL_FREE,
+        base = const 0,
+        boo = const 0,
+    );
+}
+"#,
+            r#"
+fn test() {
+    core::arch::asm!(
+        "push {bose}",
+        "push {bose}",
+        boo = const 0,
+        virtual_free = sym VIRTUAL_FREE,
+        bose = const 0,
+        boo = const 0,
+    );
+}
+"#,
+        );
+    }
+
+    #[test]
     fn rename_path_inside_use_tree() {
         check(
             "Baz",
diff --git a/crates/ide/src/syntax_highlighting/format.rs b/crates/ide/src/syntax_highlighting/format.rs
index 518e714..7234108 100644
--- a/crates/ide/src/syntax_highlighting/format.rs
+++ b/crates/ide/src/syntax_highlighting/format.rs
@@ -19,21 +19,21 @@
     expanded_string: &ast::String,
     range: TextRange,
 ) {
-    if !is_format_string(expanded_string) {
+    if is_format_string(expanded_string) {
+        // FIXME: Replace this with the HIR info we have now.
+        lex_format_specifiers(string, &mut |piece_range, kind| {
+            if let Some(highlight) = highlight_format_specifier(kind) {
+                stack.add(HlRange {
+                    range: piece_range + range.start(),
+                    highlight: highlight.into(),
+                    binding_hash: None,
+                });
+            }
+        });
+
         return;
     }
 
-    // FIXME: Replace this with the HIR info we have now.
-    lex_format_specifiers(string, &mut |piece_range, kind| {
-        if let Some(highlight) = highlight_format_specifier(kind) {
-            stack.add(HlRange {
-                range: piece_range + range.start(),
-                highlight: highlight.into(),
-                binding_hash: None,
-            });
-        }
-    });
-
     if let Some(parts) = sema.as_format_args_parts(string) {
         parts.into_iter().for_each(|(range, res)| {
             if let Some(res) = res {
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index eeba9cf..9637593 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -534,6 +534,10 @@
         Definition::BuiltinAttr(_) => Highlight::new(HlTag::Symbol(SymbolKind::BuiltinAttr)),
         Definition::ToolModule(_) => Highlight::new(HlTag::Symbol(SymbolKind::ToolModule)),
         Definition::DeriveHelper(_) => Highlight::new(HlTag::Symbol(SymbolKind::DeriveHelper)),
+        Definition::InlineAsmRegOrRegClass(_) => {
+            Highlight::new(HlTag::Symbol(SymbolKind::InlineAsmRegOrRegClass))
+        }
+        Definition::InlineAsmOperand(_) => Highlight::new(HlTag::Symbol(SymbolKind::Local)),
     };
 
     let def_crate = def.krate(db);
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index bc1ec53..5583f1b 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -315,6 +315,8 @@
         Definition::BuiltinAttr(_) => SymbolKind::BuiltinAttr,
         Definition::ToolModule(_) => SymbolKind::ToolModule,
         Definition::DeriveHelper(_) => SymbolKind::DeriveHelper,
+        Definition::InlineAsmRegOrRegClass(_) => SymbolKind::InlineAsmRegOrRegClass,
+        Definition::InlineAsmOperand(_) => SymbolKind::Local,
     };
     HlTag::Symbol(symbol)
 }
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs
index e329023..3b5d1af 100644
--- a/crates/ide/src/syntax_highlighting/tags.rs
+++ b/crates/ide/src/syntax_highlighting/tags.rs
@@ -146,6 +146,7 @@
                 SymbolKind::Field => "field",
                 SymbolKind::Function => "function",
                 SymbolKind::Impl => "self_type",
+                SymbolKind::InlineAsmRegOrRegClass => "reg",
                 SymbolKind::Label => "label",
                 SymbolKind::LifetimeParam => "lifetime",
                 SymbolKind::Local => "variable",
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html b/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html
new file mode 100644
index 0000000..15a6386
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html
@@ -0,0 +1,119 @@
+
+<style>
+body                { margin: 0; }
+pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime           { color: #DFAF8F; font-style: italic; }
+.label              { color: #DFAF8F; font-style: italic; }
+.comment            { color: #7F9F7F; }
+.documentation      { color: #629755; }
+.intra_doc_link     { font-style: italic; }
+.injected           { opacity: 0.65 ; }
+.struct, .enum      { color: #7CB8BB; }
+.enum_variant       { color: #BDE0F3; }
+.string_literal     { color: #CC9393; }
+.field              { color: #94BFF3; }
+.function           { color: #93E0E3; }
+.function.unsafe    { color: #BC8383; }
+.trait.unsafe       { color: #BC8383; }
+.operator.unsafe    { color: #BC8383; }
+.mutable.unsafe     { color: #BC8383; text-decoration: underline; }
+.keyword.unsafe     { color: #BC8383; font-weight: bold; }
+.macro.unsafe       { color: #BC8383; }
+.parameter          { color: #94BFF3; }
+.text               { color: #DCDCCC; }
+.type               { color: #7CB8BB; }
+.builtin_type       { color: #8CD0D3; }
+.type_param         { color: #DFAF8F; }
+.attribute          { color: #94BFF3; }
+.numeric_literal    { color: #BFEBBF; }
+.bool_literal       { color: #BFE6EB; }
+.macro              { color: #94BFF3; }
+.proc_macro         { color: #94BFF3; text-decoration: underline; }
+.derive             { color: #94BFF3; font-style: italic; }
+.module             { color: #AFD8AF; }
+.value_param        { color: #DCDCCC; }
+.variable           { color: #DCDCCC; }
+.format_specifier   { color: #CC696B; }
+.mutable            { text-decoration: underline; }
+.escape_sequence    { color: #94BFF3; }
+.keyword            { color: #F0DFAF; font-weight: bold; }
+.control            { font-style: italic; }
+.reference          { font-style: italic; font-weight: bold; }
+.const              { font-weight: bolder; }
+
+.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
+.unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
+    <span class="keyword unsafe">unsafe</span> <span class="brace">{</span>
+        <span class="keyword">let</span> <span class="variable declaration">foo</span> <span class="operator">=</span> <span class="numeric_literal">1</span><span class="semicolon">;</span>
+        <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">o</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
+        <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
+            <span class="string_literal macro">"%input = OpLoad _ {</span><span class="variable">0</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
+            <span class="macro default_library library macro">concat</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"%result = "</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="string_literal macro">" _ %input"</span><span class="parenthesis macro">)</span><span class="comma macro">,</span>
+            <span class="string_literal macro">"OpStore {</span><span class="variable">1</span><span class="string_literal macro">} %result"</span><span class="comma macro">,</span>
+            <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="operator macro">&</span><span class="variable macro">foo</span><span class="comma macro">,</span>
+            <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="operator macro">&</span><span class="keyword macro">mut</span> <span class="variable macro mutable">o</span><span class="comma macro">,</span>
+        <span class="parenthesis macro">)</span><span class="semicolon">;</span>
+
+        <span class="keyword">let</span> <span class="variable declaration">thread_id</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
+        <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"
+            mov {</span><span class="variable">0</span><span class="string_literal macro">}, gs:[0x30]
+            mov {</span><span class="variable">0</span><span class="string_literal macro">}, [{</span><span class="variable">0</span><span class="string_literal macro">}+0x48]
+        "</span><span class="comma macro">,</span> <span class="keyword macro">out</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">thread_id</span><span class="comma macro">,</span> <span class="keyword macro">options</span><span class="parenthesis macro">(</span><span class="keyword macro">pure</span><span class="comma macro">,</span> <span class="keyword macro">readonly</span><span class="comma macro">,</span> <span class="keyword macro">nostack</span><span class="parenthesis macro">)</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+
+        <span class="keyword">static</span> <span class="static declaration">UNMAP_BASE</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
+        <span class="keyword const">const</span> <span class="constant const declaration">MEM_RELEASE</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
+        <span class="keyword">static</span> <span class="static declaration">VirtualFree</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
+        <span class="keyword const">const</span> <span class="constant const declaration">OffPtr</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
+        <span class="keyword const">const</span> <span class="constant const declaration">OffFn</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
+        <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"
+            push {</span><span class="variable">free_type</span><span class="string_literal macro">}
+            push {</span><span class="variable">free_size</span><span class="string_literal macro">}
+            push {</span><span class="variable">base</span><span class="string_literal macro">}
+
+            mov eax, fs:[30h]
+            mov eax, [eax+8h]
+            add eax, {</span><span class="variable">off_fn</span><span class="string_literal macro">}
+            mov [eax-{</span><span class="variable">off_fn</span><span class="string_literal macro">}+{</span><span class="variable">off_ptr</span><span class="string_literal macro">}], eax
+
+            push eax
+
+            jmp {</span><span class="variable">virtual_free</span><span class="string_literal macro">}
+            "</span><span class="comma macro">,</span>
+            <span class="variable declaration macro">off_ptr</span> <span class="operator macro">=</span> <span class="keyword macro">const</span> <span class="constant const macro">OffPtr</span><span class="comma macro">,</span>
+            <span class="variable declaration macro">off_fn</span>  <span class="operator macro">=</span> <span class="keyword macro">const</span> <span class="constant const macro">OffFn</span><span class="comma macro">,</span>
+
+            <span class="variable declaration macro">free_size</span> <span class="operator macro">=</span> <span class="keyword macro">const</span> <span class="numeric_literal macro">0</span><span class="comma macro">,</span>
+            <span class="variable declaration macro">free_type</span> <span class="operator macro">=</span> <span class="keyword macro">const</span> <span class="constant const macro">MEM_RELEASE</span><span class="comma macro">,</span>
+
+            <span class="variable declaration macro">virtual_free</span> <span class="operator macro">=</span> <span class="keyword macro">sym</span> <span class="static macro">VirtualFree</span><span class="comma macro">,</span>
+
+            <span class="variable declaration macro">base</span> <span class="operator macro">=</span> <span class="keyword macro">sym</span> <span class="static macro">UNMAP_BASE</span><span class="comma macro">,</span>
+            <span class="keyword macro">options</span><span class="parenthesis macro">(</span><span class="keyword macro">noreturn</span><span class="parenthesis macro">)</span><span class="comma macro">,</span>
+        <span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="brace">}</span>
+<span class="brace">}</span>
+<span class="comment">// taken from https://github.com/rust-embedded/cortex-m/blob/47921b51f8b960344fcfa1255a50a0d19efcde6d/cortex-m/src/asm.rs#L254-L274</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">inline</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">pub</span> <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration public unsafe">bootstrap</span><span class="parenthesis">(</span><span class="value_param declaration">msp</span><span class="colon">:</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="builtin_type">u32</span><span class="comma">,</span> <span class="value_param declaration">rv</span><span class="colon">:</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="builtin_type">u32</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">!</span> <span class="brace">{</span>
+    <span class="comment">// Ensure thumb mode is set.</span>
+    <span class="keyword">let</span> <span class="variable declaration">rv</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="value_param">rv</span> <span class="keyword">as</span> <span class="builtin_type">u32</span><span class="parenthesis">)</span> <span class="bitwise">|</span> <span class="numeric_literal">1</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration">msp</span> <span class="operator">=</span> <span class="value_param">msp</span> <span class="keyword">as</span> <span class="builtin_type">u32</span><span class="semicolon">;</span>
+    <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
+        <span class="string_literal macro">"mrs {</span><span class="variable">tmp</span><span class="string_literal macro">}, CONTROL"</span><span class="comma macro">,</span>
+        <span class="string_literal macro">"bics {</span><span class="variable">tmp</span><span class="string_literal macro">}, {</span><span class="variable">spsel</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
+        <span class="string_literal macro">"msr CONTROL, {</span><span class="variable">tmp</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
+        <span class="string_literal macro">"isb"</span><span class="comma macro">,</span>
+        <span class="string_literal macro">"msr MSP, {</span><span class="variable">msp</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
+        <span class="string_literal macro">"bx {</span><span class="variable">rv</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
+        <span class="comment macro">// `out(reg) _` is not permitted in a `noreturn` asm! call,</span>
+        <span class="comment macro">// so instead use `in(reg) 0` and don't restore it afterwards.</span>
+        <span class="variable declaration macro">tmp</span> <span class="operator macro">=</span> <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="numeric_literal macro">0</span><span class="comma macro">,</span>
+        <span class="variable declaration macro">spsel</span> <span class="operator macro">=</span> <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="numeric_literal macro">2</span><span class="comma macro">,</span>
+        <span class="variable declaration macro">msp</span> <span class="operator macro">=</span> <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">msp</span><span class="comma macro">,</span>
+        <span class="variable declaration macro">rv</span> <span class="operator macro">=</span> <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">rv</span><span class="comma macro">,</span>
+        <span class="keyword macro">options</span><span class="parenthesis macro">(</span><span class="keyword macro">noreturn</span><span class="comma macro">,</span> <span class="keyword macro">nomem</span><span class="comma macro">,</span> <span class="keyword macro">nostack</span><span class="parenthesis macro">)</span><span class="comma macro">,</span>
+    <span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="brace">}</span></code></pre>
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html b/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html
new file mode 100644
index 0000000..d07ba74
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html
@@ -0,0 +1,53 @@
+
+<style>
+body                { margin: 0; }
+pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime           { color: #DFAF8F; font-style: italic; }
+.label              { color: #DFAF8F; font-style: italic; }
+.comment            { color: #7F9F7F; }
+.documentation      { color: #629755; }
+.intra_doc_link     { font-style: italic; }
+.injected           { opacity: 0.65 ; }
+.struct, .enum      { color: #7CB8BB; }
+.enum_variant       { color: #BDE0F3; }
+.string_literal     { color: #CC9393; }
+.field              { color: #94BFF3; }
+.function           { color: #93E0E3; }
+.function.unsafe    { color: #BC8383; }
+.trait.unsafe       { color: #BC8383; }
+.operator.unsafe    { color: #BC8383; }
+.mutable.unsafe     { color: #BC8383; text-decoration: underline; }
+.keyword.unsafe     { color: #BC8383; font-weight: bold; }
+.macro.unsafe       { color: #BC8383; }
+.parameter          { color: #94BFF3; }
+.text               { color: #DCDCCC; }
+.type               { color: #7CB8BB; }
+.builtin_type       { color: #8CD0D3; }
+.type_param         { color: #DFAF8F; }
+.attribute          { color: #94BFF3; }
+.numeric_literal    { color: #BFEBBF; }
+.bool_literal       { color: #BFE6EB; }
+.macro              { color: #94BFF3; }
+.proc_macro         { color: #94BFF3; text-decoration: underline; }
+.derive             { color: #94BFF3; font-style: italic; }
+.module             { color: #AFD8AF; }
+.value_param        { color: #DCDCCC; }
+.variable           { color: #DCDCCC; }
+.format_specifier   { color: #CC696B; }
+.mutable            { text-decoration: underline; }
+.escape_sequence    { color: #94BFF3; }
+.keyword            { color: #F0DFAF; font-weight: bold; }
+.control            { font-style: italic; }
+.reference          { font-style: italic; font-weight: bold; }
+.const              { font-weight: bolder; }
+
+.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
+.unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
+    <span class="macro">template</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">template</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="brace">}</span>
+
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="module attribute crate_root library">proc_macros</span><span class="operator attribute">::</span><span class="attribute attribute library">issue_18089</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">fn</span> <span class="function declaration">template</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span></code></pre>
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html
new file mode 100644
index 0000000..a790b38
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html
@@ -0,0 +1,74 @@
+
+<style>
+body                { margin: 0; }
+pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime           { color: #DFAF8F; font-style: italic; }
+.label              { color: #DFAF8F; font-style: italic; }
+.comment            { color: #7F9F7F; }
+.documentation      { color: #629755; }
+.intra_doc_link     { font-style: italic; }
+.injected           { opacity: 0.65 ; }
+.struct, .enum      { color: #7CB8BB; }
+.enum_variant       { color: #BDE0F3; }
+.string_literal     { color: #CC9393; }
+.field              { color: #94BFF3; }
+.function           { color: #93E0E3; }
+.function.unsafe    { color: #BC8383; }
+.trait.unsafe       { color: #BC8383; }
+.operator.unsafe    { color: #BC8383; }
+.mutable.unsafe     { color: #BC8383; text-decoration: underline; }
+.keyword.unsafe     { color: #BC8383; font-weight: bold; }
+.macro.unsafe       { color: #BC8383; }
+.parameter          { color: #94BFF3; }
+.text               { color: #DCDCCC; }
+.type               { color: #7CB8BB; }
+.builtin_type       { color: #8CD0D3; }
+.type_param         { color: #DFAF8F; }
+.attribute          { color: #94BFF3; }
+.numeric_literal    { color: #BFEBBF; }
+.bool_literal       { color: #BFE6EB; }
+.macro              { color: #94BFF3; }
+.proc_macro         { color: #94BFF3; text-decoration: underline; }
+.derive             { color: #94BFF3; font-style: italic; }
+.module             { color: #AFD8AF; }
+.value_param        { color: #DCDCCC; }
+.variable           { color: #DCDCCC; }
+.format_specifier   { color: #CC696B; }
+.mutable            { text-decoration: underline; }
+.escape_sequence    { color: #94BFF3; }
+.keyword            { color: #F0DFAF; font-weight: bold; }
+.control            { font-style: italic; }
+.reference          { font-style: italic; font-weight: bold; }
+.const              { font-weight: bolder; }
+
+.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
+.unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="self_keyword crate_root">self</span><span class="semicolon">;</span>
+
+<span class="keyword">use</span> <span class="keyword crate_root public">crate</span><span class="semicolon">;</span>
+<span class="keyword">use</span> <span class="self_keyword crate_root public">self</span><span class="semicolon">;</span>
+<span class="keyword">mod</span> <span class="module declaration">__</span> <span class="brace">{</span>
+    <span class="keyword">use</span> <span class="keyword crate_root public">super</span><span class="operator">::</span><span class="punctuation">*</span><span class="semicolon">;</span>
+<span class="brace">}</span>
+
+<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">void</span> <span class="brace">{</span>
+    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="brace">}</span>
+
+<span class="keyword">struct</span> <span class="struct declaration">__</span> <span class="keyword">where</span> <span class="self_type_keyword">Self</span><span class="colon">:</span><span class="semicolon">;</span>
+<span class="keyword">fn</span> <span class="function declaration">__</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="unresolved_reference">Self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">Self</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+
+<span class="comment">// edition dependent</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">try</span> <span class="none macro">async</span> <span class="none macro">await</span> <span class="none macro">gen</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// edition and context dependent</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">dyn</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// builtin custom syntax</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// contextual</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// reserved</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>'static 'self 'unsafe<span class="parenthesis macro">)</span></code></pre>
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
new file mode 100644
index 0000000..6dac066
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
@@ -0,0 +1,74 @@
+
+<style>
+body                { margin: 0; }
+pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime           { color: #DFAF8F; font-style: italic; }
+.label              { color: #DFAF8F; font-style: italic; }
+.comment            { color: #7F9F7F; }
+.documentation      { color: #629755; }
+.intra_doc_link     { font-style: italic; }
+.injected           { opacity: 0.65 ; }
+.struct, .enum      { color: #7CB8BB; }
+.enum_variant       { color: #BDE0F3; }
+.string_literal     { color: #CC9393; }
+.field              { color: #94BFF3; }
+.function           { color: #93E0E3; }
+.function.unsafe    { color: #BC8383; }
+.trait.unsafe       { color: #BC8383; }
+.operator.unsafe    { color: #BC8383; }
+.mutable.unsafe     { color: #BC8383; text-decoration: underline; }
+.keyword.unsafe     { color: #BC8383; font-weight: bold; }
+.macro.unsafe       { color: #BC8383; }
+.parameter          { color: #94BFF3; }
+.text               { color: #DCDCCC; }
+.type               { color: #7CB8BB; }
+.builtin_type       { color: #8CD0D3; }
+.type_param         { color: #DFAF8F; }
+.attribute          { color: #94BFF3; }
+.numeric_literal    { color: #BFEBBF; }
+.bool_literal       { color: #BFE6EB; }
+.macro              { color: #94BFF3; }
+.proc_macro         { color: #94BFF3; text-decoration: underline; }
+.derive             { color: #94BFF3; font-style: italic; }
+.module             { color: #AFD8AF; }
+.value_param        { color: #DCDCCC; }
+.variable           { color: #DCDCCC; }
+.format_specifier   { color: #CC696B; }
+.mutable            { text-decoration: underline; }
+.escape_sequence    { color: #94BFF3; }
+.keyword            { color: #F0DFAF; font-weight: bold; }
+.control            { font-style: italic; }
+.reference          { font-style: italic; font-weight: bold; }
+.const              { font-weight: bolder; }
+
+.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
+.unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="self_keyword crate_root">self</span><span class="semicolon">;</span>
+
+<span class="keyword">use</span> <span class="keyword crate_root public">crate</span><span class="semicolon">;</span>
+<span class="keyword">use</span> <span class="self_keyword crate_root public">self</span><span class="semicolon">;</span>
+<span class="keyword">mod</span> <span class="module declaration">__</span> <span class="brace">{</span>
+    <span class="keyword">use</span> <span class="keyword crate_root public">super</span><span class="operator">::</span><span class="punctuation">*</span><span class="semicolon">;</span>
+<span class="brace">}</span>
+
+<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">void</span> <span class="brace">{</span>
+    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="brace">}</span>
+
+<span class="keyword">struct</span> <span class="struct declaration">__</span> <span class="keyword">where</span> <span class="self_type_keyword">Self</span><span class="colon">:</span><span class="semicolon">;</span>
+<span class="keyword">fn</span> <span class="function declaration">__</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="unresolved_reference">Self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">Self</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+
+<span class="comment">// edition dependent</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">try</span> <span class="keyword async macro">async</span> <span class="keyword async control macro">await</span> <span class="none macro">gen</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// edition and context dependent</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">dyn</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// builtin custom syntax</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// contextual</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// reserved</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>'static 'self 'unsafe<span class="parenthesis macro">)</span></code></pre>
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
new file mode 100644
index 0000000..6dac066
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
@@ -0,0 +1,74 @@
+
+<style>
+body                { margin: 0; }
+pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime           { color: #DFAF8F; font-style: italic; }
+.label              { color: #DFAF8F; font-style: italic; }
+.comment            { color: #7F9F7F; }
+.documentation      { color: #629755; }
+.intra_doc_link     { font-style: italic; }
+.injected           { opacity: 0.65 ; }
+.struct, .enum      { color: #7CB8BB; }
+.enum_variant       { color: #BDE0F3; }
+.string_literal     { color: #CC9393; }
+.field              { color: #94BFF3; }
+.function           { color: #93E0E3; }
+.function.unsafe    { color: #BC8383; }
+.trait.unsafe       { color: #BC8383; }
+.operator.unsafe    { color: #BC8383; }
+.mutable.unsafe     { color: #BC8383; text-decoration: underline; }
+.keyword.unsafe     { color: #BC8383; font-weight: bold; }
+.macro.unsafe       { color: #BC8383; }
+.parameter          { color: #94BFF3; }
+.text               { color: #DCDCCC; }
+.type               { color: #7CB8BB; }
+.builtin_type       { color: #8CD0D3; }
+.type_param         { color: #DFAF8F; }
+.attribute          { color: #94BFF3; }
+.numeric_literal    { color: #BFEBBF; }
+.bool_literal       { color: #BFE6EB; }
+.macro              { color: #94BFF3; }
+.proc_macro         { color: #94BFF3; text-decoration: underline; }
+.derive             { color: #94BFF3; font-style: italic; }
+.module             { color: #AFD8AF; }
+.value_param        { color: #DCDCCC; }
+.variable           { color: #DCDCCC; }
+.format_specifier   { color: #CC696B; }
+.mutable            { text-decoration: underline; }
+.escape_sequence    { color: #94BFF3; }
+.keyword            { color: #F0DFAF; font-weight: bold; }
+.control            { font-style: italic; }
+.reference          { font-style: italic; font-weight: bold; }
+.const              { font-weight: bolder; }
+
+.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
+.unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="self_keyword crate_root">self</span><span class="semicolon">;</span>
+
+<span class="keyword">use</span> <span class="keyword crate_root public">crate</span><span class="semicolon">;</span>
+<span class="keyword">use</span> <span class="self_keyword crate_root public">self</span><span class="semicolon">;</span>
+<span class="keyword">mod</span> <span class="module declaration">__</span> <span class="brace">{</span>
+    <span class="keyword">use</span> <span class="keyword crate_root public">super</span><span class="operator">::</span><span class="punctuation">*</span><span class="semicolon">;</span>
+<span class="brace">}</span>
+
+<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">void</span> <span class="brace">{</span>
+    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="brace">}</span>
+
+<span class="keyword">struct</span> <span class="struct declaration">__</span> <span class="keyword">where</span> <span class="self_type_keyword">Self</span><span class="colon">:</span><span class="semicolon">;</span>
+<span class="keyword">fn</span> <span class="function declaration">__</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="unresolved_reference">Self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">Self</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+
+<span class="comment">// edition dependent</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">try</span> <span class="keyword async macro">async</span> <span class="keyword async control macro">await</span> <span class="none macro">gen</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// edition and context dependent</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">dyn</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// builtin custom syntax</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// contextual</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// reserved</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>'static 'self 'unsafe<span class="parenthesis macro">)</span></code></pre>
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
new file mode 100644
index 0000000..4ccc407
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
@@ -0,0 +1,74 @@
+
+<style>
+body                { margin: 0; }
+pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime           { color: #DFAF8F; font-style: italic; }
+.label              { color: #DFAF8F; font-style: italic; }
+.comment            { color: #7F9F7F; }
+.documentation      { color: #629755; }
+.intra_doc_link     { font-style: italic; }
+.injected           { opacity: 0.65 ; }
+.struct, .enum      { color: #7CB8BB; }
+.enum_variant       { color: #BDE0F3; }
+.string_literal     { color: #CC9393; }
+.field              { color: #94BFF3; }
+.function           { color: #93E0E3; }
+.function.unsafe    { color: #BC8383; }
+.trait.unsafe       { color: #BC8383; }
+.operator.unsafe    { color: #BC8383; }
+.mutable.unsafe     { color: #BC8383; text-decoration: underline; }
+.keyword.unsafe     { color: #BC8383; font-weight: bold; }
+.macro.unsafe       { color: #BC8383; }
+.parameter          { color: #94BFF3; }
+.text               { color: #DCDCCC; }
+.type               { color: #7CB8BB; }
+.builtin_type       { color: #8CD0D3; }
+.type_param         { color: #DFAF8F; }
+.attribute          { color: #94BFF3; }
+.numeric_literal    { color: #BFEBBF; }
+.bool_literal       { color: #BFE6EB; }
+.macro              { color: #94BFF3; }
+.proc_macro         { color: #94BFF3; text-decoration: underline; }
+.derive             { color: #94BFF3; font-style: italic; }
+.module             { color: #AFD8AF; }
+.value_param        { color: #DCDCCC; }
+.variable           { color: #DCDCCC; }
+.format_specifier   { color: #CC696B; }
+.mutable            { text-decoration: underline; }
+.escape_sequence    { color: #94BFF3; }
+.keyword            { color: #F0DFAF; font-weight: bold; }
+.control            { font-style: italic; }
+.reference          { font-style: italic; font-weight: bold; }
+.const              { font-weight: bolder; }
+
+.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
+.unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="self_keyword crate_root">self</span><span class="semicolon">;</span>
+
+<span class="keyword">use</span> <span class="keyword crate_root public">crate</span><span class="semicolon">;</span>
+<span class="keyword">use</span> <span class="self_keyword crate_root public">self</span><span class="semicolon">;</span>
+<span class="keyword">mod</span> <span class="module declaration">__</span> <span class="brace">{</span>
+    <span class="keyword">use</span> <span class="keyword crate_root public">super</span><span class="operator">::</span><span class="punctuation">*</span><span class="semicolon">;</span>
+<span class="brace">}</span>
+
+<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">void</span> <span class="brace">{</span>
+    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="brace">}</span>
+
+<span class="keyword">struct</span> <span class="struct declaration">__</span> <span class="keyword">where</span> <span class="self_type_keyword">Self</span><span class="colon">:</span><span class="semicolon">;</span>
+<span class="keyword">fn</span> <span class="function declaration">__</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="unresolved_reference">Self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">Self</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+
+<span class="comment">// edition dependent</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">try</span> <span class="keyword async macro">async</span> <span class="keyword async control macro">await</span> <span class="keyword macro">gen</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// edition and context dependent</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">dyn</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// builtin custom syntax</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// contextual</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="comment">// reserved</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>'static 'self 'unsafe<span class="parenthesis macro">)</span></code></pre>
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
index cb47fc6..5594a36 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -165,16 +165,16 @@
     <span class="macro">toho</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"{}fmt"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
     <span class="keyword">let</span> <span class="variable declaration">i</span><span class="colon">:</span> <span class="builtin_type">u64</span> <span class="operator">=</span> <span class="numeric_literal">3</span><span class="semicolon">;</span>
     <span class="keyword">let</span> <span class="variable declaration">o</span><span class="colon">:</span> <span class="builtin_type">u64</span><span class="semicolon">;</span>
-    <span class="macro default_library library">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
-        <span class="string_literal macro">"mov </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro">, </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span>
-        <span class="string_literal macro">"add </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro">, 5"</span><span class="comma macro">,</span>
-        <span class="none macro">out</span><span class="parenthesis macro">(</span><span class="none macro">reg</span><span class="parenthesis macro">)</span> <span class="none macro">o</span><span class="comma macro">,</span>
-        <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="none macro">reg</span><span class="parenthesis macro">)</span> <span class="none macro">i</span><span class="comma macro">,</span>
+    <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
+        <span class="string_literal macro">"mov {</span><span class="variable">0</span><span class="string_literal macro">}, {</span><span class="variable">1</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
+        <span class="string_literal macro">"add {</span><span class="variable">0</span><span class="string_literal macro">}, 5"</span><span class="comma macro">,</span>
+        <span class="keyword macro">out</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">o</span><span class="comma macro">,</span>
+        <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">i</span><span class="comma macro">,</span>
     <span class="parenthesis macro">)</span><span class="semicolon">;</span>
 
     <span class="keyword const">const</span> <span class="constant const declaration">CONSTANT</span><span class="colon">:</span> <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="colon">:</span>
     <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">m</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="macro default_library library macro">concat</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"{}"</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="string_literal macro">"{}"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable reference">backslash</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="constant const">CONSTANT</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable mutable">m</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="comma macro">,</span> <span class="macro default_library library macro">format_args</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="unresolved_reference macro">foo</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="macro macro">toho</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro">reuse_twice</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable reference">backslash</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">backslash</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">CONSTANT</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">m</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="comma macro">,</span> <span class="macro default_library library macro">format_args</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="unresolved_reference macro">foo</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="macro macro">toho</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro">reuse_twice</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">backslash</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
 <span class="brace">}</span></code></pre>
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 2070022..94cee4e 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -2,6 +2,7 @@
 
 use expect_test::{expect_file, ExpectFile};
 use ide_db::SymbolKind;
+use span::Edition;
 use test_utils::{bench, bench_fixture, skip_slow_tests, AssertLinear};
 
 use crate::{fixture, FileRange, HighlightConfig, HlTag, TextRange};
@@ -383,8 +384,10 @@
 
 #[test]
 fn test_keyword_highlighting() {
-    check_highlighting(
-        r#"
+    for edition in Edition::iter() {
+        check_highlighting(
+            &(format!("//- /main.rs crate:main edition:{edition}")
+                + r#"
 extern crate self;
 
 use crate;
@@ -396,13 +399,27 @@
 macro_rules! void {
     ($($tt:tt)*) => {}
 }
-void!(Self);
+
 struct __ where Self:;
 fn __(_: Self) {}
-"#,
-        expect_file!["./test_data/highlight_keywords.html"],
-        false,
-    );
+void!(Self);
+
+// edition dependent
+void!(try async await gen);
+// edition and context dependent
+void!(dyn);
+// builtin custom syntax
+void!(builtin offset_of format_args asm);
+// contextual
+void!(macro_rules, union, default, raw, auto, yeet);
+// reserved
+void!(abstract become box do final macro override priv typeof unsized virtual yield);
+void!('static 'self 'unsafe)
+"#),
+            expect_file![format!("./test_data/highlight_keywords_{edition}.html")],
+            false,
+        );
+    }
 }
 
 #[test]
@@ -532,7 +549,7 @@
     toho!("{}fmt", 0);
     let i: u64 = 3;
     let o: u64;
-    asm!(
+    core::arch::asm!(
         "mov {0}, {1}",
         "add {0}, 5",
         out(reg) o,
@@ -554,6 +571,7 @@
 fn test_unsafe_highlighting() {
     check_highlighting(
         r#"
+//- minicore: sized
 macro_rules! id {
     ($($tt:tt)*) => {
         $($tt)*
@@ -1257,3 +1275,103 @@
     );
     let _ = analysis.highlight(HL_CONFIG, file_id).unwrap();
 }
+
+#[test]
+fn test_asm_highlighting() {
+    check_highlighting(
+        r#"
+//- minicore: asm, concat
+fn main() {
+    unsafe {
+        let foo = 1;
+        let mut o = 0;
+        core::arch::asm!(
+            "%input = OpLoad _ {0}",
+            concat!("%result = ", "bar", " _ %input"),
+            "OpStore {1} %result",
+            in(reg) &foo,
+            in(reg) &mut o,
+        );
+
+        let thread_id: usize;
+        core::arch::asm!("
+            mov {0}, gs:[0x30]
+            mov {0}, [{0}+0x48]
+        ", out(reg) thread_id, options(pure, readonly, nostack));
+
+        static UNMAP_BASE: usize;
+        const MEM_RELEASE: usize;
+        static VirtualFree: usize;
+        const OffPtr: usize;
+        const OffFn: usize;
+        core::arch::asm!("
+            push {free_type}
+            push {free_size}
+            push {base}
+
+            mov eax, fs:[30h]
+            mov eax, [eax+8h]
+            add eax, {off_fn}
+            mov [eax-{off_fn}+{off_ptr}], eax
+
+            push eax
+
+            jmp {virtual_free}
+            ",
+            off_ptr = const OffPtr,
+            off_fn  = const OffFn,
+
+            free_size = const 0,
+            free_type = const MEM_RELEASE,
+
+            virtual_free = sym VirtualFree,
+
+            base = sym UNMAP_BASE,
+            options(noreturn),
+        );
+    }
+}
+// taken from https://github.com/rust-embedded/cortex-m/blob/47921b51f8b960344fcfa1255a50a0d19efcde6d/cortex-m/src/asm.rs#L254-L274
+#[inline]
+pub unsafe fn bootstrap(msp: *const u32, rv: *const u32) -> ! {
+    // Ensure thumb mode is set.
+    let rv = (rv as u32) | 1;
+    let msp = msp as u32;
+    core::arch::asm!(
+        "mrs {tmp}, CONTROL",
+        "bics {tmp}, {spsel}",
+        "msr CONTROL, {tmp}",
+        "isb",
+        "msr MSP, {msp}",
+        "bx {rv}",
+        // `out(reg) _` is not permitted in a `noreturn` asm! call,
+        // so instead use `in(reg) 0` and don't restore it afterwards.
+        tmp = in(reg) 0,
+        spsel = in(reg) 2,
+        msp = in(reg) msp,
+        rv = in(reg) rv,
+        options(noreturn, nomem, nostack),
+    );
+}
+"#,
+        expect_file!["./test_data/highlight_asm.html"],
+        false,
+    );
+}
+
+#[test]
+fn issue_18089() {
+    check_highlighting(
+        r#"
+//- proc_macros: issue_18089
+fn main() {
+    template!(template);
+}
+
+#[proc_macros::issue_18089]
+fn template() {}
+"#,
+        expect_file!["./test_data/highlight_issue_18089.html"],
+        false,
+    );
+}
diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs
index c066f50..a62cbc7 100644
--- a/crates/intern/src/symbol/symbols.rs
+++ b/crates/intern/src/symbol/symbols.rs
@@ -15,7 +15,7 @@
     (@WITH_NAME: $($alias:ident = $value:literal,)* @PLAIN: $($name:ident,)*) => {
         // Ideally we would be emitting `const` here, but then we no longer have stable addresses
         // which is what we are relying on for equality! In the future if consts can refer to
-        // statics we should swap these for `const`s and have the the string literal being pointed
+        // statics we should swap these for `const`s and have the string literal being pointed
         // to be statics to refer to such that their address is stable.
         $(
             pub static $name: Symbol = Symbol { repr: TaggedArcPtr::non_arc(&stringify!($name)) };
@@ -243,6 +243,7 @@
     future_output,
     Future,
     ge,
+    generic_associated_type_extended,
     get_context,
     global_allocator,
     global_asm,
diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs
index abad7e9..baa4517 100644
--- a/crates/load-cargo/src/lib.rs
+++ b/crates/load-cargo/src/lib.rs
@@ -10,7 +10,7 @@
     ProcMacros,
 };
 use ide_db::{
-    base_db::{CrateGraph, Env, SourceRoot, SourceRootId},
+    base_db::{CrateGraph, CrateWorkspaceData, Env, SourceRoot, SourceRootId},
     prime_caches, ChangeWithProcMacros, FxHashMap, RootDatabase,
 };
 use itertools::Itertools;
@@ -447,12 +447,16 @@
     let source_roots = source_root_config.partition(vfs);
     analysis_change.set_roots(source_roots);
 
-    let num_crates = crate_graph.len();
-    analysis_change.set_crate_graph(crate_graph);
+    let ws_data = crate_graph
+        .iter()
+        .zip(iter::repeat(From::from(CrateWorkspaceData {
+            proc_macro_cwd: None,
+            data_layout: target_layout.clone(),
+            toolchain: toolchain.clone(),
+        })))
+        .collect();
+    analysis_change.set_crate_graph(crate_graph, ws_data);
     analysis_change.set_proc_macros(proc_macros);
-    analysis_change
-        .set_target_data_layouts(iter::repeat(target_layout.clone()).take(num_crates).collect());
-    analysis_change.set_toolchains(iter::repeat(toolchain.clone()).take(num_crates).collect());
 
     db.apply_change(analysis_change);
     db
@@ -489,8 +493,17 @@
         def_site: Span,
         call_site: Span,
         mixed_site: Span,
+        current_dir: Option<String>,
     ) -> Result<tt::Subtree<Span>, ProcMacroExpansionError> {
-        match self.0.expand(subtree, attrs, env.clone(), def_site, call_site, mixed_site) {
+        match self.0.expand(
+            subtree,
+            attrs,
+            env.clone(),
+            def_site,
+            call_site,
+            mixed_site,
+            current_dir,
+        ) {
             Ok(Ok(subtree)) => Ok(subtree),
             Ok(Err(err)) => Err(ProcMacroExpansionError::Panic(err.0)),
             Err(err) => Err(ProcMacroExpansionError::System(err.to_string())),
diff --git a/crates/mbe/Cargo.toml b/crates/mbe/Cargo.toml
index 756d42e..b37d57f 100644
--- a/crates/mbe/Cargo.toml
+++ b/crates/mbe/Cargo.toml
@@ -18,6 +18,7 @@
 smallvec.workspace = true
 tracing.workspace = true
 arrayvec.workspace = true
+ra-ap-rustc_lexer.workspace = true
 
 # local deps
 syntax.workspace = true
@@ -30,6 +31,7 @@
 
 [dev-dependencies]
 test-utils.workspace = true
+expect-test.workspace = true
 
 [features]
 in-rust-tree = ["parser/in-rust-tree", "tt/in-rust-tree", "syntax/in-rust-tree"]
diff --git a/crates/mbe/src/benchmark.rs b/crates/mbe/src/benchmark.rs
index 43604eb..9e4ef14 100644
--- a/crates/mbe/src/benchmark.rs
+++ b/crates/mbe/src/benchmark.rs
@@ -146,7 +146,7 @@
                 Some(MetaVarKind::Pat) => token_trees.push(make_ident("foo")),
                 Some(MetaVarKind::Path) => token_trees.push(make_ident("foo")),
                 Some(MetaVarKind::Literal) => token_trees.push(make_literal("1")),
-                Some(MetaVarKind::Expr) => token_trees.push(make_ident("foo")),
+                Some(MetaVarKind::Expr(_)) => token_trees.push(make_ident("foo")),
                 Some(MetaVarKind::Lifetime) => {
                     token_trees.push(make_punct('\''));
                     token_trees.push(make_ident("a"));
@@ -216,7 +216,11 @@
 
                 token_trees.push(subtree.into());
             }
-            Op::Ignore { .. } | Op::Index { .. } | Op::Count { .. } | Op::Len { .. } => {}
+            Op::Ignore { .. }
+            | Op::Index { .. }
+            | Op::Count { .. }
+            | Op::Len { .. }
+            | Op::Concat { .. } => {}
         };
 
         // Simple linear congruential generator for deterministic result
diff --git a/crates/mbe/src/expander/matcher.rs b/crates/mbe/src/expander/matcher.rs
index e69d7d1..95641ab 100644
--- a/crates/mbe/src/expander/matcher.rs
+++ b/crates/mbe/src/expander/matcher.rs
@@ -69,7 +69,7 @@
 use crate::{
     expander::{Binding, Bindings, ExpandResult, Fragment},
     expect_fragment,
-    parser::{MetaVarKind, Op, RepeatKind, Separator},
+    parser::{ExprKind, MetaVarKind, Op, RepeatKind, Separator},
     ExpandError, ExpandErrorKind, MetaTemplate, ValueResult,
 };
 
@@ -584,7 +584,11 @@
                 error_items.push(item);
             }
             OpDelimited::Op(
-                Op::Ignore { .. } | Op::Index { .. } | Op::Count { .. } | Op::Len { .. },
+                Op::Ignore { .. }
+                | Op::Index { .. }
+                | Op::Count { .. }
+                | Op::Len { .. }
+                | Op::Concat { .. },
             ) => {
                 stdx::never!("metavariable expression in lhs found");
             }
@@ -769,23 +773,28 @@
                     it.map(|it| tt::TokenTree::subtree_or_wrap(it, delim_span)).map(Fragment::Path)
                 });
         }
-        MetaVarKind::Expr => {
-            // `expr` should not match underscores, let expressions, or inline const. The latter
-            // two are for [backwards compatibility][0].
+        MetaVarKind::Expr(expr) => {
+            // `expr_2021` should not match underscores, let expressions, or inline const.
+            // The latter two are for [backwards compatibility][0].
+            // And `expr` also should not contain let expressions but may contain the other two
+            // since `Edition2024`.
             // HACK: Macro expansion should not be done using "rollback and try another alternative".
             // rustc [explicitly checks the next token][1].
             // [0]: https://github.com/rust-lang/rust/issues/86730
             // [1]: https://github.com/rust-lang/rust/blob/f0c4da499/compiler/rustc_expand/src/mbe/macro_parser.rs#L576
             match input.peek_n(0) {
-                Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it)))
-                    if it.sym == sym::underscore
-                        || it.sym == sym::let_
-                        || it.sym == sym::const_ =>
-                {
-                    return ExpandResult::only_err(ExpandError::new(
-                        it.span,
-                        ExpandErrorKind::NoMatchingRule,
-                    ))
+                Some(tt::TokenTree::Leaf(tt::Leaf::Ident(it))) => {
+                    let is_err = if it.is_raw.no() && matches!(expr, ExprKind::Expr2021) {
+                        it.sym == sym::underscore || it.sym == sym::let_ || it.sym == sym::const_
+                    } else {
+                        it.sym == sym::let_
+                    };
+                    if is_err {
+                        return ExpandResult::only_err(ExpandError::new(
+                            it.span,
+                            ExpandErrorKind::NoMatchingRule,
+                        ));
+                    }
                 }
                 _ => {}
             };
@@ -874,7 +883,11 @@
             Op::Subtree { tokens, .. } => collect_vars(collector_fun, tokens),
             Op::Repeat { tokens, .. } => collect_vars(collector_fun, tokens),
             Op::Literal(_) | Op::Ident(_) | Op::Punct(_) => {}
-            Op::Ignore { .. } | Op::Index { .. } | Op::Count { .. } | Op::Len { .. } => {
+            Op::Ignore { .. }
+            | Op::Index { .. }
+            | Op::Count { .. }
+            | Op::Len { .. }
+            | Op::Concat { .. } => {
                 stdx::never!("metavariable expression in lhs found");
             }
         }
diff --git a/crates/mbe/src/expander/transcriber.rs b/crates/mbe/src/expander/transcriber.rs
index 286bd74..1db2f35 100644
--- a/crates/mbe/src/expander/transcriber.rs
+++ b/crates/mbe/src/expander/transcriber.rs
@@ -2,12 +2,12 @@
 //! `$ident => foo`, interpolates variables in the template, to get `fn foo() {}`
 
 use intern::{sym, Symbol};
-use span::Span;
+use span::{Edition, Span};
 use tt::Delimiter;
 
 use crate::{
     expander::{Binding, Bindings, Fragment},
-    parser::{MetaVarKind, Op, RepeatKind, Separator},
+    parser::{ConcatMetaVarExprElem, MetaVarKind, Op, RepeatKind, Separator},
     ExpandError, ExpandErrorKind, ExpandResult, MetaTemplate,
 };
 
@@ -97,7 +97,7 @@
                     | MetaVarKind::Ty
                     | MetaVarKind::Pat
                     | MetaVarKind::PatParam
-                    | MetaVarKind::Expr
+                    | MetaVarKind::Expr(_)
                     | MetaVarKind::Ident => {
                         Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
                             sym: sym::missing.clone(),
@@ -312,6 +312,82 @@
                     .into(),
                 );
             }
+            Op::Concat { elements, span: concat_span } => {
+                let mut concatenated = String::new();
+                for element in elements {
+                    match element {
+                        ConcatMetaVarExprElem::Ident(ident) => {
+                            concatenated.push_str(ident.sym.as_str())
+                        }
+                        ConcatMetaVarExprElem::Literal(lit) => {
+                            // FIXME: This isn't really correct wrt. escaping, but that's what rustc does and anyway
+                            // escaping is used most of the times for characters that are invalid in identifiers.
+                            concatenated.push_str(lit.symbol.as_str())
+                        }
+                        ConcatMetaVarExprElem::Var(var) => {
+                            // Handling of repetitions in `${concat}` isn't fleshed out in rustc, so we currently
+                            // err at it.
+                            // FIXME: Do what rustc does for repetitions.
+                            let var_value = match ctx.bindings.get_fragment(
+                                &var.sym,
+                                var.span,
+                                &mut ctx.nesting,
+                                marker,
+                            ) {
+                                Ok(var) => var,
+                                Err(e) => {
+                                    if err.is_none() {
+                                        err = Some(e);
+                                    };
+                                    continue;
+                                }
+                            };
+                            let value = match &var_value {
+                                Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => {
+                                    ident.sym.as_str()
+                                }
+                                Fragment::Tokens(tt::TokenTree::Leaf(tt::Leaf::Literal(lit))) => {
+                                    lit.symbol.as_str()
+                                }
+                                _ => {
+                                    if err.is_none() {
+                                        err = Some(ExpandError::binding_error(var.span, "metavariables of `${concat(..)}` must be of type `ident`, `literal` or `tt`"))
+                                    }
+                                    continue;
+                                }
+                            };
+                            concatenated.push_str(value);
+                        }
+                    }
+                }
+
+                // `${concat}` span comes from the macro (at least for now).
+                // See https://github.com/rust-lang/rust/blob/b0af276da341/compiler/rustc_expand/src/mbe/transcribe.rs#L724-L726.
+                let mut result_span = *concat_span;
+                marker(&mut result_span);
+
+                // FIXME: NFC normalize the result.
+                if !rustc_lexer::is_ident(&concatenated) {
+                    if err.is_none() {
+                        err = Some(ExpandError::binding_error(
+                            *concat_span,
+                            "`${concat(..)}` is not generating a valid identifier",
+                        ));
+                    }
+                    // Insert a dummy identifier for better parsing.
+                    concatenated.clear();
+                    concatenated.push_str("__ra_concat_dummy");
+                }
+
+                let needs_raw =
+                    parser::SyntaxKind::from_keyword(&concatenated, Edition::LATEST).is_some();
+                let is_raw = if needs_raw { tt::IdentIsRaw::Yes } else { tt::IdentIsRaw::No };
+                arena.push(tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
+                    is_raw,
+                    span: result_span,
+                    sym: Symbol::intern(&concatenated),
+                })));
+            }
         }
     }
     // drain the elements added in this instance of expand_subtree
diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs
index 8878553..ca10a2b 100644
--- a/crates/mbe/src/lib.rs
+++ b/crates/mbe/src/lib.rs
@@ -6,11 +6,20 @@
 //! The tests for this functionality live in another crate:
 //! `hir_def::macro_expansion_tests::mbe`.
 
+#![cfg_attr(feature = "in-rust-tree", feature(rustc_private))]
+
+#[cfg(not(feature = "in-rust-tree"))]
+extern crate ra_ap_rustc_lexer as rustc_lexer;
+#[cfg(feature = "in-rust-tree")]
+extern crate rustc_lexer;
+
 mod expander;
 mod parser;
 
 #[cfg(test)]
 mod benchmark;
+#[cfg(test)]
+mod tests;
 
 use span::{Edition, Span, SyntaxContextId};
 use syntax_bridge::to_parser_input;
diff --git a/crates/mbe/src/parser.rs b/crates/mbe/src/parser.rs
index 218c046..b55edf4 100644
--- a/crates/mbe/src/parser.rs
+++ b/crates/mbe/src/parser.rs
@@ -84,6 +84,10 @@
         // FIXME: `usize`` once we drop support for 1.76
         depth: Option<usize>,
     },
+    Concat {
+        elements: Box<[ConcatMetaVarExprElem]>,
+        span: Span,
+    },
     Repeat {
         tokens: MetaTemplate,
         kind: RepeatKind,
@@ -98,6 +102,18 @@
     Ident(tt::Ident<Span>),
 }
 
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub(crate) enum ConcatMetaVarExprElem {
+    /// There is NO preceding dollar sign, which means that this identifier should be interpreted
+    /// as a literal.
+    Ident(tt::Ident<Span>),
+    /// There is a preceding dollar sign, which means that this identifier should be expanded
+    /// and interpreted as a variable.
+    Var(tt::Ident<Span>),
+    /// For example, a number or a string.
+    Literal(tt::Literal<Span>),
+}
+
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub(crate) enum RepeatKind {
     ZeroOrMore,
@@ -106,6 +122,16 @@
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub(crate) enum ExprKind {
+    // Matches expressions using the post-edition 2024. Was written using
+    // `expr` in edition 2024 or later.
+    Expr,
+    // Matches expressions using the pre-edition 2024 rules.
+    // Either written using `expr` in edition 2021 or earlier or.was written using `expr_2021`.
+    Expr2021,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub(crate) enum MetaVarKind {
     Path,
     Ty,
@@ -116,7 +142,7 @@
     Meta,
     Item,
     Vis,
-    Expr,
+    Expr(ExprKind),
     Ident,
     Tt,
     Lifetime,
@@ -277,17 +303,27 @@
         let kind = match ident.sym.as_str() {
             "path" => MetaVarKind::Path,
             "ty" => MetaVarKind::Ty,
-            "pat" => match edition(ident.span.ctx) {
-                Edition::Edition2015 | Edition::Edition2018 => MetaVarKind::PatParam,
-                Edition::Edition2021 | Edition::Edition2024 => MetaVarKind::Pat,
-            },
+            "pat" => {
+                if edition(ident.span.ctx).at_least_2021() {
+                    MetaVarKind::Pat
+                } else {
+                    MetaVarKind::PatParam
+                }
+            }
             "pat_param" => MetaVarKind::PatParam,
             "stmt" => MetaVarKind::Stmt,
             "block" => MetaVarKind::Block,
             "meta" => MetaVarKind::Meta,
             "item" => MetaVarKind::Item,
             "vis" => MetaVarKind::Vis,
-            "expr" => MetaVarKind::Expr,
+            "expr" => {
+                if edition(ident.span.ctx).at_least_2024() {
+                    MetaVarKind::Expr(ExprKind::Expr)
+                } else {
+                    MetaVarKind::Expr(ExprKind::Expr2021)
+                }
+            }
+            "expr_2021" => MetaVarKind::Expr(ExprKind::Expr2021),
             "ident" => MetaVarKind::Ident,
             "tt" => MetaVarKind::Tt,
             "lifetime" => MetaVarKind::Lifetime,
@@ -364,6 +400,32 @@
             let depth = if try_eat_comma(&mut args) { Some(parse_depth(&mut args)?) } else { None };
             Op::Count { name: ident.sym.clone(), depth }
         }
+        s if sym::concat == *s => {
+            let mut elements = Vec::new();
+            while let Some(next) = args.peek_n(0) {
+                let element = if let tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) = next {
+                    args.next().expect("already peeked");
+                    ConcatMetaVarExprElem::Literal(lit.clone())
+                } else {
+                    let is_var = try_eat_dollar(&mut args);
+                    let ident = args.expect_ident_or_underscore()?.clone();
+
+                    if is_var {
+                        ConcatMetaVarExprElem::Var(ident)
+                    } else {
+                        ConcatMetaVarExprElem::Ident(ident)
+                    }
+                };
+                elements.push(element);
+                if args.peek_n(0).is_some() {
+                    args.expect_comma()?;
+                }
+            }
+            if elements.len() < 2 {
+                return Err(());
+            }
+            Op::Concat { elements: elements.into_boxed_slice(), span: func.span }
+        }
         _ => return Err(()),
     };
 
@@ -394,3 +456,11 @@
     }
     false
 }
+
+fn try_eat_dollar(src: &mut TtIter<'_, Span>) -> bool {
+    if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '$', .. }))) = src.peek_n(0) {
+        let _ = src.next();
+        return true;
+    }
+    false
+}
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs
new file mode 100644
index 0000000..e63ad11
--- /dev/null
+++ b/crates/mbe/src/tests.rs
@@ -0,0 +1,332 @@
+//! Tests specific to declarative macros, aka macros by example. This covers
+//! both stable `macro_rules!` macros as well as unstable `macro` macros.
+// FIXME: Move more of the nameres independent tests from
+// crates\hir-def\src\macro_expansion_tests\mod.rs to this
+use expect_test::expect;
+use span::{Edition, EditionedFileId, ErasedFileAstId, FileId, Span, SpanAnchor, SyntaxContextId};
+use stdx::format_to;
+use tt::{TextRange, TextSize};
+
+use crate::DeclarativeMacro;
+
+#[expect(deprecated)]
+fn check_(
+    def_edition: Edition,
+    call_edition: Edition,
+    macro2: bool,
+    decl: &str,
+    arg: &str,
+    render_debug: bool,
+    expect: expect_test::Expect,
+    parse: parser::TopEntryPoint,
+) {
+    let decl_tt = &syntax_bridge::parse_to_token_tree(
+        def_edition,
+        SpanAnchor {
+            file_id: EditionedFileId::new(FileId::from_raw(0), def_edition),
+            ast_id: ErasedFileAstId::from_raw(0),
+        },
+        SyntaxContextId::ROOT,
+        decl,
+    )
+    .unwrap();
+    let mac = if macro2 {
+        DeclarativeMacro::parse_macro2(None, decl_tt, |_| def_edition)
+    } else {
+        DeclarativeMacro::parse_macro_rules(decl_tt, |_| def_edition)
+    };
+    let call_anchor = SpanAnchor {
+        file_id: EditionedFileId::new(FileId::from_raw(1), call_edition),
+        ast_id: ErasedFileAstId::from_raw(0),
+    };
+    let arg_tt =
+        syntax_bridge::parse_to_token_tree(call_edition, call_anchor, SyntaxContextId::ROOT, arg)
+            .unwrap();
+    let res = mac.expand(
+        &arg_tt,
+        |_| (),
+        Span {
+            range: TextRange::up_to(TextSize::of(arg)),
+            anchor: call_anchor,
+            ctx: SyntaxContextId::ROOT,
+        },
+        def_edition,
+    );
+    let mut expect_res = String::new();
+    if let Some(err) = res.err {
+        format_to!(expect_res, "{err:#?}\n\n",);
+    }
+    if render_debug {
+        format_to!(expect_res, "{:#?}\n\n", res.value.0);
+    }
+    let (node, _) = syntax_bridge::token_tree_to_syntax_node(&res.value.0, parse, def_edition);
+    format_to!(
+        expect_res,
+        "{}",
+        syntax_bridge::prettify_macro_expansion::prettify_macro_expansion(
+            node.syntax_node(),
+            &mut |it| it.clone()
+        )
+    );
+    expect.assert_eq(&expect_res);
+}
+
+fn check(
+    def_edition: Edition,
+    call_edition: Edition,
+    decl: &str,
+    arg: &str,
+    expect: expect_test::Expect,
+) {
+    check_(
+        def_edition,
+        call_edition,
+        false,
+        decl,
+        arg,
+        true,
+        expect,
+        parser::TopEntryPoint::SourceFile,
+    );
+}
+
+#[test]
+fn token_mapping_smoke_test() {
+    check(
+        Edition::CURRENT,
+        Edition::CURRENT,
+        r#"
+( struct $ident:ident ) => {
+    struct $ident {
+        map: ::std::collections::HashSet<()>,
+    }
+};
+"#,
+        r#"
+struct MyTraitMap2
+"#,
+        expect![[r#"
+            SUBTREE $$ 1:0@0..20#0 1:0@0..20#0
+              IDENT   struct 0:0@34..40#0
+              IDENT   MyTraitMap2 1:0@8..19#0
+              SUBTREE {} 0:0@48..49#0 0:0@100..101#0
+                IDENT   map 0:0@58..61#0
+                PUNCH   : [alone] 0:0@61..62#0
+                PUNCH   : [joint] 0:0@63..64#0
+                PUNCH   : [alone] 0:0@64..65#0
+                IDENT   std 0:0@65..68#0
+                PUNCH   : [joint] 0:0@68..69#0
+                PUNCH   : [alone] 0:0@69..70#0
+                IDENT   collections 0:0@70..81#0
+                PUNCH   : [joint] 0:0@81..82#0
+                PUNCH   : [alone] 0:0@82..83#0
+                IDENT   HashSet 0:0@83..90#0
+                PUNCH   < [alone] 0:0@90..91#0
+                SUBTREE () 0:0@91..92#0 0:0@92..93#0
+                PUNCH   > [joint] 0:0@93..94#0
+                PUNCH   , [alone] 0:0@94..95#0
+
+            struct MyTraitMap2 {
+                map: ::std::collections::HashSet<()>,
+            }"#]],
+    );
+}
+
+#[test]
+fn token_mapping_floats() {
+    // Regression test for https://github.com/rust-lang/rust-analyzer/issues/12216
+    // (and related issues)
+    check(
+        Edition::CURRENT,
+        Edition::CURRENT,
+        r#"
+($($tt:tt)*) => {
+    $($tt)*
+};
+"#,
+        r#"
+fn main() {
+    1;
+    1.0;
+    ((1,),).0.0;
+    let x = 1;
+}
+"#,
+        expect![[r#"
+            SUBTREE $$ 1:0@0..63#0 1:0@0..63#0
+              IDENT   fn 1:0@1..3#0
+              IDENT   main 1:0@4..8#0
+              SUBTREE () 1:0@8..9#0 1:0@9..10#0
+              SUBTREE {} 1:0@11..12#0 1:0@61..62#0
+                LITERAL Integer 1 1:0@17..18#0
+                PUNCH   ; [alone] 1:0@18..19#0
+                LITERAL Float 1.0 1:0@24..27#0
+                PUNCH   ; [alone] 1:0@27..28#0
+                SUBTREE () 1:0@33..34#0 1:0@39..40#0
+                  SUBTREE () 1:0@34..35#0 1:0@37..38#0
+                    LITERAL Integer 1 1:0@35..36#0
+                    PUNCH   , [alone] 1:0@36..37#0
+                  PUNCH   , [alone] 1:0@38..39#0
+                PUNCH   . [alone] 1:0@40..41#0
+                LITERAL Float 0.0 1:0@41..44#0
+                PUNCH   ; [alone] 1:0@44..45#0
+                IDENT   let 1:0@50..53#0
+                IDENT   x 1:0@54..55#0
+                PUNCH   = [alone] 1:0@56..57#0
+                LITERAL Integer 1 1:0@58..59#0
+                PUNCH   ; [alone] 1:0@59..60#0
+
+            fn main(){
+                1;
+                1.0;
+                ((1,),).0.0;
+                let x = 1;
+            }"#]],
+    );
+}
+
+#[test]
+fn expr_2021() {
+    check(
+        Edition::Edition2024,
+        Edition::Edition2024,
+        r#"
+($($e:expr),* $(,)?) => {
+    $($e);* ;
+};
+"#,
+        r#"
+    _,
+    const { 1 },
+"#,
+        expect![[r#"
+            SUBTREE $$ 1:0@0..25#0 1:0@0..25#0
+              IDENT   _ 1:0@5..6#0
+              PUNCH   ; [joint] 0:0@36..37#0
+              SUBTREE () 0:0@34..35#0 0:0@34..35#0
+                IDENT   const 1:0@12..17#0
+                SUBTREE {} 1:0@18..19#0 1:0@22..23#0
+                  LITERAL Integer 1 1:0@20..21#0
+              PUNCH   ; [alone] 0:0@39..40#0
+
+            _;
+            (const  {
+                1
+            });"#]],
+    );
+    check(
+        Edition::Edition2021,
+        Edition::Edition2024,
+        r#"
+($($e:expr),* $(,)?) => {
+    $($e);* ;
+};
+"#,
+        r#"
+    _,
+"#,
+        expect![[r#"
+            ExpandError {
+                inner: (
+                    1:0@5..6#0,
+                    NoMatchingRule,
+                ),
+            }
+
+            SUBTREE $$ 1:0@0..8#0 1:0@0..8#0
+              PUNCH   ; [alone] 0:0@39..40#0
+
+            ;"#]],
+    );
+    check(
+        Edition::Edition2021,
+        Edition::Edition2024,
+        r#"
+($($e:expr),* $(,)?) => {
+    $($e);* ;
+};
+"#,
+        r#"
+    const { 1 },
+"#,
+        expect![[r#"
+            ExpandError {
+                inner: (
+                    1:0@5..10#0,
+                    NoMatchingRule,
+                ),
+            }
+
+            SUBTREE $$ 1:0@0..18#0 1:0@0..18#0
+              PUNCH   ; [alone] 0:0@39..40#0
+
+            ;"#]],
+    );
+    check(
+        Edition::Edition2024,
+        Edition::Edition2024,
+        r#"
+($($e:expr_2021),* $(,)?) => {
+    $($e);* ;
+};
+"#,
+        r#"
+    4,
+    "literal",
+    funcall(),
+    future.await,
+    break 'foo bar,
+"#,
+        expect![[r#"
+            SUBTREE $$ 1:0@0..76#0 1:0@0..76#0
+              LITERAL Integer 4 1:0@5..6#0
+              PUNCH   ; [joint] 0:0@41..42#0
+              LITERAL Str literal 1:0@12..21#0
+              PUNCH   ; [joint] 0:0@41..42#0
+              SUBTREE () 0:0@39..40#0 0:0@39..40#0
+                IDENT   funcall 1:0@27..34#0
+                SUBTREE () 1:0@34..35#0 1:0@35..36#0
+              PUNCH   ; [joint] 0:0@41..42#0
+              SUBTREE () 0:0@39..40#0 0:0@39..40#0
+                IDENT   future 1:0@42..48#0
+                PUNCH   . [alone] 1:0@48..49#0
+                IDENT   await 1:0@49..54#0
+              PUNCH   ; [joint] 0:0@41..42#0
+              SUBTREE () 0:0@39..40#0 0:0@39..40#0
+                IDENT   break 1:0@60..65#0
+                PUNCH   ' [joint] 1:0@66..67#0
+                IDENT   foo 1:0@67..70#0
+                IDENT   bar 1:0@71..74#0
+              PUNCH   ; [alone] 0:0@44..45#0
+
+            4;
+            "literal";
+            (funcall());
+            (future.await);
+            (break 'foo bar);"#]],
+    );
+    check(
+        Edition::Edition2024,
+        Edition::Edition2024,
+        r#"
+($($e:expr_2021),* $(,)?) => {
+    $($e);* ;
+};
+"#,
+        r#"
+    _,
+"#,
+        expect![[r#"
+            ExpandError {
+                inner: (
+                    1:0@5..6#0,
+                    NoMatchingRule,
+                ),
+            }
+
+            SUBTREE $$ 1:0@0..8#0 1:0@0..8#0
+              PUNCH   ; [alone] 0:0@44..45#0
+
+            ;"#]],
+    );
+}
diff --git a/crates/parser/src/edition.rs b/crates/parser/src/edition.rs
index be0a2c7..702b162 100644
--- a/crates/parser/src/edition.rs
+++ b/crates/parser/src/edition.rs
@@ -30,6 +30,12 @@
     pub fn at_least_2018(self) -> bool {
         self >= Edition::Edition2018
     }
+
+    pub fn iter() -> impl Iterator<Item = Edition> {
+        [Edition::Edition2015, Edition::Edition2018, Edition::Edition2021, Edition::Edition2024]
+            .iter()
+            .copied()
+    }
 }
 
 #[derive(Debug)]
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs
index a678c1f..2333e6c 100644
--- a/crates/parser/src/grammar/expressions/atom.rs
+++ b/crates/parser/src/grammar/expressions/atom.rs
@@ -245,7 +245,7 @@
 
 // test builtin_expr
 // fn foo() {
-//     builtin#asm(0);
+//     builtin#asm("");
 //     builtin#format_args("", 0, 1, a = 2 + 3, a + b);
 //     builtin#offset_of(Foo, bar.baz.0);
 // }
@@ -297,18 +297,188 @@
         p.expect(T![')']);
         Some(m.complete(p, FORMAT_ARGS_EXPR))
     } else if p.at_contextual_kw(T![asm]) {
-        p.bump_remap(T![asm]);
-        p.expect(T!['(']);
-        // FIXME: We just put expression here so highlighting kind of keeps working
-        expr(p);
-        p.expect(T![')']);
-        Some(m.complete(p, ASM_EXPR))
+        parse_asm_expr(p, m)
     } else {
         m.abandon(p);
         None
     }
 }
 
+// test asm_expr
+// fn foo() {
+//     builtin#asm(
+//         "mov {tmp}, {x}",
+//         "shl {tmp}, 1",
+//         "shl {x}, 2",
+//         "add {x}, {tmp}",
+//         x = inout(reg) x,
+//         tmp = out(reg) _,
+//     );
+// }
+fn parse_asm_expr(p: &mut Parser<'_>, m: Marker) -> Option<CompletedMarker> {
+    p.bump_remap(T![asm]);
+    p.expect(T!['(']);
+    if expr(p).is_none() {
+        p.err_and_bump("expected asm template");
+    }
+    let mut allow_templates = true;
+    while !p.at(EOF) && !p.at(T![')']) {
+        p.expect(T![,]);
+        // accept trailing commas
+        if p.at(T![')']) {
+            break;
+        }
+
+        let op_n = p.start();
+        // Parse clobber_abi
+        if p.eat_contextual_kw(T![clobber_abi]) {
+            parse_clobber_abi(p);
+            op_n.complete(p, ASM_CLOBBER_ABI);
+            allow_templates = false;
+            continue;
+        }
+
+        // Parse options
+        if p.eat_contextual_kw(T![options]) {
+            parse_options(p);
+            op_n.complete(p, ASM_OPTIONS);
+            allow_templates = false;
+            continue;
+        }
+
+        // Parse operand names
+        if p.at(T![ident]) && p.nth_at(1, T![=]) {
+            name(p);
+            p.bump(T![=]);
+            allow_templates = false;
+            true
+        } else {
+            false
+        };
+
+        let op = p.start();
+        let dir_spec = p.start();
+        if p.eat(T![in]) || p.eat_contextual_kw(T![out]) || p.eat_contextual_kw(T![lateout]) {
+            dir_spec.complete(p, ASM_DIR_SPEC);
+            parse_reg(p);
+            let op_expr = p.start();
+            expr(p);
+            op_expr.complete(p, ASM_OPERAND_EXPR);
+            op.complete(p, ASM_REG_OPERAND);
+            op_n.complete(p, ASM_OPERAND_NAMED);
+        } else if p.eat_contextual_kw(T![inout]) || p.eat_contextual_kw(T![inlateout]) {
+            dir_spec.complete(p, ASM_DIR_SPEC);
+            parse_reg(p);
+            let op_expr = p.start();
+            expr(p);
+            if p.eat(T![=>]) {
+                expr(p);
+            }
+            op_expr.complete(p, ASM_OPERAND_EXPR);
+            op.complete(p, ASM_REG_OPERAND);
+            op_n.complete(p, ASM_OPERAND_NAMED);
+        } else if p.eat_contextual_kw(T![label]) {
+            dir_spec.abandon(p);
+            block_expr(p);
+            op.complete(p, ASM_OPERAND_NAMED);
+            op_n.complete(p, ASM_LABEL);
+        } else if p.eat(T![const]) {
+            dir_spec.abandon(p);
+            expr(p);
+            op.complete(p, ASM_CONST);
+            op_n.complete(p, ASM_OPERAND_NAMED);
+        } else if p.eat_contextual_kw(T![sym]) {
+            dir_spec.abandon(p);
+            paths::type_path(p);
+            op.complete(p, ASM_SYM);
+            op_n.complete(p, ASM_OPERAND_NAMED);
+        } else if allow_templates {
+            dir_spec.abandon(p);
+            op.abandon(p);
+            op_n.abandon(p);
+            if expr(p).is_none() {
+                p.err_and_bump("expected asm template");
+            }
+            continue;
+        } else {
+            dir_spec.abandon(p);
+            op.abandon(p);
+            op_n.abandon(p);
+            p.err_and_bump("expected asm operand");
+            if p.at(T!['}']) {
+                break;
+            }
+            continue;
+        };
+        allow_templates = false;
+    }
+    p.expect(T![')']);
+    Some(m.complete(p, ASM_EXPR))
+}
+
+fn parse_options(p: &mut Parser<'_>) {
+    p.expect(T!['(']);
+
+    while !p.eat(T![')']) && !p.at(EOF) {
+        const OPTIONS: &[SyntaxKind] = &[
+            T![pure],
+            T![nomem],
+            T![readonly],
+            T![preserves_flags],
+            T![noreturn],
+            T![nostack],
+            T![may_unwind],
+            T![att_syntax],
+            T![raw],
+        ];
+        let m = p.start();
+        if !OPTIONS.iter().any(|&syntax| p.eat_contextual_kw(syntax)) {
+            p.err_and_bump("expected asm option");
+            m.abandon(p);
+            continue;
+        }
+        m.complete(p, ASM_OPTION);
+
+        // Allow trailing commas
+        if p.eat(T![')']) {
+            break;
+        }
+        p.expect(T![,]);
+    }
+}
+
+fn parse_clobber_abi(p: &mut Parser<'_>) {
+    p.expect(T!['(']);
+
+    while !p.eat(T![')']) && !p.at(EOF) {
+        if !p.expect(T![string]) {
+            break;
+        }
+
+        // Allow trailing commas
+        if p.eat(T![')']) {
+            break;
+        }
+        p.expect(T![,]);
+    }
+}
+
+fn parse_reg(p: &mut Parser<'_>) {
+    p.expect(T!['(']);
+    if p.at(T![ident]) {
+        let m = p.start();
+        name_ref(p);
+        m.complete(p, ASM_REG_SPEC);
+    } else if p.at(T![string]) {
+        let m = p.start();
+        p.bump_any();
+        m.complete(p, ASM_REG_SPEC);
+    } else {
+        p.err_and_bump("expected register name");
+    }
+    p.expect(T![')']);
+}
+
 // test array_expr
 // fn foo() {
 //     [];
diff --git a/crates/parser/src/lexed_str.rs b/crates/parser/src/lexed_str.rs
index 3590486..dceac81 100644
--- a/crates/parser/src/lexed_str.rs
+++ b/crates/parser/src/lexed_str.rs
@@ -202,9 +202,7 @@
                     err = "Unknown lifetime prefix";
                     LIFETIME_IDENT
                 }
-                rustc_lexer::TokenKind::RawLifetime => {
-                    LIFETIME_IDENT
-                }
+                rustc_lexer::TokenKind::RawLifetime => LIFETIME_IDENT,
 
                 rustc_lexer::TokenKind::Semi => T![;],
                 rustc_lexer::TokenKind::Comma => T![,],
diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs
index 7d3eb5d..f6b3783 100644
--- a/crates/parser/src/parser.rs
+++ b/crates/parser/src/parser.rs
@@ -131,6 +131,14 @@
         true
     }
 
+    pub(crate) fn eat_contextual_kw(&mut self, kind: SyntaxKind) -> bool {
+        if !self.at_contextual_kw(kind) {
+            return false;
+        }
+        self.bump_remap(kind);
+        true
+    }
+
     fn at_composite2(&self, n: usize, k1: SyntaxKind, k2: SyntaxKind) -> bool {
         self.inp.kind(self.pos + n) == k1
             && self.inp.kind(self.pos + n + 1) == k2
diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs
index 00f2124..288a07e 100644
--- a/crates/parser/src/syntax_kind/generated.rs
+++ b/crates/parser/src/syntax_kind/generated.rs
@@ -111,16 +111,32 @@
     YIELD_KW,
     ASM_KW,
     ASYNC_KW,
+    ATT_SYNTAX_KW,
     AUTO_KW,
     AWAIT_KW,
     BUILTIN_KW,
+    CLOBBER_ABI_KW,
     DEFAULT_KW,
     DYN_KW,
     FORMAT_ARGS_KW,
     GEN_KW,
+    INLATEOUT_KW,
+    INOUT_KW,
+    LABEL_KW,
+    LATEOUT_KW,
     MACRO_RULES_KW,
+    MAY_UNWIND_KW,
+    NOMEM_KW,
+    NORETURN_KW,
+    NOSTACK_KW,
     OFFSET_OF_KW,
+    OPTIONS_KW,
+    OUT_KW,
+    PRESERVES_FLAGS_KW,
+    PURE_KW,
     RAW_KW,
+    READONLY_KW,
+    SYM_KW,
     TRY_KW,
     UNION_KW,
     YEET_KW,
@@ -146,7 +162,20 @@
     ARG_LIST,
     ARRAY_EXPR,
     ARRAY_TYPE,
+    ASM_CLOBBER_ABI,
+    ASM_CONST,
+    ASM_DIR_SPEC,
     ASM_EXPR,
+    ASM_LABEL,
+    ASM_OPERAND,
+    ASM_OPERAND_EXPR,
+    ASM_OPERAND_NAMED,
+    ASM_OPTION,
+    ASM_OPTIONS,
+    ASM_PIECE,
+    ASM_REG_OPERAND,
+    ASM_REG_SPEC,
+    ASM_SYM,
     ASSOC_ITEM,
     ASSOC_ITEM_LIST,
     ASSOC_TYPE_ARG,
@@ -364,14 +393,30 @@
     pub fn is_contextual_keyword(self, edition: Edition) -> bool {
         match self {
             ASM_KW => true,
+            ATT_SYNTAX_KW => true,
             AUTO_KW => true,
             BUILTIN_KW => true,
+            CLOBBER_ABI_KW => true,
             DEFAULT_KW => true,
             DYN_KW if edition < Edition::Edition2018 => true,
             FORMAT_ARGS_KW => true,
+            INLATEOUT_KW => true,
+            INOUT_KW => true,
+            LABEL_KW => true,
+            LATEOUT_KW => true,
             MACRO_RULES_KW => true,
+            MAY_UNWIND_KW => true,
+            NOMEM_KW => true,
+            NORETURN_KW => true,
+            NOSTACK_KW => true,
             OFFSET_OF_KW => true,
+            OPTIONS_KW => true,
+            OUT_KW => true,
+            PRESERVES_FLAGS_KW => true,
+            PURE_KW => true,
             RAW_KW => true,
+            READONLY_KW => true,
+            SYM_KW => true,
             UNION_KW => true,
             YEET_KW => true,
             _ => false,
@@ -435,14 +480,30 @@
             GEN_KW if Edition::Edition2024 <= edition => true,
             TRY_KW if Edition::Edition2018 <= edition => true,
             ASM_KW => true,
+            ATT_SYNTAX_KW => true,
             AUTO_KW => true,
             BUILTIN_KW => true,
+            CLOBBER_ABI_KW => true,
             DEFAULT_KW => true,
             DYN_KW if edition < Edition::Edition2018 => true,
             FORMAT_ARGS_KW => true,
+            INLATEOUT_KW => true,
+            INOUT_KW => true,
+            LABEL_KW => true,
+            LATEOUT_KW => true,
             MACRO_RULES_KW => true,
+            MAY_UNWIND_KW => true,
+            NOMEM_KW => true,
+            NORETURN_KW => true,
+            NOSTACK_KW => true,
             OFFSET_OF_KW => true,
+            OPTIONS_KW => true,
+            OUT_KW => true,
+            PRESERVES_FLAGS_KW => true,
+            PURE_KW => true,
             RAW_KW => true,
+            READONLY_KW => true,
+            SYM_KW => true,
             UNION_KW => true,
             YEET_KW => true,
             _ => false,
@@ -580,14 +641,30 @@
     pub fn from_contextual_keyword(ident: &str, edition: Edition) -> Option<SyntaxKind> {
         let kw = match ident {
             "asm" => ASM_KW,
+            "att_syntax" => ATT_SYNTAX_KW,
             "auto" => AUTO_KW,
             "builtin" => BUILTIN_KW,
+            "clobber_abi" => CLOBBER_ABI_KW,
             "default" => DEFAULT_KW,
             "dyn" if edition < Edition::Edition2018 => DYN_KW,
             "format_args" => FORMAT_ARGS_KW,
+            "inlateout" => INLATEOUT_KW,
+            "inout" => INOUT_KW,
+            "label" => LABEL_KW,
+            "lateout" => LATEOUT_KW,
             "macro_rules" => MACRO_RULES_KW,
+            "may_unwind" => MAY_UNWIND_KW,
+            "nomem" => NOMEM_KW,
+            "noreturn" => NORETURN_KW,
+            "nostack" => NOSTACK_KW,
             "offset_of" => OFFSET_OF_KW,
+            "options" => OPTIONS_KW,
+            "out" => OUT_KW,
+            "preserves_flags" => PRESERVES_FLAGS_KW,
+            "pure" => PURE_KW,
             "raw" => RAW_KW,
+            "readonly" => READONLY_KW,
+            "sym" => SYM_KW,
             "union" => UNION_KW,
             "yeet" => YEET_KW,
             _ => return None,
@@ -630,4 +707,4 @@
     }
 }
 #[macro_export]
-macro_rules ! T { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
+macro_rules ! T { [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [Self] => { $ crate :: SyntaxKind :: SELF_TYPE_KW } ; [abstract] => { $ crate :: SyntaxKind :: ABSTRACT_KW } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [become] => { $ crate :: SyntaxKind :: BECOME_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [do] => { $ crate :: SyntaxKind :: DO_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [final] => { $ crate :: SyntaxKind :: FINAL_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [override] => { $ crate :: SyntaxKind :: OVERRIDE_KW } ; [priv] => { $ crate :: SyntaxKind :: PRIV_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [typeof] => { $ crate :: SyntaxKind :: TYPEOF_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [unsized] => { $ crate :: SyntaxKind :: UNSIZED_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [virtual] => { $ crate :: SyntaxKind :: VIRTUAL_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [asm] => { $ crate :: SyntaxKind :: ASM_KW } ; [att_syntax] => { $ crate :: SyntaxKind :: ATT_SYNTAX_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [builtin] => { $ crate :: SyntaxKind :: BUILTIN_KW } ; [clobber_abi] => { $ crate :: SyntaxKind :: CLOBBER_ABI_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [format_args] => { $ crate :: SyntaxKind :: FORMAT_ARGS_KW } ; [inlateout] => { $ crate :: SyntaxKind :: INLATEOUT_KW } ; [inout] => { $ crate :: SyntaxKind :: INOUT_KW } ; [label] => { $ crate :: SyntaxKind :: LABEL_KW } ; [lateout] => { $ crate :: SyntaxKind :: LATEOUT_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [may_unwind] => { $ crate :: SyntaxKind :: MAY_UNWIND_KW } ; [nomem] => { $ crate :: SyntaxKind :: NOMEM_KW } ; [noreturn] => { $ crate :: SyntaxKind :: NORETURN_KW } ; [nostack] => { $ crate :: SyntaxKind :: NOSTACK_KW } ; [offset_of] => { $ crate :: SyntaxKind :: OFFSET_OF_KW } ; [options] => { $ crate :: SyntaxKind :: OPTIONS_KW } ; [out] => { $ crate :: SyntaxKind :: OUT_KW } ; [preserves_flags] => { $ crate :: SyntaxKind :: PRESERVES_FLAGS_KW } ; [pure] => { $ crate :: SyntaxKind :: PURE_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [readonly] => { $ crate :: SyntaxKind :: READONLY_KW } ; [sym] => { $ crate :: SyntaxKind :: SYM_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [yeet] => { $ crate :: SyntaxKind :: YEET_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [gen] => { $ crate :: SyntaxKind :: GEN_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [int_number] => { $ crate :: SyntaxKind :: INT_NUMBER } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [string] => { $ crate :: SyntaxKind :: STRING } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; }
diff --git a/crates/parser/test_data/generated/runner.rs b/crates/parser/test_data/generated/runner.rs
index 9ce5a2a..164d0f3 100644
--- a/crates/parser/test_data/generated/runner.rs
+++ b/crates/parser/test_data/generated/runner.rs
@@ -19,6 +19,8 @@
     #[test]
     fn as_precedence() { run_and_expect_no_errors("test_data/parser/inline/ok/as_precedence.rs"); }
     #[test]
+    fn asm_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/asm_expr.rs"); }
+    #[test]
     fn assoc_const_eq() {
         run_and_expect_no_errors("test_data/parser/inline/ok/assoc_const_eq.rs");
     }
diff --git a/crates/parser/test_data/parser/inline/ok/asm_expr.rast b/crates/parser/test_data/parser/inline/ok/asm_expr.rast
new file mode 100644
index 0000000..f0213d0
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/asm_expr.rast
@@ -0,0 +1,85 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "foo"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        EXPR_STMT
+          ASM_EXPR
+            BUILTIN_KW "builtin"
+            POUND "#"
+            ASM_KW "asm"
+            L_PAREN "("
+            WHITESPACE "\n        "
+            LITERAL
+              STRING "\"mov {tmp}, {x}\""
+            COMMA ","
+            WHITESPACE "\n        "
+            LITERAL
+              STRING "\"shl {tmp}, 1\""
+            COMMA ","
+            WHITESPACE "\n        "
+            LITERAL
+              STRING "\"shl {x}, 2\""
+            COMMA ","
+            WHITESPACE "\n        "
+            LITERAL
+              STRING "\"add {x}, {tmp}\""
+            COMMA ","
+            WHITESPACE "\n        "
+            ASM_OPERAND_NAMED
+              NAME
+                IDENT "x"
+              WHITESPACE " "
+              EQ "="
+              WHITESPACE " "
+              ASM_REG_OPERAND
+                ASM_DIR_SPEC
+                  INOUT_KW "inout"
+                L_PAREN "("
+                ASM_REG_SPEC
+                  NAME_REF
+                    IDENT "reg"
+                R_PAREN ")"
+                WHITESPACE " "
+                ASM_OPERAND_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        NAME_REF
+                          IDENT "x"
+            COMMA ","
+            WHITESPACE "\n        "
+            ASM_OPERAND_NAMED
+              NAME
+                IDENT "tmp"
+              WHITESPACE " "
+              EQ "="
+              WHITESPACE " "
+              ASM_REG_OPERAND
+                ASM_DIR_SPEC
+                  OUT_KW "out"
+                L_PAREN "("
+                ASM_REG_SPEC
+                  NAME_REF
+                    IDENT "reg"
+                R_PAREN ")"
+                WHITESPACE " "
+                ASM_OPERAND_EXPR
+                  UNDERSCORE_EXPR
+                    UNDERSCORE "_"
+            COMMA ","
+            WHITESPACE "\n    "
+            R_PAREN ")"
+          SEMICOLON ";"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/asm_expr.rs b/crates/parser/test_data/parser/inline/ok/asm_expr.rs
new file mode 100644
index 0000000..0906cd3
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/asm_expr.rs
@@ -0,0 +1,10 @@
+fn foo() {
+    builtin#asm(
+        "mov {tmp}, {x}",
+        "shl {tmp}, 1",
+        "shl {x}, 2",
+        "add {x}, {tmp}",
+        x = inout(reg) x,
+        tmp = out(reg) _,
+    );
+}
diff --git a/crates/parser/test_data/parser/inline/ok/builtin_expr.rast b/crates/parser/test_data/parser/inline/ok/builtin_expr.rast
index 361900b..19a84ac 100644
--- a/crates/parser/test_data/parser/inline/ok/builtin_expr.rast
+++ b/crates/parser/test_data/parser/inline/ok/builtin_expr.rast
@@ -19,7 +19,7 @@
             ASM_KW "asm"
             L_PAREN "("
             LITERAL
-              INT_NUMBER "0"
+              STRING "\"\""
             R_PAREN ")"
           SEMICOLON ";"
         WHITESPACE "\n    "
diff --git a/crates/parser/test_data/parser/inline/ok/builtin_expr.rs b/crates/parser/test_data/parser/inline/ok/builtin_expr.rs
index 14431b0..920d0f7 100644
--- a/crates/parser/test_data/parser/inline/ok/builtin_expr.rs
+++ b/crates/parser/test_data/parser/inline/ok/builtin_expr.rs
@@ -1,5 +1,5 @@
 fn foo() {
-    builtin#asm(0);
+    builtin#asm("");
     builtin#format_args("", 0, 1, a = 2 + 3, a + b);
     builtin#offset_of(Foo, bar.baz.0);
 }
diff --git a/crates/proc-macro-api/src/lib.rs b/crates/proc-macro-api/src/lib.rs
index d50a3cd..011baad 100644
--- a/crates/proc-macro-api/src/lib.rs
+++ b/crates/proc-macro-api/src/lib.rs
@@ -152,10 +152,9 @@
         def_site: Span,
         call_site: Span,
         mixed_site: Span,
+        current_dir: Option<String>,
     ) -> Result<Result<tt::Subtree<Span>, PanicMessage>, ServerError> {
         let version = self.process.version();
-        let current_dir =
-            env.get("CARGO_RUSTC_CURRENT_DIR").or_else(|| env.get("CARGO_MANIFEST_DIR"));
 
         let mut span_data_table = SpanDataIndexMap::default();
         let def_site = span_data_table.insert_full(def_site).0;
diff --git a/crates/project-model/src/lib.rs b/crates/project-model/src/lib.rs
index b8ac55e..91bdef4 100644
--- a/crates/project-model/src/lib.rs
+++ b/crates/project-model/src/lib.rs
@@ -52,6 +52,15 @@
 };
 pub use cargo_metadata::Metadata;
 
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ProjectJsonFromCommand {
+    /// The data describing this project, such as its dependencies.
+    pub data: ProjectJsonData,
+    /// The build system specific file that describes this project,
+    /// such as a `my-project/BUCK` file.
+    pub buildfile: AbsPathBuf,
+}
+
 #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
 pub enum ProjectManifest {
     ProjectJson(ManifestPath),
diff --git a/crates/project-model/src/project_json.rs b/crates/project-model/src/project_json.rs
index a09c7a7..6a88cf0 100644
--- a/crates/project-model/src/project_json.rs
+++ b/crates/project-model/src/project_json.rs
@@ -66,6 +66,8 @@
     /// e.g. `path/to/sysroot/lib/rustlib/src/rust`
     pub(crate) sysroot_src: Option<AbsPathBuf>,
     project_root: AbsPathBuf,
+    /// The path to the rust-project.json file. May be None if this
+    /// data was generated by the discoverConfig command.
     manifest: Option<ManifestPath>,
     crates: Vec<Crate>,
     /// Configuration for CLI commands.
diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs
index f540bb9..30d1ddb 100644
--- a/crates/project-model/src/tests.rs
+++ b/crates/project-model/src/tests.rs
@@ -45,39 +45,6 @@
     to_crate_graph(project_workspace)
 }
 
-fn load_cargo_with_fake_sysroot(
-    file_map: &mut FxHashMap<AbsPathBuf, FileId>,
-    file: &str,
-) -> (CrateGraph, ProcMacroPaths) {
-    let meta: Metadata = get_test_json_file(file);
-    let manifest_path =
-        ManifestPath::try_from(AbsPathBuf::try_from(meta.workspace_root.clone()).unwrap()).unwrap();
-    let cargo_workspace = CargoWorkspace::new(meta, manifest_path);
-    let project_workspace = ProjectWorkspace {
-        kind: ProjectWorkspaceKind::Cargo {
-            cargo: cargo_workspace,
-            build_scripts: WorkspaceBuildScripts::default(),
-            rustc: Err(None),
-            cargo_config_extra_env: Default::default(),
-            error: None,
-        },
-        sysroot: get_fake_sysroot(),
-        rustc_cfg: Vec::new(),
-        cfg_overrides: Default::default(),
-        toolchain: None,
-        target_layout: Err("target_data_layout not loaded".into()),
-    };
-    project_workspace.to_crate_graph(
-        &mut {
-            |path| {
-                let len = file_map.len();
-                Some(*file_map.entry(path.to_path_buf()).or_insert(FileId::from_raw(len as u32)))
-            }
-        },
-        &Default::default(),
-    )
-}
-
 fn load_rust_project(file: &str) -> (CrateGraph, ProcMacroPaths) {
     let data = get_test_json_file(file);
     let project = rooted_project_json(data);
@@ -254,34 +221,6 @@
 }
 
 #[test]
-fn crate_graph_dedup_identical() {
-    let (mut crate_graph, proc_macros) =
-        load_cargo_with_fake_sysroot(&mut Default::default(), "regex-metadata.json");
-    crate_graph.sort_deps();
-
-    let (d_crate_graph, mut d_proc_macros) = (crate_graph.clone(), proc_macros.clone());
-
-    crate_graph.extend(d_crate_graph.clone(), &mut d_proc_macros, |(_, a), (_, b)| a == b);
-    assert!(crate_graph.iter().eq(d_crate_graph.iter()));
-    assert_eq!(proc_macros, d_proc_macros);
-}
-
-#[test]
-fn crate_graph_dedup() {
-    let path_map = &mut Default::default();
-    let (mut crate_graph, _proc_macros) =
-        load_cargo_with_fake_sysroot(path_map, "ripgrep-metadata.json");
-    assert_eq!(crate_graph.iter().count(), 81);
-    crate_graph.sort_deps();
-    let (regex_crate_graph, mut regex_proc_macros) =
-        load_cargo_with_fake_sysroot(path_map, "regex-metadata.json");
-    assert_eq!(regex_crate_graph.iter().count(), 60);
-
-    crate_graph.extend(regex_crate_graph, &mut regex_proc_macros, |(_, a), (_, b)| a == b);
-    assert_eq!(crate_graph.iter().count(), 118);
-}
-
-#[test]
 // FIXME Remove the ignore
 #[ignore = "requires nightly until the sysroot ships a cargo workspace for library on stable"]
 fn smoke_test_real_sysroot_cargo() {
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index 7834238..17b40a8 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -109,7 +109,7 @@
             ProjectWorkspaceKind::Cargo {
                 cargo,
                 error: _,
-                build_scripts: _,
+                build_scripts,
                 rustc,
                 cargo_config_extra_env,
             } => f
@@ -126,6 +126,7 @@
                 .field("toolchain", &toolchain)
                 .field("data_layout", &target_layout)
                 .field("cargo_config_extra_env", &cargo_config_extra_env)
+                .field("build_scripts", &build_scripts.error().unwrap_or("ok"))
                 .finish(),
             ProjectWorkspaceKind::Json(project) => {
                 let mut debug_struct = f.debug_struct("Json");
@@ -1456,7 +1457,7 @@
 
             // Remove all crates except the ones we are interested in to keep the sysroot graph small.
             let removed_mapping = cg.remove_crates_except(&marker_set);
-            let mapping = crate_graph.extend(cg, &mut pm, |(_, a), (_, b)| a == b);
+            let mapping = crate_graph.extend(cg, &mut pm);
 
             // Map the id through the removal mapping first, then through the crate graph extension mapping.
             pub_deps.iter_mut().for_each(|(_, cid, _)| {
@@ -1554,6 +1555,6 @@
 
 fn add_dep_inner(graph: &mut CrateGraph, from: CrateId, dep: Dependency) {
     if let Err(err) = graph.add_dep(from, dep) {
-        tracing::error!("{}", err)
+        tracing::warn!("{}", err)
     }
 }
diff --git a/crates/project-model/test_data/regex-metadata.json b/crates/project-model/test_data/regex-metadata.json
deleted file mode 100644
index 371464d..0000000
--- a/crates/project-model/test_data/regex-metadata.json
+++ /dev/null
@@ -1,6420 +0,0 @@
-{
-    "packages": [
-        {
-            "name": "aho-corasick",
-            "version": "0.7.20",
-            "id": "aho-corasick 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "Fast multiple substring searching.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "memchr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.4.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "aho_corasick",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/aho-corasick-0.7.20/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "default": [
-                    "std"
-                ],
-                "std": [
-                    "memchr/std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/aho-corasick-0.7.20/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "text-processing"
-            ],
-            "keywords": [
-                "string",
-                "search",
-                "text",
-                "aho",
-                "multi"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/aho-corasick",
-            "homepage": "https://github.com/BurntSushi/aho-corasick",
-            "documentation": null,
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "cc",
-            "version": "1.0.79",
-            "id": "cc 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A build-time dependency for Cargo build scripts to assist in invoking the native\nC compiler to compile native C code into a static archive to be linked into Rust\ncode.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "jobserver",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.16",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "tempfile",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "cc",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bin"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "gcc-shim",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/src/bin/gcc-shim.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cc_env",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/tests/cc_env.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cflags",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/tests/cflags.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cxxflags",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/tests/cxxflags.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/tests/test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "jobserver": [
-                    "dep:jobserver"
-                ],
-                "parallel": [
-                    "jobserver"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [
-                "development-tools::build-utils"
-            ],
-            "keywords": [
-                "build-dependencies"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/cc-rs",
-            "homepage": "https://github.com/rust-lang/cc-rs",
-            "documentation": "https://docs.rs/cc",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "cfg-if",
-            "version": "0.1.10",
-            "id": "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "A macro to ergonomically define an item depending on a large number of #[cfg]\nparameters. Structured like an if-else chain, the first matching branch is the\nitem that gets emitted.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "compiler_builtins",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": "core",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "cfg-if",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cfg-if-0.1.10/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "xcrate",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cfg-if-0.1.10/tests/xcrate.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "compiler_builtins": [
-                    "dep:compiler_builtins"
-                ],
-                "core": [
-                    "dep:core"
-                ],
-                "rustc-dep-of-std": [
-                    "core",
-                    "compiler_builtins"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cfg-if-0.1.10/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/alexcrichton/cfg-if",
-            "homepage": "https://github.com/alexcrichton/cfg-if",
-            "documentation": "https://docs.rs/cfg-if",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "cfg-if",
-            "version": "1.0.0",
-            "id": "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "A macro to ergonomically define an item depending on a large number of #[cfg]\nparameters. Structured like an if-else chain, the first matching branch is the\nitem that gets emitted.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "compiler_builtins",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": "core",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "cfg-if",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cfg-if-1.0.0/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "xcrate",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cfg-if-1.0.0/tests/xcrate.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "compiler_builtins": [
-                    "dep:compiler_builtins"
-                ],
-                "core": [
-                    "dep:core"
-                ],
-                "rustc-dep-of-std": [
-                    "core",
-                    "compiler_builtins"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cfg-if-1.0.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/alexcrichton/cfg-if",
-            "homepage": "https://github.com/alexcrichton/cfg-if",
-            "documentation": "https://docs.rs/cfg-if",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "docopt",
-            "version": "1.1.1",
-            "id": "docopt 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense/MIT",
-            "license_file": null,
-            "description": "Command line argument parsing.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.4.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "std",
-                        "unicode"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "derive"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "strsim",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.10",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "docopt",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/docopt-1.1.1/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bin"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "docopt-wordlist",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/docopt-1.1.1/src/wordlist.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cargo",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/docopt-1.1.1/examples/cargo.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cp",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/docopt-1.1.1/examples/cp.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "decode",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/docopt-1.1.1/examples/decode.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "hashmap",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/docopt-1.1.1/examples/hashmap.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "optional_command",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/docopt-1.1.1/examples/optional_command.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "verbose_multiple",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/docopt-1.1.1/examples/verbose_multiple.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/docopt-1.1.1/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "command-line-interface"
-            ],
-            "keywords": [
-                "docopt",
-                "argument",
-                "command",
-                "argv"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/docopt/docopt.rs",
-            "homepage": "https://github.com/docopt/docopt.rs",
-            "documentation": "http://burntsushi.net/rustdoc/docopt/",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "getrandom",
-            "version": "0.2.9",
-            "id": "getrandom 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A small cross-platform library for retrieving random data from system source",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "cfg-if",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "compiler_builtins",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": "core",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "js-sys",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(all(any(target_arch = \"wasm32\", target_arch = \"wasm64\"), target_os = \"unknown\"))",
-                    "registry": null
-                },
-                {
-                    "name": "wasm-bindgen",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.62",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": "cfg(all(any(target_arch = \"wasm32\", target_arch = \"wasm64\"), target_os = \"unknown\"))",
-                    "registry": null
-                },
-                {
-                    "name": "wasm-bindgen-test",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.18",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(all(any(target_arch = \"wasm32\", target_arch = \"wasm64\"), target_os = \"unknown\"))",
-                    "registry": null
-                },
-                {
-                    "name": "wasi",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.11",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": "cfg(target_os = \"wasi\")",
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.139",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": "cfg(unix)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "getrandom",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.9/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "custom",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.9/tests/custom.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "normal",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.9/tests/normal.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "rdrand",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.9/tests/rdrand.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "buffer",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.9/benches/buffer.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "compiler_builtins": [
-                    "dep:compiler_builtins"
-                ],
-                "core": [
-                    "dep:core"
-                ],
-                "custom": [],
-                "js": [
-                    "wasm-bindgen",
-                    "js-sys"
-                ],
-                "js-sys": [
-                    "dep:js-sys"
-                ],
-                "rdrand": [],
-                "rustc-dep-of-std": [
-                    "compiler_builtins",
-                    "core",
-                    "libc/rustc-dep-of-std",
-                    "wasi/rustc-dep-of-std"
-                ],
-                "std": [],
-                "test-in-browser": [],
-                "wasm-bindgen": [
-                    "dep:wasm-bindgen"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/getrandom-0.2.9/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "features": [
-                            "std",
-                            "custom"
-                        ],
-                        "rustdoc-args": [
-                            "--cfg",
-                            "docsrs"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "The Rand Project Developers"
-            ],
-            "categories": [
-                "os",
-                "no-std"
-            ],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-random/getrandom",
-            "homepage": null,
-            "documentation": "https://docs.rs/getrandom",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "lazy_static",
-            "version": "1.4.0",
-            "id": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "A macro for declaring lazily evaluated statics in Rust.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "spin",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.5.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "doc-comment",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "lazy_static",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/lazy_static-1.4.0/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "no_std",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/lazy_static-1.4.0/tests/no_std.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/lazy_static-1.4.0/tests/test.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "spin": [
-                    "dep:spin"
-                ],
-                "spin_no_std": [
-                    "spin"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/lazy_static-1.4.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Marvin Löbel <loebel.marvin@gmail.com>"
-            ],
-            "categories": [
-                "no-std",
-                "rust-patterns",
-                "memory-management"
-            ],
-            "keywords": [
-                "macro",
-                "lazy",
-                "static"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang-nursery/lazy-static.rs",
-            "homepage": null,
-            "documentation": "https://docs.rs/lazy_static",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "libc",
-            "version": "0.2.142",
-            "id": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Raw FFI bindings to platform libraries like libc.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "libc",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.142/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "const_fn",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.142/tests/const_fn.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.142/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "align": [],
-                "const-extern-fn": [],
-                "default": [
-                    "std"
-                ],
-                "extra_traits": [],
-                "rustc-dep-of-std": [
-                    "align",
-                    "rustc-std-workspace-core"
-                ],
-                "rustc-std-workspace-core": [
-                    "dep:rustc-std-workspace-core"
-                ],
-                "std": [],
-                "use_std": [
-                    "std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.142/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "features": [
-                            "const-extern-fn",
-                            "extra_traits"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [
-                "external-ffi-bindings",
-                "no-std",
-                "os"
-            ],
-            "keywords": [
-                "libc",
-                "ffi",
-                "bindings",
-                "operating",
-                "system"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/libc",
-            "homepage": "https://github.com/rust-lang/libc",
-            "documentation": "https://docs.rs/libc/",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "memchr",
-            "version": "2.5.0",
-            "id": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense/MIT",
-            "license_file": null,
-            "description": "Safe interface to memchr.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "compiler_builtins",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": "core",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.18",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quickcheck",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "memchr",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memchr-2.5.0/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memchr-2.5.0/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "compiler_builtins": [
-                    "dep:compiler_builtins"
-                ],
-                "core": [
-                    "dep:core"
-                ],
-                "default": [
-                    "std"
-                ],
-                "libc": [
-                    "dep:libc"
-                ],
-                "rustc-dep-of-std": [
-                    "core",
-                    "compiler_builtins"
-                ],
-                "std": [],
-                "use_std": [
-                    "std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memchr-2.5.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>",
-                "bluss"
-            ],
-            "categories": [],
-            "keywords": [
-                "memchr",
-                "char",
-                "scan",
-                "strchr",
-                "string"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/memchr",
-            "homepage": "https://github.com/BurntSushi/memchr",
-            "documentation": "https://docs.rs/memchr/",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "memmap",
-            "version": "0.6.2",
-            "id": "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "Cross-platform Rust API for memory-mapped file IO",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "tempdir",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(unix)",
-                    "registry": null
-                },
-                {
-                    "name": "winapi",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "basetsd",
-                        "handleapi",
-                        "memoryapi",
-                        "minwindef",
-                        "std",
-                        "sysinfoapi"
-                    ],
-                    "target": "cfg(windows)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "memmap",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memmap-0.6.2/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cat",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memmap-0.6.2/examples/cat.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memmap-0.6.2/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Dan Burkert <dan@danburkert.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "mmap",
-                "memory-map",
-                "io",
-                "file"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/danburkert/memmap-rs",
-            "homepage": null,
-            "documentation": "https://docs.rs/memmap",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "pkg-config",
-            "version": "0.3.26",
-            "id": "pkg-config 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A library to run the pkg-config system tool at build time in order to be used in\nCargo build scripts.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "pkg-config",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pkg-config-0.3.26/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pkg-config-0.3.26/tests/test.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pkg-config-0.3.26/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "build-dependencies"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/pkg-config-rs",
-            "homepage": null,
-            "documentation": "https://docs.rs/pkg-config",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "proc-macro2",
-            "version": "1.0.56",
-            "id": "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "unicode-ident",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quote",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustversion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "proc-macro2",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "comments",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/comments.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "features",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/features.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "marker",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/marker.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_fmt",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/test_fmt.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_size",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/test_size.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "proc-macro"
-                ],
-                "nightly": [],
-                "proc-macro": [],
-                "span-locations": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "rustc-args": [
-                            "--cfg",
-                            "procmacro2_semver_exempt"
-                        ],
-                        "rustdoc-args": [
-                            "--cfg",
-                            "procmacro2_semver_exempt",
-                            "--cfg",
-                            "doc_cfg"
-                        ],
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                },
-                "playground": {
-                    "features": [
-                        "span-locations"
-                    ]
-                }
-            },
-            "publish": null,
-            "authors": [
-                "David Tolnay <dtolnay@gmail.com>",
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [
-                "development-tools::procedural-macro-helpers"
-            ],
-            "keywords": [
-                "macros",
-                "syn"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dtolnay/proc-macro2",
-            "homepage": null,
-            "documentation": "https://docs.rs/proc-macro2",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.31"
-        },
-        {
-            "name": "quickcheck",
-            "version": "1.0.3",
-            "id": "quickcheck 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense/MIT",
-            "license_file": null,
-            "description": "Automatic property based testing with shrinking.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "env_logger",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "log",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "getrandom",
-                        "small_rng"
-                    ],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "quickcheck",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quickcheck-1.0.3/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "btree_set_range",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quickcheck-1.0.3/examples/btree_set_range.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "out_of_bounds",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quickcheck-1.0.3/examples/out_of_bounds.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "reverse",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quickcheck-1.0.3/examples/reverse.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "reverse_single",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quickcheck-1.0.3/examples/reverse_single.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "sieve",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quickcheck-1.0.3/examples/sieve.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "sort",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quickcheck-1.0.3/examples/sort.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "regex",
-                    "use_logging"
-                ],
-                "env_logger": [
-                    "dep:env_logger"
-                ],
-                "log": [
-                    "dep:log"
-                ],
-                "regex": [
-                    "env_logger/regex"
-                ],
-                "use_logging": [
-                    "log",
-                    "env_logger"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quickcheck-1.0.3/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "development-tools::testing"
-            ],
-            "keywords": [
-                "testing",
-                "quickcheck",
-                "property",
-                "shrinking",
-                "fuzz"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/quickcheck",
-            "homepage": "https://github.com/BurntSushi/quickcheck",
-            "documentation": "https://docs.rs/quickcheck",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "quote",
-            "version": "1.0.26",
-            "id": "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Quasi-quoting macro quote!(...)",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "proc-macro2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.52",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustversion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "trybuild",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.66",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "diff"
-                    ],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "quote",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quote-1.0.26/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "compiletest",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quote-1.0.26/tests/compiletest.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quote-1.0.26/tests/test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quote-1.0.26/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "proc-macro"
-                ],
-                "proc-macro": [
-                    "proc-macro2/proc-macro"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quote-1.0.26/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "development-tools::procedural-macro-helpers"
-            ],
-            "keywords": [
-                "macros",
-                "syn"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dtolnay/quote",
-            "homepage": null,
-            "documentation": "https://docs.rs/quote/",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.31"
-        },
-        {
-            "name": "rand",
-            "version": "0.8.5",
-            "id": "rand 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Random number generators and other randomness functionality.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "log",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "packed_simd_2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.7",
-                    "kind": null,
-                    "rename": "packed_simd",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [
-                        "into_bits"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand_chacha",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand_core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.6.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.103",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [
-                        "derive"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "bincode",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.2.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand_pcg",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.22",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": "cfg(unix)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "rand",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/rand-0.8.5/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "alloc": [
-                    "rand_core/alloc"
-                ],
-                "default": [
-                    "std",
-                    "std_rng"
-                ],
-                "getrandom": [
-                    "rand_core/getrandom"
-                ],
-                "libc": [
-                    "dep:libc"
-                ],
-                "log": [
-                    "dep:log"
-                ],
-                "min_const_gen": [],
-                "nightly": [],
-                "packed_simd": [
-                    "dep:packed_simd"
-                ],
-                "rand_chacha": [
-                    "dep:rand_chacha"
-                ],
-                "serde": [
-                    "dep:serde"
-                ],
-                "serde1": [
-                    "serde",
-                    "rand_core/serde1"
-                ],
-                "simd_support": [
-                    "packed_simd"
-                ],
-                "small_rng": [],
-                "std": [
-                    "rand_core/std",
-                    "rand_chacha/std",
-                    "alloc",
-                    "getrandom",
-                    "libc"
-                ],
-                "std_rng": [
-                    "rand_chacha"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/rand-0.8.5/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "all-features": true,
-                        "rustdoc-args": [
-                            "--cfg",
-                            "doc_cfg"
-                        ]
-                    }
-                },
-                "playground": {
-                    "features": [
-                        "small_rng",
-                        "serde1"
-                    ]
-                }
-            },
-            "publish": null,
-            "authors": [
-                "The Rand Project Developers",
-                "The Rust Project Developers"
-            ],
-            "categories": [
-                "algorithms",
-                "no-std"
-            ],
-            "keywords": [
-                "random",
-                "rng"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-random/rand",
-            "homepage": "https://rust-random.github.io/book",
-            "documentation": "https://docs.rs/rand",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "rand_core",
-            "version": "0.6.4",
-            "id": "rand_core 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Core random number generator traits and tools for implementation.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "getrandom",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [
-                        "derive"
-                    ],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "rand_core",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/rand_core-0.6.4/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "alloc": [],
-                "getrandom": [
-                    "dep:getrandom"
-                ],
-                "serde": [
-                    "dep:serde"
-                ],
-                "serde1": [
-                    "serde"
-                ],
-                "std": [
-                    "alloc",
-                    "getrandom",
-                    "getrandom/std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/rand_core-0.6.4/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "all-features": true,
-                        "rustdoc-args": [
-                            "--cfg",
-                            "doc_cfg"
-                        ]
-                    }
-                },
-                "playground": {
-                    "all-features": true
-                }
-            },
-            "publish": null,
-            "authors": [
-                "The Rand Project Developers",
-                "The Rust Project Developers"
-            ],
-            "categories": [
-                "algorithms",
-                "no-std"
-            ],
-            "keywords": [
-                "random",
-                "rng"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-random/rand",
-            "homepage": "https://rust-random.github.io/book",
-            "documentation": "https://docs.rs/rand_core",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "regex",
-            "version": "1.7.1",
-            "id": "regex 1.7.1 (path+file:///$ROOT$regex)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "An implementation of regular expressions for Rust. This implementation uses\nfinite automata and guarantees linear time matching on all inputs.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "aho-corasick",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.7.18",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "memchr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.4.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex-syntax",
-                    "source": null,
-                    "req": "^0.6.27",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$regex/regex-syntax"
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quickcheck",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "getrandom",
-                        "small_rng"
-                    ],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "regex",
-                    "src_path": "$ROOT$regex/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-bytes",
-                    "src_path": "$ROOT$regex/examples/shootout-regex-dna-bytes.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-cheat",
-                    "src_path": "$ROOT$regex/examples/shootout-regex-dna-cheat.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-replace",
-                    "src_path": "$ROOT$regex/examples/shootout-regex-dna-replace.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-single-cheat",
-                    "src_path": "$ROOT$regex/examples/shootout-regex-dna-single-cheat.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-single",
-                    "src_path": "$ROOT$regex/examples/shootout-regex-dna-single.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna",
-                    "src_path": "$ROOT$regex/examples/shootout-regex-dna.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "default",
-                    "src_path": "$ROOT$regex/tests/test_default.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "default-bytes",
-                    "src_path": "$ROOT$regex/tests/test_default_bytes.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "nfa",
-                    "src_path": "$ROOT$regex/tests/test_nfa.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "nfa-utf8bytes",
-                    "src_path": "$ROOT$regex/tests/test_nfa_utf8bytes.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "nfa-bytes",
-                    "src_path": "$ROOT$regex/tests/test_nfa_bytes.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "backtrack",
-                    "src_path": "$ROOT$regex/tests/test_backtrack.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "backtrack-utf8bytes",
-                    "src_path": "$ROOT$regex/tests/test_backtrack_utf8bytes.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "backtrack-bytes",
-                    "src_path": "$ROOT$regex/tests/test_backtrack_bytes.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "crates-regex",
-                    "src_path": "$ROOT$regex/tests/test_crates_regex.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "aho-corasick": [
-                    "dep:aho-corasick"
-                ],
-                "default": [
-                    "std",
-                    "perf",
-                    "unicode",
-                    "regex-syntax/default"
-                ],
-                "memchr": [
-                    "dep:memchr"
-                ],
-                "pattern": [],
-                "perf": [
-                    "perf-cache",
-                    "perf-dfa",
-                    "perf-inline",
-                    "perf-literal"
-                ],
-                "perf-cache": [],
-                "perf-dfa": [],
-                "perf-inline": [],
-                "perf-literal": [
-                    "aho-corasick",
-                    "memchr"
-                ],
-                "std": [],
-                "unicode": [
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment",
-                    "regex-syntax/unicode"
-                ],
-                "unicode-age": [
-                    "regex-syntax/unicode-age"
-                ],
-                "unicode-bool": [
-                    "regex-syntax/unicode-bool"
-                ],
-                "unicode-case": [
-                    "regex-syntax/unicode-case"
-                ],
-                "unicode-gencat": [
-                    "regex-syntax/unicode-gencat"
-                ],
-                "unicode-perl": [
-                    "regex-syntax/unicode-perl"
-                ],
-                "unicode-script": [
-                    "regex-syntax/unicode-script"
-                ],
-                "unicode-segment": [
-                    "regex-syntax/unicode-segment"
-                ],
-                "unstable": [
-                    "pattern"
-                ],
-                "use_std": [
-                    "std"
-                ]
-            },
-            "manifest_path": "$ROOT$regex/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [
-                "text-processing"
-            ],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/regex",
-            "homepage": "https://github.com/rust-lang/regex",
-            "documentation": "https://docs.rs/regex",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "regex",
-            "version": "1.8.1",
-            "id": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "An implementation of regular expressions for Rust. This implementation uses\nfinite automata and guarantees linear time matching on all inputs.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "aho-corasick",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "memchr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.5.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex-syntax",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.7.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quickcheck",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "getrandom",
-                        "small_rng"
-                    ],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "regex",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna-bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-cheat",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna-cheat.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-replace",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna-replace.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-single-cheat",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna-single-cheat.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-single",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna-single.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "default",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_default.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "default-bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_default_bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "nfa",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_nfa.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "nfa-utf8bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_nfa_utf8bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "nfa-bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_nfa_bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "backtrack",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_backtrack.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "backtrack-utf8bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_backtrack_utf8bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "backtrack-bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_backtrack_bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "crates-regex",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_crates_regex.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "aho-corasick": [
-                    "dep:aho-corasick"
-                ],
-                "default": [
-                    "std",
-                    "perf",
-                    "unicode",
-                    "regex-syntax/default"
-                ],
-                "memchr": [
-                    "dep:memchr"
-                ],
-                "pattern": [],
-                "perf": [
-                    "perf-cache",
-                    "perf-dfa",
-                    "perf-inline",
-                    "perf-literal"
-                ],
-                "perf-cache": [],
-                "perf-dfa": [],
-                "perf-inline": [],
-                "perf-literal": [
-                    "aho-corasick",
-                    "memchr"
-                ],
-                "std": [],
-                "unicode": [
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment",
-                    "regex-syntax/unicode"
-                ],
-                "unicode-age": [
-                    "regex-syntax/unicode-age"
-                ],
-                "unicode-bool": [
-                    "regex-syntax/unicode-bool"
-                ],
-                "unicode-case": [
-                    "regex-syntax/unicode-case"
-                ],
-                "unicode-gencat": [
-                    "regex-syntax/unicode-gencat"
-                ],
-                "unicode-perl": [
-                    "regex-syntax/unicode-perl"
-                ],
-                "unicode-script": [
-                    "regex-syntax/unicode-script"
-                ],
-                "unicode-segment": [
-                    "regex-syntax/unicode-segment"
-                ],
-                "unstable": [
-                    "pattern"
-                ],
-                "use_std": [
-                    "std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [
-                "text-processing"
-            ],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/regex",
-            "homepage": "https://github.com/rust-lang/regex",
-            "documentation": "https://docs.rs/regex",
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.60.0"
-        },
-        {
-            "name": "regex-benchmark",
-            "version": "0.1.0",
-            "id": "regex-benchmark 0.1.0 (path+file:///$ROOT$regex/bench)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Regex benchmarks for Rust's and other engines.",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "cfg-if",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "docopt",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "libpcre-sys",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "memmap",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.6.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "onig",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": null,
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$regex"
-                },
-                {
-                    "name": "regex-syntax",
-                    "source": null,
-                    "req": "^0.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$regex/regex-syntax"
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "derive"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "cc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "build",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "pkg-config",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.9",
-                    "kind": "build",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "bin"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "regex-run-one",
-                    "src_path": "$ROOT$regex/bench/src/main.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench",
-                    "src_path": "$ROOT$regex/bench/src/bench.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$regex/bench/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "libpcre-sys": [
-                    "dep:libpcre-sys"
-                ],
-                "onig": [
-                    "dep:onig"
-                ],
-                "re-onig": [
-                    "onig"
-                ],
-                "re-pcre1": [
-                    "libpcre-sys"
-                ],
-                "re-pcre2": [],
-                "re-re2": [],
-                "re-rust": [],
-                "re-rust-bytes": [],
-                "re-tcl": []
-            },
-            "manifest_path": "$ROOT$regex/bench/Cargo.toml",
-            "metadata": null,
-            "publish": [],
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": null,
-            "repository": "https://github.com/rust-lang/regex",
-            "homepage": "https://github.com/rust-lang/regex",
-            "documentation": "https://docs.rs/regex",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "regex-debug",
-            "version": "0.1.0",
-            "id": "regex-debug 0.1.0 (path+file:///$ROOT$regex/regex-debug)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A tool useful for debugging regular expressions.",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "docopt",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": null,
-                    "req": "^1.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$regex"
-                },
-                {
-                    "name": "regex-syntax",
-                    "source": null,
-                    "req": "^0.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$regex/regex-syntax"
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "derive"
-                    ],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "bin"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "regex-debug",
-                    "src_path": "$ROOT$regex/regex-debug/src/main.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$regex/regex-debug/Cargo.toml",
-            "metadata": null,
-            "publish": [],
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": null,
-            "repository": "https://github.com/rust-lang/regex",
-            "homepage": "https://github.com/rust-lang/regex",
-            "documentation": "https://docs.rs/regex",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "regex-syntax",
-            "version": "0.6.28",
-            "id": "regex-syntax 0.6.28 (path+file:///$ROOT$regex/regex-syntax)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A regular expression parser.",
-            "source": null,
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "regex-syntax",
-                    "src_path": "$ROOT$regex/regex-syntax/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench",
-                    "src_path": "$ROOT$regex/regex-syntax/benches/bench.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "unicode"
-                ],
-                "unicode": [
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ],
-                "unicode-age": [],
-                "unicode-bool": [],
-                "unicode-case": [],
-                "unicode-gencat": [],
-                "unicode-perl": [],
-                "unicode-script": [],
-                "unicode-segment": []
-            },
-            "manifest_path": "$ROOT$regex/regex-syntax/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/regex",
-            "homepage": "https://github.com/rust-lang/regex",
-            "documentation": "https://docs.rs/regex-syntax",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "regex-syntax",
-            "version": "0.7.1",
-            "id": "regex-syntax 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A regular expression parser.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "regex-syntax",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-syntax-0.7.1/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-syntax-0.7.1/benches/bench.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "std",
-                    "unicode"
-                ],
-                "std": [],
-                "unicode": [
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ],
-                "unicode-age": [],
-                "unicode-bool": [],
-                "unicode-case": [],
-                "unicode-gencat": [],
-                "unicode-perl": [],
-                "unicode-script": [],
-                "unicode-segment": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-syntax-0.7.1/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "all-features": true,
-                        "rustdoc-args": [
-                            "--cfg",
-                            "docsrs"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/regex",
-            "homepage": "https://github.com/rust-lang/regex",
-            "documentation": "https://docs.rs/regex-syntax",
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.60.0"
-        },
-        {
-            "name": "rure",
-            "version": "0.2.2",
-            "id": "rure 0.2.2 (path+file:///$ROOT$regex/regex-capi)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A C API for Rust's regular expression library.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": null,
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$regex"
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "staticlib",
-                        "cdylib",
-                        "rlib"
-                    ],
-                    "crate_types": [
-                        "staticlib",
-                        "cdylib",
-                        "rlib"
-                    ],
-                    "name": "rure",
-                    "src_path": "$ROOT$regex/regex-capi/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$regex/regex-capi/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/regex",
-            "homepage": "https://github.com/rust-lang/regex",
-            "documentation": "https://github.com/rust-lang/regex/tree/master/regex-capi",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "serde",
-            "version": "1.0.160",
-            "id": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A generic serialization/deserialization framework",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "serde_derive",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "=1.0.160",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_derive",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "serde",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde-1.0.160/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde-1.0.160/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "alloc": [],
-                "default": [
-                    "std"
-                ],
-                "derive": [
-                    "serde_derive"
-                ],
-                "rc": [],
-                "serde_derive": [
-                    "dep:serde_derive"
-                ],
-                "std": [],
-                "unstable": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde-1.0.160/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "features": [
-                            "derive"
-                        ],
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                },
-                "playground": {
-                    "features": [
-                        "derive",
-                        "rc"
-                    ]
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Erick Tryzelaar <erick.tryzelaar@gmail.com>",
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "encoding",
-                "no-std"
-            ],
-            "keywords": [
-                "serde",
-                "serialization",
-                "no_std"
-            ],
-            "readme": "crates-io.md",
-            "repository": "https://github.com/serde-rs/serde",
-            "homepage": "https://serde.rs",
-            "documentation": "https://docs.rs/serde",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.19"
-        },
-        {
-            "name": "serde_derive",
-            "version": "1.0.160",
-            "id": "serde_derive 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "proc-macro2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quote",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "syn",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.0.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "proc-macro"
-                    ],
-                    "crate_types": [
-                        "proc-macro"
-                    ],
-                    "name": "serde_derive",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_derive-1.0.160/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_derive-1.0.160/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [],
-                "deserialize_in_place": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_derive-1.0.160/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Erick Tryzelaar <erick.tryzelaar@gmail.com>",
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "no-std"
-            ],
-            "keywords": [
-                "serde",
-                "serialization",
-                "no_std",
-                "derive"
-            ],
-            "readme": "crates-io.md",
-            "repository": "https://github.com/serde-rs/serde",
-            "homepage": "https://serde.rs",
-            "documentation": "https://serde.rs/derive.html",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.56"
-        },
-        {
-            "name": "strsim",
-            "version": "0.10.0",
-            "id": "strsim 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT",
-            "license_file": null,
-            "description": "Implementations of string similarity metrics. Includes Hamming, Levenshtein,\nOSA, Damerau-Levenshtein, Jaro, Jaro-Winkler, and Sørensen-Dice.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "strsim",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/strsim-0.10.0/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "lib",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/strsim-0.10.0/tests/lib.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "benches",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/strsim-0.10.0/benches/benches.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/strsim-0.10.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Danny Guo <danny@dannyguo.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "string",
-                "similarity",
-                "Hamming",
-                "Levenshtein",
-                "Jaro"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dguo/strsim-rs",
-            "homepage": "https://github.com/dguo/strsim-rs",
-            "documentation": "https://docs.rs/strsim/",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "syn",
-            "version": "2.0.15",
-            "id": "syn 2.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Parser for Rust source code",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "proc-macro2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.55",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quote",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.25",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "unicode-ident",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "anyhow",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "automod",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "flate2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "insta",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rayon",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "ref-cast",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "reqwest",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.11",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "blocking"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustversion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "syn-test-suite",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "tar",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.16",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "termcolor",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "walkdir",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.3.2",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "syn",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "regression",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/regression.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_asyncness",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_asyncness.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_attribute",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_attribute.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_derive_input",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_derive_input.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_expr",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_expr.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_generics",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_generics.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_grouping",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_grouping.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_ident",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_ident.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_item",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_item.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_iterators",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_iterators.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_lit",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_lit.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_meta",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_meta.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_parse_buffer",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_parse_buffer.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_parse_stream",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_parse_stream.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_pat",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_pat.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_path",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_path.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_precedence",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_precedence.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_receiver",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_receiver.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_round_trip",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_round_trip.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_shebang",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_shebang.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_should_parse",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_should_parse.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_size",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_size.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_stmt",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_stmt.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_token_trees",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_token_trees.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_ty",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_ty.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_visibility",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_visibility.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "zzz_stable",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/zzz_stable.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "rust",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/benches/rust.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "full",
-                        "parsing"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "file",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/benches/file.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "full",
-                        "parsing"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "clone-impls": [],
-                "default": [
-                    "derive",
-                    "parsing",
-                    "printing",
-                    "clone-impls",
-                    "proc-macro"
-                ],
-                "derive": [],
-                "extra-traits": [],
-                "fold": [],
-                "full": [],
-                "parsing": [],
-                "printing": [
-                    "quote"
-                ],
-                "proc-macro": [
-                    "proc-macro2/proc-macro",
-                    "quote/proc-macro"
-                ],
-                "quote": [
-                    "dep:quote"
-                ],
-                "test": [
-                    "syn-test-suite/all-features"
-                ],
-                "visit": [],
-                "visit-mut": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "all-features": true,
-                        "rustdoc-args": [
-                            "--cfg",
-                            "doc_cfg"
-                        ],
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                },
-                "playground": {
-                    "features": [
-                        "full",
-                        "visit",
-                        "visit-mut",
-                        "fold",
-                        "extra-traits"
-                    ]
-                }
-            },
-            "publish": null,
-            "authors": [
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "development-tools::procedural-macro-helpers",
-                "parser-implementations"
-            ],
-            "keywords": [
-                "macros",
-                "syn"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dtolnay/syn",
-            "homepage": null,
-            "documentation": "https://docs.rs/syn",
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.56"
-        },
-        {
-            "name": "unicode-ident",
-            "version": "1.0.8",
-            "id": "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "(MIT OR Apache-2.0) AND Unicode-DFS-2016",
-            "license_file": null,
-            "description": "Determine whether characters have the XID_Start or XID_Continue properties according to Unicode Standard Annex #31",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "criterion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "fst",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "small_rng"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "roaring",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.10",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "ucd-trie",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "unicode-xid",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.4",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "unicode-ident",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-ident-1.0.8/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "compare",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-ident-1.0.8/tests/compare.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "static_size",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-ident-1.0.8/tests/static_size.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "xid",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-ident-1.0.8/benches/xid.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-ident-1.0.8/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "development-tools::procedural-macro-helpers",
-                "no-std"
-            ],
-            "keywords": [
-                "unicode",
-                "xid"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dtolnay/unicode-ident",
-            "homepage": null,
-            "documentation": "https://docs.rs/unicode-ident",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.31"
-        },
-        {
-            "name": "wasi",
-            "version": "0.11.0+wasi-snapshot-preview1",
-            "id": "wasi 0.11.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT",
-            "license_file": null,
-            "description": "Experimental WASI API bindings for Rust",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "compiler_builtins",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": "core",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-alloc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "wasi",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasi-0.11.0+wasi-snapshot-preview1/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "compiler_builtins": [
-                    "dep:compiler_builtins"
-                ],
-                "core": [
-                    "dep:core"
-                ],
-                "default": [
-                    "std"
-                ],
-                "rustc-dep-of-std": [
-                    "compiler_builtins",
-                    "core",
-                    "rustc-std-workspace-alloc"
-                ],
-                "rustc-std-workspace-alloc": [
-                    "dep:rustc-std-workspace-alloc"
-                ],
-                "std": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasi-0.11.0+wasi-snapshot-preview1/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "The Cranelift Project Developers"
-            ],
-            "categories": [
-                "no-std",
-                "wasm"
-            ],
-            "keywords": [
-                "webassembly",
-                "wasm"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/bytecodealliance/wasi",
-            "homepage": null,
-            "documentation": "https://docs.rs/wasi",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "winapi",
-            "version": "0.3.9",
-            "id": "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "Raw FFI bindings for all of Windows API.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "winapi-i686-pc-windows-gnu",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "i686-pc-windows-gnu",
-                    "registry": null
-                },
-                {
-                    "name": "winapi-x86_64-pc-windows-gnu",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "x86_64-pc-windows-gnu",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "winapi",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-0.3.9/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-0.3.9/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "accctrl": [],
-                "aclapi": [],
-                "activation": [],
-                "adhoc": [],
-                "appmgmt": [],
-                "audioclient": [],
-                "audiosessiontypes": [],
-                "avrt": [],
-                "basetsd": [],
-                "bcrypt": [],
-                "bits": [],
-                "bits10_1": [],
-                "bits1_5": [],
-                "bits2_0": [],
-                "bits2_5": [],
-                "bits3_0": [],
-                "bits4_0": [],
-                "bits5_0": [],
-                "bitscfg": [],
-                "bitsmsg": [],
-                "bluetoothapis": [],
-                "bluetoothleapis": [],
-                "bthdef": [],
-                "bthioctl": [],
-                "bthledef": [],
-                "bthsdpdef": [],
-                "bugcodes": [],
-                "cderr": [],
-                "cfg": [],
-                "cfgmgr32": [],
-                "cguid": [],
-                "combaseapi": [],
-                "coml2api": [],
-                "commapi": [],
-                "commctrl": [],
-                "commdlg": [],
-                "commoncontrols": [],
-                "consoleapi": [],
-                "corecrt": [],
-                "corsym": [],
-                "d2d1": [],
-                "d2d1_1": [],
-                "d2d1_2": [],
-                "d2d1_3": [],
-                "d2d1effectauthor": [],
-                "d2d1effects": [],
-                "d2d1effects_1": [],
-                "d2d1effects_2": [],
-                "d2d1svg": [],
-                "d2dbasetypes": [],
-                "d3d": [],
-                "d3d10": [],
-                "d3d10_1": [],
-                "d3d10_1shader": [],
-                "d3d10effect": [],
-                "d3d10misc": [],
-                "d3d10sdklayers": [],
-                "d3d10shader": [],
-                "d3d11": [],
-                "d3d11_1": [],
-                "d3d11_2": [],
-                "d3d11_3": [],
-                "d3d11_4": [],
-                "d3d11on12": [],
-                "d3d11sdklayers": [],
-                "d3d11shader": [],
-                "d3d11tokenizedprogramformat": [],
-                "d3d12": [],
-                "d3d12sdklayers": [],
-                "d3d12shader": [],
-                "d3d9": [],
-                "d3d9caps": [],
-                "d3d9types": [],
-                "d3dcommon": [],
-                "d3dcompiler": [],
-                "d3dcsx": [],
-                "d3dkmdt": [],
-                "d3dkmthk": [],
-                "d3dukmdt": [],
-                "d3dx10core": [],
-                "d3dx10math": [],
-                "d3dx10mesh": [],
-                "datetimeapi": [],
-                "davclnt": [],
-                "dbghelp": [],
-                "dbt": [],
-                "dcommon": [],
-                "dcomp": [],
-                "dcompanimation": [],
-                "dcomptypes": [],
-                "dde": [],
-                "ddraw": [],
-                "ddrawi": [],
-                "ddrawint": [],
-                "debug": [
-                    "impl-debug"
-                ],
-                "debugapi": [],
-                "devguid": [],
-                "devicetopology": [],
-                "devpkey": [],
-                "devpropdef": [],
-                "dinput": [],
-                "dinputd": [],
-                "dispex": [],
-                "dmksctl": [],
-                "dmusicc": [],
-                "docobj": [],
-                "documenttarget": [],
-                "dot1x": [],
-                "dpa_dsa": [],
-                "dpapi": [],
-                "dsgetdc": [],
-                "dsound": [],
-                "dsrole": [],
-                "dvp": [],
-                "dwmapi": [],
-                "dwrite": [],
-                "dwrite_1": [],
-                "dwrite_2": [],
-                "dwrite_3": [],
-                "dxdiag": [],
-                "dxfile": [],
-                "dxgi": [],
-                "dxgi1_2": [],
-                "dxgi1_3": [],
-                "dxgi1_4": [],
-                "dxgi1_5": [],
-                "dxgi1_6": [],
-                "dxgidebug": [],
-                "dxgiformat": [],
-                "dxgitype": [],
-                "dxva2api": [],
-                "dxvahd": [],
-                "eaptypes": [],
-                "enclaveapi": [],
-                "endpointvolume": [],
-                "errhandlingapi": [],
-                "everything": [],
-                "evntcons": [],
-                "evntprov": [],
-                "evntrace": [],
-                "excpt": [],
-                "exdisp": [],
-                "fibersapi": [],
-                "fileapi": [],
-                "functiondiscoverykeys_devpkey": [],
-                "gl-gl": [],
-                "guiddef": [],
-                "handleapi": [],
-                "heapapi": [],
-                "hidclass": [],
-                "hidpi": [],
-                "hidsdi": [],
-                "hidusage": [],
-                "highlevelmonitorconfigurationapi": [],
-                "hstring": [],
-                "http": [],
-                "ifdef": [],
-                "ifmib": [],
-                "imm": [],
-                "impl-debug": [],
-                "impl-default": [],
-                "in6addr": [],
-                "inaddr": [],
-                "inspectable": [],
-                "interlockedapi": [],
-                "intsafe": [],
-                "ioapiset": [],
-                "ipexport": [],
-                "iphlpapi": [],
-                "ipifcons": [],
-                "ipmib": [],
-                "iprtrmib": [],
-                "iptypes": [],
-                "jobapi": [],
-                "jobapi2": [],
-                "knownfolders": [],
-                "ks": [],
-                "ksmedia": [],
-                "ktmtypes": [],
-                "ktmw32": [],
-                "l2cmn": [],
-                "libloaderapi": [],
-                "limits": [],
-                "lmaccess": [],
-                "lmalert": [],
-                "lmapibuf": [],
-                "lmat": [],
-                "lmcons": [],
-                "lmdfs": [],
-                "lmerrlog": [],
-                "lmjoin": [],
-                "lmmsg": [],
-                "lmremutl": [],
-                "lmrepl": [],
-                "lmserver": [],
-                "lmshare": [],
-                "lmstats": [],
-                "lmsvc": [],
-                "lmuse": [],
-                "lmwksta": [],
-                "lowlevelmonitorconfigurationapi": [],
-                "lsalookup": [],
-                "memoryapi": [],
-                "minschannel": [],
-                "minwinbase": [],
-                "minwindef": [],
-                "mmdeviceapi": [],
-                "mmeapi": [],
-                "mmreg": [],
-                "mmsystem": [],
-                "mprapidef": [],
-                "msaatext": [],
-                "mscat": [],
-                "mschapp": [],
-                "mssip": [],
-                "mstcpip": [],
-                "mswsock": [],
-                "mswsockdef": [],
-                "namedpipeapi": [],
-                "namespaceapi": [],
-                "nb30": [],
-                "ncrypt": [],
-                "netioapi": [],
-                "nldef": [],
-                "ntddndis": [],
-                "ntddscsi": [],
-                "ntddser": [],
-                "ntdef": [],
-                "ntlsa": [],
-                "ntsecapi": [],
-                "ntstatus": [],
-                "oaidl": [],
-                "objbase": [],
-                "objidl": [],
-                "objidlbase": [],
-                "ocidl": [],
-                "ole2": [],
-                "oleauto": [],
-                "olectl": [],
-                "oleidl": [],
-                "opmapi": [],
-                "pdh": [],
-                "perflib": [],
-                "physicalmonitorenumerationapi": [],
-                "playsoundapi": [],
-                "portabledevice": [],
-                "portabledeviceapi": [],
-                "portabledevicetypes": [],
-                "powerbase": [],
-                "powersetting": [],
-                "powrprof": [],
-                "processenv": [],
-                "processsnapshot": [],
-                "processthreadsapi": [],
-                "processtopologyapi": [],
-                "profileapi": [],
-                "propidl": [],
-                "propkey": [],
-                "propkeydef": [],
-                "propsys": [],
-                "prsht": [],
-                "psapi": [],
-                "qos": [],
-                "realtimeapiset": [],
-                "reason": [],
-                "restartmanager": [],
-                "restrictederrorinfo": [],
-                "rmxfguid": [],
-                "roapi": [],
-                "robuffer": [],
-                "roerrorapi": [],
-                "rpc": [],
-                "rpcdce": [],
-                "rpcndr": [],
-                "rtinfo": [],
-                "sapi": [],
-                "sapi51": [],
-                "sapi53": [],
-                "sapiddk": [],
-                "sapiddk51": [],
-                "schannel": [],
-                "sddl": [],
-                "securityappcontainer": [],
-                "securitybaseapi": [],
-                "servprov": [],
-                "setupapi": [],
-                "shellapi": [],
-                "shellscalingapi": [],
-                "shlobj": [],
-                "shobjidl": [],
-                "shobjidl_core": [],
-                "shtypes": [],
-                "softpub": [],
-                "spapidef": [],
-                "spellcheck": [],
-                "sporder": [],
-                "sql": [],
-                "sqlext": [],
-                "sqltypes": [],
-                "sqlucode": [],
-                "sspi": [],
-                "std": [],
-                "stralign": [],
-                "stringapiset": [],
-                "strmif": [],
-                "subauth": [],
-                "synchapi": [],
-                "sysinfoapi": [],
-                "systemtopologyapi": [],
-                "taskschd": [],
-                "tcpestats": [],
-                "tcpmib": [],
-                "textstor": [],
-                "threadpoolapiset": [],
-                "threadpoollegacyapiset": [],
-                "timeapi": [],
-                "timezoneapi": [],
-                "tlhelp32": [],
-                "transportsettingcommon": [],
-                "tvout": [],
-                "udpmib": [],
-                "unknwnbase": [],
-                "urlhist": [],
-                "urlmon": [],
-                "usb": [],
-                "usbioctl": [],
-                "usbiodef": [],
-                "usbscan": [],
-                "usbspec": [],
-                "userenv": [],
-                "usp10": [],
-                "utilapiset": [],
-                "uxtheme": [],
-                "vadefs": [],
-                "vcruntime": [],
-                "vsbackup": [],
-                "vss": [],
-                "vsserror": [],
-                "vswriter": [],
-                "wbemads": [],
-                "wbemcli": [],
-                "wbemdisp": [],
-                "wbemprov": [],
-                "wbemtran": [],
-                "wct": [],
-                "werapi": [],
-                "winbase": [],
-                "wincodec": [],
-                "wincodecsdk": [],
-                "wincon": [],
-                "wincontypes": [],
-                "wincred": [],
-                "wincrypt": [],
-                "windef": [],
-                "windot11": [],
-                "windowsceip": [],
-                "windowsx": [],
-                "winefs": [],
-                "winerror": [],
-                "winevt": [],
-                "wingdi": [],
-                "winhttp": [],
-                "wininet": [],
-                "winineti": [],
-                "winioctl": [],
-                "winnetwk": [],
-                "winnls": [],
-                "winnt": [],
-                "winreg": [],
-                "winsafer": [],
-                "winscard": [],
-                "winsmcrd": [],
-                "winsock2": [],
-                "winspool": [],
-                "winstring": [],
-                "winsvc": [],
-                "wintrust": [],
-                "winusb": [],
-                "winusbio": [],
-                "winuser": [],
-                "winver": [],
-                "wlanapi": [],
-                "wlanihv": [],
-                "wlanihvtypes": [],
-                "wlantypes": [],
-                "wlclient": [],
-                "wmistr": [],
-                "wnnc": [],
-                "wow64apiset": [],
-                "wpdmtpextensions": [],
-                "ws2bth": [],
-                "ws2def": [],
-                "ws2ipdef": [],
-                "ws2spi": [],
-                "ws2tcpip": [],
-                "wtsapi32": [],
-                "wtypes": [],
-                "wtypesbase": [],
-                "xinput": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-0.3.9/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "default-target": "x86_64-pc-windows-msvc",
-                        "features": [
-                            "everything",
-                            "impl-debug",
-                            "impl-default"
-                        ],
-                        "targets": [
-                            "aarch64-pc-windows-msvc",
-                            "i686-pc-windows-msvc",
-                            "x86_64-pc-windows-msvc"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Peter Atashian <retep998@gmail.com>"
-            ],
-            "categories": [
-                "external-ffi-bindings",
-                "no-std",
-                "os::windows-apis"
-            ],
-            "keywords": [
-                "windows",
-                "ffi",
-                "win32",
-                "com",
-                "directx"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/retep998/winapi-rs",
-            "homepage": null,
-            "documentation": "https://docs.rs/winapi/",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "winapi-i686-pc-windows-gnu",
-            "version": "0.4.0",
-            "id": "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "Import libraries for the i686-pc-windows-gnu target. Please don't use this crate directly, depend on winapi instead.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "winapi-i686-pc-windows-gnu",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-i686-pc-windows-gnu-0.4.0/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-i686-pc-windows-gnu-0.4.0/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-i686-pc-windows-gnu-0.4.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Peter Atashian <retep998@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "windows"
-            ],
-            "readme": null,
-            "repository": "https://github.com/retep998/winapi-rs",
-            "homepage": null,
-            "documentation": null,
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "winapi-x86_64-pc-windows-gnu",
-            "version": "0.4.0",
-            "id": "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "Import libraries for the x86_64-pc-windows-gnu target. Please don't use this crate directly, depend on winapi instead.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "winapi-x86_64-pc-windows-gnu",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-x86_64-pc-windows-gnu-0.4.0/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-x86_64-pc-windows-gnu-0.4.0/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-x86_64-pc-windows-gnu-0.4.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Peter Atashian <retep998@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "windows"
-            ],
-            "readme": null,
-            "repository": "https://github.com/retep998/winapi-rs",
-            "homepage": null,
-            "documentation": null,
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        }
-    ],
-    "workspace_members": [
-        "regex-benchmark 0.1.0 (path+file:///$ROOT$regex/bench)",
-        "regex 1.7.1 (path+file:///$ROOT$regex)",
-        "regex-syntax 0.6.28 (path+file:///$ROOT$regex/regex-syntax)",
-        "rure 0.2.2 (path+file:///$ROOT$regex/regex-capi)",
-        "regex-debug 0.1.0 (path+file:///$ROOT$regex/regex-debug)"
-    ],
-    "resolve": {
-        "nodes": [
-            {
-                "id": "aho-corasick 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "memchr",
-                        "pkg": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default",
-                    "std"
-                ]
-            },
-            {
-                "id": "cc 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "docopt 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "strsim 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "lazy_static",
-                        "pkg": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde",
-                        "pkg": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "strsim",
-                        "pkg": "strsim 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "getrandom 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "wasi 0.11.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "cfg_if",
-                        "pkg": "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(unix)"
-                            }
-                        ]
-                    },
-                    {
-                        "name": "wasi",
-                        "pkg": "wasi 0.11.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(target_os = \"wasi\")"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default",
-                    "std"
-                ]
-            },
-            {
-                "id": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default",
-                    "std"
-                ]
-            },
-            {
-                "id": "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(unix)"
-                            }
-                        ]
-                    },
-                    {
-                        "name": "winapi",
-                        "pkg": "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(windows)"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "pkg-config 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "unicode_ident",
-                        "pkg": "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default",
-                    "proc-macro"
-                ]
-            },
-            {
-                "id": "quickcheck 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "rand 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "rand",
-                        "pkg": "rand 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "proc_macro2",
-                        "pkg": "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default",
-                    "proc-macro"
-                ]
-            },
-            {
-                "id": "rand 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "rand_core 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "rand_core",
-                        "pkg": "rand_core 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "getrandom",
-                    "small_rng"
-                ]
-            },
-            {
-                "id": "rand_core 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "getrandom 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "getrandom",
-                        "pkg": "getrandom 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "getrandom"
-                ]
-            },
-            {
-                "id": "regex 1.7.1 (path+file:///$ROOT$regex)",
-                "dependencies": [
-                    "aho-corasick 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "quickcheck 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "rand 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex-syntax 0.6.28 (path+file:///$ROOT$regex/regex-syntax)"
-                ],
-                "deps": [
-                    {
-                        "name": "aho_corasick",
-                        "pkg": "aho-corasick 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "lazy_static",
-                        "pkg": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "memchr",
-                        "pkg": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "quickcheck",
-                        "pkg": "quickcheck 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "rand",
-                        "pkg": "rand 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex_syntax",
-                        "pkg": "regex-syntax 0.6.28 (path+file:///$ROOT$regex/regex-syntax)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "aho-corasick",
-                    "default",
-                    "memchr",
-                    "perf",
-                    "perf-cache",
-                    "perf-dfa",
-                    "perf-inline",
-                    "perf-literal",
-                    "std",
-                    "unicode",
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ]
-            },
-            {
-                "id": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "regex-syntax 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "regex_syntax",
-                        "pkg": "regex-syntax 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "std",
-                    "unicode",
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ]
-            },
-            {
-                "id": "regex-benchmark 0.1.0 (path+file:///$ROOT$regex/bench)",
-                "dependencies": [
-                    "cc 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "docopt 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "pkg-config 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.7.1 (path+file:///$ROOT$regex)",
-                    "regex-syntax 0.6.28 (path+file:///$ROOT$regex/regex-syntax)",
-                    "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "cc",
-                        "pkg": "cc 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "build",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "cfg_if",
-                        "pkg": "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "docopt",
-                        "pkg": "docopt 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "lazy_static",
-                        "pkg": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "memmap",
-                        "pkg": "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "pkg_config",
-                        "pkg": "pkg-config 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "build",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.7.1 (path+file:///$ROOT$regex)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex_syntax",
-                        "pkg": "regex-syntax 0.6.28 (path+file:///$ROOT$regex/regex-syntax)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde",
-                        "pkg": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "regex-debug 0.1.0 (path+file:///$ROOT$regex/regex-debug)",
-                "dependencies": [
-                    "docopt 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.7.1 (path+file:///$ROOT$regex)",
-                    "regex-syntax 0.6.28 (path+file:///$ROOT$regex/regex-syntax)",
-                    "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "docopt",
-                        "pkg": "docopt 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.7.1 (path+file:///$ROOT$regex)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex_syntax",
-                        "pkg": "regex-syntax 0.6.28 (path+file:///$ROOT$regex/regex-syntax)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde",
-                        "pkg": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "regex-syntax 0.6.28 (path+file:///$ROOT$regex/regex-syntax)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default",
-                    "unicode",
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ]
-            },
-            {
-                "id": "regex-syntax 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "unicode",
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ]
-            },
-            {
-                "id": "rure 0.2.2 (path+file:///$ROOT$regex/regex-capi)",
-                "dependencies": [
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.7.1 (path+file:///$ROOT$regex)"
-                ],
-                "deps": [
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.7.1 (path+file:///$ROOT$regex)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "serde_derive 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "serde_derive",
-                        "pkg": "serde_derive 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default",
-                    "derive",
-                    "serde_derive",
-                    "std"
-                ]
-            },
-            {
-                "id": "serde_derive 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "syn 2.0.15 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "proc_macro2",
-                        "pkg": "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "quote",
-                        "pkg": "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "syn",
-                        "pkg": "syn 2.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default"
-                ]
-            },
-            {
-                "id": "strsim 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "syn 2.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "proc_macro2",
-                        "pkg": "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "quote",
-                        "pkg": "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "unicode_ident",
-                        "pkg": "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "clone-impls",
-                    "default",
-                    "derive",
-                    "parsing",
-                    "printing",
-                    "proc-macro",
-                    "quote"
-                ]
-            },
-            {
-                "id": "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "wasi 0.11.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "winapi_i686_pc_windows_gnu",
-                        "pkg": "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "i686-pc-windows-gnu"
-                            }
-                        ]
-                    },
-                    {
-                        "name": "winapi_x86_64_pc_windows_gnu",
-                        "pkg": "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "x86_64-pc-windows-gnu"
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "basetsd",
-                    "handleapi",
-                    "memoryapi",
-                    "minwindef",
-                    "std",
-                    "sysinfoapi"
-                ]
-            },
-            {
-                "id": "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            }
-        ],
-        "root": "regex 1.7.1 (path+file:///$ROOT$regex)"
-    },
-    "target_directory": "$ROOT$regex/target",
-    "version": 1,
-    "workspace_root": "$ROOT$regex",
-    "metadata": null
-}
diff --git a/crates/project-model/test_data/ripgrep-metadata.json b/crates/project-model/test_data/ripgrep-metadata.json
deleted file mode 100644
index 131ff5d..0000000
--- a/crates/project-model/test_data/ripgrep-metadata.json
+++ /dev/null
@@ -1,12816 +0,0 @@
-{
-    "packages": [
-        {
-            "name": "aho-corasick",
-            "version": "0.7.20",
-            "id": "aho-corasick 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "Fast multiple substring searching.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "memchr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.4.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "aho_corasick",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/aho-corasick-0.7.20/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "default": [
-                    "std"
-                ],
-                "std": [
-                    "memchr/std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/aho-corasick-0.7.20/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "text-processing"
-            ],
-            "keywords": [
-                "string",
-                "search",
-                "text",
-                "aho",
-                "multi"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/aho-corasick",
-            "homepage": "https://github.com/BurntSushi/aho-corasick",
-            "documentation": null,
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "aho-corasick",
-            "version": "1.0.1",
-            "id": "aho-corasick 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "Fast multiple substring searching.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "log",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.17",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "memchr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.4.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "doc-comment",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "aho_corasick",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/aho-corasick-1.0.1/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "default": [
-                    "std",
-                    "perf-literal"
-                ],
-                "logging": [
-                    "dep:log"
-                ],
-                "perf-literal": [
-                    "dep:memchr"
-                ],
-                "std": [
-                    "memchr?/std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/aho-corasick-1.0.1/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "all-features": true,
-                        "rustdoc-args": [
-                            "--cfg",
-                            "docsrs"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "text-processing"
-            ],
-            "keywords": [
-                "string",
-                "search",
-                "text",
-                "pattern",
-                "multi"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/aho-corasick",
-            "homepage": "https://github.com/BurntSushi/aho-corasick",
-            "documentation": null,
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.60.0"
-        },
-        {
-            "name": "atty",
-            "version": "0.2.14",
-            "id": "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT",
-            "license_file": null,
-            "description": "A simple interface for querying atty",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "hermit-abi",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(target_os = \"hermit\")",
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": "cfg(unix)",
-                    "registry": null
-                },
-                {
-                    "name": "winapi",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "consoleapi",
-                        "processenv",
-                        "minwinbase",
-                        "minwindef",
-                        "winbase"
-                    ],
-                    "target": "cfg(windows)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "atty",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/atty-0.2.14/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "atty",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/atty-0.2.14/examples/atty.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/atty-0.2.14/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "softprops <d.tangren@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "terminal",
-                "tty",
-                "isatty"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/softprops/atty",
-            "homepage": "https://github.com/softprops/atty",
-            "documentation": "http://softprops.github.io/atty",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "base64",
-            "version": "0.20.0",
-            "id": "base64 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "encodes and decodes base64 as bytes or utf8",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "criterion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8.5",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "small_rng"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rstest",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.12.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rstest_reuse",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "structopt",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.26",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "base64",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64-0.20.0/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "base64",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64-0.20.0/examples/base64.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "encode",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64-0.20.0/tests/encode.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "tests",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64-0.20.0/tests/tests.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "benchmarks",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64-0.20.0/benches/benchmarks.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "alloc": [],
-                "default": [
-                    "std"
-                ],
-                "std": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/base64-0.20.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Alice Maz <alice@alicemaz.com>",
-                "Marshall Pierce <marshall@mpierce.org>"
-            ],
-            "categories": [
-                "encoding"
-            ],
-            "keywords": [
-                "base64",
-                "utf8",
-                "encode",
-                "decode",
-                "no_std"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/marshallpierce/rust-base64",
-            "homepage": null,
-            "documentation": "https://docs.rs/base64",
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.57.0"
-        },
-        {
-            "name": "bitflags",
-            "version": "1.3.2",
-            "id": "bitflags 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "A macro to generate structures which behave like bitflags.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "compiler_builtins",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": "core",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustversion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_derive",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_json",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "trybuild",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "walkdir",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "bitflags",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitflags-1.3.2/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "basic",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitflags-1.3.2/tests/basic.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "compile",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitflags-1.3.2/tests/compile.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "compiler_builtins": [
-                    "dep:compiler_builtins"
-                ],
-                "core": [
-                    "dep:core"
-                ],
-                "default": [],
-                "example_generated": [],
-                "rustc-dep-of-std": [
-                    "core",
-                    "compiler_builtins"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bitflags-1.3.2/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "features": [
-                            "example_generated"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [
-                "no-std"
-            ],
-            "keywords": [
-                "bit",
-                "bitmask",
-                "bitflags",
-                "flags"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/bitflags/bitflags",
-            "homepage": "https://github.com/bitflags/bitflags",
-            "documentation": "https://docs.rs/bitflags",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "bstr",
-            "version": "1.4.0",
-            "id": "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A string type that is not required to be valid UTF-8.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "memchr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.4.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "once_cell",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.14.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex-automata",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.85",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quickcheck",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "ucd-parse",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "unicode-segmentation",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.2.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "bstr",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bstr-1.4.0/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "graphemes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bstr-1.4.0/examples/graphemes.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std",
-                        "unicode"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "lines",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bstr-1.4.0/examples/lines.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "uppercase",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bstr-1.4.0/examples/uppercase.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std",
-                        "unicode"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "words",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bstr-1.4.0/examples/words.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std",
-                        "unicode"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "graphemes-std",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bstr-1.4.0/examples/graphemes-std.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "lines-std",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bstr-1.4.0/examples/lines-std.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "uppercase-std",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bstr-1.4.0/examples/uppercase-std.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "words-std",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bstr-1.4.0/examples/words-std.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "alloc": [
-                    "serde?/alloc"
-                ],
-                "default": [
-                    "std",
-                    "unicode"
-                ],
-                "serde": [
-                    "dep:serde"
-                ],
-                "std": [
-                    "alloc",
-                    "memchr/std",
-                    "serde?/std"
-                ],
-                "unicode": [
-                    "dep:once_cell",
-                    "dep:regex-automata"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bstr-1.4.0/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "all-features": true,
-                        "rustdoc-args": [
-                            "--cfg",
-                            "docsrs"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "text-processing",
-                "encoding"
-            ],
-            "keywords": [
-                "string",
-                "str",
-                "byte",
-                "bytes",
-                "text"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/bstr",
-            "homepage": "https://github.com/BurntSushi/bstr",
-            "documentation": "https://docs.rs/bstr",
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.60"
-        },
-        {
-            "name": "bytecount",
-            "version": "0.6.3",
-            "id": "bytecount 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Apache-2.0/MIT",
-            "license_file": null,
-            "description": "count occurrences of a given byte, or the number of UTF-8 code points, in a byte slice, fast",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "packed_simd_2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.8",
-                    "kind": null,
-                    "rename": "packed_simd",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "criterion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quickcheck",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "bytecount",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bytecount-0.6.3/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "check",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bytecount-0.6.3/tests/check.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bytecount-0.6.3/benches/bench.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "generic-simd": [
-                    "packed_simd"
-                ],
-                "html_report": [],
-                "packed_simd": [
-                    "dep:packed_simd"
-                ],
-                "runtime-dispatch-simd": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/bytecount-0.6.3/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andre Bogus <bogusandre@gmail.de>",
-                "Joshua Landau <joshua@landau.ws>"
-            ],
-            "categories": [
-                "algorithms",
-                "no-std"
-            ],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/llogiq/bytecount",
-            "homepage": null,
-            "documentation": null,
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "cc",
-            "version": "1.0.79",
-            "id": "cc 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A build-time dependency for Cargo build scripts to assist in invoking the native\nC compiler to compile native C code into a static archive to be linked into Rust\ncode.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "jobserver",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.16",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "tempfile",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "cc",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bin"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "gcc-shim",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/src/bin/gcc-shim.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cc_env",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/tests/cc_env.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cflags",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/tests/cflags.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cxxflags",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/tests/cxxflags.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/tests/test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "jobserver": [
-                    "dep:jobserver"
-                ],
-                "parallel": [
-                    "jobserver"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cc-1.0.79/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [
-                "development-tools::build-utils"
-            ],
-            "keywords": [
-                "build-dependencies"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/cc-rs",
-            "homepage": "https://github.com/rust-lang/cc-rs",
-            "documentation": "https://docs.rs/cc",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "cfg-if",
-            "version": "1.0.0",
-            "id": "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "A macro to ergonomically define an item depending on a large number of #[cfg]\nparameters. Structured like an if-else chain, the first matching branch is the\nitem that gets emitted.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "compiler_builtins",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": "core",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "cfg-if",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cfg-if-1.0.0/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "xcrate",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cfg-if-1.0.0/tests/xcrate.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "compiler_builtins": [
-                    "dep:compiler_builtins"
-                ],
-                "core": [
-                    "dep:core"
-                ],
-                "rustc-dep-of-std": [
-                    "core",
-                    "compiler_builtins"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/cfg-if-1.0.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/alexcrichton/cfg-if",
-            "homepage": "https://github.com/alexcrichton/cfg-if",
-            "documentation": "https://docs.rs/cfg-if",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "clap",
-            "version": "2.34.0",
-            "id": "clap 2.34.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT",
-            "license_file": null,
-            "description": "A simple to use, efficient, and full-featured Command Line Argument Parser\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "atty",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "bitflags",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "clippy",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "~0.0.166",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "strsim",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "term_size",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "textwrap",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.11.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "unicode-width",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "vec_map",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "yaml-rust",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "version-sync",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "ansi_term",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.12",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(not(windows))",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "clap",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/clap-2.34.0/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "ansi_term": [
-                    "dep:ansi_term"
-                ],
-                "atty": [
-                    "dep:atty"
-                ],
-                "clippy": [
-                    "dep:clippy"
-                ],
-                "color": [
-                    "ansi_term",
-                    "atty"
-                ],
-                "debug": [],
-                "default": [
-                    "suggestions",
-                    "color",
-                    "vec_map"
-                ],
-                "doc": [
-                    "yaml"
-                ],
-                "nightly": [],
-                "no_cargo": [],
-                "strsim": [
-                    "dep:strsim"
-                ],
-                "suggestions": [
-                    "strsim"
-                ],
-                "term_size": [
-                    "dep:term_size"
-                ],
-                "unstable": [],
-                "vec_map": [
-                    "dep:vec_map"
-                ],
-                "wrap_help": [
-                    "term_size",
-                    "textwrap/term_size"
-                ],
-                "yaml": [
-                    "yaml-rust"
-                ],
-                "yaml-rust": [
-                    "dep:yaml-rust"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/clap-2.34.0/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "features": [
-                            "doc"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Kevin K. <kbknapp@gmail.com>"
-            ],
-            "categories": [
-                "command-line-interface"
-            ],
-            "keywords": [
-                "argument",
-                "cli",
-                "arg",
-                "parser",
-                "parse"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/clap-rs/clap",
-            "homepage": "https://clap.rs/",
-            "documentation": "https://docs.rs/clap/",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "crossbeam-channel",
-            "version": "0.5.8",
-            "id": "crossbeam-channel 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Multi-producer multi-consumer channels for message passing",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "cfg-if",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "crossbeam-utils",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "num_cpus",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.13.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "signal-hook",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "crossbeam-channel",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "fibonacci",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/examples/fibonacci.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "matching",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/examples/matching.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "stopwatch",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/examples/stopwatch.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "after",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/after.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "array",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/array.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "golang",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/golang.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "iter",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/iter.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "list",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/list.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "mpsc",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/mpsc.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "never",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/never.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "ready",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/ready.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "same_channel",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/same_channel.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "select",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/select.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "select_macro",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/select_macro.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "thread_locals",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/thread_locals.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "tick",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/tick.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "zero",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/tests/zero.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "crossbeam",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/benches/crossbeam.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "crossbeam-utils": [
-                    "dep:crossbeam-utils"
-                ],
-                "default": [
-                    "std"
-                ],
-                "std": [
-                    "crossbeam-utils/std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-channel-0.5.8/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [],
-            "categories": [
-                "algorithms",
-                "concurrency",
-                "data-structures"
-            ],
-            "keywords": [
-                "channel",
-                "mpmc",
-                "select",
-                "golang",
-                "message"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/crossbeam-rs/crossbeam",
-            "homepage": "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-channel",
-            "documentation": null,
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.38"
-        },
-        {
-            "name": "crossbeam-utils",
-            "version": "0.8.15",
-            "id": "crossbeam-utils 0.8.15 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Utilities for concurrent programming",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "cfg-if",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustversion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "loom",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(crossbeam_loom)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "crossbeam-utils",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.8.15/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "atomic_cell",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.8.15/tests/atomic_cell.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cache_padded",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.8.15/tests/cache_padded.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "parker",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.8.15/tests/parker.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "sharded_lock",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.8.15/tests/sharded_lock.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "thread",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.8.15/tests/thread.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "wait_group",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.8.15/tests/wait_group.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "atomic_cell",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.8.15/benches/atomic_cell.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.8.15/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "std"
-                ],
-                "loom": [
-                    "dep:loom"
-                ],
-                "nightly": [],
-                "std": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/crossbeam-utils-0.8.15/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [],
-            "categories": [
-                "algorithms",
-                "concurrency",
-                "data-structures",
-                "no-std"
-            ],
-            "keywords": [
-                "scoped",
-                "thread",
-                "atomic",
-                "cache"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/crossbeam-rs/crossbeam",
-            "homepage": "https://github.com/crossbeam-rs/crossbeam/tree/master/crossbeam-utils",
-            "documentation": null,
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.38"
-        },
-        {
-            "name": "encoding_rs",
-            "version": "0.8.32",
-            "id": "encoding_rs 0.8.32 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "(Apache-2.0 OR MIT) AND BSD-3-Clause",
-            "license_file": null,
-            "description": "A Gecko-oriented implementation of the Encoding Standard",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "cfg-if",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "packed_simd_2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.4",
-                    "kind": null,
-                    "rename": "packed_simd",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "bincode",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_derive",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_json",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "encoding_rs",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/encoding_rs-0.8.32/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "alloc": [],
-                "default": [
-                    "alloc"
-                ],
-                "fast-big5-hanzi-encode": [],
-                "fast-gb-hanzi-encode": [],
-                "fast-hangul-encode": [],
-                "fast-hanja-encode": [],
-                "fast-kanji-encode": [],
-                "fast-legacy-encode": [
-                    "fast-hangul-encode",
-                    "fast-hanja-encode",
-                    "fast-kanji-encode",
-                    "fast-gb-hanzi-encode",
-                    "fast-big5-hanzi-encode"
-                ],
-                "less-slow-big5-hanzi-encode": [],
-                "less-slow-gb-hanzi-encode": [],
-                "less-slow-kanji-encode": [],
-                "packed_simd": [
-                    "dep:packed_simd"
-                ],
-                "serde": [
-                    "dep:serde"
-                ],
-                "simd-accel": [
-                    "packed_simd",
-                    "packed_simd/into_bits"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/encoding_rs-0.8.32/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Henri Sivonen <hsivonen@hsivonen.fi>"
-            ],
-            "categories": [
-                "text-processing",
-                "encoding",
-                "web-programming",
-                "internationalization"
-            ],
-            "keywords": [
-                "encoding",
-                "web",
-                "unicode",
-                "charset"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/hsivonen/encoding_rs",
-            "homepage": "https://docs.rs/encoding_rs/",
-            "documentation": "https://docs.rs/encoding_rs/",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "encoding_rs_io",
-            "version": "0.1.7",
-            "id": "encoding_rs_io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Streaming transcoding for encoding_rs",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "encoding_rs",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "encoding_rs_io",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/encoding_rs_io-0.1.7/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/encoding_rs_io-0.1.7/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "text-processing",
-                "encoding",
-                "web-programming",
-                "email"
-            ],
-            "keywords": [
-                "encoding",
-                "transcoding",
-                "stream",
-                "io",
-                "read"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/encoding_rs_io",
-            "homepage": null,
-            "documentation": "https://docs.rs/encoding_rs_io",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "fnv",
-            "version": "1.0.7",
-            "id": "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Apache-2.0 / MIT",
-            "license_file": null,
-            "description": "Fowler–Noll–Vo hash function",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "fnv",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/fnv-1.0.7/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "default": [
-                    "std"
-                ],
-                "std": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/fnv-1.0.7/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/servo/rust-fnv",
-            "homepage": null,
-            "documentation": "https://doc.servo.org/fnv/",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "glob",
-            "version": "0.3.1",
-            "id": "glob 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Support for matching file paths against Unix shell style patterns.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "doc-comment",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "tempdir",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "glob",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/glob-0.3.1/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "glob-std",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/glob-0.3.1/tests/glob-std.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/glob-0.3.1/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [
-                "filesystem"
-            ],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/glob",
-            "homepage": "https://github.com/rust-lang/glob",
-            "documentation": "https://docs.rs/glob/0.3.1",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "globset",
-            "version": "0.4.10",
-            "id": "globset 0.4.10 (path+file:///$ROOT$ripgrep/crates/globset)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "Cross platform single glob and glob set matching. Glob set matching is the\nprocess of matching one or more glob patterns against a single candidate path\nsimultaneously, and returning all of the globs that matched.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "aho-corasick",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.7.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "bstr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "std"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "fnv",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "log",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "perf",
-                        "std"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.104",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "glob",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_json",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.45",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "globset",
-                    "src_path": "$ROOT$ripgrep/crates/globset/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench",
-                    "src_path": "$ROOT$ripgrep/crates/globset/benches/bench.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "log"
-                ],
-                "log": [
-                    "dep:log"
-                ],
-                "serde": [
-                    "dep:serde"
-                ],
-                "serde1": [
-                    "serde"
-                ],
-                "simd-accel": []
-            },
-            "manifest_path": "$ROOT$ripgrep/crates/globset/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "regex",
-                "glob",
-                "multiple",
-                "set",
-                "pattern"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/ripgrep/tree/master/crates/globset",
-            "homepage": "https://github.com/BurntSushi/ripgrep/tree/master/crates/globset",
-            "documentation": "https://docs.rs/globset",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "grep",
-            "version": "0.2.11",
-            "id": "grep 0.2.11 (path+file:///$ROOT$ripgrep/crates/grep)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "Fast line oriented regex searching as a library.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "grep-cli",
-                    "source": null,
-                    "req": "^0.1.7",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/cli"
-                },
-                {
-                    "name": "grep-matcher",
-                    "source": null,
-                    "req": "^0.1.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/matcher"
-                },
-                {
-                    "name": "grep-pcre2",
-                    "source": null,
-                    "req": "^0.1.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/pcre2"
-                },
-                {
-                    "name": "grep-printer",
-                    "source": null,
-                    "req": "^0.1.7",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/printer"
-                },
-                {
-                    "name": "grep-regex",
-                    "source": null,
-                    "req": "^0.1.11",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/regex"
-                },
-                {
-                    "name": "grep-searcher",
-                    "source": null,
-                    "req": "^0.1.11",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/searcher"
-                },
-                {
-                    "name": "termcolor",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.4",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "walkdir",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.2.7",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "grep",
-                    "src_path": "$ROOT$ripgrep/crates/grep/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "simplegrep",
-                    "src_path": "$ROOT$ripgrep/crates/grep/examples/simplegrep.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "avx-accel": [],
-                "grep-pcre2": [
-                    "dep:grep-pcre2"
-                ],
-                "pcre2": [
-                    "grep-pcre2"
-                ],
-                "simd-accel": [
-                    "grep-searcher/simd-accel"
-                ]
-            },
-            "manifest_path": "$ROOT$ripgrep/crates/grep/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "regex",
-                "grep",
-                "egrep",
-                "search",
-                "pattern"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/ripgrep/tree/master/crates/grep",
-            "homepage": "https://github.com/BurntSushi/ripgrep/tree/master/crates/grep",
-            "documentation": "https://docs.rs/grep",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "grep-cli",
-            "version": "0.1.7",
-            "id": "grep-cli 0.1.7 (path+file:///$ROOT$ripgrep/crates/cli)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "Utilities for search oriented command line applications.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "atty",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.11",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "bstr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "globset",
-                    "source": null,
-                    "req": "^0.4.10",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/globset"
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "log",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "same-file",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "termcolor",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "winapi-util",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(windows)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "grep-cli",
-                    "src_path": "$ROOT$ripgrep/crates/cli/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$ripgrep/crates/cli/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "regex",
-                "grep",
-                "cli",
-                "utility",
-                "util"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/ripgrep/tree/master/crates/cli",
-            "homepage": "https://github.com/BurntSushi/ripgrep/tree/master/crates/cli",
-            "documentation": "https://docs.rs/grep-cli",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "grep-matcher",
-            "version": "0.1.6",
-            "id": "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "A trait for regular expressions, with a focus on line oriented search.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "memchr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "grep-matcher",
-                    "src_path": "$ROOT$ripgrep/crates/matcher/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "integration",
-                    "src_path": "$ROOT$ripgrep/crates/matcher/tests/tests.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$ripgrep/crates/matcher/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "regex",
-                "pattern",
-                "trait"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/ripgrep/tree/master/crates/matcher",
-            "homepage": "https://github.com/BurntSushi/ripgrep/tree/master/crates/matcher",
-            "documentation": "https://docs.rs/grep-matcher",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "grep-pcre2",
-            "version": "0.1.6",
-            "id": "grep-pcre2 0.1.6 (path+file:///$ROOT$ripgrep/crates/pcre2)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "Use PCRE2 with the 'grep' crate.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "grep-matcher",
-                    "source": null,
-                    "req": "^0.1.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/matcher"
-                },
-                {
-                    "name": "pcre2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "grep-pcre2",
-                    "src_path": "$ROOT$ripgrep/crates/pcre2/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$ripgrep/crates/pcre2/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "regex",
-                "grep",
-                "pcre",
-                "backreference",
-                "look"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/ripgrep/tree/master/crates/pcre2",
-            "homepage": "https://github.com/BurntSushi/ripgrep/tree/master/crates/pcre2",
-            "documentation": "https://docs.rs/grep-pcre2",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "grep-printer",
-            "version": "0.1.7",
-            "id": "grep-printer 0.1.7 (path+file:///$ROOT$ripgrep/crates/printer)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "An implementation of the grep crate's Sink trait that provides standard\nprinting of search results, similar to grep itself.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "base64",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.20.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "bstr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "grep-matcher",
-                    "source": null,
-                    "req": "^0.1.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/matcher"
-                },
-                {
-                    "name": "grep-searcher",
-                    "source": null,
-                    "req": "^0.1.11",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/searcher"
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.77",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [
-                        "derive"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_json",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.27",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "termcolor",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "grep-regex",
-                    "source": null,
-                    "req": "^0.1.11",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/regex"
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "grep-printer",
-                    "src_path": "$ROOT$ripgrep/crates/printer/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "base64": [
-                    "dep:base64"
-                ],
-                "default": [
-                    "serde1"
-                ],
-                "serde": [
-                    "dep:serde"
-                ],
-                "serde1": [
-                    "base64",
-                    "serde",
-                    "serde_json"
-                ],
-                "serde_json": [
-                    "dep:serde_json"
-                ]
-            },
-            "manifest_path": "$ROOT$ripgrep/crates/printer/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "grep",
-                "pattern",
-                "print",
-                "printer",
-                "sink"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/ripgrep/tree/master/crates/printer",
-            "homepage": "https://github.com/BurntSushi/ripgrep/tree/master/crates/printer",
-            "documentation": "https://docs.rs/grep-printer",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "grep-regex",
-            "version": "0.1.11",
-            "id": "grep-regex 0.1.11 (path+file:///$ROOT$ripgrep/crates/regex)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "Use Rust's regex library with the 'grep' crate.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "aho-corasick",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.7.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "bstr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "grep-matcher",
-                    "source": null,
-                    "req": "^0.1.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/matcher"
-                },
-                {
-                    "name": "log",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex-syntax",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.6.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "thread_local",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "grep-regex",
-                    "src_path": "$ROOT$ripgrep/crates/regex/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$ripgrep/crates/regex/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "regex",
-                "grep",
-                "search",
-                "pattern",
-                "line"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/ripgrep/tree/master/crates/regex",
-            "homepage": "https://github.com/BurntSushi/ripgrep/tree/master/crates/regex",
-            "documentation": "https://docs.rs/grep-regex",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "grep-searcher",
-            "version": "0.1.11",
-            "id": "grep-searcher 0.1.11 (path+file:///$ROOT$ripgrep/crates/searcher)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "Fast line oriented regex searching as a library.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "bstr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "std"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "bytecount",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "encoding_rs",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8.14",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "encoding_rs_io",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "grep-matcher",
-                    "source": null,
-                    "req": "^0.1.6",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/matcher"
-                },
-                {
-                    "name": "log",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "memmap2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.5.3",
-                    "kind": null,
-                    "rename": "memmap",
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "grep-regex",
-                    "source": null,
-                    "req": "^0.1.11",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/regex"
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "grep-searcher",
-                    "src_path": "$ROOT$ripgrep/crates/searcher/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "search-stdin",
-                    "src_path": "$ROOT$ripgrep/crates/searcher/examples/search-stdin.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "avx-accel": [],
-                "default": [
-                    "bytecount/runtime-dispatch-simd"
-                ],
-                "simd-accel": [
-                    "encoding_rs/simd-accel"
-                ]
-            },
-            "manifest_path": "$ROOT$ripgrep/crates/searcher/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "regex",
-                "grep",
-                "egrep",
-                "search",
-                "pattern"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/ripgrep/tree/master/crates/searcher",
-            "homepage": "https://github.com/BurntSushi/ripgrep/tree/master/crates/searcher",
-            "documentation": "https://docs.rs/grep-searcher",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "hermit-abi",
-            "version": "0.1.19",
-            "id": "hermit-abi 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "hermit-abi is small interface to call functions from the unikernel RustyHermit.\nIt is used to build the target `x86_64-unknown-hermit`.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "compiler_builtins",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": "core",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.51",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "hermit-abi",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/hermit-abi-0.1.19/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "compiler_builtins": [
-                    "dep:compiler_builtins"
-                ],
-                "core": [
-                    "dep:core"
-                ],
-                "default": [],
-                "docs": [],
-                "rustc-dep-of-std": [
-                    "core",
-                    "compiler_builtins/rustc-dep-of-std",
-                    "libc/rustc-dep-of-std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/hermit-abi-0.1.19/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "default-target": "x86_64-unknown-hermit",
-                        "features": [
-                            "docs"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Stefan Lankes"
-            ],
-            "categories": [
-                "os"
-            ],
-            "keywords": [
-                "unikernel",
-                "libos"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/hermitcore/libhermit-rs",
-            "homepage": null,
-            "documentation": "https://hermitcore.github.io/rusty-hermit/hermit_abi",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "ignore",
-            "version": "0.4.20",
-            "id": "ignore 0.4.20 (path+file:///$ROOT$ripgrep/crates/ignore)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "A fast library for efficiently matching ignore files such as `.gitignore`\nagainst file paths.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "globset",
-                    "source": null,
-                    "req": "^0.4.10",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/globset"
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "log",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "memchr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "same-file",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "thread_local",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "walkdir",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.2.7",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "crossbeam-channel",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.5.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "winapi-util",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(windows)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "ignore",
-                    "src_path": "$ROOT$ripgrep/crates/ignore/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "walk",
-                    "src_path": "$ROOT$ripgrep/crates/ignore/examples/walk.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "gitignore_matched_path_or_any_parents_tests",
-                    "src_path": "$ROOT$ripgrep/crates/ignore/tests/gitignore_matched_path_or_any_parents_tests.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "simd-accel": [
-                    "globset/simd-accel"
-                ]
-            },
-            "manifest_path": "$ROOT$ripgrep/crates/ignore/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "glob",
-                "ignore",
-                "gitignore",
-                "pattern",
-                "file"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/ripgrep/tree/master/crates/ignore",
-            "homepage": "https://github.com/BurntSushi/ripgrep/tree/master/crates/ignore",
-            "documentation": "https://docs.rs/ignore",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "itoa",
-            "version": "1.0.6",
-            "id": "itoa 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Fast integer primitive to string conversion",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "no-panic",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "itoa",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.6/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.6/tests/test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.6/benches/bench.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "no-panic": [
-                    "dep:no-panic"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/itoa-1.0.6/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "value-formatting",
-                "no-std"
-            ],
-            "keywords": [
-                "integer"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dtolnay/itoa",
-            "homepage": null,
-            "documentation": "https://docs.rs/itoa",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.36"
-        },
-        {
-            "name": "jemalloc-sys",
-            "version": "0.5.3+5.3.0-patched",
-            "id": "jemalloc-sys 0.5.3+5.3.0-patched (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "Rust FFI bindings to jemalloc\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.8",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "cc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.13",
-                    "kind": "build",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "jemalloc-sys",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemalloc-sys-0.5.3+5.3.0-patched/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "malloc_conf_empty",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemalloc-sys-0.5.3+5.3.0-patched/tests/malloc_conf_empty.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "malloc_conf_set",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemalloc-sys-0.5.3+5.3.0-patched/tests/malloc_conf_set.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "unprefixed_malloc",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemalloc-sys-0.5.3+5.3.0-patched/tests/unprefixed_malloc.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemalloc-sys-0.5.3+5.3.0-patched/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "background_threads": [
-                    "background_threads_runtime_support"
-                ],
-                "background_threads_runtime_support": [],
-                "debug": [],
-                "default": [
-                    "background_threads_runtime_support"
-                ],
-                "disable_initial_exec_tls": [],
-                "profiling": [],
-                "stats": [],
-                "unprefixed_malloc_on_supported_platforms": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemalloc-sys-0.5.3+5.3.0-patched/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "rustdoc-args": [
-                            "--cfg",
-                            "jemallocator_docs"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>",
-                "Gonzalo Brito Gadeschi <gonzalobg88@gmail.com>",
-                "The TiKV Project Developers"
-            ],
-            "categories": [],
-            "keywords": [
-                "allocator",
-                "jemalloc"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/tikv/jemallocator",
-            "homepage": "https://github.com/tikv/jemallocator",
-            "documentation": "https://docs.rs/jemallocator-sys",
-            "edition": "2018",
-            "links": "jemalloc",
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "jemallocator",
-            "version": "0.5.0",
-            "id": "jemallocator 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "A Rust allocator backed by jemalloc\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "jemalloc-sys",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.5.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.8",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "paste",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "jemallocator",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "background_thread_defaults",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/tests/background_thread_defaults.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "background_thread_enabled",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/tests/background_thread_enabled.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "ffi",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/tests/ffi.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "grow_in_place",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/tests/grow_in_place.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "malloctl",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/tests/malloctl.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shrink_in_place",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/tests/shrink_in_place.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "smoke",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/tests/smoke.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "smoke_ffi",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/tests/smoke_ffi.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "usable_size",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/tests/usable_size.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "roundtrip",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/benches/roundtrip.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "alloc_trait": [],
-                "background_threads": [
-                    "jemalloc-sys/background_threads"
-                ],
-                "background_threads_runtime_support": [
-                    "jemalloc-sys/background_threads_runtime_support"
-                ],
-                "debug": [
-                    "jemalloc-sys/debug"
-                ],
-                "default": [
-                    "background_threads_runtime_support"
-                ],
-                "disable_initial_exec_tls": [
-                    "jemalloc-sys/disable_initial_exec_tls"
-                ],
-                "profiling": [
-                    "jemalloc-sys/profiling"
-                ],
-                "stats": [
-                    "jemalloc-sys/stats"
-                ],
-                "unprefixed_malloc_on_supported_platforms": [
-                    "jemalloc-sys/unprefixed_malloc_on_supported_platforms"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jemallocator-0.5.0/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "features": [],
-                        "rustdoc-args": [
-                            "--cfg",
-                            "jemallocator_docs"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>",
-                "Gonzalo Brito Gadeschi <gonzalobg88@gmail.com>",
-                "Simon Sapin <simon.sapin@exyr.org>",
-                "Steven Fackler <sfackler@gmail.com>",
-                "The TiKV Project Developers"
-            ],
-            "categories": [
-                "memory-management",
-                "api-bindings"
-            ],
-            "keywords": [
-                "allocator",
-                "jemalloc"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/tikv/jemallocator",
-            "homepage": "https://github.com/tikv/jemallocator",
-            "documentation": "https://docs.rs/jemallocator",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "jobserver",
-            "version": "0.1.26",
-            "id": "jobserver 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "An implementation of the GNU make jobserver for Rust\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "futures",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "num_cpus",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "tempfile",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "tokio-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "tokio-process",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.50",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(unix)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "jobserver",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jobserver-0.1.26/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "client",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jobserver-0.1.26/tests/client.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "server",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jobserver-0.1.26/tests/server.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "client-of-myself",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jobserver-0.1.26/tests/client-of-myself.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "make-as-a-client",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jobserver-0.1.26/tests/make-as-a-client.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "helper",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jobserver-0.1.26/tests/helper.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/jobserver-0.1.26/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/alexcrichton/jobserver-rs",
-            "homepage": "https://github.com/alexcrichton/jobserver-rs",
-            "documentation": "https://docs.rs/jobserver",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "lazy_static",
-            "version": "1.4.0",
-            "id": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "A macro for declaring lazily evaluated statics in Rust.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "spin",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.5.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "doc-comment",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "lazy_static",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/lazy_static-1.4.0/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "no_std",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/lazy_static-1.4.0/tests/no_std.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/lazy_static-1.4.0/tests/test.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "spin": [
-                    "dep:spin"
-                ],
-                "spin_no_std": [
-                    "spin"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/lazy_static-1.4.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Marvin Löbel <loebel.marvin@gmail.com>"
-            ],
-            "categories": [
-                "no-std",
-                "rust-patterns",
-                "memory-management"
-            ],
-            "keywords": [
-                "macro",
-                "lazy",
-                "static"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang-nursery/lazy-static.rs",
-            "homepage": null,
-            "documentation": "https://docs.rs/lazy_static",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "libc",
-            "version": "0.2.142",
-            "id": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Raw FFI bindings to platform libraries like libc.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "libc",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.142/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "const_fn",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.142/tests/const_fn.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.142/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "align": [],
-                "const-extern-fn": [],
-                "default": [
-                    "std"
-                ],
-                "extra_traits": [],
-                "rustc-dep-of-std": [
-                    "align",
-                    "rustc-std-workspace-core"
-                ],
-                "rustc-std-workspace-core": [
-                    "dep:rustc-std-workspace-core"
-                ],
-                "std": [],
-                "use_std": [
-                    "std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/libc-0.2.142/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "features": [
-                            "const-extern-fn",
-                            "extra_traits"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [
-                "external-ffi-bindings",
-                "no-std",
-                "os"
-            ],
-            "keywords": [
-                "libc",
-                "ffi",
-                "bindings",
-                "operating",
-                "system"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/libc",
-            "homepage": "https://github.com/rust-lang/libc",
-            "documentation": "https://docs.rs/libc/",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "log",
-            "version": "0.4.17",
-            "id": "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A lightweight logging facade for Rust\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "cfg-if",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "sval",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "=1.0.0-alpha.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "value-bag",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "=1.0.0-alpha.9",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustversion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "derive"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_test",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "sval",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "=1.0.0-alpha.5",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "derive"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "value-bag",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "=1.0.0-alpha.9",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "test"
-                    ],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "log",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.17/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "filters",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.17/tests/filters.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "macros",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.17/tests/macros.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "value",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.17/benches/value.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.17/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "kv_unstable": [
-                    "value-bag"
-                ],
-                "kv_unstable_serde": [
-                    "kv_unstable_std",
-                    "value-bag/serde",
-                    "serde"
-                ],
-                "kv_unstable_std": [
-                    "std",
-                    "kv_unstable",
-                    "value-bag/error"
-                ],
-                "kv_unstable_sval": [
-                    "kv_unstable",
-                    "value-bag/sval",
-                    "sval"
-                ],
-                "max_level_debug": [],
-                "max_level_error": [],
-                "max_level_info": [],
-                "max_level_off": [],
-                "max_level_trace": [],
-                "max_level_warn": [],
-                "release_max_level_debug": [],
-                "release_max_level_error": [],
-                "release_max_level_info": [],
-                "release_max_level_off": [],
-                "release_max_level_trace": [],
-                "release_max_level_warn": [],
-                "serde": [
-                    "dep:serde"
-                ],
-                "std": [],
-                "sval": [
-                    "dep:sval"
-                ],
-                "value-bag": [
-                    "dep:value-bag"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/log-0.4.17/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "features": [
-                            "std",
-                            "serde",
-                            "kv_unstable_std",
-                            "kv_unstable_sval",
-                            "kv_unstable_serde"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [
-                "development-tools::debugging"
-            ],
-            "keywords": [
-                "logging"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/log",
-            "homepage": null,
-            "documentation": "https://docs.rs/log",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "memchr",
-            "version": "2.5.0",
-            "id": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense/MIT",
-            "license_file": null,
-            "description": "Safe interface to memchr.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "compiler_builtins",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": "core",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.18",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quickcheck",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "memchr",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memchr-2.5.0/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memchr-2.5.0/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "compiler_builtins": [
-                    "dep:compiler_builtins"
-                ],
-                "core": [
-                    "dep:core"
-                ],
-                "default": [
-                    "std"
-                ],
-                "libc": [
-                    "dep:libc"
-                ],
-                "rustc-dep-of-std": [
-                    "core",
-                    "compiler_builtins"
-                ],
-                "std": [],
-                "use_std": [
-                    "std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memchr-2.5.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>",
-                "bluss"
-            ],
-            "categories": [],
-            "keywords": [
-                "memchr",
-                "char",
-                "scan",
-                "strchr",
-                "string"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/memchr",
-            "homepage": "https://github.com/BurntSushi/memchr",
-            "documentation": "https://docs.rs/memchr/",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "memmap2",
-            "version": "0.5.10",
-            "id": "memmap2 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Cross-platform Rust API for memory-mapped file IO",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "stable_deref_trait",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "owning_ref",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "tempfile",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(unix)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "memmap2",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memmap2-0.5.10/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "cat",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memmap2-0.5.10/examples/cat.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "stable_deref_trait": [
-                    "dep:stable_deref_trait"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/memmap2-0.5.10/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Dan Burkert <dan@danburkert.com>",
-                "Yevhenii Reizner <razrfalcon@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "mmap",
-                "memory-map",
-                "io",
-                "file"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/RazrFalcon/memmap2-rs",
-            "homepage": null,
-            "documentation": "https://docs.rs/memmap2",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "once_cell",
-            "version": "1.17.1",
-            "id": "once_cell 1.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Single assignment cells and lazy values.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "atomic-polyfill",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": "atomic_polyfill",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "critical-section",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": "critical_section",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "parking_lot_core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.9.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "critical-section",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.1",
-                    "kind": "dev",
-                    "rename": "critical_section",
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "std"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "crossbeam-utils",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8.7",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.2.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "once_cell",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.17.1/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.17.1/examples/bench.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench_acquire",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.17.1/examples/bench_acquire.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench_vs_lazy_static",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.17.1/examples/bench_vs_lazy_static.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "lazy_static",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.17.1/examples/lazy_static.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "reentrant_init_deadlocks",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.17.1/examples/reentrant_init_deadlocks.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "regex",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.17.1/examples/regex.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_synchronization",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.17.1/examples/test_synchronization.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "std"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "it",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.17.1/tests/it.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "alloc": [
-                    "race"
-                ],
-                "atomic-polyfill": [
-                    "critical-section"
-                ],
-                "atomic_polyfill": [
-                    "dep:atomic_polyfill"
-                ],
-                "critical-section": [
-                    "critical_section",
-                    "atomic_polyfill"
-                ],
-                "critical_section": [
-                    "dep:critical_section"
-                ],
-                "default": [
-                    "std"
-                ],
-                "parking_lot": [
-                    "parking_lot_core"
-                ],
-                "parking_lot_core": [
-                    "dep:parking_lot_core"
-                ],
-                "race": [],
-                "std": [
-                    "alloc"
-                ],
-                "unstable": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.17.1/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "all-features": true
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Aleksey Kladov <aleksey.kladov@gmail.com>"
-            ],
-            "categories": [
-                "rust-patterns",
-                "memory-management"
-            ],
-            "keywords": [
-                "lazy",
-                "static"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/matklad/once_cell",
-            "homepage": null,
-            "documentation": "https://docs.rs/once_cell",
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.56"
-        },
-        {
-            "name": "pcre2",
-            "version": "0.2.3",
-            "id": "pcre2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense/MIT",
-            "license_file": null,
-            "description": "High level wrapper library for PCRE2.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.46",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "log",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "pcre2-sys",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "thread_local",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "pcre2",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pcre2-0.2.3/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pcre2-0.2.3/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "text-processing"
-            ],
-            "keywords": [
-                "pcre",
-                "pcre2",
-                "regex",
-                "jit",
-                "perl"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/rust-pcre2",
-            "homepage": "https://github.com/BurntSushi/rust-pcre2",
-            "documentation": "https://docs.rs/pcre2",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "pcre2-sys",
-            "version": "0.2.5",
-            "id": "pcre2-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense/MIT",
-            "license_file": null,
-            "description": "Low level bindings to PCRE2.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "libc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "cc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "build",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "parallel"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "pkg-config",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.13",
-                    "kind": "build",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "pcre2-sys",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pcre2-sys-0.2.5/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pcre2-sys-0.2.5/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pcre2-sys-0.2.5/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "external-ffi-bindings"
-            ],
-            "keywords": [
-                "pcre",
-                "pcre2",
-                "regex",
-                "jit"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/rust-pcre2",
-            "homepage": "https://github.com/BurntSushi/rust-pcre2",
-            "documentation": "https://docs.rs/pcre2-sys",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "pkg-config",
-            "version": "0.3.26",
-            "id": "pkg-config 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A library to run the pkg-config system tool at build time in order to be used in\nCargo build scripts.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "pkg-config",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pkg-config-0.3.26/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pkg-config-0.3.26/tests/test.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/pkg-config-0.3.26/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "build-dependencies"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/pkg-config-rs",
-            "homepage": null,
-            "documentation": "https://docs.rs/pkg-config",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "proc-macro2",
-            "version": "1.0.56",
-            "id": "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A substitute implementation of the compiler's `proc_macro` API to decouple token-based libraries from the procedural macro use case.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "unicode-ident",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quote",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustversion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "proc-macro2",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "comments",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/comments.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "features",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/features.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "marker",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/marker.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_fmt",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/test_fmt.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_size",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/tests/test_size.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "proc-macro"
-                ],
-                "nightly": [],
-                "proc-macro": [],
-                "span-locations": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/proc-macro2-1.0.56/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "rustc-args": [
-                            "--cfg",
-                            "procmacro2_semver_exempt"
-                        ],
-                        "rustdoc-args": [
-                            "--cfg",
-                            "procmacro2_semver_exempt",
-                            "--cfg",
-                            "doc_cfg"
-                        ],
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                },
-                "playground": {
-                    "features": [
-                        "span-locations"
-                    ]
-                }
-            },
-            "publish": null,
-            "authors": [
-                "David Tolnay <dtolnay@gmail.com>",
-                "Alex Crichton <alex@alexcrichton.com>"
-            ],
-            "categories": [
-                "development-tools::procedural-macro-helpers"
-            ],
-            "keywords": [
-                "macros",
-                "syn"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dtolnay/proc-macro2",
-            "homepage": null,
-            "documentation": "https://docs.rs/proc-macro2",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.31"
-        },
-        {
-            "name": "quote",
-            "version": "1.0.26",
-            "id": "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Quasi-quoting macro quote!(...)",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "proc-macro2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.52",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustversion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "trybuild",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.66",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "diff"
-                    ],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "quote",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quote-1.0.26/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "compiletest",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quote-1.0.26/tests/compiletest.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quote-1.0.26/tests/test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quote-1.0.26/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "proc-macro"
-                ],
-                "proc-macro": [
-                    "proc-macro2/proc-macro"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/quote-1.0.26/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "development-tools::procedural-macro-helpers"
-            ],
-            "keywords": [
-                "macros",
-                "syn"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dtolnay/quote",
-            "homepage": null,
-            "documentation": "https://docs.rs/quote/",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.31"
-        },
-        {
-            "name": "regex",
-            "version": "1.8.1",
-            "id": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "An implementation of regular expressions for Rust. This implementation uses\nfinite automata and guarantees linear time matching on all inputs.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "aho-corasick",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "memchr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.5.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex-syntax",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.7.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quickcheck",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "getrandom",
-                        "small_rng"
-                    ],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "regex",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna-bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-cheat",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna-cheat.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-replace",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna-replace.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-single-cheat",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna-single-cheat.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna-single",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna-single.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "shootout-regex-dna",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/examples/shootout-regex-dna.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "default",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_default.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "default-bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_default_bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "nfa",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_nfa.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "nfa-utf8bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_nfa_utf8bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "nfa-bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_nfa_bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "backtrack",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_backtrack.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "backtrack-utf8bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_backtrack_utf8bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "backtrack-bytes",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_backtrack_bytes.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "crates-regex",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/tests/test_crates_regex.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "aho-corasick": [
-                    "dep:aho-corasick"
-                ],
-                "default": [
-                    "std",
-                    "perf",
-                    "unicode",
-                    "regex-syntax/default"
-                ],
-                "memchr": [
-                    "dep:memchr"
-                ],
-                "pattern": [],
-                "perf": [
-                    "perf-cache",
-                    "perf-dfa",
-                    "perf-inline",
-                    "perf-literal"
-                ],
-                "perf-cache": [],
-                "perf-dfa": [],
-                "perf-inline": [],
-                "perf-literal": [
-                    "aho-corasick",
-                    "memchr"
-                ],
-                "std": [],
-                "unicode": [
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment",
-                    "regex-syntax/unicode"
-                ],
-                "unicode-age": [
-                    "regex-syntax/unicode-age"
-                ],
-                "unicode-bool": [
-                    "regex-syntax/unicode-bool"
-                ],
-                "unicode-case": [
-                    "regex-syntax/unicode-case"
-                ],
-                "unicode-gencat": [
-                    "regex-syntax/unicode-gencat"
-                ],
-                "unicode-perl": [
-                    "regex-syntax/unicode-perl"
-                ],
-                "unicode-script": [
-                    "regex-syntax/unicode-script"
-                ],
-                "unicode-segment": [
-                    "regex-syntax/unicode-segment"
-                ],
-                "unstable": [
-                    "pattern"
-                ],
-                "use_std": [
-                    "std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.8.1/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [
-                "text-processing"
-            ],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/regex",
-            "homepage": "https://github.com/rust-lang/regex",
-            "documentation": "https://docs.rs/regex",
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.60.0"
-        },
-        {
-            "name": "regex-automata",
-            "version": "0.1.10",
-            "id": "regex-automata 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense/MIT",
-            "license_file": null,
-            "description": "Automata construction and matching using regular expressions.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "fst",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex-syntax",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.6.16",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "bstr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "std"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.2.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.82",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_bytes",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.11",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_derive",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.82",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "toml",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.10",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "regex-automata",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-automata-0.1.10/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "default",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-automata-0.1.10/tests/tests.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                }
-            ],
-            "features": {
-                "default": [
-                    "std"
-                ],
-                "fst": [
-                    "dep:fst"
-                ],
-                "regex-syntax": [
-                    "dep:regex-syntax"
-                ],
-                "std": [
-                    "regex-syntax"
-                ],
-                "transducer": [
-                    "std",
-                    "fst"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-automata-0.1.10/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "text-processing"
-            ],
-            "keywords": [
-                "regex",
-                "dfa",
-                "automata",
-                "automaton",
-                "nfa"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/regex-automata",
-            "homepage": "https://github.com/BurntSushi/regex-automata",
-            "documentation": "https://docs.rs/regex-automata",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "regex-syntax",
-            "version": "0.6.29",
-            "id": "regex-syntax 0.6.29 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A regular expression parser.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "regex-syntax",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-syntax-0.6.29/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-syntax-0.6.29/benches/bench.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "unicode"
-                ],
-                "unicode": [
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ],
-                "unicode-age": [],
-                "unicode-bool": [],
-                "unicode-case": [],
-                "unicode-gencat": [],
-                "unicode-perl": [],
-                "unicode-script": [],
-                "unicode-segment": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-syntax-0.6.29/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/regex",
-            "homepage": "https://github.com/rust-lang/regex",
-            "documentation": "https://docs.rs/regex-syntax",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "regex-syntax",
-            "version": "0.7.1",
-            "id": "regex-syntax 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A regular expression parser.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "regex-syntax",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-syntax-0.7.1/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-syntax-0.7.1/benches/bench.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [
-                    "std",
-                    "unicode"
-                ],
-                "std": [],
-                "unicode": [
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ],
-                "unicode-age": [],
-                "unicode-bool": [],
-                "unicode-case": [],
-                "unicode-gencat": [],
-                "unicode-perl": [],
-                "unicode-script": [],
-                "unicode-segment": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-syntax-0.7.1/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "all-features": true,
-                        "rustdoc-args": [
-                            "--cfg",
-                            "docsrs"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "The Rust Project Developers"
-            ],
-            "categories": [],
-            "keywords": [],
-            "readme": "README.md",
-            "repository": "https://github.com/rust-lang/regex",
-            "homepage": "https://github.com/rust-lang/regex",
-            "documentation": "https://docs.rs/regex-syntax",
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.60.0"
-        },
-        {
-            "name": "ripgrep",
-            "version": "13.0.0",
-            "id": "ripgrep 13.0.0 (path+file:///$ROOT$ripgrep)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "ripgrep is a line-oriented search tool that recursively searches the current\ndirectory for a regex pattern while respecting gitignore rules. ripgrep has\nfirst class support on Windows, macOS and Linux.\n",
-            "source": null,
-            "dependencies": [
-                {
-                    "name": "bstr",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "clap",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.33.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "suggestions"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "grep",
-                    "source": null,
-                    "req": "^0.2.11",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/grep"
-                },
-                {
-                    "name": "ignore",
-                    "source": null,
-                    "req": "^0.4.19",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null,
-                    "path": "$ROOT$ripgrep/crates/ignore"
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "log",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.3.5",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_json",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.23",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "termcolor",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.77",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_derive",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.77",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "walkdir",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "clap",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.33.0",
-                    "kind": "build",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [
-                        "suggestions"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "lazy_static",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.1.0",
-                    "kind": "build",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "jemallocator",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.5.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(all(target_env = \"musl\", target_pointer_width = \"64\"))",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "bin"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "rg",
-                    "src_path": "$ROOT$ripgrep/crates/core/main.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "integration",
-                    "src_path": "$ROOT$ripgrep/tests/tests.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$ripgrep/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "pcre2": [
-                    "grep/pcre2"
-                ],
-                "simd-accel": [
-                    "grep/simd-accel"
-                ]
-            },
-            "manifest_path": "$ROOT$ripgrep/Cargo.toml",
-            "metadata": {
-                "deb": {
-                    "assets": [
-                        [
-                            "target/release/rg",
-                            "usr/bin/",
-                            "755"
-                        ],
-                        [
-                            "COPYING",
-                            "usr/share/doc/ripgrep/",
-                            "644"
-                        ],
-                        [
-                            "LICENSE-MIT",
-                            "usr/share/doc/ripgrep/",
-                            "644"
-                        ],
-                        [
-                            "UNLICENSE",
-                            "usr/share/doc/ripgrep/",
-                            "644"
-                        ],
-                        [
-                            "CHANGELOG.md",
-                            "usr/share/doc/ripgrep/CHANGELOG",
-                            "644"
-                        ],
-                        [
-                            "README.md",
-                            "usr/share/doc/ripgrep/README",
-                            "644"
-                        ],
-                        [
-                            "FAQ.md",
-                            "usr/share/doc/ripgrep/FAQ",
-                            "644"
-                        ],
-                        [
-                            "deployment/deb/rg.1",
-                            "usr/share/man/man1/rg.1",
-                            "644"
-                        ],
-                        [
-                            "deployment/deb/rg.bash",
-                            "usr/share/bash-completion/completions/rg",
-                            "644"
-                        ],
-                        [
-                            "deployment/deb/rg.fish",
-                            "usr/share/fish/vendor_completions.d/rg.fish",
-                            "644"
-                        ],
-                        [
-                            "deployment/deb/_rg",
-                            "usr/share/zsh/vendor-completions/",
-                            "644"
-                        ]
-                    ],
-                    "extended-description": "ripgrep (rg) recursively searches your current directory for a regex pattern.\nBy default, ripgrep will respect your .gitignore and automatically skip hidden\nfiles/directories and binary files.\n",
-                    "features": [
-                        "pcre2"
-                    ],
-                    "section": "utils"
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "command-line-utilities",
-                "text-processing"
-            ],
-            "keywords": [
-                "regex",
-                "grep",
-                "egrep",
-                "search",
-                "pattern"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/ripgrep",
-            "homepage": "https://github.com/BurntSushi/ripgrep",
-            "documentation": "https://github.com/BurntSushi/ripgrep",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.65"
-        },
-        {
-            "name": "ryu",
-            "version": "1.0.13",
-            "id": "ryu 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Apache-2.0 OR BSL-1.0",
-            "license_file": null,
-            "description": "Fast floating point to string conversion",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "no-panic",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "num_cpus",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.8",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand_xorshift",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "ryu",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "upstream_benchmark",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/examples/upstream_benchmark.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "common_test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/tests/common_test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "d2s_table_test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/tests/d2s_table_test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "d2s_test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/tests/d2s_test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "exhaustive",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/tests/exhaustive.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "f2s_test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/tests/f2s_test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "s2d_test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/tests/s2d_test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "s2f_test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/tests/s2f_test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "bench",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/benches/bench.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "no-panic": [
-                    "dep:no-panic"
-                ],
-                "small": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/ryu-1.0.13/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "value-formatting",
-                "no-std"
-            ],
-            "keywords": [
-                "float"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dtolnay/ryu",
-            "homepage": null,
-            "documentation": "https://docs.rs/ryu",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.36"
-        },
-        {
-            "name": "same-file",
-            "version": "1.0.6",
-            "id": "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense/MIT",
-            "license_file": null,
-            "description": "A simple crate for determining whether two file paths point to the same file.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "doc-comment",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "winapi-util",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(windows)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "same-file",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/same-file-1.0.6/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "is_same_file",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/same-file-1.0.6/examples/is_same_file.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "is_stderr",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/same-file-1.0.6/examples/is_stderr.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/same-file-1.0.6/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "same",
-                "file",
-                "equal",
-                "inode"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/same-file",
-            "homepage": "https://github.com/BurntSushi/same-file",
-            "documentation": "https://docs.rs/same-file",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "serde",
-            "version": "1.0.160",
-            "id": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A generic serialization/deserialization framework",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "serde_derive",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "=1.0.160",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_derive",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "serde",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde-1.0.160/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde-1.0.160/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "alloc": [],
-                "default": [
-                    "std"
-                ],
-                "derive": [
-                    "serde_derive"
-                ],
-                "rc": [],
-                "serde_derive": [
-                    "dep:serde_derive"
-                ],
-                "std": [],
-                "unstable": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde-1.0.160/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "features": [
-                            "derive"
-                        ],
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                },
-                "playground": {
-                    "features": [
-                        "derive",
-                        "rc"
-                    ]
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Erick Tryzelaar <erick.tryzelaar@gmail.com>",
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "encoding",
-                "no-std"
-            ],
-            "keywords": [
-                "serde",
-                "serialization",
-                "no_std"
-            ],
-            "readme": "crates-io.md",
-            "repository": "https://github.com/serde-rs/serde",
-            "homepage": "https://serde.rs",
-            "documentation": "https://docs.rs/serde",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.19"
-        },
-        {
-            "name": "serde_derive",
-            "version": "1.0.160",
-            "id": "serde_derive 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "proc-macro2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quote",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "syn",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.0.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "proc-macro"
-                    ],
-                    "crate_types": [
-                        "proc-macro"
-                    ],
-                    "name": "serde_derive",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_derive-1.0.160/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_derive-1.0.160/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "default": [],
-                "deserialize_in_place": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_derive-1.0.160/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Erick Tryzelaar <erick.tryzelaar@gmail.com>",
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "no-std"
-            ],
-            "keywords": [
-                "serde",
-                "serialization",
-                "no_std",
-                "derive"
-            ],
-            "readme": "crates-io.md",
-            "repository": "https://github.com/serde-rs/serde",
-            "homepage": "https://serde.rs",
-            "documentation": "https://serde.rs/derive.html",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.56"
-        },
-        {
-            "name": "serde_json",
-            "version": "1.0.96",
-            "id": "serde_json 1.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "A JSON serialization file format",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "indexmap",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.5.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [
-                        "std"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "itoa",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "ryu",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.100",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "automod",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "indoc",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "ref-cast",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustversion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.100",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "derive"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_bytes",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.11",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_derive",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "serde_stacker",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "trybuild",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.49",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "diff"
-                    ],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "serde_json",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.96/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "compiletest",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.96/tests/compiletest.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "debug",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.96/tests/debug.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "lexical",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.96/tests/lexical.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "map",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.96/tests/map.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "regression",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.96/tests/regression.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "stream",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.96/tests/stream.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.96/tests/test.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.96/build.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "alloc": [
-                    "serde/alloc"
-                ],
-                "arbitrary_precision": [],
-                "default": [
-                    "std"
-                ],
-                "float_roundtrip": [],
-                "indexmap": [
-                    "dep:indexmap"
-                ],
-                "preserve_order": [
-                    "indexmap",
-                    "std"
-                ],
-                "raw_value": [],
-                "std": [
-                    "serde/std"
-                ],
-                "unbounded_depth": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/serde_json-1.0.96/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "features": [
-                            "raw_value",
-                            "unbounded_depth"
-                        ],
-                        "rustdoc-args": [
-                            "--cfg",
-                            "docsrs"
-                        ],
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                },
-                "playground": {
-                    "features": [
-                        "raw_value"
-                    ]
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Erick Tryzelaar <erick.tryzelaar@gmail.com>",
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "encoding",
-                "parser-implementations",
-                "no-std"
-            ],
-            "keywords": [
-                "json",
-                "serde",
-                "serialization"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/serde-rs/json",
-            "homepage": null,
-            "documentation": "https://docs.rs/serde_json",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.36"
-        },
-        {
-            "name": "strsim",
-            "version": "0.8.0",
-            "id": "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT",
-            "license_file": null,
-            "description": "Implementations of string similarity metrics.\nIncludes Hamming, Levenshtein, OSA, Damerau-Levenshtein, Jaro, and Jaro-Winkler.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "strsim",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/strsim-0.8.0/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "lib",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/strsim-0.8.0/tests/lib.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "benches",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/strsim-0.8.0/benches/benches.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/strsim-0.8.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Danny Guo <dannyguo91@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "string",
-                "similarity",
-                "Hamming",
-                "Levenshtein",
-                "Jaro"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dguo/strsim-rs",
-            "homepage": "https://github.com/dguo/strsim-rs",
-            "documentation": "https://docs.rs/strsim/",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "syn",
-            "version": "2.0.15",
-            "id": "syn 2.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Parser for Rust source code",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "proc-macro2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.55",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "quote",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.25",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "unicode-ident",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "anyhow",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "automod",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "flate2",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "insta",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rayon",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "ref-cast",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "regex",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "reqwest",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.11",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "blocking"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustversion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "syn-test-suite",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "tar",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.16",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "termcolor",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "walkdir",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^2.3.2",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "syn",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "regression",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/regression.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_asyncness",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_asyncness.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_attribute",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_attribute.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_derive_input",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_derive_input.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_expr",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_expr.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_generics",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_generics.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_grouping",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_grouping.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_ident",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_ident.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_item",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_item.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_iterators",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_iterators.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_lit",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_lit.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_meta",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_meta.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_parse_buffer",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_parse_buffer.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_parse_stream",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_parse_stream.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_pat",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_pat.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_path",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_path.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_precedence",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_precedence.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_receiver",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_receiver.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_round_trip",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_round_trip.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_shebang",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_shebang.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_should_parse",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_should_parse.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_size",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_size.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_stmt",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_stmt.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_token_trees",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_token_trees.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_ty",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_ty.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "test_visibility",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/test_visibility.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "zzz_stable",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/tests/zzz_stable.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "rust",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/benches/rust.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "full",
-                        "parsing"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "file",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/benches/file.rs",
-                    "edition": "2021",
-                    "required-features": [
-                        "full",
-                        "parsing"
-                    ],
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "clone-impls": [],
-                "default": [
-                    "derive",
-                    "parsing",
-                    "printing",
-                    "clone-impls",
-                    "proc-macro"
-                ],
-                "derive": [],
-                "extra-traits": [],
-                "fold": [],
-                "full": [],
-                "parsing": [],
-                "printing": [
-                    "quote"
-                ],
-                "proc-macro": [
-                    "proc-macro2/proc-macro",
-                    "quote/proc-macro"
-                ],
-                "quote": [
-                    "dep:quote"
-                ],
-                "test": [
-                    "syn-test-suite/all-features"
-                ],
-                "visit": [],
-                "visit-mut": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/syn-2.0.15/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "all-features": true,
-                        "rustdoc-args": [
-                            "--cfg",
-                            "doc_cfg"
-                        ],
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                },
-                "playground": {
-                    "features": [
-                        "full",
-                        "visit",
-                        "visit-mut",
-                        "fold",
-                        "extra-traits"
-                    ]
-                }
-            },
-            "publish": null,
-            "authors": [
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "development-tools::procedural-macro-helpers",
-                "parser-implementations"
-            ],
-            "keywords": [
-                "macros",
-                "syn"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dtolnay/syn",
-            "homepage": null,
-            "documentation": "https://docs.rs/syn",
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.56"
-        },
-        {
-            "name": "termcolor",
-            "version": "1.2.0",
-            "id": "termcolor 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense OR MIT",
-            "license_file": null,
-            "description": "A simple cross platform library for writing colored text to a terminal.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "winapi-util",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(windows)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "termcolor",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/termcolor-1.2.0/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/termcolor-1.2.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "windows",
-                "win",
-                "color",
-                "ansi",
-                "console"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/termcolor",
-            "homepage": "https://github.com/BurntSushi/termcolor",
-            "documentation": "https://docs.rs/termcolor",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "textwrap",
-            "version": "0.11.0",
-            "id": "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT",
-            "license_file": null,
-            "description": "Textwrap is a small library for word wrapping, indenting, and\ndedenting strings.\n\nYou can use it to format strings (such as help and error messages) for\ndisplay in commandline applications. It is designed to be efficient\nand handle Unicode characters correctly.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "hyphenation",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.7.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [
-                        "embed_all"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "term_size",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "unicode-width",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "lipsum",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.6",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.6",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand_xorshift",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "version-sync",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.6",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "textwrap",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/textwrap-0.11.0/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "layout",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/textwrap-0.11.0/examples/layout.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "example"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "termwidth",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/textwrap-0.11.0/examples/termwidth.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "version-numbers",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/textwrap-0.11.0/tests/version-numbers.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "linear",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/textwrap-0.11.0/benches/linear.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "hyphenation": [
-                    "dep:hyphenation"
-                ],
-                "term_size": [
-                    "dep:term_size"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/textwrap-0.11.0/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "all-features": true
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Martin Geisler <martin@geisler.net>"
-            ],
-            "categories": [
-                "text-processing",
-                "command-line-interface"
-            ],
-            "keywords": [
-                "text",
-                "formatting",
-                "wrap",
-                "typesetting",
-                "hyphenation"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/mgeisler/textwrap",
-            "homepage": null,
-            "documentation": "https://docs.rs/textwrap/",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "thread_local",
-            "version": "1.1.7",
-            "id": "thread_local 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT OR Apache-2.0",
-            "license_file": null,
-            "description": "Per-object thread-local storage",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "cfg-if",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.0",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "once_cell",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.5.2",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "criterion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4.0",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "thread_local",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/thread_local-1.1.7/src/lib.rs",
-                    "edition": "2021",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "thread_local",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/thread_local-1.1.7/benches/thread_local.rs",
-                    "edition": "2021",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "nightly": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/thread_local-1.1.7/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Amanieu d'Antras <amanieu@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "thread_local",
-                "concurrent",
-                "thread"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/Amanieu/thread_local-rs",
-            "homepage": null,
-            "documentation": "https://docs.rs/thread_local/",
-            "edition": "2021",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "unicode-ident",
-            "version": "1.0.8",
-            "id": "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "(MIT OR Apache-2.0) AND Unicode-DFS-2016",
-            "license_file": null,
-            "description": "Determine whether characters have the XID_Start or XID_Continue properties according to Unicode Standard Annex #31",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "criterion",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "fst",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rand",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.8",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "small_rng"
-                    ],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "roaring",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.10",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "ucd-trie",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": false,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "unicode-xid",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.2.4",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "unicode-ident",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-ident-1.0.8/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "compare",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-ident-1.0.8/tests/compare.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "test"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "static_size",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-ident-1.0.8/tests/static_size.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "bench"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "xid",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-ident-1.0.8/benches/xid.rs",
-                    "edition": "2018",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-ident-1.0.8/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "targets": [
-                            "x86_64-unknown-linux-gnu"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "David Tolnay <dtolnay@gmail.com>"
-            ],
-            "categories": [
-                "development-tools::procedural-macro-helpers",
-                "no-std"
-            ],
-            "keywords": [
-                "unicode",
-                "xid"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/dtolnay/unicode-ident",
-            "homepage": null,
-            "documentation": "https://docs.rs/unicode-ident",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": "1.31"
-        },
-        {
-            "name": "unicode-width",
-            "version": "0.1.10",
-            "id": "unicode-width 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "Determine displayed width of `char` and `str` types\naccording to Unicode Standard Annex #11 rules.\n",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "compiler_builtins",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-core",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": "core",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "rustc-std-workspace-std",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0",
-                    "kind": null,
-                    "rename": "std",
-                    "optional": true,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "unicode-width",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-width-0.1.10/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {
-                "bench": [],
-                "compiler_builtins": [
-                    "dep:compiler_builtins"
-                ],
-                "core": [
-                    "dep:core"
-                ],
-                "default": [],
-                "no_std": [],
-                "rustc-dep-of-std": [
-                    "std",
-                    "core",
-                    "compiler_builtins"
-                ],
-                "std": [
-                    "dep:std"
-                ]
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/unicode-width-0.1.10/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "kwantam <kwantam@gmail.com>",
-                "Manish Goregaokar <manishsmail@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "text",
-                "width",
-                "unicode"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/unicode-rs/unicode-width",
-            "homepage": "https://github.com/unicode-rs/unicode-width",
-            "documentation": "https://unicode-rs.github.io/unicode-width",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "walkdir",
-            "version": "2.3.3",
-            "id": "walkdir 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense/MIT",
-            "license_file": null,
-            "description": "Recursively walk a directory.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "same-file",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^1.0.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "doc-comment",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": "dev",
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": null,
-                    "registry": null
-                },
-                {
-                    "name": "winapi-util",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.1.1",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "cfg(windows)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "walkdir",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/walkdir-2.3.3/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/walkdir-2.3.3/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "filesystem"
-            ],
-            "keywords": [
-                "directory",
-                "recursive",
-                "walk",
-                "iterator"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/walkdir",
-            "homepage": "https://github.com/BurntSushi/walkdir",
-            "documentation": "https://docs.rs/walkdir/",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "winapi",
-            "version": "0.3.9",
-            "id": "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "Raw FFI bindings for all of Windows API.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "winapi-i686-pc-windows-gnu",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "i686-pc-windows-gnu",
-                    "registry": null
-                },
-                {
-                    "name": "winapi-x86_64-pc-windows-gnu",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.4",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [],
-                    "target": "x86_64-pc-windows-gnu",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "winapi",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-0.3.9/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-0.3.9/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {
-                "accctrl": [],
-                "aclapi": [],
-                "activation": [],
-                "adhoc": [],
-                "appmgmt": [],
-                "audioclient": [],
-                "audiosessiontypes": [],
-                "avrt": [],
-                "basetsd": [],
-                "bcrypt": [],
-                "bits": [],
-                "bits10_1": [],
-                "bits1_5": [],
-                "bits2_0": [],
-                "bits2_5": [],
-                "bits3_0": [],
-                "bits4_0": [],
-                "bits5_0": [],
-                "bitscfg": [],
-                "bitsmsg": [],
-                "bluetoothapis": [],
-                "bluetoothleapis": [],
-                "bthdef": [],
-                "bthioctl": [],
-                "bthledef": [],
-                "bthsdpdef": [],
-                "bugcodes": [],
-                "cderr": [],
-                "cfg": [],
-                "cfgmgr32": [],
-                "cguid": [],
-                "combaseapi": [],
-                "coml2api": [],
-                "commapi": [],
-                "commctrl": [],
-                "commdlg": [],
-                "commoncontrols": [],
-                "consoleapi": [],
-                "corecrt": [],
-                "corsym": [],
-                "d2d1": [],
-                "d2d1_1": [],
-                "d2d1_2": [],
-                "d2d1_3": [],
-                "d2d1effectauthor": [],
-                "d2d1effects": [],
-                "d2d1effects_1": [],
-                "d2d1effects_2": [],
-                "d2d1svg": [],
-                "d2dbasetypes": [],
-                "d3d": [],
-                "d3d10": [],
-                "d3d10_1": [],
-                "d3d10_1shader": [],
-                "d3d10effect": [],
-                "d3d10misc": [],
-                "d3d10sdklayers": [],
-                "d3d10shader": [],
-                "d3d11": [],
-                "d3d11_1": [],
-                "d3d11_2": [],
-                "d3d11_3": [],
-                "d3d11_4": [],
-                "d3d11on12": [],
-                "d3d11sdklayers": [],
-                "d3d11shader": [],
-                "d3d11tokenizedprogramformat": [],
-                "d3d12": [],
-                "d3d12sdklayers": [],
-                "d3d12shader": [],
-                "d3d9": [],
-                "d3d9caps": [],
-                "d3d9types": [],
-                "d3dcommon": [],
-                "d3dcompiler": [],
-                "d3dcsx": [],
-                "d3dkmdt": [],
-                "d3dkmthk": [],
-                "d3dukmdt": [],
-                "d3dx10core": [],
-                "d3dx10math": [],
-                "d3dx10mesh": [],
-                "datetimeapi": [],
-                "davclnt": [],
-                "dbghelp": [],
-                "dbt": [],
-                "dcommon": [],
-                "dcomp": [],
-                "dcompanimation": [],
-                "dcomptypes": [],
-                "dde": [],
-                "ddraw": [],
-                "ddrawi": [],
-                "ddrawint": [],
-                "debug": [
-                    "impl-debug"
-                ],
-                "debugapi": [],
-                "devguid": [],
-                "devicetopology": [],
-                "devpkey": [],
-                "devpropdef": [],
-                "dinput": [],
-                "dinputd": [],
-                "dispex": [],
-                "dmksctl": [],
-                "dmusicc": [],
-                "docobj": [],
-                "documenttarget": [],
-                "dot1x": [],
-                "dpa_dsa": [],
-                "dpapi": [],
-                "dsgetdc": [],
-                "dsound": [],
-                "dsrole": [],
-                "dvp": [],
-                "dwmapi": [],
-                "dwrite": [],
-                "dwrite_1": [],
-                "dwrite_2": [],
-                "dwrite_3": [],
-                "dxdiag": [],
-                "dxfile": [],
-                "dxgi": [],
-                "dxgi1_2": [],
-                "dxgi1_3": [],
-                "dxgi1_4": [],
-                "dxgi1_5": [],
-                "dxgi1_6": [],
-                "dxgidebug": [],
-                "dxgiformat": [],
-                "dxgitype": [],
-                "dxva2api": [],
-                "dxvahd": [],
-                "eaptypes": [],
-                "enclaveapi": [],
-                "endpointvolume": [],
-                "errhandlingapi": [],
-                "everything": [],
-                "evntcons": [],
-                "evntprov": [],
-                "evntrace": [],
-                "excpt": [],
-                "exdisp": [],
-                "fibersapi": [],
-                "fileapi": [],
-                "functiondiscoverykeys_devpkey": [],
-                "gl-gl": [],
-                "guiddef": [],
-                "handleapi": [],
-                "heapapi": [],
-                "hidclass": [],
-                "hidpi": [],
-                "hidsdi": [],
-                "hidusage": [],
-                "highlevelmonitorconfigurationapi": [],
-                "hstring": [],
-                "http": [],
-                "ifdef": [],
-                "ifmib": [],
-                "imm": [],
-                "impl-debug": [],
-                "impl-default": [],
-                "in6addr": [],
-                "inaddr": [],
-                "inspectable": [],
-                "interlockedapi": [],
-                "intsafe": [],
-                "ioapiset": [],
-                "ipexport": [],
-                "iphlpapi": [],
-                "ipifcons": [],
-                "ipmib": [],
-                "iprtrmib": [],
-                "iptypes": [],
-                "jobapi": [],
-                "jobapi2": [],
-                "knownfolders": [],
-                "ks": [],
-                "ksmedia": [],
-                "ktmtypes": [],
-                "ktmw32": [],
-                "l2cmn": [],
-                "libloaderapi": [],
-                "limits": [],
-                "lmaccess": [],
-                "lmalert": [],
-                "lmapibuf": [],
-                "lmat": [],
-                "lmcons": [],
-                "lmdfs": [],
-                "lmerrlog": [],
-                "lmjoin": [],
-                "lmmsg": [],
-                "lmremutl": [],
-                "lmrepl": [],
-                "lmserver": [],
-                "lmshare": [],
-                "lmstats": [],
-                "lmsvc": [],
-                "lmuse": [],
-                "lmwksta": [],
-                "lowlevelmonitorconfigurationapi": [],
-                "lsalookup": [],
-                "memoryapi": [],
-                "minschannel": [],
-                "minwinbase": [],
-                "minwindef": [],
-                "mmdeviceapi": [],
-                "mmeapi": [],
-                "mmreg": [],
-                "mmsystem": [],
-                "mprapidef": [],
-                "msaatext": [],
-                "mscat": [],
-                "mschapp": [],
-                "mssip": [],
-                "mstcpip": [],
-                "mswsock": [],
-                "mswsockdef": [],
-                "namedpipeapi": [],
-                "namespaceapi": [],
-                "nb30": [],
-                "ncrypt": [],
-                "netioapi": [],
-                "nldef": [],
-                "ntddndis": [],
-                "ntddscsi": [],
-                "ntddser": [],
-                "ntdef": [],
-                "ntlsa": [],
-                "ntsecapi": [],
-                "ntstatus": [],
-                "oaidl": [],
-                "objbase": [],
-                "objidl": [],
-                "objidlbase": [],
-                "ocidl": [],
-                "ole2": [],
-                "oleauto": [],
-                "olectl": [],
-                "oleidl": [],
-                "opmapi": [],
-                "pdh": [],
-                "perflib": [],
-                "physicalmonitorenumerationapi": [],
-                "playsoundapi": [],
-                "portabledevice": [],
-                "portabledeviceapi": [],
-                "portabledevicetypes": [],
-                "powerbase": [],
-                "powersetting": [],
-                "powrprof": [],
-                "processenv": [],
-                "processsnapshot": [],
-                "processthreadsapi": [],
-                "processtopologyapi": [],
-                "profileapi": [],
-                "propidl": [],
-                "propkey": [],
-                "propkeydef": [],
-                "propsys": [],
-                "prsht": [],
-                "psapi": [],
-                "qos": [],
-                "realtimeapiset": [],
-                "reason": [],
-                "restartmanager": [],
-                "restrictederrorinfo": [],
-                "rmxfguid": [],
-                "roapi": [],
-                "robuffer": [],
-                "roerrorapi": [],
-                "rpc": [],
-                "rpcdce": [],
-                "rpcndr": [],
-                "rtinfo": [],
-                "sapi": [],
-                "sapi51": [],
-                "sapi53": [],
-                "sapiddk": [],
-                "sapiddk51": [],
-                "schannel": [],
-                "sddl": [],
-                "securityappcontainer": [],
-                "securitybaseapi": [],
-                "servprov": [],
-                "setupapi": [],
-                "shellapi": [],
-                "shellscalingapi": [],
-                "shlobj": [],
-                "shobjidl": [],
-                "shobjidl_core": [],
-                "shtypes": [],
-                "softpub": [],
-                "spapidef": [],
-                "spellcheck": [],
-                "sporder": [],
-                "sql": [],
-                "sqlext": [],
-                "sqltypes": [],
-                "sqlucode": [],
-                "sspi": [],
-                "std": [],
-                "stralign": [],
-                "stringapiset": [],
-                "strmif": [],
-                "subauth": [],
-                "synchapi": [],
-                "sysinfoapi": [],
-                "systemtopologyapi": [],
-                "taskschd": [],
-                "tcpestats": [],
-                "tcpmib": [],
-                "textstor": [],
-                "threadpoolapiset": [],
-                "threadpoollegacyapiset": [],
-                "timeapi": [],
-                "timezoneapi": [],
-                "tlhelp32": [],
-                "transportsettingcommon": [],
-                "tvout": [],
-                "udpmib": [],
-                "unknwnbase": [],
-                "urlhist": [],
-                "urlmon": [],
-                "usb": [],
-                "usbioctl": [],
-                "usbiodef": [],
-                "usbscan": [],
-                "usbspec": [],
-                "userenv": [],
-                "usp10": [],
-                "utilapiset": [],
-                "uxtheme": [],
-                "vadefs": [],
-                "vcruntime": [],
-                "vsbackup": [],
-                "vss": [],
-                "vsserror": [],
-                "vswriter": [],
-                "wbemads": [],
-                "wbemcli": [],
-                "wbemdisp": [],
-                "wbemprov": [],
-                "wbemtran": [],
-                "wct": [],
-                "werapi": [],
-                "winbase": [],
-                "wincodec": [],
-                "wincodecsdk": [],
-                "wincon": [],
-                "wincontypes": [],
-                "wincred": [],
-                "wincrypt": [],
-                "windef": [],
-                "windot11": [],
-                "windowsceip": [],
-                "windowsx": [],
-                "winefs": [],
-                "winerror": [],
-                "winevt": [],
-                "wingdi": [],
-                "winhttp": [],
-                "wininet": [],
-                "winineti": [],
-                "winioctl": [],
-                "winnetwk": [],
-                "winnls": [],
-                "winnt": [],
-                "winreg": [],
-                "winsafer": [],
-                "winscard": [],
-                "winsmcrd": [],
-                "winsock2": [],
-                "winspool": [],
-                "winstring": [],
-                "winsvc": [],
-                "wintrust": [],
-                "winusb": [],
-                "winusbio": [],
-                "winuser": [],
-                "winver": [],
-                "wlanapi": [],
-                "wlanihv": [],
-                "wlanihvtypes": [],
-                "wlantypes": [],
-                "wlclient": [],
-                "wmistr": [],
-                "wnnc": [],
-                "wow64apiset": [],
-                "wpdmtpextensions": [],
-                "ws2bth": [],
-                "ws2def": [],
-                "ws2ipdef": [],
-                "ws2spi": [],
-                "ws2tcpip": [],
-                "wtsapi32": [],
-                "wtypes": [],
-                "wtypesbase": [],
-                "xinput": []
-            },
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-0.3.9/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "default-target": "x86_64-pc-windows-msvc",
-                        "features": [
-                            "everything",
-                            "impl-debug",
-                            "impl-default"
-                        ],
-                        "targets": [
-                            "aarch64-pc-windows-msvc",
-                            "i686-pc-windows-msvc",
-                            "x86_64-pc-windows-msvc"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Peter Atashian <retep998@gmail.com>"
-            ],
-            "categories": [
-                "external-ffi-bindings",
-                "no-std",
-                "os::windows-apis"
-            ],
-            "keywords": [
-                "windows",
-                "ffi",
-                "win32",
-                "com",
-                "directx"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/retep998/winapi-rs",
-            "homepage": null,
-            "documentation": "https://docs.rs/winapi/",
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "winapi-i686-pc-windows-gnu",
-            "version": "0.4.0",
-            "id": "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "Import libraries for the i686-pc-windows-gnu target. Please don't use this crate directly, depend on winapi instead.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "winapi-i686-pc-windows-gnu",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-i686-pc-windows-gnu-0.4.0/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-i686-pc-windows-gnu-0.4.0/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-i686-pc-windows-gnu-0.4.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Peter Atashian <retep998@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "windows"
-            ],
-            "readme": null,
-            "repository": "https://github.com/retep998/winapi-rs",
-            "homepage": null,
-            "documentation": null,
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "winapi-util",
-            "version": "0.1.5",
-            "id": "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "Unlicense/MIT",
-            "license_file": null,
-            "description": "A dumping ground for high level safe wrappers over winapi.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [
-                {
-                    "name": "winapi",
-                    "source": "registry+https://github.com/rust-lang/crates.io-index",
-                    "req": "^0.3",
-                    "kind": null,
-                    "rename": null,
-                    "optional": false,
-                    "uses_default_features": true,
-                    "features": [
-                        "std",
-                        "consoleapi",
-                        "errhandlingapi",
-                        "fileapi",
-                        "minwindef",
-                        "processenv",
-                        "winbase",
-                        "wincon",
-                        "winerror",
-                        "winnt"
-                    ],
-                    "target": "cfg(windows)",
-                    "registry": null
-                }
-            ],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "winapi-util",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-util-0.1.5/src/lib.rs",
-                    "edition": "2018",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-util-0.1.5/Cargo.toml",
-            "metadata": {
-                "docs": {
-                    "rs": {
-                        "targets": [
-                            "x86_64-pc-windows-msvc"
-                        ]
-                    }
-                }
-            },
-            "publish": null,
-            "authors": [
-                "Andrew Gallant <jamslam@gmail.com>"
-            ],
-            "categories": [
-                "os::windows-apis",
-                "external-ffi-bindings"
-            ],
-            "keywords": [
-                "windows",
-                "winapi",
-                "util",
-                "win"
-            ],
-            "readme": "README.md",
-            "repository": "https://github.com/BurntSushi/winapi-util",
-            "homepage": "https://github.com/BurntSushi/winapi-util",
-            "documentation": "https://docs.rs/winapi-util",
-            "edition": "2018",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        },
-        {
-            "name": "winapi-x86_64-pc-windows-gnu",
-            "version": "0.4.0",
-            "id": "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-            "license": "MIT/Apache-2.0",
-            "license_file": null,
-            "description": "Import libraries for the x86_64-pc-windows-gnu target. Please don't use this crate directly, depend on winapi instead.",
-            "source": "registry+https://github.com/rust-lang/crates.io-index",
-            "dependencies": [],
-            "targets": [
-                {
-                    "kind": [
-                        "lib"
-                    ],
-                    "crate_types": [
-                        "lib"
-                    ],
-                    "name": "winapi-x86_64-pc-windows-gnu",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-x86_64-pc-windows-gnu-0.4.0/src/lib.rs",
-                    "edition": "2015",
-                    "doc": true,
-                    "doctest": true,
-                    "test": true
-                },
-                {
-                    "kind": [
-                        "custom-build"
-                    ],
-                    "crate_types": [
-                        "bin"
-                    ],
-                    "name": "build-script-build",
-                    "src_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-x86_64-pc-windows-gnu-0.4.0/build.rs",
-                    "edition": "2015",
-                    "doc": false,
-                    "doctest": false,
-                    "test": false
-                }
-            ],
-            "features": {},
-            "manifest_path": "$ROOT$.cargo/registry/src/index.crates.io-6f17d22bba15001f/winapi-x86_64-pc-windows-gnu-0.4.0/Cargo.toml",
-            "metadata": null,
-            "publish": null,
-            "authors": [
-                "Peter Atashian <retep998@gmail.com>"
-            ],
-            "categories": [],
-            "keywords": [
-                "windows"
-            ],
-            "readme": null,
-            "repository": "https://github.com/retep998/winapi-rs",
-            "homepage": null,
-            "documentation": null,
-            "edition": "2015",
-            "links": null,
-            "default_run": null,
-            "rust_version": null
-        }
-    ],
-    "workspace_members": [
-        "globset 0.4.10 (path+file:///$ROOT$ripgrep/crates/globset)",
-        "grep 0.2.11 (path+file:///$ROOT$ripgrep/crates/grep)",
-        "grep-cli 0.1.7 (path+file:///$ROOT$ripgrep/crates/cli)",
-        "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-        "grep-pcre2 0.1.6 (path+file:///$ROOT$ripgrep/crates/pcre2)",
-        "grep-printer 0.1.7 (path+file:///$ROOT$ripgrep/crates/printer)",
-        "grep-searcher 0.1.11 (path+file:///$ROOT$ripgrep/crates/searcher)",
-        "grep-regex 0.1.11 (path+file:///$ROOT$ripgrep/crates/regex)",
-        "ignore 0.4.20 (path+file:///$ROOT$ripgrep/crates/ignore)",
-        "ripgrep 13.0.0 (path+file:///$ROOT$ripgrep)"
-    ],
-    "resolve": {
-        "nodes": [
-            {
-                "id": "aho-corasick 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "memchr",
-                        "pkg": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default",
-                    "std"
-                ]
-            },
-            {
-                "id": "aho-corasick 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "memchr",
-                        "pkg": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default",
-                    "perf-literal",
-                    "std"
-                ]
-            },
-            {
-                "id": "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "hermit-abi 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "hermit_abi",
-                        "pkg": "hermit-abi 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(target_os = \"hermit\")"
-                            }
-                        ]
-                    },
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(unix)"
-                            }
-                        ]
-                    },
-                    {
-                        "name": "winapi",
-                        "pkg": "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(windows)"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "base64 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default",
-                    "std"
-                ]
-            },
-            {
-                "id": "bitflags 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default"
-                ]
-            },
-            {
-                "id": "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "once_cell 1.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex-automata 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "memchr",
-                        "pkg": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "once_cell",
-                        "pkg": "once_cell 1.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex_automata",
-                        "pkg": "regex-automata 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde",
-                        "pkg": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "alloc",
-                    "default",
-                    "std",
-                    "unicode"
-                ]
-            },
-            {
-                "id": "bytecount 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "runtime-dispatch-simd"
-                ]
-            },
-            {
-                "id": "cc 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "jobserver 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "jobserver",
-                        "pkg": "jobserver 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "jobserver",
-                    "parallel"
-                ]
-            },
-            {
-                "id": "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "clap 2.34.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "bitflags 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "unicode-width 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "bitflags",
-                        "pkg": "bitflags 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "strsim",
-                        "pkg": "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "textwrap",
-                        "pkg": "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "unicode_width",
-                        "pkg": "unicode-width 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "strsim",
-                    "suggestions"
-                ]
-            },
-            {
-                "id": "crossbeam-channel 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "crossbeam-utils 0.8.15 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "cfg_if",
-                        "pkg": "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "crossbeam_utils",
-                        "pkg": "crossbeam-utils 0.8.15 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "crossbeam-utils",
-                    "default",
-                    "std"
-                ]
-            },
-            {
-                "id": "crossbeam-utils 0.8.15 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "cfg_if",
-                        "pkg": "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "std"
-                ]
-            },
-            {
-                "id": "encoding_rs 0.8.32 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "cfg_if",
-                        "pkg": "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "alloc",
-                    "default"
-                ]
-            },
-            {
-                "id": "encoding_rs_io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "encoding_rs 0.8.32 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "encoding_rs",
-                        "pkg": "encoding_rs 0.8.32 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default",
-                    "std"
-                ]
-            },
-            {
-                "id": "glob 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "globset 0.4.10 (path+file:///$ROOT$ripgrep/crates/globset)",
-                "dependencies": [
-                    "aho-corasick 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "glob 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "serde_json 1.0.96 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "aho_corasick",
-                        "pkg": "aho-corasick 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "bstr",
-                        "pkg": "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "fnv",
-                        "pkg": "fnv 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "glob",
-                        "pkg": "glob 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "lazy_static",
-                        "pkg": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "log",
-                        "pkg": "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde_json",
-                        "pkg": "serde_json 1.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default",
-                    "log"
-                ]
-            },
-            {
-                "id": "grep 0.2.11 (path+file:///$ROOT$ripgrep/crates/grep)",
-                "dependencies": [
-                    "grep-cli 0.1.7 (path+file:///$ROOT$ripgrep/crates/cli)",
-                    "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                    "grep-printer 0.1.7 (path+file:///$ROOT$ripgrep/crates/printer)",
-                    "grep-regex 0.1.11 (path+file:///$ROOT$ripgrep/crates/regex)",
-                    "grep-searcher 0.1.11 (path+file:///$ROOT$ripgrep/crates/searcher)",
-                    "termcolor 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "walkdir 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "grep_cli",
-                        "pkg": "grep-cli 0.1.7 (path+file:///$ROOT$ripgrep/crates/cli)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep_matcher",
-                        "pkg": "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep_printer",
-                        "pkg": "grep-printer 0.1.7 (path+file:///$ROOT$ripgrep/crates/printer)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep_regex",
-                        "pkg": "grep-regex 0.1.11 (path+file:///$ROOT$ripgrep/crates/regex)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep_searcher",
-                        "pkg": "grep-searcher 0.1.11 (path+file:///$ROOT$ripgrep/crates/searcher)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "termcolor",
-                        "pkg": "termcolor 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "walkdir",
-                        "pkg": "walkdir 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "grep-cli 0.1.7 (path+file:///$ROOT$ripgrep/crates/cli)",
-                "dependencies": [
-                    "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "globset 0.4.10 (path+file:///$ROOT$ripgrep/crates/globset)",
-                    "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "termcolor 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "atty",
-                        "pkg": "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "bstr",
-                        "pkg": "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "globset",
-                        "pkg": "globset 0.4.10 (path+file:///$ROOT$ripgrep/crates/globset)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "lazy_static",
-                        "pkg": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "log",
-                        "pkg": "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "same_file",
-                        "pkg": "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "termcolor",
-                        "pkg": "termcolor 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "winapi_util",
-                        "pkg": "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(windows)"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                "dependencies": [
-                    "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "memchr",
-                        "pkg": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "grep-pcre2 0.1.6 (path+file:///$ROOT$ripgrep/crates/pcre2)",
-                "dependencies": [
-                    "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                    "pcre2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "grep_matcher",
-                        "pkg": "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "pcre2",
-                        "pkg": "pcre2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "grep-printer 0.1.7 (path+file:///$ROOT$ripgrep/crates/printer)",
-                "dependencies": [
-                    "base64 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                    "grep-regex 0.1.11 (path+file:///$ROOT$ripgrep/crates/regex)",
-                    "grep-searcher 0.1.11 (path+file:///$ROOT$ripgrep/crates/searcher)",
-                    "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "serde_json 1.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "termcolor 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "base64",
-                        "pkg": "base64 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "bstr",
-                        "pkg": "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep_matcher",
-                        "pkg": "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep_regex",
-                        "pkg": "grep-regex 0.1.11 (path+file:///$ROOT$ripgrep/crates/regex)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep_searcher",
-                        "pkg": "grep-searcher 0.1.11 (path+file:///$ROOT$ripgrep/crates/searcher)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde",
-                        "pkg": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde_json",
-                        "pkg": "serde_json 1.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "termcolor",
-                        "pkg": "termcolor 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "base64",
-                    "default",
-                    "serde",
-                    "serde1",
-                    "serde_json"
-                ]
-            },
-            {
-                "id": "grep-regex 0.1.11 (path+file:///$ROOT$ripgrep/crates/regex)",
-                "dependencies": [
-                    "aho-corasick 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                    "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex-syntax 0.6.29 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "thread_local 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "aho_corasick",
-                        "pkg": "aho-corasick 0.7.20 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "bstr",
-                        "pkg": "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep_matcher",
-                        "pkg": "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "log",
-                        "pkg": "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex_syntax",
-                        "pkg": "regex-syntax 0.6.29 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "thread_local",
-                        "pkg": "thread_local 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "grep-searcher 0.1.11 (path+file:///$ROOT$ripgrep/crates/searcher)",
-                "dependencies": [
-                    "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "bytecount 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "encoding_rs 0.8.32 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "encoding_rs_io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                    "grep-regex 0.1.11 (path+file:///$ROOT$ripgrep/crates/regex)",
-                    "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "memmap2 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "bstr",
-                        "pkg": "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "bytecount",
-                        "pkg": "bytecount 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "encoding_rs",
-                        "pkg": "encoding_rs 0.8.32 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "encoding_rs_io",
-                        "pkg": "encoding_rs_io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep_matcher",
-                        "pkg": "grep-matcher 0.1.6 (path+file:///$ROOT$ripgrep/crates/matcher)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep_regex",
-                        "pkg": "grep-regex 0.1.11 (path+file:///$ROOT$ripgrep/crates/regex)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "log",
-                        "pkg": "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "memmap",
-                        "pkg": "memmap2 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default"
-                ]
-            },
-            {
-                "id": "hermit-abi 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default"
-                ]
-            },
-            {
-                "id": "ignore 0.4.20 (path+file:///$ROOT$ripgrep/crates/ignore)",
-                "dependencies": [
-                    "crossbeam-channel 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "globset 0.4.10 (path+file:///$ROOT$ripgrep/crates/globset)",
-                    "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "thread_local 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "walkdir 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "crossbeam_channel",
-                        "pkg": "crossbeam-channel 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "globset",
-                        "pkg": "globset 0.4.10 (path+file:///$ROOT$ripgrep/crates/globset)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "lazy_static",
-                        "pkg": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "log",
-                        "pkg": "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "memchr",
-                        "pkg": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "same_file",
-                        "pkg": "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "thread_local",
-                        "pkg": "thread_local 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "walkdir",
-                        "pkg": "walkdir 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "winapi_util",
-                        "pkg": "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(windows)"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "itoa 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "jemalloc-sys 0.5.3+5.3.0-patched (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "cc 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "cc",
-                        "pkg": "cc 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "build",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "background_threads_runtime_support"
-                ]
-            },
-            {
-                "id": "jemallocator 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "jemalloc-sys 0.5.3+5.3.0-patched (registry+https://github.com/rust-lang/crates.io-index)",
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "jemalloc_sys",
-                        "pkg": "jemalloc-sys 0.5.3+5.3.0-patched (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "background_threads_runtime_support",
-                    "default"
-                ]
-            },
-            {
-                "id": "jobserver 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(unix)"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default",
-                    "std"
-                ]
-            },
-            {
-                "id": "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "cfg_if",
-                        "pkg": "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default",
-                    "std"
-                ]
-            },
-            {
-                "id": "memmap2 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(unix)"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "once_cell 1.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "alloc",
-                    "default",
-                    "race",
-                    "std"
-                ]
-            },
-            {
-                "id": "pcre2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "pcre2-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "thread_local 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "log",
-                        "pkg": "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "pcre2_sys",
-                        "pkg": "pcre2-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "thread_local",
-                        "pkg": "thread_local 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "pcre2-sys 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "cc 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "pkg-config 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "cc",
-                        "pkg": "cc 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "build",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "libc",
-                        "pkg": "libc 0.2.142 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "pkg_config",
-                        "pkg": "pkg-config 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "build",
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "pkg-config 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "unicode_ident",
-                        "pkg": "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default",
-                    "proc-macro"
-                ]
-            },
-            {
-                "id": "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "proc_macro2",
-                        "pkg": "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default",
-                    "proc-macro"
-                ]
-            },
-            {
-                "id": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "aho-corasick 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex-syntax 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "aho_corasick",
-                        "pkg": "aho-corasick 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "memchr",
-                        "pkg": "memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex_syntax",
-                        "pkg": "regex-syntax 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "aho-corasick",
-                    "default",
-                    "memchr",
-                    "perf",
-                    "perf-cache",
-                    "perf-dfa",
-                    "perf-inline",
-                    "perf-literal",
-                    "std",
-                    "unicode",
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ]
-            },
-            {
-                "id": "regex-automata 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "regex-syntax 0.6.29 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default",
-                    "unicode",
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ]
-            },
-            {
-                "id": "regex-syntax 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default",
-                    "std",
-                    "unicode",
-                    "unicode-age",
-                    "unicode-bool",
-                    "unicode-case",
-                    "unicode-gencat",
-                    "unicode-perl",
-                    "unicode-script",
-                    "unicode-segment"
-                ]
-            },
-            {
-                "id": "ripgrep 13.0.0 (path+file:///$ROOT$ripgrep)",
-                "dependencies": [
-                    "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "clap 2.34.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "grep 0.2.11 (path+file:///$ROOT$ripgrep/crates/grep)",
-                    "ignore 0.4.20 (path+file:///$ROOT$ripgrep/crates/ignore)",
-                    "jemallocator 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "serde_derive 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "serde_json 1.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "termcolor 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "walkdir 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "bstr",
-                        "pkg": "bstr 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "clap",
-                        "pkg": "clap 2.34.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            },
-                            {
-                                "kind": "build",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "grep",
-                        "pkg": "grep 0.2.11 (path+file:///$ROOT$ripgrep/crates/grep)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "ignore",
-                        "pkg": "ignore 0.4.20 (path+file:///$ROOT$ripgrep/crates/ignore)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "jemallocator",
-                        "pkg": "jemallocator 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(all(target_env = \"musl\", target_pointer_width = \"64\"))"
-                            }
-                        ]
-                    },
-                    {
-                        "name": "lazy_static",
-                        "pkg": "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            },
-                            {
-                                "kind": "build",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "log",
-                        "pkg": "log 0.4.17 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "regex",
-                        "pkg": "regex 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde",
-                        "pkg": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde_derive",
-                        "pkg": "serde_derive 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde_json",
-                        "pkg": "serde_json 1.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "termcolor",
-                        "pkg": "termcolor 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "walkdir",
-                        "pkg": "walkdir 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": "dev",
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "ryu 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "winapi_util",
-                        "pkg": "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(windows)"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "serde_derive 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "serde_derive",
-                        "pkg": "serde_derive 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "alloc",
-                    "default",
-                    "derive",
-                    "serde_derive",
-                    "std"
-                ]
-            },
-            {
-                "id": "serde_derive 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "syn 2.0.15 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "proc_macro2",
-                        "pkg": "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "quote",
-                        "pkg": "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "syn",
-                        "pkg": "syn 2.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default"
-                ]
-            },
-            {
-                "id": "serde_json 1.0.96 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "itoa 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "ryu 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "itoa",
-                        "pkg": "itoa 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "ryu",
-                        "pkg": "ryu 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "serde",
-                        "pkg": "serde 1.0.160 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "default",
-                    "std"
-                ]
-            },
-            {
-                "id": "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "syn 2.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "proc_macro2",
-                        "pkg": "proc-macro2 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "quote",
-                        "pkg": "quote 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "unicode_ident",
-                        "pkg": "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "clone-impls",
-                    "default",
-                    "derive",
-                    "parsing",
-                    "printing",
-                    "proc-macro",
-                    "quote"
-                ]
-            },
-            {
-                "id": "termcolor 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "winapi_util",
-                        "pkg": "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(windows)"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "unicode-width 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "unicode_width",
-                        "pkg": "unicode-width 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "thread_local 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "once_cell 1.17.1 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "cfg_if",
-                        "pkg": "cfg-if 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "once_cell",
-                        "pkg": "once_cell 1.17.1 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "unicode-ident 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "unicode-width 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": [
-                    "default"
-                ]
-            },
-            {
-                "id": "walkdir 2.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "same_file",
-                        "pkg": "same-file 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": null
-                            }
-                        ]
-                    },
-                    {
-                        "name": "winapi_util",
-                        "pkg": "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(windows)"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                    "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "winapi_i686_pc_windows_gnu",
-                        "pkg": "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "i686-pc-windows-gnu"
-                            }
-                        ]
-                    },
-                    {
-                        "name": "winapi_x86_64_pc_windows_gnu",
-                        "pkg": "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "x86_64-pc-windows-gnu"
-                            }
-                        ]
-                    }
-                ],
-                "features": [
-                    "consoleapi",
-                    "errhandlingapi",
-                    "fileapi",
-                    "minwinbase",
-                    "minwindef",
-                    "processenv",
-                    "std",
-                    "winbase",
-                    "wincon",
-                    "winerror",
-                    "winnt"
-                ]
-            },
-            {
-                "id": "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            },
-            {
-                "id": "winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [
-                    "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)"
-                ],
-                "deps": [
-                    {
-                        "name": "winapi",
-                        "pkg": "winapi 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
-                        "dep_kinds": [
-                            {
-                                "kind": null,
-                                "target": "cfg(windows)"
-                            }
-                        ]
-                    }
-                ],
-                "features": []
-            },
-            {
-                "id": "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
-                "dependencies": [],
-                "deps": [],
-                "features": []
-            }
-        ],
-        "root": "ripgrep 13.0.0 (path+file:///$ROOT$ripgrep)"
-    },
-    "target_directory": "$ROOT$ripgrep/target",
-    "version": 1,
-    "workspace_root": "$ROOT$ripgrep",
-    "metadata": null
-}
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 21b481c..41b4257 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -82,6 +82,7 @@
         flags::RustAnalyzerCmd::Highlight(cmd) => cmd.run()?,
         flags::RustAnalyzerCmd::AnalysisStats(cmd) => cmd.run(verbosity)?,
         flags::RustAnalyzerCmd::Diagnostics(cmd) => cmd.run()?,
+        flags::RustAnalyzerCmd::UnresolvedReferences(cmd) => cmd.run()?,
         flags::RustAnalyzerCmd::Ssr(cmd) => cmd.run()?,
         flags::RustAnalyzerCmd::Search(cmd) => cmd.run()?,
         flags::RustAnalyzerCmd::Lsif(cmd) => cmd.run()?,
diff --git a/crates/rust-analyzer/src/cli.rs b/crates/rust-analyzer/src/cli.rs
index 5eb6ff6..a7ec5af 100644
--- a/crates/rust-analyzer/src/cli.rs
+++ b/crates/rust-analyzer/src/cli.rs
@@ -13,6 +13,7 @@
 mod scip;
 mod ssr;
 mod symbols;
+mod unresolved_references;
 
 mod progress_report;
 
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 44e5664..e899e0e 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -64,6 +64,7 @@
                 true => None,
                 false => Some(RustLibSource::Discover),
             },
+            all_targets: true,
             ..Default::default()
         };
         let no_progress = &|_| ();
@@ -77,7 +78,11 @@
         let metadata_time = db_load_sw.elapsed();
         let load_cargo_config = LoadCargoConfig {
             load_out_dirs_from_check: !self.disable_build_scripts,
-            with_proc_macro_server: ProcMacroServerChoice::Sysroot,
+            with_proc_macro_server: if self.disable_proc_macros {
+                ProcMacroServerChoice::None
+            } else {
+                ProcMacroServerChoice::Sysroot
+            },
             prefill_caches: false,
         };
 
@@ -339,6 +344,7 @@
                 true => None,
                 false => Some(RustLibSource::Discover),
             },
+            all_targets: true,
             ..Default::default()
         };
 
diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs
index cdac0e5..28f2597 100644
--- a/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -24,8 +24,11 @@
         handle.join()
     }
     fn run_(self) -> anyhow::Result<()> {
-        let cargo_config =
-            CargoConfig { sysroot: Some(RustLibSource::Discover), ..Default::default() };
+        let cargo_config = CargoConfig {
+            sysroot: Some(RustLibSource::Discover),
+            all_targets: true,
+            ..Default::default()
+        };
         let with_proc_macro_server = if let Some(p) = &self.proc_macro_srv {
             let path = vfs::AbsPathBuf::assert_utf8(std::env::current_dir()?.join(p));
             ProcMacroServerChoice::Explicit(path)
diff --git a/crates/rust-analyzer/src/cli/flags.rs b/crates/rust-analyzer/src/cli/flags.rs
index 16d90de..73e7165 100644
--- a/crates/rust-analyzer/src/cli/flags.rs
+++ b/crates/rust-analyzer/src/cli/flags.rs
@@ -124,6 +124,19 @@
             optional --proc-macro-srv path: PathBuf
         }
 
+        /// Report unresolved references
+        cmd unresolved-references {
+            /// Directory with Cargo.toml.
+            required path: PathBuf
+
+            /// Don't run build scripts or load `OUT_DIR` values by running `cargo check` before analysis.
+            optional --disable-build-scripts
+            /// Don't use expand proc macros.
+            optional --disable-proc-macros
+            /// Run a custom proc-macro-srv binary.
+            optional --proc-macro-srv path: PathBuf
+        }
+
         cmd ssr {
             /// A structured search replace rule (`$a.foo($b) ==>> bar($a, $b)`)
             repeated rule: SsrRule
@@ -181,6 +194,7 @@
     RunTests(RunTests),
     RustcTests(RustcTests),
     Diagnostics(Diagnostics),
+    UnresolvedReferences(UnresolvedReferences),
     Ssr(Ssr),
     Search(Search),
     Lsif(Lsif),
@@ -251,6 +265,15 @@
 }
 
 #[derive(Debug)]
+pub struct UnresolvedReferences {
+    pub path: PathBuf,
+
+    pub disable_build_scripts: bool,
+    pub disable_proc_macros: bool,
+    pub proc_macro_srv: Option<PathBuf>,
+}
+
+#[derive(Debug)]
 pub struct Ssr {
     pub rule: Vec<SsrRule>,
 }
diff --git a/crates/rust-analyzer/src/cli/lsif.rs b/crates/rust-analyzer/src/cli/lsif.rs
index 89fe712..e4263a3 100644
--- a/crates/rust-analyzer/src/cli/lsif.rs
+++ b/crates/rust-analyzer/src/cli/lsif.rs
@@ -273,10 +273,12 @@
 
 impl flags::Lsif {
     pub fn run(self) -> anyhow::Result<()> {
-        eprintln!("Generating LSIF started...");
         let now = Instant::now();
-        let cargo_config =
-            &CargoConfig { sysroot: Some(RustLibSource::Discover), ..Default::default() };
+        let cargo_config = &CargoConfig {
+            sysroot: Some(RustLibSource::Discover),
+            all_targets: true,
+            ..Default::default()
+        };
         let no_progress = &|_| ();
         let load_cargo_config = LoadCargoConfig {
             load_out_dirs_from_check: true,
@@ -285,6 +287,7 @@
         };
         let path = AbsPathBuf::assert_utf8(env::current_dir()?.join(self.path));
         let root = ProjectManifest::discover_single(&path)?;
+        eprintln!("Generating LSIF for project at {root}");
         let mut workspace = ProjectWorkspace::load(root, cargo_config, no_progress)?;
 
         let build_scripts = workspace.run_build_scripts(cargo_config, no_progress)?;
diff --git a/crates/rust-analyzer/src/cli/run_tests.rs b/crates/rust-analyzer/src/cli/run_tests.rs
index 157ef43..f90ebcf 100644
--- a/crates/rust-analyzer/src/cli/run_tests.rs
+++ b/crates/rust-analyzer/src/cli/run_tests.rs
@@ -13,8 +13,11 @@
 
 impl flags::RunTests {
     pub fn run(self) -> Result<()> {
-        let cargo_config =
-            CargoConfig { sysroot: Some(RustLibSource::Discover), ..Default::default() };
+        let cargo_config = CargoConfig {
+            sysroot: Some(RustLibSource::Discover),
+            all_targets: true,
+            ..Default::default()
+        };
         let load_cargo_config = LoadCargoConfig {
             load_out_dirs_from_check: true,
             with_proc_macro_server: ProcMacroServerChoice::Sysroot,
diff --git a/crates/rust-analyzer/src/cli/rustc_tests.rs b/crates/rust-analyzer/src/cli/rustc_tests.rs
index 75efdfd..730f3c0 100644
--- a/crates/rust-analyzer/src/cli/rustc_tests.rs
+++ b/crates/rust-analyzer/src/cli/rustc_tests.rs
@@ -67,8 +67,11 @@
         path.push("ra-rustc-test.rs");
         let tmp_file = AbsPathBuf::try_from(Utf8PathBuf::from_path_buf(path).unwrap()).unwrap();
         std::fs::write(&tmp_file, "")?;
-        let cargo_config =
-            CargoConfig { sysroot: Some(RustLibSource::Discover), ..Default::default() };
+        let cargo_config = CargoConfig {
+            sysroot: Some(RustLibSource::Discover),
+            all_targets: true,
+            ..Default::default()
+        };
 
         let sysroot = Sysroot::discover(tmp_file.parent().unwrap(), &cargo_config.extra_env);
         let data_layout = target_data_layout::get(
diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs
index ceb8534..e919897 100644
--- a/crates/rust-analyzer/src/cli/scip.rs
+++ b/crates/rust-analyzer/src/cli/scip.rs
@@ -51,7 +51,7 @@
             // FIXME @alibektas : What happens to errors without logging?
             error!(?error_sink, "Config Error(s)");
         }
-        let cargo_config = config.cargo();
+        let cargo_config = config.cargo(None);
         let (db, vfs, _) = load_workspace_at(
             root.as_path().as_ref(),
             &cargo_config,
@@ -142,7 +142,7 @@
                 let mut symbol_roles = Default::default();
 
                 if let Some(def) = token.definition {
-                    // if the the range of the def and the range of the token are the same, this must be the definition.
+                    // if the range of the def and the range of the token are the same, this must be the definition.
                     // they also must be in the same file. See https://github.com/rust-lang/rust-analyzer/pull/17988
                     if def.file_id == file_id && def.range == text_range {
                         symbol_roles |= scip_types::SymbolRole::Definition as i32;
diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs
index 3caa487..bdca800 100644
--- a/crates/rust-analyzer/src/cli/ssr.rs
+++ b/crates/rust-analyzer/src/cli/ssr.rs
@@ -10,8 +10,11 @@
 
 impl flags::Ssr {
     pub fn run(self) -> anyhow::Result<()> {
-        let cargo_config =
-            CargoConfig { sysroot: Some(RustLibSource::Discover), ..Default::default() };
+        let cargo_config = CargoConfig {
+            sysroot: Some(RustLibSource::Discover),
+            all_targets: true,
+            ..Default::default()
+        };
         let load_cargo_config = LoadCargoConfig {
             load_out_dirs_from_check: true,
             with_proc_macro_server: ProcMacroServerChoice::Sysroot,
diff --git a/crates/rust-analyzer/src/cli/unresolved_references.rs b/crates/rust-analyzer/src/cli/unresolved_references.rs
new file mode 100644
index 0000000..986bd01
--- /dev/null
+++ b/crates/rust-analyzer/src/cli/unresolved_references.rs
@@ -0,0 +1,175 @@
+//! Reports references in code that the IDE layer cannot resolve.
+use hir::{db::HirDatabase, AnyDiagnostic, Crate, HirFileIdExt as _, Module, Semantics};
+use ide::{AnalysisHost, RootDatabase, TextRange};
+use ide_db::{
+    base_db::{SourceDatabase, SourceRootDatabase},
+    defs::NameRefClass,
+    EditionedFileId, FxHashSet, LineIndexDatabase as _,
+};
+use load_cargo::{load_workspace_at, LoadCargoConfig, ProcMacroServerChoice};
+use parser::SyntaxKind;
+use syntax::{ast, AstNode, WalkEvent};
+use vfs::FileId;
+
+use crate::cli::flags;
+
+impl flags::UnresolvedReferences {
+    pub fn run(self) -> anyhow::Result<()> {
+        const STACK_SIZE: usize = 1024 * 1024 * 8;
+
+        let handle = stdx::thread::Builder::new(stdx::thread::ThreadIntent::LatencySensitive)
+            .name("BIG_STACK_THREAD".into())
+            .stack_size(STACK_SIZE)
+            .spawn(|| self.run_())
+            .unwrap();
+
+        handle.join()
+    }
+
+    fn run_(self) -> anyhow::Result<()> {
+        let root =
+            vfs::AbsPathBuf::assert_utf8(std::env::current_dir()?.join(&self.path)).normalize();
+        let config = crate::config::Config::new(
+            root.clone(),
+            lsp_types::ClientCapabilities::default(),
+            vec![],
+            None,
+        );
+        let cargo_config = config.cargo(None);
+        let with_proc_macro_server = if let Some(p) = &self.proc_macro_srv {
+            let path = vfs::AbsPathBuf::assert_utf8(std::env::current_dir()?.join(p));
+            ProcMacroServerChoice::Explicit(path)
+        } else {
+            ProcMacroServerChoice::Sysroot
+        };
+        let load_cargo_config = LoadCargoConfig {
+            load_out_dirs_from_check: !self.disable_build_scripts,
+            with_proc_macro_server,
+            prefill_caches: false,
+        };
+        let (db, vfs, _proc_macro) =
+            load_workspace_at(&self.path, &cargo_config, &load_cargo_config, &|_| {})?;
+        let host = AnalysisHost::with_database(db);
+        let db = host.raw_database();
+        let sema = Semantics::new(db);
+
+        let mut visited_files = FxHashSet::default();
+
+        let work = all_modules(db).into_iter().filter(|module| {
+            let file_id = module.definition_source_file_id(db).original_file(db);
+            let source_root = db.file_source_root(file_id.into());
+            let source_root = db.source_root(source_root);
+            !source_root.is_library
+        });
+
+        for module in work {
+            let file_id = module.definition_source_file_id(db).original_file(db);
+            if !visited_files.contains(&file_id) {
+                let crate_name =
+                    module.krate().display_name(db).as_deref().unwrap_or("unknown").to_owned();
+                let file_path = vfs.file_path(file_id.into());
+                eprintln!("processing crate: {crate_name}, module: {file_path}",);
+
+                let line_index = db.line_index(file_id.into());
+                let file_text = db.file_text(file_id.into());
+
+                for range in find_unresolved_references(db, &sema, file_id.into(), &module) {
+                    let line_col = line_index.line_col(range.start());
+                    let line = line_col.line + 1;
+                    let col = line_col.col + 1;
+                    let text = &file_text[range];
+                    println!("{file_path}:{line}:{col}: {text}");
+                }
+
+                visited_files.insert(file_id);
+            }
+        }
+
+        eprintln!();
+        eprintln!("scan complete");
+
+        Ok(())
+    }
+}
+
+fn all_modules(db: &dyn HirDatabase) -> Vec<Module> {
+    let mut worklist: Vec<_> =
+        Crate::all(db).into_iter().map(|krate| krate.root_module()).collect();
+    let mut modules = Vec::new();
+
+    while let Some(module) = worklist.pop() {
+        modules.push(module);
+        worklist.extend(module.children(db));
+    }
+
+    modules
+}
+
+fn find_unresolved_references(
+    db: &RootDatabase,
+    sema: &Semantics<'_, RootDatabase>,
+    file_id: FileId,
+    module: &Module,
+) -> Vec<TextRange> {
+    let mut unresolved_references = all_unresolved_references(sema, file_id);
+
+    // remove unresolved references which are within inactive code
+    let mut diagnostics = Vec::new();
+    module.diagnostics(db, &mut diagnostics, false);
+    for diagnostic in diagnostics {
+        let AnyDiagnostic::InactiveCode(inactive_code) = diagnostic else {
+            continue;
+        };
+
+        let node = inactive_code.node;
+        let range = node.map(|it| it.text_range()).original_node_file_range_rooted(db);
+
+        if range.file_id != file_id {
+            continue;
+        }
+
+        unresolved_references.retain(|r| !range.range.contains_range(*r));
+    }
+
+    unresolved_references
+}
+
+fn all_unresolved_references(
+    sema: &Semantics<'_, RootDatabase>,
+    file_id: FileId,
+) -> Vec<TextRange> {
+    let file_id = sema
+        .attach_first_edition(file_id)
+        .unwrap_or_else(|| EditionedFileId::current_edition(file_id));
+    let file = sema.parse(file_id);
+    let root = file.syntax();
+
+    let mut unresolved_references = Vec::new();
+    for event in root.preorder() {
+        let WalkEvent::Enter(syntax) = event else {
+            continue;
+        };
+        let Some(name_ref) = ast::NameRef::cast(syntax) else {
+            continue;
+        };
+        let Some(descended_name_ref) = name_ref.syntax().first_token().and_then(|tok| {
+            sema.descend_into_macros_single_exact(tok).parent().and_then(ast::NameRef::cast)
+        }) else {
+            continue;
+        };
+
+        // if we can classify the name_ref, it's not unresolved
+        if NameRefClass::classify(sema, &descended_name_ref).is_some() {
+            continue;
+        }
+
+        // if we couldn't classify it, but it's in an attr, ignore it. See #10935
+        if descended_name_ref.syntax().ancestors().any(|it| it.kind() == SyntaxKind::ATTR) {
+            continue;
+        }
+
+        // otherwise, it's unresolved
+        unresolved_references.push(name_ref.syntax().text_range());
+    }
+    unresolved_references
+}
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 2889af8..4cc6069 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -24,7 +24,8 @@
 use itertools::Itertools;
 use paths::{Utf8Path, Utf8PathBuf};
 use project_model::{
-    CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectManifest, RustLibSource,
+    CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectJsonFromCommand,
+    ProjectManifest, RustLibSource,
 };
 use rustc_hash::{FxHashMap, FxHashSet};
 use semver::Version;
@@ -59,15 +60,13 @@
 // However, editor specific config, which the server doesn't know about, should
 // be specified directly in `package.json`.
 //
-// To deprecate an option by replacing it with another name use `new_name | `old_name` so that we keep
+// To deprecate an option by replacing it with another name use `new_name` | `old_name` so that we keep
 // parsing the old name.
 config_data! {
-    /// Configs that apply on a workspace-wide scope. There are 3 levels on which a global configuration can be configured
-    // FIXME: 1. and 3. should be split, some configs do not make sense per project
+    /// Configs that apply on a workspace-wide scope. There are 2 levels on which a global configuration can be configured
     ///
-    /// 1. `rust-analyzer.toml` file under user's config directory (e.g ~/.config/rust-analyzer.toml)
+    /// 1. `rust-analyzer.toml` file under user's config directory (e.g ~/.config/rust-analyzer/rust-analyzer.toml)
     /// 2. Client's own configurations (e.g `settings.json` on VS Code)
-    /// 3. `rust-analyzer.toml` file located at the workspace root
     ///
     /// A config is searched for by traversing a "config tree" in a bottom up fashion. It is chosen by the nearest first principle.
     global: struct GlobalDefaultConfigData <- GlobalConfigInput -> {
@@ -76,178 +75,9 @@
         /// How many worker threads to handle priming caches. The default `0` means to pick automatically.
         cachePriming_numThreads: NumThreads = NumThreads::Physical,
 
-        /// Pass `--all-targets` to cargo invocation.
-        cargo_allTargets: bool           = true,
-        /// Automatically refresh project info via `cargo metadata` on
-        /// `Cargo.toml` or `.cargo/config.toml` changes.
-        pub(crate) cargo_autoreload: bool           = true,
-        /// Run build scripts (`build.rs`) for more precise code analysis.
-        cargo_buildScripts_enable: bool  = true,
-        /// Specifies the invocation strategy to use when running the build scripts command.
-        /// If `per_workspace` is set, the command will be executed for each Rust workspace with the
-        /// workspace as the working directory.
-        /// If `once` is set, the command will be executed once with the opened project as the
-        /// working directory.
-        /// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
-        /// is set.
-        cargo_buildScripts_invocationStrategy: InvocationStrategy = InvocationStrategy::PerWorkspace,
-        /// Override the command rust-analyzer uses to run build scripts and
-        /// build procedural macros. The command is required to output json
-        /// and should therefore include `--message-format=json` or a similar
-        /// option.
-        ///
-        /// If there are multiple linked projects/workspaces, this command is invoked for
-        /// each of them, with the working directory being the workspace root
-        /// (i.e., the folder containing the `Cargo.toml`). This can be overwritten
-        /// by changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#`.
-        ///
-        /// By default, a cargo invocation will be constructed for the configured
-        /// targets and features, with the following base command line:
-        ///
-        /// ```bash
-        /// cargo check --quiet --workspace --message-format=json --all-targets --keep-going
-        /// ```
-        /// .
-        cargo_buildScripts_overrideCommand: Option<Vec<String>> = None,
-        /// Rerun proc-macros building/build-scripts running when proc-macro
-        /// or build-script sources change and are saved.
-        cargo_buildScripts_rebuildOnSave: bool = true,
-        /// Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to
-        /// avoid checking unnecessary things.
-        cargo_buildScripts_useRustcWrapper: bool = true,
-        /// List of cfg options to enable with the given values.
-        cargo_cfgs: FxHashMap<String, Option<String>> = {
-            let mut m = FxHashMap::default();
-            m.insert("debug_assertions".to_owned(), None);
-            m.insert("miri".to_owned(), None);
-            m
-        },
-        /// Extra arguments that are passed to every cargo invocation.
-        cargo_extraArgs: Vec<String> = vec![],
-        /// Extra environment variables that will be set when running cargo, rustc
-        /// or other commands within the workspace. Useful for setting RUSTFLAGS.
-        cargo_extraEnv: FxHashMap<String, String> = FxHashMap::default(),
-        /// List of features to activate.
-        ///
-        /// Set this to `"all"` to pass `--all-features` to cargo.
-        cargo_features: CargoFeaturesDef      = CargoFeaturesDef::Selected(vec![]),
-        /// Whether to pass `--no-default-features` to cargo.
-        cargo_noDefaultFeatures: bool    = false,
-        /// Relative path to the sysroot, or "discover" to try to automatically find it via
-        /// "rustc --print sysroot".
-        ///
-        /// Unsetting this disables sysroot loading.
-        ///
-        /// This option does not take effect until rust-analyzer is restarted.
-        cargo_sysroot: Option<String>    = Some("discover".to_owned()),
-        /// Relative path to the sysroot library sources. If left unset, this will default to
-        /// `{cargo.sysroot}/lib/rustlib/src/rust/library`.
-        ///
-        /// This option does not take effect until rust-analyzer is restarted.
-        cargo_sysrootSrc: Option<String>    = None,
-        /// Compilation target override (target triple).
-        // FIXME(@poliorcetics): move to multiple targets here too, but this will need more work
-        // than `checkOnSave_target`
-        cargo_target: Option<String>     = None,
-        /// Optional path to a rust-analyzer specific target directory.
-        /// This prevents rust-analyzer's `cargo check` and initial build-script and proc-macro
-        /// building from locking the `Cargo.lock` at the expense of duplicating build artifacts.
-        ///
-        /// Set to `true` to use a subdirectory of the existing target directory or
-        /// set to a path relative to the workspace to use that path.
-        cargo_targetDir | rust_analyzerTargetDir: Option<TargetDirectory> = None,
+        /// Custom completion snippets.
+        completion_snippets_custom: FxHashMap<String, SnippetDef> = Config::completion_snippets_default(),
 
-        /// Run the check command for diagnostics on save.
-        checkOnSave | checkOnSave_enable: bool                         = true,
-
-        /// Check all targets and tests (`--all-targets`). Defaults to
-        /// `#rust-analyzer.cargo.allTargets#`.
-        check_allTargets | checkOnSave_allTargets: Option<bool>          = None,
-        /// Cargo command to use for `cargo check`.
-        check_command | checkOnSave_command: String                      = "check".to_owned(),
-        /// Extra arguments for `cargo check`.
-        check_extraArgs | checkOnSave_extraArgs: Vec<String>             = vec![],
-        /// Extra environment variables that will be set when running `cargo check`.
-        /// Extends `#rust-analyzer.cargo.extraEnv#`.
-        check_extraEnv | checkOnSave_extraEnv: FxHashMap<String, String> = FxHashMap::default(),
-        /// List of features to activate. Defaults to
-        /// `#rust-analyzer.cargo.features#`.
-        ///
-        /// Set to `"all"` to pass `--all-features` to Cargo.
-        check_features | checkOnSave_features: Option<CargoFeaturesDef>  = None,
-        /// List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore.
-        ///
-        /// For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,...
-        check_ignore: FxHashSet<String> = FxHashSet::default(),
-        /// Specifies the invocation strategy to use when running the check command.
-        /// If `per_workspace` is set, the command will be executed for each workspace.
-        /// If `once` is set, the command will be executed once.
-        /// This config only has an effect when `#rust-analyzer.check.overrideCommand#`
-        /// is set.
-        check_invocationStrategy | checkOnSave_invocationStrategy: InvocationStrategy = InvocationStrategy::PerWorkspace,
-        /// Whether to pass `--no-default-features` to Cargo. Defaults to
-        /// `#rust-analyzer.cargo.noDefaultFeatures#`.
-        check_noDefaultFeatures | checkOnSave_noDefaultFeatures: Option<bool>         = None,
-        /// Override the command rust-analyzer uses instead of `cargo check` for
-        /// diagnostics on save. The command is required to output json and
-        /// should therefore include `--message-format=json` or a similar option
-        /// (if your client supports the `colorDiagnosticOutput` experimental
-        /// capability, you can use `--message-format=json-diagnostic-rendered-ansi`).
-        ///
-        /// If you're changing this because you're using some tool wrapping
-        /// Cargo, you might also want to change
-        /// `#rust-analyzer.cargo.buildScripts.overrideCommand#`.
-        ///
-        /// If there are multiple linked projects/workspaces, this command is invoked for
-        /// each of them, with the working directory being the workspace root
-        /// (i.e., the folder containing the `Cargo.toml`). This can be overwritten
-        /// by changing `#rust-analyzer.check.invocationStrategy#`.
-        ///
-        /// If `$saved_file` is part of the command, rust-analyzer will pass
-        /// the absolute path of the saved file to the provided command. This is
-        /// intended to be used with non-Cargo build systems.
-        /// Note that `$saved_file` is experimental and may be removed in the future.
-        ///
-        /// An example command would be:
-        ///
-        /// ```bash
-        /// cargo check --workspace --message-format=json --all-targets
-        /// ```
-        /// .
-        check_overrideCommand | checkOnSave_overrideCommand: Option<Vec<String>>             = None,
-        /// Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty.
-        ///
-        /// Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets, e.g.
-        /// `["aarch64-apple-darwin", "x86_64-apple-darwin"]`.
-        ///
-        /// Aliased as `"checkOnSave.targets"`.
-        check_targets | checkOnSave_targets | checkOnSave_target: Option<CheckOnSaveTargets> = None,
-        /// Whether `--workspace` should be passed to `cargo check`.
-        /// If false, `-p <package>` will be passed instead.
-        check_workspace: bool = true,
-
-        /// List of rust-analyzer diagnostics to disable.
-        diagnostics_disabled: FxHashSet<String> = FxHashSet::default(),
-        /// Whether to show native rust-analyzer diagnostics.
-        diagnostics_enable: bool                = true,
-        /// Whether to show experimental rust-analyzer diagnostics that might
-        /// have more false positives than usual.
-        diagnostics_experimental_enable: bool    = false,
-        /// Map of prefixes to be substituted when parsing diagnostic file paths.
-        /// This should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`.
-        diagnostics_remapPrefix: FxHashMap<String, String> = FxHashMap::default(),
-        /// Whether to run additional style lints.
-        diagnostics_styleLints_enable: bool =    false,
-        /// List of warnings that should be displayed with hint severity.
-        ///
-        /// The warnings will be indicated by faded text or three dots in code
-        /// and will not show up in the `Problems Panel`.
-        diagnostics_warningsAsHint: Vec<String> = vec![],
-        /// List of warnings that should be displayed with info severity.
-        ///
-        /// The warnings will be indicated by a blue squiggly underline in code
-        /// and a blue icon in the `Problems Panel`.
-        diagnostics_warningsAsInfo: Vec<String> = vec![],
 
         /// These directories will be ignored by rust-analyzer. They are
         /// relative to the workspace root, and globs are not supported. You may
@@ -255,266 +85,6 @@
         files_excludeDirs: Vec<Utf8PathBuf> = vec![],
 
 
-        /// Disable project auto-discovery in favor of explicitly specified set
-        /// of projects.
-        ///
-        /// Elements must be paths pointing to `Cargo.toml`,
-        /// `rust-project.json`, `.rs` files (which will be treated as standalone files) or JSON
-        /// objects in `rust-project.json` format.
-        linkedProjects: Vec<ManifestOrProjectJson> = vec![],
-
-        /// Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.
-        lru_capacity: Option<u16>                 = None,
-        /// Sets the LRU capacity of the specified queries.
-        lru_query_capacities: FxHashMap<Box<str>, u16> = FxHashMap::default(),
-
-        /// These proc-macros will be ignored when trying to expand them.
-        ///
-        /// This config takes a map of crate names with the exported proc-macro names to ignore as values.
-        procMacro_ignored: FxHashMap<Box<str>, Box<[Box<str>]>>          = FxHashMap::default(),
-
-        /// Command to be executed instead of 'cargo' for runnables.
-        runnables_command: Option<String> = None,
-        /// Additional arguments to be passed to cargo for runnables such as
-        /// tests or binaries. For example, it may be `--release`.
-        runnables_extraArgs: Vec<String>   = vec![],
-        /// Additional arguments to be passed through Cargo to launched tests, benchmarks, or
-        /// doc-tests.
-        ///
-        /// Unless the launched target uses a
-        /// [custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field),
-        /// they will end up being interpreted as options to
-        /// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).
-        runnables_extraTestBinaryArgs: Vec<String> = vec!["--show-output".to_owned()],
-
-        /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
-        /// projects, or "discover" to try to automatically find it if the `rustc-dev` component
-        /// is installed.
-        ///
-        /// Any project which uses rust-analyzer with the rustcPrivate
-        /// crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it.
-        ///
-        /// This option does not take effect until rust-analyzer is restarted.
-        rustc_source: Option<String> = None,
-
-
-        /// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].
-        ///
-        /// [`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`.
-        /// `progress_label` is used for the title in progress indicators, whereas `files_to_watch`
-        /// is used to determine which build system-specific files should be watched in order to
-        /// reload rust-analyzer.
-        ///
-        /// Below is an example of a valid configuration:
-        /// ```json
-        /// "rust-analyzer.workspace.discoverConfig": {
-        ///     "command": [
-        ///         "rust-project",
-        ///         "develop-json"
-        ///     ],
-        ///     "progressLabel": "rust-analyzer",
-        ///     "filesToWatch": [
-        ///         "BUCK"
-        ///     ]
-        /// }
-        /// ```
-        ///
-        /// ## On `DiscoverWorkspaceConfig::command`
-        ///
-        /// **Warning**: This format is provisional and subject to change.
-        ///
-        /// [`DiscoverWorkspaceConfig::command`] *must* return a JSON object
-        /// corresponding to `DiscoverProjectData::Finished`:
-        ///
-        /// ```norun
-        /// #[derive(Debug, Clone, Deserialize, Serialize)]
-        /// #[serde(tag = "kind")]
-        /// #[serde(rename_all = "snake_case")]
-        /// enum DiscoverProjectData {
-        ///     Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },
-        ///     Error { error: String, source: Option<String> },
-        ///     Progress { message: String },
-        /// }
-        /// ```
-        ///
-        /// As JSON, `DiscoverProjectData::Finished` is:
-        ///
-        /// ```json
-        /// {
-        ///     // the internally-tagged representation of the enum.
-        ///     "kind": "finished",
-        ///     // the file used by a non-Cargo build system to define
-        ///     // a package or target.
-        ///     "buildfile": "rust-analyzer/BUILD",
-        ///     // the contents of a rust-project.json, elided for brevity
-        ///     "project": {
-        ///         "sysroot": "foo",
-        ///         "crates": []
-        ///     }
-        /// }
-        /// ```
-        ///
-        /// It is encouraged, but not required, to use the other variants on
-        /// `DiscoverProjectData` to provide a more polished end-user experience.
-        ///
-        /// `DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`,
-        /// which will be substituted with the JSON-serialized form of the following
-        /// enum:
-        ///
-        /// ```norun
-        /// #[derive(PartialEq, Clone, Debug, Serialize)]
-        /// #[serde(rename_all = "camelCase")]
-        /// pub enum DiscoverArgument {
-        ///    Path(AbsPathBuf),
-        ///    Buildfile(AbsPathBuf),
-        /// }
-        /// ```
-        ///
-        /// The JSON representation of `DiscoverArgument::Path` is:
-        ///
-        /// ```json
-        /// {
-        ///     "path": "src/main.rs"
-        /// }
-        /// ```
-        ///
-        /// Similarly, the JSON representation of `DiscoverArgument::Buildfile` is:
-        ///
-        /// ```
-        /// {
-        ///     "buildfile": "BUILD"
-        /// }
-        /// ```
-        ///
-        /// `DiscoverArgument::Path` is used to find and generate a `rust-project.json`,
-        /// and therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to
-        /// to update an existing workspace. As a reference for implementors,
-        /// buck2's `rust-project` will likely be useful:
-        /// https://github.com/facebook/buck2/tree/main/integrations/rust-project.
-        workspace_discoverConfig: Option<DiscoverWorkspaceConfig> = None,
-    }
-}
-
-config_data! {
-    /// Local configurations can be defined per `SourceRoot`. This almost always corresponds to a `Crate`.
-    local: struct LocalDefaultConfigData <- LocalConfigInput ->  {
-        /// Whether to insert #[must_use] when generating `as_` methods
-        /// for enum variants.
-        assist_emitMustUse: bool               = false,
-        /// Placeholder expression to use for missing expressions in assists.
-        assist_expressionFillDefault: ExprFillDefaultDef              = ExprFillDefaultDef::Todo,
-        /// Enable borrow checking for term search code assists. If set to false, also there will be more suggestions, but some of them may not borrow-check.
-        assist_termSearch_borrowcheck: bool = true,
-        /// Term search fuel in "units of work" for assists (Defaults to 1800).
-        assist_termSearch_fuel: usize = 1800,
-
-        /// Whether to enforce the import granularity setting for all files. If set to false rust-analyzer will try to keep import styles consistent per file.
-        imports_granularity_enforce: bool              = false,
-        /// How imports should be grouped into use statements.
-        imports_granularity_group: ImportGranularityDef  = ImportGranularityDef::Crate,
-        /// Group inserted imports by the https://rust-analyzer.github.io/manual.html#auto-import[following order]. Groups are separated by newlines.
-        imports_group_enable: bool                           = true,
-        /// Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
-        imports_merge_glob: bool           = true,
-        /// Prefer to unconditionally use imports of the core and alloc crate, over the std crate.
-        imports_preferNoStd | imports_prefer_no_std: bool = false,
-         /// Whether to prefer import paths containing a `prelude` module.
-        imports_preferPrelude: bool                       = false,
-        /// The path structure for newly inserted paths to use.
-        imports_prefix: ImportPrefixDef               = ImportPrefixDef::Plain,
-        /// Whether to prefix external (including std, core) crate imports with `::`. e.g. "use ::std::io::Read;".
-        imports_prefixExternPrelude: bool = false,
-    }
-}
-
-config_data! {
-    workspace: struct WorkspaceDefaultConfigData <- WorkspaceConfigInput -> {
-
-        /// Additional arguments to `rustfmt`.
-        rustfmt_extraArgs: Vec<String>               = vec![],
-        /// Advanced option, fully override the command rust-analyzer uses for
-        /// formatting. This should be the equivalent of `rustfmt` here, and
-        /// not that of `cargo fmt`. The file contents will be passed on the
-        /// standard input and the formatted result will be read from the
-        /// standard output.
-        rustfmt_overrideCommand: Option<Vec<String>> = None,
-        /// Enables the use of rustfmt's unstable range formatting command for the
-        /// `textDocument/rangeFormatting` request. The rustfmt option is unstable and only
-        /// available on a nightly build.
-        rustfmt_rangeFormatting_enable: bool = false,
-
-    }
-}
-
-config_data! {
-    /// Configs that only make sense when they are set by a client. As such they can only be defined
-    /// by setting them using client's settings (e.g `settings.json` on VS Code).
-    client: struct ClientDefaultConfigData <- ClientConfigInput -> {
-        /// Toggles the additional completions that automatically add imports when completed.
-        /// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
-        completion_autoimport_enable: bool       = true,
-        /// Toggles the additional completions that automatically show method calls and field accesses
-        /// with `self` prefixed to them when inside a method.
-        completion_autoself_enable: bool        = true,
-        /// Whether to add parenthesis and argument snippets when completing function.
-        completion_callable_snippets: CallableCompletionDef  = CallableCompletionDef::FillArguments,
-        /// Whether to show full function/method signatures in completion docs.
-        completion_fullFunctionSignatures_enable: bool = false,
-        /// Maximum number of completions to return. If `None`, the limit is infinite.
-        completion_limit: Option<usize> = None,
-        /// Whether to show postfix snippets like `dbg`, `if`, `not`, etc.
-        completion_postfix_enable: bool         = true,
-        /// Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position.
-        completion_privateEditable_enable: bool = false,
-        /// Custom completion snippets.
-        completion_snippets_custom: FxHashMap<String, SnippetDef> = serde_json::from_str(r#"{
-            "Arc::new": {
-                "postfix": "arc",
-                "body": "Arc::new(${receiver})",
-                "requires": "std::sync::Arc",
-                "description": "Put the expression into an `Arc`",
-                "scope": "expr"
-            },
-            "Rc::new": {
-                "postfix": "rc",
-                "body": "Rc::new(${receiver})",
-                "requires": "std::rc::Rc",
-                "description": "Put the expression into an `Rc`",
-                "scope": "expr"
-            },
-            "Box::pin": {
-                "postfix": "pinbox",
-                "body": "Box::pin(${receiver})",
-                "requires": "std::boxed::Box",
-                "description": "Put the expression into a pinned `Box`",
-                "scope": "expr"
-            },
-            "Ok": {
-                "postfix": "ok",
-                "body": "Ok(${receiver})",
-                "description": "Wrap the expression in a `Result::Ok`",
-                "scope": "expr"
-            },
-            "Err": {
-                "postfix": "err",
-                "body": "Err(${receiver})",
-                "description": "Wrap the expression in a `Result::Err`",
-                "scope": "expr"
-            },
-            "Some": {
-                "postfix": "some",
-                "body": "Some(${receiver})",
-                "description": "Wrap the expression in an `Option::Some`",
-                "scope": "expr"
-            }
-        }"#).unwrap(),
-        /// Whether to enable term search based snippets like `Some(foo.bar().baz())`.
-        completion_termSearch_enable: bool = false,
-        /// Term search fuel in "units of work" for autocompletion (Defaults to 1000).
-        completion_termSearch_fuel: usize = 1000,
-
-        /// Controls file watching implementation.
-        files_watcher: FilesWatcherDef = FilesWatcherDef::Client,
 
         /// Enables highlighting of related references while the cursor is on `break`, `loop`, `while`, or `for` keywords.
         highlightRelated_breakPoints_enable: bool = true,
@@ -663,6 +233,19 @@
         /// `#rust-analyzer.lens.enable#` is set.
         lens_run_enable: bool              = true,
 
+        /// Disable project auto-discovery in favor of explicitly specified set
+        /// of projects.
+        ///
+        /// Elements must be paths pointing to `Cargo.toml`,
+        /// `rust-project.json`, `.rs` files (which will be treated as standalone files) or JSON
+        /// objects in `rust-project.json` format.
+        linkedProjects: Vec<ManifestOrProjectJson> = vec![],
+
+        /// Number of syntax trees rust-analyzer keeps in memory. Defaults to 128.
+        lru_capacity: Option<u16>                 = None,
+        /// Sets the LRU capacity of the specified queries.
+        lru_query_capacities: FxHashMap<Box<str>, u16> = FxHashMap::default(),
+
         /// Whether to show `can't find Cargo.toml` error message.
         notifications_cargoTomlNotFound: bool      = true,
 
@@ -727,6 +310,383 @@
         /// Whether to insert closing angle brackets when typing an opening angle bracket of a generic argument list.
         typing_autoClosingAngleBrackets_enable: bool = false,
 
+
+        /// Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`].
+        ///
+        /// [`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`.
+        /// `progress_label` is used for the title in progress indicators, whereas `files_to_watch`
+        /// is used to determine which build system-specific files should be watched in order to
+        /// reload rust-analyzer.
+        ///
+        /// Below is an example of a valid configuration:
+        /// ```json
+        /// "rust-analyzer.workspace.discoverConfig": {
+        ///     "command": [
+        ///         "rust-project",
+        ///         "develop-json"
+        ///     ],
+        ///     "progressLabel": "rust-analyzer",
+        ///     "filesToWatch": [
+        ///         "BUCK"
+        ///     ]
+        /// }
+        /// ```
+        ///
+        /// ## On `DiscoverWorkspaceConfig::command`
+        ///
+        /// **Warning**: This format is provisional and subject to change.
+        ///
+        /// [`DiscoverWorkspaceConfig::command`] *must* return a JSON object
+        /// corresponding to `DiscoverProjectData::Finished`:
+        ///
+        /// ```norun
+        /// #[derive(Debug, Clone, Deserialize, Serialize)]
+        /// #[serde(tag = "kind")]
+        /// #[serde(rename_all = "snake_case")]
+        /// enum DiscoverProjectData {
+        ///     Finished { buildfile: Utf8PathBuf, project: ProjectJsonData },
+        ///     Error { error: String, source: Option<String> },
+        ///     Progress { message: String },
+        /// }
+        /// ```
+        ///
+        /// As JSON, `DiscoverProjectData::Finished` is:
+        ///
+        /// ```json
+        /// {
+        ///     // the internally-tagged representation of the enum.
+        ///     "kind": "finished",
+        ///     // the file used by a non-Cargo build system to define
+        ///     // a package or target.
+        ///     "buildfile": "rust-analyzer/BUILD",
+        ///     // the contents of a rust-project.json, elided for brevity
+        ///     "project": {
+        ///         "sysroot": "foo",
+        ///         "crates": []
+        ///     }
+        /// }
+        /// ```
+        ///
+        /// It is encouraged, but not required, to use the other variants on
+        /// `DiscoverProjectData` to provide a more polished end-user experience.
+        ///
+        /// `DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`,
+        /// which will be substituted with the JSON-serialized form of the following
+        /// enum:
+        ///
+        /// ```norun
+        /// #[derive(PartialEq, Clone, Debug, Serialize)]
+        /// #[serde(rename_all = "camelCase")]
+        /// pub enum DiscoverArgument {
+        ///    Path(AbsPathBuf),
+        ///    Buildfile(AbsPathBuf),
+        /// }
+        /// ```
+        ///
+        /// The JSON representation of `DiscoverArgument::Path` is:
+        ///
+        /// ```json
+        /// {
+        ///     "path": "src/main.rs"
+        /// }
+        /// ```
+        ///
+        /// Similarly, the JSON representation of `DiscoverArgument::Buildfile` is:
+        ///
+        /// ```
+        /// {
+        ///     "buildfile": "BUILD"
+        /// }
+        /// ```
+        ///
+        /// `DiscoverArgument::Path` is used to find and generate a `rust-project.json`,
+        /// and therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to
+        /// to update an existing workspace. As a reference for implementors,
+        /// buck2's `rust-project` will likely be useful:
+        /// https://github.com/facebook/buck2/tree/main/integrations/rust-project.
+        workspace_discoverConfig: Option<DiscoverWorkspaceConfig> = None,
+    }
+}
+
+config_data! {
+    /// Local configurations can be defined per `SourceRoot`. This almost always corresponds to a `Crate`.
+    local: struct LocalDefaultConfigData <- LocalConfigInput ->  {
+        /// Whether to insert #[must_use] when generating `as_` methods
+        /// for enum variants.
+        assist_emitMustUse: bool               = false,
+        /// Placeholder expression to use for missing expressions in assists.
+        assist_expressionFillDefault: ExprFillDefaultDef              = ExprFillDefaultDef::Todo,
+        /// Enable borrow checking for term search code assists. If set to false, also there will be more suggestions, but some of them may not borrow-check.
+        assist_termSearch_borrowcheck: bool = true,
+        /// Term search fuel in "units of work" for assists (Defaults to 1800).
+        assist_termSearch_fuel: usize = 1800,
+
+
+        /// Whether to automatically add a semicolon when completing unit-returning functions.
+        ///
+        /// In `match` arms it completes a comma instead.
+        completion_addSemicolonToUnit: bool = true,
+        /// Toggles the additional completions that automatically add imports when completed.
+        /// Note that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.
+        completion_autoimport_enable: bool       = true,
+        /// Toggles the additional completions that automatically show method calls and field accesses
+        /// with `self` prefixed to them when inside a method.
+        completion_autoself_enable: bool        = true,
+        /// Whether to add parenthesis and argument snippets when completing function.
+        completion_callable_snippets: CallableCompletionDef  = CallableCompletionDef::FillArguments,
+        /// Whether to show full function/method signatures in completion docs.
+        completion_fullFunctionSignatures_enable: bool = false,
+        /// Whether to omit deprecated items from autocompletion. By default they are marked as deprecated but not hidden.
+        completion_hideDeprecated: bool = false,
+        /// Maximum number of completions to return. If `None`, the limit is infinite.
+        completion_limit: Option<usize> = None,
+        /// Whether to show postfix snippets like `dbg`, `if`, `not`, etc.
+        completion_postfix_enable: bool         = true,
+        /// Enables completions of private items and fields that are defined in the current workspace even if they are not visible at the current position.
+        completion_privateEditable_enable: bool = false,
+        /// Whether to enable term search based snippets like `Some(foo.bar().baz())`.
+        completion_termSearch_enable: bool = false,
+        /// Term search fuel in "units of work" for autocompletion (Defaults to 1000).
+        completion_termSearch_fuel: usize = 1000,
+
+        /// List of rust-analyzer diagnostics to disable.
+        diagnostics_disabled: FxHashSet<String> = FxHashSet::default(),
+        /// Whether to show native rust-analyzer diagnostics.
+        diagnostics_enable: bool                = true,
+        /// Whether to show experimental rust-analyzer diagnostics that might
+        /// have more false positives than usual.
+        diagnostics_experimental_enable: bool    = false,
+        /// Map of prefixes to be substituted when parsing diagnostic file paths.
+        /// This should be the reverse mapping of what is passed to `rustc` as `--remap-path-prefix`.
+        diagnostics_remapPrefix: FxHashMap<String, String> = FxHashMap::default(),
+        /// Whether to run additional style lints.
+        diagnostics_styleLints_enable: bool =    false,
+        /// List of warnings that should be displayed with hint severity.
+        ///
+        /// The warnings will be indicated by faded text or three dots in code
+        /// and will not show up in the `Problems Panel`.
+        diagnostics_warningsAsHint: Vec<String> = vec![],
+        /// List of warnings that should be displayed with info severity.
+        ///
+        /// The warnings will be indicated by a blue squiggly underline in code
+        /// and a blue icon in the `Problems Panel`.
+        diagnostics_warningsAsInfo: Vec<String> = vec![],
+
+        /// Whether to enforce the import granularity setting for all files. If set to false rust-analyzer will try to keep import styles consistent per file.
+        imports_granularity_enforce: bool              = false,
+        /// How imports should be grouped into use statements.
+        imports_granularity_group: ImportGranularityDef  = ImportGranularityDef::Crate,
+        /// Group inserted imports by the https://rust-analyzer.github.io/manual.html#auto-import[following order]. Groups are separated by newlines.
+        imports_group_enable: bool                           = true,
+        /// Whether to allow import insertion to merge new imports into single path glob imports like `use std::fmt::*;`.
+        imports_merge_glob: bool           = true,
+        /// Prefer to unconditionally use imports of the core and alloc crate, over the std crate.
+        imports_preferNoStd | imports_prefer_no_std: bool = false,
+         /// Whether to prefer import paths containing a `prelude` module.
+        imports_preferPrelude: bool                       = false,
+        /// The path structure for newly inserted paths to use.
+        imports_prefix: ImportPrefixDef               = ImportPrefixDef::Plain,
+        /// Whether to prefix external (including std, core) crate imports with `::`. e.g. "use ::std::io::Read;".
+        imports_prefixExternPrelude: bool = false,
+    }
+}
+
+config_data! {
+    workspace: struct WorkspaceDefaultConfigData <- WorkspaceConfigInput -> {
+        /// Pass `--all-targets` to cargo invocation.
+        cargo_allTargets: bool           = true,
+        /// Automatically refresh project info via `cargo metadata` on
+        /// `Cargo.toml` or `.cargo/config.toml` changes.
+        cargo_autoreload: bool           = true,
+        /// Run build scripts (`build.rs`) for more precise code analysis.
+        cargo_buildScripts_enable: bool  = true,
+        /// Specifies the invocation strategy to use when running the build scripts command.
+        /// If `per_workspace` is set, the command will be executed for each Rust workspace with the
+        /// workspace as the working directory.
+        /// If `once` is set, the command will be executed once with the opened project as the
+        /// working directory.
+        /// This config only has an effect when `#rust-analyzer.cargo.buildScripts.overrideCommand#`
+        /// is set.
+        cargo_buildScripts_invocationStrategy: InvocationStrategy = InvocationStrategy::PerWorkspace,
+        /// Override the command rust-analyzer uses to run build scripts and
+        /// build procedural macros. The command is required to output json
+        /// and should therefore include `--message-format=json` or a similar
+        /// option.
+        ///
+        /// If there are multiple linked projects/workspaces, this command is invoked for
+        /// each of them, with the working directory being the workspace root
+        /// (i.e., the folder containing the `Cargo.toml`). This can be overwritten
+        /// by changing `#rust-analyzer.cargo.buildScripts.invocationStrategy#`.
+        ///
+        /// By default, a cargo invocation will be constructed for the configured
+        /// targets and features, with the following base command line:
+        ///
+        /// ```bash
+        /// cargo check --quiet --workspace --message-format=json --all-targets --keep-going
+        /// ```
+        /// .
+        cargo_buildScripts_overrideCommand: Option<Vec<String>> = None,
+        /// Rerun proc-macros building/build-scripts running when proc-macro
+        /// or build-script sources change and are saved.
+        cargo_buildScripts_rebuildOnSave: bool = true,
+        /// Use `RUSTC_WRAPPER=rust-analyzer` when running build scripts to
+        /// avoid checking unnecessary things.
+        cargo_buildScripts_useRustcWrapper: bool = true,
+        /// List of cfg options to enable with the given values.
+        cargo_cfgs: FxHashMap<String, Option<String>> = {
+            let mut m = FxHashMap::default();
+            m.insert("debug_assertions".to_owned(), None);
+            m.insert("miri".to_owned(), None);
+            m
+        },
+        /// Extra arguments that are passed to every cargo invocation.
+        cargo_extraArgs: Vec<String> = vec![],
+        /// Extra environment variables that will be set when running cargo, rustc
+        /// or other commands within the workspace. Useful for setting RUSTFLAGS.
+        cargo_extraEnv: FxHashMap<String, String> = FxHashMap::default(),
+        /// List of features to activate.
+        ///
+        /// Set this to `"all"` to pass `--all-features` to cargo.
+        cargo_features: CargoFeaturesDef      = CargoFeaturesDef::Selected(vec![]),
+        /// Whether to pass `--no-default-features` to cargo.
+        cargo_noDefaultFeatures: bool    = false,
+        /// Relative path to the sysroot, or "discover" to try to automatically find it via
+        /// "rustc --print sysroot".
+        ///
+        /// Unsetting this disables sysroot loading.
+        ///
+        /// This option does not take effect until rust-analyzer is restarted.
+        cargo_sysroot: Option<String>    = Some("discover".to_owned()),
+        /// Relative path to the sysroot library sources. If left unset, this will default to
+        /// `{cargo.sysroot}/lib/rustlib/src/rust/library`.
+        ///
+        /// This option does not take effect until rust-analyzer is restarted.
+        cargo_sysrootSrc: Option<String>    = None,
+        /// Compilation target override (target triple).
+        // FIXME(@poliorcetics): move to multiple targets here too, but this will need more work
+        // than `checkOnSave_target`
+        cargo_target: Option<String>     = None,
+        /// Optional path to a rust-analyzer specific target directory.
+        /// This prevents rust-analyzer's `cargo check` and initial build-script and proc-macro
+        /// building from locking the `Cargo.lock` at the expense of duplicating build artifacts.
+        ///
+        /// Set to `true` to use a subdirectory of the existing target directory or
+        /// set to a path relative to the workspace to use that path.
+        cargo_targetDir | rust_analyzerTargetDir: Option<TargetDirectory> = None,
+
+        /// Run the check command for diagnostics on save.
+        checkOnSave | checkOnSave_enable: bool                         = true,
+
+
+        /// Check all targets and tests (`--all-targets`). Defaults to
+        /// `#rust-analyzer.cargo.allTargets#`.
+        check_allTargets | checkOnSave_allTargets: Option<bool>          = None,
+        /// Cargo command to use for `cargo check`.
+        check_command | checkOnSave_command: String                      = "check".to_owned(),
+        /// Extra arguments for `cargo check`.
+        check_extraArgs | checkOnSave_extraArgs: Vec<String>             = vec![],
+        /// Extra environment variables that will be set when running `cargo check`.
+        /// Extends `#rust-analyzer.cargo.extraEnv#`.
+        check_extraEnv | checkOnSave_extraEnv: FxHashMap<String, String> = FxHashMap::default(),
+        /// List of features to activate. Defaults to
+        /// `#rust-analyzer.cargo.features#`.
+        ///
+        /// Set to `"all"` to pass `--all-features` to Cargo.
+        check_features | checkOnSave_features: Option<CargoFeaturesDef>  = None,
+        /// List of `cargo check` (or other command specified in `check.command`) diagnostics to ignore.
+        ///
+        /// For example for `cargo check`: `dead_code`, `unused_imports`, `unused_variables`,...
+        check_ignore: FxHashSet<String> = FxHashSet::default(),
+        /// Specifies the invocation strategy to use when running the check command.
+        /// If `per_workspace` is set, the command will be executed for each workspace.
+        /// If `once` is set, the command will be executed once.
+        /// This config only has an effect when `#rust-analyzer.check.overrideCommand#`
+        /// is set.
+        check_invocationStrategy | checkOnSave_invocationStrategy: InvocationStrategy = InvocationStrategy::PerWorkspace,
+        /// Whether to pass `--no-default-features` to Cargo. Defaults to
+        /// `#rust-analyzer.cargo.noDefaultFeatures#`.
+        check_noDefaultFeatures | checkOnSave_noDefaultFeatures: Option<bool>         = None,
+        /// Override the command rust-analyzer uses instead of `cargo check` for
+        /// diagnostics on save. The command is required to output json and
+        /// should therefore include `--message-format=json` or a similar option
+        /// (if your client supports the `colorDiagnosticOutput` experimental
+        /// capability, you can use `--message-format=json-diagnostic-rendered-ansi`).
+        ///
+        /// If you're changing this because you're using some tool wrapping
+        /// Cargo, you might also want to change
+        /// `#rust-analyzer.cargo.buildScripts.overrideCommand#`.
+        ///
+        /// If there are multiple linked projects/workspaces, this command is invoked for
+        /// each of them, with the working directory being the workspace root
+        /// (i.e., the folder containing the `Cargo.toml`). This can be overwritten
+        /// by changing `#rust-analyzer.check.invocationStrategy#`.
+        ///
+        /// If `$saved_file` is part of the command, rust-analyzer will pass
+        /// the absolute path of the saved file to the provided command. This is
+        /// intended to be used with non-Cargo build systems.
+        /// Note that `$saved_file` is experimental and may be removed in the future.
+        ///
+        /// An example command would be:
+        ///
+        /// ```bash
+        /// cargo check --workspace --message-format=json --all-targets
+        /// ```
+        /// .
+        check_overrideCommand | checkOnSave_overrideCommand: Option<Vec<String>>             = None,
+        /// Check for specific targets. Defaults to `#rust-analyzer.cargo.target#` if empty.
+        ///
+        /// Can be a single target, e.g. `"x86_64-unknown-linux-gnu"` or a list of targets, e.g.
+        /// `["aarch64-apple-darwin", "x86_64-apple-darwin"]`.
+        ///
+        /// Aliased as `"checkOnSave.targets"`.
+        check_targets | checkOnSave_targets | checkOnSave_target: Option<CheckOnSaveTargets> = None,
+        /// Whether `--workspace` should be passed to `cargo check`.
+        /// If false, `-p <package>` will be passed instead.
+        check_workspace: bool = true,
+
+        /// These proc-macros will be ignored when trying to expand them.
+        ///
+        /// This config takes a map of crate names with the exported proc-macro names to ignore as values.
+        procMacro_ignored: FxHashMap<Box<str>, Box<[Box<str>]>>          = FxHashMap::default(),
+
+        /// Command to be executed instead of 'cargo' for runnables.
+        runnables_command: Option<String> = None,
+        /// Additional arguments to be passed to cargo for runnables such as
+        /// tests or binaries. For example, it may be `--release`.
+        runnables_extraArgs: Vec<String>   = vec![],
+        /// Additional arguments to be passed through Cargo to launched tests, benchmarks, or
+        /// doc-tests.
+        ///
+        /// Unless the launched target uses a
+        /// [custom test harness](https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-harness-field),
+        /// they will end up being interpreted as options to
+        /// [`rustc`’s built-in test harness (“libtest”)](https://doc.rust-lang.org/rustc/tests/index.html#cli-arguments).
+        runnables_extraTestBinaryArgs: Vec<String> = vec!["--show-output".to_owned()],
+
+        /// Path to the Cargo.toml of the rust compiler workspace, for usage in rustc_private
+        /// projects, or "discover" to try to automatically find it if the `rustc-dev` component
+        /// is installed.
+        ///
+        /// Any project which uses rust-analyzer with the rustcPrivate
+        /// crates must set `[package.metadata.rust-analyzer] rustc_private=true` to use it.
+        ///
+        /// This option does not take effect until rust-analyzer is restarted.
+        rustc_source: Option<String> = None,
+
+        /// Additional arguments to `rustfmt`.
+        rustfmt_extraArgs: Vec<String>               = vec![],
+        /// Advanced option, fully override the command rust-analyzer uses for
+        /// formatting. This should be the equivalent of `rustfmt` here, and
+        /// not that of `cargo fmt`. The file contents will be passed on the
+        /// standard input and the formatted result will be read from the
+        /// standard output.
+        rustfmt_overrideCommand: Option<Vec<String>> = None,
+        /// Enables the use of rustfmt's unstable range formatting command for the
+        /// `textDocument/rangeFormatting` request. The rustfmt option is unstable and only
+        /// available on a nightly build.
+        rustfmt_rangeFormatting_enable: bool = false,
+
+
         /// Workspace symbol search kind.
         workspace_symbol_search_kind: WorkspaceSymbolSearchKindDef = WorkspaceSymbolSearchKindDef::OnlyTypes,
         /// Limits the number of items returned from a workspace symbol search (Defaults to 128).
@@ -735,6 +695,19 @@
         workspace_symbol_search_limit: usize = 128,
         /// Workspace symbol search scope.
         workspace_symbol_search_scope: WorkspaceSymbolSearchScopeDef = WorkspaceSymbolSearchScopeDef::Workspace,
+
+    }
+}
+
+config_data! {
+    /// Configs that only make sense when they are set by a client. As such they can only be defined
+    /// by setting them using client's settings (e.g `settings.json` on VS Code).
+    client: struct ClientDefaultConfigData <- ClientConfigInput -> {
+
+        /// Controls file watching implementation.
+        files_watcher: FilesWatcherDef = FilesWatcherDef::Client,
+
+
     }
 }
 
@@ -753,7 +726,13 @@
 
 #[derive(Debug, Clone)]
 pub struct Config {
-    discovered_projects: Vec<ProjectManifest>,
+    /// Projects that have a Cargo.toml or a rust-project.json in a
+    /// parent directory, so we can discover them by walking the
+    /// file system.
+    discovered_projects_from_filesystem: Vec<ProjectManifest>,
+    /// Projects whose configuration was generated by a command
+    /// configured in discoverConfig.
+    discovered_projects_from_command: Vec<ProjectJsonFromCommand>,
     /// The workspace roots as registered by the LSP client
     workspace_roots: Vec<AbsPathBuf>,
     caps: ClientCapabilities,
@@ -1016,7 +995,7 @@
             config.source_root_parent_map = source_root_map;
         }
 
-        if config.check_command().is_empty() {
+        if config.check_command(None).is_empty() {
             config.validation_errors.0.push(Arc::new(ConfigErrorInner::Json {
                 config_key: "/check/command".to_owned(),
                 error: serde_json::Error::custom("expected a non-empty string"),
@@ -1046,19 +1025,19 @@
         (config, e, should_update)
     }
 
-    pub fn add_linked_projects(&mut self, data: ProjectJsonData, buildfile: AbsPathBuf) {
-        let linked_projects = &mut self.client_config.0.global.linkedProjects;
-
-        let new_project = ManifestOrProjectJson::DiscoveredProjectJson { data, buildfile };
-        match linked_projects {
-            Some(projects) => {
-                match projects.iter_mut().find(|p| p.manifest() == new_project.manifest()) {
-                    Some(p) => *p = new_project,
-                    None => projects.push(new_project),
-                }
+    pub fn add_discovered_project_from_command(
+        &mut self,
+        data: ProjectJsonData,
+        buildfile: AbsPathBuf,
+    ) {
+        for proj in self.discovered_projects_from_command.iter_mut() {
+            if proj.buildfile == buildfile {
+                proj.data = data;
+                return;
             }
-            None => *linked_projects = Some(vec![new_project]),
         }
+
+        self.discovered_projects_from_command.push(ProjectJsonFromCommand { data, buildfile });
     }
 }
 
@@ -1251,7 +1230,7 @@
     pub cargo_toml_not_found: bool,
 }
 
-#[derive(Debug, Clone)]
+#[derive(Deserialize, Serialize, Debug, Clone)]
 pub enum RustfmtConfig {
     Rustfmt { extra_args: Vec<String>, enable_range_formatting: bool },
     CustomCommand { command: String, args: Vec<String> },
@@ -1336,7 +1315,8 @@
 
         Config {
             caps: ClientCapabilities::new(caps),
-            discovered_projects: Vec::new(),
+            discovered_projects_from_filesystem: Vec::new(),
+            discovered_projects_from_command: Vec::new(),
             root_path,
             snippets: Default::default(),
             workspace_roots,
@@ -1357,7 +1337,7 @@
         if discovered.is_empty() {
             tracing::error!("failed to find any projects in {:?}", &self.workspace_roots);
         }
-        self.discovered_projects = discovered;
+        self.discovered_projects_from_filesystem = discovered;
     }
 
     pub fn remove_workspace(&mut self, path: &AbsPath) {
@@ -1412,29 +1392,36 @@
 
     pub fn completion(&self, source_root: Option<SourceRootId>) -> CompletionConfig {
         CompletionConfig {
-            enable_postfix_completions: self.completion_postfix_enable().to_owned(),
-            enable_imports_on_the_fly: self.completion_autoimport_enable().to_owned()
+            enable_postfix_completions: self.completion_postfix_enable(source_root).to_owned(),
+            enable_imports_on_the_fly: self.completion_autoimport_enable(source_root).to_owned()
                 && self.caps.completion_item_edit_resolve(),
-            enable_self_on_the_fly: self.completion_autoself_enable().to_owned(),
-            enable_private_editable: self.completion_privateEditable_enable().to_owned(),
-            full_function_signatures: self.completion_fullFunctionSignatures_enable().to_owned(),
-            callable: match self.completion_callable_snippets() {
+            enable_self_on_the_fly: self.completion_autoself_enable(source_root).to_owned(),
+            enable_private_editable: self.completion_privateEditable_enable(source_root).to_owned(),
+            full_function_signatures: self
+                .completion_fullFunctionSignatures_enable(source_root)
+                .to_owned(),
+            callable: match self.completion_callable_snippets(source_root) {
                 CallableCompletionDef::FillArguments => Some(CallableSnippets::FillArguments),
                 CallableCompletionDef::AddParentheses => Some(CallableSnippets::AddParentheses),
                 CallableCompletionDef::None => None,
             },
+            add_semicolon_to_unit: *self.completion_addSemicolonToUnit(source_root),
             snippet_cap: SnippetCap::new(self.completion_snippet()),
             insert_use: self.insert_use_config(source_root),
             prefer_no_std: self.imports_preferNoStd(source_root).to_owned(),
             prefer_prelude: self.imports_preferPrelude(source_root).to_owned(),
             prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(),
             snippets: self.snippets.clone().to_vec(),
-            limit: self.completion_limit().to_owned(),
-            enable_term_search: self.completion_termSearch_enable().to_owned(),
-            term_search_fuel: self.completion_termSearch_fuel().to_owned() as u64,
+            limit: self.completion_limit(source_root).to_owned(),
+            enable_term_search: self.completion_termSearch_enable(source_root).to_owned(),
+            term_search_fuel: self.completion_termSearch_fuel(source_root).to_owned() as u64,
         }
     }
 
+    pub fn completion_hide_deprecated(&self) -> bool {
+        *self.completion_hideDeprecated(None)
+    }
+
     pub fn detached_files(&self) -> &Vec<AbsPathBuf> {
         // FIXME @alibektas : This is the only config that is confusing. If it's a proper configuration
         // why is it not among the others? If it's client only which I doubt it is current state should be alright
@@ -1443,11 +1430,11 @@
 
     pub fn diagnostics(&self, source_root: Option<SourceRootId>) -> DiagnosticsConfig {
         DiagnosticsConfig {
-            enabled: *self.diagnostics_enable(),
+            enabled: *self.diagnostics_enable(source_root),
             proc_attr_macros_enabled: self.expand_proc_attr_macros(),
             proc_macros_enabled: *self.procMacro_enable(),
-            disable_experimental: !self.diagnostics_experimental_enable(),
-            disabled: self.diagnostics_disabled().clone(),
+            disable_experimental: !self.diagnostics_experimental_enable(source_root),
+            disabled: self.diagnostics_disabled(source_root).clone(),
             expr_fill_default: match self.assist_expressionFillDefault(source_root) {
                 ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo,
                 ExprFillDefaultDef::Default => ExprFillDefaultMode::Default,
@@ -1457,7 +1444,7 @@
             prefer_no_std: self.imports_preferNoStd(source_root).to_owned(),
             prefer_prelude: self.imports_preferPrelude(source_root).to_owned(),
             prefer_absolute: self.imports_prefixExternPrelude(source_root).to_owned(),
-            style_lints: self.diagnostics_styleLints_enable().to_owned(),
+            style_lints: self.diagnostics_styleLints_enable(source_root).to_owned(),
             term_search_fuel: self.assist_termSearch_fuel(source_root).to_owned() as u64,
             term_search_borrowck: self.assist_termSearch_borrowcheck(source_root).to_owned(),
         }
@@ -1673,78 +1660,95 @@
         self.workspace_discoverConfig().as_ref()
     }
 
-    pub fn linked_or_discovered_projects(&self) -> Vec<LinkedProject> {
-        match self.linkedProjects().as_slice() {
-            [] => {
-                let exclude_dirs: Vec<_> =
-                    self.files_excludeDirs().iter().map(|p| self.root_path.join(p)).collect();
-                self.discovered_projects
-                    .iter()
-                    .filter(|project| {
-                        !exclude_dirs.iter().any(|p| project.manifest_path().starts_with(p))
-                    })
-                    .cloned()
-                    .map(LinkedProject::from)
-                    .collect()
-            }
-            linked_projects => linked_projects
-                .iter()
-                .filter_map(|linked_project| match linked_project {
-                    ManifestOrProjectJson::Manifest(it) => {
-                        let path = self.root_path.join(it);
-                        ProjectManifest::from_manifest_file(path)
-                            .map_err(|e| tracing::error!("failed to load linked project: {}", e))
-                            .ok()
-                            .map(Into::into)
-                    }
-                    ManifestOrProjectJson::DiscoveredProjectJson { data, buildfile } => {
-                        let root_path =
-                            buildfile.parent().expect("Unable to get parent of buildfile");
+    fn discovered_projects(&self) -> Vec<ManifestOrProjectJson> {
+        let exclude_dirs: Vec<_> =
+            self.files_excludeDirs().iter().map(|p| self.root_path.join(p)).collect();
 
-                        Some(ProjectJson::new(None, root_path, data.clone()).into())
-                    }
-                    ManifestOrProjectJson::ProjectJson(it) => {
-                        Some(ProjectJson::new(None, &self.root_path, it.clone()).into())
-                    }
-                })
-                .collect(),
+        let mut projects = vec![];
+        for fs_proj in &self.discovered_projects_from_filesystem {
+            let manifest_path = fs_proj.manifest_path();
+            if exclude_dirs.iter().any(|p| manifest_path.starts_with(p)) {
+                continue;
+            }
+
+            let buf: Utf8PathBuf = manifest_path.to_path_buf().into();
+            projects.push(ManifestOrProjectJson::Manifest(buf));
         }
+
+        for dis_proj in &self.discovered_projects_from_command {
+            projects.push(ManifestOrProjectJson::DiscoveredProjectJson {
+                data: dis_proj.data.clone(),
+                buildfile: dis_proj.buildfile.clone(),
+            });
+        }
+
+        projects
+    }
+
+    pub fn linked_or_discovered_projects(&self) -> Vec<LinkedProject> {
+        let linked_projects = self.linkedProjects();
+        let projects = if linked_projects.is_empty() {
+            self.discovered_projects()
+        } else {
+            linked_projects.clone()
+        };
+
+        projects
+            .iter()
+            .filter_map(|linked_project| match linked_project {
+                ManifestOrProjectJson::Manifest(it) => {
+                    let path = self.root_path.join(it);
+                    ProjectManifest::from_manifest_file(path)
+                        .map_err(|e| tracing::error!("failed to load linked project: {}", e))
+                        .ok()
+                        .map(Into::into)
+                }
+                ManifestOrProjectJson::DiscoveredProjectJson { data, buildfile } => {
+                    let root_path = buildfile.parent().expect("Unable to get parent of buildfile");
+
+                    Some(ProjectJson::new(None, root_path, data.clone()).into())
+                }
+                ManifestOrProjectJson::ProjectJson(it) => {
+                    Some(ProjectJson::new(None, &self.root_path, it.clone()).into())
+                }
+            })
+            .collect()
     }
 
     pub fn prefill_caches(&self) -> bool {
         self.cachePriming_enable().to_owned()
     }
 
-    pub fn publish_diagnostics(&self) -> bool {
-        self.diagnostics_enable().to_owned()
+    pub fn publish_diagnostics(&self, source_root: Option<SourceRootId>) -> bool {
+        self.diagnostics_enable(source_root).to_owned()
     }
 
-    pub fn diagnostics_map(&self) -> DiagnosticsMapConfig {
+    pub fn diagnostics_map(&self, source_root: Option<SourceRootId>) -> DiagnosticsMapConfig {
         DiagnosticsMapConfig {
-            remap_prefix: self.diagnostics_remapPrefix().clone(),
-            warnings_as_info: self.diagnostics_warningsAsInfo().clone(),
-            warnings_as_hint: self.diagnostics_warningsAsHint().clone(),
-            check_ignore: self.check_ignore().clone(),
+            remap_prefix: self.diagnostics_remapPrefix(source_root).clone(),
+            warnings_as_info: self.diagnostics_warningsAsInfo(source_root).clone(),
+            warnings_as_hint: self.diagnostics_warningsAsHint(source_root).clone(),
+            check_ignore: self.check_ignore(source_root).clone(),
         }
     }
 
-    pub fn extra_args(&self) -> &Vec<String> {
-        self.cargo_extraArgs()
+    pub fn extra_args(&self, source_root: Option<SourceRootId>) -> &Vec<String> {
+        self.cargo_extraArgs(source_root)
     }
 
-    pub fn extra_env(&self) -> &FxHashMap<String, String> {
-        self.cargo_extraEnv()
+    pub fn extra_env(&self, source_root: Option<SourceRootId>) -> &FxHashMap<String, String> {
+        self.cargo_extraEnv(source_root)
     }
 
-    pub fn check_extra_args(&self) -> Vec<String> {
-        let mut extra_args = self.extra_args().clone();
-        extra_args.extend_from_slice(self.check_extraArgs());
+    pub fn check_extra_args(&self, source_root: Option<SourceRootId>) -> Vec<String> {
+        let mut extra_args = self.extra_args(source_root).clone();
+        extra_args.extend_from_slice(self.check_extraArgs(source_root));
         extra_args
     }
 
-    pub fn check_extra_env(&self) -> FxHashMap<String, String> {
-        let mut extra_env = self.cargo_extraEnv().clone();
-        extra_env.extend(self.check_extraEnv().clone());
+    pub fn check_extra_env(&self, source_root: Option<SourceRootId>) -> FxHashMap<String, String> {
+        let mut extra_env = self.cargo_extraEnv(source_root).clone();
+        extra_env.extend(self.check_extraEnv(source_root).clone());
         extra_env
     }
 
@@ -1761,8 +1765,11 @@
         Some(AbsPathBuf::try_from(path).unwrap_or_else(|path| self.root_path.join(path)))
     }
 
-    pub fn ignored_proc_macros(&self) -> &FxHashMap<Box<str>, Box<[Box<str>]>> {
-        self.procMacro_ignored()
+    pub fn ignored_proc_macros(
+        &self,
+        source_root: Option<SourceRootId>,
+    ) -> &FxHashMap<Box<str>, Box<[Box<str>]>> {
+        self.procMacro_ignored(source_root)
     }
 
     pub fn expand_proc_macros(&self) -> bool {
@@ -1787,23 +1794,23 @@
         }
     }
 
-    pub fn cargo_autoreload_config(&self) -> bool {
-        self.cargo_autoreload().to_owned()
+    pub fn cargo_autoreload_config(&self, source_root: Option<SourceRootId>) -> bool {
+        self.cargo_autoreload(source_root).to_owned()
     }
 
-    pub fn run_build_scripts(&self) -> bool {
-        self.cargo_buildScripts_enable().to_owned() || self.procMacro_enable().to_owned()
+    pub fn run_build_scripts(&self, source_root: Option<SourceRootId>) -> bool {
+        self.cargo_buildScripts_enable(source_root).to_owned() || self.procMacro_enable().to_owned()
     }
 
-    pub fn cargo(&self) -> CargoConfig {
-        let rustc_source = self.rustc_source().as_ref().map(|rustc_src| {
+    pub fn cargo(&self, source_root: Option<SourceRootId>) -> CargoConfig {
+        let rustc_source = self.rustc_source(source_root).as_ref().map(|rustc_src| {
             if rustc_src == "discover" {
                 RustLibSource::Discover
             } else {
                 RustLibSource::Path(self.root_path.join(rustc_src))
             }
         });
-        let sysroot = self.cargo_sysroot().as_ref().map(|sysroot| {
+        let sysroot = self.cargo_sysroot(source_root).as_ref().map(|sysroot| {
             if sysroot == "discover" {
                 RustLibSource::Discover
             } else {
@@ -1811,24 +1818,24 @@
             }
         });
         let sysroot_src =
-            self.cargo_sysrootSrc().as_ref().map(|sysroot| self.root_path.join(sysroot));
+            self.cargo_sysrootSrc(source_root).as_ref().map(|sysroot| self.root_path.join(sysroot));
 
         CargoConfig {
-            all_targets: *self.cargo_allTargets(),
-            features: match &self.cargo_features() {
+            all_targets: *self.cargo_allTargets(source_root),
+            features: match &self.cargo_features(source_root) {
                 CargoFeaturesDef::All => CargoFeatures::All,
                 CargoFeaturesDef::Selected(features) => CargoFeatures::Selected {
                     features: features.clone(),
-                    no_default_features: self.cargo_noDefaultFeatures().to_owned(),
+                    no_default_features: self.cargo_noDefaultFeatures(source_root).to_owned(),
                 },
             },
-            target: self.cargo_target().clone(),
+            target: self.cargo_target(source_root).clone(),
             sysroot,
             sysroot_src,
             rustc_source,
             cfg_overrides: project_model::CfgOverrides {
                 global: CfgDiff::new(
-                    self.cargo_cfgs()
+                    self.cargo_cfgs(source_root)
                         .iter()
                         .map(|(key, val)| match val {
                             Some(val) => CfgAtom::KeyValue {
@@ -1843,18 +1850,65 @@
                 .unwrap(),
                 selective: Default::default(),
             },
-            wrap_rustc_in_build_scripts: *self.cargo_buildScripts_useRustcWrapper(),
-            invocation_strategy: match self.cargo_buildScripts_invocationStrategy() {
+            wrap_rustc_in_build_scripts: *self.cargo_buildScripts_useRustcWrapper(source_root),
+            invocation_strategy: match self.cargo_buildScripts_invocationStrategy(source_root) {
                 InvocationStrategy::Once => project_model::InvocationStrategy::Once,
                 InvocationStrategy::PerWorkspace => project_model::InvocationStrategy::PerWorkspace,
             },
-            run_build_script_command: self.cargo_buildScripts_overrideCommand().clone(),
-            extra_args: self.cargo_extraArgs().clone(),
-            extra_env: self.cargo_extraEnv().clone(),
-            target_dir: self.target_dir_from_config(),
+            run_build_script_command: self.cargo_buildScripts_overrideCommand(source_root).clone(),
+            extra_args: self.cargo_extraArgs(source_root).clone(),
+            extra_env: self.cargo_extraEnv(source_root).clone(),
+            target_dir: self.target_dir_from_config(source_root),
         }
     }
 
+    pub(crate) fn completion_snippets_default() -> FxHashMap<String, SnippetDef> {
+        serde_json::from_str(
+            r#"{
+            "Arc::new": {
+                "postfix": "arc",
+                "body": "Arc::new(${receiver})",
+                "requires": "std::sync::Arc",
+                "description": "Put the expression into an `Arc`",
+                "scope": "expr"
+            },
+            "Rc::new": {
+                "postfix": "rc",
+                "body": "Rc::new(${receiver})",
+                "requires": "std::rc::Rc",
+                "description": "Put the expression into an `Rc`",
+                "scope": "expr"
+            },
+            "Box::pin": {
+                "postfix": "pinbox",
+                "body": "Box::pin(${receiver})",
+                "requires": "std::boxed::Box",
+                "description": "Put the expression into a pinned `Box`",
+                "scope": "expr"
+            },
+            "Ok": {
+                "postfix": "ok",
+                "body": "Ok(${receiver})",
+                "description": "Wrap the expression in a `Result::Ok`",
+                "scope": "expr"
+            },
+            "Err": {
+                "postfix": "err",
+                "body": "Err(${receiver})",
+                "description": "Wrap the expression in a `Result::Err`",
+                "scope": "expr"
+            },
+            "Some": {
+                "postfix": "some",
+                "body": "Some(${receiver})",
+                "description": "Wrap the expression in an `Option::Some`",
+                "scope": "expr"
+            }
+        }"#,
+        )
+        .unwrap()
+    }
+
     pub fn rustfmt(&self, source_root_id: Option<SourceRootId>) -> RustfmtConfig {
         match &self.rustfmt_overrideCommand(source_root_id) {
             Some(args) if !args.is_empty() => {
@@ -1869,37 +1923,37 @@
         }
     }
 
-    pub fn flycheck_workspace(&self) -> bool {
-        *self.check_workspace()
+    pub fn flycheck_workspace(&self, source_root: Option<SourceRootId>) -> bool {
+        *self.check_workspace(source_root)
     }
 
-    pub(crate) fn cargo_test_options(&self) -> CargoOptions {
+    pub(crate) fn cargo_test_options(&self, source_root: Option<SourceRootId>) -> CargoOptions {
         CargoOptions {
-            target_triples: self.cargo_target().clone().into_iter().collect(),
+            target_triples: self.cargo_target(source_root).clone().into_iter().collect(),
             all_targets: false,
-            no_default_features: *self.cargo_noDefaultFeatures(),
-            all_features: matches!(self.cargo_features(), CargoFeaturesDef::All),
-            features: match self.cargo_features().clone() {
+            no_default_features: *self.cargo_noDefaultFeatures(source_root),
+            all_features: matches!(self.cargo_features(source_root), CargoFeaturesDef::All),
+            features: match self.cargo_features(source_root).clone() {
                 CargoFeaturesDef::All => vec![],
                 CargoFeaturesDef::Selected(it) => it,
             },
-            extra_args: self.extra_args().clone(),
-            extra_test_bin_args: self.runnables_extraTestBinaryArgs().clone(),
-            extra_env: self.extra_env().clone(),
-            target_dir: self.target_dir_from_config(),
+            extra_args: self.extra_args(source_root).clone(),
+            extra_test_bin_args: self.runnables_extraTestBinaryArgs(source_root).clone(),
+            extra_env: self.extra_env(source_root).clone(),
+            target_dir: self.target_dir_from_config(source_root),
         }
     }
 
-    pub(crate) fn flycheck(&self) -> FlycheckConfig {
-        match &self.check_overrideCommand() {
+    pub(crate) fn flycheck(&self, source_root: Option<SourceRootId>) -> FlycheckConfig {
+        match &self.check_overrideCommand(source_root) {
             Some(args) if !args.is_empty() => {
                 let mut args = args.clone();
                 let command = args.remove(0);
                 FlycheckConfig::CustomCommand {
                     command,
                     args,
-                    extra_env: self.check_extra_env(),
-                    invocation_strategy: match self.check_invocationStrategy() {
+                    extra_env: self.check_extra_env(source_root),
+                    invocation_strategy: match self.check_invocationStrategy(source_root) {
                         InvocationStrategy::Once => crate::flycheck::InvocationStrategy::Once,
                         InvocationStrategy::PerWorkspace => {
                             crate::flycheck::InvocationStrategy::PerWorkspace
@@ -1908,44 +1962,50 @@
                 }
             }
             Some(_) | None => FlycheckConfig::CargoCommand {
-                command: self.check_command().clone(),
+                command: self.check_command(source_root).clone(),
                 options: CargoOptions {
                     target_triples: self
-                        .check_targets()
+                        .check_targets(source_root)
                         .clone()
                         .and_then(|targets| match &targets.0[..] {
                             [] => None,
                             targets => Some(targets.into()),
                         })
-                        .unwrap_or_else(|| self.cargo_target().clone().into_iter().collect()),
-                    all_targets: self.check_allTargets().unwrap_or(*self.cargo_allTargets()),
+                        .unwrap_or_else(|| {
+                            self.cargo_target(source_root).clone().into_iter().collect()
+                        }),
+                    all_targets: self
+                        .check_allTargets(source_root)
+                        .unwrap_or(*self.cargo_allTargets(source_root)),
                     no_default_features: self
-                        .check_noDefaultFeatures()
-                        .unwrap_or(*self.cargo_noDefaultFeatures()),
+                        .check_noDefaultFeatures(source_root)
+                        .unwrap_or(*self.cargo_noDefaultFeatures(source_root)),
                     all_features: matches!(
-                        self.check_features().as_ref().unwrap_or(self.cargo_features()),
+                        self.check_features(source_root)
+                            .as_ref()
+                            .unwrap_or(self.cargo_features(source_root)),
                         CargoFeaturesDef::All
                     ),
                     features: match self
-                        .check_features()
+                        .check_features(source_root)
                         .clone()
-                        .unwrap_or_else(|| self.cargo_features().clone())
+                        .unwrap_or_else(|| self.cargo_features(source_root).clone())
                     {
                         CargoFeaturesDef::All => vec![],
                         CargoFeaturesDef::Selected(it) => it,
                     },
-                    extra_args: self.check_extra_args(),
-                    extra_test_bin_args: self.runnables_extraTestBinaryArgs().clone(),
-                    extra_env: self.check_extra_env(),
-                    target_dir: self.target_dir_from_config(),
+                    extra_args: self.check_extra_args(source_root),
+                    extra_test_bin_args: self.runnables_extraTestBinaryArgs(source_root).clone(),
+                    extra_env: self.check_extra_env(source_root),
+                    target_dir: self.target_dir_from_config(source_root),
                 },
                 ansi_color_output: self.color_diagnostic_output(),
             },
         }
     }
 
-    fn target_dir_from_config(&self) -> Option<Utf8PathBuf> {
-        self.cargo_targetDir().as_ref().and_then(|target_dir| match target_dir {
+    fn target_dir_from_config(&self, source_root: Option<SourceRootId>) -> Option<Utf8PathBuf> {
+        self.cargo_targetDir(source_root).as_ref().and_then(|target_dir| match target_dir {
             TargetDirectory::UseSubdirectory(true) => {
                 Some(Utf8PathBuf::from("target/rust-analyzer"))
             }
@@ -1955,19 +2015,19 @@
         })
     }
 
-    pub fn check_on_save(&self) -> bool {
-        *self.checkOnSave()
+    pub fn check_on_save(&self, source_root: Option<SourceRootId>) -> bool {
+        *self.checkOnSave(source_root)
     }
 
-    pub fn script_rebuild_on_save(&self) -> bool {
-        *self.cargo_buildScripts_rebuildOnSave()
+    pub fn script_rebuild_on_save(&self, source_root: Option<SourceRootId>) -> bool {
+        *self.cargo_buildScripts_rebuildOnSave(source_root)
     }
 
-    pub fn runnables(&self) -> RunnablesConfig {
+    pub fn runnables(&self, source_root: Option<SourceRootId>) -> RunnablesConfig {
         RunnablesConfig {
-            override_cargo: self.runnables_command().clone(),
-            cargo_extra_args: self.runnables_extraArgs().clone(),
-            extra_test_binary_args: self.runnables_extraTestBinaryArgs().clone(),
+            override_cargo: self.runnables_command(source_root).clone(),
+            cargo_extra_args: self.runnables_extraArgs(source_root).clone(),
+            extra_test_binary_args: self.runnables_extraTestBinaryArgs(source_root).clone(),
         }
     }
 
@@ -2006,19 +2066,19 @@
         }
     }
 
-    pub fn workspace_symbol(&self) -> WorkspaceSymbolConfig {
+    pub fn workspace_symbol(&self, source_root: Option<SourceRootId>) -> WorkspaceSymbolConfig {
         WorkspaceSymbolConfig {
-            search_scope: match self.workspace_symbol_search_scope() {
+            search_scope: match self.workspace_symbol_search_scope(source_root) {
                 WorkspaceSymbolSearchScopeDef::Workspace => WorkspaceSymbolSearchScope::Workspace,
                 WorkspaceSymbolSearchScopeDef::WorkspaceAndDependencies => {
                     WorkspaceSymbolSearchScope::WorkspaceAndDependencies
                 }
             },
-            search_kind: match self.workspace_symbol_search_kind() {
+            search_kind: match self.workspace_symbol_search_kind(source_root) {
                 WorkspaceSymbolSearchKindDef::OnlyTypes => WorkspaceSymbolSearchKind::OnlyTypes,
                 WorkspaceSymbolSearchKindDef::AllSymbols => WorkspaceSymbolSearchKind::AllSymbols,
             },
-            search_limit: *self.workspace_symbol_search_limit(),
+            search_limit: *self.workspace_symbol_search_limit(source_root),
         }
     }
 
@@ -2259,18 +2319,6 @@
     se.serialize_str(path.as_str())
 }
 
-impl ManifestOrProjectJson {
-    fn manifest(&self) -> Option<&Utf8Path> {
-        match self {
-            ManifestOrProjectJson::Manifest(manifest) => Some(manifest),
-            ManifestOrProjectJson::DiscoveredProjectJson { buildfile, .. } => {
-                Some(buildfile.as_ref())
-            }
-            ManifestOrProjectJson::ProjectJson(_) => None,
-        }
-    }
-}
-
 #[derive(Serialize, Deserialize, Debug, Clone)]
 #[serde(rename_all = "snake_case")]
 enum ExprFillDefaultDef {
@@ -3522,9 +3570,9 @@
         }));
 
         (config, _, _) = config.apply_change(change);
-        assert_eq!(config.cargo_targetDir(), &None);
+        assert_eq!(config.cargo_targetDir(None), &None);
         assert!(
-            matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir.is_none())
+            matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir.is_none())
         );
     }
 
@@ -3540,9 +3588,9 @@
 
         (config, _, _) = config.apply_change(change);
 
-        assert_eq!(config.cargo_targetDir(), &Some(TargetDirectory::UseSubdirectory(true)));
+        assert_eq!(config.cargo_targetDir(None), &Some(TargetDirectory::UseSubdirectory(true)));
         assert!(
-            matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("target/rust-analyzer")))
+            matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("target/rust-analyzer")))
         );
     }
 
@@ -3559,83 +3607,11 @@
         (config, _, _) = config.apply_change(change);
 
         assert_eq!(
-            config.cargo_targetDir(),
+            config.cargo_targetDir(None),
             &Some(TargetDirectory::Directory(Utf8PathBuf::from("other_folder")))
         );
         assert!(
-            matches!(config.flycheck(), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("other_folder")))
+            matches!(config.flycheck(None), FlycheckConfig::CargoCommand { options, .. } if options.target_dir == Some(Utf8PathBuf::from("other_folder")))
         );
     }
-
-    #[test]
-    fn toml_unknown_key() {
-        let config =
-            Config::new(AbsPathBuf::assert(project_root()), Default::default(), vec![], None);
-
-        let mut change = ConfigChange::default();
-
-        change.change_user_config(Some(
-            toml::toml! {
-                [cargo.cfgs]
-                these = "these"
-                should = "should"
-                be = "be"
-                valid = "valid"
-
-                [invalid.config]
-                err = "error"
-
-                [cargo]
-                target = "ok"
-
-                // FIXME: This should be an error
-                [cargo.sysroot]
-                non-table = "expected"
-            }
-            .to_string()
-            .into(),
-        ));
-
-        let (config, e, _) = config.apply_change(change);
-        expect_test::expect![[r#"
-            ConfigErrors(
-                [
-                    Toml {
-                        config_key: "invalid/config/err",
-                        error: Error {
-                            inner: Error {
-                                inner: TomlError {
-                                    message: "unexpected field",
-                                    raw: None,
-                                    keys: [],
-                                    span: None,
-                                },
-                            },
-                        },
-                    },
-                ],
-            )
-        "#]]
-        .assert_debug_eq(&e);
-        let mut change = ConfigChange::default();
-
-        change.change_user_config(Some(
-            toml::toml! {
-                [cargo.cfgs]
-                these = "these"
-                should = "should"
-                be = "be"
-                valid = "valid"
-            }
-            .to_string()
-            .into(),
-        ));
-        let (_, e, _) = config.apply_change(change);
-        expect_test::expect![[r#"
-            ConfigErrors(
-                [],
-            )
-        "#]]
-        .assert_debug_eq(&e);
-    }
 }
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index 9d0082c..89487aa 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -540,7 +540,7 @@
     }
 
     pub(crate) fn respond(&mut self, response: lsp_server::Response) {
-        if let Some((method, start)) = self.req_queue.incoming.complete(response.id.clone()) {
+        if let Some((method, start)) = self.req_queue.incoming.complete(&response.id) {
             if let Some(err) = &response.error {
                 if err.message.starts_with("server panicked") {
                     self.poke_rust_analyzer_developer(format!("{}, check the log", err.message))
@@ -631,6 +631,10 @@
         file_id_to_url(&self.vfs_read(), id)
     }
 
+    pub(crate) fn vfs_path_to_file_id(&self, vfs_path: &VfsPath) -> anyhow::Result<FileId> {
+        vfs_path_to_file_id(&self.vfs_read(), vfs_path)
+    }
+
     pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancellable<LineIndex> {
         let endings = self.vfs.read().1[&file_id];
         let index = self.analysis.file_line_index(file_id)?;
@@ -725,3 +729,9 @@
     let res = vfs.file_id(&path).ok_or_else(|| anyhow::format_err!("file not found: {path}"))?;
     Ok(res)
 }
+
+pub(crate) fn vfs_path_to_file_id(vfs: &vfs::Vfs, vfs_path: &VfsPath) -> anyhow::Result<FileId> {
+    let res =
+        vfs.file_id(vfs_path).ok_or_else(|| anyhow::format_err!("file not found: {vfs_path}"))?;
+    Ok(res)
+}
diff --git a/crates/rust-analyzer/src/handlers/dispatch.rs b/crates/rust-analyzer/src/handlers/dispatch.rs
index f03de8c..ed7bf27 100644
--- a/crates/rust-analyzer/src/handlers/dispatch.rs
+++ b/crates/rust-analyzer/src/handlers/dispatch.rs
@@ -325,14 +325,14 @@
     pub(crate) fn on_sync_mut<N>(
         &mut self,
         f: fn(&mut GlobalState, N::Params) -> anyhow::Result<()>,
-    ) -> anyhow::Result<&mut Self>
+    ) -> &mut Self
     where
         N: lsp_types::notification::Notification,
         N::Params: DeserializeOwned + Send + Debug,
     {
         let not = match self.not.take() {
             Some(it) => it,
-            None => return Ok(self),
+            None => return self,
         };
 
         let _guard = tracing::info_span!("notification", method = ?not.method).entered();
@@ -344,7 +344,7 @@
             }
             Err(ExtractError::MethodMismatch(not)) => {
                 self.not = Some(not);
-                return Ok(self);
+                return self;
             }
         };
 
@@ -355,8 +355,10 @@
             version(),
             N::METHOD
         ));
-        f(self.global_state, params)?;
-        Ok(self)
+        if let Err(e) = f(self.global_state, params) {
+            tracing::error!(handler = %N::METHOD, error = %e, "notification handler failed");
+        }
+        self
     }
 
     pub(crate) fn finish(&mut self) {
diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs
index 38b88ff..49b1ba3 100644
--- a/crates/rust-analyzer/src/handlers/notification.rs
+++ b/crates/rust-analyzer/src/handlers/notification.rs
@@ -145,14 +145,18 @@
     state: &mut GlobalState,
     params: DidSaveTextDocumentParams,
 ) -> anyhow::Result<()> {
-    if state.config.script_rebuild_on_save() && state.build_deps_changed {
-        state.build_deps_changed = false;
-        state
-            .fetch_build_data_queue
-            .request_op("build_deps_changed - save notification".to_owned(), ());
-    }
-
     if let Ok(vfs_path) = from_proto::vfs_path(&params.text_document.uri) {
+        let snap = state.snapshot();
+        let file_id = snap.vfs_path_to_file_id(&vfs_path)?;
+        let sr = snap.analysis.source_root_id(file_id)?;
+
+        if state.config.script_rebuild_on_save(Some(sr)) && state.build_deps_changed {
+            state.build_deps_changed = false;
+            state
+                .fetch_build_data_queue
+                .request_op("build_deps_changed - save notification".to_owned(), ());
+        }
+
         // Re-fetch workspaces if a workspace related file has changed
         if let Some(path) = vfs_path.as_path() {
             let additional_files = &state
@@ -182,15 +186,16 @@
             }
         }
 
-        if !state.config.check_on_save() || run_flycheck(state, vfs_path) {
+        if !state.config.check_on_save(Some(sr)) || run_flycheck(state, vfs_path) {
             return Ok(());
         }
-    } else if state.config.check_on_save() {
+    } else if state.config.check_on_save(None) {
         // No specific flycheck was triggered, so let's trigger all of them.
         for flycheck in state.flycheck.iter() {
             flycheck.restart_workspace(None);
         }
     }
+
     Ok(())
 }
 
@@ -288,6 +293,7 @@
     let file_id = state.vfs.read().0.file_id(&vfs_path);
     if let Some(file_id) = file_id {
         let world = state.snapshot();
+        let source_root_id = world.analysis.source_root_id(file_id).ok();
         let mut updated = false;
         let task = move || -> std::result::Result<(), ide::Cancelled> {
             // Is the target binary? If so we let flycheck run only for the workspace that contains the crate.
@@ -351,7 +357,7 @@
                             .targets
                             .iter()
                             .any(|&it| crate_root_paths.contains(&cargo[it].root.as_path()));
-                        has_target_with_root.then(|| cargo[pkg].name.clone())
+                        has_target_with_root.then(|| cargo.package_flag(&cargo[pkg]))
                     }),
                     project_model::ProjectWorkspaceKind::Json(project) => {
                         if !project.crates().any(|(_, krate)| {
@@ -373,9 +379,9 @@
                 for (id, package) in workspace_ids.clone() {
                     if id == flycheck.id() {
                         updated = true;
-                        match package
-                            .filter(|_| !world.config.flycheck_workspace() || target.is_some())
-                        {
+                        match package.filter(|_| {
+                            !world.config.flycheck_workspace(source_root_id) || target.is_some()
+                        }) {
                             Some(package) => flycheck
                                 .restart_for_package(package, target.clone().map(TupleExt::head)),
                             None => flycheck.restart_workspace(saved_file.clone()),
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs
index 1ad5ff0..bcbd970 100644
--- a/crates/rust-analyzer/src/handlers/request.rs
+++ b/crates/rust-analyzer/src/handlers/request.rs
@@ -40,7 +40,10 @@
     hack_recover_crate_name,
     line_index::LineEndings,
     lsp::{
-        ext::InternalTestingFetchConfigParams,
+        ext::{
+            InternalTestingFetchConfigOption, InternalTestingFetchConfigParams,
+            InternalTestingFetchConfigResponse,
+        },
         from_proto, to_proto,
         utils::{all_edits_are_disjoint, invalid_params_error},
         LspError,
@@ -256,7 +259,7 @@
 
             let handle = CargoTestHandle::new(
                 test_path,
-                state.config.cargo_test_options(),
+                state.config.cargo_test_options(None),
                 cargo.workspace_root(),
                 test_target,
                 state.test_run_sender.clone(),
@@ -565,7 +568,7 @@
 ) -> anyhow::Result<Option<lsp_types::WorkspaceSymbolResponse>> {
     let _p = tracing::info_span!("handle_workspace_symbol").entered();
 
-    let config = snap.config.workspace_symbol();
+    let config = snap.config.workspace_symbol(None);
     let (all_symbols, libs) = decide_search_scope_and_kind(&params, &config);
 
     let query = {
@@ -852,6 +855,7 @@
 ) -> anyhow::Result<Vec<lsp_ext::Runnable>> {
     let _p = tracing::info_span!("handle_runnables").entered();
     let file_id = from_proto::file_id(&snap, &params.text_document.uri)?;
+    let source_root = snap.analysis.source_root_id(file_id).ok();
     let line_index = snap.file_line_index(file_id)?;
     let offset = params.position.and_then(|it| from_proto::offset(&line_index, it).ok());
     let target_spec = TargetSpec::for_file(&snap, file_id)?;
@@ -894,7 +898,7 @@
     }
 
     // Add `cargo check` and `cargo test` for all targets of the whole package
-    let config = snap.config.runnables();
+    let config = snap.config.runnables(source_root);
     match target_spec {
         Some(TargetSpec::Cargo(spec)) => {
             let is_crate_no_std = snap.analysis.is_crate_no_std(spec.crate_id)?;
@@ -1602,14 +1606,14 @@
     anyhow::ensure!(snap.file_exists(file_id), "Invalid LSP resolve data");
 
     let line_index = snap.file_line_index(file_id)?;
-    let hint_position = from_proto::offset(&line_index, original_hint.position)?;
+    let range = from_proto::text_range(&line_index, resolve_data.resolve_range)?;
 
     let mut forced_resolve_inlay_hints_config = snap.config.inlay_hints();
     forced_resolve_inlay_hints_config.fields_to_resolve = InlayFieldsToResolve::empty();
     let resolve_hints = snap.analysis.inlay_hints_resolve(
         &forced_resolve_inlay_hints_config,
         file_id,
-        hint_position,
+        range,
         hash,
         |hint| {
             std::hash::BuildHasher::hash_one(
@@ -2119,7 +2123,7 @@
         RustfmtConfig::Rustfmt { extra_args, enable_range_formatting } => {
             // FIXME: Set RUSTUP_TOOLCHAIN
             let mut cmd = process::Command::new(toolchain::Tool::Rustfmt.path());
-            cmd.envs(snap.config.extra_env());
+            cmd.envs(snap.config.extra_env(source_root_id));
             cmd.args(extra_args);
 
             if let Some(edition) = edition {
@@ -2177,7 +2181,7 @@
                 _ => process::Command::new(cmd),
             };
 
-            cmd.envs(snap.config.extra_env());
+            cmd.envs(snap.config.extra_env(source_root_id));
             cmd.args(args);
             cmd
         }
@@ -2291,7 +2295,7 @@
 pub(crate) fn internal_testing_fetch_config(
     state: GlobalStateSnapshot,
     params: InternalTestingFetchConfigParams,
-) -> anyhow::Result<serde_json::Value> {
+) -> anyhow::Result<Option<InternalTestingFetchConfigResponse>> {
     let source_root = params
         .text_document
         .map(|it| {
@@ -2301,15 +2305,18 @@
                 .map_err(anyhow::Error::from)
         })
         .transpose()?;
-    serde_json::to_value(match &*params.config {
-        "local" => state.config.assist(source_root).assist_emit_must_use,
-        "workspace" => matches!(
-            state.config.rustfmt(source_root),
-            RustfmtConfig::Rustfmt { enable_range_formatting: true, .. }
-        ),
-        _ => return Err(anyhow::anyhow!("Unknown test config key: {}", params.config)),
-    })
-    .map_err(Into::into)
+    Ok(Some(match params.config {
+        InternalTestingFetchConfigOption::AssistEmitMustUse => {
+            InternalTestingFetchConfigResponse::AssistEmitMustUse(
+                state.config.assist(source_root).assist_emit_must_use,
+            )
+        }
+        InternalTestingFetchConfigOption::CheckWorkspace => {
+            InternalTestingFetchConfigResponse::CheckWorkspace(
+                state.config.flycheck_workspace(source_root),
+            )
+        }
+    }))
 }
 
 /// Searches for the directory of a Rust crate given this crate's root file path.
diff --git a/crates/rust-analyzer/src/integrated_benchmarks.rs b/crates/rust-analyzer/src/integrated_benchmarks.rs
index 28f4b80..118469d 100644
--- a/crates/rust-analyzer/src/integrated_benchmarks.rs
+++ b/crates/rust-analyzer/src/integrated_benchmarks.rs
@@ -167,6 +167,7 @@
             prefer_absolute: false,
             snippets: Vec::new(),
             limit: None,
+            add_semicolon_to_unit: true,
         };
         let position =
             FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
@@ -213,6 +214,7 @@
             prefer_absolute: false,
             snippets: Vec::new(),
             limit: None,
+            add_semicolon_to_unit: true,
         };
         let position =
             FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
@@ -257,6 +259,7 @@
             prefer_absolute: false,
             snippets: Vec::new(),
             limit: None,
+            add_semicolon_to_unit: true,
         };
         let position =
             FilePosition { file_id, offset: TextSize::try_from(completion_offset).unwrap() };
diff --git a/crates/rust-analyzer/src/lsp/ext.rs b/crates/rust-analyzer/src/lsp/ext.rs
index 8d1a686..618481b 100644
--- a/crates/rust-analyzer/src/lsp/ext.rs
+++ b/crates/rust-analyzer/src/lsp/ext.rs
@@ -16,9 +16,22 @@
 
 pub enum InternalTestingFetchConfig {}
 
+#[derive(Deserialize, Serialize, Debug)]
+pub enum InternalTestingFetchConfigOption {
+    AssistEmitMustUse,
+    CheckWorkspace,
+}
+
+#[derive(Deserialize, Serialize, Debug, PartialEq, Eq)]
+pub enum InternalTestingFetchConfigResponse {
+    AssistEmitMustUse(bool),
+    CheckWorkspace(bool),
+}
+
 impl Request for InternalTestingFetchConfig {
     type Params = InternalTestingFetchConfigParams;
-    type Result = serde_json::Value;
+    // Option is solely to circumvent Default bound.
+    type Result = Option<InternalTestingFetchConfigResponse>;
     const METHOD: &'static str = "rust-analyzer-internal/internalTestingFetchConfig";
 }
 
@@ -26,7 +39,7 @@
 #[serde(rename_all = "camelCase")]
 pub struct InternalTestingFetchConfigParams {
     pub text_document: Option<TextDocumentIdentifier>,
-    pub config: String,
+    pub config: InternalTestingFetchConfigOption,
 }
 pub enum AnalyzerStatus {}
 
@@ -819,6 +832,7 @@
     pub file_id: u32,
     // This is a string instead of a u64 as javascript can't represent u64 fully
     pub hash: String,
+    pub resolve_range: lsp_types::Range,
     pub version: Option<i32>,
 }
 
diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs
index eb6bc2a..4902c9f 100644
--- a/crates/rust-analyzer/src/lsp/to_proto.rs
+++ b/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -80,6 +80,7 @@
         | SymbolKind::ValueParam
         | SymbolKind::Label => lsp_types::SymbolKind::VARIABLE,
         SymbolKind::Union => lsp_types::SymbolKind::STRUCT,
+        SymbolKind::InlineAsmRegOrRegClass => lsp_types::SymbolKind::VARIABLE,
     }
 }
 
@@ -159,6 +160,7 @@
             SymbolKind::Variant => lsp_types::CompletionItemKind::ENUM_MEMBER,
             SymbolKind::BuiltinAttr => lsp_types::CompletionItemKind::FUNCTION,
             SymbolKind::ToolModule => lsp_types::CompletionItemKind::MODULE,
+            SymbolKind::InlineAsmRegOrRegClass => lsp_types::CompletionItemKind::KEYWORD,
         },
     }
 }
@@ -228,8 +230,12 @@
     line_index: &LineIndex,
     version: Option<i32>,
     tdpp: lsp_types::TextDocumentPositionParams,
-    items: Vec<CompletionItem>,
+    mut items: Vec<CompletionItem>,
 ) -> Vec<lsp_types::CompletionItem> {
+    if config.completion_hide_deprecated() {
+        items.retain(|item| !item.deprecated);
+    }
+
     let max_relevance = items.iter().map(|it| it.relevance.score()).max().unwrap_or_default();
     let mut res = Vec::with_capacity(items.len());
     for item in items {
@@ -452,10 +458,13 @@
     file_id: FileId,
     mut inlay_hint: InlayHint,
 ) -> Cancellable<lsp_types::InlayHint> {
-    let resolve_hash = inlay_hint.needs_resolve().then(|| {
-        std::hash::BuildHasher::hash_one(
-            &std::hash::BuildHasherDefault::<FxHasher>::default(),
-            &inlay_hint,
+    let resolve_range_and_hash = inlay_hint.needs_resolve().map(|range| {
+        (
+            range,
+            std::hash::BuildHasher::hash_one(
+                &std::hash::BuildHasherDefault::<FxHasher>::default(),
+                &inlay_hint,
+            ),
         )
     });
 
@@ -465,7 +474,7 @@
         .visual_studio_code_version()
         // https://github.com/microsoft/vscode/issues/193124
         .map_or(true, |version| VersionReq::parse(">=1.86.0").unwrap().matches(version))
-        && resolve_hash.is_some()
+        && resolve_range_and_hash.is_some()
         && fields_to_resolve.resolve_text_edits
     {
         something_to_resolve |= inlay_hint.text_edit.is_some();
@@ -477,16 +486,17 @@
         snap,
         fields_to_resolve,
         &mut something_to_resolve,
-        resolve_hash.is_some(),
+        resolve_range_and_hash.is_some(),
         inlay_hint.label,
     )?;
 
-    let data = match resolve_hash {
-        Some(hash) if something_to_resolve => Some(
+    let data = match resolve_range_and_hash {
+        Some((resolve_range, hash)) if something_to_resolve => Some(
             to_value(lsp_ext::InlayHintResolveData {
                 file_id: file_id.index(),
                 hash: hash.to_string(),
                 version: snap.file_version(file_id),
+                resolve_range: range(line_index, resolve_range),
             })
             .unwrap(),
         ),
@@ -694,6 +704,7 @@
             SymbolKind::ProcMacro => types::PROC_MACRO,
             SymbolKind::BuiltinAttr => types::BUILTIN_ATTRIBUTE,
             SymbolKind::ToolModule => types::TOOL_MODULE,
+            SymbolKind::InlineAsmRegOrRegClass => types::KEYWORD,
         },
         HlTag::AttributeBracket => types::ATTRIBUTE_BRACKET,
         HlTag::BoolLiteral => types::BOOLEAN,
@@ -1365,8 +1376,9 @@
     snap: &GlobalStateSnapshot,
     runnable: Runnable,
 ) -> Cancellable<Option<lsp_ext::Runnable>> {
-    let config = snap.config.runnables();
     let target_spec = TargetSpec::for_file(snap, runnable.nav.file_id)?;
+    let source_root = snap.analysis.source_root_id(runnable.nav.file_id).ok();
+    let config = snap.config.runnables(source_root);
 
     match target_spec {
         Some(TargetSpec::Cargo(spec)) => {
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 616d6b4..8355923 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -4,6 +4,7 @@
 use std::{
     fmt,
     ops::Div as _,
+    panic::AssertUnwindSafe,
     time::{Duration, Instant},
 };
 
@@ -195,7 +196,7 @@
             ) {
                 return Ok(());
             }
-            self.handle_event(event)?;
+            self.handle_event(event);
         }
 
         Err(anyhow::anyhow!("A receiver has been dropped, something panicked!"))
@@ -277,7 +278,7 @@
         .map(Some)
     }
 
-    fn handle_event(&mut self, event: Event) -> anyhow::Result<()> {
+    fn handle_event(&mut self, event: Event) {
         let loop_start = Instant::now();
         let _p = tracing::info_span!("GlobalState::handle_event", event = %event).entered();
 
@@ -294,7 +295,7 @@
         match event {
             Event::Lsp(msg) => match msg {
                 lsp_server::Message::Request(req) => self.on_new_request(loop_start, req),
-                lsp_server::Message::Notification(not) => self.on_notification(not)?,
+                lsp_server::Message::Notification(not) => self.on_notification(not),
                 lsp_server::Message::Response(resp) => self.complete_request(resp),
             },
             Event::QueuedTask(task) => {
@@ -404,7 +405,7 @@
         if self.is_quiescent() {
             let became_quiescent = !was_quiescent;
             if became_quiescent {
-                if self.config.check_on_save() {
+                if self.config.check_on_save(None) {
                     // Project has loaded properly, kick off initial flycheck
                     self.flycheck.iter().for_each(|flycheck| flycheck.restart_workspace(None));
                 }
@@ -434,7 +435,7 @@
 
             let project_or_mem_docs_changed =
                 became_quiescent || state_changed || memdocs_added_or_removed;
-            if project_or_mem_docs_changed && self.config.publish_diagnostics() {
+            if project_or_mem_docs_changed && self.config.publish_diagnostics(None) {
                 self.update_diagnostics();
             }
             if project_or_mem_docs_changed && self.config.test_explorer() {
@@ -455,7 +456,7 @@
             }
         }
 
-        if self.config.cargo_autoreload_config()
+        if self.config.cargo_autoreload_config(None)
             || self.config.discover_workspace_config().is_some()
         {
             if let Some((cause, FetchWorkspaceRequest { path, force_crate_graph_reload })) =
@@ -486,7 +487,6 @@
                 "overly long loop turn took {loop_duration:?} (event handling took {event_handling_duration:?}): {event_dbg_msg}"
             ));
         }
-        Ok(())
     }
 
     fn prime_caches(&mut self, cause: String) {
@@ -552,23 +552,33 @@
                 let fetch_semantic =
                     self.vfs_done && self.fetch_workspaces_queue.last_op_result().is_some();
                 move |sender| {
-                    let diags = fetch_native_diagnostics(
-                        &snapshot,
-                        subscriptions.clone(),
-                        slice.clone(),
-                        NativeDiagnosticsFetchKind::Syntax,
-                    );
+                    // We aren't observing the semantics token cache here
+                    let snapshot = AssertUnwindSafe(&snapshot);
+                    let Ok(diags) = std::panic::catch_unwind(|| {
+                        fetch_native_diagnostics(
+                            &snapshot,
+                            subscriptions.clone(),
+                            slice.clone(),
+                            NativeDiagnosticsFetchKind::Syntax,
+                        )
+                    }) else {
+                        return;
+                    };
                     sender
                         .send(Task::Diagnostics(DiagnosticsTaskKind::Syntax(generation, diags)))
                         .unwrap();
 
                     if fetch_semantic {
-                        let diags = fetch_native_diagnostics(
-                            &snapshot,
-                            subscriptions,
-                            slice,
-                            NativeDiagnosticsFetchKind::Semantic,
-                        );
+                        let Ok(diags) = std::panic::catch_unwind(|| {
+                            fetch_native_diagnostics(
+                                &snapshot,
+                                subscriptions.clone(),
+                                slice.clone(),
+                                NativeDiagnosticsFetchKind::Semantic,
+                            )
+                        }) else {
+                            return;
+                        };
                         sender
                             .send(Task::Diagnostics(DiagnosticsTaskKind::Semantic(
                                 generation, diags,
@@ -875,7 +885,7 @@
                 self.discover_workspace_queue.op_completed(());
 
                 let mut config = Config::clone(&*self.config);
-                config.add_linked_projects(project, buildfile);
+                config.add_discovered_project_from_command(project, buildfile);
                 self.update_configuration(config);
             }
             DiscoverProjectMessage::Progress { message } => {
@@ -925,7 +935,7 @@
             FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => {
                 let snap = self.snapshot();
                 let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
-                    &self.config.diagnostics_map(),
+                    &self.config.diagnostics_map(None),
                     &diagnostic,
                     &workspace_root,
                     &snap,
@@ -973,9 +983,9 @@
                 // When we're running multiple flychecks, we have to include a disambiguator in
                 // the title, or the editor complains. Note that this is a user-facing string.
                 let title = if self.flycheck.len() == 1 {
-                    format!("{}", self.config.flycheck())
+                    format!("{}", self.config.flycheck(None))
                 } else {
-                    format!("{} (#{})", self.config.flycheck(), id + 1)
+                    format!("{} (#{})", self.config.flycheck(None), id + 1)
                 };
                 self.report_progress(
                     &title,
@@ -1105,37 +1115,32 @@
     }
 
     /// Handles an incoming notification.
-    fn on_notification(&mut self, not: Notification) -> anyhow::Result<()> {
+    fn on_notification(&mut self, not: Notification) {
         let _p =
             span!(Level::INFO, "GlobalState::on_notification", not.method = ?not.method).entered();
         use crate::handlers::notification as handlers;
         use lsp_types::notification as notifs;
 
         NotificationDispatcher { not: Some(not), global_state: self }
-            .on_sync_mut::<notifs::Cancel>(handlers::handle_cancel)?
+            .on_sync_mut::<notifs::Cancel>(handlers::handle_cancel)
             .on_sync_mut::<notifs::WorkDoneProgressCancel>(
                 handlers::handle_work_done_progress_cancel,
-            )?
-            .on_sync_mut::<notifs::DidOpenTextDocument>(handlers::handle_did_open_text_document)?
-            .on_sync_mut::<notifs::DidChangeTextDocument>(
-                handlers::handle_did_change_text_document,
-            )?
-            .on_sync_mut::<notifs::DidCloseTextDocument>(handlers::handle_did_close_text_document)?
-            .on_sync_mut::<notifs::DidSaveTextDocument>(handlers::handle_did_save_text_document)?
+            )
+            .on_sync_mut::<notifs::DidOpenTextDocument>(handlers::handle_did_open_text_document)
+            .on_sync_mut::<notifs::DidChangeTextDocument>(handlers::handle_did_change_text_document)
+            .on_sync_mut::<notifs::DidCloseTextDocument>(handlers::handle_did_close_text_document)
+            .on_sync_mut::<notifs::DidSaveTextDocument>(handlers::handle_did_save_text_document)
             .on_sync_mut::<notifs::DidChangeConfiguration>(
                 handlers::handle_did_change_configuration,
-            )?
+            )
             .on_sync_mut::<notifs::DidChangeWorkspaceFolders>(
                 handlers::handle_did_change_workspace_folders,
-            )?
-            .on_sync_mut::<notifs::DidChangeWatchedFiles>(
-                handlers::handle_did_change_watched_files,
-            )?
-            .on_sync_mut::<lsp_ext::CancelFlycheck>(handlers::handle_cancel_flycheck)?
-            .on_sync_mut::<lsp_ext::ClearFlycheck>(handlers::handle_clear_flycheck)?
-            .on_sync_mut::<lsp_ext::RunFlycheck>(handlers::handle_run_flycheck)?
-            .on_sync_mut::<lsp_ext::AbortRunTest>(handlers::handle_abort_run_test)?
+            )
+            .on_sync_mut::<notifs::DidChangeWatchedFiles>(handlers::handle_did_change_watched_files)
+            .on_sync_mut::<lsp_ext::CancelFlycheck>(handlers::handle_cancel_flycheck)
+            .on_sync_mut::<lsp_ext::ClearFlycheck>(handlers::handle_clear_flycheck)
+            .on_sync_mut::<lsp_ext::RunFlycheck>(handlers::handle_run_flycheck)
+            .on_sync_mut::<lsp_ext::AbortRunTest>(handlers::handle_abort_run_test)
             .finish();
-        Ok(())
     }
 }
diff --git a/crates/rust-analyzer/src/op_queue.rs b/crates/rust-analyzer/src/op_queue.rs
index eab9733..5c4c858 100644
--- a/crates/rust-analyzer/src/op_queue.rs
+++ b/crates/rust-analyzer/src/op_queue.rs
@@ -37,9 +37,13 @@
 }
 
 impl<Args, Output> OpQueue<Args, Output> {
+    /// Request an operation to start.
     pub(crate) fn request_op(&mut self, reason: Cause, args: Args) {
         self.op_requested = Some((reason, args));
     }
+
+    /// If there was an operation requested, mark this queue as
+    /// started and return the request arguments.
     pub(crate) fn should_start_op(&mut self) -> Option<(Cause, Args)> {
         if self.op_in_progress {
             return None;
@@ -47,18 +51,25 @@
         self.op_in_progress = self.op_requested.is_some();
         self.op_requested.take()
     }
+
+    /// Mark an operation as completed.
     pub(crate) fn op_completed(&mut self, result: Output) {
         assert!(self.op_in_progress);
         self.op_in_progress = false;
         self.last_op_result = result;
     }
 
+    /// Get the result of the last operation.
     pub(crate) fn last_op_result(&self) -> &Output {
         &self.last_op_result
     }
+
+    // Is there an operation that has started, but hasn't yet finished?
     pub(crate) fn op_in_progress(&self) -> bool {
         self.op_in_progress
     }
+
+    // Has an operation been requested?
     pub(crate) fn op_requested(&self) -> bool {
         self.op_requested.is_some()
     }
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 6836613..f676571 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -16,8 +16,9 @@
 use std::{iter, mem};
 
 use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros, ProcMacrosBuilder};
+use ide::CrateId;
 use ide_db::{
-    base_db::{salsa::Durability, CrateGraph, ProcMacroPaths, Version},
+    base_db::{salsa::Durability, CrateGraph, CrateWorkspaceData, ProcMacroPaths},
     FxHashMap,
 };
 use itertools::Itertools;
@@ -100,7 +101,7 @@
         {
             let req = FetchWorkspaceRequest { path: None, force_crate_graph_reload: false };
             self.fetch_workspaces_queue.request_op("discovered projects changed".to_owned(), req)
-        } else if self.config.flycheck() != old_config.flycheck() {
+        } else if self.config.flycheck(None) != old_config.flycheck(None) {
             self.reload_flycheck();
         }
 
@@ -122,7 +123,7 @@
         };
         let mut message = String::new();
 
-        if !self.config.cargo_autoreload()
+        if !self.config.cargo_autoreload_config(None)
             && self.is_quiescent()
             && self.fetch_workspaces_queue.op_requested()
             && self.config.discover_workspace_config().is_none()
@@ -264,7 +265,7 @@
                 .map(ManifestPath::try_from)
                 .filter_map(Result::ok)
                 .collect();
-            let cargo_config = self.config.cargo();
+            let cargo_config = self.config.cargo(None);
             let discover_command = self.config.discover_workspace_config().cloned();
             let is_quiescent = !(self.discover_workspace_queue.op_in_progress()
                 || self.vfs_progress_config_version < self.vfs_config_version
@@ -357,7 +358,7 @@
     pub(crate) fn fetch_build_data(&mut self, cause: Cause) {
         info!(%cause, "will fetch build data");
         let workspaces = Arc::clone(&self.workspaces);
-        let config = self.config.cargo();
+        let config = self.config.cargo(None);
         let root_path = self.config.root_path().clone();
 
         self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, move |sender| {
@@ -382,7 +383,7 @@
 
     pub(crate) fn fetch_proc_macros(&mut self, cause: Cause, paths: Vec<ProcMacroPaths>) {
         info!(%cause, "will load proc macros");
-        let ignored_proc_macros = self.config.ignored_proc_macros().clone();
+        let ignored_proc_macros = self.config.ignored_proc_macros(None).clone();
         let proc_macro_clients = self.proc_macro_clients.clone();
 
         self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, move |sender| {
@@ -507,7 +508,7 @@
             // FIXME: can we abort the build scripts here if they are already running?
             self.workspaces = Arc::new(workspaces);
 
-            if self.config.run_build_scripts() {
+            if self.config.run_build_scripts(None) {
                 self.build_deps_changed = false;
                 self.fetch_build_data_queue.request_op("workspace updated".to_owned(), ());
             }
@@ -627,7 +628,7 @@
                         ..
                     } => cargo_config_extra_env
                         .iter()
-                        .chain(self.config.extra_env())
+                        .chain(self.config.extra_env(None))
                         .map(|(a, b)| (a.clone(), b.clone()))
                         .chain(
                             ws.sysroot
@@ -692,7 +693,7 @@
             })
             .collect();
 
-        let (crate_graph, proc_macro_paths, layouts, toolchains) = {
+        let (crate_graph, proc_macro_paths, ws_data) = {
             // Create crate graph from all the workspaces
             let vfs = &mut self.vfs.write().0;
 
@@ -702,7 +703,7 @@
                 vfs.file_id(&vfs_path)
             };
 
-            ws_to_crate_graph(&self.workspaces, self.config.extra_env(), load)
+            ws_to_crate_graph(&self.workspaces, self.config.extra_env(None), load)
         };
         let mut change = ChangeWithProcMacros::new();
         if self.config.expand_proc_macros() {
@@ -721,9 +722,7 @@
                     .collect(),
             );
         }
-        change.set_crate_graph(crate_graph);
-        change.set_target_data_layouts(layouts);
-        change.set_toolchains(toolchains);
+        change.set_crate_graph(crate_graph, ws_data);
         self.analysis_host.apply_change(change);
         self.report_progress(
             "Building CrateGraph",
@@ -791,7 +790,7 @@
 
     fn reload_flycheck(&mut self) {
         let _p = tracing::info_span!("GlobalState::reload_flycheck").entered();
-        let config = self.config.flycheck();
+        let config = self.config.flycheck(None);
         let sender = self.flycheck_sender.clone();
         let invocation_strategy = match config {
             FlycheckConfig::CargoCommand { .. } => {
@@ -863,51 +862,27 @@
     workspaces: &[ProjectWorkspace],
     extra_env: &FxHashMap<String, String>,
     mut load: impl FnMut(&AbsPath) -> Option<vfs::FileId>,
-) -> (CrateGraph, Vec<ProcMacroPaths>, Vec<Result<Arc<str>, Arc<str>>>, Vec<Option<Version>>) {
+) -> (CrateGraph, Vec<ProcMacroPaths>, FxHashMap<CrateId, Arc<CrateWorkspaceData>>) {
     let mut crate_graph = CrateGraph::default();
     let mut proc_macro_paths = Vec::default();
-    let mut layouts = Vec::default();
-    let mut toolchains = Vec::default();
-    let e = Err(Arc::from("missing layout"));
+    let mut ws_data = FxHashMap::default();
     for ws in workspaces {
         let (other, mut crate_proc_macros) = ws.to_crate_graph(&mut load, extra_env);
-        let num_layouts = layouts.len();
-        let num_toolchains = toolchains.len();
         let ProjectWorkspace { toolchain, target_layout, .. } = ws;
 
-        let mapping = crate_graph.extend(
-            other,
-            &mut crate_proc_macros,
-            |(cg_id, cg_data), (_o_id, o_data)| {
-                // if the newly created crate graph's layout is equal to the crate of the merged graph, then
-                // we can merge the crates.
-                let id = cg_id.into_raw().into_u32() as usize;
-                layouts[id] == *target_layout && toolchains[id] == *toolchain && cg_data == o_data
-            },
-        );
+        let mapping = crate_graph.extend(other, &mut crate_proc_macros);
         // Populate the side tables for the newly merged crates
-        mapping.values().for_each(|val| {
-            let idx = val.into_raw().into_u32() as usize;
-            // we only need to consider crates that were not merged and remapped, as the
-            // ones that were remapped already have the correct layout and toolchain
-            if idx >= num_layouts {
-                if layouts.len() <= idx {
-                    layouts.resize(idx + 1, e.clone());
-                }
-                layouts[idx].clone_from(target_layout);
-            }
-            if idx >= num_toolchains {
-                if toolchains.len() <= idx {
-                    toolchains.resize(idx + 1, None);
-                }
-                toolchains[idx].clone_from(toolchain);
-            }
-        });
+        ws_data.extend(mapping.values().copied().zip(iter::repeat(Arc::new(CrateWorkspaceData {
+            toolchain: toolchain.clone(),
+            data_layout: target_layout.clone(),
+            proc_macro_cwd: Some(ws.workspace_root().to_owned()),
+        }))));
         proc_macro_paths.push(crate_proc_macros);
     }
+
     crate_graph.shrink_to_fit();
     proc_macro_paths.shrink_to_fit();
-    (crate_graph, proc_macro_paths, layouts, toolchains)
+    (crate_graph, proc_macro_paths, ws_data)
 }
 
 pub(crate) fn should_refresh_for_change(
diff --git a/crates/rust-analyzer/src/target_spec.rs b/crates/rust-analyzer/src/target_spec.rs
index 954e13c..b4aa73d 100644
--- a/crates/rust-analyzer/src/target_spec.rs
+++ b/crates/rust-analyzer/src/target_spec.rs
@@ -113,7 +113,7 @@
         kind: &RunnableKind,
         cfg: &Option<CfgExpr>,
     ) -> (Vec<String>, Vec<String>) {
-        let config = snap.config.runnables();
+        let config = snap.config.runnables(None);
         let extra_test_binary_args = config.extra_test_binary_args;
 
         let mut cargo_args = Vec::new();
@@ -168,7 +168,7 @@
             (Default::default(), Default::default())
         };
 
-        let cargo_config = snap.config.cargo();
+        let cargo_config = snap.config.cargo(None);
 
         match &cargo_config.features {
             CargoFeatures::All => {
diff --git a/crates/rust-analyzer/tests/crate_graph.rs b/crates/rust-analyzer/tests/crate_graph.rs
deleted file mode 100644
index 04b6713..0000000
--- a/crates/rust-analyzer/tests/crate_graph.rs
+++ /dev/null
@@ -1,126 +0,0 @@
-use std::path::PathBuf;
-
-use project_model::{
-    CargoWorkspace, ManifestPath, Metadata, ProjectWorkspace, ProjectWorkspaceKind, Sysroot,
-    WorkspaceBuildScripts,
-};
-use rust_analyzer::ws_to_crate_graph;
-use rustc_hash::FxHashMap;
-use serde::de::DeserializeOwned;
-use vfs::{AbsPathBuf, FileId};
-
-fn load_cargo_with_fake_sysroot(file: &str) -> ProjectWorkspace {
-    let meta: Metadata = get_test_json_file(file);
-    let manifest_path =
-        ManifestPath::try_from(AbsPathBuf::try_from(meta.workspace_root.clone()).unwrap()).unwrap();
-    let cargo_workspace = CargoWorkspace::new(meta, manifest_path);
-    ProjectWorkspace {
-        kind: ProjectWorkspaceKind::Cargo {
-            cargo: cargo_workspace,
-            build_scripts: WorkspaceBuildScripts::default(),
-            rustc: Err(None),
-            cargo_config_extra_env: Default::default(),
-            error: None,
-        },
-        sysroot: get_fake_sysroot(),
-        rustc_cfg: Vec::new(),
-        cfg_overrides: Default::default(),
-        toolchain: None,
-        target_layout: Err("target_data_layout not loaded".into()),
-    }
-}
-
-fn get_test_json_file<T: DeserializeOwned>(file: &str) -> T {
-    let base = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
-    let file = base.join("tests/test_data").join(file);
-    let data = std::fs::read_to_string(file).unwrap();
-    let mut json = data.parse::<serde_json::Value>().unwrap();
-    fixup_paths(&mut json);
-    return serde_json::from_value(json).unwrap();
-
-    fn fixup_paths(val: &mut serde_json::Value) {
-        match val {
-            serde_json::Value::String(s) => replace_root(s, true),
-            serde_json::Value::Array(vals) => vals.iter_mut().for_each(fixup_paths),
-            serde_json::Value::Object(kvals) => kvals.values_mut().for_each(fixup_paths),
-            serde_json::Value::Null | serde_json::Value::Bool(_) | serde_json::Value::Number(_) => {
-            }
-        }
-    }
-}
-
-fn replace_root(s: &mut String, direction: bool) {
-    if direction {
-        let root = if cfg!(windows) { r#"C:\\ROOT\"# } else { "/ROOT/" };
-        *s = s.replace("$ROOT$", root)
-    } else {
-        let root = if cfg!(windows) { r#"C:\\\\ROOT\\"# } else { "/ROOT/" };
-        *s = s.replace(root, "$ROOT$")
-    }
-}
-
-fn get_fake_sysroot_path() -> PathBuf {
-    let base = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
-    base.join("../project-model/test_data/fake-sysroot")
-}
-
-fn get_fake_sysroot() -> Sysroot {
-    let sysroot_path = get_fake_sysroot_path();
-    // there's no `libexec/` directory with a `proc-macro-srv` binary in that
-    // fake sysroot, so we give them both the same path:
-    let sysroot_dir = AbsPathBuf::assert_utf8(sysroot_path);
-    let sysroot_src_dir = sysroot_dir.clone();
-    Sysroot::load(Some(sysroot_dir), Some(sysroot_src_dir))
-}
-
-#[test]
-fn test_deduplicate_origin_dev() {
-    let path_map = &mut FxHashMap::default();
-    let ws = load_cargo_with_fake_sysroot("deduplication_crate_graph_A.json");
-    let ws2 = load_cargo_with_fake_sysroot("deduplication_crate_graph_B.json");
-
-    let (crate_graph, ..) = ws_to_crate_graph(&[ws, ws2], &Default::default(), |path| {
-        let len = path_map.len();
-        Some(*path_map.entry(path.to_path_buf()).or_insert(FileId::from_raw(len as u32)))
-    });
-
-    let mut crates_named_p2 = vec![];
-    for id in crate_graph.iter() {
-        let krate = &crate_graph[id];
-        if let Some(name) = krate.display_name.as_ref() {
-            if name.to_string() == "p2" {
-                crates_named_p2.push(krate);
-            }
-        }
-    }
-
-    assert_eq!(crates_named_p2.len(), 1);
-    let p2 = crates_named_p2[0];
-    assert!(p2.origin.is_local());
-}
-
-#[test]
-fn test_deduplicate_origin_dev_rev() {
-    let path_map = &mut FxHashMap::default();
-    let ws = load_cargo_with_fake_sysroot("deduplication_crate_graph_B.json");
-    let ws2 = load_cargo_with_fake_sysroot("deduplication_crate_graph_A.json");
-
-    let (crate_graph, ..) = ws_to_crate_graph(&[ws, ws2], &Default::default(), |path| {
-        let len = path_map.len();
-        Some(*path_map.entry(path.to_path_buf()).or_insert(FileId::from_raw(len as u32)))
-    });
-
-    let mut crates_named_p2 = vec![];
-    for id in crate_graph.iter() {
-        let krate = &crate_graph[id];
-        if let Some(name) = krate.display_name.as_ref() {
-            if name.to_string() == "p2" {
-                crates_named_p2.push(krate);
-            }
-        }
-    }
-
-    assert_eq!(crates_named_p2.len(), 1);
-    let p2 = crates_named_p2[0];
-    assert!(p2.origin.is_local());
-}
diff --git a/crates/rust-analyzer/tests/slow-tests/ratoml.rs b/crates/rust-analyzer/tests/slow-tests/ratoml.rs
index 295d1d4..a857e0c 100644
--- a/crates/rust-analyzer/tests/slow-tests/ratoml.rs
+++ b/crates/rust-analyzer/tests/slow-tests/ratoml.rs
@@ -9,18 +9,13 @@
 use paths::Utf8PathBuf;
 
 use rust_analyzer::config::Config;
-use rust_analyzer::lsp::ext::{InternalTestingFetchConfig, InternalTestingFetchConfigParams};
+use rust_analyzer::lsp::ext::{
+    InternalTestingFetchConfig, InternalTestingFetchConfigOption, InternalTestingFetchConfigParams,
+    InternalTestingFetchConfigResponse,
+};
 use serde_json::json;
 use test_utils::skip_slow_tests;
 
-enum QueryType {
-    Local,
-    /// A query whose config key is a part of the global configs, so that
-    /// testing for changes to this config means testing if global changes
-    /// take affect.
-    Workspace,
-}
-
 struct RatomlTest {
     urls: Vec<Url>,
     server: Server,
@@ -158,20 +153,24 @@
         });
     }
 
-    fn query(&self, query: QueryType, source_file_idx: usize) -> bool {
-        let config = match query {
-            QueryType::Local => "local".to_owned(),
-            QueryType::Workspace => "workspace".to_owned(),
-        };
+    fn query(
+        &self,
+        query: InternalTestingFetchConfigOption,
+        source_file_idx: usize,
+        expected: InternalTestingFetchConfigResponse,
+    ) {
         let res = self.server.send_request::<InternalTestingFetchConfig>(
             InternalTestingFetchConfigParams {
                 text_document: Some(TextDocumentIdentifier {
                     uri: self.urls[source_file_idx].clone(),
                 }),
-                config,
+                config: query,
             },
         );
-        res.as_bool().unwrap()
+        assert_eq!(
+            serde_json::from_value::<InternalTestingFetchConfigResponse>(res).unwrap(),
+            expected
+        )
     }
 }
 
@@ -206,7 +205,11 @@
         })),
     );
 
-    assert!(server.query(QueryType::Local, 1));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        1,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
 }
 
 /// Checks if client config can be modified.
@@ -311,7 +314,11 @@
         None,
     );
 
-    assert!(server.query(QueryType::Local, 2));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        2,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
 }
 
 #[test]
@@ -341,12 +348,20 @@
         None,
     );
 
-    assert!(!server.query(QueryType::Local, 1));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        1,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(false),
+    );
     server.create(
         "//- /$$CONFIG_DIR$$/rust-analyzer/rust-analyzer.toml",
         RatomlTest::EMIT_MUST_USE.to_owned(),
     );
-    assert!(server.query(QueryType::Local, 1));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        1,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
 }
 
 #[test]
@@ -378,9 +393,17 @@
         None,
     );
 
-    assert!(server.query(QueryType::Local, 1));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        1,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
     server.edit(2, String::new());
-    assert!(!server.query(QueryType::Local, 1));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        1,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(false),
+    );
 }
 
 #[test]
@@ -412,9 +435,17 @@
         None,
     );
 
-    assert!(server.query(QueryType::Local, 1));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        1,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
     server.delete(2);
-    assert!(!server.query(QueryType::Local, 1));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        1,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(false),
+    );
 }
 
 #[test]
@@ -461,7 +492,11 @@
         None,
     );
 
-    assert!(server.query(QueryType::Local, 3));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
 }
 
 #[test]
@@ -508,9 +543,17 @@
         None,
     );
 
-    assert!(!server.query(QueryType::Local, 3));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(false),
+    );
     server.edit(1, "assist.emitMustUse = true".to_owned());
-    assert!(server.query(QueryType::Local, 3));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
 }
 
 #[test]
@@ -557,9 +600,17 @@
         None,
     );
 
-    assert!(server.query(QueryType::Local, 3));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
     server.delete(1);
-    assert!(!server.query(QueryType::Local, 3));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(false),
+    );
 }
 
 #[test]
@@ -606,9 +657,17 @@
         None,
     );
 
-    assert!(server.query(QueryType::Local, 3));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
     server.create("//- /p1/p2/rust-analyzer.toml", RatomlTest::EMIT_MUST_NOT_USE.to_owned());
-    assert!(!server.query(QueryType::Local, 3));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(false),
+    );
 }
 
 #[test]
@@ -656,9 +715,17 @@
         None,
     );
 
-    assert!(server.query(QueryType::Local, 3));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
     server.delete(1);
-    assert!(!server.query(QueryType::Local, 3));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(false),
+    );
 }
 
 #[test]
@@ -705,8 +772,16 @@
         None,
     );
 
-    assert!(server.query(QueryType::Local, 3));
-    assert!(server.query(QueryType::Local, 4));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        4,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
 }
 
 #[test]
@@ -744,7 +819,11 @@
         None,
     );
 
-    assert!(server.query(QueryType::Local, 3));
+    server.query(
+        InternalTestingFetchConfigOption::AssistEmitMustUse,
+        3,
+        InternalTestingFetchConfigResponse::AssistEmitMustUse(true),
+    );
 }
 
 /// If a root is non-local, so we cannot find what its parent is
@@ -765,7 +844,7 @@
 
 // [dependencies]
 // p2 = { path = "../p2" }
-// #,
+// "#,
 //                 r#"
 // //- /p1/src/lib.rs
 // enum Value {
@@ -836,7 +915,7 @@
         "#,
             r#"
 //- /p1/rust-analyzer.toml
-rustfmt.rangeFormatting.enable = true
+check.workspace = false
         "#,
             r#"
 //- /p1/src/lib.rs
@@ -848,7 +927,11 @@
         None,
     );
 
-    assert!(server.query(QueryType::Workspace, 2));
+    server.query(
+        InternalTestingFetchConfigOption::CheckWorkspace,
+        2,
+        InternalTestingFetchConfigResponse::CheckWorkspace(false),
+    )
 }
 
 #[test]
@@ -868,7 +951,7 @@
         "#,
             r#"
 //- /p1/rust-analyzer.toml
-rustfmt.rangeFormatting.enable = true
+check.workspace = false
     "#,
             r#"
 //- /p1/src/lib.rs
@@ -880,9 +963,17 @@
         None,
     );
 
-    assert!(server.query(QueryType::Workspace, 2));
-    server.edit(1, "rustfmt.rangeFormatting.enable = false".to_owned());
-    assert!(!server.query(QueryType::Workspace, 2));
+    server.query(
+        InternalTestingFetchConfigOption::CheckWorkspace,
+        2,
+        InternalTestingFetchConfigResponse::CheckWorkspace(false),
+    );
+    server.edit(1, "check.workspace = true".to_owned());
+    server.query(
+        InternalTestingFetchConfigOption::CheckWorkspace,
+        2,
+        InternalTestingFetchConfigResponse::CheckWorkspace(true),
+    );
 }
 
 #[test]
@@ -902,7 +993,7 @@
         "#,
             r#"
 //- /p1/rust-analyzer.toml
-rustfmt.rangeFormatting.enable = true
+check.workspace = false
        "#,
             r#"
 //- /p1/src/lib.rs
@@ -914,7 +1005,15 @@
         None,
     );
 
-    assert!(server.query(QueryType::Workspace, 2));
+    server.query(
+        InternalTestingFetchConfigOption::CheckWorkspace,
+        2,
+        InternalTestingFetchConfigResponse::CheckWorkspace(false),
+    );
     server.delete(1);
-    assert!(!server.query(QueryType::Workspace, 2));
+    server.query(
+        InternalTestingFetchConfigOption::CheckWorkspace,
+        2,
+        InternalTestingFetchConfigResponse::CheckWorkspace(true),
+    );
 }
diff --git a/crates/rust-analyzer/tests/test_data/deduplication_crate_graph_A.json b/crates/rust-analyzer/tests/test_data/deduplication_crate_graph_A.json
deleted file mode 100644
index b0fb584..0000000
--- a/crates/rust-analyzer/tests/test_data/deduplication_crate_graph_A.json
+++ /dev/null
@@ -1,140 +0,0 @@
-{
-  "packages": [
-    {
-      "name": "p1",
-      "version": "0.1.0",
-      "id": "p1 0.1.0 (path+file:///example_project/p1)",
-      "license": null,
-      "license_file": null,
-      "description": null,
-      "source": null,
-      "dependencies": [
-        {
-          "name": "p2",
-          "source": null,
-          "req": "*",
-          "kind": null,
-          "rename": null,
-          "optional": false,
-          "uses_default_features": true,
-          "features": [],
-          "target": null,
-          "registry": null,
-          "path": "$ROOT$example_project/p2"
-        }
-      ],
-      "targets": [
-        {
-          "kind": [
-            "lib"
-          ],
-          "crate_types": [
-            "lib"
-          ],
-          "name": "p1",
-          "src_path": "$ROOT$example_project/p1/src/lib.rs",
-          "edition": "2021",
-          "doc": true,
-          "doctest": true,
-          "test": true
-        }
-      ],
-      "features": {},
-      "manifest_path": "$ROOT$example_project/p1/Cargo.toml",
-      "metadata": null,
-      "publish": null,
-      "authors": [],
-      "categories": [],
-      "keywords": [],
-      "readme": null,
-      "repository": null,
-      "homepage": null,
-      "documentation": null,
-      "edition": "2021",
-      "links": null,
-      "default_run": null,
-      "rust_version": null
-    },
-    {
-      "name": "p2",
-      "version": "0.1.0",
-      "id": "p2 0.1.0 (path+file:///example_project/p2)",
-      "license": null,
-      "license_file": null,
-      "description": null,
-      "source": null,
-      "dependencies": [],
-      "targets": [
-        {
-          "kind": [
-            "lib"
-          ],
-          "crate_types": [
-            "lib"
-          ],
-          "name": "p2",
-          "src_path": "$ROOT$example_project/p2/src/lib.rs",
-          "edition": "2021",
-          "doc": true,
-          "doctest": true,
-          "test": true
-        }
-      ],
-      "features": {},
-      "manifest_path": "$ROOT$example_project/p2/Cargo.toml",
-      "metadata": null,
-      "publish": null,
-      "authors": [],
-      "categories": [],
-      "keywords": [],
-      "readme": null,
-      "repository": null,
-      "homepage": null,
-      "documentation": null,
-      "edition": "2021",
-      "links": null,
-      "default_run": null,
-      "rust_version": null
-    }
-  ],
-  "workspace_members": [
-    "p1 0.1.0 (path+file:///example_project/p1)"
-  ],
-  "workspace_default_members": [
-    "p1 0.1.0 (path+file:///example_project/p1)"
-  ],
-  "resolve": {
-    "nodes": [
-      {
-        "id": "p1 0.1.0 (path+file:///example_project/p1)",
-        "dependencies": [
-          "p2 0.1.0 (path+file:///example_project/p2)"
-        ],
-        "deps": [
-          {
-            "name": "p2",
-            "pkg": "p2 0.1.0 (path+file:///example_project/p2)",
-            "dep_kinds": [
-              {
-                "kind": null,
-                "target": null
-              }
-            ]
-          }
-        ],
-        "features": []
-      },
-      {
-        "id": "p2 0.1.0 (path+file:///example_project/p2)",
-        "dependencies": [],
-        "deps": [],
-        "features": []
-      }
-    ],
-    "root": "p1 0.1.0 (path+file:///example_project/p1)"
-  },
-  "target_directory": "$ROOT$example_project/p1/target",
-  "version": 1,
-  "workspace_root": "$ROOT$example_project/p1",
-  "metadata": null
-}
\ No newline at end of file
diff --git a/crates/rust-analyzer/tests/test_data/deduplication_crate_graph_B.json b/crates/rust-analyzer/tests/test_data/deduplication_crate_graph_B.json
deleted file mode 100644
index b5d1e16..0000000
--- a/crates/rust-analyzer/tests/test_data/deduplication_crate_graph_B.json
+++ /dev/null
@@ -1,66 +0,0 @@
-{
-  "packages": [
-    {
-      "name": "p2",
-      "version": "0.1.0",
-      "id": "p2 0.1.0 (path+file:///example_project/p2)",
-      "license": null,
-      "license_file": null,
-      "description": null,
-      "source": null,
-      "dependencies": [],
-      "targets": [
-        {
-          "kind": [
-            "lib"
-          ],
-          "crate_types": [
-            "lib"
-          ],
-          "name": "p2",
-          "src_path": "$ROOT$example_project/p2/src/lib.rs",
-          "edition": "2021",
-          "doc": true,
-          "doctest": true,
-          "test": true
-        }
-      ],
-      "features": {},
-      "manifest_path": "$ROOT$example_project/p2/Cargo.toml",
-      "metadata": null,
-      "publish": null,
-      "authors": [],
-      "categories": [],
-      "keywords": [],
-      "readme": null,
-      "repository": null,
-      "homepage": null,
-      "documentation": null,
-      "edition": "2021",
-      "links": null,
-      "default_run": null,
-      "rust_version": null
-    }
-  ],
-  "workspace_members": [
-    "p2 0.1.0 (path+file:///example_project/p2)"
-  ],
-  "workspace_default_members": [
-    "p2 0.1.0 (path+file:///example_project/p2)"
-  ],
-  "resolve": {
-    "nodes": [
-      {
-        "id": "p2 0.1.0 (path+file:///example_project/p2)",
-        "dependencies": [],
-        "deps": [],
-        "features": []
-      }
-    ],
-    "root": "p2 0.1.0 (path+file:///example_project/p2)"
-  },
-  "target_directory": "$ROOT$example_project/p2/target",
-  "version": 1,
-  "workspace_root": "$ROOT$example_project/p2",
-  "metadata": null
-}
\ No newline at end of file
diff --git a/crates/span/src/hygiene.rs b/crates/span/src/hygiene.rs
index 874480c..cb9c092 100644
--- a/crates/span/src/hygiene.rs
+++ b/crates/span/src/hygiene.rs
@@ -81,7 +81,7 @@
     /// Invariant: Only [`SyntaxContextId::ROOT`] has a [`None`] outer expansion.
     // FIXME: The None case needs to encode the context crate id. We can encode that as the MSB of
     // MacroCallId is reserved anyways so we can do bit tagging here just fine.
-    // The bigger issue is that that will cause interning to now create completely separate chains
+    // The bigger issue is that this will cause interning to now create completely separate chains
     // per crate. Though that is likely not a problem as `MacroCallId`s are already crate calling dependent.
     pub outer_expn: Option<MacroCallId>,
     pub outer_transparency: Transparency,
diff --git a/crates/span/src/map.rs b/crates/span/src/map.rs
index c539754..f80de05 100644
--- a/crates/span/src/map.rs
+++ b/crates/span/src/map.rs
@@ -13,6 +13,7 @@
 /// Maps absolute text ranges for the corresponding file to the relevant span data.
 #[derive(Debug, PartialEq, Eq, Clone, Hash)]
 pub struct SpanMap<S> {
+    /// The offset stored here is the *end* of the node.
     spans: Vec<(TextSize, SpanData<S>)>,
     /// Index of the matched macro arm on successful expansion for declarative macros.
     // FIXME: Does it make sense to have this here?
@@ -104,6 +105,52 @@
     pub fn iter(&self) -> impl Iterator<Item = (TextSize, SpanData<S>)> + '_ {
         self.spans.iter().copied()
     }
+
+    /// Merges this span map with another span map, where `other` is inserted at (and replaces) `other_range`.
+    ///
+    /// The length of the replacement node needs to be `other_size`.
+    pub fn merge(&mut self, other_range: TextRange, other_size: TextSize, other: &SpanMap<S>) {
+        // I find the following diagram helpful to illustrate the bounds and why we use `<` or `<=`:
+        // --------------------------------------------------------------------
+        //   1   3   5   6   7   10    11          <-- offsets we store
+        // 0-1 1-3 3-5 5-6 6-7 7-10 10-11          <-- ranges these offsets refer to
+        //       3   ..      7                     <-- other_range
+        //         3-5 5-6 6-7                     <-- ranges we replace (len = 7-3 = 4)
+        //         ^^^^^^^^^^^ ^^^^^^^^^^
+        //           remove       shift
+        //   2   3   5   9                         <-- offsets we insert
+        // 0-2 2-3 3-5 5-9                         <-- ranges we insert (other_size = 9-0 = 9)
+        // ------------------------------------
+        //   1   3
+        // 0-1 1-3                                 <-- these remain intact
+        //           5   6   8   12
+        //         3-5 5-6 6-8 8-12                <-- we shift these by other_range.start() and insert them
+        //                             15    16
+        //                          12-15 15-16    <-- we shift these by other_size-other_range.len() = 9-4 = 5
+        // ------------------------------------
+        //   1   3   5   6   8   12    15    16    <-- final offsets we store
+        // 0-1 1-3 3-5 5-6 6-8 8-12 12-15 15-16    <-- final ranges
+
+        self.spans.retain_mut(|(offset, _)| {
+            if other_range.start() < *offset && *offset <= other_range.end() {
+                false
+            } else {
+                if *offset > other_range.end() {
+                    *offset += other_size;
+                    *offset -= other_range.len();
+                }
+                true
+            }
+        });
+
+        self.spans
+            .extend(other.spans.iter().map(|&(offset, span)| (offset + other_range.start(), span)));
+
+        self.spans.sort_unstable_by_key(|&(offset, _)| offset);
+
+        // Matched arm info is no longer correct once we have multiple macros.
+        self.matched_arm = None;
+    }
 }
 
 #[derive(PartialEq, Eq, Hash, Debug)]
diff --git a/crates/syntax-bridge/src/lib.rs b/crates/syntax-bridge/src/lib.rs
index 56e43e8..0ccd088 100644
--- a/crates/syntax-bridge/src/lib.rs
+++ b/crates/syntax-bridge/src/lib.rs
@@ -17,6 +17,7 @@
     token_to_literal,
 };
 
+pub mod prettify_macro_expansion;
 mod to_parser_input;
 pub use to_parser_input::to_parser_input;
 // FIXME: we probably should re-think  `token_tree_to_syntax_node` interfaces
diff --git a/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs b/crates/syntax-bridge/src/prettify_macro_expansion.rs
similarity index 84%
rename from crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs
rename to crates/syntax-bridge/src/prettify_macro_expansion.rs
index dd4a665..fc7caaa 100644
--- a/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs
+++ b/crates/syntax-bridge/src/prettify_macro_expansion.rs
@@ -7,13 +7,20 @@
     SyntaxNode, SyntaxToken, WalkEvent, T,
 };
 
-// FIXME: It would also be cool to share logic here and in the mbe tests,
-// which are pretty unreadable at the moment.
 /// Renders a [`SyntaxNode`] with whitespace inserted between tokens that require them.
-pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode {
+///
+/// This is an internal API that is only exported because `mbe` needs it for tests and cannot depend
+/// on `hir-expand`. For any purpose other than tests, you are supposed to use the `prettify_macro_expansion`
+/// from `hir-expand` that handles `$crate` for you.
+#[deprecated = "use `hir_expand::prettify_macro_expansion()` instead"]
+pub fn prettify_macro_expansion(
+    syn: SyntaxNode,
+    dollar_crate_replacement: &mut dyn FnMut(&SyntaxToken) -> SyntaxToken,
+) -> SyntaxNode {
     let mut indent = 0;
     let mut last: Option<SyntaxKind> = None;
     let mut mods = Vec::new();
+    let mut dollar_crate_replacements = Vec::new();
     let syn = syn.clone_subtree().clone_for_update();
 
     let before = Position::before;
@@ -51,6 +58,9 @@
             }
             _ => continue,
         };
+        if token.kind() == SyntaxKind::IDENT && token.text() == "$crate" {
+            dollar_crate_replacements.push((token.clone(), dollar_crate_replacement(&token)));
+        }
         let tok = &token;
 
         let is_next = |f: fn(SyntaxKind) -> bool, default| -> bool {
@@ -122,6 +132,9 @@
     for (pos, insert) in mods {
         ted::insert(pos, insert);
     }
+    for (old, new) in dollar_crate_replacements {
+        ted::replace(old, new);
+    }
 
     if let Some(it) = syn.last_token().filter(|it| it.kind() == SyntaxKind::WHITESPACE) {
         ted::remove(it);
diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram
index 43375ce..52ad439 100644
--- a/crates/syntax/rust.ungram
+++ b/crates/syntax/rust.ungram
@@ -391,8 +391,33 @@
 OffsetOfExpr =
   Attr* 'builtin' '#' 'offset_of' '(' Type ',' fields:(NameRef ('.' NameRef)* ) ')'
 
+// asm := "asm!(" format_string *("," format_string) *("," operand) [","] ")"
+// global_asm := "global_asm!(" format_string *("," format_string) *("," operand) [","] ")"
+// format_string := STRING_LITERAL / RAW_STRING_LITERAL
 AsmExpr =
-  Attr* 'builtin' '#' 'asm' '(' Expr ')'
+  Attr* 'builtin' '#' 'asm' '(' template:(Expr (',' Expr)*) (AsmPiece (',' AsmPiece)*)? ','? ')'
+
+// operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_"
+AsmOperandExpr = in_expr:Expr ('=>' out_expr:Expr)?
+// dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout"
+AsmDirSpec = 'in' | 'out' | 'lateout' | 'inout' | 'inlateout'
+// reg_spec := <register class> / "\"" <explicit register> "\""
+AsmRegSpec = '@string' | NameRef
+// reg_operand := [ident "="] dir_spec "(" reg_spec ")" operand_expr
+AsmRegOperand = AsmDirSpec '(' AsmRegSpec ')' AsmOperandExpr
+// clobber_abi := "clobber_abi(" <abi> *("," <abi>) [","] ")"
+AsmClobberAbi = 'clobber_abi' '(' ('@string' (',' '@string')* ','?) ')'
+// option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw"
+AsmOption = 'pure' | 'nomem' | 'readonly' | 'preserves_flags' | 'noreturn' | 'nostack' | 'att_syntax' | 'raw' | 'may_unwind'
+// options := "options(" option *("," option) [","] ")"
+AsmOptions = 'options' '(' AsmOption *(',' AsmOption) ','? ')'
+AsmLabel = 'label' BlockExpr
+AsmSym = 'sym' Path
+AsmConst = 'const' Expr
+// operand := reg_operand / clobber_abi / options
+AsmOperand = AsmRegOperand | AsmLabel | AsmSym | AsmConst
+AsmOperandNamed = (Name '=')? AsmOperand
+AsmPiece = AsmOperandNamed | AsmClobberAbi | AsmOptions
 
 FormatArgsExpr =
   Attr* 'builtin' '#' 'format_args' '('
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index c9b39e9..c81a19f 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -65,13 +65,62 @@
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmClobberAbi {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AsmClobberAbi {
+    #[inline]
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    #[inline]
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+    #[inline]
+    pub fn clobber_abi_token(&self) -> Option<SyntaxToken> {
+        support::token(&self.syntax, T![clobber_abi])
+    }
+    #[inline]
+    pub fn string_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![string]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmConst {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AsmConst {
+    #[inline]
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+    #[inline]
+    pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmDirSpec {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AsmDirSpec {
+    #[inline]
+    pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) }
+    #[inline]
+    pub fn inlateout_token(&self) -> Option<SyntaxToken> {
+        support::token(&self.syntax, T![inlateout])
+    }
+    #[inline]
+    pub fn inout_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![inout]) }
+    #[inline]
+    pub fn lateout_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![lateout]) }
+    #[inline]
+    pub fn out_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![out]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct AsmExpr {
     pub(crate) syntax: SyntaxNode,
 }
 impl ast::HasAttrs for AsmExpr {}
 impl AsmExpr {
     #[inline]
-    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+    pub fn asm_pieces(&self) -> AstChildren<AsmPiece> { support::children(&self.syntax) }
+    #[inline]
+    pub fn template(&self) -> AstChildren<Expr> { support::children(&self.syntax) }
     #[inline]
     pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
     #[inline]
@@ -79,12 +128,143 @@
     #[inline]
     pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
     #[inline]
+    pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
+    #[inline]
     pub fn asm_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![asm]) }
     #[inline]
     pub fn builtin_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![builtin]) }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmLabel {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AsmLabel {
+    #[inline]
+    pub fn block_expr(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
+    #[inline]
+    pub fn label_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![label]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmOperandExpr {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AsmOperandExpr {
+    #[inline]
+    pub fn in_expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+    #[inline]
+    pub fn out_expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+    #[inline]
+    pub fn fat_arrow_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=>]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmOperandNamed {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ast::HasName for AsmOperandNamed {}
+impl AsmOperandNamed {
+    #[inline]
+    pub fn asm_operand(&self) -> Option<AsmOperand> { support::child(&self.syntax) }
+    #[inline]
+    pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmOption {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AsmOption {
+    #[inline]
+    pub fn att_syntax_token(&self) -> Option<SyntaxToken> {
+        support::token(&self.syntax, T![att_syntax])
+    }
+    #[inline]
+    pub fn may_unwind_token(&self) -> Option<SyntaxToken> {
+        support::token(&self.syntax, T![may_unwind])
+    }
+    #[inline]
+    pub fn nomem_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![nomem]) }
+    #[inline]
+    pub fn noreturn_token(&self) -> Option<SyntaxToken> {
+        support::token(&self.syntax, T![noreturn])
+    }
+    #[inline]
+    pub fn nostack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![nostack]) }
+    #[inline]
+    pub fn preserves_flags_token(&self) -> Option<SyntaxToken> {
+        support::token(&self.syntax, T![preserves_flags])
+    }
+    #[inline]
+    pub fn pure_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![pure]) }
+    #[inline]
+    pub fn raw_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![raw]) }
+    #[inline]
+    pub fn readonly_token(&self) -> Option<SyntaxToken> {
+        support::token(&self.syntax, T![readonly])
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmOptions {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AsmOptions {
+    #[inline]
+    pub fn asm_option(&self) -> Option<AsmOption> { support::child(&self.syntax) }
+    #[inline]
+    pub fn asm_options(&self) -> AstChildren<AsmOption> { support::children(&self.syntax) }
+    #[inline]
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    #[inline]
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+    #[inline]
+    pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
+    #[inline]
+    pub fn options_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![options]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmRegOperand {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AsmRegOperand {
+    #[inline]
+    pub fn asm_dir_spec(&self) -> Option<AsmDirSpec> { support::child(&self.syntax) }
+    #[inline]
+    pub fn asm_operand_expr(&self) -> Option<AsmOperandExpr> { support::child(&self.syntax) }
+    #[inline]
+    pub fn asm_reg_spec(&self) -> Option<AsmRegSpec> { support::child(&self.syntax) }
+    #[inline]
+    pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+    #[inline]
+    pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmRegSpec {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AsmRegSpec {
+    #[inline]
+    pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
+    #[inline]
+    pub fn string_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![string]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct AsmSym {
+    pub(crate) syntax: SyntaxNode,
+}
+impl AsmSym {
+    #[inline]
+    pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
+    #[inline]
+    pub fn sym_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![sym]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct AssocItemList {
     pub(crate) syntax: SyntaxNode,
 }
@@ -2052,6 +2232,21 @@
 impl ast::HasVisibility for Adt {}
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum AsmOperand {
+    AsmConst(AsmConst),
+    AsmLabel(AsmLabel),
+    AsmRegOperand(AsmRegOperand),
+    AsmSym(AsmSym),
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum AsmPiece {
+    AsmClobberAbi(AsmClobberAbi),
+    AsmOperandNamed(AsmOperandNamed),
+    AsmOptions(AsmOptions),
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum AssocItem {
     Const(Const),
     Fn(Fn),
@@ -2316,6 +2511,48 @@
     #[inline]
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for AsmClobberAbi {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_CLOBBER_ABI }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for AsmConst {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_CONST }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for AsmDirSpec {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_DIR_SPEC }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for AsmExpr {
     #[inline]
     fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_EXPR }
@@ -2330,6 +2567,118 @@
     #[inline]
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for AsmLabel {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_LABEL }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for AsmOperandExpr {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_OPERAND_EXPR }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for AsmOperandNamed {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_OPERAND_NAMED }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for AsmOption {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_OPTION }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for AsmOptions {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_OPTIONS }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for AsmRegOperand {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_REG_OPERAND }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for AsmRegSpec {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_REG_SPEC }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
+impl AstNode for AsmSym {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool { kind == ASM_SYM }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for AssocItemList {
     #[inline]
     fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_ITEM_LIST }
@@ -4268,6 +4617,84 @@
         }
     }
 }
+impl From<AsmConst> for AsmOperand {
+    #[inline]
+    fn from(node: AsmConst) -> AsmOperand { AsmOperand::AsmConst(node) }
+}
+impl From<AsmLabel> for AsmOperand {
+    #[inline]
+    fn from(node: AsmLabel) -> AsmOperand { AsmOperand::AsmLabel(node) }
+}
+impl From<AsmRegOperand> for AsmOperand {
+    #[inline]
+    fn from(node: AsmRegOperand) -> AsmOperand { AsmOperand::AsmRegOperand(node) }
+}
+impl From<AsmSym> for AsmOperand {
+    #[inline]
+    fn from(node: AsmSym) -> AsmOperand { AsmOperand::AsmSym(node) }
+}
+impl AstNode for AsmOperand {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool {
+        matches!(kind, ASM_CONST | ASM_LABEL | ASM_REG_OPERAND | ASM_SYM)
+    }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        let res = match syntax.kind() {
+            ASM_CONST => AsmOperand::AsmConst(AsmConst { syntax }),
+            ASM_LABEL => AsmOperand::AsmLabel(AsmLabel { syntax }),
+            ASM_REG_OPERAND => AsmOperand::AsmRegOperand(AsmRegOperand { syntax }),
+            ASM_SYM => AsmOperand::AsmSym(AsmSym { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            AsmOperand::AsmConst(it) => &it.syntax,
+            AsmOperand::AsmLabel(it) => &it.syntax,
+            AsmOperand::AsmRegOperand(it) => &it.syntax,
+            AsmOperand::AsmSym(it) => &it.syntax,
+        }
+    }
+}
+impl From<AsmClobberAbi> for AsmPiece {
+    #[inline]
+    fn from(node: AsmClobberAbi) -> AsmPiece { AsmPiece::AsmClobberAbi(node) }
+}
+impl From<AsmOperandNamed> for AsmPiece {
+    #[inline]
+    fn from(node: AsmOperandNamed) -> AsmPiece { AsmPiece::AsmOperandNamed(node) }
+}
+impl From<AsmOptions> for AsmPiece {
+    #[inline]
+    fn from(node: AsmOptions) -> AsmPiece { AsmPiece::AsmOptions(node) }
+}
+impl AstNode for AsmPiece {
+    #[inline]
+    fn can_cast(kind: SyntaxKind) -> bool {
+        matches!(kind, ASM_CLOBBER_ABI | ASM_OPERAND_NAMED | ASM_OPTIONS)
+    }
+    #[inline]
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        let res = match syntax.kind() {
+            ASM_CLOBBER_ABI => AsmPiece::AsmClobberAbi(AsmClobberAbi { syntax }),
+            ASM_OPERAND_NAMED => AsmPiece::AsmOperandNamed(AsmOperandNamed { syntax }),
+            ASM_OPTIONS => AsmPiece::AsmOptions(AsmOptions { syntax }),
+            _ => return None,
+        };
+        Some(res)
+    }
+    #[inline]
+    fn syntax(&self) -> &SyntaxNode {
+        match self {
+            AsmPiece::AsmClobberAbi(it) => &it.syntax,
+            AsmPiece::AsmOperandNamed(it) => &it.syntax,
+            AsmPiece::AsmOptions(it) => &it.syntax,
+        }
+    }
+}
 impl From<Const> for AssocItem {
     #[inline]
     fn from(node: Const) -> AssocItem { AssocItem::Const(node) }
@@ -5803,7 +6230,8 @@
     fn can_cast(kind: SyntaxKind) -> bool {
         matches!(
             kind,
-            CONST
+            ASM_OPERAND_NAMED
+                | CONST
                 | CONST_PARAM
                 | ENUM
                 | FN
@@ -5832,6 +6260,10 @@
     #[inline]
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl From<AsmOperandNamed> for AnyHasName {
+    #[inline]
+    fn from(node: AsmOperandNamed) -> AnyHasName { AnyHasName { syntax: node.syntax } }
+}
 impl From<Const> for AnyHasName {
     #[inline]
     fn from(node: Const) -> AnyHasName { AnyHasName { syntax: node.syntax } }
@@ -6072,6 +6504,16 @@
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for AsmOperand {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for AsmPiece {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for AssocItem {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
@@ -6142,11 +6584,66 @@
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for AsmClobberAbi {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for AsmConst {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for AsmDirSpec {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for AsmExpr {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for AsmLabel {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for AsmOperandExpr {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for AsmOperandNamed {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for AsmOption {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for AsmOptions {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for AsmRegOperand {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for AsmRegSpec {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
+impl std::fmt::Display for AsmSym {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for AssocItemList {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs
index abf1a1f..fcdc97c 100644
--- a/crates/syntax/src/ast/make.rs
+++ b/crates/syntax/src/ast/make.rs
@@ -1162,7 +1162,7 @@
 
     pub(super) static SOURCE_FILE: LazyLock<Parse<SourceFile>> = LazyLock::new(|| {
         SourceFile::parse(
-            "const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p, { let _ @ [] })\n;\n\nimpl A for B where: {}", Edition::CURRENT,
+            "use crate::foo; const C: <()>::Item = ( true && true , true || true , 1 != 1, 2 == 2, 3 < 3, 4 <= 4, 5 > 5, 6 >= 6, !true, *p, &p , &mut p, async { let _ @ [] })\n;\n\nimpl A for B where: {}", Edition::CURRENT,
         )
     });
 
@@ -1188,6 +1188,17 @@
             .unwrap()
     }
 
+    pub fn crate_kw() -> SyntaxToken {
+        SOURCE_FILE
+            .tree()
+            .syntax()
+            .clone_for_update()
+            .descendants_with_tokens()
+            .filter_map(|it| it.into_token())
+            .find(|it| it.kind() == CRATE_KW)
+            .unwrap()
+    }
+
     pub fn whitespace(text: &str) -> SyntaxToken {
         assert!(text.trim().is_empty());
         let sf = SourceFile::parse(text, Edition::CURRENT).ok().unwrap();
diff --git a/crates/syntax/src/ast/traits.rs b/crates/syntax/src/ast/traits.rs
index 152b0cb..5d6aa43 100644
--- a/crates/syntax/src/ast/traits.rs
+++ b/crates/syntax/src/ast/traits.rs
@@ -75,6 +75,33 @@
     fn has_atom_attr(&self, atom: &str) -> bool {
         self.attrs().filter_map(|x| x.as_simple_atom()).any(|x| x == atom)
     }
+
+    /// Returns all attributes of this node, including inner attributes that may not be directly under this node
+    /// but under a child.
+    fn attrs_including_inner(self) -> impl Iterator<Item = ast::Attr>
+    where
+        Self: Sized,
+    {
+        let inner_attrs_node = if let Some(it) =
+            support::child::<ast::BlockExpr>(self.syntax()).and_then(|it| it.stmt_list())
+        {
+            Some(it.syntax)
+        } else if let Some(it) = support::child::<ast::MatchArmList>(self.syntax()) {
+            Some(it.syntax)
+        } else if let Some(it) = support::child::<ast::AssocItemList>(self.syntax()) {
+            Some(it.syntax)
+        } else if let Some(it) = support::child::<ast::ItemList>(self.syntax()) {
+            Some(it.syntax)
+        } else if let Some(it) = support::child::<ast::ExternItemList>(self.syntax()) {
+            Some(it.syntax)
+        } else if let Some(it) = support::child::<ast::MacroItems>(self.syntax()) {
+            Some(it.syntax)
+        } else {
+            None
+        };
+
+        self.attrs().chain(inner_attrs_node.into_iter().flat_map(|it| support::children(&it)))
+    }
 }
 
 pub trait HasDocComments: HasAttrs {
diff --git a/crates/syntax/src/hacks.rs b/crates/syntax/src/hacks.rs
index 9e63448..2184359 100644
--- a/crates/syntax/src/hacks.rs
+++ b/crates/syntax/src/hacks.rs
@@ -8,10 +8,15 @@
 
 pub fn parse_expr_from_str(s: &str, edition: Edition) -> Option<ast::Expr> {
     let s = s.trim();
-    let file = ast::SourceFile::parse(&format!("const _: () = {s};"), edition);
-    let expr = file.syntax_node().descendants().find_map(ast::Expr::cast)?;
-    if expr.syntax().text() != s {
-        return None;
-    }
-    Some(expr)
+
+    let file = ast::SourceFile::parse(
+        // Need a newline because the text may contain line comments.
+        &format!("const _: () = ({s}\n);"),
+        edition,
+    );
+    let expr = file.syntax_node().descendants().find_map(ast::ParenExpr::cast)?;
+    // Can't check the text because the original text may contain whitespace and comments.
+    // Wrap in parentheses to better allow for verification. Of course, the real fix is
+    // to get rid of this hack.
+    expr.expr()
 }
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs
index b683748..c1554c4 100644
--- a/crates/syntax/src/lib.rs
+++ b/crates/syntax/src/lib.rs
@@ -40,6 +40,7 @@
 #[doc(hidden)]
 pub mod fuzz;
 pub mod hacks;
+pub mod syntax_editor;
 pub mod ted;
 pub mod utils;
 
@@ -65,7 +66,7 @@
     TokenAtOffset, WalkEvent,
 };
 pub use rustc_lexer::unescape;
-pub use smol_str::{format_smolstr, SmolStr, ToSmolStr};
+pub use smol_str::{format_smolstr, SmolStr, SmolStrBuilder, ToSmolStr};
 
 /// `Parse` is the result of the parsing: a syntax tree and a collection of
 /// errors.
diff --git a/crates/syntax/src/syntax_editor.rs b/crates/syntax/src/syntax_editor.rs
new file mode 100644
index 0000000..eb114f5
--- /dev/null
+++ b/crates/syntax/src/syntax_editor.rs
@@ -0,0 +1,611 @@
+//! Syntax Tree editor
+//!
+//! Inspired by Roslyn's [`SyntaxEditor`], but is temporarily built upon mutable syntax tree editing.
+//!
+//! [`SyntaxEditor`]: https://github.com/dotnet/roslyn/blob/43b0b05cc4f492fd5de00f6f6717409091df8daa/src/Workspaces/Core/Portable/Editing/SyntaxEditor.cs
+
+use std::{
+    num::NonZeroU32,
+    ops::RangeInclusive,
+    sync::atomic::{AtomicU32, Ordering},
+};
+
+use rowan::TextRange;
+use rustc_hash::FxHashMap;
+
+use crate::{SyntaxElement, SyntaxNode, SyntaxToken};
+
+mod edit_algo;
+mod mapping;
+
+pub use mapping::{SyntaxMapping, SyntaxMappingBuilder};
+
+#[derive(Debug)]
+pub struct SyntaxEditor {
+    root: SyntaxNode,
+    changes: Vec<Change>,
+    mappings: SyntaxMapping,
+    annotations: Vec<(SyntaxElement, SyntaxAnnotation)>,
+}
+
+impl SyntaxEditor {
+    /// Creates a syntax editor to start editing from `root`
+    pub fn new(root: SyntaxNode) -> Self {
+        Self { root, changes: vec![], mappings: SyntaxMapping::new(), annotations: vec![] }
+    }
+
+    pub fn add_annotation(&mut self, element: impl Element, annotation: SyntaxAnnotation) {
+        self.annotations.push((element.syntax_element(), annotation))
+    }
+
+    pub fn merge(&mut self, mut other: SyntaxEditor) {
+        debug_assert!(
+            self.root == other.root || other.root.ancestors().any(|node| node == self.root),
+            "{:?} is not in the same tree as {:?}",
+            other.root,
+            self.root
+        );
+
+        self.changes.append(&mut other.changes);
+        self.mappings.merge(other.mappings);
+        self.annotations.append(&mut other.annotations);
+    }
+
+    pub fn insert(&mut self, position: Position, element: impl Element) {
+        debug_assert!(is_ancestor_or_self(&position.parent(), &self.root));
+        self.changes.push(Change::Insert(position, element.syntax_element()))
+    }
+
+    pub fn insert_all(&mut self, position: Position, elements: Vec<SyntaxElement>) {
+        debug_assert!(is_ancestor_or_self(&position.parent(), &self.root));
+        self.changes.push(Change::InsertAll(position, elements))
+    }
+
+    pub fn delete(&mut self, element: impl Element) {
+        let element = element.syntax_element();
+        debug_assert!(is_ancestor_or_self_of_element(&element, &self.root));
+        debug_assert!(
+            !matches!(&element, SyntaxElement::Node(node) if node == &self.root),
+            "should not delete root node"
+        );
+        self.changes.push(Change::Replace(element.syntax_element(), None));
+    }
+
+    pub fn replace(&mut self, old: impl Element, new: impl Element) {
+        let old = old.syntax_element();
+        debug_assert!(is_ancestor_or_self_of_element(&old, &self.root));
+        self.changes.push(Change::Replace(old.syntax_element(), Some(new.syntax_element())));
+    }
+
+    pub fn replace_with_many(&mut self, old: impl Element, new: Vec<SyntaxElement>) {
+        let old = old.syntax_element();
+        debug_assert!(is_ancestor_or_self_of_element(&old, &self.root));
+        debug_assert!(
+            !(matches!(&old, SyntaxElement::Node(node) if node == &self.root) && new.len() > 1),
+            "cannot replace root node with many elements"
+        );
+        self.changes.push(Change::ReplaceWithMany(old.syntax_element(), new));
+    }
+
+    pub fn replace_all(&mut self, range: RangeInclusive<SyntaxElement>, new: Vec<SyntaxElement>) {
+        if range.start() == range.end() {
+            self.replace_with_many(range.start(), new);
+            return;
+        }
+
+        debug_assert!(is_ancestor_or_self_of_element(range.start(), &self.root));
+        self.changes.push(Change::ReplaceAll(range, new))
+    }
+
+    pub fn finish(self) -> SyntaxEdit {
+        edit_algo::apply_edits(self)
+    }
+}
+
+/// Represents a completed [`SyntaxEditor`] operation.
+pub struct SyntaxEdit {
+    old_root: SyntaxNode,
+    new_root: SyntaxNode,
+    changed_elements: Vec<SyntaxElement>,
+    annotations: FxHashMap<SyntaxAnnotation, Vec<SyntaxElement>>,
+}
+
+impl SyntaxEdit {
+    /// Root of the initial unmodified syntax tree.
+    pub fn old_root(&self) -> &SyntaxNode {
+        &self.old_root
+    }
+
+    /// Root of the modified syntax tree.
+    pub fn new_root(&self) -> &SyntaxNode {
+        &self.new_root
+    }
+
+    /// Which syntax elements in the modified syntax tree were inserted or
+    /// modified as part of the edit.
+    ///
+    /// Note that for syntax nodes, only the upper-most parent of a set of
+    /// changes is included, not any child elements that may have been modified.
+    pub fn changed_elements(&self) -> &[SyntaxElement] {
+        self.changed_elements.as_slice()
+    }
+
+    /// Finds which syntax elements have been annotated with the given
+    /// annotation.
+    ///
+    /// Note that an annotation might not appear in the modified syntax tree if
+    /// the syntax elements that were annotated did not make it into the final
+    /// syntax tree.
+    pub fn find_annotation(&self, annotation: SyntaxAnnotation) -> &[SyntaxElement] {
+        self.annotations.get(&annotation).as_ref().map_or(&[], |it| it.as_slice())
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[repr(transparent)]
+pub struct SyntaxAnnotation(NonZeroU32);
+
+impl SyntaxAnnotation {
+    /// Creates a unique syntax annotation to attach data to.
+    pub fn new() -> Self {
+        static COUNTER: AtomicU32 = AtomicU32::new(1);
+
+        // Only consistency within a thread matters, as SyntaxElements are !Send
+        let id = COUNTER.fetch_add(1, Ordering::Relaxed);
+
+        Self(NonZeroU32::new(id).expect("syntax annotation id overflow"))
+    }
+}
+
+impl Default for SyntaxAnnotation {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+/// Position describing where to insert elements
+#[derive(Debug)]
+pub struct Position {
+    repr: PositionRepr,
+}
+
+impl Position {
+    pub(crate) fn parent(&self) -> SyntaxNode {
+        self.place().0
+    }
+
+    pub(crate) fn place(&self) -> (SyntaxNode, usize) {
+        match &self.repr {
+            PositionRepr::FirstChild(parent) => (parent.clone(), 0),
+            PositionRepr::After(child) => (child.parent().unwrap(), child.index() + 1),
+        }
+    }
+}
+
+#[derive(Debug)]
+enum PositionRepr {
+    FirstChild(SyntaxNode),
+    After(SyntaxElement),
+}
+
+impl Position {
+    pub fn after(elem: impl Element) -> Position {
+        let repr = PositionRepr::After(elem.syntax_element());
+        Position { repr }
+    }
+
+    pub fn before(elem: impl Element) -> Position {
+        let elem = elem.syntax_element();
+        let repr = match elem.prev_sibling_or_token() {
+            Some(it) => PositionRepr::After(it),
+            None => PositionRepr::FirstChild(elem.parent().unwrap()),
+        };
+        Position { repr }
+    }
+
+    pub fn first_child_of(node: &(impl Into<SyntaxNode> + Clone)) -> Position {
+        let repr = PositionRepr::FirstChild(node.clone().into());
+        Position { repr }
+    }
+
+    pub fn last_child_of(node: &(impl Into<SyntaxNode> + Clone)) -> Position {
+        let node = node.clone().into();
+        let repr = match node.last_child_or_token() {
+            Some(it) => PositionRepr::After(it),
+            None => PositionRepr::FirstChild(node),
+        };
+        Position { repr }
+    }
+}
+
+#[derive(Debug)]
+enum Change {
+    /// Inserts a single element at the specified position.
+    Insert(Position, SyntaxElement),
+    /// Inserts many elements in-order at the specified position.
+    InsertAll(Position, Vec<SyntaxElement>),
+    /// Represents both a replace single element and a delete element operation.
+    Replace(SyntaxElement, Option<SyntaxElement>),
+    /// Replaces a single element with many elements.
+    ReplaceWithMany(SyntaxElement, Vec<SyntaxElement>),
+    /// Replaces a range of elements with another list of elements.
+    /// Range will always have start != end.
+    ReplaceAll(RangeInclusive<SyntaxElement>, Vec<SyntaxElement>),
+}
+
+impl Change {
+    fn target_range(&self) -> TextRange {
+        match self {
+            Change::Insert(target, _) | Change::InsertAll(target, _) => match &target.repr {
+                PositionRepr::FirstChild(parent) => TextRange::at(
+                    parent.first_child_or_token().unwrap().text_range().start(),
+                    0.into(),
+                ),
+                PositionRepr::After(child) => TextRange::at(child.text_range().end(), 0.into()),
+            },
+            Change::Replace(target, _) | Change::ReplaceWithMany(target, _) => target.text_range(),
+            Change::ReplaceAll(range, _) => {
+                range.start().text_range().cover(range.end().text_range())
+            }
+        }
+    }
+
+    fn target_parent(&self) -> SyntaxNode {
+        match self {
+            Change::Insert(target, _) | Change::InsertAll(target, _) => target.parent(),
+            Change::Replace(target, _) | Change::ReplaceWithMany(target, _) => match target {
+                SyntaxElement::Node(target) => target.parent().unwrap_or_else(|| target.clone()),
+                SyntaxElement::Token(target) => target.parent().unwrap(),
+            },
+            Change::ReplaceAll(target, _) => target.start().parent().unwrap(),
+        }
+    }
+
+    fn change_kind(&self) -> ChangeKind {
+        match self {
+            Change::Insert(_, _) | Change::InsertAll(_, _) => ChangeKind::Insert,
+            Change::Replace(_, _) | Change::ReplaceWithMany(_, _) => ChangeKind::Replace,
+            Change::ReplaceAll(_, _) => ChangeKind::ReplaceRange,
+        }
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
+enum ChangeKind {
+    Insert,
+    ReplaceRange,
+    Replace,
+}
+
+/// Utility trait to allow calling syntax editor functions with references or owned
+/// nodes. Do not use outside of this module.
+pub trait Element {
+    fn syntax_element(self) -> SyntaxElement;
+}
+
+impl<E: Element + Clone> Element for &'_ E {
+    fn syntax_element(self) -> SyntaxElement {
+        self.clone().syntax_element()
+    }
+}
+
+impl Element for SyntaxElement {
+    fn syntax_element(self) -> SyntaxElement {
+        self
+    }
+}
+
+impl Element for SyntaxNode {
+    fn syntax_element(self) -> SyntaxElement {
+        self.into()
+    }
+}
+
+impl Element for SyntaxToken {
+    fn syntax_element(self) -> SyntaxElement {
+        self.into()
+    }
+}
+
+fn is_ancestor_or_self(node: &SyntaxNode, ancestor: &SyntaxNode) -> bool {
+    node == ancestor || node.ancestors().any(|it| &it == ancestor)
+}
+
+fn is_ancestor_or_self_of_element(node: &SyntaxElement, ancestor: &SyntaxNode) -> bool {
+    matches!(node, SyntaxElement::Node(node) if node == ancestor)
+        || node.ancestors().any(|it| &it == ancestor)
+}
+
+#[cfg(test)]
+mod tests {
+    use expect_test::expect;
+    use itertools::Itertools;
+
+    use crate::{
+        ast::{self, make, HasName},
+        AstNode,
+    };
+
+    use super::*;
+
+    fn make_ident_pat(
+        editor: Option<&mut SyntaxEditor>,
+        ref_: bool,
+        mut_: bool,
+        name: ast::Name,
+    ) -> ast::IdentPat {
+        let ast = make::ident_pat(ref_, mut_, name.clone()).clone_for_update();
+
+        if let Some(editor) = editor {
+            let mut mapping = SyntaxMappingBuilder::new(ast.syntax().clone());
+            mapping.map_node(name.syntax().clone(), ast.name().unwrap().syntax().clone());
+            mapping.finish(editor);
+        }
+
+        ast
+    }
+
+    fn make_let_stmt(
+        editor: Option<&mut SyntaxEditor>,
+        pattern: ast::Pat,
+        ty: Option<ast::Type>,
+        initializer: Option<ast::Expr>,
+    ) -> ast::LetStmt {
+        let ast =
+            make::let_stmt(pattern.clone(), ty.clone(), initializer.clone()).clone_for_update();
+
+        if let Some(editor) = editor {
+            let mut mapping = SyntaxMappingBuilder::new(ast.syntax().clone());
+            mapping.map_node(pattern.syntax().clone(), ast.pat().unwrap().syntax().clone());
+            if let Some(input) = ty {
+                mapping.map_node(input.syntax().clone(), ast.ty().unwrap().syntax().clone());
+            }
+            if let Some(input) = initializer {
+                mapping
+                    .map_node(input.syntax().clone(), ast.initializer().unwrap().syntax().clone());
+            }
+            mapping.finish(editor);
+        }
+
+        ast
+    }
+
+    fn make_block_expr(
+        editor: Option<&mut SyntaxEditor>,
+        stmts: impl IntoIterator<Item = ast::Stmt>,
+        tail_expr: Option<ast::Expr>,
+    ) -> ast::BlockExpr {
+        let stmts = stmts.into_iter().collect_vec();
+        let input = stmts.iter().map(|it| it.syntax().clone()).collect_vec();
+
+        let ast = make::block_expr(stmts, tail_expr.clone()).clone_for_update();
+
+        if let Some((editor, stmt_list)) = editor.zip(ast.stmt_list()) {
+            let mut mapping = SyntaxMappingBuilder::new(stmt_list.syntax().clone());
+
+            mapping.map_children(
+                input.into_iter(),
+                stmt_list.statements().map(|it| it.syntax().clone()),
+            );
+
+            if let Some((input, output)) = tail_expr.zip(stmt_list.tail_expr()) {
+                mapping.map_node(input.syntax().clone(), output.syntax().clone());
+            }
+
+            mapping.finish(editor);
+        }
+
+        ast
+    }
+
+    #[test]
+    fn basic_usage() {
+        let root = make::match_arm(
+            [make::wildcard_pat().into()],
+            None,
+            make::expr_tuple([
+                make::expr_bin_op(
+                    make::expr_literal("2").into(),
+                    ast::BinaryOp::ArithOp(ast::ArithOp::Add),
+                    make::expr_literal("2").into(),
+                ),
+                make::expr_literal("true").into(),
+            ]),
+        );
+
+        let to_wrap = root.syntax().descendants().find_map(ast::TupleExpr::cast).unwrap();
+        let to_replace = root.syntax().descendants().find_map(ast::BinExpr::cast).unwrap();
+
+        let mut editor = SyntaxEditor::new(root.syntax().clone());
+
+        let name = make::name("var_name");
+        let name_ref = make::name_ref("var_name").clone_for_update();
+
+        let placeholder_snippet = SyntaxAnnotation::new();
+        editor.add_annotation(name.syntax(), placeholder_snippet);
+        editor.add_annotation(name_ref.syntax(), placeholder_snippet);
+
+        let make_ident_pat = make_ident_pat(Some(&mut editor), false, false, name);
+        let make_let_stmt = make_let_stmt(
+            Some(&mut editor),
+            make_ident_pat.into(),
+            None,
+            Some(to_replace.clone().into()),
+        );
+        let new_block = make_block_expr(
+            Some(&mut editor),
+            [make_let_stmt.into()],
+            Some(to_wrap.clone().into()),
+        );
+
+        editor.replace(to_replace.syntax(), name_ref.syntax());
+        editor.replace(to_wrap.syntax(), new_block.syntax());
+
+        let edit = editor.finish();
+
+        let expect = expect![[r#"
+            _ => {
+                let var_name = 2 + 2;
+                (var_name, true)
+            }"#]];
+        expect.assert_eq(&edit.new_root.to_string());
+
+        assert_eq!(edit.find_annotation(placeholder_snippet).len(), 2);
+        assert!(edit
+            .annotations
+            .iter()
+            .flat_map(|(_, elements)| elements)
+            .all(|element| element.ancestors().any(|it| &it == edit.new_root())))
+    }
+
+    #[test]
+    fn test_insert_independent() {
+        let root = make::block_expr(
+            [make::let_stmt(
+                make::ext::simple_ident_pat(make::name("second")).into(),
+                None,
+                Some(make::expr_literal("2").into()),
+            )
+            .into()],
+            None,
+        );
+
+        let second_let = root.syntax().descendants().find_map(ast::LetStmt::cast).unwrap();
+
+        let mut editor = SyntaxEditor::new(root.syntax().clone());
+
+        editor.insert(
+            Position::first_child_of(root.stmt_list().unwrap().syntax()),
+            make_let_stmt(
+                None,
+                make::ext::simple_ident_pat(make::name("first")).into(),
+                None,
+                Some(make::expr_literal("1").into()),
+            )
+            .syntax(),
+        );
+
+        editor.insert(
+            Position::after(second_let.syntax()),
+            make_let_stmt(
+                None,
+                make::ext::simple_ident_pat(make::name("third")).into(),
+                None,
+                Some(make::expr_literal("3").into()),
+            )
+            .syntax(),
+        );
+
+        let edit = editor.finish();
+
+        let expect = expect![[r#"
+            let first = 1;{
+                let second = 2;let third = 3;
+            }"#]];
+        expect.assert_eq(&edit.new_root.to_string());
+    }
+
+    #[test]
+    fn test_insert_dependent() {
+        let root = make::block_expr(
+            [],
+            Some(
+                make::block_expr(
+                    [make::let_stmt(
+                        make::ext::simple_ident_pat(make::name("second")).into(),
+                        None,
+                        Some(make::expr_literal("2").into()),
+                    )
+                    .into()],
+                    None,
+                )
+                .into(),
+            ),
+        );
+
+        let inner_block =
+            root.syntax().descendants().flat_map(ast::BlockExpr::cast).nth(1).unwrap();
+        let second_let = root.syntax().descendants().find_map(ast::LetStmt::cast).unwrap();
+
+        let mut editor = SyntaxEditor::new(root.syntax().clone());
+
+        let new_block_expr =
+            make_block_expr(Some(&mut editor), [], Some(ast::Expr::BlockExpr(inner_block.clone())));
+
+        let first_let = make_let_stmt(
+            Some(&mut editor),
+            make::ext::simple_ident_pat(make::name("first")).into(),
+            None,
+            Some(make::expr_literal("1").into()),
+        );
+
+        let third_let = make_let_stmt(
+            Some(&mut editor),
+            make::ext::simple_ident_pat(make::name("third")).into(),
+            None,
+            Some(make::expr_literal("3").into()),
+        );
+
+        editor.insert(
+            Position::first_child_of(inner_block.stmt_list().unwrap().syntax()),
+            first_let.syntax(),
+        );
+        editor.insert(Position::after(second_let.syntax()), third_let.syntax());
+        editor.replace(inner_block.syntax(), new_block_expr.syntax());
+
+        let edit = editor.finish();
+
+        let expect = expect![[r#"
+            {
+                {
+                let first = 1;{
+                let second = 2;let third = 3;
+            }
+            }
+            }"#]];
+        expect.assert_eq(&edit.new_root.to_string());
+    }
+
+    #[test]
+    fn test_replace_root_with_dependent() {
+        let root = make::block_expr(
+            [make::let_stmt(
+                make::ext::simple_ident_pat(make::name("second")).into(),
+                None,
+                Some(make::expr_literal("2").into()),
+            )
+            .into()],
+            None,
+        );
+
+        let inner_block = root.clone();
+
+        let mut editor = SyntaxEditor::new(root.syntax().clone());
+
+        let new_block_expr =
+            make_block_expr(Some(&mut editor), [], Some(ast::Expr::BlockExpr(inner_block.clone())));
+
+        let first_let = make_let_stmt(
+            Some(&mut editor),
+            make::ext::simple_ident_pat(make::name("first")).into(),
+            None,
+            Some(make::expr_literal("1").into()),
+        );
+
+        editor.insert(
+            Position::first_child_of(inner_block.stmt_list().unwrap().syntax()),
+            first_let.syntax(),
+        );
+        editor.replace(inner_block.syntax(), new_block_expr.syntax());
+
+        let edit = editor.finish();
+
+        let expect = expect![[r#"
+            {
+                let first = 1;{
+                let second = 2;
+            }
+            }"#]];
+        expect.assert_eq(&edit.new_root.to_string());
+    }
+}
diff --git a/crates/syntax/src/syntax_editor/edit_algo.rs b/crates/syntax/src/syntax_editor/edit_algo.rs
new file mode 100644
index 0000000..b769c94
--- /dev/null
+++ b/crates/syntax/src/syntax_editor/edit_algo.rs
@@ -0,0 +1,367 @@
+//! Implementation of applying changes to a syntax tree.
+
+use std::{cmp::Ordering, collections::VecDeque, ops::RangeInclusive};
+
+use rowan::TextRange;
+use rustc_hash::FxHashMap;
+
+use crate::{
+    syntax_editor::{mapping::MissingMapping, Change, ChangeKind, PositionRepr},
+    SyntaxElement, SyntaxNode, SyntaxNodePtr,
+};
+
+use super::{SyntaxEdit, SyntaxEditor};
+
+pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
+    // Algorithm overview:
+    //
+    // - Sort changes by (range, type)
+    //   - Ensures that parent edits are before child edits
+    //   - Ensures that inserts will be guaranteed to be inserted at the right range
+    // - Validate changes
+    //   - Checking for invalid changes is easy since the changes will be sorted by range
+    // - Fixup change targets
+    //   - standalone change? map to original syntax tree
+    //   - dependent change?
+    //     - try to map to parent change (either independent or another dependent)
+    //     - note: need to keep track of a parent change stack, since a change can be a parent of multiple changes
+    // - Apply changes
+    //   - find changes to apply to real tree by applying nested changes first
+    //   - changed nodes become part of the changed node set (useful for the formatter to only change those parts)
+    // - Propagate annotations
+
+    let SyntaxEditor { root, mut changes, mappings, annotations } = editor;
+
+    let mut node_depths = FxHashMap::<SyntaxNode, usize>::default();
+    let mut get_node_depth = |node: SyntaxNode| {
+        *node_depths.entry(node).or_insert_with_key(|node| node.ancestors().count())
+    };
+
+    // Sort changes by range, then depth, then change kind, so that we can:
+    // - ensure that parent edits are ordered before child edits
+    // - ensure that inserts will be guaranteed to be inserted at the right range
+    // - easily check for disjoint replace ranges
+    changes.sort_by(|a, b| {
+        a.target_range()
+            .start()
+            .cmp(&b.target_range().start())
+            .then_with(|| {
+                let a_target = a.target_parent();
+                let b_target = b.target_parent();
+
+                if a_target == b_target {
+                    return Ordering::Equal;
+                }
+
+                get_node_depth(a_target).cmp(&get_node_depth(b_target))
+            })
+            .then(a.change_kind().cmp(&b.change_kind()))
+    });
+
+    let disjoint_replaces_ranges = changes
+        .iter()
+        .zip(changes.iter().skip(1))
+        .filter(|(l, r)| {
+            // We only care about checking for disjoint replace ranges
+            matches!(
+                (l.change_kind(), r.change_kind()),
+                (
+                    ChangeKind::Replace | ChangeKind::ReplaceRange,
+                    ChangeKind::Replace | ChangeKind::ReplaceRange
+                )
+            )
+        })
+        .all(|(l, r)| {
+            get_node_depth(l.target_parent()) != get_node_depth(r.target_parent())
+                || l.target_range().intersect(r.target_range()).is_none()
+        });
+
+    if stdx::never!(
+        !disjoint_replaces_ranges,
+        "some replace change ranges intersect: {:?}",
+        changes
+    ) {
+        return SyntaxEdit {
+            old_root: root.clone(),
+            new_root: root,
+            annotations: Default::default(),
+            changed_elements: vec![],
+        };
+    }
+
+    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+    struct DependentChange {
+        parent: u32,
+        child: u32,
+    }
+
+    // Build change tree
+    let mut changed_ancestors: VecDeque<ChangedAncestor> = VecDeque::new();
+    let mut dependent_changes = vec![];
+    let mut independent_changes = vec![];
+
+    for (change_index, change) in changes.iter().enumerate() {
+        // Check if this change is dependent on another change (i.e. it's contained within another range)
+        if let Some(index) = changed_ancestors
+            .iter()
+            .rev()
+            .position(|ancestor| ancestor.affected_range().contains_range(change.target_range()))
+        {
+            // Pop off any ancestors that aren't applicable
+            changed_ancestors.drain((index + 1)..);
+
+            // FIXME: Resolve changes that depend on a range of elements
+            let ancestor = &changed_ancestors[index];
+
+            dependent_changes.push(DependentChange {
+                parent: ancestor.change_index as u32,
+                child: change_index as u32,
+            });
+        } else {
+            // This change is independent of any other change
+
+            // Drain the changed ancestors since we're no longer in a set of dependent changes
+            changed_ancestors.drain(..);
+
+            independent_changes.push(change_index as u32);
+        }
+
+        // Add to changed ancestors, if applicable
+        match change {
+            Change::Insert(_, _) | Change::InsertAll(_, _) => {}
+            Change::Replace(target, _) | Change::ReplaceWithMany(target, _) => {
+                changed_ancestors.push_back(ChangedAncestor::single(target, change_index))
+            }
+            Change::ReplaceAll(range, _) => {
+                changed_ancestors.push_back(ChangedAncestor::multiple(range, change_index))
+            }
+        }
+    }
+
+    // Map change targets to the correct syntax nodes
+    let tree_mutator = TreeMutator::new(&root);
+    let mut changed_elements = vec![];
+
+    for index in independent_changes {
+        match &mut changes[index as usize] {
+            Change::Insert(target, _) | Change::InsertAll(target, _) => {
+                match &mut target.repr {
+                    PositionRepr::FirstChild(parent) => {
+                        *parent = tree_mutator.make_syntax_mut(parent);
+                    }
+                    PositionRepr::After(child) => {
+                        *child = tree_mutator.make_element_mut(child);
+                    }
+                };
+            }
+            Change::Replace(target, _) | Change::ReplaceWithMany(target, _) => {
+                *target = tree_mutator.make_element_mut(target);
+            }
+            Change::ReplaceAll(range, _) => {
+                let start = tree_mutator.make_element_mut(range.start());
+                let end = tree_mutator.make_element_mut(range.end());
+
+                *range = start..=end;
+            }
+        }
+
+        // Collect changed elements
+        match &changes[index as usize] {
+            Change::Insert(_, element) => changed_elements.push(element.clone()),
+            Change::InsertAll(_, elements) => changed_elements.extend(elements.iter().cloned()),
+            Change::Replace(_, Some(element)) => changed_elements.push(element.clone()),
+            Change::Replace(_, None) => {}
+            Change::ReplaceWithMany(_, elements) => {
+                changed_elements.extend(elements.iter().cloned())
+            }
+            Change::ReplaceAll(_, elements) => changed_elements.extend(elements.iter().cloned()),
+        }
+    }
+
+    for DependentChange { parent, child } in dependent_changes.into_iter() {
+        let (input_ancestor, output_ancestor) = match &changes[parent as usize] {
+            // No change will depend on an insert since changes can only depend on nodes in the root tree
+            Change::Insert(_, _) | Change::InsertAll(_, _) => unreachable!(),
+            Change::Replace(target, Some(new_target)) => {
+                (to_owning_node(target), to_owning_node(new_target))
+            }
+            // Silently drop outdated change
+            Change::Replace(_, None) => continue,
+            Change::ReplaceAll(_, _) | Change::ReplaceWithMany(_, _) => {
+                unimplemented!("cannot resolve changes that depend on replacing many elements")
+            }
+        };
+
+        let upmap_target_node = |target: &SyntaxNode| {
+            match mappings.upmap_child(target, &input_ancestor, &output_ancestor) {
+                Ok(it) => it,
+                Err(MissingMapping(current)) => unreachable!("no mappings exist between {current:?} (ancestor of {input_ancestor:?}) and {output_ancestor:?}"),
+            }
+        };
+
+        let upmap_target = |target: &SyntaxElement| {
+            match mappings.upmap_child_element(target, &input_ancestor, &output_ancestor) {
+                Ok(it) => it,
+                Err(MissingMapping(current)) => unreachable!("no mappings exist between {current:?} (ancestor of {input_ancestor:?}) and {output_ancestor:?}"),
+            }
+        };
+
+        match &mut changes[child as usize] {
+            Change::Insert(target, _) | Change::InsertAll(target, _) => match &mut target.repr {
+                PositionRepr::FirstChild(parent) => {
+                    *parent = upmap_target_node(parent);
+                }
+                PositionRepr::After(child) => {
+                    *child = upmap_target(child);
+                }
+            },
+            Change::Replace(target, _) | Change::ReplaceWithMany(target, _) => {
+                *target = upmap_target(target);
+            }
+            Change::ReplaceAll(range, _) => {
+                *range = upmap_target(range.start())..=upmap_target(range.end());
+            }
+        }
+    }
+
+    // Apply changes
+    let mut root = tree_mutator.mutable_clone;
+
+    for change in changes {
+        match change {
+            Change::Insert(position, element) => {
+                let (parent, index) = position.place();
+                parent.splice_children(index..index, vec![element]);
+            }
+            Change::InsertAll(position, elements) => {
+                let (parent, index) = position.place();
+                parent.splice_children(index..index, elements);
+            }
+            Change::Replace(target, None) => {
+                target.detach();
+            }
+            Change::Replace(SyntaxElement::Node(target), Some(new_target)) if target == root => {
+                root = new_target.into_node().expect("root node replacement should be a node");
+            }
+            Change::Replace(target, Some(new_target)) => {
+                let parent = target.parent().unwrap();
+                parent.splice_children(target.index()..target.index() + 1, vec![new_target]);
+            }
+            Change::ReplaceWithMany(target, elements) => {
+                let parent = target.parent().unwrap();
+                parent.splice_children(target.index()..target.index() + 1, elements);
+            }
+            Change::ReplaceAll(range, elements) => {
+                let start = range.start().index();
+                let end = range.end().index();
+                let parent = range.start().parent().unwrap();
+                parent.splice_children(start..end + 1, elements);
+            }
+        }
+    }
+
+    // Propagate annotations
+    let annotations = annotations.into_iter().filter_map(|(element, annotation)| {
+        match mappings.upmap_element(&element, &root) {
+            // Needed to follow the new tree to find the resulting element
+            Some(Ok(mapped)) => Some((mapped, annotation)),
+            // Element did not need to be mapped
+            None => Some((element, annotation)),
+            // Element did not make it to the final tree
+            Some(Err(_)) => None,
+        }
+    });
+
+    let mut annotation_groups = FxHashMap::default();
+
+    for (element, annotation) in annotations {
+        annotation_groups.entry(annotation).or_insert(vec![]).push(element);
+    }
+
+    SyntaxEdit {
+        old_root: tree_mutator.immutable,
+        new_root: root,
+        changed_elements,
+        annotations: annotation_groups,
+    }
+}
+
+fn to_owning_node(element: &SyntaxElement) -> SyntaxNode {
+    match element {
+        SyntaxElement::Node(node) => node.clone(),
+        SyntaxElement::Token(token) => token.parent().unwrap().clone(),
+    }
+}
+
+struct ChangedAncestor {
+    kind: ChangedAncestorKind,
+    change_index: usize,
+}
+
+enum ChangedAncestorKind {
+    Single { node: SyntaxNode },
+    Range { _changed_elements: RangeInclusive<SyntaxElement>, _in_parent: SyntaxNode },
+}
+
+impl ChangedAncestor {
+    fn single(element: &SyntaxElement, change_index: usize) -> Self {
+        let kind = match element {
+            SyntaxElement::Node(node) => ChangedAncestorKind::Single { node: node.clone() },
+            SyntaxElement::Token(token) => {
+                ChangedAncestorKind::Single { node: token.parent().unwrap() }
+            }
+        };
+
+        Self { kind, change_index }
+    }
+
+    fn multiple(range: &RangeInclusive<SyntaxElement>, change_index: usize) -> Self {
+        Self {
+            kind: ChangedAncestorKind::Range {
+                _changed_elements: range.clone(),
+                _in_parent: range.start().parent().unwrap(),
+            },
+            change_index,
+        }
+    }
+
+    fn affected_range(&self) -> TextRange {
+        match &self.kind {
+            ChangedAncestorKind::Single { node } => node.text_range(),
+            ChangedAncestorKind::Range { _changed_elements: changed_nodes, _in_parent: _ } => {
+                TextRange::new(
+                    changed_nodes.start().text_range().start(),
+                    changed_nodes.end().text_range().end(),
+                )
+            }
+        }
+    }
+}
+
+struct TreeMutator {
+    immutable: SyntaxNode,
+    mutable_clone: SyntaxNode,
+}
+
+impl TreeMutator {
+    fn new(immutable: &SyntaxNode) -> TreeMutator {
+        let immutable = immutable.clone();
+        let mutable_clone = immutable.clone_for_update();
+        TreeMutator { immutable, mutable_clone }
+    }
+
+    fn make_element_mut(&self, element: &SyntaxElement) -> SyntaxElement {
+        match element {
+            SyntaxElement::Node(node) => SyntaxElement::Node(self.make_syntax_mut(node)),
+            SyntaxElement::Token(token) => {
+                let parent = self.make_syntax_mut(&token.parent().unwrap());
+                parent.children_with_tokens().nth(token.index()).unwrap()
+            }
+        }
+    }
+
+    fn make_syntax_mut(&self, node: &SyntaxNode) -> SyntaxNode {
+        let ptr = SyntaxNodePtr::new(node);
+        ptr.to_node(&self.mutable_clone)
+    }
+}
diff --git a/crates/syntax/src/syntax_editor/mapping.rs b/crates/syntax/src/syntax_editor/mapping.rs
new file mode 100644
index 0000000..9bb5e6d
--- /dev/null
+++ b/crates/syntax/src/syntax_editor/mapping.rs
@@ -0,0 +1,272 @@
+//! Maps syntax elements through disjoint syntax nodes.
+//!
+//! [`SyntaxMappingBuilder`] should be used to create mappings to add to a [`SyntaxEditor`]
+
+use itertools::Itertools;
+use rustc_hash::FxHashMap;
+
+use crate::{SyntaxElement, SyntaxNode};
+
+use super::SyntaxEditor;
+
+#[derive(Debug, Default)]
+pub struct SyntaxMapping {
+    // important information to keep track of:
+    // node -> node
+    // token -> token (implicit in mappings)
+    // input parent -> output parent (for deep lookups)
+
+    // mappings ->  parents
+    entry_parents: Vec<SyntaxNode>,
+    node_mappings: FxHashMap<SyntaxNode, MappingEntry>,
+}
+
+impl SyntaxMapping {
+    pub fn new() -> Self {
+        Self::default()
+    }
+
+    /// Like [`SyntaxMapping::upmap_child`] but for syntax elements.
+    pub fn upmap_child_element(
+        &self,
+        child: &SyntaxElement,
+        input_ancestor: &SyntaxNode,
+        output_ancestor: &SyntaxNode,
+    ) -> Result<SyntaxElement, MissingMapping> {
+        match child {
+            SyntaxElement::Node(node) => {
+                self.upmap_child(node, input_ancestor, output_ancestor).map(SyntaxElement::Node)
+            }
+            SyntaxElement::Token(token) => {
+                let upmap_parent =
+                    self.upmap_child(&token.parent().unwrap(), input_ancestor, output_ancestor)?;
+
+                let element = upmap_parent.children_with_tokens().nth(token.index()).unwrap();
+                debug_assert!(
+                    element.as_token().is_some_and(|it| it.kind() == token.kind()),
+                    "token upmapping mapped to the wrong node ({token:?} -> {element:?})"
+                );
+
+                Ok(element)
+            }
+        }
+    }
+
+    /// Maps a child node of the input ancestor to the corresponding node in
+    /// the output ancestor.
+    pub fn upmap_child(
+        &self,
+        child: &SyntaxNode,
+        input_ancestor: &SyntaxNode,
+        output_ancestor: &SyntaxNode,
+    ) -> Result<SyntaxNode, MissingMapping> {
+        debug_assert!(
+            child == input_ancestor
+                || child.ancestors().any(|ancestor| &ancestor == input_ancestor)
+        );
+
+        // Build a list mapping up to the first mappable ancestor
+        let to_first_upmap = if child != input_ancestor {
+            std::iter::successors(Some((child.index(), child.clone())), |(_, current)| {
+                let parent = current.parent().unwrap();
+
+                if &parent == input_ancestor {
+                    return None;
+                }
+
+                Some((parent.index(), parent))
+            })
+            .map(|(i, _)| i)
+            .collect::<Vec<_>>()
+        } else {
+            vec![]
+        };
+
+        // Progressively up-map the input ancestor until we get to the output ancestor
+        let to_output_ancestor = if input_ancestor != output_ancestor {
+            self.upmap_to_ancestor(input_ancestor, output_ancestor)?
+        } else {
+            vec![]
+        };
+
+        let to_map_down =
+            to_output_ancestor.into_iter().rev().chain(to_first_upmap.into_iter().rev());
+
+        let mut target = output_ancestor.clone();
+
+        for index in to_map_down {
+            target = target
+                .children_with_tokens()
+                .nth(index)
+                .and_then(|it| it.into_node())
+                .expect("equivalent ancestor node should be present in target tree");
+        }
+
+        debug_assert_eq!(child.kind(), target.kind());
+
+        Ok(target)
+    }
+
+    fn upmap_to_ancestor(
+        &self,
+        input_ancestor: &SyntaxNode,
+        output_ancestor: &SyntaxNode,
+    ) -> Result<Vec<usize>, MissingMapping> {
+        let mut current =
+            self.upmap_node_single(input_ancestor).unwrap_or_else(|| input_ancestor.clone());
+        let mut upmap_chain = vec![current.index()];
+
+        loop {
+            let Some(parent) = current.parent() else { break };
+
+            if &parent == output_ancestor {
+                return Ok(upmap_chain);
+            }
+
+            current = match self.upmap_node_single(&parent) {
+                Some(next) => next,
+                None => parent,
+            };
+            upmap_chain.push(current.index());
+        }
+
+        Err(MissingMapping(current))
+    }
+
+    pub fn upmap_element(
+        &self,
+        input: &SyntaxElement,
+        output_root: &SyntaxNode,
+    ) -> Option<Result<SyntaxElement, MissingMapping>> {
+        match input {
+            SyntaxElement::Node(node) => {
+                Some(self.upmap_node(node, output_root)?.map(SyntaxElement::Node))
+            }
+            SyntaxElement::Token(token) => {
+                let upmap_parent = match self.upmap_node(&token.parent().unwrap(), output_root)? {
+                    Ok(it) => it,
+                    Err(err) => return Some(Err(err)),
+                };
+
+                let element = upmap_parent.children_with_tokens().nth(token.index()).unwrap();
+                debug_assert!(
+                    element.as_token().is_some_and(|it| it.kind() == token.kind()),
+                    "token upmapping mapped to the wrong node ({token:?} -> {element:?})"
+                );
+
+                Some(Ok(element))
+            }
+        }
+    }
+
+    pub fn upmap_node(
+        &self,
+        input: &SyntaxNode,
+        output_root: &SyntaxNode,
+    ) -> Option<Result<SyntaxNode, MissingMapping>> {
+        // Try to follow the mapping tree, if it exists
+        let input_mapping = self.upmap_node_single(input);
+        let input_ancestor =
+            input.ancestors().find_map(|ancestor| self.upmap_node_single(&ancestor));
+
+        match (input_mapping, input_ancestor) {
+            (Some(input_mapping), _) => {
+                // A mapping exists at the input, follow along the tree
+                Some(self.upmap_child(&input_mapping, &input_mapping, output_root))
+            }
+            (None, Some(input_ancestor)) => {
+                // A mapping exists at an ancestor, follow along the tree
+                Some(self.upmap_child(input, &input_ancestor, output_root))
+            }
+            (None, None) => {
+                // No mapping exists at all, is the same position in the final tree
+                None
+            }
+        }
+    }
+
+    pub fn merge(&mut self, mut other: SyntaxMapping) {
+        // Remap other's entry parents to be after the current list of entry parents
+        let remap_base: u32 = self.entry_parents.len().try_into().unwrap();
+
+        self.entry_parents.append(&mut other.entry_parents);
+        self.node_mappings.extend(other.node_mappings.into_iter().map(|(node, entry)| {
+            (node, MappingEntry { parent: entry.parent + remap_base, ..entry })
+        }));
+    }
+
+    /// Follows the input one step along the syntax mapping tree
+    fn upmap_node_single(&self, input: &SyntaxNode) -> Option<SyntaxNode> {
+        let MappingEntry { parent, child_slot } = self.node_mappings.get(input)?;
+
+        let output = self.entry_parents[*parent as usize]
+            .children_with_tokens()
+            .nth(*child_slot as usize)
+            .and_then(SyntaxElement::into_node)
+            .unwrap();
+
+        debug_assert_eq!(input.kind(), output.kind());
+        Some(output)
+    }
+
+    fn add_mapping(&mut self, syntax_mapping: SyntaxMappingBuilder) {
+        let SyntaxMappingBuilder { parent_node, node_mappings } = syntax_mapping;
+
+        let parent_entry: u32 = self.entry_parents.len().try_into().unwrap();
+        self.entry_parents.push(parent_node);
+
+        let node_entries = node_mappings
+            .into_iter()
+            .map(|(node, slot)| (node, MappingEntry { parent: parent_entry, child_slot: slot }));
+
+        self.node_mappings.extend(node_entries);
+    }
+}
+
+#[derive(Debug)]
+pub struct SyntaxMappingBuilder {
+    parent_node: SyntaxNode,
+    node_mappings: Vec<(SyntaxNode, u32)>,
+}
+
+impl SyntaxMappingBuilder {
+    pub fn new(parent_node: SyntaxNode) -> Self {
+        Self { parent_node, node_mappings: vec![] }
+    }
+
+    pub fn map_node(&mut self, input: SyntaxNode, output: SyntaxNode) {
+        debug_assert_eq!(output.parent().as_ref(), Some(&self.parent_node));
+        self.node_mappings.push((input, output.index() as u32));
+    }
+
+    pub fn map_children(
+        &mut self,
+        input: impl Iterator<Item = SyntaxNode>,
+        output: impl Iterator<Item = SyntaxNode>,
+    ) {
+        for pairs in input.zip_longest(output) {
+            let (input, output) = match pairs {
+                itertools::EitherOrBoth::Both(l, r) => (l, r),
+                itertools::EitherOrBoth::Left(_) => {
+                    unreachable!("mapping more input nodes than there are output nodes")
+                }
+                itertools::EitherOrBoth::Right(_) => break,
+            };
+
+            self.map_node(input, output);
+        }
+    }
+
+    pub fn finish(self, editor: &mut SyntaxEditor) {
+        editor.mappings.add_mapping(self);
+    }
+}
+
+#[derive(Debug)]
+pub struct MissingMapping(pub SyntaxNode);
+
+#[derive(Debug, Clone, Copy)]
+struct MappingEntry {
+    parent: u32,
+    child_slot: u32,
+}
diff --git a/crates/syntax/src/ted.rs b/crates/syntax/src/ted.rs
index 29788d0..8592df1 100644
--- a/crates/syntax/src/ted.rs
+++ b/crates/syntax/src/ted.rs
@@ -147,6 +147,11 @@
     insert_raw(position, child);
 }
 
+pub fn prepend_child(node: &(impl Into<SyntaxNode> + Clone), child: impl Element) {
+    let position = Position::first_child_of(node);
+    insert(position, child);
+}
+
 fn ws_before(position: &Position, new: &SyntaxElement) -> Option<SyntaxToken> {
     let prev = match &position.repr {
         PositionRepr::FirstChild(_) => return None,
diff --git a/crates/test-fixture/src/lib.rs b/crates/test-fixture/src/lib.rs
index 03e85a8..593e31c 100644
--- a/crates/test-fixture/src/lib.rs
+++ b/crates/test-fixture/src/lib.rs
@@ -2,8 +2,8 @@
 use std::{iter, mem, str::FromStr, sync};
 
 use base_db::{
-    CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Env, FileChange,
-    FileSet, LangCrateOrigin, SourceRoot, SourceRootDatabase, Version, VfsPath,
+    CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, CrateWorkspaceData, Dependency,
+    Env, FileChange, FileSet, LangCrateOrigin, SourceRoot, SourceRootDatabase, Version, VfsPath,
 };
 use cfg::CfgOptions;
 use hir_expand::{
@@ -13,7 +13,7 @@
     proc_macro::{
         ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind, ProcMacrosBuilder,
     },
-    FileRange,
+    quote, FileRange,
 };
 use intern::Symbol;
 use rustc_hash::FxHashMap;
@@ -95,8 +95,10 @@
     fn test_crate(&self) -> CrateId {
         let crate_graph = self.crate_graph();
         let mut it = crate_graph.iter();
-        let res = it.next().unwrap();
-        assert!(it.next().is_none());
+        let mut res = it.next().unwrap();
+        while crate_graph[res].origin.is_lang() {
+            res = it.next().unwrap();
+        }
         res
     }
 }
@@ -352,23 +354,27 @@
         };
         roots.push(root);
 
-        let mut change = ChangeWithProcMacros {
-            source_change,
-            proc_macros: Some(proc_macros.build()),
-            toolchains: Some(iter::repeat(toolchain).take(crate_graph.len()).collect()),
-            target_data_layouts: Some(
-                iter::repeat(target_data_layout).take(crate_graph.len()).collect(),
-            ),
-        };
+        let mut change =
+            ChangeWithProcMacros { source_change, proc_macros: Some(proc_macros.build()) };
 
         change.source_change.set_roots(roots);
+        change.source_change.set_ws_data(
+            crate_graph
+                .iter()
+                .zip(iter::repeat(From::from(CrateWorkspaceData {
+                    proc_macro_cwd: None,
+                    data_layout: target_data_layout,
+                    toolchain,
+                })))
+                .collect(),
+        );
         change.source_change.set_crate_graph(crate_graph);
 
         ChangeFixture { file_position, files, change }
     }
 }
 
-fn default_test_proc_macros() -> [(String, ProcMacro); 5] {
+fn default_test_proc_macros() -> [(String, ProcMacro); 6] {
     [
         (
             r#"
@@ -445,6 +451,21 @@
                 disabled: false,
             },
         ),
+        (
+            r#"
+#[proc_macro_attribute]
+pub fn issue_18089(_attr: TokenStream, _item: TokenStream) -> TokenStream {
+    loop {}
+}
+"#
+            .into(),
+            ProcMacro {
+                name: Symbol::intern("issue_18089"),
+                kind: ProcMacroKind::Attr,
+                expander: sync::Arc::new(Issue18089ProcMacroExpander),
+                disabled: false,
+            },
+        ),
     ]
 }
 
@@ -565,11 +586,41 @@
         _: Span,
         _: Span,
         _: Span,
+        _: Option<String>,
     ) -> Result<Subtree<Span>, ProcMacroExpansionError> {
         Ok(subtree.clone())
     }
 }
 
+// Expands to a macro_rules! macro, for issue #18089.
+#[derive(Debug)]
+struct Issue18089ProcMacroExpander;
+impl ProcMacroExpander for Issue18089ProcMacroExpander {
+    fn expand(
+        &self,
+        subtree: &Subtree<Span>,
+        _: Option<&Subtree<Span>>,
+        _: &Env,
+        _: Span,
+        call_site: Span,
+        _: Span,
+        _: Option<String>,
+    ) -> Result<Subtree<Span>, ProcMacroExpansionError> {
+        let macro_name = &subtree.token_trees[1];
+        Ok(quote! { call_site =>
+            #[macro_export]
+            macro_rules! my_macro___ {
+                ($($token:tt)*) => {{
+                }};
+            }
+
+            pub use my_macro___ as #macro_name;
+
+            #subtree
+        })
+    }
+}
+
 // Pastes the attribute input as its output
 #[derive(Debug)]
 struct AttributeInputReplaceProcMacroExpander;
@@ -582,6 +633,7 @@
         _: Span,
         _: Span,
         _: Span,
+        _: Option<String>,
     ) -> Result<Subtree<Span>, ProcMacroExpansionError> {
         attrs
             .cloned()
@@ -600,6 +652,7 @@
         _: Span,
         _: Span,
         _: Span,
+        _: Option<String>,
     ) -> Result<Subtree<Span>, ProcMacroExpansionError> {
         fn traverse(input: &Subtree<Span>) -> Subtree<Span> {
             let mut token_trees = vec![];
@@ -630,6 +683,7 @@
         _: Span,
         _: Span,
         _: Span,
+        _: Option<String>,
     ) -> Result<Subtree<Span>, ProcMacroExpansionError> {
         return Ok(traverse(input));
 
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index 3be4469..67629fc 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -33,6 +33,7 @@
 //!     from: sized
 //!     future: pin
 //!     coroutine: pin
+//!     dispatch_from_dyn: unsize, pin
 //!     hash:
 //!     include:
 //!     index: sized
@@ -64,6 +65,7 @@
 //!     todo: panic
 //!     unimplemented: panic
 //!     column:
+//!     addr_of:
 
 #![rustc_coherence_is_core]
 
@@ -169,7 +171,7 @@
     macro_rules! impl_default {
         ($v:literal; $($t:ty)*) => {
             $(
-                impl const Default for $t {
+                impl Default for $t {
                     fn default() -> Self {
                         $v
                     }
@@ -420,6 +422,17 @@
     }
     // endregion:coerce_unsized
     // endregion:non_null
+
+    // region:addr_of
+    #[rustc_macro_transparency = "semitransparent"]
+    pub macro addr_of($place:expr) {
+        &raw const $place
+    }
+    #[rustc_macro_transparency = "semitransparent"]
+    pub macro addr_of_mut($place:expr) {
+        &raw mut $place
+    }
+    // endregion:addr_of
 }
 
 pub mod ops {
@@ -673,7 +686,7 @@
     // endregion:fn
     // region:try
     mod try_ {
-        use super::super::convert::Infallible;
+        use crate::convert::Infallible;
 
         pub enum ControlFlow<B, C = ()> {
             #[lang = "Continue"]
@@ -743,7 +756,7 @@
         // endregion:option
         // region:result
         // region:from
-        use super::super::convert::From;
+        use crate::convert::From;
 
         impl<T, E> Try for Result<T, E> {
             type Output = T;
@@ -764,7 +777,7 @@
         impl<T, E, F: From<E>> FromResidual<Result<Infallible, E>> for Result<T, F> {
             fn from_residual(residual: Result<Infallible, E>) -> Self {
                 match residual {
-                    Err(e) => Err(From::from(e)),
+                    Err(e) => Err(F::from(e)),
                     Ok(_) => loop {},
                 }
             }
@@ -822,6 +835,24 @@
     }
     pub use self::coroutine::{Coroutine, CoroutineState};
     // endregion:coroutine
+
+    // region:dispatch_from_dyn
+    mod dispatch_from_dyn {
+        use crate::marker::Unsize;
+
+        #[lang = "dispatch_from_dyn"]
+        pub trait DispatchFromDyn<T> {}
+
+        impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
+
+        impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
+
+        impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
+
+        impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
+    }
+    pub use self::dispatch_from_dyn::DispatchFromDyn;
+    // endregion:dispatch_from_dyn
 }
 
 // region:eq
@@ -1183,6 +1214,12 @@
         }
     }
     // endregion:deref
+    // region:dispatch_from_dyn
+    impl<Ptr, U> crate::ops::DispatchFromDyn<Pin<U>> for Pin<Ptr> where
+        Ptr: crate::ops::DispatchFromDyn<U>
+    {
+    }
+    // endregion:dispatch_from_dyn
 }
 // endregion:pin
 
@@ -1309,7 +1346,10 @@
                     self
                 }
                 // region:iterators
-                fn take(self, n: usize) -> crate::iter::Take<Self> {
+                fn take(self, n: usize) -> crate::iter::Take<Self>
+                where
+                    Self: Sized,
+                {
                     loop {}
                 }
                 fn filter_map<B, F>(self, _f: F) -> crate::iter::FilterMap<Self, F>
@@ -1435,6 +1475,19 @@
 }
 // endregion:panic
 
+// region:asm
+mod arch {
+    #[rustc_builtin_macro]
+    pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
+        /* compiler built-in */
+    }
+    #[rustc_builtin_macro]
+    pub macro global_asm("assembly template", $(operands,)* $(options($(option),*))?) {
+        /* compiler built-in */
+    }
+}
+// endregion:asm
+
 #[macro_use]
 mod macros {
     // region:panic
@@ -1447,16 +1500,6 @@
     }
     // endregion:panic
 
-    // region:asm
-    #[macro_export]
-    #[rustc_builtin_macro]
-    macro_rules! asm {
-        ($($arg:tt)*) => {
-            /* compiler built-in */
-        };
-    }
-    // endregion:asm
-
     // region:assert
     #[macro_export]
     #[rustc_builtin_macro]
diff --git a/crates/tt/src/iter.rs b/crates/tt/src/iter.rs
index e96bed0..587b903 100644
--- a/crates/tt/src/iter.rs
+++ b/crates/tt/src/iter.rs
@@ -57,6 +57,13 @@
         }
     }
 
+    pub fn expect_comma(&mut self) -> Result<(), ()> {
+        match self.expect_leaf()? {
+            Leaf::Punct(Punct { char: ',', .. }) => Ok(()),
+            _ => Err(()),
+        }
+    }
+
     pub fn expect_ident(&mut self) -> Result<&'a Ident<S>, ()> {
         match self.expect_leaf()? {
             Leaf::Ident(it) if it.sym != sym::underscore => Ok(it),
diff --git a/crates/vfs/src/lib.rs b/crates/vfs/src/lib.rs
index bc40e03..a26444e 100644
--- a/crates/vfs/src/lib.rs
+++ b/crates/vfs/src/lib.rs
@@ -67,7 +67,7 @@
 // pub struct FileId(NonMaxU32);
 
 impl FileId {
-    pub const MAX: u32 = 0x7fff_ffff;
+    const MAX: u32 = 0x7fff_ffff;
 
     #[inline]
     pub const fn from_raw(raw: u32) -> FileId {
diff --git a/docs/dev/lsp-extensions.md b/docs/dev/lsp-extensions.md
index 4786bd5..b7bac4d 100644
--- a/docs/dev/lsp-extensions.md
+++ b/docs/dev/lsp-extensions.md
@@ -1,5 +1,5 @@
 <!---
-lsp/ext.rs hash: 3429c08745984b3d
+lsp/ext.rs hash: 6292ee8d88d4c9ec
 
 If you need to change the above hash to make the test pass, please check if you
 need to adjust this doc as well and ping this issue:
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index e4a8c64..f37fd7f 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -261,6 +261,13 @@
 Whether `--workspace` should be passed to `cargo check`.
 If false, `-p <package>` will be passed instead.
 --
+[[rust-analyzer.completion.addSemicolonToUnit]]rust-analyzer.completion.addSemicolonToUnit (default: `true`)::
++
+--
+Whether to automatically add a semicolon when completing unit-returning functions.
+
+In `match` arms it completes a comma instead.
+--
 [[rust-analyzer.completion.autoimport.enable]]rust-analyzer.completion.autoimport.enable (default: `true`)::
 +
 --
@@ -283,6 +290,11 @@
 --
 Whether to show full function/method signatures in completion docs.
 --
+[[rust-analyzer.completion.hideDeprecated]]rust-analyzer.completion.hideDeprecated (default: `false`)::
++
+--
+Whether to omit deprecated items from autocompletion. By default they are marked as deprecated but not hidden.
+--
 [[rust-analyzer.completion.limit]]rust-analyzer.completion.limit (default: `null`)::
 +
 --
diff --git a/editors/code/package.json b/editors/code/package.json
index 98e8bbf..b66f0a6 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -1030,6 +1030,16 @@
             {
                 "title": "completion",
                 "properties": {
+                    "rust-analyzer.completion.addSemicolonToUnit": {
+                        "markdownDescription": "Whether to automatically add a semicolon when completing unit-returning functions.\n\nIn `match` arms it completes a comma instead.",
+                        "default": true,
+                        "type": "boolean"
+                    }
+                }
+            },
+            {
+                "title": "completion",
+                "properties": {
                     "rust-analyzer.completion.autoimport.enable": {
                         "markdownDescription": "Toggles the additional completions that automatically add imports when completed.\nNote that your client must specify the `additionalTextEdits` LSP client capability to truly have this feature enabled.",
                         "default": true,
@@ -1080,6 +1090,16 @@
             {
                 "title": "completion",
                 "properties": {
+                    "rust-analyzer.completion.hideDeprecated": {
+                        "markdownDescription": "Whether to omit deprecated items from autocompletion. By default they are marked as deprecated but not hidden.",
+                        "default": false,
+                        "type": "boolean"
+                    }
+                }
+            },
+            {
+                "title": "completion",
+                "properties": {
                     "rust-analyzer.completion.limit": {
                         "markdownDescription": "Maximum number of completions to return. If `None`, the limit is infinite.",
                         "default": null,
diff --git a/lib/lsp-server/Cargo.toml b/lib/lsp-server/Cargo.toml
index fb3411c..cce007a 100644
--- a/lib/lsp-server/Cargo.toml
+++ b/lib/lsp-server/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lsp-server"
-version = "0.7.6"
+version = "0.7.7"
 description = "Generic LSP server scaffold."
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server"
diff --git a/lib/lsp-server/src/stdio.rs b/lib/lsp-server/src/stdio.rs
index c28545f..279a6bc 100644
--- a/lib/lsp-server/src/stdio.rs
+++ b/lib/lsp-server/src/stdio.rs
@@ -30,7 +30,9 @@
                 let is_exit = matches!(&msg, Message::Notification(n) if n.is_exit());
 
                 debug!("sending message {:#?}", msg);
-                reader_sender.send(msg).expect("receiver was dropped, failed to send a message");
+                if let Err(e) = reader_sender.send(msg) {
+                    return Err(io::Error::new(io::ErrorKind::Other, e));
+                }
 
                 if is_exit {
                     break;
@@ -60,15 +62,11 @@
     pub fn join(self) -> io::Result<()> {
         match self.reader.join() {
             Ok(r) => r?,
-            Err(err) => {
-                println!("reader panicked!");
-                std::panic::panic_any(err)
-            }
+            Err(err) => std::panic::panic_any(err),
         }
         match self.writer.join() {
             Ok(r) => r,
             Err(err) => {
-                println!("writer panicked!");
                 std::panic::panic_any(err);
             }
         }
diff --git a/rust-version b/rust-version
index 5f21a43..79ed6cc 100644
--- a/rust-version
+++ b/rust-version
@@ -1 +1 @@
-6cf068db566de080dfa7ed24a216ea3aed2b98ce
+1b5aa96d6016bafe50e071b45d4d2e3c90fd766f
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index 192de86..4bc1821 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -19,6 +19,7 @@
 proc-macro2 = "1.0.47"
 quote = "1.0.20"
 ungrammar = "1.16.1"
+either.workspace = true
 itertools.workspace = true
 # Avoid adding more dependencies to this crate
 
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs
index aeb0c00..4c7b07c 100644
--- a/xtask/src/codegen.rs
+++ b/xtask/src/codegen.rs
@@ -126,27 +126,35 @@
     }
 }
 
-fn ensure_rustfmt(sh: &Shell) {
-    let version = cmd!(sh, "rustup run stable rustfmt --version").read().unwrap_or_default();
-    if !version.contains("stable") {
-        panic!(
-            "Failed to run rustfmt from toolchain 'stable'. \
-                 Please run `rustup component add rustfmt --toolchain stable` to install it.",
-        );
-    }
-}
-
 fn reformat(text: String) -> String {
     let sh = Shell::new().unwrap();
-    ensure_rustfmt(&sh);
     let rustfmt_toml = project_root().join("rustfmt.toml");
-    let mut stdout = cmd!(
-        sh,
-        "rustup run stable rustfmt --config-path {rustfmt_toml} --config fn_single_line=true"
-    )
-    .stdin(text)
-    .read()
-    .unwrap();
+    let version = cmd!(sh, "rustup run stable rustfmt --version").read().unwrap_or_default();
+
+    // First try explicitly requesting the stable channel via rustup in case nightly is being used by default,
+    // then plain rustfmt in case rustup isn't being used to manage the compiler (e.g. when using Nix).
+    let mut stdout = if !version.contains("stable") {
+        let version = cmd!(sh, "rustfmt --version").read().unwrap_or_default();
+        if !version.contains("stable") {
+            panic!(
+                "Failed to run rustfmt from toolchain 'stable'. \
+                 Please run `rustup component add rustfmt --toolchain stable` to install it.",
+            );
+        } else {
+            cmd!(sh, "rustfmt --config-path {rustfmt_toml} --config fn_single_line=true")
+                .stdin(text)
+                .read()
+                .unwrap()
+        }
+    } else {
+        cmd!(
+            sh,
+            "rustup run stable rustfmt --config-path {rustfmt_toml} --config fn_single_line=true"
+        )
+        .stdin(text)
+        .read()
+        .unwrap()
+    };
     if !stdout.ends_with('\n') {
         stdout.push('\n');
     }
diff --git a/xtask/src/codegen/grammar.rs b/xtask/src/codegen/grammar.rs
index 39e06f9..e753458 100644
--- a/xtask/src/codegen/grammar.rs
+++ b/xtask/src/codegen/grammar.rs
@@ -11,9 +11,11 @@
     fs,
 };
 
+use either::Either;
 use itertools::Itertools;
 use proc_macro2::{Punct, Spacing};
 use quote::{format_ident, quote};
+use stdx::panic_context;
 use ungrammar::{Grammar, Rule};
 
 use crate::{
@@ -462,6 +464,7 @@
 
     let tokens = grammar.tokens.iter().map(|name| format_ident!("{}", name)).collect::<Vec<_>>();
 
+    // FIXME: This generates enum kinds?
     let nodes = grammar.nodes.iter().map(|name| format_ident!("{}", name)).collect::<Vec<_>>();
 
     let ast = quote! {
@@ -711,6 +714,7 @@
     for &node in &nodes {
         let name = grammar[node].name.clone();
         let rule = &grammar[node].rule;
+        let _g = panic_context::enter(name.clone());
         match lower_enum(grammar, rule) {
             Some(variants) => {
                 let enum_src = AstEnumSrc { doc: Vec::new(), name, traits: Vec::new(), variants };
@@ -838,11 +842,16 @@
         Rule::Seq(it) => it,
         _ => return false,
     };
-    let (node, repeat, trailing_sep) = match rule.as_slice() {
+
+    let (nt, repeat, trailing_sep) = match rule.as_slice() {
         [Rule::Node(node), Rule::Rep(repeat), Rule::Opt(trailing_sep)] => {
-            (node, repeat, Some(trailing_sep))
+            (Either::Left(node), repeat, Some(trailing_sep))
         }
-        [Rule::Node(node), Rule::Rep(repeat)] => (node, repeat, None),
+        [Rule::Node(node), Rule::Rep(repeat)] => (Either::Left(node), repeat, None),
+        [Rule::Token(token), Rule::Rep(repeat), Rule::Opt(trailing_sep)] => {
+            (Either::Right(token), repeat, Some(trailing_sep))
+        }
+        [Rule::Token(token), Rule::Rep(repeat)] => (Either::Right(token), repeat, None),
         _ => return false,
     };
     let repeat = match &**repeat {
@@ -851,15 +860,28 @@
     };
     if !matches!(
         repeat.as_slice(),
-        [comma, Rule::Node(n)]
-            if trailing_sep.map_or(true, |it| comma == &**it) && n == node
+        [comma, nt_]
+            if trailing_sep.map_or(true, |it| comma == &**it) && match (nt, nt_) {
+                (Either::Left(node), Rule::Node(nt_)) => node == nt_,
+                (Either::Right(token), Rule::Token(nt_)) => token == nt_,
+                _ => false,
+            }
     ) {
         return false;
     }
-    let ty = grammar[*node].name.clone();
-    let name = label.cloned().unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty)));
-    let field = Field::Node { name, ty, cardinality: Cardinality::Many };
-    acc.push(field);
+    match nt {
+        Either::Right(token) => {
+            let name = clean_token_name(&grammar[*token].name);
+            let field = Field::Token(name);
+            acc.push(field);
+        }
+        Either::Left(node) => {
+            let ty = grammar[*node].name.clone();
+            let name = label.cloned().unwrap_or_else(|| pluralize(&to_lower_snake_case(&ty)));
+            let field = Field::Node { name, ty, cardinality: Cardinality::Many };
+            acc.push(field);
+        }
+    }
     true
 }
 
diff --git a/xtask/src/codegen/grammar/ast_src.rs b/xtask/src/codegen/grammar/ast_src.rs
index 34151bd..f1a96e0 100644
--- a/xtask/src/codegen/grammar/ast_src.rs
+++ b/xtask/src/codegen/grammar/ast_src.rs
@@ -113,7 +113,31 @@
 const CONTEXTUAL_KEYWORDS: &[&str] =
     &["macro_rules", "union", "default", "raw", "dyn", "auto", "yeet"];
 // keywords we use for special macro expansions
-const CONTEXTUAL_BUILTIN_KEYWORDS: &[&str] = &["builtin", "offset_of", "format_args", "asm"];
+const CONTEXTUAL_BUILTIN_KEYWORDS: &[&str] = &[
+    "asm",
+    "att_syntax",
+    "builtin",
+    "clobber_abi",
+    "format_args",
+    // "in",
+    "inlateout",
+    "inout",
+    "label",
+    "lateout",
+    "may_unwind",
+    "nomem",
+    "noreturn",
+    "nostack",
+    "offset_of",
+    "options",
+    "out",
+    "preserves_flags",
+    "pure",
+    // "raw",
+    "readonly",
+    "sym",
+];
+
 // keywords that are keywords depending on the edition
 const EDITION_DEPENDENT_KEYWORDS: &[(&str, Edition)] = &[
     ("try", Edition::Edition2018),