Repository: rust-lang/rust-analyzer
Pull request #15282 (2023-07-14 16:45:51)

Give real discriminant_type to chalk


Patch:
diff --git a/.editorconfig b/.editorconfig
index f00ade5fd8..314f79d3f9 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -7,10 +7,13 @@ trim_trailing_whitespace = true
 end_of_line = lf
 insert_final_newline = true
 indent_style = space
-indent_size = 4
 
-[*.md]
-indent_size = 2
+[*.{rs,toml}]
+indent_size = 4
 
-[*.{yml, yaml}]
-indent_size = 2
+[*.ts]
+indent_size = 4
+[*.js]
+indent_size = 4
+[*.json]
+indent_size = 4
diff --git a/.github/workflows/metrics.yaml b/.github/workflows/metrics.yaml
index 260e45ff51..fd86d5622b 100644
--- a/.github/workflows/metrics.yaml
+++ b/.github/workflows/metrics.yaml
@@ -1,8 +1,8 @@
 name: metrics
 on:
   push:
-    branches:
-      - master
+   branches:
+   - master
 
 env:
   CARGO_INCREMENTAL: 0
@@ -19,7 +19,6 @@ jobs:
         run: |
           rustup update --no-self-update stable
           rustup component add rustfmt rust-src
-          rustup default stable
       - name: Cache cargo
         uses: actions/cache@v3
         with:
@@ -35,34 +34,35 @@ jobs:
     needs: setup_cargo
 
     steps:
-      - name: Checkout repository
-        uses: actions/checkout@v3
-
-      - name: Restore cargo cache
-        uses: actions/cache@v3
-        with:
-          path: |
-            ~/.cargo/bin/
-            ~/.cargo/registry/index/
-            ~/.cargo/registry/cache/
-            ~/.cargo/git/db/
-          key: ${{ runner.os }}-cargo-${{ github.sha }}
-
-      - name: Collect build metrics
-        run: cargo xtask metrics build
-
-      - name: Cache target
-        uses: actions/cache@v3
-        with:
-          path: target/
-          key: ${{ runner.os }}-target-${{ github.sha }}
-
-      - name: Upload build metrics
-        uses: actions/upload-artifact@v3
-        with:
-          name: build-${{ github.sha }}
-          path: target/build.json
-          if-no-files-found: error
+    - name: Checkout repository
+      uses: actions/checkout@v3
+
+    - name: Restore cargo cache
+      uses: actions/cache@v3
+      with:
+        path: |
+          ~/.cargo/bin/
+          ~/.cargo/registry/index/
+          ~/.cargo/registry/cache/
+          ~/.cargo/git/db/
+        key: ${{ runner.os }}-cargo-${{ github.sha }}
+
+
+    - name: Collect build metrics
+      run: cargo xtask metrics build
+
+    - name: Cache target
+      uses: actions/cache@v3
+      with:
+        path: target/
+        key: ${{ runner.os }}-target-${{ github.sha }}
+
+    - name: Upload build metrics
+      uses: actions/upload-artifact@v3
+      with:
+        name: build-${{ github.sha }}
+        path: target/build.json
+        if-no-files-found: error
 
   other_metrics:
     strategy:
@@ -72,74 +72,74 @@ jobs:
     needs: [setup_cargo, build_metrics]
 
     steps:
-      - name: Checkout repository
-        uses: actions/checkout@v3
-
-      - name: Restore cargo cache
-        uses: actions/cache@v3
-        with:
-          path: |
-            ~/.cargo/bin/
-            ~/.cargo/registry/index/
-            ~/.cargo/registry/cache/
-            ~/.cargo/git/db/
-          key: ${{ runner.os }}-cargo-${{ github.sha }}
-
-      - name: Restore target cache
-        uses: actions/cache@v3
-        with:
-          path: target/
-          key: ${{ runner.os }}-target-${{ github.sha }}
-
-      - name: Collect metrics
-        run: cargo xtask metrics ${{ matrix.names }}
-
-      - name: Upload metrics
-        uses: actions/upload-artifact@v3
-        with:
-          name: ${{ matrix.names }}-${{ github.sha }}
-          path: target/${{ matrix.names }}.json
-          if-no-files-found: error
+    - name: Checkout repository
+      uses: actions/checkout@v3
+
+    - name: Restore cargo cache
+      uses: actions/cache@v3
+      with:
+        path: |
+          ~/.cargo/bin/
+          ~/.cargo/registry/index/
+          ~/.cargo/registry/cache/
+          ~/.cargo/git/db/
+        key: ${{ runner.os }}-cargo-${{ github.sha }}
+
+    - name: Restore target cache
+      uses: actions/cache@v3
+      with:
+        path: target/
+        key: ${{ runner.os }}-target-${{ github.sha }}
+
+    - name: Collect metrics
+      run: cargo xtask metrics ${{ matrix.names }}
+
+    - name: Upload metrics
+      uses: actions/upload-artifact@v3
+      with:
+        name: ${{ matrix.names }}-${{ github.sha }}
+        path: target/${{ matrix.names }}.json
+        if-no-files-found: error
 
   generate_final_metrics:
     runs-on: ubuntu-latest
     needs: [build_metrics, other_metrics]
     steps:
-      - name: Checkout repository
-        uses: actions/checkout@v3
-
-      - name: Download build metrics
-        uses: actions/download-artifact@v3
-        with:
-          name: build-${{ github.sha }}
-
-      - name: Download self metrics
-        uses: actions/download-artifact@v3
-        with:
-          name: self-${{ github.sha }}
-
-      - name: Download ripgrep metrics
-        uses: actions/download-artifact@v3
-        with:
-          name: ripgrep-${{ github.sha }}
-
-      - name: Download webrender metrics
-        uses: actions/download-artifact@v3
-        with:
-          name: webrender-${{ github.sha }}
-
-      - name: Download diesel metrics
-        uses: actions/download-artifact@v3
-        with:
-          name: diesel-${{ github.sha }}
-
-      - name: Combine json
-        run: |
-          git clone --depth 1 https://$METRICS_TOKEN@github.com/rust-analyzer/metrics.git
-          jq -s ".[0] * .[1] * .[2] * .[3] * .[4]" build.json self.json ripgrep.json webrender.json diesel.json -c >> metrics/metrics.json
-          cd metrics
-          git add .
-          git -c user.name=Bot -c user.email=dummy@example.com commit --message 📈
-          git push origin master
+    - name: Checkout repository
+      uses: actions/checkout@v3
+
+    - name: Download build metrics
+      uses: actions/download-artifact@v3
+      with:
+        name: build-${{ github.sha }}
+
+    - name: Download self metrics
+      uses: actions/download-artifact@v3
+      with:
+        name: self-${{ github.sha }}
+
+    - name: Download ripgrep metrics
+      uses: actions/download-artifact@v3
+      with:
+        name: ripgrep-${{ github.sha }}
+
+    - name: Download webrender metrics
+      uses: actions/download-artifact@v3
+      with:
+        name: webrender-${{ github.sha }}
+
+    - name: Download diesel metrics
+      uses: actions/download-artifact@v3
+      with:
+        name: diesel-${{ github.sha }}
+
+    - name: Combine json
+      run: |
+        git clone --depth 1 https://$METRICS_TOKEN@github.com/rust-analyzer/metrics.git
+        jq -s ".[0] * .[1] * .[2] * .[3] * .[4]" build.json self.json ripgrep.json webrender.json diesel.json -c >> metrics/metrics.json
+        cd metrics
+        git add .
+        git -c user.name=Bot -c user.email=dummy@example.com commit --message 📈
+        git push origin master
     env:
       METRICS_TOKEN: ${{ secrets.METRICS_TOKEN }}
diff --git a/crates/base-db/src/fixture.rs b/crates/base-db/src/fixture.rs
index 6bfdf402c4..323ee4260e 100644
--- a/crates/base-db/src/fixture.rs
+++ b/crates/base-db/src/fixture.rs
@@ -26,7 +26,7 @@ pub trait WithFixture: Default + SourceDatabaseExt + 'static {
         let fixture = ChangeFixture::parse(ra_fixture);
         let mut db = Self::default();
         fixture.change.apply(&mut db);
-        assert_eq!(fixture.files.len(), 1);
+        assert_eq!(fixture.files.len(), 1, "Multiple file found in the fixture");
         (db, fixture.files[0])
     }
 
diff --git a/crates/hir-expand/src/builtin_derive_macro.rs b/crates/hir-expand/src/builtin_derive_macro.rs
index c8c3cebb88..ecc8b407a9 100644
--- a/crates/hir-expand/src/builtin_derive_macro.rs
+++ b/crates/hir-expand/src/builtin_derive_macro.rs
@@ -624,9 +624,14 @@ fn hash_expand(
                 }
             },
         );
+        let check_discriminant = if matches!(&adt.shape, AdtShape::Enum { .. }) {
+            quote! { #krate::mem::discriminant(self).hash(ra_expand_state); }
+        } else {
+            quote! {}
+        };
         quote! {
             fn hash<H: #krate::hash::Hasher>(&self, ra_expand_state: &mut H) {
-                #krate::mem::discriminant(self).hash(ra_expand_state);
+                #check_discriminant
                 match self {
                     ##arms
                 }
@@ -742,9 +747,6 @@ fn ord_expand(
             // FIXME: Return expand error here
             return quote!();
         }
-        let left = quote!(#krate::intrinsics::discriminant_value(self));
-        let right = quote!(#krate::intrinsics::discriminant_value(other));
-
         let (self_patterns, other_patterns) = self_and_other_patterns(adt, &adt.name);
         let arms = izip!(self_patterns, other_patterns, adt.shape.field_names()).map(
             |(pat1, pat2, fields)| {
@@ -759,17 +761,17 @@ fn ord_expand(
             },
         );
         let fat_arrow = fat_arrow();
-        let body = compare(
-            krate,
-            left,
-            right,
-            quote! {
-                match (self, other) {
-                    ##arms
-                    _unused #fat_arrow #krate::cmp::Ordering::Equal
-                }
-            },
-        );
+        let mut body = quote! {
+            match (self, other) {
+                ##arms
+                _unused #fat_arrow #krate::cmp::Ordering::Equal
+            }
+        };
+        if matches!(&adt.shape, AdtShape::Enum { .. }) {
+            let left = quote!(#krate::intrinsics::discriminant_value(self));
+            let right = quote!(#krate::intrinsics::discriminant_value(other));
+            body = compare(krate, left, right, body);
+        }
         quote! {
             fn cmp(&self, other: &Self) -> #krate::cmp::Ordering {
                 #body
diff --git a/crates/hir-expand/src/builtin_fn_macro.rs b/crates/hir-expand/src/builtin_fn_macro.rs
index 95c6baf42d..7370f07a52 100644
--- a/crates/hir-expand/src/builtin_fn_macro.rs
+++ b/crates/hir-expand/src/builtin_fn_macro.rs
@@ -692,7 +692,7 @@ pub(crate) fn include_arg_to_tt(
     arg_id: MacroCallId,
 ) -> Result<(triomphe::Arc<(::tt::Subtree<::tt::TokenId>, TokenMap)>, FileId), ExpandError> {
     let loc = db.lookup_intern_macro_call(arg_id);
-    let Some(EagerCallInfo { arg,arg_id, .. }) = loc.eager.as_deref() else {
+    let Some(EagerCallInfo { arg, arg_id: Some(arg_id), .. }) = loc.eager.as_deref() else {
         panic!("include_arg_to_tt called on non include macro call: {:?}", &loc.eager);
     };
     let path = parse_string(&arg.0)?;
diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs
index 309c0930d1..a2b642cd11 100644
--- a/crates/hir-expand/src/db.rs
+++ b/crates/hir-expand/src/db.rs
@@ -3,7 +3,7 @@
 use base_db::{salsa, CrateId, Edition, SourceDatabase};
 use either::Either;
 use limit::Limit;
-use mbe::{syntax_node_to_token_tree, ValueResult};
+use mbe::syntax_node_to_token_tree;
 use rustc_hash::FxHashSet;
 use syntax::{
     ast::{self, HasAttrs, HasDocComments},
@@ -124,21 +124,16 @@ pub trait ExpandDatabase: SourceDatabase {
     fn macro_arg(
         &self,
         id: MacroCallId,
-    ) -> ValueResult<
-        Option<Arc<(tt::Subtree, mbe::TokenMap, fixup::SyntaxFixupUndoInfo)>>,
-        Arc<Box<[SyntaxError]>>,
-    >;
+    ) -> Option<Arc<(tt::Subtree, mbe::TokenMap, fixup::SyntaxFixupUndoInfo)>>;
     /// Extracts syntax node, corresponding to a macro call. That's a firewall
     /// query, only typing in the macro call itself changes the returned
     /// subtree.
-    fn macro_arg_node(
-        &self,
-        id: MacroCallId,
-    ) -> ValueResult<Option<GreenNode>, Arc<Box<[SyntaxError]>>>;
-    /// Fetches the expander for this macro.
+    fn macro_arg_text(&self, id: MacroCallId) -> Option<GreenNode>;
+    /// Gets the expander for this macro. This compiles declarative macros, and
+    /// just fetches procedural ones.
+    // FIXME: Rename this
     #[salsa::transparent]
-    fn macro_expander(&self, id: MacroDefId) -> TokenExpander;
-    /// Fetches (and compiles) the expander of this decl macro.
+    fn macro_def(&self, id: MacroDefId) -> TokenExpander;
     fn decl_macro_expander(
         &self,
         def_crate: CrateId,
@@ -340,20 +335,14 @@ fn parse_macro_expansion_error(
 fn macro_arg(
     db: &dyn ExpandDatabase,
     id: MacroCallId,
-) -> ValueResult<
-    Option<Arc<(tt::Subtree, mbe::TokenMap, fixup::SyntaxFixupUndoInfo)>>,
-    Arc<Box<[SyntaxError]>>,
-> {
+) -> Option<Arc<(tt::Subtree, mbe::TokenMap, fixup::SyntaxFixupUndoInfo)>> {
     let loc = db.lookup_intern_macro_call(id);
 
-    if let Some(EagerCallInfo { arg, arg_id: _, error: _ }) = loc.eager.as_deref() {
-        return ValueResult::ok(Some(Arc::new((arg.0.clone(), arg.1.clone(), Default::default()))));
+    if let Some(EagerCallInfo { arg, arg_id: Some(_), error: _ }) = loc.eager.as_deref() {
+        return Some(Arc::new((arg.0.clone(), arg.1.clone(), Default::default())));
     }
 
-    let ValueResult { value, err } = db.macro_arg_node(id);
-    let Some(arg) = value else {
-        return ValueResult { value: None, err };
-    };
+    let arg = db.macro_arg_text(id)?;
 
     let node = SyntaxNode::new_root(arg);
     let censor = censor_for_macro_input(&loc, &node);
@@ -371,11 +360,7 @@ fn macro_arg(
         // proc macros expect their inputs without parentheses, MBEs expect it with them included
         tt.delimiter = tt::Delimiter::unspecified();
     }
-    let val = Some(Arc::new((tt, tmap, fixups.undo_info)));
-    match err {
-        Some(err) => ValueResult::new(val, err),
-        None => ValueResult::ok(val),
-    }
+    Some(Arc::new((tt, tmap, fixups.undo_info)))
 }
 
 /// Certain macro calls expect some nodes in the input to be preprocessed away, namely:
@@ -417,44 +402,9 @@ fn censor_for_macro_input(loc: &MacroCallLoc, node: &SyntaxNode) -> FxHashSet<Sy
     .unwrap_or_default()
 }
 
-fn macro_arg_node(
-    db: &dyn ExpandDatabase,
-    id: MacroCallId,
-) -> ValueResult<Option<GreenNode>, Arc<Box<[SyntaxError]>>> {
-    let err = || -> Arc<Box<[_]>> {
-        Arc::new(Box::new([SyntaxError::new_at_offset(
-            "invalid macro call".to_owned(),
-            syntax::TextSize::from(0),
-        )]))
-    };
+fn macro_arg_text(db: &dyn ExpandDatabase, id: MacroCallId) -> Option<GreenNode> {
     let loc = db.lookup_intern_macro_call(id);
-    let arg = if let MacroDefKind::BuiltInEager(..) = loc.def.kind {
-        let res = if let Some(EagerCallInfo { arg, .. }) = loc.eager.as_deref() {
-            Some(mbe::token_tree_to_syntax_node(&arg.0, mbe::TopEntryPoint::Expr).0)
-        } else {
-            loc.kind
-                .arg(db)
-                .and_then(|arg| ast::TokenTree::cast(arg.value))
-                .map(|tt| tt.reparse_as_expr().to_syntax())
-        };
-
-        match res {
-            Some(res) if res.errors().is_empty() => res.syntax_node(),
-            Some(res) => {
-                return ValueResult::new(
-                    Some(res.syntax_node().green().into()),
-                    // Box::<[_]>::from(res.errors()), not stable yet
-                    Arc::new(res.errors().to_vec().into_boxed_slice()),
-                );
-            }
-            None => return ValueResult::only_err(err()),
-        }
-    } else {
-        match loc.kind.arg(db) {
-            Some(res) => res.value,
-            None => return ValueResult::only_err(err()),
-        }
-    };
+    let arg = loc.kind.arg(db)?;
     if matches!(loc.kind, MacroCallKind::FnLike { .. }) {
         let first = arg.first_child_or_token().map_or(T![.], |it| it.kind());
         let last = arg.last_child_or_token().map_or(T![.], |it| it.kind());
@@ -469,13 +419,20 @@ fn macro_arg_node(
             // Some day, we'll have explicit recursion counters for all
             // recursive things, at which point this code might be removed.
             cov_mark::hit!(issue9358_bad_macro_stack_overflow);
-            return ValueResult::only_err(Arc::new(Box::new([SyntaxError::new(
-                "unbalanced token tree".to_owned(),
-                arg.text_range(),
-            )])));
+            return None;
         }
     }
-    ValueResult::ok(Some(arg.green().into()))
+    if let Some(EagerCallInfo { arg, .. }) = loc.eager.as_deref() {
+        Some(
+            mbe::token_tree_to_syntax_node(&arg.0, mbe::TopEntryPoint::Expr)
+                .0
+                .syntax_node()
+                .green()
+                .into(),
+        )
+    } else {
+        Some(arg.green().into())
+    }
 }
 
 fn decl_macro_expander(
@@ -517,7 +474,7 @@ fn decl_macro_expander(
     Arc::new(DeclarativeMacroExpander { mac, def_site_token_map })
 }
 
-fn macro_expander(db: &dyn ExpandDatabase, id: MacroDefId) -> TokenExpander {
+fn macro_def(db: &dyn ExpandDatabase, id: MacroDefId) -> TokenExpander {
     match id.kind {
         MacroDefKind::Declarative(ast_id) => {
             TokenExpander::DeclarativeMacro(db.decl_macro_expander(id.krate, ast_id))
@@ -533,11 +490,15 @@ fn macro_expander(db: &dyn ExpandDatabase, id: MacroDefId) -> TokenExpander {
 fn macro_expand(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt::Subtree>> {
     let _p = profile::span("macro_expand");
     let loc = db.lookup_intern_macro_call(id);
+    if let Some(EagerCallInfo { arg, arg_id: None, error }) = loc.eager.as_deref() {
+        // This is an input expansion for an eager macro. These are already pre-expanded
+        return ExpandResult { value: Arc::new(arg.0.clone()), err: error.clone() };
+    }
 
-    let ExpandResult { value: tt, mut err } = match loc.def.kind {
+    let (ExpandResult { value: mut tt, mut err }, tmap) = match loc.def.kind {
         MacroDefKind::ProcMacro(..) => return db.expand_proc_macro(id),
         MacroDefKind::BuiltInDerive(expander, ..) => {
-            let arg = db.macro_arg_node(id).value.unwrap();
+            let arg = db.macro_arg_text(id).unwrap();
 
             let node = SyntaxNode::new_root(arg);
             let censor = censor_for_macro_input(&loc, &node);
@@ -553,13 +514,10 @@ fn macro_expand(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt
 
             // this cast is a bit sus, can we avoid losing the typedness here?
             let adt = ast::Adt::cast(node).unwrap();
-            let mut res = expander.expand(db, id, &adt, &tmap);
-            fixup::reverse_fixups(&mut res.value, &tmap, &fixups.undo_info);
-            res
+            (expander.expand(db, id, &adt, &tmap), Some((tmap, fixups.undo_info)))
         }
         _ => {
-            let ValueResult { value, err } = db.macro_arg(id);
-            let Some(macro_arg) = value else {
+            let Some(macro_arg) = db.macro_arg(id) else {
                 return ExpandResult {
                     value: Arc::new(tt::Subtree {
                         delimiter: tt::Delimiter::UNSPECIFIED,
@@ -570,43 +528,18 @@ fn macro_expand(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt
                     err: Some(ExpandError::other("invalid token tree")),
                 };
             };
-
             let (arg, arg_tm, undo_info) = &*macro_arg;
             let mut res = match loc.def.kind {
                 MacroDefKind::Declarative(id) => {
                     db.decl_macro_expander(loc.def.krate, id).expand(arg.clone())
                 }
                 MacroDefKind::BuiltIn(it, _) => it.expand(db, id, &arg).map_err(Into::into),
-                // This might look a bit odd, but we do not expand the inputs to eager macros here.
-                // Eager macros inputs are expanded, well, eagerly when we collect the macro calls.
-                // That kind of expansion uses the ast id map of an eager macros input though which goes through
-                // the HirFileId machinery. As eager macro inputs are assigned a macro file id that query
-                // will end up going through here again, whereas we want to just want to inspect the raw input.
-                // As such we just return the input subtree here.
-                MacroDefKind::BuiltInEager(..) if loc.eager.is_none() => {
-                    let mut arg = arg.clone();
-                    fixup::reverse_fixups(&mut arg, arg_tm, undo_info);
-
-                    return ExpandResult {
-                        value: Arc::new(arg),
-                        err: err.map(|err| {
-                            let mut buf = String::new();
-                            for err in &**err {
-                                use std::fmt::Write;
-                                _ = write!(buf, "{}, ", err);
-                            }
-                            buf.pop();
-                            buf.pop();
-                            ExpandError::other(buf)
-                        }),
-                    };
-                }
                 MacroDefKind::BuiltInEager(it, _) => it.expand(db, id, &arg).map_err(Into::into),
                 MacroDefKind::BuiltInAttr(it, _) => it.expand(db, id, &arg),
                 _ => unreachable!(),
             };
             fixup::reverse_fixups(&mut res.value, arg_tm, undo_info);
-            res
+            (res, None)
         }
     };
 
@@ -620,23 +553,24 @@ fn macro_expand(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt
         return value;
     }
 
+    if let Some((arg_tm, undo_info)) = &tmap {
+        fixup::reverse_fixups(&mut tt, arg_tm, undo_info);
+    }
+
     ExpandResult { value: Arc::new(tt), err }
 }
 
 fn expand_proc_macro(db: &dyn ExpandDatabase, id: MacroCallId) -> ExpandResult<Arc<tt::Subtree>> {
     let loc = db.lookup_intern_macro_call(id);
-    let Some(macro_arg) = db.macro_arg(id).value else {
+    let Some(macro_arg) = db.macro_arg(id) else {
         return ExpandResult {
             value: Arc::new(tt::Subtree {
                 delimiter: tt::Delimiter::UNSPECIFIED,
                 token_trees: Vec::new(),
             }),
-            // FIXME: We should make sure to enforce an invariant that invalid macro
-            // calls do not reach this call path!
             err: Some(ExpandError::other("invalid token tree")),
         };
     };
-
     let (arg_tt, arg_tm, undo_info) = &*macro_arg;
 
     let expander = match loc.def.kind {
diff --git a/crates/hir-expand/src/eager.rs b/crates/hir-expand/src/eager.rs
index 876813eab5..3ccc3ab1e1 100644
--- a/crates/hir-expand/src/eager.rs
+++ b/crates/hir-expand/src/eager.rs
@@ -19,8 +19,7 @@
 //!
 //! See the full discussion : <https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Eager.20expansion.20of.20built-in.20macros>
 use base_db::CrateId;
-use rustc_hash::FxHashMap;
-use syntax::{ted, Parse, SyntaxNode, TextRange, TextSize, WalkEvent};
+use syntax::{ted, Parse, SyntaxNode};
 use triomphe::Arc;
 
 use crate::{
@@ -39,8 +38,18 @@ pub fn expand_eager_macro_input(
     def: MacroDefId,
     resolver: &dyn Fn(ModPath) -> Option<MacroDefId>,
 ) -> Result<ExpandResult<Option<MacroCallId>>, UnresolvedMacro> {
+    assert!(matches!(def.kind, MacroDefKind::BuiltInEager(..)));
+    let token_tree = macro_call.value.token_tree();
+
+    let Some(token_tree) = token_tree else {
+        return Ok(ExpandResult {
+            value: None,
+            err: Some(ExpandError::other("invalid token tree")),
+        });
+    };
+    let (parsed_args, arg_token_map) = mbe::syntax_node_to_token_tree(token_tree.syntax());
+
     let ast_map = db.ast_id_map(macro_call.file_id);
-    // the expansion which the ast id map is built upon has no whitespace, so the offsets are wrong as macro_call is from the token tree that has whitespace!
     let call_id = InFile::new(macro_call.file_id, ast_map.ast_id(&macro_call.value));
     let expand_to = ExpandTo::from_call_site(&macro_call.value);
 
@@ -51,69 +60,41 @@ pub fn expand_eager_macro_input(
     let arg_id = db.intern_macro_call(MacroCallLoc {
         def,
         krate,
-        eager: None,
+        eager: Some(Box::new(EagerCallInfo {
+            arg: Arc::new((parsed_args, arg_token_map)),
+            arg_id: None,
+            error: None,
+        })),
         kind: MacroCallKind::FnLike { ast_id: call_id, expand_to: ExpandTo::Expr },
     });
-    let ExpandResult { value: (arg_exp, arg_exp_map), err: parse_err } =
-        db.parse_macro_expansion(arg_id.as_macro_file());
-    // we need this map here as the expansion of the eager input fake file loses whitespace ...
-    let mut ws_mapping = FxHashMap::default();
-    if let Some((_, tm, _)) = db.macro_arg(arg_id).value.as_deref() {
-        ws_mapping.extend(tm.entries().filter_map(|(id, range)| {
-            Some((arg_exp_map.first_range_by_token(id, syntax::SyntaxKind::TOMBSTONE)?, range))
-        }));
-    }
-
-    let ExpandResult { value: expanded_eager_input, err } = {
-        eager_macro_recur(
-            db,
-            &Hygiene::new(db, macro_call.file_id),
-            InFile::new(arg_id.as_file(), arg_exp.syntax_node()),
-            krate,
-            resolver,
-        )?
+    let arg_as_expr = match db.macro_arg_text(arg_id) {
+        Some(it) => it,
+        None => {
+            return Ok(ExpandResult {
+                value: None,
+                err: Some(ExpandError::other("invalid token tree")),
+            })
+        }
     };
-    let err = parse_err.or(err);
-
-    let Some((expanded_eager_input, mapping)) = expanded_eager_input else {
+    let ExpandResult { value: expanded_eager_input, err } = eager_macro_recur(
+        db,
+        &Hygiene::new(db, macro_call.file_id),
+        InFile::new(arg_id.as_file(), SyntaxNode::new_root(arg_as_expr)),
+        krate,
+        resolver,
+    )?;
+    let Some(expanded_eager_input) = expanded_eager_input else {
         return Ok(ExpandResult { value: None, err });
     };
-
-    let og_tmap = mbe::syntax_node_to_token_map(
-        macro_call.value.token_tree().expect("macro_arg_text succeeded").syntax(),
-    );
-
-    let (mut subtree, expanded_eager_input_token_map) =
-        mbe::syntax_node_to_token_tree(&expanded_eager_input);
-
-    // The tokenmap and ids of subtree point into the expanded syntax node, but that is inaccessible from the outside
-    // so we need to remap them to the original input of the eager macro.
-    subtree.visit_ids(&|id| {
-        // Note: we discard all token ids of braces and the like here, but that's not too bad and only a temporary fix
-
-        if let Some(range) =
-            expanded_eager_input_token_map.first_range_by_token(id, syntax::SyntaxKind::TOMBSTONE)
-        {
-            // remap from expanded eager input to eager input expansion
-            if let Some(og_range) = mapping.get(&range) {
-                // remap from eager input expansion to original eager input
-                if let Some(&og_range) = ws_mapping.get(og_range) {
-                    if let Some(og_token) = og_tmap.token_by_range(og_range) {
-                        return og_token;
-                    }
-                }
-            }
-        }
-        tt::TokenId::UNSPECIFIED
-    });
+    let (mut subtree, token_map) = mbe::syntax_node_to_token_tree(&expanded_eager_input);
     subtree.delimiter = crate::tt::Delimiter::unspecified();
 
     let loc = MacroCallLoc {
         def,
         krate,
         eager: Some(Box::new(EagerCallInfo {
-            arg: Arc::new((subtree, og_tmap)),
-            arg_id,
+            arg: Arc::new((subtree, token_map)),
+            arg_id: Some(arg_id),
             error: err.clone(),
         })),
         kind: MacroCallKind::FnLike { ast_id: call_id, expand_to },
@@ -127,16 +108,19 @@ fn lazy_expand(
     def: &MacroDefId,
     macro_call: InFile<ast::MacroCall>,
     krate: CrateId,
-) -> ExpandResult<(InFile<Parse<SyntaxNode>>, Arc<mbe::TokenMap>)> {
+) -> ExpandResult<InFile<Parse<SyntaxNode>>> {
     let ast_id = db.ast_id_map(macro_call.file_id).ast_id(&macro_call.value);
 
     let expand_to = ExpandTo::from_call_site(&macro_call.value);
-    let ast_id = macro_call.with_value(ast_id);
-    let id = def.as_lazy_macro(db, krate, MacroCallKind::FnLike { ast_id, expand_to });
+    let id = def.as_lazy_macro(
+        db,
+        krate,
+        MacroCallKind::FnLike { ast_id: macro_call.with_value(ast_id), expand_to },
+    );
+
     let macro_file = id.as_macro_file();
 
-    db.parse_macro_expansion(macro_file)
-        .map(|parse| (InFile::new(macro_file.into(), parse.0), parse.1))
+    db.parse_macro_expansion(macro_file).map(|parse| InFile::new(macro_file.into(), parse.0))
 }
 
 fn eager_macro_recur(
@@ -145,43 +129,18 @@ fn eager_macro_recur(
     curr: InFile<SyntaxNode>,
     krate: CrateId,
     macro_resolver: &dyn Fn(ModPath) -> Option<MacroDefId>,
-) -> Result<ExpandResult<Option<(SyntaxNode, FxHashMap<TextRange, TextRange>)>>, UnresolvedMacro> {
+) -> Result<ExpandResult<Option<SyntaxNode>>, UnresolvedMacro> {
     let original = curr.value.clone_for_update();
-    let mut mapping = FxHashMap::default();
 
+    let children = original.descendants().filter_map(ast::MacroCall::cast);
     let mut replacements = Vec::new();
 
     // Note: We only report a single error inside of eager expansions
     let mut error = None;
-    let mut offset = 0i32;
-    let apply_offset = |it: TextSize, offset: i32| {
-        TextSize::from(u32::try_from(offset + u32::from(it) as i32).unwrap_or_default())
-    };
-    let mut children = original.preorder_with_tokens();
 
     // Collect replacement
-    while let Some(child) = children.next() {
-        let WalkEvent::Enter(child) = child else { continue };
-        let call = match child {
-            syntax::NodeOrToken::Node(node) => match ast::MacroCall::cast(node) {
-                Some(it) => {
-                    children.skip_subtree();
-                    it
-                }
-                None => continue,
-            },
-            syntax::NodeOrToken::Token(t) => {
-                mapping.insert(
-                    TextRange::new(
-                        apply_offset(t.text_range().start(), offset),
-                        apply_offset(t.text_range().end(), offset),
-                    ),
-                    t.text_range(),
-                );
-                continue;
-            }
-        };
-        let def = match call.path().and_then(|path| ModPath::from_src(db, path, hygiene)) {
+    for child in children {
+        let def = match child.path().and_then(|path| ModPath::from_src(db, path, hygiene)) {
             Some(path) => macro_resolver(path.clone()).ok_or(UnresolvedMacro { path })?,
             None => {
                 error = Some(ExpandError::other("malformed macro invocation"));
@@ -193,7 +152,7 @@ fn eager_macro_recur(
                 let ExpandResult { value, err } = match expand_eager_macro_input(
                     db,
                     krate,
-                    curr.with_value(call.clone()),
+                    curr.with_value(child.clone()),
                     def,
                     macro_resolver,
                 ) {
@@ -201,22 +160,9 @@ fn eager_macro_recur(
                     Err(err) => return Err(err),
                 };
                 match value {
-                    Some(call_id) => {
+                    Some(call) => {
                         let ExpandResult { value, err: err2 } =
-                            db.parse_macro_expansion(call_id.as_macro_file());
-
-                        let call_tt_start =
-                            call.token_tree().unwrap().syntax().text_range().start();
-                        let call_start = apply_offset(call.syntax().text_range().start(), offset);
-                        if let Some((_, arg_map, _)) = db.macro_arg(call_id).value.as_deref() {
-                            mapping.extend(arg_map.entries().filter_map(|(tid, range)| {
-                                value
-                                    .1
-                                    .first_range_by_token(tid, syntax::SyntaxKind::TOMBSTONE)
-                                    .map(|r| (r + call_start, range + call_tt_start))
-                            }));
-                        };
-
+                            db.parse_macro_expansion(call.as_macro_file());
                         ExpandResult {
                             value: Some(value.0.syntax_node().clone_for_update()),
                             err: err.or(err2),
@@ -230,61 +176,36 @@ fn eager_macro_recur(
             | MacroDefKind::BuiltInAttr(..)
             | MacroDefKind::BuiltInDerive(..)
             | MacroDefKind::ProcMacro(..) => {
-                let ExpandResult { value: (parse, tm), err } =
-                    lazy_expand(db, &def, curr.with_value(call.clone()), krate);
-                let decl_mac = if let MacroDefKind::Declarative(ast_id) = def.kind {
-                    Some(db.decl_macro_expander(def.krate, ast_id))
-                } else {
-                    None
-                };
+                let ExpandResult { value, err } =
+                    lazy_expand(db, &def, curr.with_value(child.clone()), krate);
 
                 // replace macro inside
-                let hygiene = Hygiene::new(db, parse.file_id);
+                let hygiene = Hygiene::new(db, value.file_id);
                 let ExpandResult { value, err: error } = eager_macro_recur(
                     db,
                     &hygiene,
                     // FIXME: We discard parse errors here
-                    parse.as_ref().map(|it| it.syntax_node()),
+                    value.map(|it| it.syntax_node()),
                     krate,
                     macro_resolver,
                 )?;
                 let err = err.or(error);
-
-                let call_tt_start = call.token_tree().unwrap().syntax().text_range().start();
-                let call_start = apply_offset(call.syntax().text_range().start(), offset);
-                if let Some((_tt, arg_map, _)) = parse
-                    .file_id
-                    .macro_file()
-                    .and_then(|id| db.macro_arg(id.macro_call_id).value)
-                    .as_deref()
-                {
-                    mapping.extend(arg_map.entries().filter_map(|(tid, range)| {
-                        tm.first_range_by_token(
-                            decl_mac.as_ref().map(|it| it.map_id_down(tid)).unwrap_or(tid),
-                            syntax::SyntaxKind::TOMBSTONE,
-                        )
-                        .map(|r| (r + call_start, range + call_tt_start))
-                    }));
-                };
-                // FIXME: Do we need to re-use _m here?
-                ExpandResult { value: value.map(|(n, _m)| n), err }
+                ExpandResult { value, err }
             }
         };
         if err.is_some() {
             error = err;
         }
         // check if the whole original syntax is replaced
-        if call.syntax() == &original {
-            return Ok(ExpandResult { value: value.zip(Some(mapping)), err: error });
+        if child.syntax() == &original {
+            return Ok(ExpandResult { value, err: error });
         }
 
         if let Some(insert) = value {
-            offset += u32::from(insert.text_range().len()) as i32
-                - u32::from(call.syntax().text_range().len()) as i32;
-            replacements.push((call, insert));
+            replacements.push((child, insert));
         }
     }
 
     replacements.into_iter().rev().for_each(|(old, new)| ted::replace(old.syntax(), new));
-    Ok(ExpandResult { value: Some((original, mapping)), err: error })
+    Ok(ExpandResult { value: Some(original), err: error })
 }
diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index e6e8d8c029..af9d2d78dd 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -26,7 +26,7 @@ pub(crate) struct SyntaxFixups {
 /// This is the information needed to reverse the fixups.
 #[derive(Debug, Default, PartialEq, Eq)]
 pub struct SyntaxFixupUndoInfo {
-    original: Box<[Subtree]>,
+    original: Vec<Subtree>,
 }
 
 const EMPTY_ID: SyntheticTokenId = SyntheticTokenId(!0);
@@ -272,7 +272,7 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
         replace,
         token_map,
         next_id,
-        undo_info: SyntaxFixupUndoInfo { original: original.into_boxed_slice() },
+        undo_info: SyntaxFixupUndoInfo { original },
     }
 }
 
diff --git a/crates/hir-expand/src/hygiene.rs b/crates/hir-expand/src/hygiene.rs
index 54e74d50c8..b2921bb173 100644
--- a/crates/hir-expand/src/hygiene.rs
+++ b/crates/hir-expand/src/hygiene.rs
@@ -149,12 +149,16 @@ impl HygieneInfo {
                     token_id = unshifted;
                     (&attr_args.1, self.attr_input_or_mac_def_start?)
                 }
-                None => (&self.macro_arg.1, loc.kind.arg(db)?.map(|it| it.text_range().start())),
+                None => (
+                    &self.macro_arg.1,
+                    InFile::new(loc.kind.file_id(), loc.kind.arg(db)?.text_range().start()),
+                ),
             },
             _ => match origin {
-                mbe::Origin::Call => {
-                    (&self.macro_arg.1, loc.kind.arg(db)?.map(|it| it.text_range().start()))
-                }
+                mbe::Origin::Call => (
+                    &self.macro_arg.1,
+                    InFile::new(loc.kind.file_id(), loc.kind.arg(db)?.text_range().start()),
+                ),
                 mbe::Origin::Def => match (&self.macro_def, &self.attr_input_or_mac_def_start) {
                     (TokenExpander::DeclarativeMacro(expander), Some(tt)) => {
                         (&expander.def_site_token_map, *tt)
@@ -194,9 +198,9 @@ fn make_hygiene_info(
         _ => None,
     });
 
-    let macro_def = db.macro_expander(loc.def);
+    let macro_def = db.macro_def(loc.def);
     let (_, exp_map) = db.parse_macro_expansion(macro_file).value;
-    let macro_arg = db.macro_arg(macro_file.macro_call_id).value.unwrap_or_else(|| {
+    let macro_arg = db.macro_arg(macro_file.macro_call_id).unwrap_or_else(|| {
         Arc::new((
             tt::Subtree { delimiter: tt::Delimiter::UNSPECIFIED, token_trees: Vec::new() },
             Default::default(),
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index 9ed6c31ddd..a92c17f4ed 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -127,8 +127,7 @@ impl_intern_key!(MacroCallId);
 pub struct MacroCallLoc {
     pub def: MacroDefId,
     pub(crate) krate: CrateId,
-    /// Some if this is a macro call for an eager macro. Note that this is `None`
-    /// for the eager input macro file.
+    /// Some if `def` is a builtin eager macro.
     eager: Option<Box<EagerCallInfo>>,
     pub kind: MacroCallKind,
 }
@@ -153,10 +152,11 @@ pub enum MacroDefKind {
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 struct EagerCallInfo {
-    /// The expanded argument of the eager macro.
+    /// NOTE: This can be *either* the expansion result, *or* the argument to the eager macro!
     arg: Arc<(tt::Subtree, TokenMap)>,
-    /// Call id of the eager macro's input file (this is the macro file for its fully expanded input).
-    arg_id: MacroCallId,
+    /// call id of the eager macro's input file. If this is none, macro call containing this call info
+    /// is an eager macro's input, otherwise it is its output.
+    arg_id: Option<MacroCallId>,
     error: Option<ExpandError>,
 }
 
@@ -221,7 +221,11 @@ impl HirFileId {
                 HirFileIdRepr::FileId(id) => break id,
                 HirFileIdRepr::MacroFile(MacroFile { macro_call_id }) => {
                     let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_call_id);
-                    let is_include_expansion = loc.def.is_include() && loc.eager.is_some();
+                    let is_include_expansion = loc.def.is_include()
+                        && matches!(
+                            loc.eager.as_deref(),
+                            Some(EagerCallInfo { arg_id: Some(_), .. })
+                        );
                     file_id = match is_include_expansion.then(|| db.include_expand(macro_call_id)) {
                         Some(Ok((_, file))) => file.into(),
                         _ => loc.kind.file_id(),
@@ -266,7 +270,53 @@ impl HirFileId {
     /// Return expansion information if it is a macro-expansion file
     pub fn expansion_info(self, db: &dyn db::ExpandDatabase) -> Option<ExpansionInfo> {
         let macro_file = self.macro_file()?;
-        ExpansionInfo::new(db, macro_file)
+        let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
+
+        let arg_tt = loc.kind.arg(db)?;
+
+        let macro_def = db.macro_def(loc.def);
+        let (parse, exp_map) = db.parse_macro_expansion(macro_file).value;
+        let macro_arg = db.macro_arg(macro_file.macro_call_id).unwrap_or_else(|| {
+            Arc::new((
+                tt::Subtree { delimiter: tt::Delimiter::UNSPECIFIED, token_trees: Vec::new() },
+                Default::default(),
+                Default::default(),
+            ))
+        });
+
+        let def = loc.def.ast_id().left().and_then(|id| {
+            let def_tt = match id.to_node(db) {
+                ast::Macro::MacroRules(mac) => mac.token_tree()?,
+                ast::Macro::MacroDef(_) if matches!(macro_def, TokenExpander::BuiltInAttr(_)) => {
+                    return None
+                }
+                ast::Macro::MacroDef(mac) => mac.body()?,
+            };
+            Some(InFile::new(id.file_id, def_tt))
+        });
+        let attr_input_or_mac_def = def.or_else(|| match loc.kind {
+            MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => {
+                // FIXME: handle `cfg_attr`
+                let tt = ast_id
+                    .to_node(db)
+                    .doc_comments_and_attrs()
+                    .nth(invoc_attr_index.ast_index())
+                    .and_then(Either::left)?
+                    .token_tree()?;
+                Some(InFile::new(ast_id.file_id, tt))
+            }
+            _ => None,
+        });
+
+        Some(ExpansionInfo {
+            expanded: InFile::new(self, parse.syntax_node()),
+            arg: InFile::new(loc.kind.file_id(), arg_tt),
+            attr_input_or_mac_def,
+            macro_arg_shift: mbe::Shift::new(&macro_arg.0),
+            macro_arg,
+            macro_def,
+            exp_map,
+        })
     }
 
     pub fn as_builtin_derive_attr_node(
@@ -320,7 +370,7 @@ impl HirFileId {
         match self.macro_file() {
             Some(macro_file) => {
                 let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
-                matches!(loc.def.kind, MacroDefKind::BuiltInEager(..))
+                matches!(loc.eager.as_deref(), Some(EagerCallInfo { .. }))
             }
             _ => false,
         }
@@ -553,18 +603,13 @@ impl MacroCallKind {
         FileRange { range, file_id }
     }
 
-    fn arg(&self, db: &dyn db::ExpandDatabase) -> Option<InFile<SyntaxNode>> {
+    fn arg(&self, db: &dyn db::ExpandDatabase) -> Option<SyntaxNode> {
         match self {
-            MacroCallKind::FnLike { ast_id, .. } => ast_id
-                .to_in_file_node(db)
-                .map(|it| Some(it.token_tree()?.syntax().clone()))
-                .transpose(),
-            MacroCallKind::Derive { ast_id, .. } => {
-                Some(ast_id.to_in_file_node(db).syntax().cloned())
-            }
-            MacroCallKind::Attr { ast_id, .. } => {
-                Some(ast_id.to_in_file_node(db).syntax().cloned())
+            MacroCallKind::FnLike { ast_id, .. } => {
+                Some(ast_id.to_node(db).token_tree()?.syntax().clone())
             }
+            MacroCallKind::Derive { ast_id, .. } => Some(ast_id.to_node(db).syntax().clone()),
+            MacroCallKind::Attr { ast_id, .. } => Some(ast_id.to_node(db).syntax().clone()),
         }
     }
 }
@@ -582,7 +627,7 @@ impl MacroCallId {
 /// ExpansionInfo mainly describes how to map text range between src and expanded macro
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct ExpansionInfo {
-    expanded: InMacroFile<SyntaxNode>,
+    expanded: InFile<SyntaxNode>,
     /// The argument TokenTree or item for attributes
     arg: InFile<SyntaxNode>,
     /// The `macro_rules!` or attribute input.
@@ -598,7 +643,7 @@ pub struct ExpansionInfo {
 
 impl ExpansionInfo {
     pub fn expanded(&self) -> InFile<SyntaxNode> {
-        self.expanded.clone().into()
+        self.expanded.clone()
     }
 
     pub fn call_node(&self) -> Option<InFile<SyntaxNode>> {
@@ -629,7 +674,7 @@ impl ExpansionInfo {
         let token_id_in_attr_input = if let Some(item) = item {
             // check if we are mapping down in an attribute input
             // this is a special case as attributes can have two inputs
-            let call_id = self.expanded.file_id.macro_call_id;
+            let call_id = self.expanded.file_id.macro_file()?.macro_call_id;
             let loc = db.lookup_intern_macro_call(call_id);
 
             let token_range = token.value.text_range();
@@ -675,7 +720,7 @@ impl ExpansionInfo {
                 let relative_range =
                     token.value.text_range().checked_sub(self.arg.value.text_range().start())?;
                 let token_id = self.macro_arg.1.token_by_range(relative_range)?;
-                // conditionally shift the id by a declarative macro definition
+                // conditionally shift the id by a declaratives macro definition
                 self.macro_def.map_id_down(token_id)
             }
         };
@@ -685,7 +730,7 @@ impl ExpansionInfo {
             .ranges_by_token(token_id, token.value.kind())
             .flat_map(move |range| self.expanded.value.covering_element(range).into_token());
 
-        Some(tokens.map(move |token| InFile::new(self.expanded.file_id.into(), token)))
+        Some(tokens.map(move |token| self.expanded.with_value(token)))
     }
 
     /// Map a token up out of the expansion it resides in into the arguments of the macro call of the expansion.
@@ -694,17 +739,18 @@ impl ExpansionInfo {
         db: &dyn db::ExpandDatabase,
         token: InFile<&SyntaxToken>,
     ) -> Option<(InFile<SyntaxToken>, Origin)> {
-        assert_eq!(token.file_id, self.expanded.file_id.into());
         // Fetch the id through its text range,
         let token_id = self.exp_map.token_by_range(token.value.text_range())?;
         // conditionally unshifting the id to accommodate for macro-rules def site
         let (mut token_id, origin) = self.macro_def.map_id_up(token_id);
 
-        let call_id = self.expanded.file_id.macro_call_id;
+        let call_id = self.expanded.file_id.macro_file()?.macro_call_id;
         let loc = db.lookup_intern_macro_call(call_id);
 
         // Special case: map tokens from `include!` expansions to the included file
-        if loc.def.is_include() {
+        if loc.def.is_include()
+            && matches!(loc.eager.as_deref(), Some(EagerCallInfo { arg_id: Some(_), .. }))
+        {
             if let Ok((tt_and_map, file_id)) = db.include_expand(call_id) {
                 let range = tt_and_map.1.first_range_by_token(token_id, token.value.kind())?;
                 let source = db.parse(file_id);
@@ -748,58 +794,6 @@ impl ExpansionInfo {
             tt.value.covering_element(range + tt.value.text_range().start()).into_token()?;
         Some((tt.with_value(token), origin))
     }
-
-    fn new(db: &dyn db::ExpandDatabase, macro_file: MacroFile) -> Option<ExpansionInfo> {
-        let loc: MacroCallLoc = db.lookup_intern_macro_call(macro_file.macro_call_id);
-
-        let arg_tt = loc.kind.arg(db)?;
-
-        let macro_def = db.macro_expander(loc.def);
-        let (parse, exp_map) = db.parse_macro_expansion(macro_file).value;
-        let expanded = InMacroFile { file_id: macro_file, value: parse.syntax_node() };
-
-        let macro_arg = db.macro_arg(macro_file.macro_call_id).value.unwrap_or_else(|| {
-            Arc::new((
-                tt::Subtree { delimiter: tt::Delimiter::UNSPECIFIED, token_trees: Vec::new() },
-                Default::default(),
-                Default::default(),
-            ))
-        });
-
-        let def = loc.def.ast_id().left().and_then(|id| {
-            let def_tt = match id.to_node(db) {
-                ast::Macro::MacroRules(mac) => mac.token_tree()?,
-                ast::Macro::MacroDef(_) if matches!(macro_def, TokenExpander::BuiltInAttr(_)) => {
-                    return None
-                }
-                ast::Macro::MacroDef(mac) => mac.body()?,
-            };
-            Some(InFile::new(id.file_id, def_tt))
-        });
-        let attr_input_or_mac_def = def.or_else(|| match loc.kind {
-            MacroCallKind::Attr { ast_id, invoc_attr_index, .. } => {
-                // FIXME: handle `cfg_attr`
-                let tt = ast_id
-                    .to_node(db)
-                    .doc_comments_and_attrs()
-                    .nth(invoc_attr_index.ast_index())
-                    .and_then(Either::left)?
-                    .token_tree()?;
-                Some(InFile::new(ast_id.file_id, tt))
-            }
-            _ => None,
-        });
-
-        Some(ExpansionInfo {
-            expanded,
-            arg: arg_tt,
-            attr_input_or_mac_def,
-            macro_arg_shift: mbe::Shift::new(&macro_arg.0),
-            macro_arg,
-            macro_def,
-            exp_map,
-        })
-    }
 }
 
 /// `AstId` points to an AST node in any file.
@@ -811,9 +805,6 @@ impl<N: AstIdNode> AstId<N> {
     pub fn to_node(&self, db: &dyn db::ExpandDatabase) -> N {
         self.to_ptr(db).to_node(&db.parse_or_expand(self.file_id))
     }
-    pub fn to_in_file_node(&self, db: &dyn db::ExpandDatabase) -> InFile<N> {
-        InFile::new(self.file_id, self.to_ptr(db).to_node(&db.parse_or_expand(self.file_id)))
-    }
     pub fn to_ptr(&self, db: &dyn db::ExpandDatabase) -> AstPtr<N> {
         db.ast_id_map(self.file_id).get(self.value)
     }
@@ -829,7 +820,6 @@ impl ErasedAstId {
         db.ast_id_map(self.file_id).get_raw(self.value)
     }
 }
-
 /// `InFile<T>` stores a value of `T` inside a particular file/syntax tree.
 ///
 /// Typical usages are:
@@ -1048,18 +1038,6 @@ impl InFile<SyntaxToken> {
     }
 }
 
-#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
-pub struct InMacroFile<T> {
-    pub file_id: MacroFile,
-    pub value: T,
-}
-
-impl<T> From<InMacroFile<T>> for InFile<T> {
-    fn from(macro_file: InMacroFile<T>) -> Self {
-        InFile { file_id: macro_file.file_id.into(), value: macro_file.value }
-    }
-}
-
 fn ascend_node_border_tokens(
     db: &dyn db::ExpandDatabase,
     InFile { file_id, value: node }: InFile<&SyntaxNode>,
diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs
index 50eabc867b..f4fbace19e 100644
--- a/crates/hir-ty/src/chalk_db.rs
+++ b/crates/hir-ty/src/chalk_db.rs
@@ -60,9 +60,37 @@ impl chalk_solve::RustIrDatabase<Interner> for ChalkContext<'_> {
         // FIXME: keep track of these
         Arc::new(rust_ir::AdtRepr { c: false, packed: false, int: None })
     }
-    fn discriminant_type(&self, _ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
-        // FIXME: keep track of this
-        chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U32)).intern(Interner)
+    fn discriminant_type(&self, ty: chalk_ir::Ty<Interner>) -> chalk_ir::Ty<Interner> {
+        if let chalk_ir::TyKind::Adt(id, _) = ty.kind(Interner) {
+            if let hir_def::AdtId::EnumId(e) = id.0 {
+                let enum_data = self.db.enum_data(e);
+                let ty = enum_data.repr.unwrap_or_default().discr_type();
+                return chalk_ir::TyKind::Scalar(match ty {
+                    hir_def::layout::IntegerType::Pointer(is_signed) => match is_signed {
+                        true => chalk_ir::Scalar::Int(chalk_ir::IntTy::Isize),
+                        false => chalk_ir::Scalar::Uint(chalk_ir::UintTy::Usize),
+                    },
+                    hir_def::layout::IntegerType::Fixed(size, is_signed) => match is_signed {
+                        true => chalk_ir::Scalar::Int(match size {
+                            hir_def::layout::Integer::I8 => chalk_ir::IntTy::I8,
+                            hir_def::layout::Integer::I16 => chalk_ir::IntTy::I16,
+                            hir_def::layout::Integer::I32 => chalk_ir::IntTy::I32,
+                            hir_def::layout::Integer::I64 => chalk_ir::IntTy::I64,
+                            hir_def::layout::Integer::I128 => chalk_ir::IntTy::I128,
+                        }),
+                        false => chalk_ir::Scalar::Uint(match size {
+                            hir_def::layout::Integer::I8 => chalk_ir::UintTy::U8,
+                            hir_def::layout::Integer::I16 => chalk_ir::UintTy::U16,
+                            hir_def::layout::Integer::I32 => chalk_ir::UintTy::U32,
+                            hir_def::layout::Integer::I64 => chalk_ir::UintTy::U64,
+                            hir_def::layout::Integer::I128 => chalk_ir::UintTy::U128,
+                        }),
+                    },
+                })
+                .intern(Interner);
+            }
+        }
+        chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(chalk_ir::UintTy::U8)).intern(Interner)
     }
     fn impl_datum(&self, impl_id: ImplId) -> Arc<ImplDatum> {
         self.db.impl_datum(self.krate, impl_id)
diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs
index dc846fc394..5e92b350a3 100644
--- a/crates/hir-ty/src/mir.rs
+++ b/crates/hir-ty/src/mir.rs
@@ -323,8 +323,8 @@ impl SwitchTargets {
 
 #[derive(Debug, PartialEq, Eq, Clone)]
 pub struct Terminator {
-    pub span: MirSpan,
-    pub kind: TerminatorKind,
+    span: MirSpan,
+    kind: TerminatorKind,
 }
 
 #[derive(Debug, PartialEq, Eq, Clone)]
diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs
index 47c9354768..d7820de629 100644
--- a/crates/hir-ty/src/mir/eval.rs
+++ b/crates/hir-ty/src/mir/eval.rs
@@ -29,7 +29,7 @@ use crate::{
     infer::PointerCast,
     layout::{Layout, LayoutError, RustcEnumVariantIdx},
     mapping::from_chalk,
-    method_resolution::is_dyn_method,
+    method_resolution::{is_dyn_method, lookup_impl_const},
     name, static_lifetime,
     traits::FnTrait,
     utils::{detect_variant_from_bytes, ClosureSubst},
@@ -1571,35 +1571,51 @@ impl Evaluator<'_> {
         let chalk_ir::ConstValue::Concrete(c) = &konst.data(Interner).value else {
             not_supported!("evaluating non concrete constant");
         };
-        Ok(match &c.interned {
-            ConstScalar::Bytes(v, memory_map) => {
-                let mut v: Cow<'_, [u8]> = Cow::Borrowed(v);
-                let patch_map = memory_map.transform_addresses(|b, align| {
-                    let addr = self.heap_allocate(b.len(), align)?;
-                    self.write_memory(addr, b)?;
-                    Ok(addr.to_usize())
+        let result_owner;
+        let (v, memory_map) = match &c.interned {
+            ConstScalar::Bytes(v, mm) => (v, mm),
+            ConstScalar::UnevaluatedConst(const_id, subst) => 'b: {
+                let mut const_id = *const_id;
+                let mut subst = subst.clone();
+                if let hir_def::GeneralConstId::ConstId(c) = const_id {
+                    let (c, s) = lookup_impl_const(self.db, self.trait_env.clone(), c, subst);
+                    const_id = hir_def::GeneralConstId::ConstId(c);
+                    subst = s;
+                }
+                result_owner = self.db.const_eval(const_id.into(), subst).map_err(|e| {
+                    let name = const_id.name(self.db.upcast());
+                    MirEvalError::ConstEvalError(name, Box::new(e))
                 })?;
-                let (size, align) = self.size_align_of(ty, locals)?.unwrap_or((v.len(), 1));
-                if size != v.len() {
-                    // Handle self enum
-                    if size == 16 && v.len() < 16 {
-                        v = Cow::Owned(pad16(&v, false).to_vec());
-                    } else if size < 16 && v.len() == 16 {
-                        v = Cow::Owned(v[0..size].to_vec());
-                    } else {
-                        return Err(MirEvalError::InvalidConst(konst.clone()));
+                if let chalk_ir::ConstValue::Concrete(c) = &result_owner.data(Interner).value {
+                    if let ConstScalar::Bytes(v, mm) = &c.interned {
+                        break 'b (v, mm);
                     }
                 }
-                let addr = self.heap_allocate(size, align)?;
-                self.write_memory(addr, &v)?;
-                self.patch_addresses(&patch_map, &memory_map.vtable, addr, ty, locals)?;
-                Interval::new(addr, size)
-            }
-            ConstScalar::UnevaluatedConst(..) => {
-                not_supported!("unevaluated const present in monomorphized mir");
+                not_supported!("unevaluatable constant");
             }
             ConstScalar::Unknown => not_supported!("evaluating unknown const"),
-        })
+        };
+        let mut v: Cow<'_, [u8]> = Cow::Borrowed(v);
+        let patch_map = memory_map.transform_addresses(|b, align| {
+            let addr = self.heap_allocate(b.len(), align)?;
+            self.write_memory(addr, b)?;
+            Ok(addr.to_usize())
+        })?;
+        let (size, align) = self.size_align_of(ty, locals)?.unwrap_or((v.len(), 1));
+        if size != v.len() {
+            // Handle self enum
+            if size == 16 && v.len() < 16 {
+                v = Cow::Owned(pad16(&v, false).to_vec());
+            } else if size < 16 && v.len() == 16 {
+                v = Cow::Owned(v[0..size].to_vec());
+            } else {
+                return Err(MirEvalError::InvalidConst(konst.clone()));
+            }
+        }
+        let addr = self.heap_allocate(size, align)?;
+        self.write_memory(addr, &v)?;
+        self.patch_addresses(&patch_map, &memory_map.vtable, addr, ty, locals)?;
+        Ok(Interval::new(addr, size))
     }
 
     fn eval_place(&mut self, p: &Place, locals: &Locals) -> Result<Interval> {
diff --git a/crates/hir-ty/src/mir/eval/shim.rs b/crates/hir-ty/src/mir/eval/shim.rs
index cedc453803..28a5e50a56 100644
--- a/crates/hir-ty/src/mir/eval/shim.rs
+++ b/crates/hir-ty/src/mir/eval/shim.rs
@@ -602,6 +602,26 @@ impl Evaluator<'_> {
                     destination.write_from_bytes(self, &align.to_le_bytes())
                 }
             }
+            "type_name" => {
+                let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
+                else {
+                    return Err(MirEvalError::TypeError("type_name generic arg is not provided"));
+                };
+                let Ok(ty_name) = ty.display_source_code(
+                    self.db,
+                    locals.body.owner.module(self.db.upcast()),
+                    true,
+                ) else {
+                    not_supported!("fail in generating type_name using source code display");
+                };
+                let len = ty_name.len();
+                let addr = self.heap_allocate(len, 1)?;
+                self.write_memory(addr, ty_name.as_bytes())?;
+                destination.slice(0..self.ptr_size()).write_from_bytes(self, &addr.to_bytes())?;
+                destination
+                    .slice(self.ptr_size()..2 * self.ptr_size())
+                    .write_from_bytes(self, &len.to_le_bytes())
+            }
             "needs_drop" => {
                 let Some(ty) = generic_args.as_slice(Interner).get(0).and_then(|it| it.ty(Interner))
                 else {
diff --git a/crates/hir-ty/src/mir/monomorphization.rs b/crates/hir-ty/src/mir/monomorphization.rs
index e4574c77e2..c565228d91 100644
--- a/crates/hir-ty/src/mir/monomorphization.rs
+++ b/crates/hir-ty/src/mir/monomorphization.rs
@@ -13,15 +13,14 @@ use chalk_ir::{
     fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable},
     ConstData, DebruijnIndex,
 };
-use hir_def::{DefWithBodyId, GeneralConstId};
+use hir_def::DefWithBodyId;
 use triomphe::Arc;
 
 use crate::{
-    consteval::unknown_const,
+    consteval::{intern_const_scalar, unknown_const},
     db::HirDatabase,
     from_placeholder_idx,
     infer::normalize,
-    method_resolution::lookup_impl_const,
     utils::{generics, Generics},
     ClosureId, Const, Interner, ProjectionTy, Substitution, TraitEnvironment, Ty, TyKind,
 };
@@ -193,25 +192,12 @@ impl Filler<'_> {
                     | chalk_ir::ConstValue::Placeholder(_) => {}
                     chalk_ir::ConstValue::Concrete(cc) => match &cc.interned {
                         crate::ConstScalar::UnevaluatedConst(const_id, subst) => {
-                            let mut const_id = *const_id;
                             let mut subst = subst.clone();
                             self.fill_subst(&mut subst)?;
-                            if let GeneralConstId::ConstId(c) = const_id {
-                                let (c, s) = lookup_impl_const(
-                                    self.db,
-                                    self.db.trait_environment_for_body(self.owner),
-                                    c,
-                                    subst,
-                                );
-                                const_id = GeneralConstId::ConstId(c);
-                                subst = s;
-                            }
-                            let result =
-                                self.db.const_eval(const_id.into(), subst).map_err(|e| {
-                                    let name = const_id.name(self.db.upcast());
-                                    MirLowerError::ConstEvalError(name, Box::new(e))
-                                })?;
-                            *c = result;
+                            *c = intern_const_scalar(
+                                crate::ConstScalar::UnevaluatedConst(*const_id, subst),
+                                c.data(Interner).ty.clone(),
+                            );
                         }
                         crate::ConstScalar::Bytes(_, _) | crate::ConstScalar::Unknown => (),
                     },
diff --git a/crates/hir/src/db.rs b/crates/hir/src/db.rs
index f3a0608944..fa2deb7215 100644
--- a/crates/hir/src/db.rs
+++ b/crates/hir/src/db.rs
@@ -6,7 +6,7 @@
 pub use hir_def::db::*;
 pub use hir_expand::db::{
     AstIdMapQuery, DeclMacroExpanderQuery, ExpandDatabase, ExpandDatabaseStorage,
-    ExpandProcMacroQuery, HygieneFrameQuery, InternMacroCallQuery, MacroArgNodeQuery,
+    ExpandProcMacroQuery, HygieneFrameQuery, InternMacroCallQuery, MacroArgTextQuery,
     MacroExpandQuery, ParseMacroExpansionErrorQuery, ParseMacroExpansionQuery,
 };
 pub use hir_ty::db::*;
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index f8d9398ae2..d09963d4d3 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -698,7 +698,7 @@ impl Module {
 
 fn emit_macro_def_diagnostics(db: &dyn HirDatabase, acc: &mut Vec<AnyDiagnostic>, m: Macro) {
     let id = macro_id_to_def_id(db.upcast(), m.id);
-    if let hir_expand::db::TokenExpander::DeclarativeMacro(expander) = db.macro_expander(id) {
+    if let hir_expand::db::TokenExpander::DeclarativeMacro(expander) = db.macro_def(id) {
         if let Some(e) = expander.mac.err() {
             let Some(ast) = id.ast_id().left() else {
                 never!("declarative expander for non decl-macro: {:?}", e);
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 ac0b74ee8e..7384390f28 100644
--- a/crates/ide-assists/src/handlers/add_missing_match_arms.rs
+++ b/crates/ide-assists/src/handlers/add_missing_match_arms.rs
@@ -8,7 +8,10 @@ use itertools::Itertools;
 use syntax::ast::edit_in_place::Removable;
 use syntax::ast::{self, make, AstNode, HasName, MatchArmList, MatchExpr, Pat};
 
-use crate::{utils, AssistContext, AssistId, AssistKind, Assists};
+use crate::{
+    utils::{self, render_snippet, Cursor},
+    AssistContext, AssistId, AssistKind, Assists,
+};
 
 // Assist: add_missing_match_arms
 //
@@ -72,18 +75,14 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
         .collect();
 
     let module = ctx.sema.scope(expr.syntax())?.module();
-    let (mut missing_pats, is_non_exhaustive, has_hidden_variants): (
+    let (mut missing_pats, is_non_exhaustive): (
         Peekable<Box<dyn Iterator<Item = (ast::Pat, bool)>>>,
         bool,
-        bool,
     ) = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) {
         let is_non_exhaustive = enum_def.is_non_exhaustive(ctx.db(), module.krate());
 
         let variants = enum_def.variants(ctx.db());
 
-        let has_hidden_variants =
-            variants.iter().any(|variant| variant.should_be_hidden(ctx.db(), module.krate()));
-
         let missing_pats = variants
             .into_iter()
             .filter_map(|variant| {
@@ -102,7 +101,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
         } else {
             Box::new(missing_pats)
         };
-        (missing_pats.peekable(), is_non_exhaustive, has_hidden_variants)
+        (missing_pats.peekable(), is_non_exhaustive)
     } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) {
         let is_non_exhaustive =
             enum_defs.iter().any(|enum_def| enum_def.is_non_exhaustive(ctx.db(), module.krate()));
@@ -125,12 +124,6 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
         if n_arms > 256 {
             return None;
         }
-
-        let has_hidden_variants = variants_of_enums
-            .iter()
-            .flatten()
-            .any(|variant| variant.should_be_hidden(ctx.db(), module.krate()));
-
         let missing_pats = variants_of_enums
             .into_iter()
             .multi_cartesian_product()
@@ -146,11 +139,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
                 (ast::Pat::from(make::tuple_pat(patterns)), is_hidden)
             })
             .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat));
-        (
-            (Box::new(missing_pats) as Box<dyn Iterator<Item = _>>).peekable(),
-            is_non_exhaustive,
-            has_hidden_variants,
-        )
+        ((Box::new(missing_pats) as Box<dyn Iterator<Item = _>>).peekable(), is_non_exhaustive)
     } else if let Some((enum_def, len)) = resolve_array_of_enum_def(&ctx.sema, &expr) {
         let is_non_exhaustive = enum_def.is_non_exhaustive(ctx.db(), module.krate());
         let variants = enum_def.variants(ctx.db());
@@ -159,9 +148,6 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
             return None;
         }
 
-        let has_hidden_variants =
-            variants.iter().any(|variant| variant.should_be_hidden(ctx.db(), module.krate()));
-
         let variants_of_enums = vec![variants; len];
 
         let missing_pats = variants_of_enums
@@ -178,20 +164,14 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
                 (ast::Pat::from(make::slice_pat(patterns)), is_hidden)
             })
             .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat));
-        (
-            (Box::new(missing_pats) as Box<dyn Iterator<Item = _>>).peekable(),
-            is_non_exhaustive,
-            has_hidden_variants,
-        )
+        ((Box::new(missing_pats) as Box<dyn Iterator<Item = _>>).peekable(), is_non_exhaustive)
     } else {
         return None;
     };
 
     let mut needs_catch_all_arm = is_non_exhaustive && !has_catch_all_arm;
 
-    if !needs_catch_all_arm
-        && ((has_hidden_variants && has_catch_all_arm) || missing_pats.peek().is_none())
-    {
+    if !needs_catch_all_arm && missing_pats.peek().is_none() {
         return None;
     }
 
@@ -199,21 +179,13 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
         AssistId("add_missing_match_arms", AssistKind::QuickFix),
         "Fill match arms",
         target_range,
-        |edit| {
+        |builder| {
             let new_match_arm_list = match_arm_list.clone_for_update();
-
-            // having any hidden variants means that we need a catch-all arm
-            needs_catch_all_arm |= has_hidden_variants;
-
             let missing_arms = missing_pats
-                .filter(|(_, hidden)| {
-                    // filter out hidden patterns because they're handled by the catch-all arm
-                    !hidden
+                .map(|(pat, hidden)| {
+                    (make::match_arm(iter::once(pat), None, make::ext::expr_todo()), hidden)
                 })
-                .map(|(pat, _)| {
-                    make::match_arm(iter::once(pat), None, make::ext::expr_todo())
-                        .clone_for_update()
-                });
+                .map(|(it, hidden)| (it.clone_for_update(), hidden));
 
             let catch_all_arm = new_match_arm_list
                 .arms()
@@ -232,13 +204,15 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
                     cov_mark::hit!(add_missing_match_arms_empty_expr);
                 }
             }
-
             let mut first_new_arm = None;
-            for arm in missing_arms {
-                first_new_arm.get_or_insert_with(|| arm.clone());
-                new_match_arm_list.add_arm(arm);
+            for (arm, hidden) in missing_arms {
+                if hidden {
+                    needs_catch_all_arm = !has_catch_all_arm;
+                } else {
+                    first_new_arm.get_or_insert_with(|| arm.clone());
+                    new_match_arm_list.add_arm(arm);
+                }
             }
-
             if needs_catch_all_arm && !has_catch_all_arm {
                 cov_mark::hit!(added_wildcard_pattern);
                 let arm = make::match_arm(
@@ -251,39 +225,24 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
                 new_match_arm_list.add_arm(arm);
             }
 
-            if let (Some(first_new_arm), Some(cap)) = (first_new_arm, ctx.config.snippet_cap) {
-                match first_new_arm.syntax().descendants().find_map(ast::WildcardPat::cast) {
-                    Some(it) => edit.add_placeholder_snippet(cap, it),
-                    None => edit.add_tabstop_before(cap, first_new_arm),
+            let old_range = ctx.sema.original_range(match_arm_list.syntax()).range;
+            match (first_new_arm, ctx.config.snippet_cap) {
+                (Some(first_new_arm), Some(cap)) => {
+                    let extend_lifetime;
+                    let cursor =
+                        match first_new_arm.syntax().descendants().find_map(ast::WildcardPat::cast)
+                        {
+                            Some(it) => {
+                                extend_lifetime = it.syntax().clone();
+                                Cursor::Replace(&extend_lifetime)
+                            }
+                            None => Cursor::Before(first_new_arm.syntax()),
+                        };
+                    let snippet = render_snippet(cap, new_match_arm_list.syntax(), cursor);
+                    builder.replace_snippet(cap, old_range, snippet);
                 }
+                _ => builder.replace(old_range, new_match_arm_list.to_string()),
             }
-
-            // FIXME: Hack for mutable syntax trees not having great support for macros
-            // Just replace the element that the original range came from
-            let old_place = {
-                // Find the original element
-                let old_file_range = ctx.sema.original_range(match_arm_list.syntax());
-                let file = ctx.sema.parse(old_file_range.file_id);
-                let old_place = file.syntax().covering_element(old_file_range.range);
-
-                // Make `old_place` mut
-                match old_place {
-                    syntax::SyntaxElement::Node(it) => {
-                        syntax::SyntaxElement::from(edit.make_syntax_mut(it))
-                    }
-                    syntax::SyntaxElement::Token(it) => {
-                        // Don't have a way to make tokens mut, so instead make the parent mut
-                        // and find the token again
-                        let parent = edit.make_syntax_mut(it.parent().unwrap());
-                        let mut_token =
-                            parent.covering_element(it.text_range()).into_token().unwrap();
-
-                        syntax::SyntaxElement::from(mut_token)
-                    }
-                }
-            };
-
-            syntax::ted::replace(old_place, new_match_arm_list.syntax());
         },
     )
 }
@@ -1662,9 +1621,10 @@ pub enum E { #[doc(hidden)] A, }
         );
     }
 
+    // FIXME: I don't think the assist should be applicable in this case
     #[test]
     fn does_not_fill_wildcard_with_wildcard() {
-        check_assist_not_applicable(
+        check_assist(
             add_missing_match_arms,
             r#"
 //- /main.rs crate:main deps:e
@@ -1675,6 +1635,13 @@ fn foo(t: ::e::E) {
 }
 //- /e.rs crate:e
 pub enum E { #[doc(hidden)] A, }
+"#,
+            r#"
+fn foo(t: ::e::E) {
+    match t {
+        _ => todo!(),
+    }
+}
 "#,
         );
     }
@@ -1810,7 +1777,7 @@ fn foo(t: ::e::E, b: bool) {
 
     #[test]
     fn does_not_fill_wildcard_with_partial_wildcard_and_wildcard() {
-        check_assist_not_applicable(
+        check_assist(
             add_missing_match_arms,
             r#"
 //- /main.rs crate:main deps:e
@@ -1822,6 +1789,14 @@ fn foo(t: ::e::E, b: bool) {
 }
 //- /e.rs crate:e
 pub enum E { #[doc(hidden)] A, }"#,
+            r#"
+fn foo(t: ::e::E, b: bool) {
+    match t {
+        _ if b => todo!(),
+        _ => todo!(),
+    }
+}
+"#,
         );
     }
 
diff --git a/crates/ide-assists/src/handlers/fix_visibility.rs b/crates/ide-assists/src/handlers/fix_visibility.rs
index c9f272474e..4a2ab18c98 100644
--- a/crates/ide-assists/src/handlers/fix_visibility.rs
+++ b/crates/ide-assists/src/handlers/fix_visibility.rs
@@ -1,11 +1,11 @@
 use hir::{db::HirDatabase, HasSource, HasVisibility, ModuleDef, PathResolution, ScopeDef};
 use ide_db::base_db::FileId;
 use syntax::{
-    ast::{self, edit_in_place::HasVisibilityEdit, make, HasVisibility as _},
-    AstNode, TextRange,
+    ast::{self, HasVisibility as _},
+    AstNode, TextRange, TextSize,
 };
 
-use crate::{AssistContext, AssistId, AssistKind, Assists};
+use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists};
 
 // FIXME: this really should be a fix for diagnostic, rather than an assist.
 
@@ -58,13 +58,11 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
         return None;
     };
 
-    let (vis_owner, target, target_file, target_name) = target_data_for_def(ctx.db(), def)?;
+    let (offset, current_visibility, target, target_file, target_name) =
+        target_data_for_def(ctx.db(), def)?;
 
-    let missing_visibility = if current_module.krate() == target_module.krate() {
-        make::visibility_pub_crate()
-    } else {
-        make::visibility_pub()
-    };
+    let missing_visibility =
+        if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
 
     let assist_label = match target_name {
         None => format!("Change visibility to {missing_visibility}"),
@@ -73,14 +71,23 @@ fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext<'_>)
         }
     };
 
-    acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |edit| {
-        edit.edit_file(target_file);
-
-        let vis_owner = edit.make_mut(vis_owner);
-        vis_owner.set_visibility(missing_visibility.clone_for_update());
-
-        if let Some((cap, vis)) = ctx.config.snippet_cap.zip(vis_owner.visibility()) {
-            edit.add_tabstop_before(cap, vis);
+    acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
+        builder.edit_file(target_file);
+        match ctx.config.snippet_cap {
+            Some(cap) => match current_visibility {
+                Some(current_visibility) => builder.replace_snippet(
+                    cap,
+                    current_visibility.syntax().text_range(),
+                    format!("$0{missing_visibility}"),
+                ),
+                None => builder.insert_snippet(cap, offset, format!("$0{missing_visibility} ")),
+            },
+            None => match current_visibility {
+                Some(current_visibility) => {
+                    builder.replace(current_visibility.syntax().text_range(), missing_visibility)
+                }
+                None => builder.insert(offset, format!("{missing_visibility} ")),
+            },
         }
     })
 }
@@ -100,22 +107,19 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
     let target_module = parent.module(ctx.db());
 
     let in_file_source = record_field_def.source(ctx.db())?;
-    let (vis_owner, target) = match in_file_source.value {
+    let (offset, current_visibility, target) = match in_file_source.value {
         hir::FieldSource::Named(it) => {
-            let range = it.syntax().text_range();
-            (ast::AnyHasVisibility::new(it), range)
+            let s = it.syntax();
+            (vis_offset(s), it.visibility(), s.text_range())
         }
         hir::FieldSource::Pos(it) => {
-            let range = it.syntax().text_range();
-            (ast::AnyHasVisibility::new(it), range)
+            let s = it.syntax();
+            (vis_offset(s), it.visibility(), s.text_range())
         }
     };
 
-    let missing_visibility = if current_module.krate() == target_module.krate() {
-        make::visibility_pub_crate()
-    } else {
-        make::visibility_pub()
-    };
+    let missing_visibility =
+        if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
     let target_file = in_file_source.file_id.original_file(ctx.db());
 
     let target_name = record_field_def.name(ctx.db());
@@ -125,14 +129,23 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
         target_name.display(ctx.db())
     );
 
-    acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |edit| {
-        edit.edit_file(target_file);
-
-        let vis_owner = edit.make_mut(vis_owner);
-        vis_owner.set_visibility(missing_visibility.clone_for_update());
-
-        if let Some((cap, vis)) = ctx.config.snippet_cap.zip(vis_owner.visibility()) {
-            edit.add_tabstop_before(cap, vis);
+    acc.add(AssistId("fix_visibility", AssistKind::QuickFix), assist_label, target, |builder| {
+        builder.edit_file(target_file);
+        match ctx.config.snippet_cap {
+            Some(cap) => match current_visibility {
+                Some(current_visibility) => builder.replace_snippet(
+                    cap,
+                    current_visibility.syntax().text_range(),
+                    format!("$0{missing_visibility}"),
+                ),
+                None => builder.insert_snippet(cap, offset, format!("$0{missing_visibility} ")),
+            },
+            None => match current_visibility {
+                Some(current_visibility) => {
+                    builder.replace(current_visibility.syntax().text_range(), missing_visibility)
+                }
+                None => builder.insert(offset, format!("{missing_visibility} ")),
+            },
         }
     })
 }
@@ -140,11 +153,11 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext<'_>
 fn target_data_for_def(
     db: &dyn HirDatabase,
     def: hir::ModuleDef,
-) -> Option<(ast::AnyHasVisibility, TextRange, FileId, Option<hir::Name>)> {
+) -> Option<(TextSize, Option<ast::Visibility>, TextRange, FileId, Option<hir::Name>)> {
     fn offset_target_and_file_id<S, Ast>(
         db: &dyn HirDatabase,
         x: S,
-    ) -> Option<(ast::AnyHasVisibility, TextRange, FileId)>
+    ) -> Option<(TextSize, Option<ast::Visibility>, TextRange, FileId)>
     where
         S: HasSource<Ast = Ast>,
         Ast: AstNode + ast::HasVisibility,
@@ -152,12 +165,18 @@ fn target_data_for_def(
         let source = x.source(db)?;
         let in_file_syntax = source.syntax();
         let file_id = in_file_syntax.file_id;
-        let range = in_file_syntax.value.text_range();
-        Some((ast::AnyHasVisibility::new(source.value), range, file_id.original_file(db.upcast())))
+        let syntax = in_file_syntax.value;
+        let current_visibility = source.value.visibility();
+        Some((
+            vis_offset(syntax),
+            current_visibility,
+            syntax.text_range(),
+            file_id.original_file(db.upcast()),
+        ))
     }
 
     let target_name;
-    let (offset, target, target_file) = match def {
+    let (offset, current_visibility, target, target_file) = match def {
         hir::ModuleDef::Function(f) => {
             target_name = Some(f.name(db));
             offset_target_and_file_id(db, f)?
@@ -194,8 +213,8 @@ fn target_data_for_def(
             target_name = m.name(db);
             let in_file_source = m.declaration_source(db)?;
             let file_id = in_file_source.file_id.original_file(db.upcast());
-            let range = in_file_source.value.syntax().text_range();
-            (ast::AnyHasVisibility::new(in_file_source.value), range, file_id)
+            let syntax = in_file_source.value.syntax();
+            (vis_offset(syntax), in_file_source.value.visibility(), syntax.text_range(), file_id)
         }
         // FIXME
         hir::ModuleDef::Macro(_) => return None,
@@ -203,7 +222,7 @@ fn target_data_for_def(
         hir::ModuleDef::Variant(_) | hir::ModuleDef::BuiltinType(_) => return None,
     };
 
-    Some((offset, target, target_file, target_name))
+    Some((offset, current_visibility, target, target_file, target_name))
 }
 
 #[cfg(test)]
diff --git a/crates/ide-assists/src/handlers/promote_local_to_const.rs b/crates/ide-assists/src/handlers/promote_local_to_const.rs
index 5cc110cf12..23153b4c56 100644
--- a/crates/ide-assists/src/handlers/promote_local_to_const.rs
+++ b/crates/ide-assists/src/handlers/promote_local_to_const.rs
@@ -8,10 +8,13 @@ use ide_db::{
 use stdx::to_upper_snake_case;
 use syntax::{
     ast::{self, make, HasName},
-    ted, AstNode, WalkEvent,
+    AstNode, WalkEvent,
 };
 
-use crate::assist_context::{AssistContext, Assists};
+use crate::{
+    assist_context::{AssistContext, Assists},
+    utils::{render_snippet, Cursor},
+};
 
 // Assist: promote_local_to_const
 //
@@ -67,33 +70,29 @@ pub(crate) fn promote_local_to_const(acc: &mut Assists, ctx: &AssistContext<'_>)
         cov_mark::hit!(promote_local_non_const);
         return None;
     }
-
+    let target = let_stmt.syntax().text_range();
     acc.add(
         AssistId("promote_local_to_const", AssistKind::Refactor),
         "Promote local to constant",
-        let_stmt.syntax().text_range(),
-        |edit| {
+        target,
+        |builder| {
             let name = to_upper_snake_case(&name.to_string());
             let usages = Definition::Local(local).usages(&ctx.sema).all();
             if let Some(usages) = usages.references.get(&ctx.file_id()) {
-                let name = make::name_ref(&name);
-
                 for usage in usages {
-                    let Some(usage) = usage.name.as_name_ref().cloned() else { continue };
-                    let usage = edit.make_mut(usage);
-                    ted::replace(usage.syntax(), name.clone_for_update().syntax());
+                    builder.replace(usage.range, &name);
                 }
             }
 
-            let item = make::item_const(None, make::name(&name), make::ty(&ty), initializer)
-                .clone_for_update();
-            let let_stmt = edit.make_mut(let_stmt);
-
-            if let Some((cap, name)) = ctx.config.snippet_cap.zip(item.name()) {
-                edit.add_tabstop_before(cap, name);
+            let item = make::item_const(None, make::name(&name), make::ty(&ty), initializer);
+            match ctx.config.snippet_cap.zip(item.name()) {
+                Some((cap, name)) => builder.replace_snippet(
+                    cap,
+                    target,
+                    render_snippet(cap, item.syntax(), Cursor::Before(name.syntax())),
+                ),
+                None => builder.replace(target, item.to_string()),
             }
-
-            ted::replace(let_stmt.syntax(), item.syntax());
         },
     )
 }
@@ -158,27 +157,6 @@ fn foo() {
         );
     }
 
-    #[test]
-    fn multiple_uses() {
-        check_assist(
-            promote_local_to_const,
-            r"
-fn foo() {
-    let x$0 = 0;
-    let y = x;
-    let z = (x, x, x, x);
-}
-",
-            r"
-fn foo() {
-    const $0X: i32 = 0;
-    let y = X;
-    let z = (X, X, X, X);
-}
-",
-        );
-    }
-
     #[test]
     fn not_applicable_non_const_meth_call() {
         cov_mark::check!(promote_local_non_const);
diff --git a/crates/ide-db/src/apply_change.rs b/crates/ide-db/src/apply_change.rs
index a0b05c87ae..7ba0bd73ec 100644
--- a/crates/ide-db/src/apply_change.rs
+++ b/crates/ide-db/src/apply_change.rs
@@ -99,7 +99,7 @@ impl RootDatabase {
             hir::db::AstIdMapQuery
             hir::db::ParseMacroExpansionQuery
             hir::db::InternMacroCallQuery
-            hir::db::MacroArgNodeQuery
+            hir::db::MacroArgTextQuery
             hir::db::DeclMacroExpanderQuery
             hir::db::MacroExpandQuery
             hir::db::ExpandProcMacroQuery
diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs
index f27ed485d8..feced7e4bb 100644
--- a/crates/ide-db/src/lib.rs
+++ b/crates/ide-db/src/lib.rs
@@ -200,7 +200,7 @@ impl RootDatabase {
             hir_db::AstIdMapQuery
             // hir_db::ParseMacroExpansionQuery
             // hir_db::InternMacroCallQuery
-            hir_db::MacroArgNodeQuery
+            hir_db::MacroArgTextQuery
             hir_db::DeclMacroExpanderQuery
             // hir_db::MacroExpandQuery
             hir_db::ExpandProcMacroQuery
diff --git a/crates/ide/src/inlay_hints/chaining.rs b/crates/ide/src/inlay_hints/chaining.rs
index 774383d50d..b621a8dda7 100644
--- a/crates/ide/src/inlay_hints/chaining.rs
+++ b/crates/ide/src/inlay_hints/chaining.rs
@@ -474,7 +474,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9288..9296,
+                                        range: 9289..9297,
                                     },
                                 ),
                                 tooltip: "",
@@ -487,7 +487,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9320..9324,
+                                        range: 9321..9325,
                                     },
                                 ),
                                 tooltip: "",
@@ -511,7 +511,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9288..9296,
+                                        range: 9289..9297,
                                     },
                                 ),
                                 tooltip: "",
@@ -524,7 +524,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9320..9324,
+                                        range: 9321..9325,
                                     },
                                 ),
                                 tooltip: "",
@@ -548,7 +548,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9288..9296,
+                                        range: 9289..9297,
                                     },
                                 ),
                                 tooltip: "",
@@ -561,7 +561,7 @@ fn main() {
                                         file_id: FileId(
                                             1,
                                         ),
-                                        range: 9320..9324,
+                                        range: 9321..9325,
                                     },
                                 ),
                                 tooltip: "",
diff --git a/crates/ide/src/interpret_function.rs b/crates/ide/src/interpret_function.rs
index cbcbb4b09d..d06ffd5357 100644
--- a/crates/ide/src/interpret_function.rs
+++ b/crates/ide/src/interpret_function.rs
@@ -34,13 +34,15 @@ fn find_and_interpret(db: &RootDatabase, position: FilePosition) -> Option<Strin
         _ => return None,
     };
     let span_formatter = |file_id, text_range: TextRange| {
-        let line_col = db.line_index(file_id).line_col(text_range.start());
         let path = &db
             .source_root(db.file_source_root(file_id))
             .path_for_file(&file_id)
             .map(|x| x.to_string());
         let path = path.as_deref().unwrap_or("<unknown file>");
-        format!("file://{path}#{}:{}", line_col.line + 1, line_col.col)
+        match db.line_index(file_id).try_line_col(text_range.start()) {
+            Some(line_col) => format!("file://{path}#{}:{}", line_col.line + 1, line_col.col),
+            None => format!("file://{path} range {:?}", text_range),
+        }
     };
     Some(def.eval(db, span_formatter))
 }
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 577bd2bc1f..dc06591ffe 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -265,14 +265,10 @@ fn traverse(
 
         // set macro and attribute highlighting states
         match event.clone() {
-            Enter(NodeOrToken::Node(node))
-                if current_macro.is_none() && ast::TokenTree::can_cast(node.kind()) =>
-            {
+            Enter(NodeOrToken::Node(node)) if ast::TokenTree::can_cast(node.kind()) => {
                 tt_level += 1;
             }
-            Leave(NodeOrToken::Node(node))
-                if current_macro.is_none() && ast::TokenTree::can_cast(node.kind()) =>
-            {
+            Leave(NodeOrToken::Node(node)) if ast::TokenTree::can_cast(node.kind()) => {
                 tt_level -= 1;
             }
             Enter(NodeOrToken::Node(node)) if ast::Attr::can_cast(node.kind()) => {
@@ -391,7 +387,7 @@ fn traverse(
             };
         let descended_element = if in_macro {
             // Attempt to descend tokens into macro-calls.
-            let res = match element {
+            match element {
                 NodeOrToken::Token(token) if token.kind() != COMMENT => {
                     let token = match attr_or_derive_item {
                         Some(AttrOrDerive::Attr(_)) => {
@@ -416,8 +412,7 @@ fn traverse(
                     }
                 }
                 e => e,
-            };
-            res
+            }
         } else {
             element
         };
diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs
index 665bce474a..c17ba1c58e 100644
--- a/crates/mbe/src/lib.rs
+++ b/crates/mbe/src/lib.rs
@@ -208,7 +208,7 @@ impl Shift {
     }
 }
 
-#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+#[derive(Debug, Eq, PartialEq)]
 pub enum Origin {
     Def,
     Call,
diff --git a/crates/mbe/src/token_map.rs b/crates/mbe/src/token_map.rs
index 9b2df89f9c..c923e7a69a 100644
--- a/crates/mbe/src/token_map.rs
+++ b/crates/mbe/src/token_map.rs
@@ -110,11 +110,4 @@ impl TokenMap {
         // FIXME: This could be accidentally quadratic
         self.entries.remove(idx);
     }
-
-    pub fn entries(&self) -> impl Iterator<Item = (tt::TokenId, TextRange)> + '_ {
-        self.entries.iter().filter_map(|&(tid, tr)| match tr {
-            TokenTextRange::Token(range) => Some((tid, range)),
-            TokenTextRange::Delimiter(_) => None,
-        })
-    }
 }
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs
index 606804aea2..1f5ed206b4 100644
--- a/crates/syntax/src/ast/edit_in_place.rs
+++ b/crates/syntax/src/ast/edit_in_place.rs
@@ -748,27 +748,6 @@ fn normalize_ws_between_braces(node: &SyntaxNode) -> Option<()> {
     Some(())
 }
 
-pub trait HasVisibilityEdit: ast::HasVisibility {
-    fn set_visibility(&self, visbility: ast::Visibility) {
-        match self.visibility() {
-            Some(current_visibility) => {
-                ted::replace(current_visibility.syntax(), visbility.syntax())
-            }
-            None => {
-                let vis_before = self
-                    .syntax()
-                    .children_with_tokens()
-                    .find(|it| !matches!(it.kind(), WHITESPACE | COMMENT | ATTR))
-                    .unwrap_or_else(|| self.syntax().first_child_or_token().unwrap());
-
-                ted::insert(ted::Position::before(vis_before), visbility.syntax());
-            }
-        }
-    }
-}
-
-impl<T: ast::HasVisibility> HasVisibilityEdit for T {}
-
 pub trait Indent: AstNode + Clone + Sized {
     fn indent_level(&self) -> IndentLevel {
         IndentLevel::from_node(self.syntax())
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs
index bed240a6d7..efbf879664 100644
--- a/crates/syntax/src/lib.rs
+++ b/crates/syntax/src/lib.rs
@@ -171,109 +171,6 @@ impl SourceFile {
     }
 }
 
-impl ast::TokenTree {
-    pub fn reparse_as_expr(self) -> Parse<ast::Expr> {
-        let tokens = self.syntax().descendants_with_tokens().filter_map(NodeOrToken::into_token);
-
-        let mut parser_input = parser::Input::default();
-        let mut was_joint = false;
-        for t in tokens {
-            let kind = t.kind();
-            if kind.is_trivia() {
-                was_joint = false
-            } else {
-                if kind == SyntaxKind::IDENT {
-                    let token_text = t.text();
-                    let contextual_kw = SyntaxKind::from_contextual_keyword(token_text)
-                        .unwrap_or(SyntaxKind::IDENT);
-                    parser_input.push_ident(contextual_kw);
-                } else {
-                    if was_joint {
-                        parser_input.was_joint();
-                    }
-                    parser_input.push(kind);
-                    // Tag the token as joint if it is float with a fractional part
-                    // we use this jointness to inform the parser about what token split
-                    // event to emit when we encounter a float literal in a field access
-                    if kind == SyntaxKind::FLOAT_NUMBER && !t.text().ends_with('.') {
-                        parser_input.was_joint();
-                    }
-                }
-                was_joint = true;
-            }
-        }
-
-        let parser_output = parser::TopEntryPoint::Expr.parse(&parser_input);
-
-        let mut tokens =
-            self.syntax().descendants_with_tokens().filter_map(NodeOrToken::into_token);
-        let mut text = String::new();
-        let mut pos = TextSize::from(0);
-        let mut builder = SyntaxTreeBuilder::default();
-        for event in parser_output.iter() {
-            match event {
-                parser::Step::Token { kind, n_input_tokens } => {
-                    let mut token = tokens.next().unwrap();
-                    while token.kind().is_trivia() {
-                        let text = token.text();
-                        pos += TextSize::from(text.len() as u32);
-                        builder.token(token.kind(), text);
-
-                        token = tokens.next().unwrap();
-                    }
-                    text.push_str(token.text());
-                    for _ in 1..n_input_tokens {
-                        let token = tokens.next().unwrap();
-                        text.push_str(token.text());
-                    }
-
-                    pos += TextSize::from(text.len() as u32);
-                    builder.token(kind, &text);
-                    text.clear();
-                }
-                parser::Step::FloatSplit { ends_in_dot: has_pseudo_dot } => {
-                    let token = tokens.next().unwrap();
-                    let text = token.text();
-
-                    match text.split_once('.') {
-                        Some((left, right)) => {
-                            assert!(!left.is_empty());
-                            builder.start_node(SyntaxKind::NAME_REF);
-                            builder.token(SyntaxKind::INT_NUMBER, left);
-                            builder.finish_node();
-
-                            // here we move the exit up, the original exit has been deleted in process
-                            builder.finish_node();
-
-                            builder.token(SyntaxKind::DOT, ".");
-
-                            if has_pseudo_dot {
-                                assert!(right.is_empty(), "{left}.{right}");
-                            } else {
-                                builder.start_node(SyntaxKind::NAME_REF);
-                                builder.token(SyntaxKind::INT_NUMBER, right);
-                                builder.finish_node();
-
-                                // the parser creates an unbalanced start node, we are required to close it here
-                                builder.finish_node();
-                            }
-                        }
-                        None => unreachable!(),
-                    }
-                    pos += TextSize::from(text.len() as u32);
-                }
-                parser::Step::Enter { kind } => builder.start_node(kind),
-                parser::Step::Exit => builder.finish_node(),
-                parser::Step::Error { msg } => builder.error(msg.to_owned(), pos),
-            }
-        }
-
-        let (green, errors) = builder.finish_raw();
-
-        Parse { green, errors: Arc::new(errors), _ty: PhantomData }
-    }
-}
-
 /// Matches a `SyntaxNode` against an `ast` type.
 ///
 /// # Example:
diff --git a/crates/tt/src/lib.rs b/crates/tt/src/lib.rs
index 1b8d4ba42a..c2ebf03746 100644
--- a/crates/tt/src/lib.rs
+++ b/crates/tt/src/lib.rs
@@ -68,21 +68,6 @@ pub mod token_id {
             Self::Subtree(Subtree { delimiter: Delimiter::unspecified(), token_trees: vec![] })
         }
     }
-
-    impl Subtree {
-        pub fn visit_ids(&mut self, f: &impl Fn(TokenId) -> TokenId) {
-            self.delimiter.open = f(self.delimiter.open);
-            self.delimiter.close = f(self.delimiter.close);
-            self.token_trees.iter_mut().for_each(|tt| match tt {
-                crate::TokenTree::Leaf(leaf) => match leaf {
-                    crate::Leaf::Literal(it) => it.span = f(it.span),
-                    crate::Leaf::Punct(it) => it.span = f(it.span),
-                    crate::Leaf::Ident(it) => it.span = f(it.span),
-                },
-                crate::TokenTree::Subtree(s) => s.visit_ids(f),
-            })
-        }
-    }
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
diff --git a/editors/code/.eslintrc.js b/editors/code/.eslintrc.js
index 9705c5f5ec..297e9fa1e5 100644
--- a/editors/code/.eslintrc.js
+++ b/editors/code/.eslintrc.js
@@ -6,7 +6,7 @@ module.exports = {
     extends: ["prettier"],
     parser: "@typescript-eslint/parser",
     parserOptions: {
-        project: true,
+        project: "tsconfig.eslint.json",
         tsconfigRootDir: __dirname,
         sourceType: "module",
     },
@@ -33,14 +33,5 @@ module.exports = {
         "@typescript-eslint/semi": ["error", "always"],
         "@typescript-eslint/no-unnecessary-type-assertion": "error",
         "@typescript-eslint/no-floating-promises": "error",
-
-        "@typescript-eslint/consistent-type-imports": [
-            "error",
-            {
-                prefer: "type-imports",
-                fixStyle: "inline-type-imports",
-            },
-        ],
-        "@typescript-eslint/no-import-type-side-effects": "error",
     },
 };
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index 1c94f13d74..d99fd8f617 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -19,99 +19,26 @@
                 "@tsconfig/strictest": "^2.0.1",
                 "@types/node": "~16.11.7",
                 "@types/vscode": "~1.78.1",
-                "@typescript-eslint/eslint-plugin": "^6.0.0",
-                "@typescript-eslint/parser": "^6.0.0",
+                "@typescript-eslint/eslint-plugin": "^5.60.1",
+                "@typescript-eslint/parser": "^5.60.1",
                 "@vscode/test-electron": "^2.3.3",
                 "@vscode/vsce": "^2.19.0",
-                "esbuild": "^0.18.12",
-                "eslint": "^8.44.0",
+                "esbuild": "^0.18.10",
+                "eslint": "^8.43.0",
                 "eslint-config-prettier": "^8.8.0",
-                "ovsx": "^0.8.2",
-                "prettier": "^3.0.0",
+                "ovsx": "^0.8.1",
+                "prettier": "^2.8.8",
                 "tslib": "^2.6.0",
-                "typescript": "^5.1.6"
+                "typescript": "^5.1.3"
             },
             "engines": {
                 "vscode": "^1.78.0"
             }
         },
-        "node_modules/@aashutoshrathi/word-wrap": {
-            "version": "1.2.6",
-            "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
-            "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
-            "dev": true,
-            "engines": {
-                "node": ">=0.10.0"
-            }
-        },
-        "node_modules/@esbuild/android-arm": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.12.tgz",
-            "integrity": "sha512-LIxaNIQfkFZbTLb4+cX7dozHlAbAshhFE5PKdro0l+FnCpx1GDJaQ2WMcqm+ToXKMt8p8Uojk/MFRuGyz3V5Sw==",
-            "cpu": [
-                "arm"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "android"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/android-arm64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.12.tgz",
-            "integrity": "sha512-BMAlczRqC/LUt2P97E4apTBbkvS9JTJnp2DKFbCwpZ8vBvXVbNdqmvzW/OsdtI/+mGr+apkkpqGM8WecLkPgrA==",
-            "cpu": [
-                "arm64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "android"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/android-x64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.12.tgz",
-            "integrity": "sha512-zU5MyluNsykf5cOJ0LZZZjgAHbhPJ1cWfdH1ZXVMXxVMhEV0VZiZXQdwBBVvmvbF28EizeK7obG9fs+fpmS0eQ==",
-            "cpu": [
-                "x64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "android"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/darwin-arm64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.12.tgz",
-            "integrity": "sha512-zUZMep7YONnp6954QOOwEBwFX9svlKd3ov6PkxKd53LGTHsp/gy7vHaPGhhjBmEpqXEXShi6dddjIkmd+NgMsA==",
-            "cpu": [
-                "arm64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "darwin"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
         "node_modules/@esbuild/darwin-x64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.12.tgz",
-            "integrity": "sha512-ohqLPc7i67yunArPj1+/FeeJ7AgwAjHqKZ512ADk3WsE3FHU9l+m5aa7NdxXr0HmN1bjDlUslBjWNbFlD9y12Q==",
+            "version": "0.18.10",
+            "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.10.tgz",
+            "integrity": "sha512-tnz/mdZk1L1Z3WpGjin/L2bKTe8/AKZpI8fcCLtH+gq8WXWsCNJSxlesAObV4qbtTl6pG5vmqFXfWUQ5hV8PAQ==",
             "cpu": [
                 "x64"
             ],
@@ -124,278 +51,6 @@
                 "node": ">=12"
             }
         },
-        "node_modules/@esbuild/freebsd-arm64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.12.tgz",
-            "integrity": "sha512-GIIHtQXqgeOOqdG16a/A9N28GpkvjJnjYMhOnXVbn3EDJcoItdR58v/pGN31CHjyXDc8uCcRnFWmqaJt24AYJg==",
-            "cpu": [
-                "arm64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "freebsd"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/freebsd-x64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.12.tgz",
-            "integrity": "sha512-zK0b9a1/0wZY+6FdOS3BpZcPc1kcx2G5yxxfEJtEUzVxI6n/FrC2Phsxj/YblPuBchhBZ/1wwn7AyEBUyNSa6g==",
-            "cpu": [
-                "x64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "freebsd"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/linux-arm": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.12.tgz",
-            "integrity": "sha512-y75OijvrBE/1XRrXq1jtrJfG26eHeMoqLJ2dwQNwviwTuTtHGCojsDO6BJNF8gU+3jTn1KzJEMETytwsFSvc+Q==",
-            "cpu": [
-                "arm"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "linux"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/linux-arm64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.12.tgz",
-            "integrity": "sha512-JKgG8Q/LL/9sw/iHHxQyVMoQYu3rU3+a5Z87DxC+wAu3engz+EmctIrV+FGOgI6gWG1z1+5nDDbXiRMGQZXqiw==",
-            "cpu": [
-                "arm64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "linux"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/linux-ia32": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.12.tgz",
-            "integrity": "sha512-yoRIAqc0B4lDIAAEFEIu9ttTRFV84iuAl0KNCN6MhKLxNPfzwCBvEMgwco2f71GxmpBcTtn7KdErueZaM2rEvw==",
-            "cpu": [
-                "ia32"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "linux"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/linux-loong64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.12.tgz",
-            "integrity": "sha512-qYgt3dHPVvf/MgbIBpJ4Sup/yb9DAopZ3a2JgMpNKIHUpOdnJ2eHBo/aQdnd8dJ21X/+sS58wxHtA9lEazYtXQ==",
-            "cpu": [
-                "loong64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "linux"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/linux-mips64el": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.12.tgz",
-            "integrity": "sha512-wHphlMLK4ufNOONqukELfVIbnGQJrHJ/mxZMMrP2jYrPgCRZhOtf0kC4yAXBwnfmULimV1qt5UJJOw4Kh13Yfg==",
-            "cpu": [
-                "mips64el"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "linux"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/linux-ppc64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.12.tgz",
-            "integrity": "sha512-TeN//1Ft20ZZW41+zDSdOI/Os1bEq5dbvBvYkberB7PHABbRcsteeoNVZFlI0YLpGdlBqohEpjrn06kv8heCJg==",
-            "cpu": [
-                "ppc64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "linux"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/linux-riscv64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.12.tgz",
-            "integrity": "sha512-AgUebVS4DoAblBgiB2ACQ/8l4eGE5aWBb8ZXtkXHiET9mbj7GuWt3OnsIW/zX+XHJt2RYJZctbQ2S/mDjbp0UA==",
-            "cpu": [
-                "riscv64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "linux"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/linux-s390x": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.12.tgz",
-            "integrity": "sha512-dJ3Rb3Ei2u/ysSXd6pzleGtfDdc2MuzKt8qc6ls8vreP1G3B7HInX3i7gXS4BGeVd24pp0yqyS7bJ5NHaI9ing==",
-            "cpu": [
-                "s390x"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "linux"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/linux-x64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.12.tgz",
-            "integrity": "sha512-OrNJMGQbPaVyHHcDF8ybNSwu7TDOfX8NGpXCbetwOSP6txOJiWlgQnRymfC9ocR1S0Y5PW0Wb1mV6pUddqmvmQ==",
-            "cpu": [
-                "x64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "linux"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/netbsd-x64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.12.tgz",
-            "integrity": "sha512-55FzVCAiwE9FK8wWeCRuvjazNRJ1QqLCYGZVB6E8RuQuTeStSwotpSW4xoRGwp3a1wUsaVCdYcj5LGCASVJmMg==",
-            "cpu": [
-                "x64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "netbsd"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/openbsd-x64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.12.tgz",
-            "integrity": "sha512-qnluf8rfb6Y5Lw2tirfK2quZOBbVqmwxut7GPCIJsM8lc4AEUj9L8y0YPdLaPK0TECt4IdyBdBD/KRFKorlK3g==",
-            "cpu": [
-                "x64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "openbsd"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/sunos-x64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.12.tgz",
-            "integrity": "sha512-+RkKpVQR7bICjTOPUpkTBTaJ4TFqQBX5Ywyd/HSdDkQGn65VPkTsR/pL4AMvuMWy+wnXgIl4EY6q4mVpJal8Kg==",
-            "cpu": [
-                "x64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "sunos"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/win32-arm64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.12.tgz",
-            "integrity": "sha512-GNHuciv0mFM7ouzsU0+AwY+7eV4Mgo5WnbhfDCQGtpvOtD1vbOiRjPYG6dhmMoFyBjj+pNqQu2X+7DKn0KQ/Gw==",
-            "cpu": [
-                "arm64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "win32"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/win32-ia32": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.12.tgz",
-            "integrity": "sha512-kR8cezhYipbbypGkaqCTWIeu4zID17gamC8YTPXYtcN3E5BhhtTnwKBn9I0PJur/T6UVwIEGYzkffNL0lFvxEw==",
-            "cpu": [
-                "ia32"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "win32"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
-        "node_modules/@esbuild/win32-x64": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.12.tgz",
-            "integrity": "sha512-O0UYQVkvfM/jO8a4OwoV0mAKSJw+mjWTAd1MJd/1FCX6uiMdLmMRPK/w6e9OQ0ob2WGxzIm9va/KG0Ja4zIOgg==",
-            "cpu": [
-                "x64"
-            ],
-            "dev": true,
-            "optional": true,
-            "os": [
-                "win32"
-            ],
-            "engines": {
-                "node": ">=12"
-            }
-        },
         "node_modules/@eslint-community/eslint-utils": {
             "version": "4.4.0",
             "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -421,14 +76,14 @@
             }
         },
         "node_modules/@eslint/eslintrc": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz",
-            "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==",
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
+            "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
             "dev": true,
             "dependencies": {
                 "ajv": "^6.12.4",
                 "debug": "^4.3.2",
-                "espree": "^9.6.0",
+                "espree": "^9.5.2",
                 "globals": "^13.19.0",
                 "ignore": "^5.2.0",
                 "import-fresh": "^3.2.1",
@@ -444,9 +99,9 @@
             }
         },
         "node_modules/@eslint/js": {
-            "version": "8.44.0",
-            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz",
-            "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==",
+            "version": "8.43.0",
+            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz",
+            "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==",
             "dev": true,
             "engines": {
                 "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -571,35 +226,32 @@
             "dev": true
         },
         "node_modules/@typescript-eslint/eslint-plugin": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz",
-            "integrity": "sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==",
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz",
+            "integrity": "sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==",
             "dev": true,
             "dependencies": {
-                "@eslint-community/regexpp": "^4.5.0",
-                "@typescript-eslint/scope-manager": "6.0.0",
-                "@typescript-eslint/type-utils": "6.0.0",
-                "@typescript-eslint/utils": "6.0.0",
-                "@typescript-eslint/visitor-keys": "6.0.0",
+                "@eslint-community/regexpp": "^4.4.0",
+                "@typescript-eslint/scope-manager": "5.60.1",
+                "@typescript-eslint/type-utils": "5.60.1",
+                "@typescript-eslint/utils": "5.60.1",
                 "debug": "^4.3.4",
                 "grapheme-splitter": "^1.0.4",
-                "graphemer": "^1.4.0",
-                "ignore": "^5.2.4",
-                "natural-compare": "^1.4.0",
+                "ignore": "^5.2.0",
                 "natural-compare-lite": "^1.4.0",
-                "semver": "^7.5.0",
-                "ts-api-utils": "^1.0.1"
+                "semver": "^7.3.7",
+                "tsutils": "^3.21.0"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
-                "eslint": "^7.0.0 || ^8.0.0"
+                "@typescript-eslint/parser": "^5.0.0",
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
             },
             "peerDependenciesMeta": {
                 "typescript": {
@@ -608,26 +260,25 @@
             }
         },
         "node_modules/@typescript-eslint/parser": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.0.0.tgz",
-            "integrity": "sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==",
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz",
+            "integrity": "sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/scope-manager": "6.0.0",
-                "@typescript-eslint/types": "6.0.0",
-                "@typescript-eslint/typescript-estree": "6.0.0",
-                "@typescript-eslint/visitor-keys": "6.0.0",
+                "@typescript-eslint/scope-manager": "5.60.1",
+                "@typescript-eslint/types": "5.60.1",
+                "@typescript-eslint/typescript-estree": "5.60.1",
                 "debug": "^4.3.4"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "eslint": "^7.0.0 || ^8.0.0"
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
             },
             "peerDependenciesMeta": {
                 "typescript": {
@@ -636,16 +287,16 @@
             }
         },
         "node_modules/@typescript-eslint/scope-manager": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.0.0.tgz",
-            "integrity": "sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==",
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz",
+            "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/types": "6.0.0",
-                "@typescript-eslint/visitor-keys": "6.0.0"
+                "@typescript-eslint/types": "5.60.1",
+                "@typescript-eslint/visitor-keys": "5.60.1"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -653,25 +304,25 @@
             }
         },
         "node_modules/@typescript-eslint/type-utils": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.0.0.tgz",
-            "integrity": "sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==",
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz",
+            "integrity": "sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/typescript-estree": "6.0.0",
-                "@typescript-eslint/utils": "6.0.0",
+                "@typescript-eslint/typescript-estree": "5.60.1",
+                "@typescript-eslint/utils": "5.60.1",
                 "debug": "^4.3.4",
-                "ts-api-utils": "^1.0.1"
+                "tsutils": "^3.21.0"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "eslint": "^7.0.0 || ^8.0.0"
+                "eslint": "*"
             },
             "peerDependenciesMeta": {
                 "typescript": {
@@ -680,12 +331,12 @@
             }
         },
         "node_modules/@typescript-eslint/types": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.0.0.tgz",
-            "integrity": "sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==",
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz",
+            "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==",
             "dev": true,
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -693,21 +344,21 @@
             }
         },
         "node_modules/@typescript-eslint/typescript-estree": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.0.0.tgz",
-            "integrity": "sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==",
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz",
+            "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/types": "6.0.0",
-                "@typescript-eslint/visitor-keys": "6.0.0",
+                "@typescript-eslint/types": "5.60.1",
+                "@typescript-eslint/visitor-keys": "5.60.1",
                 "debug": "^4.3.4",
                 "globby": "^11.1.0",
                 "is-glob": "^4.0.3",
-                "semver": "^7.5.0",
-                "ts-api-utils": "^1.0.1"
+                "semver": "^7.3.7",
+                "tsutils": "^3.21.0"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -720,42 +371,42 @@
             }
         },
         "node_modules/@typescript-eslint/utils": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.0.0.tgz",
-            "integrity": "sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==",
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.1.tgz",
+            "integrity": "sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==",
             "dev": true,
             "dependencies": {
-                "@eslint-community/eslint-utils": "^4.3.0",
-                "@types/json-schema": "^7.0.11",
+                "@eslint-community/eslint-utils": "^4.2.0",
+                "@types/json-schema": "^7.0.9",
                 "@types/semver": "^7.3.12",
-                "@typescript-eslint/scope-manager": "6.0.0",
-                "@typescript-eslint/types": "6.0.0",
-                "@typescript-eslint/typescript-estree": "6.0.0",
+                "@typescript-eslint/scope-manager": "5.60.1",
+                "@typescript-eslint/types": "5.60.1",
+                "@typescript-eslint/typescript-estree": "5.60.1",
                 "eslint-scope": "^5.1.1",
-                "semver": "^7.5.0"
+                "semver": "^7.3.7"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "eslint": "^7.0.0 || ^8.0.0"
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
             }
         },
         "node_modules/@typescript-eslint/visitor-keys": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz",
-            "integrity": "sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==",
+            "version": "5.60.1",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz",
+            "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==",
             "dev": true,
             "dependencies": {
-                "@typescript-eslint/types": "6.0.0",
-                "eslint-visitor-keys": "^3.4.1"
+                "@typescript-eslint/types": "5.60.1",
+                "eslint-visitor-keys": "^3.3.0"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -883,9 +534,9 @@
             }
         },
         "node_modules/@vscode/vsce/node_modules/semver": {
-            "version": "5.7.2",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
-            "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+            "version": "5.7.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+            "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
             "dev": true,
             "bin": {
                 "semver": "bin/semver"
@@ -917,9 +568,9 @@
             }
         },
         "node_modules/acorn": {
-            "version": "8.10.0",
-            "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
-            "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+            "version": "8.9.0",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz",
+            "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==",
             "dev": true,
             "bin": {
                 "acorn": "bin/acorn"
@@ -1905,9 +1556,9 @@
             }
         },
         "node_modules/esbuild": {
-            "version": "0.18.12",
-            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.12.tgz",
-            "integrity": "sha512-XuOVLDdtsDslXStStduT41op21Ytmf4/BDS46aa3xPJ7X5h2eMWBF1oAe3QjUH3bDksocNXgzGUZ7XHIBya6Tg==",
+            "version": "0.18.10",
+            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.10.tgz",
+            "integrity": "sha512-33WKo67auOXzZHBY/9DTJRo7kIvfU12S+D4sp2wIz39N88MDIaCGyCwbW01RR70pK6Iya0I74lHEpyLfFqOHPA==",
             "dev": true,
             "hasInstallScript": true,
             "bin": {
@@ -1917,28 +1568,28 @@
                 "node": ">=12"
             },
             "optionalDependencies": {
-                "@esbuild/android-arm": "0.18.12",
-                "@esbuild/android-arm64": "0.18.12",
-                "@esbuild/android-x64": "0.18.12",
-                "@esbuild/darwin-arm64": "0.18.12",
-                "@esbuild/darwin-x64": "0.18.12",
-                "@esbuild/freebsd-arm64": "0.18.12",
-                "@esbuild/freebsd-x64": "0.18.12",
-                "@esbuild/linux-arm": "0.18.12",
-                "@esbuild/linux-arm64": "0.18.12",
-                "@esbuild/linux-ia32": "0.18.12",
-                "@esbuild/linux-loong64": "0.18.12",
-                "@esbuild/linux-mips64el": "0.18.12",
-                "@esbuild/linux-ppc64": "0.18.12",
-                "@esbuild/linux-riscv64": "0.18.12",
-                "@esbuild/linux-s390x": "0.18.12",
-                "@esbuild/linux-x64": "0.18.12",
-                "@esbuild/netbsd-x64": "0.18.12",
-                "@esbuild/openbsd-x64": "0.18.12",
-                "@esbuild/sunos-x64": "0.18.12",
-                "@esbuild/win32-arm64": "0.18.12",
-                "@esbuild/win32-ia32": "0.18.12",
-                "@esbuild/win32-x64": "0.18.12"
+                "@esbuild/android-arm": "0.18.10",
+                "@esbuild/android-arm64": "0.18.10",
+                "@esbuild/android-x64": "0.18.10",
+                "@esbuild/darwin-arm64": "0.18.10",
+                "@esbuild/darwin-x64": "0.18.10",
+                "@esbuild/freebsd-arm64": "0.18.10",
+                "@esbuild/freebsd-x64": "0.18.10",
+                "@esbuild/linux-arm": "0.18.10",
+                "@esbuild/linux-arm64": "0.18.10",
+                "@esbuild/linux-ia32": "0.18.10",
+                "@esbuild/linux-loong64": "0.18.10",
+                "@esbuild/linux-mips64el": "0.18.10",
+                "@esbuild/linux-ppc64": "0.18.10",
+                "@esbuild/linux-riscv64": "0.18.10",
+                "@esbuild/linux-s390x": "0.18.10",
+                "@esbuild/linux-x64": "0.18.10",
+                "@esbuild/netbsd-x64": "0.18.10",
+                "@esbuild/openbsd-x64": "0.18.10",
+                "@esbuild/sunos-x64": "0.18.10",
+                "@esbuild/win32-arm64": "0.18.10",
+                "@esbuild/win32-ia32": "0.18.10",
+                "@esbuild/win32-x64": "0.18.10"
             }
         },
         "node_modules/escalade": {
@@ -1962,15 +1613,15 @@
             }
         },
         "node_modules/eslint": {
-            "version": "8.44.0",
-            "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz",
-            "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==",
+            "version": "8.43.0",
+            "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz",
+            "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==",
             "dev": true,
             "dependencies": {
                 "@eslint-community/eslint-utils": "^4.2.0",
                 "@eslint-community/regexpp": "^4.4.0",
-                "@eslint/eslintrc": "^2.1.0",
-                "@eslint/js": "8.44.0",
+                "@eslint/eslintrc": "^2.0.3",
+                "@eslint/js": "8.43.0",
                 "@humanwhocodes/config-array": "^0.11.10",
                 "@humanwhocodes/module-importer": "^1.0.1",
                 "@nodelib/fs.walk": "^1.2.8",
@@ -1982,7 +1633,7 @@
                 "escape-string-regexp": "^4.0.0",
                 "eslint-scope": "^7.2.0",
                 "eslint-visitor-keys": "^3.4.1",
-                "espree": "^9.6.0",
+                "espree": "^9.5.2",
                 "esquery": "^1.4.2",
                 "esutils": "^2.0.2",
                 "fast-deep-equal": "^3.1.3",
@@ -2002,7 +1653,7 @@
                 "lodash.merge": "^4.6.2",
                 "minimatch": "^3.1.2",
                 "natural-compare": "^1.4.0",
-                "optionator": "^0.9.3",
+                "optionator": "^0.9.1",
                 "strip-ansi": "^6.0.1",
                 "strip-json-comments": "^3.1.0",
                 "text-table": "^0.2.0"
@@ -2080,12 +1731,12 @@
             }
         },
         "node_modules/espree": {
-            "version": "9.6.0",
-            "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz",
-            "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==",
+            "version": "9.5.2",
+            "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
+            "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
             "dev": true,
             "dependencies": {
-                "acorn": "^8.9.0",
+                "acorn": "^8.8.0",
                 "acorn-jsx": "^5.3.2",
                 "eslint-visitor-keys": "^3.4.1"
             },
@@ -2173,9 +1824,9 @@
             "dev": true
         },
         "node_modules/fast-glob": {
-            "version": "3.3.0",
-            "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz",
-            "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==",
+            "version": "3.2.12",
+            "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
+            "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
             "dev": true,
             "dependencies": {
                 "@nodelib/fs.stat": "^2.0.2",
@@ -3016,34 +2667,34 @@
             }
         },
         "node_modules/optionator": {
-            "version": "0.9.3",
-            "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
-            "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+            "version": "0.9.1",
+            "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+            "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
             "dev": true,
             "dependencies": {
-                "@aashutoshrathi/word-wrap": "^1.2.3",
                 "deep-is": "^0.1.3",
                 "fast-levenshtein": "^2.0.6",
                 "levn": "^0.4.1",
                 "prelude-ls": "^1.2.1",
-                "type-check": "^0.4.0"
+                "type-check": "^0.4.0",
+                "word-wrap": "^1.2.3"
             },
             "engines": {
                 "node": ">= 0.8.0"
             }
         },
         "node_modules/ovsx": {
-            "version": "0.8.2",
-            "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.8.2.tgz",
-            "integrity": "sha512-btDXZorXlmwN9+9Un3khrVygCXmhwbrtg8gifNXw92rZPXcRBAiLG/L09Kb6srhGEratsFt42AktfD8t9XhzoA==",
+            "version": "0.8.1",
+            "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.8.1.tgz",
+            "integrity": "sha512-smfdxuSScUwzEsNgxdEWTmWVYaRmb2Xa1qF/LadMtowq/gg01+zNxDGUAlqALin82RBj++IF0O+qrzrC10O7ww==",
             "dev": true,
             "dependencies": {
-                "@vscode/vsce": "^2.19.0",
+                "@vscode/vsce": "^2.15.0",
                 "commander": "^6.1.0",
                 "follow-redirects": "^1.14.6",
                 "is-ci": "^2.0.0",
                 "leven": "^3.1.0",
-                "semver": "^7.5.2",
+                "semver": "^5.1.0",
                 "tmp": "^0.2.1"
             },
             "bin": {
@@ -3062,6 +2713,15 @@
                 "node": ">= 6"
             }
         },
+        "node_modules/ovsx/node_modules/semver": {
+            "version": "5.7.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+            "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+            "dev": true,
+            "bin": {
+                "semver": "bin/semver"
+            }
+        },
         "node_modules/p-limit": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -3120,9 +2780,9 @@
             }
         },
         "node_modules/parse-semver/node_modules/semver": {
-            "version": "5.7.2",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
-            "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+            "version": "5.7.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+            "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
             "dev": true,
             "bin": {
                 "semver": "bin/semver"
@@ -3244,15 +2904,15 @@
             }
         },
         "node_modules/prettier": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz",
-            "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==",
+            "version": "2.8.8",
+            "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+            "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
             "dev": true,
             "bin": {
-                "prettier": "bin/prettier.cjs"
+                "prettier": "bin-prettier.js"
             },
             "engines": {
-                "node": ">=14"
+                "node": ">=10.13.0"
             },
             "funding": {
                 "url": "https://github.com/prettier/prettier?sponsor=1"
@@ -3465,9 +3125,9 @@
             "dev": true
         },
         "node_modules/semver": {
-            "version": "7.5.4",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-            "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+            "version": "7.3.8",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+            "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
             "dependencies": {
                 "lru-cache": "^6.0.0"
             },
@@ -3707,22 +3367,31 @@
                 "node": ">=8.0"
             }
         },
-        "node_modules/ts-api-utils": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz",
-            "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==",
+        "node_modules/tslib": {
+            "version": "2.6.0",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
+            "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==",
+            "dev": true
+        },
+        "node_modules/tsutils": {
+            "version": "3.21.0",
+            "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
+            "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
             "dev": true,
+            "dependencies": {
+                "tslib": "^1.8.1"
+            },
             "engines": {
-                "node": ">=16.13.0"
+                "node": ">= 6"
             },
             "peerDependencies": {
-                "typescript": ">=4.2.0"
+                "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
             }
         },
-        "node_modules/tslib": {
-            "version": "2.6.0",
-            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
-            "integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==",
+        "node_modules/tsutils/node_modules/tslib": {
+            "version": "1.14.1",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+            "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
             "dev": true
         },
         "node_modules/tunnel": {
@@ -3783,9 +3452,9 @@
             }
         },
         "node_modules/typescript": {
-            "version": "5.1.6",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
-            "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
+            "version": "5.1.3",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz",
+            "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==",
             "dev": true,
             "bin": {
                 "tsc": "bin/tsc",
@@ -3897,6 +3566,15 @@
                 "node": ">= 8"
             }
         },
+        "node_modules/word-wrap": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+            "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
         "node_modules/wrap-ansi": {
             "version": "7.0.0",
             "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
diff --git a/editors/code/package.json b/editors/code/package.json
index ffb5dd9079..cd8b40e355 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -51,17 +51,17 @@
         "@tsconfig/strictest": "^2.0.1",
         "@types/node": "~16.11.7",
         "@types/vscode": "~1.78.1",
-        "@typescript-eslint/eslint-plugin": "^6.0.0",
-        "@typescript-eslint/parser": "^6.0.0",
+        "@typescript-eslint/eslint-plugin": "^5.60.1",
+        "@typescript-eslint/parser": "^5.60.1",
         "@vscode/test-electron": "^2.3.3",
         "@vscode/vsce": "^2.19.0",
-        "esbuild": "^0.18.12",
-        "eslint": "^8.44.0",
+        "esbuild": "^0.18.10",
+        "eslint": "^8.43.0",
         "eslint-config-prettier": "^8.8.0",
-        "ovsx": "^0.8.2",
-        "prettier": "^3.0.0",
+        "ovsx": "^0.8.1",
+        "prettier": "^2.8.8",
         "tslib": "^2.6.0",
-        "typescript": "^5.1.6"
+        "typescript": "^5.1.3"
     },
     "activationEvents": [
         "workspaceContains:*/Cargo.toml",
diff --git a/editors/code/src/ast_inspector.ts b/editors/code/src/ast_inspector.ts
index 688c53a9b1..fa963d8eb9 100644
--- a/editors/code/src/ast_inspector.ts
+++ b/editors/code/src/ast_inspector.ts
@@ -1,7 +1,7 @@
 import * as vscode from "vscode";
 
-import type { Ctx, Disposable } from "./ctx";
-import { type RustEditor, isRustEditor } from "./util";
+import { Ctx, Disposable } from "./ctx";
+import { RustEditor, isRustEditor } from "./util";
 import { unwrapUndefinable } from "./undefinable";
 
 // FIXME: consider implementing this via the Tree View API?
@@ -37,23 +37,23 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
 
     constructor(ctx: Ctx) {
         ctx.pushExtCleanup(
-            vscode.languages.registerHoverProvider({ scheme: "rust-analyzer" }, this),
+            vscode.languages.registerHoverProvider({ scheme: "rust-analyzer" }, this)
         );
         ctx.pushExtCleanup(vscode.languages.registerDefinitionProvider({ language: "rust" }, this));
         vscode.workspace.onDidCloseTextDocument(
             this.onDidCloseTextDocument,
             this,
-            ctx.subscriptions,
+            ctx.subscriptions
         );
         vscode.workspace.onDidChangeTextDocument(
             this.onDidChangeTextDocument,
             this,
-            ctx.subscriptions,
+            ctx.subscriptions
         );
         vscode.window.onDidChangeVisibleTextEditors(
             this.onDidChangeVisibleTextEditors,
             this,
-            ctx.subscriptions,
+            ctx.subscriptions
         );
     }
     dispose() {
@@ -85,7 +85,7 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
 
     private findAstTextEditor(): undefined | vscode.TextEditor {
         return vscode.window.visibleTextEditors.find(
-            (it) => it.document.uri.scheme === "rust-analyzer",
+            (it) => it.document.uri.scheme === "rust-analyzer"
         );
     }
 
@@ -100,7 +100,7 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
     // additional positional params are omitted
     provideDefinition(
         doc: vscode.TextDocument,
-        pos: vscode.Position,
+        pos: vscode.Position
     ): vscode.ProviderResult<vscode.DefinitionLink[]> {
         if (!this.rustEditor || doc.uri.toString() !== this.rustEditor.document.uri.toString()) {
             return;
@@ -132,7 +132,7 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
     // additional positional params are omitted
     provideHover(
         doc: vscode.TextDocument,
-        hoverPosition: vscode.Position,
+        hoverPosition: vscode.Position
     ): vscode.ProviderResult<vscode.Hover> {
         if (!this.rustEditor) return;
 
@@ -159,7 +159,7 @@ export class AstInspector implements vscode.HoverProvider, vscode.DefinitionProv
 
     private parseRustTextRange(
         doc: vscode.TextDocument,
-        astLine: string,
+        astLine: string
     ): undefined | vscode.Range {
         const parsedRange = /(\d+)\.\.(\d+)/.exec(astLine);
         if (!parsedRange) return;
diff --git a/editors/code/src/bootstrap.ts b/editors/code/src/bootstrap.ts
index ef4dff095c..7b831a8a69 100644
--- a/editors/code/src/bootstrap.ts
+++ b/editors/code/src/bootstrap.ts
@@ -1,20 +1,20 @@
 import * as vscode from "vscode";
 import * as os from "os";
-import type { Config } from "./config";
+import { Config } from "./config";
 import { log, isValidExecutable } from "./util";
-import type { PersistentState } from "./persistent_state";
+import { PersistentState } from "./persistent_state";
 import { exec } from "child_process";
 
 export async function bootstrap(
     context: vscode.ExtensionContext,
     config: Config,
-    state: PersistentState,
+    state: PersistentState
 ): Promise<string> {
     const path = await getServer(context, config, state);
     if (!path) {
         throw new Error(
             "Rust Analyzer Language Server is not available. " +
-                "Please, ensure its [proper installation](https://rust-analyzer.github.io/manual.html#installation).",
+                "Please, ensure its [proper installation](https://rust-analyzer.github.io/manual.html#installation)."
         );
     }
 
@@ -34,7 +34,7 @@ export async function bootstrap(
 async function getServer(
     context: vscode.ExtensionContext,
     config: Config,
-    state: PersistentState,
+    state: PersistentState
 ): Promise<string | undefined> {
     const explicitPath = process.env["__RA_LSP_SERVER_DEBUG"] ?? config.serverPath;
     if (explicitPath) {
@@ -49,7 +49,7 @@ async function getServer(
     const bundled = vscode.Uri.joinPath(context.extensionUri, "server", `rust-analyzer${ext}`);
     const bundledExists = await vscode.workspace.fs.stat(bundled).then(
         () => true,
-        () => false,
+        () => false
     );
     if (bundledExists) {
         let server = bundled;
@@ -58,7 +58,7 @@ async function getServer(
             const dest = vscode.Uri.joinPath(config.globalStorageUri, `rust-analyzer${ext}`);
             let exists = await vscode.workspace.fs.stat(dest).then(
                 () => true,
-                () => false,
+                () => false
             );
             if (exists && config.package.version !== state.serverVersion) {
                 await vscode.workspace.fs.delete(dest);
@@ -81,7 +81,7 @@ async function getServer(
             "run `cargo xtask install --server` to build the language server from sources. " +
             "If you feel that your platform should be supported, please create an issue " +
             "about that [here](https://github.com/rust-lang/rust-analyzer/issues) and we " +
-            "will consider it.",
+            "will consider it."
     );
     return undefined;
 }
@@ -131,7 +131,7 @@ async function patchelf(dest: vscode.Uri): Promise<void> {
                             } else {
                                 resolve(stdout);
                             }
-                        },
+                        }
                     );
                     handle.stdin?.write(expression);
                     handle.stdin?.end();
@@ -139,6 +139,6 @@ async function patchelf(dest: vscode.Uri): Promise<void> {
             } finally {
                 await vscode.workspace.fs.delete(origFile);
             }
-        },
+        }
     );
 }
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index ba8546763e..7b151c804a 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -6,7 +6,7 @@ import * as Is from "vscode-languageclient/lib/common/utils/is";
 import { assert } from "./util";
 import * as diagnostics from "./diagnostics";
 import { WorkspaceEdit } from "vscode";
-import { type Config, prepareVSCodeConfig } from "./config";
+import { Config, prepareVSCodeConfig } from "./config";
 import { randomUUID } from "crypto";
 import { sep as pathSeparator } from "path";
 import { unwrapUndefinable } from "./undefinable";
@@ -34,24 +34,21 @@ export const LINKED_COMMANDS = new Map<string, ra.CommandLink>();
 // add code to remove a target command from the map after the link is
 // clicked, but assuming most links in hover sheets won't be clicked anyway
 // this code won't change the overall memory use much.
-setInterval(
-    function cleanupOlderCommandLinks() {
-        // keys are returned in insertion order, we'll keep a few
-        // of recent keys available, and clean the rest
-        const keys = [...LINKED_COMMANDS.keys()];
-        const keysToRemove = keys.slice(0, keys.length - 10);
-        for (const key of keysToRemove) {
-            LINKED_COMMANDS.delete(key);
-        }
-    },
-    10 * 60 * 1000,
-);
+setInterval(function cleanupOlderCommandLinks() {
+    // keys are returned in insertion order, we'll keep a few
+    // of recent keys available, and clean the rest
+    const keys = [...LINKED_COMMANDS.keys()];
+    const keysToRemove = keys.slice(0, keys.length - 10);
+    for (const key of keysToRemove) {
+        LINKED_COMMANDS.delete(key);
+    }
+}, 10 * 60 * 1000);
 
 function renderCommand(cmd: ra.CommandLink): string {
     const commandId = randomUUID();
     LINKED_COMMANDS.set(commandId, cmd);
     return `[${cmd.title}](command:rust-analyzer.linkToCommand?${encodeURIComponent(
-        JSON.stringify([commandId]),
+        JSON.stringify([commandId])
     )} '${cmd.tooltip}')`;
 }
 
@@ -60,7 +57,7 @@ function renderHoverActions(actions: ra.CommandLinkGroup[]): vscode.MarkdownStri
         .map(
             (group) =>
                 (group.title ? group.title + " " : "") +
-                group.commands.map(renderCommand).join(" | "),
+                group.commands.map(renderCommand).join(" | ")
         )
         .join("___");
 
@@ -75,7 +72,7 @@ export async function createClient(
     initializationOptions: vscode.WorkspaceConfiguration,
     serverOptions: lc.ServerOptions,
     config: Config,
-    unlinkedFiles: vscode.Uri[],
+    unlinkedFiles: vscode.Uri[]
 ): Promise<lc.LanguageClient> {
     const clientOptions: lc.LanguageClientOptions = {
         documentSelector: [{ scheme: "file", language: "rust" }],
@@ -96,7 +93,7 @@ export async function createClient(
                 async configuration(
                     params: lc.ConfigurationParams,
                     token: vscode.CancellationToken,
-                    next: lc.ConfigurationRequest.HandlerSignature,
+                    next: lc.ConfigurationRequest.HandlerSignature
                 ) {
                     const resp = await next(params, token);
                     if (resp && Array.isArray(resp)) {
@@ -120,7 +117,7 @@ export async function createClient(
             async handleDiagnostics(
                 uri: vscode.Uri,
                 diagnosticList: vscode.Diagnostic[],
-                next: lc.HandleDiagnosticsSignature,
+                next: lc.HandleDiagnosticsSignature
             ) {
                 const preview = config.previewRustcOutput;
                 const errorCode = config.useRustcErrorCode;
@@ -140,20 +137,20 @@ export async function createClient(
                             const folder = vscode.workspace.getWorkspaceFolder(uri)?.uri.fsPath;
                             if (folder) {
                                 const parentBackslash = uri.fsPath.lastIndexOf(
-                                    pathSeparator + "src",
+                                    pathSeparator + "src"
                                 );
                                 const parent = uri.fsPath.substring(0, parentBackslash);
 
                                 if (parent.startsWith(folder)) {
                                     const path = vscode.Uri.file(
-                                        parent + pathSeparator + "Cargo.toml",
+                                        parent + pathSeparator + "Cargo.toml"
                                     );
                                     void vscode.workspace.fs.stat(path).then(async () => {
                                         const choice = await vscode.window.showInformationMessage(
                                             `This rust file does not belong to a loaded cargo project. It looks like it might belong to the workspace at ${path.path}, do you want to add it to the linked Projects?`,
                                             "Yes",
                                             "No",
-                                            "Don't show this again",
+                                            "Don't show this again"
                                         );
                                         switch (choice) {
                                             case undefined:
@@ -171,14 +168,14 @@ export async function createClient(
                                                     config
                                                         .get<any[]>("linkedProjects")
                                                         ?.concat(pathToInsert),
-                                                    false,
+                                                    false
                                                 );
                                                 break;
                                             case "Don't show this again":
                                                 await config.update(
                                                     "showUnlinkedFileNotification",
                                                     false,
-                                                    false,
+                                                    false
                                                 );
                                                 break;
                                         }
@@ -225,7 +222,7 @@ export async function createClient(
                 document: vscode.TextDocument,
                 position: vscode.Position,
                 token: vscode.CancellationToken,
-                _next: lc.ProvideHoverSignature,
+                _next: lc.ProvideHoverSignature
             ) {
                 const editor = vscode.window.activeTextEditor;
                 const positionOrRange = editor?.selection?.contains(position)
@@ -239,7 +236,7 @@ export async function createClient(
                                 client.code2ProtocolConverter.asTextDocumentIdentifier(document),
                             position: positionOrRange,
                         },
-                        token,
+                        token
                     )
                     .then(
                         (result) => {
@@ -253,7 +250,7 @@ export async function createClient(
                         (error) => {
                             client.handleFailedRequest(lc.HoverRequest.type, token, error, null);
                             return Promise.resolve(null);
-                        },
+                        }
                     );
             },
             // Using custom handling of CodeActions to support action groups and snippet edits.
@@ -263,14 +260,14 @@ export async function createClient(
                 range: vscode.Range,
                 context: vscode.CodeActionContext,
                 token: vscode.CancellationToken,
-                _next: lc.ProvideCodeActionsSignature,
+                _next: lc.ProvideCodeActionsSignature
             ) {
                 const params: lc.CodeActionParams = {
                     textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
                     range: client.code2ProtocolConverter.asRange(range),
                     context: await client.code2ProtocolConverter.asCodeActionContext(
                         context,
-                        token,
+                        token
                     ),
                 };
                 return client.sendRequest(lc.CodeActionRequest.type, params, token).then(
@@ -286,21 +283,21 @@ export async function createClient(
                             if (lc.CodeAction.is(item)) {
                                 assert(
                                     !item.command,
-                                    "We don't expect to receive commands in CodeActions",
+                                    "We don't expect to receive commands in CodeActions"
                                 );
                                 const action = await client.protocol2CodeConverter.asCodeAction(
                                     item,
-                                    token,
+                                    token
                                 );
                                 result.push(action);
                                 continue;
                             }
                             assert(
                                 isCodeActionWithoutEditsAndCommands(item),
-                                "We don't expect edits or commands here",
+                                "We don't expect edits or commands here"
                             );
                             const kind = client.protocol2CodeConverter.asCodeActionKind(
-                                (item as any).kind,
+                                (item as any).kind
                             );
                             const action = new vscode.CodeAction(item.title, kind);
                             const group = (item as any).group;
@@ -354,7 +351,7 @@ export async function createClient(
                         }
                         return result;
                     },
-                    (_error) => undefined,
+                    (_error) => undefined
                 );
             },
         },
@@ -367,7 +364,7 @@ export async function createClient(
         "rust-analyzer",
         "Rust Analyzer Language Server",
         serverOptions,
-        clientOptions,
+        clientOptions
     );
 
     // To turn on all proposed features use: client.registerProposedFeatures();
@@ -403,7 +400,7 @@ class ExperimentalFeatures implements lc.StaticFeature {
     }
     initialize(
         _capabilities: lc.ServerCapabilities,
-        _documentSelector: lc.DocumentSelector | undefined,
+        _documentSelector: lc.DocumentSelector | undefined
     ): void {}
     dispose(): void {}
 }
@@ -422,7 +419,7 @@ class OverrideFeatures implements lc.StaticFeature {
     }
     initialize(
         _capabilities: lc.ServerCapabilities,
-        _documentSelector: lc.DocumentSelector | undefined,
+        _documentSelector: lc.DocumentSelector | undefined
     ): void {}
     dispose(): void {}
 }
diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index e21f536f26..94ec5e99c6 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -3,23 +3,23 @@ import * as lc from "vscode-languageclient";
 import * as ra from "./lsp_ext";
 import * as path from "path";
 
-import { type Ctx, type Cmd, type CtxInit, discoverWorkspace } from "./ctx";
+import { Ctx, Cmd, CtxInit, discoverWorkspace } from "./ctx";
 import { applySnippetWorkspaceEdit, applySnippetTextEdits } from "./snippets";
 import { spawnSync } from "child_process";
-import { type RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
+import { RunnableQuickPick, selectRunnable, createTask, createArgs } from "./run";
 import { AstInspector } from "./ast_inspector";
 import {
     isRustDocument,
     isCargoTomlDocument,
     sleep,
     isRustEditor,
-    type RustEditor,
-    type RustDocument,
+    RustEditor,
+    RustDocument,
 } from "./util";
 import { startDebugSession, makeDebugConfig } from "./debug";
-import type { LanguageClient } from "vscode-languageclient/node";
+import { LanguageClient } from "vscode-languageclient/node";
 import { LINKED_COMMANDS } from "./client";
-import type { DependencyId } from "./dependencies_provider";
+import { DependencyId } from "./dependencies_provider";
 import { unwrapUndefinable } from "./undefinable";
 
 export * from "./ast_inspector";
@@ -48,7 +48,7 @@ export function analyzerStatus(ctx: CtxInit): Cmd {
     })();
 
     ctx.pushExtCleanup(
-        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-status", tdcp),
+        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-status", tdcp)
     );
 
     return async () => {
@@ -80,7 +80,7 @@ export function memoryUsage(ctx: CtxInit): Cmd {
     })();
 
     ctx.pushExtCleanup(
-        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-memory", tdcp),
+        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-memory", tdcp)
     );
 
     return async () => {
@@ -126,7 +126,7 @@ export function matchingBrace(ctx: CtxInit): Cmd {
         const response = await client.sendRequest(ra.matchingBrace, {
             textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
             positions: editor.selections.map((s) =>
-                client.code2ProtocolConverter.asPosition(s.active),
+                client.code2ProtocolConverter.asPosition(s.active)
             ),
         });
         editor.selections = editor.selections.map((sel, idx) => {
@@ -196,7 +196,7 @@ export function onEnter(ctx: CtxInit): Cmd {
         const lcEdits = await client
             .sendRequest(ra.onEnter, {
                 textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(
-                    editor.document,
+                    editor.document
                 ),
                 position: client.code2ProtocolConverter.asPosition(editor.selection.active),
             })
@@ -249,7 +249,7 @@ export function parentModule(ctx: CtxInit): Cmd {
                 client,
                 uri,
                 position,
-                locations.map((loc) => lc.Location.create(loc.targetUri, loc.targetRange)),
+                locations.map((loc) => lc.Location.create(loc.targetUri, loc.targetRange))
             );
         }
     };
@@ -357,7 +357,7 @@ export function ssr(ctx: CtxInit): Cmd {
         const position = editor.selection.active;
         const selections = editor.selections;
         const textDocument = client.code2ProtocolConverter.asTextDocumentIdentifier(
-            editor.document,
+            editor.document
         );
 
         const options: vscode.InputBoxOptions = {
@@ -397,9 +397,9 @@ export function ssr(ctx: CtxInit): Cmd {
                 });
 
                 await vscode.workspace.applyEdit(
-                    await client.protocol2CodeConverter.asWorkspaceEdit(edit, token),
+                    await client.protocol2CodeConverter.asWorkspaceEdit(edit, token)
                 );
-            },
+            }
         );
     };
 }
@@ -428,12 +428,12 @@ export function syntaxTree(ctx: CtxInit): Cmd {
             vscode.workspace.onDidChangeTextDocument(
                 this.onDidChangeTextDocument,
                 this,
-                ctx.subscriptions,
+                ctx.subscriptions
             );
             vscode.window.onDidChangeActiveTextEditor(
                 this.onDidChangeActiveTextEditor,
                 this,
-                ctx.subscriptions,
+                ctx.subscriptions
             );
         }
 
@@ -452,7 +452,7 @@ export function syntaxTree(ctx: CtxInit): Cmd {
 
         async provideTextDocumentContent(
             uri: vscode.Uri,
-            ct: vscode.CancellationToken,
+            ct: vscode.CancellationToken
         ): Promise<string> {
             const rustEditor = ctx.activeRustEditor;
             if (!rustEditor) return "";
@@ -475,12 +475,12 @@ export function syntaxTree(ctx: CtxInit): Cmd {
 
     ctx.pushExtCleanup(new AstInspector(ctx));
     ctx.pushExtCleanup(
-        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-syntax-tree", tdcp),
+        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-syntax-tree", tdcp)
     );
     ctx.pushExtCleanup(
         vscode.languages.setLanguageConfiguration("ra_syntax_tree", {
             brackets: [["[", ")"]],
-        }),
+        })
     );
 
     return async () => {
@@ -513,7 +513,7 @@ function viewFileUsingTextDocumentContentProvider(
     requestType: lc.RequestType<lc.TextDocumentPositionParams, string, void>,
     uri: string,
     scheme: string,
-    shouldUpdate: boolean,
+    shouldUpdate: boolean
 ): Cmd {
     const tdcp = new (class implements vscode.TextDocumentContentProvider {
         readonly uri = vscode.Uri.parse(uri);
@@ -522,12 +522,12 @@ function viewFileUsingTextDocumentContentProvider(
             vscode.workspace.onDidChangeTextDocument(
                 this.onDidChangeTextDocument,
                 this,
-                ctx.subscriptions,
+                ctx.subscriptions
             );
             vscode.window.onDidChangeActiveTextEditor(
                 this.onDidChangeActiveTextEditor,
                 this,
-                ctx.subscriptions,
+                ctx.subscriptions
             );
         }
 
@@ -546,7 +546,7 @@ function viewFileUsingTextDocumentContentProvider(
 
         async provideTextDocumentContent(
             _uri: vscode.Uri,
-            ct: vscode.CancellationToken,
+            ct: vscode.CancellationToken
         ): Promise<string> {
             const rustEditor = ctx.activeRustEditor;
             if (!rustEditor) return "";
@@ -554,7 +554,7 @@ function viewFileUsingTextDocumentContentProvider(
             const client = ctx.client;
             const params = {
                 textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(
-                    rustEditor.document,
+                    rustEditor.document
                 ),
                 position: client.code2ProtocolConverter.asPosition(rustEditor.selection.active),
             };
@@ -602,7 +602,7 @@ export function interpretFunction(ctx: CtxInit): Cmd {
         ra.interpretFunction,
         uri,
         `rust-analyzer-interpret-function`,
-        false,
+        false
     );
 }
 
@@ -614,12 +614,12 @@ export function viewFileText(ctx: CtxInit): Cmd {
             vscode.workspace.onDidChangeTextDocument(
                 this.onDidChangeTextDocument,
                 this,
-                ctx.subscriptions,
+                ctx.subscriptions
             );
             vscode.window.onDidChangeActiveTextEditor(
                 this.onDidChangeActiveTextEditor,
                 this,
-                ctx.subscriptions,
+                ctx.subscriptions
             );
         }
 
@@ -638,14 +638,14 @@ export function viewFileText(ctx: CtxInit): Cmd {
 
         async provideTextDocumentContent(
             _uri: vscode.Uri,
-            ct: vscode.CancellationToken,
+            ct: vscode.CancellationToken
         ): Promise<string> {
             const rustEditor = ctx.activeRustEditor;
             if (!rustEditor) return "";
             const client = ctx.client;
 
             const params = client.code2ProtocolConverter.asTextDocumentIdentifier(
-                rustEditor.document,
+                rustEditor.document
             );
             return client.sendRequest(ra.viewFileText, params, ct);
         }
@@ -656,7 +656,7 @@ export function viewFileText(ctx: CtxInit): Cmd {
     })();
 
     ctx.pushExtCleanup(
-        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-file-text", tdcp),
+        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-file-text", tdcp)
     );
 
     return async () => {
@@ -677,12 +677,12 @@ export function viewItemTree(ctx: CtxInit): Cmd {
             vscode.workspace.onDidChangeTextDocument(
                 this.onDidChangeTextDocument,
                 this,
-                ctx.subscriptions,
+                ctx.subscriptions
             );
             vscode.window.onDidChangeActiveTextEditor(
                 this.onDidChangeActiveTextEditor,
                 this,
-                ctx.subscriptions,
+                ctx.subscriptions
             );
         }
 
@@ -701,7 +701,7 @@ export function viewItemTree(ctx: CtxInit): Cmd {
 
         async provideTextDocumentContent(
             _uri: vscode.Uri,
-            ct: vscode.CancellationToken,
+            ct: vscode.CancellationToken
         ): Promise<string> {
             const rustEditor = ctx.activeRustEditor;
             if (!rustEditor) return "";
@@ -709,7 +709,7 @@ export function viewItemTree(ctx: CtxInit): Cmd {
 
             const params = {
                 textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(
-                    rustEditor.document,
+                    rustEditor.document
                 ),
             };
             return client.sendRequest(ra.viewItemTree, params, ct);
@@ -721,7 +721,7 @@ export function viewItemTree(ctx: CtxInit): Cmd {
     })();
 
     ctx.pushExtCleanup(
-        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-item-tree", tdcp),
+        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-item-tree", tdcp)
     );
 
     return async () => {
@@ -746,7 +746,7 @@ function crateGraph(ctx: CtxInit, full: boolean): Cmd {
                 enableScripts: true,
                 retainContextWhenHidden: true,
                 localResourceRoots: [nodeModulesPath],
-            },
+            }
         );
         const params = {
             full: full,
@@ -835,7 +835,7 @@ export function expandMacro(ctx: CtxInit): Cmd {
 
             const expanded = await client.sendRequest(ra.expandMacro, {
                 textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(
-                    editor.document,
+                    editor.document
                 ),
                 position,
             });
@@ -851,7 +851,7 @@ export function expandMacro(ctx: CtxInit): Cmd {
     })();
 
     ctx.pushExtCleanup(
-        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-expand-macro", tdcp),
+        vscode.workspace.registerTextDocumentContentProvider("rust-analyzer-expand-macro", tdcp)
     );
 
     return async () => {
@@ -883,7 +883,7 @@ export function addProject(ctx: CtxInit): Cmd {
                     return discoverWorkspace([file], discoverProjectCommand, {
                         cwd: path.dirname(file.uri.fsPath),
                     });
-                }),
+                })
         );
 
         ctx.addToDiscoveredWorkspaces(workspaces);
@@ -901,14 +901,14 @@ async function showReferencesImpl(
     client: LanguageClient | undefined,
     uri: string,
     position: lc.Position,
-    locations: lc.Location[],
+    locations: lc.Location[]
 ) {
     if (client) {
         await vscode.commands.executeCommand(
             "editor.action.showReferences",
             vscode.Uri.parse(uri),
             client.protocol2CodeConverter.asPosition(position),
-            locations.map(client.protocol2CodeConverter.asLocation),
+            locations.map(client.protocol2CodeConverter.asLocation)
         );
     }
 }
@@ -925,7 +925,7 @@ export function applyActionGroup(_ctx: CtxInit): Cmd {
         if (!selectedAction) return;
         await vscode.commands.executeCommand(
             "rust-analyzer.resolveCodeAction",
-            selectedAction.arguments,
+            selectedAction.arguments
         );
     };
 }
@@ -1000,7 +1000,7 @@ export function resolveCodeAction(ctx: CtxInit): Cmd {
             documentChanges: itemEdit.documentChanges?.filter((change) => "kind" in change),
         };
         const fileSystemEdit = await client.protocol2CodeConverter.asWorkspaceEdit(
-            lcFileSystemEdit,
+            lcFileSystemEdit
         );
         await vscode.workspace.applyEdit(fileSystemEdit);
         await applySnippetWorkspaceEdit(edit);
@@ -1053,12 +1053,12 @@ export function peekTests(ctx: CtxInit): Cmd {
                 const locations: lc.Location[] = tests.map((it) =>
                     lc.Location.create(
                         it.runnable.location!.targetUri,
-                        it.runnable.location!.targetSelectionRange,
-                    ),
+                        it.runnable.location!.targetSelectionRange
+                    )
                 );
 
                 await showReferencesImpl(client, uri, position, locations);
-            },
+            }
         );
     };
 }
@@ -1146,7 +1146,7 @@ export function viewMemoryLayout(ctx: CtxInit): Cmd {
             "memory_layout",
             "[Memory Layout]",
             vscode.ViewColumn.Two,
-            { enableScripts: true },
+            { enableScripts: true }
         );
 
         document.webview.html = `<!DOCTYPE html>
diff --git a/editors/code/src/config.ts b/editors/code/src/config.ts
index a047f9659a..7f4efebb2a 100644
--- a/editors/code/src/config.ts
+++ b/editors/code/src/config.ts
@@ -2,7 +2,7 @@ import * as Is from "vscode-languageclient/lib/common/utils/is";
 import * as os from "os";
 import * as path from "path";
 import * as vscode from "vscode";
-import type { Env } from "./client";
+import { Env } from "./client";
 import { log } from "./util";
 import { expectNotUndefined, unwrapUndefinable } from "./undefinable";
 
@@ -38,7 +38,7 @@ export class Config {
         vscode.workspace.onDidChangeConfiguration(
             this.onDidChangeConfiguration,
             this,
-            ctx.subscriptions,
+            ctx.subscriptions
         );
         this.refreshLogging();
         this.configureLanguage();
@@ -64,7 +64,7 @@ export class Config {
         this.configureLanguage();
 
         const requiresReloadOpt = this.requiresReloadOpts.find((opt) =>
-            event.affectsConfiguration(opt),
+            event.affectsConfiguration(opt)
         );
 
         if (!requiresReloadOpt) return;
@@ -210,8 +210,8 @@ export class Config {
                 Object.entries(extraEnv).map(([k, v]) => [
                     k,
                     typeof v !== "string" ? v.toString() : v,
-                ]),
-            ),
+                ])
+            )
         );
     }
     get traceExtension() {
@@ -306,7 +306,7 @@ export class Config {
 // to interact with.
 export function prepareVSCodeConfig<T>(
     resp: T,
-    cb?: (key: Extract<keyof T, string>, res: { [key: string]: any }) => void,
+    cb?: (key: Extract<keyof T, string>, res: { [key: string]: any }) => void
 ): T {
     if (Is.string(resp)) {
         return substituteVSCodeVariableInString(resp) as T;
@@ -349,7 +349,7 @@ export function substituteVariablesInEnv(env: Env): Env {
                 }
             }
             return [`env:${key}`, { deps: [...deps], value }];
-        }),
+        })
     );
 
     const resolved = new Set<string>();
@@ -457,7 +457,7 @@ function computeVscodeVar(varName: string): string | null {
     if (varName in supportedVariables) {
         const fn = expectNotUndefined(
             supportedVariables[varName],
-            `${varName} should not be undefined here`,
+            `${varName} should not be undefined here`
         );
         return fn();
     } else {
diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts
index ac144cbebb..a72b5391ff 100644
--- a/editors/code/src/ctx.ts
+++ b/editors/code/src/ctx.ts
@@ -1,5 +1,5 @@
 import * as vscode from "vscode";
-import type * as lc from "vscode-languageclient/node";
+import * as lc from "vscode-languageclient/node";
 import * as ra from "./lsp_ext";
 import * as path from "path";
 
@@ -12,19 +12,19 @@ import {
     isRustEditor,
     LazyOutputChannel,
     log,
-    type RustEditor,
+    RustEditor,
 } from "./util";
-import type { ServerStatusParams } from "./lsp_ext";
+import { ServerStatusParams } from "./lsp_ext";
 import {
-    type Dependency,
-    type DependencyFile,
+    Dependency,
+    DependencyFile,
     RustDependenciesProvider,
-    type DependencyId,
+    DependencyId,
 } from "./dependencies_provider";
 import { execRevealDependency } from "./commands";
 import { PersistentState } from "./persistent_state";
 import { bootstrap } from "./bootstrap";
-import type { ExecOptions } from "child_process";
+import { ExecOptions } from "child_process";
 
 // We only support local folders, not eg. Live Share (`vlsl:` scheme), so don't activate if
 // only those are in use. We use "Empty" to represent these scenarios
@@ -42,10 +42,10 @@ export type Workspace =
 
 export function fetchWorkspace(): Workspace {
     const folders = (vscode.workspace.workspaceFolders || []).filter(
-        (folder) => folder.uri.scheme === "file",
+        (folder) => folder.uri.scheme === "file"
     );
     const rustDocuments = vscode.workspace.textDocuments.filter((document) =>
-        isRustDocument(document),
+        isRustDocument(document)
     );
 
     return folders.length === 0
@@ -61,7 +61,7 @@ export function fetchWorkspace(): Workspace {
 export async function discoverWorkspace(
     files: readonly vscode.TextDocument[],
     command: string[],
-    options: ExecOptions,
+    options: ExecOptions
 ): Promise<JsonProject> {
     const paths = files.map((f) => `"${f.uri.fsPath}"`).join(" ");
     const joinedCommand = command.join(" ");
@@ -110,7 +110,7 @@ export class Ctx {
     constructor(
         readonly extCtx: vscode.ExtensionContext,
         commandFactories: Record<string, CommandFactory>,
-        workspace: Workspace,
+        workspace: Workspace
     ) {
         extCtx.subscriptions.push(this);
         this.statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
@@ -186,7 +186,7 @@ export class Ctx {
 
                     log.error("Bootstrap error", err);
                     throw new Error(message);
-                },
+                }
             );
             const newEnv = Object.assign({}, process.env, this.config.serverExtraEnv);
             const run: lc.Executable = {
@@ -216,7 +216,7 @@ export class Ctx {
                             return discoverWorkspace([file], discoverProjectCommand, {
                                 cwd: path.dirname(file.uri.fsPath),
                             });
-                        }),
+                        })
                 );
 
                 this.addToDiscoveredWorkspaces(workspaces);
@@ -230,7 +230,7 @@ export class Ctx {
                     if (key === "linkedProjects" && this.config.discoveredWorkspaces.length > 0) {
                         obj["linkedProjects"] = this.config.discoveredWorkspaces;
                     }
-                },
+                }
             );
 
             this._client = await createClient(
@@ -239,17 +239,17 @@ export class Ctx {
                 initializationOptions,
                 serverOptions,
                 this.config,
-                this.unlinkedFiles,
+                this.unlinkedFiles
             );
             this.pushClientCleanup(
                 this._client.onNotification(ra.serverStatus, (params) =>
-                    this.setServerStatus(params),
-                ),
+                    this.setServerStatus(params)
+                )
             );
             this.pushClientCleanup(
                 this._client.onNotification(ra.openServerLogs, () => {
                     this.outputChannel!.show();
-                }),
+                })
             );
         }
         return this._client;
@@ -395,7 +395,7 @@ export class Ctx {
             } else {
                 callback = () =>
                     vscode.window.showErrorMessage(
-                        `command ${fullName} failed: rust-analyzer server is not running`,
+                        `command ${fullName} failed: rust-analyzer server is not running`
                     );
             }
 
@@ -423,7 +423,7 @@ export class Ctx {
                 }
                 statusBar.color = new vscode.ThemeColor("statusBarItem.warningForeground");
                 statusBar.backgroundColor = new vscode.ThemeColor(
-                    "statusBarItem.warningBackground",
+                    "statusBarItem.warningBackground"
                 );
                 statusBar.command = "rust-analyzer.openLogs";
                 icon = "$(warning) ";
@@ -440,7 +440,7 @@ export class Ctx {
             case "stopped":
                 statusBar.tooltip.appendText("Server is stopped");
                 statusBar.tooltip.appendMarkdown(
-                    "\n\n[Start server](command:rust-analyzer.startServer)",
+                    "\n\n[Start server](command:rust-analyzer.startServer)"
                 );
                 statusBar.color = undefined;
                 statusBar.backgroundColor = undefined;
@@ -453,13 +453,13 @@ export class Ctx {
         }
         statusBar.tooltip.appendMarkdown("\n\n[Open logs](command:rust-analyzer.openLogs)");
         statusBar.tooltip.appendMarkdown(
-            "\n\n[Reload Workspace](command:rust-analyzer.reloadWorkspace)",
+            "\n\n[Reload Workspace](command:rust-analyzer.reloadWorkspace)"
         );
         statusBar.tooltip.appendMarkdown(
-            "\n\n[Rebuild Proc Macros](command:rust-analyzer.rebuildProcMacros)",
+            "\n\n[Rebuild Proc Macros](command:rust-analyzer.rebuildProcMacros)"
         );
         statusBar.tooltip.appendMarkdown(
-            "\n\n[Restart server](command:rust-analyzer.restartServer)",
+            "\n\n[Restart server](command:rust-analyzer.restartServer)"
         );
         statusBar.tooltip.appendMarkdown("\n\n[Stop server](command:rust-analyzer.stopServer)");
         if (!status.quiescent) icon = "$(sync~spin) ";
diff --git a/editors/code/src/debug.ts b/editors/code/src/debug.ts
index f3d6238d51..29758feafe 100644
--- a/editors/code/src/debug.ts
+++ b/editors/code/src/debug.ts
@@ -1,10 +1,10 @@
 import * as os from "os";
 import * as vscode from "vscode";
 import * as path from "path";
-import type * as ra from "./lsp_ext";
+import * as ra from "./lsp_ext";
 
 import { Cargo, getRustcId, getSysroot } from "./toolchain";
-import type { Ctx } from "./ctx";
+import { Ctx } from "./ctx";
 import { prepareEnv } from "./run";
 import { unwrapUndefinable } from "./undefinable";
 
@@ -13,7 +13,7 @@ type DebugConfigProvider = (
     config: ra.Runnable,
     executable: string,
     env: Record<string, string>,
-    sourceFileMap?: Record<string, string>,
+    sourceFileMap?: Record<string, string>
 ) => vscode.DebugConfiguration;
 
 export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise<void> {
@@ -31,7 +31,7 @@ export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise<
         const answer = await vscode.window.showErrorMessage(
             `Launch configuration '${debugConfig.name}' already exists!`,
             "Cancel",
-            "Update",
+            "Update"
         );
         if (answer === "Cancel") return;
 
@@ -68,7 +68,7 @@ export async function startDebugSession(ctx: Ctx, runnable: ra.Runnable): Promis
 
 async function getDebugConfiguration(
     ctx: Ctx,
-    runnable: ra.Runnable,
+    runnable: ra.Runnable
 ): Promise<vscode.DebugConfiguration | undefined> {
     const editor = ctx.activeRustEditor;
     if (!editor) return;
@@ -92,7 +92,7 @@ async function getDebugConfiguration(
     if (!debugEngine) {
         await vscode.window.showErrorMessage(
             `Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)` +
-                ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`,
+                ` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`
         );
         return;
     }
@@ -157,7 +157,7 @@ async function getDebugConfiguration(
 
 async function getDebugExecutable(
     runnable: ra.Runnable,
-    env: Record<string, string>,
+    env: Record<string, string>
 ): Promise<string> {
     const cargo = new Cargo(runnable.args.workspaceRoot || ".", debugOutput, env);
     const executable = await cargo.executableFromArgs(runnable.args.cargoArgs);
@@ -170,7 +170,7 @@ function getLldbDebugConfig(
     runnable: ra.Runnable,
     executable: string,
     env: Record<string, string>,
-    sourceFileMap?: Record<string, string>,
+    sourceFileMap?: Record<string, string>
 ): vscode.DebugConfiguration {
     return {
         type: "lldb",
@@ -189,7 +189,7 @@ function getCppvsDebugConfig(
     runnable: ra.Runnable,
     executable: string,
     env: Record<string, string>,
-    sourceFileMap?: Record<string, string>,
+    sourceFileMap?: Record<string, string>
 ): vscode.DebugConfiguration {
     return {
         type: os.platform() === "win32" ? "cppvsdbg" : "cppdbg",
diff --git a/editors/code/src/dependencies_provider.ts b/editors/code/src/dependencies_provider.ts
index 863ace0780..51ba11ecc9 100644
--- a/editors/code/src/dependencies_provider.ts
+++ b/editors/code/src/dependencies_provider.ts
@@ -1,9 +1,9 @@
 import * as vscode from "vscode";
 import * as fspath from "path";
 import * as fs from "fs";
-import type { CtxInit } from "./ctx";
+import { CtxInit } from "./ctx";
 import * as ra from "./lsp_ext";
-import type { FetchDependencyListResult } from "./lsp_ext";
+import { FetchDependencyListResult } from "./lsp_ext";
 import { unwrapUndefinable } from "./undefinable";
 
 export class RustDependenciesProvider
@@ -43,7 +43,7 @@ export class RustDependenciesProvider
     }
 
     getParent?(
-        element: Dependency | DependencyFile,
+        element: Dependency | DependencyFile
     ): vscode.ProviderResult<Dependency | DependencyFile> {
         if (element instanceof Dependency) return undefined;
         return element.parent;
@@ -60,7 +60,7 @@ export class RustDependenciesProvider
     }
 
     getChildren(
-        element?: Dependency | DependencyFile,
+        element?: Dependency | DependencyFile
     ): vscode.ProviderResult<Dependency[] | DependencyFile[]> {
         return new Promise((resolve, _reject) => {
             if (!vscode.workspace.workspaceFolders) {
@@ -87,7 +87,7 @@ export class RustDependenciesProvider
     private async getRootDependencies(): Promise<Dependency[]> {
         const dependenciesResult: FetchDependencyListResult = await this.ctx.client.sendRequest(
             ra.fetchDependencyList,
-            {},
+            {}
         );
         const crates = dependenciesResult.crates;
 
@@ -107,7 +107,7 @@ export class RustDependenciesProvider
             moduleName,
             version,
             vscode.Uri.parse(path).fsPath,
-            vscode.TreeItemCollapsibleState.Collapsed,
+            vscode.TreeItemCollapsibleState.Collapsed
         );
     }
 }
@@ -117,7 +117,7 @@ export class Dependency extends vscode.TreeItem {
         public override readonly label: string,
         private version: string,
         readonly dependencyPath: string,
-        public override readonly collapsibleState: vscode.TreeItemCollapsibleState,
+        public override readonly collapsibleState: vscode.TreeItemCollapsibleState
     ) {
         super(label, collapsibleState);
         this.resourceUri = vscode.Uri.file(dependencyPath);
@@ -136,7 +136,7 @@ export class DependencyFile extends vscode.TreeItem {
         override readonly label: string,
         readonly dependencyPath: string,
         readonly parent: Dependency | DependencyFile,
-        public override readonly collapsibleState: vscode.TreeItemCollapsibleState,
+        public override readonly collapsibleState: vscode.TreeItemCollapsibleState
     ) {
         super(vscode.Uri.file(dependencyPath), collapsibleState);
         this.id = this.resourceUri!.fsPath.toLowerCase();
diff --git a/editors/code/src/diagnostics.ts b/editors/code/src/diagnostics.ts
index e31a1cdcef..a7e0845a27 100644
--- a/editors/code/src/diagnostics.ts
+++ b/editors/code/src/diagnostics.ts
@@ -1,13 +1,7 @@
 import * as anser from "anser";
 import * as vscode from "vscode";
-import {
-    type ProviderResult,
-    Range,
-    type TextEditorDecorationType,
-    ThemeColor,
-    window,
-} from "vscode";
-import type { Ctx } from "./ctx";
+import { ProviderResult, Range, TextEditorDecorationType, ThemeColor, window } from "vscode";
+import { Ctx } from "./ctx";
 import { unwrapUndefinable } from "./undefinable";
 
 export const URI_SCHEME = "rust-analyzer-diagnostics-view";
@@ -89,7 +83,7 @@ export class AnsiDecorationProvider implements vscode.Disposable {
     }
 
     private _getDecorations(
-        uri: vscode.Uri,
+        uri: vscode.Uri
     ): ProviderResult<[TextEditorDecorationType, Range[]][]> {
         const stringContents = getRenderedDiagnostic(this.ctx, uri);
         const lines = stringContents.split("\n");
@@ -117,7 +111,7 @@ export class AnsiDecorationProvider implements vscode.Disposable {
                     lineNumber,
                     offset - totalEscapeLength,
                     lineNumber,
-                    offset + content.length - totalEscapeLength,
+                    offset + content.length - totalEscapeLength
                 );
 
                 offset += content.length;
@@ -183,7 +177,7 @@ export class AnsiDecorationProvider implements vscode.Disposable {
 
     private static _convertColor(
         color?: string,
-        truecolor?: string,
+        truecolor?: string
     ): ThemeColor | string | undefined {
         if (!color) {
             return undefined;
diff --git a/editors/code/src/lsp_ext.ts b/editors/code/src/lsp_ext.ts
index bb7896973f..5af2cab0ee 100644
--- a/editors/code/src/lsp_ext.ts
+++ b/editors/code/src/lsp_ext.ts
@@ -27,17 +27,17 @@ export type CommandLinkGroup = {
 // rust-analyzer extensions
 
 export const analyzerStatus = new lc.RequestType<AnalyzerStatusParams, string, void>(
-    "rust-analyzer/analyzerStatus",
+    "rust-analyzer/analyzerStatus"
 );
 export const cancelFlycheck = new lc.NotificationType0("rust-analyzer/cancelFlycheck");
 export const clearFlycheck = new lc.NotificationType0("rust-analyzer/clearFlycheck");
 export const expandMacro = new lc.RequestType<ExpandMacroParams, ExpandedMacro | null, void>(
-    "rust-analyzer/expandMacro",
+    "rust-analyzer/expandMacro"
 );
 export const memoryUsage = new lc.RequestType0<string, void>("rust-analyzer/memoryUsage");
 export const openServerLogs = new lc.NotificationType0("rust-analyzer/openServerLogs");
 export const relatedTests = new lc.RequestType<lc.TextDocumentPositionParams, TestInfo[], void>(
-    "rust-analyzer/relatedTests",
+    "rust-analyzer/relatedTests"
 );
 export const reloadWorkspace = new lc.RequestType0<null, void>("rust-analyzer/reloadWorkspace");
 export const rebuildProcMacros = new lc.RequestType0<null, void>("rust-analyzer/rebuildProcMacros");
@@ -47,25 +47,25 @@ export const runFlycheck = new lc.NotificationType<{
 }>("rust-analyzer/runFlycheck");
 export const shuffleCrateGraph = new lc.RequestType0<null, void>("rust-analyzer/shuffleCrateGraph");
 export const syntaxTree = new lc.RequestType<SyntaxTreeParams, string, void>(
-    "rust-analyzer/syntaxTree",
+    "rust-analyzer/syntaxTree"
 );
 export const viewCrateGraph = new lc.RequestType<ViewCrateGraphParams, string, void>(
-    "rust-analyzer/viewCrateGraph",
+    "rust-analyzer/viewCrateGraph"
 );
 export const viewFileText = new lc.RequestType<lc.TextDocumentIdentifier, string, void>(
-    "rust-analyzer/viewFileText",
+    "rust-analyzer/viewFileText"
 );
 export const viewHir = new lc.RequestType<lc.TextDocumentPositionParams, string, void>(
-    "rust-analyzer/viewHir",
+    "rust-analyzer/viewHir"
 );
 export const viewMir = new lc.RequestType<lc.TextDocumentPositionParams, string, void>(
-    "rust-analyzer/viewMir",
+    "rust-analyzer/viewMir"
 );
 export const interpretFunction = new lc.RequestType<lc.TextDocumentPositionParams, string, void>(
-    "rust-analyzer/interpretFunction",
+    "rust-analyzer/interpretFunction"
 );
 export const viewItemTree = new lc.RequestType<ViewItemTreeParams, string, void>(
-    "rust-analyzer/viewItemTree",
+    "rust-analyzer/viewItemTree"
 );
 
 export type AnalyzerStatusParams = { textDocument?: lc.TextDocumentIdentifier };
@@ -121,22 +121,22 @@ export type ViewItemTreeParams = { textDocument: lc.TextDocumentIdentifier };
 // experimental extensions
 
 export const joinLines = new lc.RequestType<JoinLinesParams, lc.TextEdit[], void>(
-    "experimental/joinLines",
+    "experimental/joinLines"
 );
 export const matchingBrace = new lc.RequestType<MatchingBraceParams, lc.Position[], void>(
-    "experimental/matchingBrace",
+    "experimental/matchingBrace"
 );
 export const moveItem = new lc.RequestType<MoveItemParams, lc.TextEdit[], void>(
-    "experimental/moveItem",
+    "experimental/moveItem"
 );
 export const onEnter = new lc.RequestType<lc.TextDocumentPositionParams, lc.TextEdit[], void>(
-    "experimental/onEnter",
+    "experimental/onEnter"
 );
 export const openCargoToml = new lc.RequestType<OpenCargoTomlParams, lc.Location, void>(
-    "experimental/openCargoToml",
+    "experimental/openCargoToml"
 );
 export const openDocs = new lc.RequestType<lc.TextDocumentPositionParams, string | void, void>(
-    "experimental/externalDocs",
+    "experimental/externalDocs"
 );
 export const parentModule = new lc.RequestType<
     lc.TextDocumentPositionParams,
@@ -144,10 +144,10 @@ export const parentModule = new lc.RequestType<
     void
 >("experimental/parentModule");
 export const runnables = new lc.RequestType<RunnablesParams, Runnable[], void>(
-    "experimental/runnables",
+    "experimental/runnables"
 );
 export const serverStatus = new lc.NotificationType<ServerStatusParams>(
-    "experimental/serverStatus",
+    "experimental/serverStatus"
 );
 export const ssr = new lc.RequestType<SsrParams, lc.WorkspaceEdit, void>("experimental/ssr");
 export const viewRecursiveMemoryLayout = new lc.RequestType<
diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts
index 448150bac0..64aea03394 100644
--- a/editors/code/src/main.ts
+++ b/editors/code/src/main.ts
@@ -2,7 +2,7 @@ import * as vscode from "vscode";
 import * as lc from "vscode-languageclient/node";
 
 import * as commands from "./commands";
-import { type CommandFactory, Ctx, fetchWorkspace } from "./ctx";
+import { CommandFactory, Ctx, fetchWorkspace } from "./ctx";
 import * as diagnostics from "./diagnostics";
 import { activateTaskProvider } from "./tasks";
 import { setContextValue } from "./util";
@@ -18,7 +18,7 @@ export async function deactivate() {
 }
 
 export async function activate(
-    context: vscode.ExtensionContext,
+    context: vscode.ExtensionContext
 ): Promise<RustAnalyzerExtensionApi> {
     if (vscode.extensions.getExtension("rust-lang.rust")) {
         vscode.window
@@ -26,7 +26,7 @@ export async function activate(
                 `You have both the rust-analyzer (rust-lang.rust-analyzer) and Rust (rust-lang.rust) ` +
                     "plugins enabled. These are known to conflict and cause various functions of " +
                     "both plugins to not work correctly. You should disable one of them.",
-                "Got it",
+                "Got it"
             )
             .then(() => {}, console.error);
     }
@@ -36,7 +36,7 @@ export async function activate(
     // so we do it ourselves.
     const api = await activateServer(ctx).catch((err) => {
         void vscode.window.showErrorMessage(
-            `Cannot activate rust-analyzer extension: ${err.message}`,
+            `Cannot activate rust-analyzer extension: ${err.message}`
         );
         throw err;
     });
@@ -53,8 +53,8 @@ async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
     ctx.pushExtCleanup(
         vscode.workspace.registerTextDocumentContentProvider(
             diagnostics.URI_SCHEME,
-            diagnosticProvider,
-        ),
+            diagnosticProvider
+        )
     );
 
     const decorationProvider = new diagnostics.AnsiDecorationProvider(ctx);
@@ -71,7 +71,7 @@ async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
     vscode.workspace.onDidChangeTextDocument(
         async (event) => await decorateVisibleEditors(event.document),
         null,
-        ctx.subscriptions,
+        ctx.subscriptions
     );
     vscode.workspace.onDidOpenTextDocument(decorateVisibleEditors, null, ctx.subscriptions);
     vscode.window.onDidChangeActiveTextEditor(
@@ -82,7 +82,7 @@ async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
             }
         },
         null,
-        ctx.subscriptions,
+        ctx.subscriptions
     );
     vscode.window.onDidChangeVisibleTextEditors(
         async (visibleEditors) => {
@@ -92,13 +92,13 @@ async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
             }
         },
         null,
-        ctx.subscriptions,
+        ctx.subscriptions
     );
 
     vscode.workspace.onDidChangeWorkspaceFolders(
         async (_) => ctx.onWorkspaceFolderChanges(),
         null,
-        ctx.subscriptions,
+        ctx.subscriptions
     );
     vscode.workspace.onDidChangeConfiguration(
         async (_) => {
@@ -107,7 +107,7 @@ async function activateServer(ctx: Ctx): Promise<RustAnalyzerExtensionApi> {
             });
         },
         null,
-        ctx.subscriptions,
+        ctx.subscriptions
     );
 
     await ctx.start();
diff --git a/editors/code/src/persistent_state.ts b/editors/code/src/persistent_state.ts
index cebd16a3c9..8964a78dc3 100644
--- a/editors/code/src/persistent_state.ts
+++ b/editors/code/src/persistent_state.ts
@@ -1,4 +1,4 @@
-import type * as vscode from "vscode";
+import * as vscode from "vscode";
 import { log } from "./util";
 
 export class PersistentState {
diff --git a/editors/code/src/run.ts b/editors/code/src/run.ts
index c893d39055..c20a5487b7 100644
--- a/editors/code/src/run.ts
+++ b/editors/code/src/run.ts
@@ -1,11 +1,11 @@
 import * as vscode from "vscode";
-import type * as lc from "vscode-languageclient";
+import * as lc from "vscode-languageclient";
 import * as ra from "./lsp_ext";
 import * as tasks from "./tasks";
 
-import type { CtxInit } from "./ctx";
+import { CtxInit } from "./ctx";
 import { makeDebugConfig } from "./debug";
-import type { Config, RunnableEnvCfg } from "./config";
+import { Config, RunnableEnvCfg } from "./config";
 import { unwrapUndefinable } from "./undefinable";
 
 const quickPickButtons = [
@@ -16,7 +16,7 @@ export async function selectRunnable(
     ctx: CtxInit,
     prevRunnable?: RunnableQuickPick,
     debuggeeOnly = false,
-    showButtons: boolean = true,
+    showButtons: boolean = true
 ): Promise<RunnableQuickPick | undefined> {
     const editor = ctx.activeRustEditor;
     if (!editor) return;
@@ -84,7 +84,7 @@ export async function selectRunnable(
                     }
                 }
             }),
-            quickPick,
+            quickPick
         );
         quickPick.show();
     });
@@ -103,7 +103,7 @@ export class RunnableQuickPick implements vscode.QuickPickItem {
 
 export function prepareEnv(
     runnable: ra.Runnable,
-    runnableEnvCfg: RunnableEnvCfg,
+    runnableEnvCfg: RunnableEnvCfg
 ): Record<string, string> {
     const env: Record<string, string> = { RUST_BACKTRACE: "short" };
 
@@ -156,7 +156,7 @@ export async function createTask(runnable: ra.Runnable, config: Config): Promise
         args,
         config.problemMatcher,
         config.cargoRunner,
-        true,
+        true
     );
 
     cargoTask.presentationOptions.clear = true;
diff --git a/editors/code/src/snippets.ts b/editors/code/src/snippets.ts
index d81765649f..1ad93d280b 100644
--- a/editors/code/src/snippets.ts
+++ b/editors/code/src/snippets.ts
@@ -17,9 +17,7 @@ export async function applySnippetWorkspaceEdit(edit: vscode.WorkspaceEdit) {
                 for (const indel of edits) {
                     assert(
                         !parseSnippet(indel.newText),
-                        `bad ws edit: snippet received with multiple edits: ${JSON.stringify(
-                            edit,
-                        )}`,
+                        `bad ws edit: snippet received with multiple edits: ${JSON.stringify(edit)}`
                     );
                     builder.replace(indel.range, indel.newText);
                 }
@@ -34,7 +32,7 @@ async function editorFromUri(uri: vscode.Uri): Promise<vscode.TextEditor | undef
         await vscode.window.showTextDocument(uri, {});
     }
     return vscode.window.visibleTextEditors.find(
-        (it) => it.document.uri.toString() === uri.toString(),
+        (it) => it.document.uri.toString() === uri.toString()
     );
 }
 
@@ -58,8 +56,8 @@ export async function applySnippetTextEdits(editor: vscode.TextEditor, edits: vs
                 selections.push(
                     new vscode.Selection(
                         new vscode.Position(startLine, startColumn),
-                        new vscode.Position(startLine, endColumn),
-                    ),
+                        new vscode.Position(startLine, endColumn)
+                    )
                 );
                 builder.replace(indel.range, newText);
             } else {
diff --git a/editors/code/src/tasks.ts b/editors/code/src/tasks.ts
index 1d5ab82aa0..5199508c82 100644
--- a/editors/code/src/tasks.ts
+++ b/editors/code/src/tasks.ts
@@ -1,6 +1,6 @@
 import * as vscode from "vscode";
 import * as toolchain from "./toolchain";
-import type { Config } from "./config";
+import { Config } from "./config";
 import { log } from "./util";
 import { unwrapUndefinable } from "./undefinable";
 
@@ -48,7 +48,7 @@ class CargoTaskProvider implements vscode.TaskProvider {
                     `cargo ${def.command}`,
                     [def.command],
                     this.config.problemMatcher,
-                    this.config.cargoRunner,
+                    this.config.cargoRunner
                 );
                 vscodeTask.group = def.group;
                 tasks.push(vscodeTask);
@@ -73,7 +73,7 @@ class CargoTaskProvider implements vscode.TaskProvider {
                 task.name,
                 args,
                 this.config.problemMatcher,
-                this.config.cargoRunner,
+                this.config.cargoRunner
             );
         }
 
@@ -88,7 +88,7 @@ export async function buildCargoTask(
     args: string[],
     problemMatcher: string[],
     customRunner?: string,
-    throwOnError: boolean = false,
+    throwOnError: boolean = false
 ): Promise<vscode.Task> {
     let exec: vscode.ProcessExecution | vscode.ShellExecution | undefined = undefined;
 
@@ -133,7 +133,7 @@ export async function buildCargoTask(
         name,
         TASK_SOURCE,
         exec,
-        problemMatcher,
+        problemMatcher
     );
 }
 
diff --git a/editors/code/src/toolchain.ts b/editors/code/src/toolchain.ts
index 58e5fc747a..014e6b66f6 100644
--- a/editors/code/src/toolchain.ts
+++ b/editors/code/src/toolchain.ts
@@ -23,7 +23,7 @@ export class Cargo {
     constructor(
         readonly rootFolder: string,
         readonly output: vscode.OutputChannel,
-        readonly env: Record<string, string>,
+        readonly env: Record<string, string>
     ) {}
 
     // Made public for testing purposes
@@ -76,7 +76,7 @@ export class Cargo {
                         this.output.append(message.message.rendered);
                     }
                 },
-                (stderr) => this.output.append(stderr),
+                (stderr) => this.output.append(stderr)
             );
         } catch (err) {
             this.output.show(true);
@@ -102,7 +102,7 @@ export class Cargo {
     private async runCargo(
         cargoArgs: string[],
         onStdoutJson: (obj: any) => void,
-        onStderrString: (data: string) => void,
+        onStderrString: (data: string) => void
     ): Promise<number> {
         const path = await cargoPath();
         return await new Promise((resolve, reject) => {
@@ -172,7 +172,7 @@ export const getPathForExecutable = memoizeAsync(
             if (await isFileAtUri(standardPath)) return standardPath.fsPath;
         }
         return executableName;
-    },
+    }
 );
 
 async function lookupInPath(exec: string): Promise<boolean> {
diff --git a/editors/code/src/util.ts b/editors/code/src/util.ts
index 38ce676157..b6240234aa 100644
--- a/editors/code/src/util.ts
+++ b/editors/code/src/util.ts
@@ -1,6 +1,6 @@
 import * as vscode from "vscode";
 import { strict as nativeAssert } from "assert";
-import { exec, type ExecOptions, spawnSync } from "child_process";
+import { exec, ExecOptions, spawnSync } from "child_process";
 import { inspect } from "util";
 
 export function assert(condition: boolean, explanation: string): asserts condition {
@@ -114,7 +114,7 @@ export function setContextValue(key: string, value: any): Thenable<void> {
  * underlying async function.
  */
 export function memoizeAsync<Ret, TThis, Param extends string>(
-    func: (this: TThis, arg: Param) => Promise<Ret>,
+    func: (this: TThis, arg: Param) => Promise<Ret>
 ) {
     const cache = new Map<string, Ret>();
 
diff --git a/lib/line-index/src/lib.rs b/lib/line-index/src/lib.rs
index 03371c9c87..58db93a589 100644
--- a/lib/line-index/src/lib.rs
+++ b/lib/line-index/src/lib.rs
@@ -199,7 +199,7 @@ impl LineIndex {
     }
 }
 
-/// This is adapted from the rustc_span crate, https://github.com/rust-lang/rust/blob/de59844c98f7925242a798a72c59dc3610dd0e2c/compiler/rustc_span/src/analyze_source_file.rs
+/// This is adapted from the rustc_span crate, https://github.com/rust-lang/rust/blob/master/compiler/rustc_span/src/analyze_source_file.rs
 fn analyze_source_file(src: &str) -> (Vec<TextSize>, IntMap<u32, Box<[WideChar]>>) {
     assert!(src.len() < !0u32 as usize);
     let mut lines = vec![];
diff --git a/lib/lsp-server/Cargo.toml b/lib/lsp-server/Cargo.toml
index 01707d3019..d44b2d4e40 100644
--- a/lib/lsp-server/Cargo.toml
+++ b/lib/lsp-server/Cargo.toml
@@ -9,7 +9,7 @@ edition = "2021"
 [dependencies]
 log = "0.4.17"
 serde_json = "1.0.96"
-serde = { version = "1.0.156", features = ["derive"] }
+serde = "1.0.156"
 crossbeam-channel = "0.5.6"
 
 [dev-dependencies]
diff --git a/lib/lsp-server/src/msg.rs b/lib/lsp-server/src/msg.rs
index 730ad51f42..b241561f9c 100644
--- a/lib/lsp-server/src/msg.rs
+++ b/lib/lsp-server/src/msg.rs
@@ -265,7 +265,7 @@ fn read_msg_text(inp: &mut dyn BufRead) -> io::Result<Option<String>> {
         let header_name = parts.next().unwrap();
         let header_value =
             parts.next().ok_or_else(|| invalid_data!("malformed header: {:?}", buf))?;
-        if header_name.eq_ignore_ascii_case("Content-Length") {
+        if header_name == "Content-Length" {
             size = Some(header_value.parse::<usize>().map_err(invalid_data)?);
         }
     }
diff --git a/xtask/src/publish.rs b/xtask/src/publish.rs
index 7faae9b20c..42b384ead0 100644
--- a/xtask/src/publish.rs
+++ b/xtask/src/publish.rs
@@ -79,7 +79,6 @@ fn update_release(sh: &Shell, tag_name: &str, release_notes: &str) -> anyhow::Re
     let release_id = cmd!(sh, "jq .id").stdin(release_json).read()?;
 
     let mut patch = String::new();
-    // note: the GitHub API doesn't update the target commit if the tag already exists
     write_json::object(&mut patch)
         .string("tag_name", tag_name)
         .string("target_commitish", "master")


Test patch:
diff --git a/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs b/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
index 145cf8ddd4..abd84c6a46 100644
--- a/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
+++ b/crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs
@@ -416,6 +416,44 @@ fn test_hash_expand() {
 //- minicore: derive, hash
 use core::hash::Hash;
 
+#[derive(Hash)]
+struct Foo {
+    x: i32,
+    y: u64,
+    z: (i32, u64),
+}
+"#,
+        expect![[r#"
+use core::hash::Hash;
+
+#[derive(Hash)]
+struct Foo {
+    x: i32,
+    y: u64,
+    z: (i32, u64),
+}
+
+impl < > core::hash::Hash for Foo< > where {
+    fn hash<H: core::hash::Hasher>(&self , ra_expand_state: &mut H) {
+        match self {
+            Foo {
+                x: x, y: y, z: z,
+            }
+            => {
+                x.hash(ra_expand_state);
+                y.hash(ra_expand_state);
+                z.hash(ra_expand_state);
+            }
+            ,
+        }
+    }
+}"#]],
+    );
+    check(
+        r#"
+//- minicore: derive, hash
+use core::hash::Hash;
+
 #[derive(Hash)]
 enum Command {
     Move { x: i32, y: i32 },
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 b232651db9..3f17f64f2a 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
@@ -235,10 +235,10 @@ macro_rules! format_args {
 
 fn main() {
     /* error: no rule matches input tokens */;
-    /* error: expected expression */;
-    /* error: expected expression, expected COMMA */;
-    /* error: expected expression */::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(), ::core::fmt::Display::fmt), ]);
-    /* error: expected expression, expected R_PAREN */;
+    /* error: no rule matches input tokens */;
+    /* error: no rule matches input tokens */;
+    /* error: no rule matches input tokens */::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(), ::core::fmt::Display::fmt), ]);
+    /* error: no rule matches input tokens */;
     ::core::fmt::Arguments::new_v1(&["", ], &[::core::fmt::ArgumentV1::new(&(5), ::core::fmt::Display::fmt), ]);
 }
 "##]],
@@ -364,7 +364,7 @@ macro_rules! format_args {
 
 fn main() {
     let _ =
-        /* error: expected field name or number *//* parse error: expected field name or number */
+        /* error: no rule matches input tokens *//* parse error: expected field name or number */
 ::core::fmt::Arguments::new_v1(&["", " ", ], &[::core::fmt::ArgumentV1::new(&(a.), ::core::fmt::Display::fmt), ::core::fmt::ArgumentV1::new(&(), ::core::fmt::Debug::fmt), ]);
 }
 "##]],
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe.rs b/crates/hir-def/src/macro_expansion_tests/mbe.rs
index b26f986758..553ffe3d0b 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe.rs
@@ -98,42 +98,6 @@ fn#19 main#20(#21)#21 {#22
 "##]],
     );
 }
-
-#[test]
-fn token_mapping_eager() {
-    check(
-        r#"
-#[rustc_builtin_macro]
-#[macro_export]
-macro_rules! format_args {}
-
-macro_rules! identity {
-    ($expr:expr) => { $expr };
-}
-
-fn main(foo: ()) {
-    format_args/*+tokenids*/!("{} {} {}", format_args!("{}", 0), foo, identity!(10), "bar")
-}
-
-"#,
-        expect![[r##"
-#[rustc_builtin_macro]
-#[macro_export]
-macro_rules! format_args {}
-
-macro_rules! identity {
-    ($expr:expr) => { $expr };
-}
-
-fn main(foo: ()) {
-    // format_args/*+tokenids*/!("{} {} {}"#1,#3 format_args!("{}", 0#10),#12 foo#13,#14 identity!(10#18),#21 "bar"#22)
-::core#4294967295::fmt#4294967295::Arguments#4294967295::new_v1#4294967295(&#4294967295[#4294967295""#4294967295,#4294967295 " "#4294967295,#4294967295 " "#4294967295,#4294967295 ]#4294967295,#4294967295 &#4294967295[::core#4294967295::fmt#4294967295::ArgumentV1#4294967295::new#4294967295(&#4294967295(::core#4294967295::fmt#4294967295::Arguments#4294967295::new_v1#4294967295(&#4294967295[#4294967295""#4294967295,#4294967295 ]#4294967295,#4294967295 &#4294967295[::core#4294967295::fmt#4294967295::ArgumentV1#4294967295::new#4294967295(&#4294967295(#42949672950#10)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::Display#4294967295::fmt#4294967295)#4294967295,#4294967295 ]#4294967295)#4294967295)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::Display#4294967295::fmt#4294967295)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::ArgumentV1#4294967295::new#4294967295(&#4294967295(#4294967295foo#13)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::Display#4294967295::fmt#4294967295)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::ArgumentV1#4294967295::new#4294967295(&#4294967295(#429496729510#18)#4294967295,#4294967295 ::core#4294967295::fmt#4294967295::Display#4294967295::fmt#4294967295)#4294967295,#4294967295 ]#4294967295)#4294967295
-}
-
-"##]],
-    );
-}
-
 #[test]
 fn float_field_access_macro_input() {
     check(
diff --git a/crates/hir-def/src/macro_expansion_tests/mod.rs b/crates/hir-def/src/macro_expansion_tests/mod.rs
index 7a87e61c69..1c15c1b7f0 100644
--- a/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -187,7 +187,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
         let range: Range<usize> = range.into();
 
         if show_token_ids {
-            if let Some((tree, map, _)) = arg.value.as_deref() {
+            if let Some((tree, map, _)) = arg.as_deref() {
                 let tt_range = call.token_tree().unwrap().syntax().text_range();
                 let mut ranges = Vec::new();
                 extract_id_ranges(&mut ranges, map, tree);
diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs
index e32ae8b268..db5a43e067 100644
--- a/crates/hir-ty/src/consteval/tests.rs
+++ b/crates/hir-ty/src/consteval/tests.rs
@@ -1,11 +1,10 @@
 use base_db::{fixture::WithFixture, FileId};
 use chalk_ir::Substitution;
 use hir_def::db::DefDatabase;
-use test_utils::skip_slow_tests;
 
 use crate::{
     consteval::try_const_usize, db::HirDatabase, mir::pad16, test_db::TestDB, Const, ConstScalar,
-    Interner,
+    Interner, MemoryMap,
 };
 
 use super::{
@@ -37,7 +36,7 @@ fn check_fail(ra_fixture: &str, error: impl FnOnce(ConstEvalError) -> bool) {
 
 #[track_caller]
 fn check_number(ra_fixture: &str, answer: i128) {
-    check_answer(ra_fixture, |b| {
+    check_answer(ra_fixture, |b, _| {
         assert_eq!(
             b,
             &answer.to_le_bytes()[0..b.len()],
@@ -48,8 +47,26 @@ fn check_number(ra_fixture: &str, answer: i128) {
 }
 
 #[track_caller]
-fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8])) {
-    let (db, file_id) = TestDB::with_single_file(ra_fixture);
+fn check_str(ra_fixture: &str, answer: &str) {
+    check_answer(ra_fixture, |b, mm| {
+        let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
+        let size = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
+        let Some(bytes) = mm.get(addr, size) else {
+            panic!("string data missed in the memory map");
+        };
+        assert_eq!(
+            bytes,
+            answer.as_bytes(),
+            "Bytes differ. In string form: actual = {}, expected = {answer}",
+            String::from_utf8_lossy(bytes)
+        );
+    });
+}
+
+#[track_caller]
+fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8], &MemoryMap)) {
+    let (db, file_ids) = TestDB::with_many_files(ra_fixture);
+    let file_id = *file_ids.last().unwrap();
     let r = match eval_goal(&db, file_id) {
         Ok(t) => t,
         Err(e) => {
@@ -59,8 +76,8 @@ fn check_answer(ra_fixture: &str, check: impl FnOnce(&[u8])) {
     };
     match &r.data(Interner).value {
         chalk_ir::ConstValue::Concrete(c) => match &c.interned {
-            ConstScalar::Bytes(b, _) => {
-                check(b);
+            ConstScalar::Bytes(b, mm) => {
+                check(b, mm);
             }
             x => panic!("Expected number but found {:?}", x),
         },
@@ -225,7 +242,7 @@ const GOAL: usize = {
     transmute(&x)
 }
         "#,
-        |b| assert_eq!(b[0] % 8, 0),
+        |b, _| assert_eq!(b[0] % 8, 0),
     );
     check_answer(
         r#"
@@ -234,7 +251,7 @@ use core::mem::transmute;
 static X: i64 = 12;
 const GOAL: usize = transmute(&X);
         "#,
-        |b| assert_eq!(b[0] % 8, 0),
+        |b, _| assert_eq!(b[0] % 8, 0),
     );
 }
 
@@ -2068,6 +2085,17 @@ fn array_and_index() {
     );
 }
 
+#[test]
+fn string() {
+    check_str(
+        r#"
+    //- minicore: coerce_unsized, index, slice
+    const GOAL: &str = "hello";
+        "#,
+        "hello",
+    );
+}
+
 #[test]
 fn byte_string() {
     check_number(
@@ -2444,6 +2472,25 @@ fn const_trait_assoc() {
     "#,
         32,
     );
+    check_number(
+        r#"
+    //- /a/lib.rs crate:a
+    pub trait ToConst {
+        const VAL: usize;
+    }
+    pub const fn to_const<T: ToConst>() -> usize {
+        T::VAL
+    }
+    //- /main.rs crate:main deps:a
+    use a::{ToConst, to_const};
+    struct U0;
+    impl ToConst for U0 {
+        const VAL: usize = 5;
+    }
+    const GOAL: usize = to_const::<U0>();
+    "#,
+        5,
+    );
     check_number(
         r#"
     struct S<T>(*mut T);
@@ -2471,10 +2518,6 @@ fn const_trait_assoc() {
 
 #[test]
 fn exec_limits() {
-    if skip_slow_tests() {
-        return;
-    }
-
     check_fail(
         r#"
     const GOAL: usize = loop {};
diff --git a/crates/hir-ty/src/consteval/tests/intrinsics.rs b/crates/hir-ty/src/consteval/tests/intrinsics.rs
index 30e87661ab..9253e31d77 100644
--- a/crates/hir-ty/src/consteval/tests/intrinsics.rs
+++ b/crates/hir-ty/src/consteval/tests/intrinsics.rs
@@ -149,6 +149,36 @@ fn min_align_of_val() {
     );
 }
 
+#[test]
+fn type_name() {
+    check_str(
+        r#"
+        extern "rust-intrinsic" {
+            pub fn type_name<T: ?Sized>() -> &'static str;
+        }
+
+        const GOAL: &str = type_name::<i32>();
+        "#,
+        "i32",
+    );
+    check_str(
+        r#"
+        extern "rust-intrinsic" {
+            pub fn type_name<T: ?Sized>() -> &'static str;
+        }
+
+        mod mod1 {
+            pub mod mod2 {
+                pub struct Ty;
+            }
+        }
+
+        const GOAL: &str = type_name::<mod1::mod2::Ty>();
+        "#,
+        "mod1::mod2::Ty",
+    );
+}
+
 #[test]
 fn transmute() {
     check_number(
diff --git a/crates/hir-ty/src/layout/tests.rs b/crates/hir-ty/src/layout/tests.rs
index 2b74f1a1a1..a3ced2bac0 100644
--- a/crates/hir-ty/src/layout/tests.rs
+++ b/crates/hir-ty/src/layout/tests.rs
@@ -464,3 +464,41 @@ fn enums_with_discriminants() {
         }
     }
 }
+
+#[test]
+fn core_mem_discriminant() {
+    size_and_align! {
+        minicore: discriminant;
+        struct S(i32, u64);
+        struct Goal(core::mem::Discriminant<S>);
+    }
+    size_and_align! {
+        minicore: discriminant;
+        #[repr(u32)]
+        enum S {
+            A,
+            B,
+            C,
+        }
+        struct Goal(core::mem::Discriminant<S>);
+    }
+    size_and_align! {
+        minicore: discriminant;
+        enum S {
+            A(i32),
+            B(i64),
+            C(u8),
+        }
+        struct Goal(core::mem::Discriminant<S>);
+    }
+    size_and_align! {
+        minicore: discriminant;
+        #[repr(C, u16)]
+        enum S {
+            A(i32),
+            B(i64) = 200,
+            C = 1000,
+        }
+        struct Goal(core::mem::Discriminant<S>);
+    }
+}
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 f4f164aa1d..fa374b04f1 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -161,7 +161,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
     <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">"</span><span class="escape_sequence">\x28</span><span class="escape_sequence">\x28</span><span class="escape_sequence">\x00</span><span class="escape_sequence">\x63</span><span class="escape_sequence">\n</span><span class="string_literal">"</span><span class="semicolon">;</span>
     <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">b"</span><span class="escape_sequence">\x28</span><span class="escape_sequence">\x28</span><span class="escape_sequence">\x00</span><span class="escape_sequence">\x63</span><span class="escape_sequence">\n</span><span class="string_literal">"</span><span class="semicolon">;</span>
-    <span class="keyword">let</span> <span class="variable declaration reference">backslash</span> <span class="operator">=</span> <span class="string_literal">r"\\"</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">r"\\"</span><span class="semicolon">;</span>
 
     <span class="macro">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="escape_sequence">\x41</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="none macro">A</span> <span class="operator macro">=</span> <span class="numeric_literal macro">92</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
     <span class="macro">println</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">ничоси</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="none macro">ничоси</span> <span class="operator macro">=</span> <span class="numeric_literal macro">92</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
@@ -173,6 +173,6 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="macro">assert</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="bool_literal macro">true</span><span class="comma macro">,</span> <span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> asdasd"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
     <span class="macro">toho</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">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="macro unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"mov eax, </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="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">concat</span><span class="punctuation 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="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">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="comma macro">,</span> <span class="none macro">backslash</span><span class="comma macro">,</span> <span class="none macro">format_args</span><span class="punctuation 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="none macro">foo</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="none macro">toho</span><span class="punctuation macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="none macro">backslash</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">concat</span><span class="punctuation 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="parenthesis macro">)</span><span class="comma 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="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro">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="comma macro">,</span> <span class="none macro">format_args</span><span class="operator 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="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 1ee451a06d..497992f684 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -507,7 +507,7 @@ fn main() {
 
     let _ = "\x28\x28\x00\x63\n";
     let _ = b"\x28\x28\x00\x63\n";
-    let backslash = r"\\";
+    let _ = r"\\";
 
     println!("{\x41}", A = 92);
     println!("{ничоси}", ничоси = 92);
@@ -520,7 +520,7 @@ fn main() {
     toho!("{}fmt", 0);
     asm!("mov eax, {0}");
     format_args!(concat!("{}"), "{}");
-    format_args!("{} {} {} {} {} {}", backslash, format_args!("{}", 0), foo, "bar", toho!(), backslash);
+    format_args!("{}", format_args!("{}", 0));
 }"#,
         expect_file!["./test_data/highlight_strings.html"],
         false,
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index ebde017686..c765f42447 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -364,6 +364,11 @@ pub mod mem {
         pub fn size_of<T>() -> usize;
     }
     // endregion:size_of
+
+    // region:discriminant
+    use crate::marker::DiscriminantKind;
+    pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
+    // endregion:discriminant
 }
 
 pub mod ptr {
diff --git a/editors/code/tests/unit/index.ts b/editors/code/tests/unit/index.ts
index 8ad46546ab..c231927bb0 100644
--- a/editors/code/tests/unit/index.ts
+++ b/editors/code/tests/unit/index.ts
@@ -63,7 +63,7 @@ export async function run(): Promise<void> {
     const context = new Context();
 
     const testFiles = (await readdir(path.resolve(__dirname))).filter((name) =>
-        name.endsWith(".test.js"),
+        name.endsWith(".test.js")
     );
     for (const testFile of testFiles) {
         try {
diff --git a/editors/code/tests/unit/launch_config.test.ts b/editors/code/tests/unit/launch_config.test.ts
index eeb8608a42..0531e064d2 100644
--- a/editors/code/tests/unit/launch_config.test.ts
+++ b/editors/code/tests/unit/launch_config.test.ts
@@ -1,6 +1,6 @@
 import * as assert from "assert";
 import { Cargo } from "../../src/toolchain";
-import type { Context } from ".";
+import { Context } from ".";
 
 export async function getTests(ctx: Context) {
     await ctx.suite("Launch configuration/Lens", (suite) => {
diff --git a/editors/code/tests/unit/runnable_env.test.ts b/editors/code/tests/unit/runnable_env.test.ts
index b1407ce019..b7d59e399d 100644
--- a/editors/code/tests/unit/runnable_env.test.ts
+++ b/editors/code/tests/unit/runnable_env.test.ts
@@ -1,8 +1,8 @@
 import * as assert from "assert";
 import { prepareEnv } from "../../src/run";
-import type { RunnableEnvCfg } from "../../src/config";
-import type { Context } from ".";
-import type * as ra from "../../src/lsp_ext";
+import { RunnableEnvCfg } from "../../src/config";
+import { Context } from ".";
+import * as ra from "../../src/lsp_ext";
 
 function makeRunnable(label: string): ra.Runnable {
     return {
diff --git a/editors/code/tests/unit/settings.test.ts b/editors/code/tests/unit/settings.test.ts
index bafb9569a1..f171f5f74f 100644
--- a/editors/code/tests/unit/settings.test.ts
+++ b/editors/code/tests/unit/settings.test.ts
@@ -1,5 +1,5 @@
 import * as assert from "assert";
-import type { Context } from ".";
+import { Context } from ".";
 import { substituteVariablesInEnv } from "../../src/config";
 
 export async function getTests(ctx: Context) {