From 61d1c3e1385be65abc197115817c28fbeb3294d6 Mon Sep 17 00:00:00 2001
From: hkalbasi <hamidrezakalbasi@protonmail.com>
Date: Thu, 28 Jul 2022 22:38:20 +0430
Subject: [PATCH 01/39] add debug impl for AnyDiagnostic

---
 crates/hir/src/diagnostics.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index 6c6c11ea4ebdc..50374f4b3fe47 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -14,6 +14,7 @@ use crate::{MacroKind, Type};
 
 macro_rules! diagnostics {
     ($($diag:ident,)*) => {
+        #[derive(Debug)]
         pub enum AnyDiagnostic {$(
             $diag(Box<$diag>),
         )*}

From c1a175f61e3584eb7c4ecf59a589a57447621461 Mon Sep 17 00:00:00 2001
From: hkalbasi <hamidrezakalbasi@protonmail.com>
Date: Thu, 28 Jul 2022 22:38:44 +0430
Subject: [PATCH 02/39] Generate rust type from json

---
 Cargo.lock                                    |   1 +
 crates/ide-diagnostics/Cargo.toml             |   1 +
 .../src/handlers/json_is_not_rust.rs          | 201 ++++++++++++++++++
 crates/ide-diagnostics/src/lib.rs             |   2 +
 4 files changed, 205 insertions(+)
 create mode 100644 crates/ide-diagnostics/src/handlers/json_is_not_rust.rs

diff --git a/Cargo.lock b/Cargo.lock
index 4c830006832c9..6c01b8a0dfd98 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -710,6 +710,7 @@ dependencies = [
  "ide-db",
  "itertools",
  "profile",
+ "serde_json",
  "sourcegen",
  "stdx",
  "syntax",
diff --git a/crates/ide-diagnostics/Cargo.toml b/crates/ide-diagnostics/Cargo.toml
index e221425edd5bf..9b9e21a4ddb59 100644
--- a/crates/ide-diagnostics/Cargo.toml
+++ b/crates/ide-diagnostics/Cargo.toml
@@ -15,6 +15,7 @@ itertools = "0.10.3"
 
 
 either = "1.7.0"
+serde_json = "1.0.82"
 
 profile = { path = "../profile", version = "0.0.0" }
 stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
new file mode 100644
index 0000000000000..aa7fcffb48ac3
--- /dev/null
+++ b/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
@@ -0,0 +1,201 @@
+//! This diagnostic provides an assist for creating a struct definition from a JSON
+//! example.
+
+use ide_db::{base_db::FileId, source_change::SourceChange};
+use itertools::Itertools;
+use stdx::format_to;
+use syntax::{
+    ast::{self, make},
+    SyntaxKind, SyntaxNode,
+};
+use text_edit::TextEdit;
+
+use crate::{fix, Diagnostic, Severity};
+
+#[derive(Default)]
+struct State {
+    result: String,
+    struct_counts: usize,
+}
+
+impl State {
+    fn generate_new_name(&mut self) -> ast::Name {
+        self.struct_counts += 1;
+        make::name(&format!("Struct{}", self.struct_counts))
+    }
+
+    fn build_struct(&mut self, value: &serde_json::Map<String, serde_json::Value>) -> ast::Type {
+        let name = self.generate_new_name();
+        let ty = make::ty(&name.to_string());
+        let strukt = make::struct_(
+            None,
+            name,
+            None,
+            make::record_field_list(value.iter().sorted_unstable_by_key(|x| x.0).map(
+                |(name, value)| make::record_field(None, make::name(name), self.type_of(value)),
+            ))
+            .into(),
+        );
+        format_to!(self.result, "#[derive(Serialize, Deserialize)]\n{}\n", strukt);
+        ty
+    }
+
+    fn type_of(&mut self, value: &serde_json::Value) -> ast::Type {
+        match value {
+            serde_json::Value::Null => make::ty_unit(),
+            serde_json::Value::Bool(_) => make::ty("bool"),
+            serde_json::Value::Number(x) => make::ty(if x.is_i64() { "i64" } else { "f64" }),
+            serde_json::Value::String(_) => make::ty("String"),
+            serde_json::Value::Array(x) => {
+                let ty = match x.iter().next() {
+                    Some(x) => self.type_of(x),
+                    None => make::ty_placeholder(),
+                };
+                make::ty(&format!("Vec<{ty}>"))
+            }
+            serde_json::Value::Object(x) => self.build_struct(x),
+        }
+    }
+}
+
+pub(crate) fn json_in_items(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &SyntaxNode) {
+    if node.kind() == SyntaxKind::ERROR
+        && node.first_token().map(|x| x.kind()) == Some(SyntaxKind::L_CURLY)
+        && node.last_token().map(|x| x.kind()) == Some(SyntaxKind::R_CURLY)
+    {
+        let node_string = node.to_string();
+        if let Ok(x) = serde_json::from_str(&node_string) {
+            if let serde_json::Value::Object(x) = x {
+                let range = node.text_range();
+                let mut edit = TextEdit::builder();
+                edit.delete(range);
+                let mut state = State::default();
+                state.build_struct(&x);
+                edit.insert(range.start(), state.result);
+                acc.push(
+                    Diagnostic::new(
+                        "json-is-not-rust",
+                        "JSON syntax is not valid as a Rust item",
+                        range,
+                    )
+                    .severity(Severity::WeakWarning)
+                    .with_fixes(Some(vec![fix(
+                        "convert_json_to_struct",
+                        "Convert JSON to struct",
+                        SourceChange::from_text_edit(file_id, edit.finish()),
+                        range,
+                    )])),
+                );
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        tests::{check_diagnostics_with_config, check_fix, check_no_fix},
+        DiagnosticsConfig,
+    };
+
+    #[test]
+    fn diagnostic_for_simple_case() {
+        let mut config = DiagnosticsConfig::default();
+        config.disabled.insert("syntax-error".to_string());
+        check_diagnostics_with_config(
+            config,
+            r#"
+            { "foo": "bar" }
+         // ^^^^^^^^^^^^^^^^ 💡 weak: JSON syntax is not valid as a Rust item
+"#,
+        );
+    }
+
+    #[test]
+    fn types_of_primitives() {
+        check_fix(
+            r#"
+            {$0
+                "foo": "bar",
+                "bar": 2.3,
+                "baz": null,
+                "bay": 57,
+                "box": true
+            }
+            "#,
+            r#"
+            #[derive(Serialize, Deserialize)]
+            struct Struct1{ bar: f64, bay: i64, baz: (), r#box: bool, foo: String }
+
+            "#,
+        );
+    }
+
+    #[test]
+    fn nested_structs() {
+        check_fix(
+            r#"
+            {$0
+                "foo": "bar",
+                "bar": {
+                    "kind": "Object",
+                    "value": {}
+                }
+            }
+            "#,
+            r#"
+            #[derive(Serialize, Deserialize)]
+            struct Struct3{  }
+            #[derive(Serialize, Deserialize)]
+            struct Struct2{ kind: String, value: Struct3 }
+            #[derive(Serialize, Deserialize)]
+            struct Struct1{ bar: Struct2, foo: String }
+
+            "#,
+        );
+    }
+
+    #[test]
+    fn arrays() {
+        check_fix(
+            r#"
+            {
+                "of_string": ["foo", "2", "x"], $0
+                "of_object": [{
+                    "x": 10,
+                    "y": 20
+                }, {
+                    "x": 10,
+                    "y": 20
+                }],
+                "nested": [[[2]]],
+                "empty": []
+            }
+            "#,
+            r#"
+            #[derive(Serialize, Deserialize)]
+            struct Struct2{ x: i64, y: i64 }
+            #[derive(Serialize, Deserialize)]
+            struct Struct1{ empty: Vec<_>, nested: Vec<Vec<Vec<i64>>>, of_object: Vec<Struct2>, of_string: Vec<String> }
+
+            "#,
+        );
+    }
+
+    #[test]
+    fn no_emit_outside_of_item_position() {
+        check_no_fix(
+            r#"
+            fn foo() {
+                let json = {$0
+                    "foo": "bar",
+                    "bar": {
+                        "kind": "Object",
+                        "value": {}
+                    }
+                };
+            }
+            "#,
+        );
+    }
+}
diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs
index 41abaa836f5fd..7034f010e1b0c 100644
--- a/crates/ide-diagnostics/src/lib.rs
+++ b/crates/ide-diagnostics/src/lib.rs
@@ -50,6 +50,7 @@ mod handlers {
     pub(crate) mod field_shorthand;
     pub(crate) mod useless_braces;
     pub(crate) mod unlinked_file;
+    pub(crate) mod json_is_not_rust;
 }
 
 #[cfg(test)]
@@ -175,6 +176,7 @@ pub fn diagnostics(
     for node in parse.tree().syntax().descendants() {
         handlers::useless_braces::useless_braces(&mut res, file_id, &node);
         handlers::field_shorthand::field_shorthand(&mut res, file_id, &node);
+        handlers::json_is_not_rust::json_in_items(&mut res, file_id, &node);
     }
 
     let module = sema.to_module_def(file_id);

From 5cb3e7a41b89b5612cefe9c688f0ffdff18d4df4 Mon Sep 17 00:00:00 2001
From: fprasx <felix725@gmail.com>
Date: Wed, 3 Aug 2022 14:44:21 -0400
Subject: [PATCH 03/39] Added fixup for match statements w/ missing parts

Passes tests
---
 crates/hir-expand/src/fixup.rs | 111 ++++++++++++++++++++++++++++++++-
 1 file changed, 110 insertions(+), 1 deletion(-)

diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index e46f43a878fe1..c875b23b2dcd3 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -67,7 +67,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
             preorder.skip_subtree();
             continue;
         }
-
         // In some other situations, we can fix things by just appending some tokens.
         let end_range = TextRange::empty(node.text_range().end());
         match_ast! {
@@ -195,6 +194,69 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
                 },
                 // FIXME: foo::
                 // FIXME: for, match etc.
+                ast::MatchExpr(it) => {
+                    if it.expr().is_none() {
+                        let match_token = match it.match_token() {
+                            Some(t) => t,
+                            None => continue
+                        };
+                        append.insert(match_token.into(), vec![
+                            SyntheticToken {
+                                kind: SyntaxKind::IDENT,
+                                text: "__ra_fixup".into(),
+                                range: end_range,
+                                id: EMPTY_ID
+                            },
+                        ]);
+                    }
+                    if it.match_arm_list().is_none() {
+                        // No match arms
+                        append.insert(node.clone().into(), vec![
+                            SyntheticToken {
+                                kind: SyntaxKind::L_CURLY,
+                                text: "{".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::UNDERSCORE,
+                                text: "_".into(),
+                                range: end_range,
+                                id: EMPTY_ID
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::EQ,
+                                text: "=".into(),
+                                range: end_range,
+                                id: EMPTY_ID
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::R_ANGLE,
+                                text: ">".into(),
+                                range: end_range,
+                                id: EMPTY_ID
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::L_CURLY,
+                                text: "{".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::R_CURLY,
+                                text: "}".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::R_CURLY,
+                                text: "}".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                        ]);
+                    }
+                },
                 _ => (),
             }
         }
@@ -287,6 +349,53 @@ mod tests {
         assert_eq!(tt.to_string(), original_as_tt.to_string());
     }
 
+
+    #[test]
+    fn match_no_expr_no_arms() {
+        check(
+            r#"
+fn foo() {
+    match
+}
+"#,
+            expect![[r#"
+fn foo () {match __ra_fixup {_ => {}}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn match_expr_no_arms() {
+        check(
+            r#"
+fn foo() {
+    match x {
+
+    }
+}
+"#,
+            expect![[r#"
+fn foo () {match x {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn match_no_expr() {
+        check(
+            r#"
+fn foo() {
+    match {
+        _ => {}
+    }
+}
+"#,
+            expect![[r#"
+fn foo () {match __ra_fixup {_ => {}}}
+"#]],
+        )
+    }
+
     #[test]
     fn incomplete_field_expr_1() {
         check(

From d513b4c8baaf2c71e5f13ce790bd0083ccb81a64 Mon Sep 17 00:00:00 2001
From: fprasx <felix725@gmail.com>
Date: Wed, 3 Aug 2022 15:51:30 -0400
Subject: [PATCH 04/39] Added fixup for for loops w/ missing parts

---
 crates/hir-expand/src/fixup.rs | 78 +++++++++++++++++++++++++++++++++-
 1 file changed, 77 insertions(+), 1 deletion(-)

diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index c875b23b2dcd3..ade28f27bf1cc 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -193,7 +193,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
                     }
                 },
                 // FIXME: foo::
-                // FIXME: for, match etc.
                 ast::MatchExpr(it) => {
                     if it.expr().is_none() {
                         let match_token = match it.match_token() {
@@ -257,6 +256,42 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
                         ]);
                     }
                 },
+                ast::ForExpr(it) => {
+                    let for_token = match it.for_token() {
+                        Some(token) => token,
+                        None => continue
+                    };
+
+                    let [pat, in_token, iter] = [
+                        (SyntaxKind::UNDERSCORE, "_"), 
+                        (SyntaxKind::IN_KW, "in"), 
+                        (SyntaxKind::IDENT, "__ra_fixup")
+                    ].map(|(kind, text)| SyntheticToken { kind, text: text.into(), range: end_range, id: EMPTY_ID});
+
+                    if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() {
+                        append.insert(for_token.into(), vec![pat, in_token, iter]);
+                    } 
+
+                    // Tricky: add logic to add in just a pattern or iterable if not all
+                    // the pieces are missing
+
+                    if it.loop_body().is_none() {
+                        append.insert(node.clone().into(), vec![
+                            SyntheticToken {
+                                kind: SyntaxKind::L_CURLY,
+                                text: "{".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                            SyntheticToken {
+                                kind: SyntaxKind::R_CURLY,
+                                text: "}".into(),
+                                range: end_range,
+                                id: EMPTY_ID,
+                            },
+                        ]);
+                    }
+                },
                 _ => (),
             }
         }
@@ -349,6 +384,47 @@ mod tests {
         assert_eq!(tt.to_string(), original_as_tt.to_string());
     }
 
+    #[test]
+    fn for_no_iter_no_body() {
+        check(
+            r#"
+fn foo() {
+    for
+}
+"#,
+            expect![[r#"
+fn foo () {for _ in __ra_fixup {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn for_no_iter() {
+        check(
+            r#"
+fn foo() {
+    for {}
+}
+"#,
+            expect![[r#"
+fn foo () {for _ in __ra_fixup {}}
+"#]],
+        )
+    }
+
+    #[test]
+    fn for_no_body() {
+        check(
+            r#"
+fn foo() {
+    for bar in qux
+}
+"#,
+            expect![[r#"
+fn foo () {for bar in qux {}}
+"#]],
+        )
+    }
 
     #[test]
     fn match_no_expr_no_arms() {

From ef2eabbfa84fb11deda705df724b28ef3431256c Mon Sep 17 00:00:00 2001
From: fprasx <felix725@gmail.com>
Date: Wed, 3 Aug 2022 16:27:43 -0400
Subject: [PATCH 05/39] Tidy formatted

---
 crates/hir-expand/src/fixup.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index ade28f27bf1cc..cd02c802e50e6 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -263,14 +263,14 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
                     };
 
                     let [pat, in_token, iter] = [
-                        (SyntaxKind::UNDERSCORE, "_"), 
-                        (SyntaxKind::IN_KW, "in"), 
+                        (SyntaxKind::UNDERSCORE, "_"),
+                        (SyntaxKind::IN_KW, "in"),
                         (SyntaxKind::IDENT, "__ra_fixup")
                     ].map(|(kind, text)| SyntheticToken { kind, text: text.into(), range: end_range, id: EMPTY_ID});
 
                     if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() {
                         append.insert(for_token.into(), vec![pat, in_token, iter]);
-                    } 
+                    }
 
                     // Tricky: add logic to add in just a pattern or iterable if not all
                     // the pieces are missing

From d6d8a1c18f29ad6402f9594e3908cbb6d80aa31c Mon Sep 17 00:00:00 2001
From: fprasx <felix725@gmail.com>
Date: Thu, 4 Aug 2022 09:28:25 -0400
Subject: [PATCH 06/39] Shortened fixup for match, added cases for for

Previously added a blank _ => {} for match statements
---
 crates/hir-expand/src/fixup.rs | 53 ++++++++++++----------------------
 1 file changed, 18 insertions(+), 35 deletions(-)

diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index cd02c802e50e6..58d73f2d6c016 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -211,30 +211,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
                     if it.match_arm_list().is_none() {
                         // No match arms
                         append.insert(node.clone().into(), vec![
-                            SyntheticToken {
-                                kind: SyntaxKind::L_CURLY,
-                                text: "{".into(),
-                                range: end_range,
-                                id: EMPTY_ID,
-                            },
-                            SyntheticToken {
-                                kind: SyntaxKind::UNDERSCORE,
-                                text: "_".into(),
-                                range: end_range,
-                                id: EMPTY_ID
-                            },
-                            SyntheticToken {
-                                kind: SyntaxKind::EQ,
-                                text: "=".into(),
-                                range: end_range,
-                                id: EMPTY_ID
-                            },
-                            SyntheticToken {
-                                kind: SyntaxKind::R_ANGLE,
-                                text: ">".into(),
-                                range: end_range,
-                                id: EMPTY_ID
-                            },
                             SyntheticToken {
                                 kind: SyntaxKind::L_CURLY,
                                 text: "{".into(),
@@ -247,12 +223,6 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
                                 range: end_range,
                                 id: EMPTY_ID,
                             },
-                            SyntheticToken {
-                                kind: SyntaxKind::R_CURLY,
-                                text: "}".into(),
-                                range: end_range,
-                                id: EMPTY_ID,
-                            },
                         ]);
                     }
                 },
@@ -270,11 +240,12 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
 
                     if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() {
                         append.insert(for_token.into(), vec![pat, in_token, iter]);
+                    } else if it.pat().is_none() {
+                        append.insert(for_token.into(), vec![pat]);
+                    } else if it.pat().is_none() && it.in_token().is_none() {
+                        append.insert(for_token.into(), vec![pat, in_token]);
                     }
 
-                    // Tricky: add logic to add in just a pattern or iterable if not all
-                    // the pieces are missing
-
                     if it.loop_body().is_none() {
                         append.insert(node.clone().into(), vec![
                             SyntheticToken {
@@ -398,6 +369,18 @@ fn foo () {for _ in __ra_fixup {}}
         )
     }
 
+    fn for_no_iter_no_in() {
+        check(
+            r#"
+fn foo() {
+    for _ {}
+}
+"#,
+            expect![[r#"
+fn foo () {for _ in __ra_fixup {}}
+"#]],
+        )
+    }
     #[test]
     fn for_no_iter() {
         check(
@@ -435,7 +418,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-fn foo () {match __ra_fixup {_ => {}}}
+fn foo () {match __ra_fixup {}}
 "#]],
         )
     }
@@ -467,7 +450,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-fn foo () {match __ra_fixup {_ => {}}}
+fn foo () {match __ra_fixup {}}
 "#]],
         )
     }

From ab44a811501c12c4e3c471387f02ad451034639f Mon Sep 17 00:00:00 2001
From: fprasx <felix725@gmail.com>
Date: Thu, 4 Aug 2022 10:43:09 -0400
Subject: [PATCH 07/39] Fixed up for loops, added fixme with problem

https://github.com/rust-lang/rust-analyzer/pull/12937#discussion_r937633695
---
 crates/hir-expand/src/fixup.rs | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index 58d73f2d6c016..46257b6bc4dce 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -240,10 +240,9 @@ pub(crate) fn fixup_syntax(node: &SyntaxNode) -> SyntaxFixups {
 
                     if it.pat().is_none() && it.in_token().is_none() && it.iterable().is_none() {
                         append.insert(for_token.into(), vec![pat, in_token, iter]);
+                    // does something funky -- see test case for_no_pat
                     } else if it.pat().is_none() {
                         append.insert(for_token.into(), vec![pat]);
-                    } else if it.pat().is_none() && it.in_token().is_none() {
-                        append.insert(for_token.into(), vec![pat, in_token]);
                     }
 
                     if it.loop_body().is_none() {
@@ -356,7 +355,7 @@ mod tests {
     }
 
     #[test]
-    fn for_no_iter_no_body() {
+    fn just_for_token() {
         check(
             r#"
 fn foo() {
@@ -369,11 +368,12 @@ fn foo () {for _ in __ra_fixup {}}
         )
     }
 
-    fn for_no_iter_no_in() {
+    #[test]
+    fn for_no_iter_pattern() {
         check(
             r#"
 fn foo() {
-    for _ {}
+    for {}
 }
 "#,
             expect![[r#"
@@ -381,30 +381,34 @@ fn foo () {for _ in __ra_fixup {}}
 "#]],
         )
     }
+
     #[test]
-    fn for_no_iter() {
+    fn for_no_body() {
         check(
             r#"
 fn foo() {
-    for {}
+    for bar in qux
 }
 "#,
             expect![[r#"
-fn foo () {for _ in __ra_fixup {}}
+fn foo () {for bar in qux {}}
 "#]],
         )
     }
 
+    // FIXME: https://github.com/rust-lang/rust-analyzer/pull/12937#discussion_r937633695
     #[test]
-    fn for_no_body() {
+    fn for_no_pat() {
         check(
             r#"
 fn foo() {
-    for bar in qux
+    for in qux {
+
+    }
 }
 "#,
             expect![[r#"
-fn foo () {for bar in qux {}}
+fn foo () {__ra_fixup}
 "#]],
         )
     }

From 859d467276bf45e621858069192d7a68c42d2a32 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida <low.ryoshida@gmail.com>
Date: Fri, 5 Aug 2022 02:51:38 +0900
Subject: [PATCH 08/39] fix: make `concat!` work with char

---
 .../src/macro_expansion_tests/builtin_fn_macro.rs  |  4 ++--
 crates/hir-expand/src/builtin_fn_macro.rs          | 14 ++++++++++++--
 2 files changed, 14 insertions(+), 4 deletions(-)

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 92dffa7f372e6..32006c4b43e19 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
@@ -295,13 +295,13 @@ fn test_concat_expand() {
 #[rustc_builtin_macro]
 macro_rules! concat {}
 
-fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false); }
+fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false, '\n'); }
 "##,
         expect![[r##"
 #[rustc_builtin_macro]
 macro_rules! concat {}
 
-fn main() { "foor0bar\nfalse"; }
+fn main() { "foor0bar\nfalse\n"; }
 "##]],
     );
 }
diff --git a/crates/hir-expand/src/builtin_fn_macro.rs b/crates/hir-expand/src/builtin_fn_macro.rs
index 76da7c9f1ee82..c21b35cdc0917 100644
--- a/crates/hir-expand/src/builtin_fn_macro.rs
+++ b/crates/hir-expand/src/builtin_fn_macro.rs
@@ -357,6 +357,12 @@ fn unquote_str(lit: &tt::Literal) -> Option<String> {
     token.value().map(|it| it.into_owned())
 }
 
+fn unquote_char(lit: &tt::Literal) -> Option<char> {
+    let lit = ast::make::tokens::literal(&lit.to_string());
+    let token = ast::Char::cast(lit)?;
+    token.value()
+}
+
 fn unquote_byte_string(lit: &tt::Literal) -> Option<Vec<u8>> {
     let lit = ast::make::tokens::literal(&lit.to_string());
     let token = ast::ByteString::cast(lit)?;
@@ -408,8 +414,12 @@ fn concat_expand(
                 // concat works with string and char literals, so remove any quotes.
                 // It also works with integer, float and boolean literals, so just use the rest
                 // as-is.
-                let component = unquote_str(it).unwrap_or_else(|| it.text.to_string());
-                text.push_str(&component);
+                if let Some(c) = unquote_char(it) {
+                    text.push(c);
+                } else {
+                    let component = unquote_str(it).unwrap_or_else(|| it.text.to_string());
+                    text.push_str(&component);
+                }
             }
             // handle boolean literals
             tt::TokenTree::Leaf(tt::Leaf::Ident(id))

From 4d5873e92f50f3f08f98f04ade4768f9d9ab380f Mon Sep 17 00:00:00 2001
From: Ryo Yoshida <low.ryoshida@gmail.com>
Date: Fri, 5 Aug 2022 22:01:09 +0900
Subject: [PATCH 09/39] minor: align with rustc on escaping characters in macro
 expansion

---
 crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs | 4 ++--
 crates/hir-expand/src/quote.rs                               | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

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 32006c4b43e19..4f626105a53d6 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
@@ -295,13 +295,13 @@ fn test_concat_expand() {
 #[rustc_builtin_macro]
 macro_rules! concat {}
 
-fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false, '\n'); }
+fn main() { concat!("foo", "r", 0, r#"bar"#, "\n", false, '"', '\0'); }
 "##,
         expect![[r##"
 #[rustc_builtin_macro]
 macro_rules! concat {}
 
-fn main() { "foor0bar\nfalse\n"; }
+fn main() { "foor0bar\nfalse\"\u{0}"; }
 "##]],
     );
 }
diff --git a/crates/hir-expand/src/quote.rs b/crates/hir-expand/src/quote.rs
index 82f410ecda91d..e839e97bf02d8 100644
--- a/crates/hir-expand/src/quote.rs
+++ b/crates/hir-expand/src/quote.rs
@@ -196,8 +196,8 @@ impl_to_to_tokentrees! {
     tt::Literal => self { self };
     tt::Ident => self { self };
     tt::Punct => self { self };
-    &str => self { tt::Literal{text: format!("\"{}\"", self.escape_debug()).into(), id: tt::TokenId::unspecified()}};
-    String => self { tt::Literal{text: format!("\"{}\"", self.escape_debug()).into(), id: tt::TokenId::unspecified()}}
+    &str => self { tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), id: tt::TokenId::unspecified()}};
+    String => self { tt::Literal{text: format!("\"{}\"", self.escape_default()).into(), id: tt::TokenId::unspecified()}}
 }
 
 #[cfg(test)]

From fd00bd4d3b96109dcd1b9fb2ebfeb3b747776ad1 Mon Sep 17 00:00:00 2001
From: Jonas Schievink <jonas.schievink@ferrous-systems.com>
Date: Fri, 5 Aug 2022 15:28:53 +0200
Subject: [PATCH 10/39] Document CLI flag stability

---
 crates/rust-analyzer/src/cli/flags.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/crates/rust-analyzer/src/cli/flags.rs b/crates/rust-analyzer/src/cli/flags.rs
index 19907ebddb6ad..080e2fb443881 100644
--- a/crates/rust-analyzer/src/cli/flags.rs
+++ b/crates/rust-analyzer/src/cli/flags.rs
@@ -10,6 +10,10 @@ xflags::xflags! {
     src "./src/cli/flags.rs"
 
     /// LSP server for the Rust programming language.
+    ///
+    /// Subcommands and their flags do not provide any stability guarantees and may be removed or
+    /// changed without notice. Top-level flags that are not are marked as [Unstable] provide
+    /// backwards-compatibility and may be relied on.
     cmd rust-analyzer {
         /// Verbosity level, can be repeated multiple times.
         repeated -v, --verbose
@@ -21,7 +25,7 @@ xflags::xflags! {
         /// Flush log records to the file immediately.
         optional --no-log-buffering
 
-        /// Wait until a debugger is attached to (requires debug build).
+        /// [Unstable] Wait until a debugger is attached to (requires debug build).
         optional --wait-dbg
 
         default cmd lsp-server {

From 851f6db7f704587e4b5f0fb429a843d5f26f73c7 Mon Sep 17 00:00:00 2001
From: hkalbasi <hamidrezakalbasi@protonmail.com>
Date: Sat, 6 Aug 2022 19:21:51 +0430
Subject: [PATCH 11/39] Import serde derives on converting json to struct

---
 crates/ide-assists/src/assist_context.rs      | 157 +-------------
 .../convert_tuple_struct_to_named_struct.rs   |  10 +-
 .../src/handlers/destructure_tuple_binding.rs |  10 +-
 .../extract_struct_from_enum_variant.rs       |   4 +-
 .../src/handlers/generate_deref.rs            |   4 +-
 .../src/handlers/introduce_named_lifetime.rs  |   4 +-
 .../src/handlers/remove_unused_param.rs       |   5 +-
 .../replace_derive_with_manual_impl.rs        |   4 +-
 crates/ide-assists/src/utils.rs               |   4 +-
 crates/ide-db/src/source_change.rs            | 136 ++++++++++++-
 .../src/handlers/inactive_code.rs             |   2 +-
 .../src/handlers/json_is_not_rust.rs          | 191 ++++++++++++++----
 .../src/handlers/macro_error.rs               |   2 +-
 crates/ide-diagnostics/src/lib.rs             |  33 ++-
 crates/ide-diagnostics/src/tests.rs           |  12 +-
 crates/rust-analyzer/src/cli/diagnostics.rs   |   2 +-
 crates/rust-analyzer/src/config.rs            |   1 +
 17 files changed, 357 insertions(+), 224 deletions(-)

diff --git a/crates/ide-assists/src/assist_context.rs b/crates/ide-assists/src/assist_context.rs
index f9b4266142574..8c7670e0cb71a 100644
--- a/crates/ide-assists/src/assist_context.rs
+++ b/crates/ide-assists/src/assist_context.rs
@@ -1,28 +1,20 @@
 //! See [`AssistContext`].
 
-use std::mem;
-
 use hir::Semantics;
-use ide_db::{
-    base_db::{AnchoredPathBuf, FileId, FileRange},
-    SnippetCap,
-};
-use ide_db::{
-    label::Label,
-    source_change::{FileSystemEdit, SourceChange},
-    RootDatabase,
-};
+use ide_db::base_db::{FileId, FileRange};
+use ide_db::{label::Label, RootDatabase};
 use syntax::{
     algo::{self, find_node_at_offset, find_node_at_range},
-    AstNode, AstToken, Direction, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr,
-    SyntaxToken, TextRange, TextSize, TokenAtOffset,
+    AstNode, AstToken, Direction, SourceFile, SyntaxElement, SyntaxKind, SyntaxToken, TextRange,
+    TextSize, TokenAtOffset,
 };
-use text_edit::{TextEdit, TextEditBuilder};
 
 use crate::{
     assist_config::AssistConfig, Assist, AssistId, AssistKind, AssistResolveStrategy, GroupLabel,
 };
 
+pub(crate) use ide_db::source_change::{SourceChangeBuilder, TreeMutator};
+
 /// `AssistContext` allows to apply an assist or check if it could be applied.
 ///
 /// Assists use a somewhat over-engineered approach, given the current needs.
@@ -163,7 +155,7 @@ impl Assists {
         id: AssistId,
         label: impl Into<String>,
         target: TextRange,
-        f: impl FnOnce(&mut AssistBuilder),
+        f: impl FnOnce(&mut SourceChangeBuilder),
     ) -> Option<()> {
         let mut f = Some(f);
         self.add_impl(None, id, label.into(), target, &mut |it| f.take().unwrap()(it))
@@ -175,7 +167,7 @@ impl Assists {
         id: AssistId,
         label: impl Into<String>,
         target: TextRange,
-        f: impl FnOnce(&mut AssistBuilder),
+        f: impl FnOnce(&mut SourceChangeBuilder),
     ) -> Option<()> {
         let mut f = Some(f);
         self.add_impl(Some(group), id, label.into(), target, &mut |it| f.take().unwrap()(it))
@@ -187,7 +179,7 @@ impl Assists {
         id: AssistId,
         label: String,
         target: TextRange,
-        f: &mut dyn FnMut(&mut AssistBuilder),
+        f: &mut dyn FnMut(&mut SourceChangeBuilder),
     ) -> Option<()> {
         if !self.is_allowed(&id) {
             return None;
@@ -195,7 +187,7 @@ impl Assists {
 
         let mut trigger_signature_help = false;
         let source_change = if self.resolve.should_resolve(&id) {
-            let mut builder = AssistBuilder::new(self.file);
+            let mut builder = SourceChangeBuilder::new(self.file);
             f(&mut builder);
             trigger_signature_help = builder.trigger_signature_help;
             Some(builder.finish())
@@ -216,132 +208,3 @@ impl Assists {
         }
     }
 }
-
-pub(crate) struct AssistBuilder {
-    edit: TextEditBuilder,
-    file_id: FileId,
-    source_change: SourceChange,
-    trigger_signature_help: bool,
-
-    /// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin.
-    mutated_tree: Option<TreeMutator>,
-}
-
-pub(crate) struct TreeMutator {
-    immutable: SyntaxNode,
-    mutable_clone: SyntaxNode,
-}
-
-impl TreeMutator {
-    pub(crate) fn new(immutable: &SyntaxNode) -> TreeMutator {
-        let immutable = immutable.ancestors().last().unwrap();
-        let mutable_clone = immutable.clone_for_update();
-        TreeMutator { immutable, mutable_clone }
-    }
-
-    pub(crate) fn make_mut<N: AstNode>(&self, node: &N) -> N {
-        N::cast(self.make_syntax_mut(node.syntax())).unwrap()
-    }
-
-    pub(crate) fn make_syntax_mut(&self, node: &SyntaxNode) -> SyntaxNode {
-        let ptr = SyntaxNodePtr::new(node);
-        ptr.to_node(&self.mutable_clone)
-    }
-}
-
-impl AssistBuilder {
-    pub(crate) fn new(file_id: FileId) -> AssistBuilder {
-        AssistBuilder {
-            edit: TextEdit::builder(),
-            file_id,
-            source_change: SourceChange::default(),
-            trigger_signature_help: false,
-            mutated_tree: None,
-        }
-    }
-
-    pub(crate) fn edit_file(&mut self, file_id: FileId) {
-        self.commit();
-        self.file_id = file_id;
-    }
-
-    fn commit(&mut self) {
-        if let Some(tm) = self.mutated_tree.take() {
-            algo::diff(&tm.immutable, &tm.mutable_clone).into_text_edit(&mut self.edit)
-        }
-
-        let edit = mem::take(&mut self.edit).finish();
-        if !edit.is_empty() {
-            self.source_change.insert_source_edit(self.file_id, edit);
-        }
-    }
-
-    pub(crate) fn make_mut<N: AstNode>(&mut self, node: N) -> N {
-        self.mutated_tree.get_or_insert_with(|| TreeMutator::new(node.syntax())).make_mut(&node)
-    }
-    /// Returns a copy of the `node`, suitable for mutation.
-    ///
-    /// Syntax trees in rust-analyzer are typically immutable, and mutating
-    /// operations panic at runtime. However, it is possible to make a copy of
-    /// the tree and mutate the copy freely. Mutation is based on interior
-    /// mutability, and different nodes in the same tree see the same mutations.
-    ///
-    /// The typical pattern for an assist is to find specific nodes in the read
-    /// phase, and then get their mutable couterparts using `make_mut` in the
-    /// mutable state.
-    pub(crate) fn make_syntax_mut(&mut self, node: SyntaxNode) -> SyntaxNode {
-        self.mutated_tree.get_or_insert_with(|| TreeMutator::new(&node)).make_syntax_mut(&node)
-    }
-
-    /// Remove specified `range` of text.
-    pub(crate) fn delete(&mut self, range: TextRange) {
-        self.edit.delete(range)
-    }
-    /// Append specified `text` at the given `offset`
-    pub(crate) fn insert(&mut self, offset: TextSize, text: impl Into<String>) {
-        self.edit.insert(offset, text.into())
-    }
-    /// Append specified `snippet` at the given `offset`
-    pub(crate) fn insert_snippet(
-        &mut self,
-        _cap: SnippetCap,
-        offset: TextSize,
-        snippet: impl Into<String>,
-    ) {
-        self.source_change.is_snippet = true;
-        self.insert(offset, snippet);
-    }
-    /// Replaces specified `range` of text with a given string.
-    pub(crate) fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
-        self.edit.replace(range, replace_with.into())
-    }
-    /// Replaces specified `range` of text with a given `snippet`.
-    pub(crate) fn replace_snippet(
-        &mut self,
-        _cap: SnippetCap,
-        range: TextRange,
-        snippet: impl Into<String>,
-    ) {
-        self.source_change.is_snippet = true;
-        self.replace(range, snippet);
-    }
-    pub(crate) fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
-        algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
-    }
-    pub(crate) fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
-        let file_system_edit = FileSystemEdit::CreateFile { dst, initial_contents: content.into() };
-        self.source_change.push_file_system_edit(file_system_edit);
-    }
-    pub(crate) fn move_file(&mut self, src: FileId, dst: AnchoredPathBuf) {
-        let file_system_edit = FileSystemEdit::MoveFile { src, dst };
-        self.source_change.push_file_system_edit(file_system_edit);
-    }
-    pub(crate) fn trigger_signature_help(&mut self) {
-        self.trigger_signature_help = true;
-    }
-
-    fn finish(mut self) -> SourceChange {
-        self.commit();
-        mem::take(&mut self.source_change)
-    }
-}
diff --git a/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
index 4ab8e93a2909f..d8f522708460e 100644
--- a/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
+++ b/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
@@ -5,7 +5,7 @@ use syntax::{
     match_ast, SyntaxNode,
 };
 
-use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
+use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
 
 // Assist: convert_tuple_struct_to_named_struct
 //
@@ -80,7 +80,7 @@ pub(crate) fn convert_tuple_struct_to_named_struct(
 
 fn edit_struct_def(
     ctx: &AssistContext<'_>,
-    edit: &mut AssistBuilder,
+    edit: &mut SourceChangeBuilder,
     strukt: &Either<ast::Struct, ast::Variant>,
     tuple_fields: ast::TupleFieldList,
     names: Vec<ast::Name>,
@@ -122,7 +122,7 @@ fn edit_struct_def(
 
 fn edit_struct_references(
     ctx: &AssistContext<'_>,
-    edit: &mut AssistBuilder,
+    edit: &mut SourceChangeBuilder,
     strukt: Either<hir::Struct, hir::Variant>,
     names: &[ast::Name],
 ) {
@@ -132,7 +132,7 @@ fn edit_struct_references(
     };
     let usages = strukt_def.usages(&ctx.sema).include_self_refs().all();
 
-    let edit_node = |edit: &mut AssistBuilder, node: SyntaxNode| -> Option<()> {
+    let edit_node = |edit: &mut SourceChangeBuilder, node: SyntaxNode| -> Option<()> {
         match_ast! {
             match node {
                 ast::TupleStructPat(tuple_struct_pat) => {
@@ -203,7 +203,7 @@ fn edit_struct_references(
 
 fn edit_field_references(
     ctx: &AssistContext<'_>,
-    edit: &mut AssistBuilder,
+    edit: &mut SourceChangeBuilder,
     fields: impl Iterator<Item = ast::TupleField>,
     names: &[ast::Name],
 ) {
diff --git a/crates/ide-assists/src/handlers/destructure_tuple_binding.rs b/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
index c1f57532bb296..dc581ff3bd2c7 100644
--- a/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
+++ b/crates/ide-assists/src/handlers/destructure_tuple_binding.rs
@@ -8,7 +8,7 @@ use syntax::{
     TextRange,
 };
 
-use crate::assist_context::{AssistBuilder, AssistContext, Assists};
+use crate::assist_context::{AssistContext, Assists, SourceChangeBuilder};
 
 // Assist: destructure_tuple_binding
 //
@@ -151,7 +151,7 @@ struct TupleData {
 }
 fn edit_tuple_assignment(
     ctx: &AssistContext<'_>,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     data: &TupleData,
     in_sub_pattern: bool,
 ) {
@@ -195,7 +195,7 @@ fn edit_tuple_assignment(
 
 fn edit_tuple_usages(
     data: &TupleData,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     ctx: &AssistContext<'_>,
     in_sub_pattern: bool,
 ) {
@@ -211,7 +211,7 @@ fn edit_tuple_usages(
 }
 fn edit_tuple_usage(
     ctx: &AssistContext<'_>,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     usage: &FileReference,
     data: &TupleData,
     in_sub_pattern: bool,
@@ -239,7 +239,7 @@ fn edit_tuple_usage(
 
 fn edit_tuple_field_usage(
     ctx: &AssistContext<'_>,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     data: &TupleData,
     index: TupleIndex,
 ) {
diff --git a/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
index a93648f2d315a..dfb5652126467 100644
--- a/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ide-assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -20,7 +20,7 @@ use syntax::{
     SyntaxNode, T,
 };
 
-use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
+use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
 
 // Assist: extract_struct_from_enum_variant
 //
@@ -374,7 +374,7 @@ fn apply_references(
 
 fn process_references(
     ctx: &AssistContext<'_>,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     visited_modules: &mut FxHashSet<Module>,
     enum_module_def: &ModuleDef,
     variant_hir_name: &Name,
diff --git a/crates/ide-assists/src/handlers/generate_deref.rs b/crates/ide-assists/src/handlers/generate_deref.rs
index b9637ee8d7c60..b484635121eb2 100644
--- a/crates/ide-assists/src/handlers/generate_deref.rs
+++ b/crates/ide-assists/src/handlers/generate_deref.rs
@@ -8,7 +8,7 @@ use syntax::{
 };
 
 use crate::{
-    assist_context::{AssistBuilder, AssistContext, Assists},
+    assist_context::{AssistContext, Assists, SourceChangeBuilder},
     utils::generate_trait_impl_text,
     AssistId, AssistKind,
 };
@@ -120,7 +120,7 @@ fn generate_tuple_deref(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()
 }
 
 fn generate_edit(
-    edit: &mut AssistBuilder,
+    edit: &mut SourceChangeBuilder,
     strukt: ast::Struct,
     field_type_syntax: &SyntaxNode,
     field_name: impl Display,
diff --git a/crates/ide-assists/src/handlers/introduce_named_lifetime.rs b/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
index ce91dd23703b6..2fc754e3e50d1 100644
--- a/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
+++ b/crates/ide-assists/src/handlers/introduce_named_lifetime.rs
@@ -5,7 +5,7 @@ use syntax::{
     AstNode, TextRange,
 };
 
-use crate::{assist_context::AssistBuilder, AssistContext, AssistId, AssistKind, Assists};
+use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
 
 static ASSIST_NAME: &str = "introduce_named_lifetime";
 static ASSIST_LABEL: &str = "Introduce named lifetime";
@@ -140,7 +140,7 @@ enum NeedsLifetime {
 }
 
 impl NeedsLifetime {
-    fn make_mut(self, builder: &mut AssistBuilder) -> Self {
+    fn make_mut(self, builder: &mut SourceChangeBuilder) -> Self {
         match self {
             Self::SelfParam(it) => Self::SelfParam(builder.make_mut(it)),
             Self::RefType(it) => Self::RefType(builder.make_mut(it)),
diff --git a/crates/ide-assists/src/handlers/remove_unused_param.rs b/crates/ide-assists/src/handlers/remove_unused_param.rs
index 59ea94ea1ff6b..bd2e8fbe38966 100644
--- a/crates/ide-assists/src/handlers/remove_unused_param.rs
+++ b/crates/ide-assists/src/handlers/remove_unused_param.rs
@@ -8,7 +8,8 @@ use syntax::{
 use SyntaxKind::WHITESPACE;
 
 use crate::{
-    assist_context::AssistBuilder, utils::next_prev, AssistContext, AssistId, AssistKind, Assists,
+    assist_context::SourceChangeBuilder, utils::next_prev, AssistContext, AssistId, AssistKind,
+    Assists,
 };
 
 // Assist: remove_unused_param
@@ -88,7 +89,7 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) ->
 
 fn process_usages(
     ctx: &AssistContext<'_>,
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     file_id: FileId,
     references: Vec<FileReference>,
     arg_to_remove: usize,
diff --git a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
index bd50208da5ffd..d139f78a6f36b 100644
--- a/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/ide-assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -10,7 +10,7 @@ use syntax::{
 };
 
 use crate::{
-    assist_context::{AssistBuilder, AssistContext, Assists},
+    assist_context::{AssistContext, Assists, SourceChangeBuilder},
     utils::{
         add_trait_assoc_items_to_impl, filter_assoc_items, gen_trait_fn_body,
         generate_trait_impl_text, render_snippet, Cursor, DefaultMethods,
@@ -224,7 +224,7 @@ fn impl_def_from_trait(
 }
 
 fn update_attribute(
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     old_derives: &[ast::Path],
     old_tree: &ast::TokenTree,
     old_trait_path: &ast::Path,
diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs
index 3e61d0741d3fe..103e3259fa2ef 100644
--- a/crates/ide-assists/src/utils.rs
+++ b/crates/ide-assists/src/utils.rs
@@ -20,7 +20,7 @@ use syntax::{
     SyntaxNode, TextRange, TextSize, T,
 };
 
-use crate::assist_context::{AssistBuilder, AssistContext};
+use crate::assist_context::{AssistContext, SourceChangeBuilder};
 
 pub(crate) mod suggest_name;
 mod gen_trait_fn_body;
@@ -484,7 +484,7 @@ fn generate_impl_text_inner(adt: &ast::Adt, trait_text: Option<&str>, code: &str
 }
 
 pub(crate) fn add_method_to_adt(
-    builder: &mut AssistBuilder,
+    builder: &mut SourceChangeBuilder,
     adt: &ast::Adt,
     impl_def: Option<ast::Impl>,
     method: &str,
diff --git a/crates/ide-db/src/source_change.rs b/crates/ide-db/src/source_change.rs
index 8132c73ef26b0..21314ad74ef93 100644
--- a/crates/ide-db/src/source_change.rs
+++ b/crates/ide-db/src/source_change.rs
@@ -3,12 +3,15 @@
 //!
 //! It can be viewed as a dual for `Change`.
 
-use std::{collections::hash_map::Entry, iter};
+use std::{collections::hash_map::Entry, iter, mem};
 
 use base_db::{AnchoredPathBuf, FileId};
 use rustc_hash::FxHashMap;
 use stdx::never;
-use text_edit::TextEdit;
+use syntax::{algo, AstNode, SyntaxNode, SyntaxNodePtr, TextRange, TextSize};
+use text_edit::{TextEdit, TextEditBuilder};
+
+use crate::SnippetCap;
 
 #[derive(Default, Debug, Clone)]
 pub struct SourceChange {
@@ -81,6 +84,135 @@ impl From<FxHashMap<FileId, TextEdit>> for SourceChange {
     }
 }
 
+pub struct SourceChangeBuilder {
+    pub edit: TextEditBuilder,
+    pub file_id: FileId,
+    pub source_change: SourceChange,
+    pub trigger_signature_help: bool,
+
+    /// Maps the original, immutable `SyntaxNode` to a `clone_for_update` twin.
+    pub mutated_tree: Option<TreeMutator>,
+}
+
+pub struct TreeMutator {
+    immutable: SyntaxNode,
+    mutable_clone: SyntaxNode,
+}
+
+impl TreeMutator {
+    pub fn new(immutable: &SyntaxNode) -> TreeMutator {
+        let immutable = immutable.ancestors().last().unwrap();
+        let mutable_clone = immutable.clone_for_update();
+        TreeMutator { immutable, mutable_clone }
+    }
+
+    pub fn make_mut<N: AstNode>(&self, node: &N) -> N {
+        N::cast(self.make_syntax_mut(node.syntax())).unwrap()
+    }
+
+    pub fn make_syntax_mut(&self, node: &SyntaxNode) -> SyntaxNode {
+        let ptr = SyntaxNodePtr::new(node);
+        ptr.to_node(&self.mutable_clone)
+    }
+}
+
+impl SourceChangeBuilder {
+    pub fn new(file_id: FileId) -> SourceChangeBuilder {
+        SourceChangeBuilder {
+            edit: TextEdit::builder(),
+            file_id,
+            source_change: SourceChange::default(),
+            trigger_signature_help: false,
+            mutated_tree: None,
+        }
+    }
+
+    pub fn edit_file(&mut self, file_id: FileId) {
+        self.commit();
+        self.file_id = file_id;
+    }
+
+    fn commit(&mut self) {
+        if let Some(tm) = self.mutated_tree.take() {
+            algo::diff(&tm.immutable, &tm.mutable_clone).into_text_edit(&mut self.edit)
+        }
+
+        let edit = mem::take(&mut self.edit).finish();
+        if !edit.is_empty() {
+            self.source_change.insert_source_edit(self.file_id, edit);
+        }
+    }
+
+    pub fn make_mut<N: AstNode>(&mut self, node: N) -> N {
+        self.mutated_tree.get_or_insert_with(|| TreeMutator::new(node.syntax())).make_mut(&node)
+    }
+    /// Returns a copy of the `node`, suitable for mutation.
+    ///
+    /// Syntax trees in rust-analyzer are typically immutable, and mutating
+    /// operations panic at runtime. However, it is possible to make a copy of
+    /// the tree and mutate the copy freely. Mutation is based on interior
+    /// mutability, and different nodes in the same tree see the same mutations.
+    ///
+    /// The typical pattern for an assist is to find specific nodes in the read
+    /// phase, and then get their mutable couterparts using `make_mut` in the
+    /// mutable state.
+    pub fn make_syntax_mut(&mut self, node: SyntaxNode) -> SyntaxNode {
+        self.mutated_tree.get_or_insert_with(|| TreeMutator::new(&node)).make_syntax_mut(&node)
+    }
+
+    /// Remove specified `range` of text.
+    pub fn delete(&mut self, range: TextRange) {
+        self.edit.delete(range)
+    }
+    /// Append specified `text` at the given `offset`
+    pub fn insert(&mut self, offset: TextSize, text: impl Into<String>) {
+        self.edit.insert(offset, text.into())
+    }
+    /// Append specified `snippet` at the given `offset`
+    pub fn insert_snippet(
+        &mut self,
+        _cap: SnippetCap,
+        offset: TextSize,
+        snippet: impl Into<String>,
+    ) {
+        self.source_change.is_snippet = true;
+        self.insert(offset, snippet);
+    }
+    /// Replaces specified `range` of text with a given string.
+    pub fn replace(&mut self, range: TextRange, replace_with: impl Into<String>) {
+        self.edit.replace(range, replace_with.into())
+    }
+    /// Replaces specified `range` of text with a given `snippet`.
+    pub fn replace_snippet(
+        &mut self,
+        _cap: SnippetCap,
+        range: TextRange,
+        snippet: impl Into<String>,
+    ) {
+        self.source_change.is_snippet = true;
+        self.replace(range, snippet);
+    }
+    pub fn replace_ast<N: AstNode>(&mut self, old: N, new: N) {
+        algo::diff(old.syntax(), new.syntax()).into_text_edit(&mut self.edit)
+    }
+    pub fn create_file(&mut self, dst: AnchoredPathBuf, content: impl Into<String>) {
+        let file_system_edit = FileSystemEdit::CreateFile { dst, initial_contents: content.into() };
+        self.source_change.push_file_system_edit(file_system_edit);
+    }
+    pub fn move_file(&mut self, src: FileId, dst: AnchoredPathBuf) {
+        let file_system_edit = FileSystemEdit::MoveFile { src, dst };
+        self.source_change.push_file_system_edit(file_system_edit);
+    }
+    pub fn trigger_signature_help(&mut self) {
+        self.trigger_signature_help = true;
+    }
+
+    pub fn finish(mut self) -> SourceChange {
+        self.commit();
+        mem::take(&mut self.source_change)
+    }
+}
+
 #[derive(Debug, Clone)]
 pub enum FileSystemEdit {
     CreateFile { dst: AnchoredPathBuf, initial_contents: String },
diff --git a/crates/ide-diagnostics/src/handlers/inactive_code.rs b/crates/ide-diagnostics/src/handlers/inactive_code.rs
index 97ea5c456a635..5694f33525e01 100644
--- a/crates/ide-diagnostics/src/handlers/inactive_code.rs
+++ b/crates/ide-diagnostics/src/handlers/inactive_code.rs
@@ -43,7 +43,7 @@ mod tests {
     use crate::{tests::check_diagnostics_with_config, DiagnosticsConfig};
 
     pub(crate) fn check(ra_fixture: &str) {
-        let config = DiagnosticsConfig::default();
+        let config = DiagnosticsConfig::test_sample();
         check_diagnostics_with_config(config, ra_fixture)
     }
 
diff --git a/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs b/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
index aa7fcffb48ac3..a21db5b2cec9d 100644
--- a/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
+++ b/crates/ide-diagnostics/src/handlers/json_is_not_rust.rs
@@ -1,21 +1,30 @@
 //! This diagnostic provides an assist for creating a struct definition from a JSON
 //! example.
 
-use ide_db::{base_db::FileId, source_change::SourceChange};
+use hir::{PathResolution, Semantics};
+use ide_db::{
+    base_db::FileId,
+    helpers::mod_path_to_ast,
+    imports::insert_use::{insert_use, ImportScope},
+    source_change::SourceChangeBuilder,
+    RootDatabase,
+};
 use itertools::Itertools;
-use stdx::format_to;
+use stdx::{format_to, never};
 use syntax::{
     ast::{self, make},
     SyntaxKind, SyntaxNode,
 };
 use text_edit::TextEdit;
 
-use crate::{fix, Diagnostic, Severity};
+use crate::{fix, Diagnostic, DiagnosticsConfig, Severity};
 
 #[derive(Default)]
 struct State {
     result: String,
     struct_counts: usize,
+    has_serialize: bool,
+    has_deserialize: bool,
 }
 
 impl State {
@@ -24,6 +33,25 @@ impl State {
         make::name(&format!("Struct{}", self.struct_counts))
     }
 
+    fn serde_derive(&self) -> String {
+        let mut v = vec![];
+        if self.has_serialize {
+            v.push("Serialize");
+        }
+        if self.has_deserialize {
+            v.push("Deserialize");
+        }
+        match v.as_slice() {
+            [] => "".to_string(),
+            [x] => format!("#[derive({x})]\n"),
+            [x, y] => format!("#[derive({x}, {y})]\n"),
+            _ => {
+                never!();
+                "".to_string()
+            }
+        }
+    }
+
     fn build_struct(&mut self, value: &serde_json::Map<String, serde_json::Value>) -> ast::Type {
         let name = self.generate_new_name();
         let ty = make::ty(&name.to_string());
@@ -36,7 +64,7 @@ impl State {
             ))
             .into(),
         );
-        format_to!(self.result, "#[derive(Serialize, Deserialize)]\n{}\n", strukt);
+        format_to!(self.result, "{}{}\n", self.serde_derive(), strukt);
         ty
     }
 
@@ -44,10 +72,10 @@ impl State {
         match value {
             serde_json::Value::Null => make::ty_unit(),
             serde_json::Value::Bool(_) => make::ty("bool"),
-            serde_json::Value::Number(x) => make::ty(if x.is_i64() { "i64" } else { "f64" }),
+            serde_json::Value::Number(it) => make::ty(if it.is_i64() { "i64" } else { "f64" }),
             serde_json::Value::String(_) => make::ty("String"),
-            serde_json::Value::Array(x) => {
-                let ty = match x.iter().next() {
+            serde_json::Value::Array(it) => {
+                let ty = match it.iter().next() {
                     Some(x) => self.type_of(x),
                     None => make::ty_placeholder(),
                 };
@@ -58,37 +86,91 @@ impl State {
     }
 }
 
-pub(crate) fn json_in_items(acc: &mut Vec<Diagnostic>, file_id: FileId, node: &SyntaxNode) {
-    if node.kind() == SyntaxKind::ERROR
-        && node.first_token().map(|x| x.kind()) == Some(SyntaxKind::L_CURLY)
-        && node.last_token().map(|x| x.kind()) == Some(SyntaxKind::R_CURLY)
-    {
-        let node_string = node.to_string();
-        if let Ok(x) = serde_json::from_str(&node_string) {
-            if let serde_json::Value::Object(x) = x {
-                let range = node.text_range();
-                let mut edit = TextEdit::builder();
-                edit.delete(range);
-                let mut state = State::default();
-                state.build_struct(&x);
-                edit.insert(range.start(), state.result);
-                acc.push(
-                    Diagnostic::new(
-                        "json-is-not-rust",
-                        "JSON syntax is not valid as a Rust item",
-                        range,
-                    )
-                    .severity(Severity::WeakWarning)
-                    .with_fixes(Some(vec![fix(
-                        "convert_json_to_struct",
-                        "Convert JSON to struct",
-                        SourceChange::from_text_edit(file_id, edit.finish()),
-                        range,
-                    )])),
-                );
+pub(crate) fn json_in_items(
+    sema: &Semantics<'_, RootDatabase>,
+    acc: &mut Vec<Diagnostic>,
+    file_id: FileId,
+    node: &SyntaxNode,
+    config: &DiagnosticsConfig,
+) {
+    (|| {
+        if node.kind() == SyntaxKind::ERROR
+            && node.first_token().map(|x| x.kind()) == Some(SyntaxKind::L_CURLY)
+            && node.last_token().map(|x| x.kind()) == Some(SyntaxKind::R_CURLY)
+        {
+            let node_string = node.to_string();
+            if let Ok(it) = serde_json::from_str(&node_string) {
+                if let serde_json::Value::Object(it) = it {
+                    let import_scope = ImportScope::find_insert_use_container(node, sema)?;
+                    let range = node.text_range();
+                    let mut edit = TextEdit::builder();
+                    edit.delete(range);
+                    let mut state = State::default();
+                    let semantics_scope = sema.scope(node)?;
+                    let scope_resolve =
+                        |it| semantics_scope.speculative_resolve(&make::path_from_text(it));
+                    let scope_has = |it| scope_resolve(it).is_some();
+                    let deserialize_resolved = scope_resolve("::serde::Deserialize");
+                    let serialize_resolved = scope_resolve("::serde::Serialize");
+                    state.has_deserialize = deserialize_resolved.is_some();
+                    state.has_serialize = serialize_resolved.is_some();
+                    state.build_struct(&it);
+                    edit.insert(range.start(), state.result);
+                    acc.push(
+                        Diagnostic::new(
+                            "json-is-not-rust",
+                            "JSON syntax is not valid as a Rust item",
+                            range,
+                        )
+                        .severity(Severity::WeakWarning)
+                        .with_fixes(Some(vec![{
+                            let mut scb = SourceChangeBuilder::new(file_id);
+                            let scope = match import_scope.clone() {
+                                ImportScope::File(it) => ImportScope::File(scb.make_mut(it)),
+                                ImportScope::Module(it) => ImportScope::Module(scb.make_mut(it)),
+                                ImportScope::Block(it) => ImportScope::Block(scb.make_mut(it)),
+                            };
+                            let current_module = semantics_scope.module();
+                            if !scope_has("Serialize") {
+                                if let Some(PathResolution::Def(it)) = serialize_resolved {
+                                    if let Some(it) = current_module.find_use_path_prefixed(
+                                        sema.db,
+                                        it,
+                                        config.insert_use.prefix_kind,
+                                    ) {
+                                        insert_use(
+                                            &scope,
+                                            mod_path_to_ast(&it),
+                                            &config.insert_use,
+                                        );
+                                    }
+                                }
+                            }
+                            if !scope_has("Deserialize") {
+                                if let Some(PathResolution::Def(it)) = deserialize_resolved {
+                                    if let Some(it) = current_module.find_use_path_prefixed(
+                                        sema.db,
+                                        it,
+                                        config.insert_use.prefix_kind,
+                                    ) {
+                                        insert_use(
+                                            &scope,
+                                            mod_path_to_ast(&it),
+                                            &config.insert_use,
+                                        );
+                                    }
+                                }
+                            }
+                            let mut sc = scb.finish();
+                            sc.insert_source_edit(file_id, edit.finish());
+                            fix("convert_json_to_struct", "Convert JSON to struct", sc, range)
+                        }])),
+                    );
+                }
             }
         }
-    }
+        Some(())
+    })();
 }
 
 #[cfg(test)]
@@ -100,7 +182,7 @@ mod tests {
 
     #[test]
     fn diagnostic_for_simple_case() {
-        let mut config = DiagnosticsConfig::default();
+        let mut config = DiagnosticsConfig::test_sample();
         config.disabled.insert("syntax-error".to_string());
         check_diagnostics_with_config(
             config,
@@ -115,6 +197,13 @@ mod tests {
     fn types_of_primitives() {
         check_fix(
             r#"
+            //- /lib.rs crate:lib deps:serde
+            use serde::Serialize;
+
+            fn some_garbage() {
+
+            }
+
             {$0
                 "foo": "bar",
                 "bar": 2.3,
@@ -122,9 +211,20 @@ mod tests {
                 "bay": 57,
                 "box": true
             }
+            //- /serde.rs crate:serde
+
+            pub trait Serialize {
+                fn serialize() -> u8;
+            }
             "#,
             r#"
-            #[derive(Serialize, Deserialize)]
+            use serde::Serialize;
+
+            fn some_garbage() {
+
+            }
+
+            #[derive(Serialize)]
             struct Struct1{ bar: f64, bay: i64, baz: (), r#box: bool, foo: String }
 
             "#,
@@ -144,11 +244,8 @@ mod tests {
             }
             "#,
             r#"
-            #[derive(Serialize, Deserialize)]
             struct Struct3{  }
-            #[derive(Serialize, Deserialize)]
             struct Struct2{ kind: String, value: Struct3 }
-            #[derive(Serialize, Deserialize)]
             struct Struct1{ bar: Struct2, foo: String }
 
             "#,
@@ -159,6 +256,7 @@ mod tests {
     fn arrays() {
         check_fix(
             r#"
+            //- /lib.rs crate:lib deps:serde
             {
                 "of_string": ["foo", "2", "x"], $0
                 "of_object": [{
@@ -171,8 +269,19 @@ mod tests {
                 "nested": [[[2]]],
                 "empty": []
             }
+            //- /serde.rs crate:serde
+
+            pub trait Serialize {
+                fn serialize() -> u8;
+            }
+            pub trait Deserialize {
+                fn deserialize() -> u8;
+            }
             "#,
             r#"
+            use serde::Serialize;
+            use serde::Deserialize;
+
             #[derive(Serialize, Deserialize)]
             struct Struct2{ x: i64, y: i64 }
             #[derive(Serialize, Deserialize)]
diff --git a/crates/ide-diagnostics/src/handlers/macro_error.rs b/crates/ide-diagnostics/src/handlers/macro_error.rs
index d6a66dc150917..43ff4ed5a6c86 100644
--- a/crates/ide-diagnostics/src/handlers/macro_error.rs
+++ b/crates/ide-diagnostics/src/handlers/macro_error.rs
@@ -79,7 +79,7 @@ pub macro panic {
 
     #[test]
     fn include_macro_should_allow_empty_content() {
-        let mut config = DiagnosticsConfig::default();
+        let mut config = DiagnosticsConfig::test_sample();
 
         // FIXME: This is a false-positive, the file is actually linked in via
         // `include!` macro
diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs
index 7034f010e1b0c..61e63ea7a93ca 100644
--- a/crates/ide-diagnostics/src/lib.rs
+++ b/crates/ide-diagnostics/src/lib.rs
@@ -60,6 +60,7 @@ use hir::{diagnostics::AnyDiagnostic, InFile, Semantics};
 use ide_db::{
     assists::{Assist, AssistId, AssistKind, AssistResolveStrategy},
     base_db::{FileId, FileRange, SourceDatabase},
+    imports::insert_use::InsertUseConfig,
     label::Label,
     source_change::SourceChange,
     FxHashSet, RootDatabase,
@@ -140,13 +141,37 @@ impl Default for ExprFillDefaultMode {
     }
 }
 
-#[derive(Default, Debug, Clone)]
+#[derive(Debug, Clone)]
 pub struct DiagnosticsConfig {
     pub proc_macros_enabled: bool,
     pub proc_attr_macros_enabled: bool,
     pub disable_experimental: bool,
     pub disabled: FxHashSet<String>,
     pub expr_fill_default: ExprFillDefaultMode,
+    // FIXME: We may want to include a whole `AssistConfig` here
+    pub insert_use: InsertUseConfig,
+}
+
+impl DiagnosticsConfig {
+    pub fn test_sample() -> Self {
+        use hir::PrefixKind;
+        use ide_db::imports::insert_use::ImportGranularity;
+
+        Self {
+            proc_macros_enabled: Default::default(),
+            proc_attr_macros_enabled: Default::default(),
+            disable_experimental: Default::default(),
+            disabled: Default::default(),
+            expr_fill_default: Default::default(),
+            insert_use: InsertUseConfig {
+                granularity: ImportGranularity::Preserve,
+                enforce_granularity: false,
+                prefix_kind: PrefixKind::Plain,
+                group: false,
+                skip_glob_imports: false,
+            },
+        }
+    }
 }
 
 struct DiagnosticsContext<'a> {
@@ -173,10 +198,12 @@ pub fn diagnostics(
         }),
     );
 
-    for node in parse.tree().syntax().descendants() {
+    let parse = sema.parse(file_id);
+
+    for node in parse.syntax().descendants() {
         handlers::useless_braces::useless_braces(&mut res, file_id, &node);
         handlers::field_shorthand::field_shorthand(&mut res, file_id, &node);
-        handlers::json_is_not_rust::json_in_items(&mut res, file_id, &node);
+        handlers::json_is_not_rust::json_in_items(&sema, &mut res, file_id, &node, &config);
     }
 
     let module = sema.to_module_def(file_id);
diff --git a/crates/ide-diagnostics/src/tests.rs b/crates/ide-diagnostics/src/tests.rs
index 7312bca32fed9..729619cfde03f 100644
--- a/crates/ide-diagnostics/src/tests.rs
+++ b/crates/ide-diagnostics/src/tests.rs
@@ -37,7 +37,7 @@ fn check_nth_fix(nth: usize, ra_fixture_before: &str, ra_fixture_after: &str) {
     let after = trim_indent(ra_fixture_after);
 
     let (db, file_position) = RootDatabase::with_position(ra_fixture_before);
-    let mut conf = DiagnosticsConfig::default();
+    let mut conf = DiagnosticsConfig::test_sample();
     conf.expr_fill_default = ExprFillDefaultMode::Default;
     let diagnostic =
         super::diagnostics(&db, &conf, &AssistResolveStrategy::All, file_position.file_id)
@@ -69,7 +69,7 @@ pub(crate) fn check_no_fix(ra_fixture: &str) {
     let (db, file_position) = RootDatabase::with_position(ra_fixture);
     let diagnostic = super::diagnostics(
         &db,
-        &DiagnosticsConfig::default(),
+        &DiagnosticsConfig::test_sample(),
         &AssistResolveStrategy::All,
         file_position.file_id,
     )
@@ -82,7 +82,7 @@ pub(crate) fn check_expect(ra_fixture: &str, expect: Expect) {
     let (db, file_id) = RootDatabase::with_single_file(ra_fixture);
     let diagnostics = super::diagnostics(
         &db,
-        &DiagnosticsConfig::default(),
+        &DiagnosticsConfig::test_sample(),
         &AssistResolveStrategy::All,
         file_id,
     );
@@ -91,7 +91,7 @@ pub(crate) fn check_expect(ra_fixture: &str, expect: Expect) {
 
 #[track_caller]
 pub(crate) fn check_diagnostics(ra_fixture: &str) {
-    let mut config = DiagnosticsConfig::default();
+    let mut config = DiagnosticsConfig::test_sample();
     config.disabled.insert("inactive-code".to_string());
     check_diagnostics_with_config(config, ra_fixture)
 }
@@ -127,7 +127,7 @@ pub(crate) fn check_diagnostics_with_config(config: DiagnosticsConfig, ra_fixtur
 
 #[test]
 fn test_disabled_diagnostics() {
-    let mut config = DiagnosticsConfig::default();
+    let mut config = DiagnosticsConfig::test_sample();
     config.disabled.insert("unresolved-module".into());
 
     let (db, file_id) = RootDatabase::with_single_file(r#"mod foo;"#);
@@ -137,7 +137,7 @@ fn test_disabled_diagnostics() {
 
     let diagnostics = super::diagnostics(
         &db,
-        &DiagnosticsConfig::default(),
+        &DiagnosticsConfig::test_sample(),
         &AssistResolveStrategy::All,
         file_id,
     );
diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs
index 52511ceb5805d..247007db0a788 100644
--- a/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -43,7 +43,7 @@ impl flags::Diagnostics {
                 println!("processing crate: {}, module: {}", crate_name, _vfs.file_path(file_id));
                 for diagnostic in analysis
                     .diagnostics(
-                        &DiagnosticsConfig::default(),
+                        &DiagnosticsConfig::test_sample(),
                         AssistResolveStrategy::None,
                         file_id,
                     )
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index ac0fdf85a774e..1629c1dd328a6 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -881,6 +881,7 @@ impl Config {
                 ExprFillDefaultDef::Todo => ExprFillDefaultMode::Todo,
                 ExprFillDefaultDef::Default => ExprFillDefaultMode::Default,
             },
+            insert_use: self.insert_use_config(),
         }
     }
 

From a81c7a2974841f335fd87bfd8c3c3b8a7c3d3612 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida <low.ryoshida@gmail.com>
Date: Fri, 5 Aug 2022 20:01:50 +0900
Subject: [PATCH 12/39] Parse range patterns in struct and slice without
 trailing comma

---
 crates/parser/src/grammar/patterns.rs         |  27 +++-
 .../parser/inline/ok/0058_range_pat.rast      | 116 ++++++++++++++++++
 .../parser/inline/ok/0058_range_pat.rs        |  10 ++
 3 files changed, 150 insertions(+), 3 deletions(-)

diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs
index 4cbf103061497..bfa41c686e5c1 100644
--- a/crates/parser/src/grammar/patterns.rs
+++ b/crates/parser/src/grammar/patterns.rs
@@ -75,6 +75,16 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
         //         Some(1..) => ()
         //     }
         //
+        //     match () {
+        //         S { a: 0 } => (),
+        //         S { a: 1.. } => (),
+        //     }
+        //
+        //     match () {
+        //         [0] => (),
+        //         [1..] => (),
+        //     }
+        //
         //     match (10 as u8, 5 as u8) {
         //         (0, _) => (),
         //         (1.., _) => ()
@@ -88,9 +98,20 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
                 let m = lhs.precede(p);
                 p.bump(range_op);
 
-                // `0 .. =>` or `let 0 .. =` or `Some(0 .. )`
-                //       ^                ^                ^
-                if p.at(T![=]) | p.at(T![')']) | p.at(T![,]) {
+                // testing if we're at one of the following positions:
+                // `0 .. =>`
+                //       ^
+                // `let 0 .. =`
+                //           ^
+                // (1.., _)
+                //     ^
+                // `Some(0 .. )`
+                //            ^
+                // `S { t: 0.. }`
+                //             ^
+                // `[0..]`
+                //      ^
+                if p.at(T![=]) | p.at(T![')']) | p.at(T![,]) | p.at(T!['}']) | p.at(T![']']) {
                     // test half_open_range_pat
                     // fn f() { let 0 .. = 1u32; }
                 } else {
diff --git a/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast b/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast
index 44c967e8dc597..cfef5d3f95387 100644
--- a/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast
+++ b/crates/parser/test_data/parser/inline/ok/0058_range_pat.rast
@@ -172,6 +172,122 @@ SOURCE_FILE
               WHITESPACE "\n    "
               R_CURLY "}"
         WHITESPACE "\n\n    "
+        EXPR_STMT
+          MATCH_EXPR
+            MATCH_KW "match"
+            WHITESPACE " "
+            TUPLE_EXPR
+              L_PAREN "("
+              R_PAREN ")"
+            WHITESPACE " "
+            MATCH_ARM_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              MATCH_ARM
+                RECORD_PAT
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "S"
+                  WHITESPACE " "
+                  RECORD_PAT_FIELD_LIST
+                    L_CURLY "{"
+                    WHITESPACE " "
+                    RECORD_PAT_FIELD
+                      NAME_REF
+                        IDENT "a"
+                      COLON ":"
+                      WHITESPACE " "
+                      LITERAL_PAT
+                        LITERAL
+                          INT_NUMBER "0"
+                    WHITESPACE " "
+                    R_CURLY "}"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n        "
+              MATCH_ARM
+                RECORD_PAT
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "S"
+                  WHITESPACE " "
+                  RECORD_PAT_FIELD_LIST
+                    L_CURLY "{"
+                    WHITESPACE " "
+                    RECORD_PAT_FIELD
+                      NAME_REF
+                        IDENT "a"
+                      COLON ":"
+                      WHITESPACE " "
+                      RANGE_PAT
+                        LITERAL_PAT
+                          LITERAL
+                            INT_NUMBER "1"
+                        DOT2 ".."
+                    WHITESPACE " "
+                    R_CURLY "}"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
+        EXPR_STMT
+          MATCH_EXPR
+            MATCH_KW "match"
+            WHITESPACE " "
+            TUPLE_EXPR
+              L_PAREN "("
+              R_PAREN ")"
+            WHITESPACE " "
+            MATCH_ARM_LIST
+              L_CURLY "{"
+              WHITESPACE "\n        "
+              MATCH_ARM
+                SLICE_PAT
+                  L_BRACK "["
+                  LITERAL_PAT
+                    LITERAL
+                      INT_NUMBER "0"
+                  R_BRACK "]"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n        "
+              MATCH_ARM
+                SLICE_PAT
+                  L_BRACK "["
+                  RANGE_PAT
+                    LITERAL_PAT
+                      LITERAL
+                        INT_NUMBER "1"
+                    DOT2 ".."
+                  R_BRACK "]"
+                WHITESPACE " "
+                FAT_ARROW "=>"
+                WHITESPACE " "
+                TUPLE_EXPR
+                  L_PAREN "("
+                  R_PAREN ")"
+                COMMA ","
+              WHITESPACE "\n    "
+              R_CURLY "}"
+        WHITESPACE "\n\n    "
         MATCH_EXPR
           MATCH_KW "match"
           WHITESPACE " "
diff --git a/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs b/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs
index 6c586a8956098..2411d51096b3b 100644
--- a/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs
+++ b/crates/parser/test_data/parser/inline/ok/0058_range_pat.rs
@@ -11,6 +11,16 @@ fn main() {
         Some(1..) => ()
     }
 
+    match () {
+        S { a: 0 } => (),
+        S { a: 1.. } => (),
+    }
+
+    match () {
+        [0] => (),
+        [1..] => (),
+    }
+
     match (10 as u8, 5 as u8) {
         (0, _) => (),
         (1.., _) => ()

From 4b648d8f6cfb9f58490a70e4539aa36c89b9d35e Mon Sep 17 00:00:00 2001
From: Jake Heinz <jh@discordapp.com>
Date: Mon, 8 Aug 2022 00:20:17 +0000
Subject: [PATCH 13/39] [code] make toggleInlayHints understand
 {off,on}UntilPressed

---
 editors/code/src/commands.ts | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/editors/code/src/commands.ts b/editors/code/src/commands.ts
index bf55329ca1f55..1b793bb0b15c8 100644
--- a/editors/code/src/commands.ts
+++ b/editors/code/src/commands.ts
@@ -326,8 +326,22 @@ export function toggleInlayHints(_ctx: Ctx): Cmd {
         const config = vscode.workspace.getConfiguration("editor.inlayHints", {
             languageId: "rust",
         });
-        const value = !config.get("enabled");
-        await config.update("enabled", value, vscode.ConfigurationTarget.Global);
+
+        const value = config.get("enabled");
+        let stringValue;
+        if (typeof value === "string") {
+            stringValue = value;
+        } else {
+            stringValue = value ? "on" : "off";
+        }
+        const nextValues: Record<string, string> = {
+            on: "off",
+            off: "on",
+            onUnlessPressed: "offUnlessPressed",
+            offUnlessPressed: "onUnlessPressed",
+        };
+        const nextValue = nextValues[stringValue] ?? "on";
+        await config.update("enabled", nextValue, vscode.ConfigurationTarget.Global);
     };
 }
 

From b14062aaecfe11978a5525824567e8011526aeb2 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida <low.ryoshida@gmail.com>
Date: Tue, 9 Aug 2022 00:00:22 +0900
Subject: [PATCH 14/39] Parse range patterns in let statement with type
 annotation

---
 crates/parser/src/grammar/patterns.rs         |  9 ++++++--
 .../inline/ok/0166_half_open_range_pat.rast   | 23 +++++++++++++++++--
 .../inline/ok/0166_half_open_range_pat.rs     |  5 +++-
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs
index bfa41c686e5c1..7e21a808da0a4 100644
--- a/crates/parser/src/grammar/patterns.rs
+++ b/crates/parser/src/grammar/patterns.rs
@@ -103,6 +103,8 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
                 //       ^
                 // `let 0 .. =`
                 //           ^
+                // `let 0..: _ =`
+                //         ^
                 // (1.., _)
                 //     ^
                 // `Some(0 .. )`
@@ -111,9 +113,12 @@ fn pattern_single_r(p: &mut Parser<'_>, recovery_set: TokenSet) {
                 //             ^
                 // `[0..]`
                 //      ^
-                if p.at(T![=]) | p.at(T![')']) | p.at(T![,]) | p.at(T!['}']) | p.at(T![']']) {
+                if matches!(p.current(), T![=] | T![,] | T![:] | T![')'] | T!['}'] | T![']']) {
                     // test half_open_range_pat
-                    // fn f() { let 0 .. = 1u32; }
+                    // fn f() {
+                    //     let 0 .. = 1u32;
+                    //     let 0..: _ = 1u32;
+                    // }
                 } else {
                     atom_pat(p, recovery_set);
                 }
diff --git a/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast b/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast
index 3d3587a706334..4b401b60df0ce 100644
--- a/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast
+++ b/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rast
@@ -11,7 +11,7 @@ SOURCE_FILE
     BLOCK_EXPR
       STMT_LIST
         L_CURLY "{"
-        WHITESPACE " "
+        WHITESPACE "\n    "
         LET_STMT
           LET_KW "let"
           WHITESPACE " "
@@ -27,6 +27,25 @@ SOURCE_FILE
           LITERAL
             INT_NUMBER "1u32"
           SEMICOLON ";"
-        WHITESPACE " "
+        WHITESPACE "\n    "
+        LET_STMT
+          LET_KW "let"
+          WHITESPACE " "
+          RANGE_PAT
+            LITERAL_PAT
+              LITERAL
+                INT_NUMBER "0"
+            DOT2 ".."
+          COLON ":"
+          WHITESPACE " "
+          INFER_TYPE
+            UNDERSCORE "_"
+          WHITESPACE " "
+          EQ "="
+          WHITESPACE " "
+          LITERAL
+            INT_NUMBER "1u32"
+          SEMICOLON ";"
+        WHITESPACE "\n"
         R_CURLY "}"
   WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs b/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs
index 1360eda056583..c9386a221a955 100644
--- a/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs
+++ b/crates/parser/test_data/parser/inline/ok/0166_half_open_range_pat.rs
@@ -1 +1,4 @@
-fn f() { let 0 .. = 1u32; }
+fn f() {
+    let 0 .. = 1u32;
+    let 0..: _ = 1u32;
+}

From e39918f553d7dd5fb5afd6517f80d3e35290c4d2 Mon Sep 17 00:00:00 2001
From: fprasx <felix725@gmail.com>
Date: Mon, 8 Aug 2022 11:05:18 -0400
Subject: [PATCH 15/39] Corrected order of printing op and `=`

---
 crates/syntax/src/ast/operators.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/crates/syntax/src/ast/operators.rs b/crates/syntax/src/ast/operators.rs
index a687ba0b77a56..8f7b3fb600879 100644
--- a/crates/syntax/src/ast/operators.rs
+++ b/crates/syntax/src/ast/operators.rs
@@ -111,10 +111,10 @@ impl fmt::Display for BinaryOp {
             BinaryOp::ArithOp(op) => fmt::Display::fmt(op, f),
             BinaryOp::CmpOp(op) => fmt::Display::fmt(op, f),
             BinaryOp::Assignment { op } => {
-                f.write_str("=")?;
                 if let Some(op) = op {
                     fmt::Display::fmt(op, f)?;
                 }
+                f.write_str("=")?;
                 Ok(())
             }
         }

From 232176b46af3955e20997eb4ffb5e77fefde0ed5 Mon Sep 17 00:00:00 2001
From: KaDiWa <kalle.wachsmuth@gmail.com>
Date: Tue, 9 Aug 2022 01:16:32 +0200
Subject: [PATCH 16/39] remove imports that are also in edition 2021's prelude

---
 crates/base-db/src/input.rs                               | 2 +-
 crates/hir-ty/src/consteval.rs                            | 1 -
 crates/ide-db/src/search.rs                               | 2 +-
 crates/ide/src/goto_definition.rs                         | 2 +-
 crates/ide/src/status.rs                                  | 2 +-
 crates/proc-macro-api/src/msg/flat.rs                     | 5 +----
 crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs | 4 ++--
 crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs      | 1 -
 crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs | 4 ++--
 crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs      | 1 -
 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs | 4 ++--
 crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs      | 1 -
 crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs   | 2 +-
 crates/proc-macro-srv/src/dylib.rs                        | 1 -
 crates/rust-analyzer/src/diagnostics/to_proto.rs          | 2 +-
 crates/rust-analyzer/src/to_proto.rs                      | 2 +-
 crates/syntax/src/fuzz.rs                                 | 5 +----
 lib/la-arena/src/lib.rs                                   | 1 -
 18 files changed, 15 insertions(+), 27 deletions(-)

diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index 9b5a10acfbeaf..9580ce8007c76 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -6,7 +6,7 @@
 //! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how
 //! actual IO is done and lowered to input.
 
-use std::{fmt, iter::FromIterator, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
+use std::{fmt, ops, panic::RefUnwindSafe, str::FromStr, sync::Arc};
 
 use cfg::CfgOptions;
 use rustc_hash::{FxHashMap, FxHashSet};
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs
index 0495a4e64caca..6ecb6e6fd173e 100644
--- a/crates/hir-ty/src/consteval.rs
+++ b/crates/hir-ty/src/consteval.rs
@@ -2,7 +2,6 @@
 
 use std::{
     collections::HashMap,
-    convert::TryInto,
     fmt::{Display, Write},
 };
 
diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs
index bd038cdaa0682..9eaabeec7a4e7 100644
--- a/crates/ide-db/src/search.rs
+++ b/crates/ide-db/src/search.rs
@@ -4,7 +4,7 @@
 //! get a super-set of matches. Then, we we confirm each match using precise
 //! name resolution.
 
-use std::{convert::TryInto, mem, sync::Arc};
+use std::{mem, sync::Arc};
 
 use base_db::{FileId, FileRange, SourceDatabase, SourceDatabaseExt};
 use hir::{DefWithBody, HasAttrs, HasSource, InFile, ModuleSource, Semantics, Visibility};
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index b2123b9a87938..d6cd5783f05ef 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -1,4 +1,4 @@
-use std::{convert::TryInto, mem::discriminant};
+use std::mem::discriminant;
 
 use crate::{doc_links::token_as_doc_comment, FilePosition, NavigationTarget, RangeInfo, TryToNav};
 use hir::{AsAssocItem, AssocItem, Semantics};
diff --git a/crates/ide/src/status.rs b/crates/ide/src/status.rs
index 32e39f82a0e9f..f4d0387440d47 100644
--- a/crates/ide/src/status.rs
+++ b/crates/ide/src/status.rs
@@ -1,4 +1,4 @@
-use std::{fmt, iter::FromIterator, sync::Arc};
+use std::{fmt, sync::Arc};
 
 use hir::{ExpandResult, MacroFile};
 use ide_db::base_db::{
diff --git a/crates/proc-macro-api/src/msg/flat.rs b/crates/proc-macro-api/src/msg/flat.rs
index 8437444e183a0..268a03bb5359b 100644
--- a/crates/proc-macro-api/src/msg/flat.rs
+++ b/crates/proc-macro-api/src/msg/flat.rs
@@ -35,10 +35,7 @@
 //! as we don't have bincode in Cargo.toml yet, lets stick with serde_json for
 //! the time being.
 
-use std::{
-    collections::{HashMap, VecDeque},
-    convert::TryInto,
-};
+use std::collections::{HashMap, VecDeque};
 
 use serde::{Deserialize, Serialize};
 use tt::TokenId;
diff --git a/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs b/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs
index 4a07f22779e66..a405497f3c9b7 100644
--- a/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs
+++ b/crates/proc-macro-srv/src/abis/abi_1_58/proc_macro/mod.rs
@@ -157,7 +157,7 @@ impl From<TokenTree> for TokenStream {
 }
 
 /// Collects a number of token trees into a single stream.
-impl iter::FromIterator<TokenTree> for TokenStream {
+impl FromIterator<TokenTree> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
         trees.into_iter().map(TokenStream::from).collect()
     }
@@ -165,7 +165,7 @@ impl iter::FromIterator<TokenTree> for TokenStream {
 
 /// A "flattening" operation on token streams, collects token trees
 /// from multiple token streams into a single stream.
-impl iter::FromIterator<TokenStream> for TokenStream {
+impl FromIterator<TokenStream> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
         let mut builder = bridge::client::TokenStreamBuilder::new();
         streams.into_iter().for_each(|stream| builder.push(stream.0));
diff --git a/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs
index ebdfca00d735d..b1e982f4779f7 100644
--- a/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs
+++ b/crates/proc-macro-srv/src/abis/abi_1_58/ra_server.rs
@@ -12,7 +12,6 @@ use super::proc_macro::bridge::{self, server};
 
 use std::collections::HashMap;
 use std::hash::Hash;
-use std::iter::FromIterator;
 use std::ops::Bound;
 use std::{ascii, vec::IntoIter};
 
diff --git a/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs b/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs
index c50a16bf4d1d8..7ab1f421daf89 100644
--- a/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs
+++ b/crates/proc-macro-srv/src/abis/abi_1_63/proc_macro/mod.rs
@@ -207,7 +207,7 @@ impl ConcatStreamsHelper {
 }
 
 /// Collects a number of token trees into a single stream.
-impl iter::FromIterator<TokenTree> for TokenStream {
+impl FromIterator<TokenTree> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
         trees.into_iter().map(TokenStream::from).collect()
     }
@@ -215,7 +215,7 @@ impl iter::FromIterator<TokenTree> for TokenStream {
 
 /// A "flattening" operation on token streams, collects token trees
 /// from multiple token streams into a single stream.
-impl iter::FromIterator<TokenStream> for TokenStream {
+impl FromIterator<TokenStream> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
         let iter = streams.into_iter();
         let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
diff --git a/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs
index 05a565fbf343e..ed49cc7596608 100644
--- a/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs
+++ b/crates/proc-macro-srv/src/abis/abi_1_63/ra_server.rs
@@ -12,7 +12,6 @@ use super::proc_macro::bridge::{self, server};
 
 use std::collections::HashMap;
 use std::hash::Hash;
-use std::iter::FromIterator;
 use std::ops::Bound;
 use std::{ascii, vec::IntoIter};
 
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs
index be62c73ef32b9..86a59b6455903 100644
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs
+++ b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs
@@ -207,7 +207,7 @@ impl ConcatStreamsHelper {
 }
 
 /// Collects a number of token trees into a single stream.
-impl iter::FromIterator<TokenTree> for TokenStream {
+impl FromIterator<TokenTree> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
         trees.into_iter().map(TokenStream::from).collect()
     }
@@ -215,7 +215,7 @@ impl iter::FromIterator<TokenTree> for TokenStream {
 
 /// A "flattening" operation on token streams, collects token trees
 /// from multiple token streams into a single stream.
-impl iter::FromIterator<TokenStream> for TokenStream {
+impl FromIterator<TokenStream> for TokenStream {
     fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
         let iter = streams.into_iter();
         let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs
index 7e8e67856e9fd..d8aa1ec429a7d 100644
--- a/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs
+++ b/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs
@@ -12,7 +12,6 @@ use super::proc_macro::bridge::{self, server};
 
 use std::collections::HashMap;
 use std::hash::Hash;
-use std::iter::FromIterator;
 use std::ops::Bound;
 use std::{ascii, vec::IntoIter};
 
diff --git a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
index 46882845a8079..52eb7ce17d6ae 100644
--- a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
+++ b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs
@@ -20,7 +20,7 @@ use token_stream::TokenStreamBuilder;
 mod symbol;
 pub use symbol::*;
 
-use std::{iter::FromIterator, ops::Bound};
+use std::ops::Bound;
 
 type Group = tt::Subtree;
 type TokenTree = tt::TokenTree;
diff --git a/crates/proc-macro-srv/src/dylib.rs b/crates/proc-macro-srv/src/dylib.rs
index 2b6c070fece3f..7aba74e5396de 100644
--- a/crates/proc-macro-srv/src/dylib.rs
+++ b/crates/proc-macro-srv/src/dylib.rs
@@ -1,7 +1,6 @@
 //! Handles dynamic library loading for proc macro
 
 use std::{
-    convert::TryInto,
     fmt,
     fs::File,
     io,
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs
index cff4bd7f66acd..74689fd8757f8 100644
--- a/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -512,7 +512,7 @@ fn clippy_code_description(code: Option<&str>) -> Option<lsp_types::CodeDescript
 #[cfg(test)]
 #[cfg(not(windows))]
 mod tests {
-    use std::{convert::TryInto, path::Path};
+    use std::path::Path;
 
     use crate::{config::Config, global_state::GlobalState};
 
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 7f4fa57fa1e09..e7115b0732e20 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -1386,7 +1386,7 @@ fn main() {
     #[test]
     #[cfg(target_os = "windows")]
     fn test_lowercase_drive_letter() {
-        use std::{convert::TryInto, path::Path};
+        use std::path::Path;
 
         let url = url_from_abs_path(Path::new("C:\\Test").try_into().unwrap());
         assert_eq!(url.to_string(), "file:///c:/Test");
diff --git a/crates/syntax/src/fuzz.rs b/crates/syntax/src/fuzz.rs
index 256999fe09cf8..7c7a60d62994e 100644
--- a/crates/syntax/src/fuzz.rs
+++ b/crates/syntax/src/fuzz.rs
@@ -2,10 +2,7 @@
 //!
 //! We don't normally run fuzzying, so this is hopelessly bitrotten :(
 
-use std::{
-    convert::TryInto,
-    str::{self, FromStr},
-};
+use std::str::{self, FromStr};
 
 use text_edit::Indel;
 
diff --git a/lib/la-arena/src/lib.rs b/lib/la-arena/src/lib.rs
index a3fe59e946ee9..50e8d06b66049 100644
--- a/lib/la-arena/src/lib.rs
+++ b/lib/la-arena/src/lib.rs
@@ -6,7 +6,6 @@
 use std::{
     fmt,
     hash::{Hash, Hasher},
-    iter::FromIterator,
     marker::PhantomData,
     ops::{Index, IndexMut, Range, RangeInclusive},
 };

From 950de7c3c355398a9c15812b74376e252cb176db Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Tue, 9 Aug 2022 14:31:17 +0200
Subject: [PATCH 17/39] Use `--keep-going` cargo flag when building build
 scripts

---
 crates/project-model/src/build_scripts.rs | 15 +++++++++++++--
 crates/project-model/src/tests.rs         |  1 +
 crates/project-model/src/workspace.rs     | 18 ++++++++++++++----
 crates/rust-analyzer/src/reload.rs        |  1 +
 4 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/crates/project-model/src/build_scripts.rs b/crates/project-model/src/build_scripts.rs
index ee7f8339a76a1..4b00479a4c9c2 100644
--- a/crates/project-model/src/build_scripts.rs
+++ b/crates/project-model/src/build_scripts.rs
@@ -12,6 +12,7 @@ use cargo_metadata::{camino::Utf8Path, Message};
 use la_arena::ArenaMap;
 use paths::AbsPathBuf;
 use rustc_hash::FxHashMap;
+use semver::Version;
 use serde::Deserialize;
 
 use crate::{cfg_flag::CfgFlag, CargoConfig, CargoWorkspace, Package};
@@ -38,7 +39,7 @@ pub(crate) struct BuildScriptOutput {
 }
 
 impl WorkspaceBuildScripts {
-    fn build_command(config: &CargoConfig) -> Command {
+    fn build_command(config: &CargoConfig, toolchain: &Option<Version>) -> Command {
         if let Some([program, args @ ..]) = config.run_build_script_command.as_deref() {
             let mut cmd = Command::new(program);
             cmd.args(args);
@@ -70,6 +71,15 @@ impl WorkspaceBuildScripts {
             }
         }
 
+        const RUST_1_62: Version = Version::new(1, 62, 0);
+
+        match toolchain {
+            Some(v) if v >= &RUST_1_62 => {
+                cmd.args(&["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
+            }
+            _ => (),
+        }
+
         cmd
     }
 
@@ -77,8 +87,9 @@ impl WorkspaceBuildScripts {
         config: &CargoConfig,
         workspace: &CargoWorkspace,
         progress: &dyn Fn(String),
+        toolchain: &Option<Version>,
     ) -> io::Result<WorkspaceBuildScripts> {
-        let mut cmd = Self::build_command(config);
+        let mut cmd = Self::build_command(config, toolchain);
 
         if config.wrap_rustc_in_build_scripts {
             // Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use
diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs
index e304a59c0180b..8d0fa757c2e17 100644
--- a/crates/project-model/src/tests.rs
+++ b/crates/project-model/src/tests.rs
@@ -28,6 +28,7 @@ fn load_cargo_with_overrides(file: &str, cfg_overrides: CfgOverrides) -> CrateGr
         rustc: None,
         rustc_cfg: Vec::new(),
         cfg_overrides,
+        toolchain: None,
     };
     to_crate_graph(project_workspace)
 }
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index b144006b44e03..daabb299f76cb 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -12,6 +12,7 @@ use base_db::{
 use cfg::{CfgDiff, CfgOptions};
 use paths::{AbsPath, AbsPathBuf};
 use rustc_hash::{FxHashMap, FxHashSet};
+use semver::Version;
 use stdx::always;
 
 use crate::{
@@ -77,6 +78,7 @@ pub enum ProjectWorkspace {
         /// different target.
         rustc_cfg: Vec<CfgFlag>,
         cfg_overrides: CfgOverrides,
+        toolchain: Option<Version>,
     },
     /// Project workspace was manually specified using a `rust-project.json` file.
     Json { project: ProjectJson, sysroot: Option<Sysroot>, rustc_cfg: Vec<CfgFlag> },
@@ -105,6 +107,7 @@ impl fmt::Debug for ProjectWorkspace {
                 rustc,
                 rustc_cfg,
                 cfg_overrides,
+                toolchain,
             } => f
                 .debug_struct("Cargo")
                 .field("root", &cargo.workspace_root().file_name())
@@ -116,6 +119,7 @@ impl fmt::Debug for ProjectWorkspace {
                 )
                 .field("n_rustc_cfg", &rustc_cfg.len())
                 .field("n_cfg_overrides", &cfg_overrides.len())
+                .field("toolchain", &toolchain)
                 .finish(),
             ProjectWorkspace::Json { project, sysroot, rustc_cfg } => {
                 let mut debug_struct = f.debug_struct("Json");
@@ -160,6 +164,9 @@ impl ProjectWorkspace {
                     cmd.arg("--version");
                     cmd
                 })?;
+                let toolchain = cargo_version
+                    .get("cargo ".len()..)
+                    .and_then(|it| Version::parse(it.split_whitespace().next()?).ok());
 
                 let meta = CargoWorkspace::fetch_metadata(
                     &cargo_toml,
@@ -169,9 +176,9 @@ impl ProjectWorkspace {
                 )
                 .with_context(|| {
                     format!(
-                        "Failed to read Cargo metadata from Cargo.toml file {}, {}",
+                        "Failed to read Cargo metadata from Cargo.toml file {}, {:?}",
                         cargo_toml.display(),
-                        cargo_version
+                        toolchain
                     )
                 })?;
                 let cargo = CargoWorkspace::new(meta);
@@ -219,6 +226,7 @@ impl ProjectWorkspace {
                     rustc,
                     rustc_cfg,
                     cfg_overrides,
+                    toolchain,
                 }
             }
         };
@@ -271,8 +279,8 @@ impl ProjectWorkspace {
         progress: &dyn Fn(String),
     ) -> Result<WorkspaceBuildScripts> {
         match self {
-            ProjectWorkspace::Cargo { cargo, .. } => {
-                WorkspaceBuildScripts::run(config, cargo, progress).with_context(|| {
+            ProjectWorkspace::Cargo { cargo, toolchain, .. } => {
+                WorkspaceBuildScripts::run(config, cargo, progress, toolchain).with_context(|| {
                     format!("Failed to run build scripts for {}", &cargo.workspace_root().display())
                 })
             }
@@ -320,6 +328,7 @@ impl ProjectWorkspace {
                 rustc_cfg: _,
                 cfg_overrides: _,
                 build_scripts,
+                toolchain: _,
             } => {
                 cargo
                     .packages()
@@ -425,6 +434,7 @@ impl ProjectWorkspace {
                 rustc_cfg,
                 cfg_overrides,
                 build_scripts,
+                toolchain: _,
             } => cargo_to_crate_graph(
                 rustc_cfg.clone(),
                 cfg_overrides,
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 49ccad71a10e8..ceb2a6d703d95 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -219,6 +219,7 @@ impl GlobalState {
                     cfg_overrides,
 
                     build_scripts: _,
+                    toolchain: _,
                 } => Some((cargo, sysroot, rustc, rustc_cfg, cfg_overrides)),
                 _ => None,
             };

From 8c9359b072098403eb0b37a1b0822bb7b4f3b8ba Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Tue, 9 Aug 2022 17:53:16 +0200
Subject: [PATCH 18/39] Fix pattern field completions not working for unions

---
 crates/ide-completion/src/completions.rs      |   1 -
 crates/ide-completion/src/completions/expr.rs | 110 ++++++++++--------
 .../ide-completion/src/completions/record.rs  |  47 ++++----
 crates/ide-completion/src/context.rs          |   1 +
 crates/ide-completion/src/tests/record.rs     |  53 +++++----
 5 files changed, 118 insertions(+), 94 deletions(-)

diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs
index 72579e6026aee..55c3e28392a4d 100644
--- a/crates/ide-completion/src/completions.rs
+++ b/crates/ide-completion/src/completions.rs
@@ -617,7 +617,6 @@ pub(super) fn complete_name_ref(
 
                     dot::complete_undotted_self(acc, ctx, path_ctx, expr_ctx);
                     item_list::complete_item_list_in_expr(acc, ctx, path_ctx, expr_ctx);
-                    record::complete_record_expr_func_update(acc, ctx, path_ctx, expr_ctx);
                     snippet::complete_expr_snippet(acc, ctx, path_ctx, expr_ctx);
                 }
                 PathKind::Type { location } => {
diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs
index 5d0ddaaf2a228..e6c4bdf5206c6 100644
--- a/crates/ide-completion/src/completions/expr.rs
+++ b/crates/ide-completion/src/completions/expr.rs
@@ -1,8 +1,10 @@
 //! Completion of names from the current scope in expression position.
 
 use hir::ScopeDef;
+use syntax::ast;
 
 use crate::{
+    completions::record::add_default_update,
     context::{ExprCtx, PathCompletionCtx, Qualified},
     CompletionContext, Completions,
 };
@@ -219,60 +221,76 @@ pub(crate) fn complete_expr_path(
                 _ => (),
             });
 
-            if is_func_update.is_none() {
-                let mut add_keyword =
-                    |kw, snippet| acc.add_keyword_snippet_expr(ctx, incomplete_let, kw, snippet);
+            match is_func_update {
+                Some(record_expr) => {
+                    let ty = ctx.sema.type_of_expr(&ast::Expr::RecordExpr(record_expr.clone()));
 
-                if !in_block_expr {
-                    add_keyword("unsafe", "unsafe {\n    $0\n}");
-                }
-                add_keyword("match", "match $1 {\n    $0\n}");
-                add_keyword("while", "while $1 {\n    $0\n}");
-                add_keyword("while let", "while let $1 = $2 {\n    $0\n}");
-                add_keyword("loop", "loop {\n    $0\n}");
-                if in_match_guard {
-                    add_keyword("if", "if $0");
-                } else {
-                    add_keyword("if", "if $1 {\n    $0\n}");
+                    match ty.as_ref().and_then(|t| t.original.as_adt()) {
+                        Some(hir::Adt::Union(_)) => (),
+                        _ => {
+                            cov_mark::hit!(functional_update);
+                            let missing_fields =
+                                ctx.sema.record_literal_missing_fields(record_expr);
+                            add_default_update(acc, ctx, ty, &missing_fields);
+                        }
+                    };
                 }
-                add_keyword("if let", "if let $1 = $2 {\n    $0\n}");
-                add_keyword("for", "for $1 in $2 {\n    $0\n}");
-                add_keyword("true", "true");
-                add_keyword("false", "false");
+                None => {
+                    let mut add_keyword = |kw, snippet| {
+                        acc.add_keyword_snippet_expr(ctx, incomplete_let, kw, snippet)
+                    };
 
-                if in_condition || in_block_expr {
-                    add_keyword("let", "let");
-                }
+                    if !in_block_expr {
+                        add_keyword("unsafe", "unsafe {\n    $0\n}");
+                    }
+                    add_keyword("match", "match $1 {\n    $0\n}");
+                    add_keyword("while", "while $1 {\n    $0\n}");
+                    add_keyword("while let", "while let $1 = $2 {\n    $0\n}");
+                    add_keyword("loop", "loop {\n    $0\n}");
+                    if in_match_guard {
+                        add_keyword("if", "if $0");
+                    } else {
+                        add_keyword("if", "if $1 {\n    $0\n}");
+                    }
+                    add_keyword("if let", "if let $1 = $2 {\n    $0\n}");
+                    add_keyword("for", "for $1 in $2 {\n    $0\n}");
+                    add_keyword("true", "true");
+                    add_keyword("false", "false");
 
-                if after_if_expr {
-                    add_keyword("else", "else {\n    $0\n}");
-                    add_keyword("else if", "else if $1 {\n    $0\n}");
-                }
+                    if in_condition || in_block_expr {
+                        add_keyword("let", "let");
+                    }
 
-                if wants_mut_token {
-                    add_keyword("mut", "mut ");
-                }
+                    if after_if_expr {
+                        add_keyword("else", "else {\n    $0\n}");
+                        add_keyword("else if", "else if $1 {\n    $0\n}");
+                    }
 
-                if in_loop_body {
-                    if in_block_expr {
-                        add_keyword("continue", "continue;");
-                        add_keyword("break", "break;");
-                    } else {
-                        add_keyword("continue", "continue");
-                        add_keyword("break", "break");
+                    if wants_mut_token {
+                        add_keyword("mut", "mut ");
+                    }
+
+                    if in_loop_body {
+                        if in_block_expr {
+                            add_keyword("continue", "continue;");
+                            add_keyword("break", "break;");
+                        } else {
+                            add_keyword("continue", "continue");
+                            add_keyword("break", "break");
+                        }
                     }
-                }
 
-                if let Some(ty) = innermost_ret_ty {
-                    add_keyword(
-                        "return",
-                        match (in_block_expr, ty.is_unit()) {
-                            (true, true) => "return ;",
-                            (true, false) => "return;",
-                            (false, true) => "return $0",
-                            (false, false) => "return",
-                        },
-                    );
+                    if let Some(ty) = innermost_ret_ty {
+                        add_keyword(
+                            "return",
+                            match (in_block_expr, ty.is_unit()) {
+                                (true, true) => "return ;",
+                                (true, false) => "return;",
+                                (false, true) => "return $0",
+                                (false, false) => "return",
+                            },
+                        );
+                    }
                 }
             }
         }
diff --git a/crates/ide-completion/src/completions/record.rs b/crates/ide-completion/src/completions/record.rs
index 1c9042390d3b2..3f85b45a13cbf 100644
--- a/crates/ide-completion/src/completions/record.rs
+++ b/crates/ide-completion/src/completions/record.rs
@@ -3,7 +3,7 @@ use ide_db::SymbolKind;
 use syntax::ast::{self, Expr};
 
 use crate::{
-    context::{DotAccess, DotAccessKind, ExprCtx, PathCompletionCtx, PatternContext, Qualified},
+    context::{DotAccess, DotAccessKind, PatternContext},
     CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
     CompletionRelevancePostfixMatch, Completions,
 };
@@ -14,7 +14,24 @@ pub(crate) fn complete_record_pattern_fields(
     pattern_ctx: &PatternContext,
 ) {
     if let PatternContext { record_pat: Some(record_pat), .. } = pattern_ctx {
-        complete_fields(acc, ctx, ctx.sema.record_pattern_missing_fields(record_pat));
+        let ty = ctx.sema.type_of_pat(&ast::Pat::RecordPat(record_pat.clone()));
+        let missing_fields = match ty.as_ref().and_then(|t| t.original.as_adt()) {
+            Some(hir::Adt::Union(un)) => {
+                // ctx.sema.record_pat_missing_fields will always return
+                // an empty Vec on a union literal. This is normally
+                // reasonable, but here we'd like to present the full list
+                // of fields if the literal is empty.
+                let were_fields_specified =
+                    record_pat.record_pat_field_list().and_then(|fl| fl.fields().next()).is_some();
+
+                match were_fields_specified {
+                    false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
+                    true => return,
+                }
+            }
+            _ => ctx.sema.record_pattern_missing_fields(record_pat),
+        };
+        complete_fields(acc, ctx, missing_fields);
     }
 }
 
@@ -44,6 +61,7 @@ pub(crate) fn complete_record_expr_fields(
             let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
             add_default_update(acc, ctx, ty, &missing_fields);
             if dot_prefix {
+                cov_mark::hit!(functional_update_one_dot);
                 let mut item =
                     CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), "..");
                 item.insert_text(".");
@@ -56,30 +74,7 @@ pub(crate) fn complete_record_expr_fields(
     complete_fields(acc, ctx, missing_fields);
 }
 
-// FIXME: This should probably be part of complete_path_expr
-pub(crate) fn complete_record_expr_func_update(
-    acc: &mut Completions,
-    ctx: &CompletionContext<'_>,
-    path_ctx: &PathCompletionCtx,
-    expr_ctx: &ExprCtx,
-) {
-    if !matches!(path_ctx.qualified, Qualified::No) {
-        return;
-    }
-    if let ExprCtx { is_func_update: Some(record_expr), .. } = expr_ctx {
-        let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));
-
-        match ty.as_ref().and_then(|t| t.original.as_adt()) {
-            Some(hir::Adt::Union(_)) => (),
-            _ => {
-                let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
-                add_default_update(acc, ctx, ty, &missing_fields);
-            }
-        };
-    }
-}
-
-fn add_default_update(
+pub(crate) fn add_default_update(
     acc: &mut Completions,
     ctx: &CompletionContext<'_>,
     ty: Option<hir::TypeInfo>,
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index e35f79d2b6951..759742d347237 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -134,6 +134,7 @@ pub(crate) struct ExprCtx {
     pub(crate) in_condition: bool,
     pub(crate) incomplete_let: bool,
     pub(crate) ref_expr_parent: Option<ast::RefExpr>,
+    /// The surrounding RecordExpression we are completing a functional update
     pub(crate) is_func_update: Option<ast::RecordExpr>,
     pub(crate) self_param: Option<hir::SelfParam>,
     pub(crate) innermost_ret_ty: Option<hir::Type>,
diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs
index f6accc68e5e80..e9ee51611796a 100644
--- a/crates/ide-completion/src/tests/record.rs
+++ b/crates/ide-completion/src/tests/record.rs
@@ -103,8 +103,9 @@ fn foo(f: Struct) {
 }
 
 #[test]
-fn functional_update() {
-    // FIXME: This should filter out all completions that do not have the type `Foo`
+fn in_functional_update() {
+    cov_mark::check!(functional_update);
+
     check(
         r#"
 //- minicore:default
@@ -116,13 +117,21 @@ impl Default for Foo {
 fn main() {
     let thing = 1;
     let foo = Foo { foo1: 0, foo2: 0 };
-    let foo2 = Foo { thing, $0 }
+    let foo2 = Foo { thing, ..$0 }
 }
 "#,
         expect![[r#"
             fd ..Default::default()
-            fd foo1                 u32
-            fd foo2                 u32
+            fn main()               fn()
+            lc foo                  Foo
+            lc thing                i32
+            md core
+            st Foo
+            st Foo {…}              Foo { foo1: u32, foo2: u32 }
+            tt Default
+            bt u32
+            kw crate::
+            kw self::
         "#]],
     );
     check(
@@ -136,14 +145,18 @@ impl Default for Foo {
 fn main() {
     let thing = 1;
     let foo = Foo { foo1: 0, foo2: 0 };
-    let foo2 = Foo { thing, .$0 }
+    let foo2 = Foo { thing, ..Default::$0 }
 }
 "#,
         expect![[r#"
-            fd ..Default::default()
-            sn ..
+            fn default() (as Default) fn() -> Self
         "#]],
     );
+}
+
+#[test]
+fn functional_update_no_dot() {
+    // FIXME: This should filter out all completions that do not have the type `Foo`
     check(
         r#"
 //- minicore:default
@@ -155,23 +168,20 @@ impl Default for Foo {
 fn main() {
     let thing = 1;
     let foo = Foo { foo1: 0, foo2: 0 };
-    let foo2 = Foo { thing, ..$0 }
+    let foo2 = Foo { thing, $0 }
 }
 "#,
         expect![[r#"
             fd ..Default::default()
-            fn main()               fn()
-            lc foo                  Foo
-            lc thing                i32
-            md core
-            st Foo
-            st Foo {…}              Foo { foo1: u32, foo2: u32 }
-            tt Default
-            bt u32
-            kw crate::
-            kw self::
+            fd foo1                 u32
+            fd foo2                 u32
         "#]],
     );
+}
+
+#[test]
+fn functional_update_one_dot() {
+    cov_mark::check!(functional_update_one_dot);
     check(
         r#"
 //- minicore:default
@@ -183,11 +193,12 @@ impl Default for Foo {
 fn main() {
     let thing = 1;
     let foo = Foo { foo1: 0, foo2: 0 };
-    let foo2 = Foo { thing, ..Default::$0 }
+    let foo2 = Foo { thing, .$0 }
 }
 "#,
         expect![[r#"
-            fn default() (as Default) fn() -> Self
+            fd ..Default::default()
+            sn ..
         "#]],
     );
 }

From b3ac58dfb80e6dad9fc777f23247fd379424b65e Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Tue, 9 Aug 2022 18:08:05 +0200
Subject: [PATCH 19/39] Add some more `cov_mark`s

---
 crates/ide-completion/src/completions/expr.rs   |  4 +++-
 crates/ide-completion/src/completions/record.rs | 12 ++++++++----
 crates/ide-completion/src/tests/record.rs       |  1 +
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs
index e6c4bdf5206c6..4d66af9e8d5b8 100644
--- a/crates/ide-completion/src/completions/expr.rs
+++ b/crates/ide-completion/src/completions/expr.rs
@@ -231,7 +231,9 @@ pub(crate) fn complete_expr_path(
                             cov_mark::hit!(functional_update);
                             let missing_fields =
                                 ctx.sema.record_literal_missing_fields(record_expr);
-                            add_default_update(acc, ctx, ty, &missing_fields);
+                            if !missing_fields.is_empty() {
+                                add_default_update(acc, ctx, ty);
+                            }
                         }
                     };
                 }
diff --git a/crates/ide-completion/src/completions/record.rs b/crates/ide-completion/src/completions/record.rs
index 3f85b45a13cbf..bfb98b9f2777f 100644
--- a/crates/ide-completion/src/completions/record.rs
+++ b/crates/ide-completion/src/completions/record.rs
@@ -59,7 +59,11 @@ pub(crate) fn complete_record_expr_fields(
         }
         _ => {
             let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
-            add_default_update(acc, ctx, ty, &missing_fields);
+
+            if !missing_fields.is_empty() {
+                cov_mark::hit!(functional_update_field);
+                add_default_update(acc, ctx, ty);
+            }
             if dot_prefix {
                 cov_mark::hit!(functional_update_one_dot);
                 let mut item =
@@ -78,14 +82,14 @@ pub(crate) fn add_default_update(
     acc: &mut Completions,
     ctx: &CompletionContext<'_>,
     ty: Option<hir::TypeInfo>,
-    missing_fields: &[(hir::Field, hir::Type)],
 ) {
     let default_trait = ctx.famous_defs().core_default_Default();
-    let impl_default_trait = default_trait
+    let impls_default_trait = default_trait
         .zip(ty.as_ref())
         .map_or(false, |(default_trait, ty)| ty.original.impls_trait(ctx.db, default_trait, &[]));
-    if impl_default_trait && !missing_fields.is_empty() {
+    if impls_default_trait {
         // FIXME: This should make use of scope_def like completions so we get all the other goodies
+        // that is we should handle this like actually completing the default function
         let completion_text = "..Default::default()";
         let mut item = CompletionItem::new(SymbolKind::Field, ctx.source_range(), completion_text);
         let completion_text =
diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs
index e9ee51611796a..328faaa060f04 100644
--- a/crates/ide-completion/src/tests/record.rs
+++ b/crates/ide-completion/src/tests/record.rs
@@ -156,6 +156,7 @@ fn main() {
 
 #[test]
 fn functional_update_no_dot() {
+    cov_mark::check!(functional_update_field);
     // FIXME: This should filter out all completions that do not have the type `Foo`
     check(
         r#"

From 49d24f639f60325000463f6bb20d832c0ac72da6 Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Tue, 9 Aug 2022 18:23:25 +0200
Subject: [PATCH 20/39] Recover from missing ellipsis in record literals for
 path expressions

---
 crates/parser/src/grammar/expressions.rs      | 26 +++++++---
 ...ord_literal_missing_ellipsis_recovery.rast | 43 ++++++++++++++++
 ...ecord_literal_missing_ellipsis_recovery.rs |  3 ++
 .../parser/inline/ok/0061_record_lit.rast     | 49 +++++++++++++++++++
 .../parser/inline/ok/0061_record_lit.rs       |  2 +
 5 files changed, 116 insertions(+), 7 deletions(-)
 create mode 100644 crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast
 create mode 100644 crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs

diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs
index e7402104eb83f..dcaceade652ab 100644
--- a/crates/parser/src/grammar/expressions.rs
+++ b/crates/parser/src/grammar/expressions.rs
@@ -564,8 +564,10 @@ fn path_expr(p: &mut Parser<'_>, r: Restrictions) -> (CompletedMarker, BlockLike
 // test record_lit
 // fn foo() {
 //     S {};
+//     S { x };
 //     S { x, y: 32, };
 //     S { x, y: 32, ..Default::default() };
+//     S { x: ::default() };
 //     TupleStruct { 0: 1 };
 // }
 pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
@@ -582,16 +584,26 @@ pub(crate) fn record_expr_field_list(p: &mut Parser<'_>) {
 
         match p.current() {
             IDENT | INT_NUMBER => {
-                // test_err record_literal_before_ellipsis_recovery
+                // test_err record_literal_missing_ellipsis_recovery
                 // fn main() {
-                //     S { field ..S::default() }
+                //     S { S::default() }
                 // }
-                if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
-                    name_ref_or_index(p);
-                    p.expect(T![:]);
+                if p.nth_at(1, T![::]) {
+                    m.abandon(p);
+                    p.expect(T![..]);
+                    expr(p);
+                } else {
+                    // test_err record_literal_before_ellipsis_recovery
+                    // fn main() {
+                    //     S { field ..S::default() }
+                    // }
+                    if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
+                        name_ref_or_index(p);
+                        p.expect(T![:]);
+                    }
+                    expr(p);
+                    m.complete(p, RECORD_EXPR_FIELD);
                 }
-                expr(p);
-                m.complete(p, RECORD_EXPR_FIELD);
             }
             T![.] if p.at(T![..]) => {
                 m.abandon(p);
diff --git a/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast b/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast
new file mode 100644
index 0000000000000..0c5b618e6f05c
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rast
@@ -0,0 +1,43 @@
+SOURCE_FILE
+  FN
+    FN_KW "fn"
+    WHITESPACE " "
+    NAME
+      IDENT "main"
+    PARAM_LIST
+      L_PAREN "("
+      R_PAREN ")"
+    WHITESPACE " "
+    BLOCK_EXPR
+      STMT_LIST
+        L_CURLY "{"
+        WHITESPACE "\n    "
+        RECORD_EXPR
+          PATH
+            PATH_SEGMENT
+              NAME_REF
+                IDENT "S"
+          WHITESPACE " "
+          RECORD_EXPR_FIELD_LIST
+            L_CURLY "{"
+            WHITESPACE " "
+            CALL_EXPR
+              PATH_EXPR
+                PATH
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "S"
+                  COLON2 "::"
+                  PATH_SEGMENT
+                    NAME_REF
+                      IDENT "default"
+              ARG_LIST
+                L_PAREN "("
+                R_PAREN ")"
+            WHITESPACE " "
+            R_CURLY "}"
+        WHITESPACE "\n"
+        R_CURLY "}"
+  WHITESPACE "\n"
+error 19: expected DOT2
diff --git a/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs b/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs
new file mode 100644
index 0000000000000..1b594e8ab962c
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/0014_record_literal_missing_ellipsis_recovery.rs
@@ -0,0 +1,3 @@
+fn main() {
+    S { S::default() }
+}
diff --git a/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast b/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast
index 9997d0ae348c4..00948c322f4c9 100644
--- a/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast
+++ b/crates/parser/test_data/parser/inline/ok/0061_record_lit.rast
@@ -24,6 +24,26 @@ SOURCE_FILE
               R_CURLY "}"
           SEMICOLON ";"
         WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              RECORD_EXPR_FIELD
+                PATH_EXPR
+                  PATH
+                    PATH_SEGMENT
+                      NAME_REF
+                        IDENT "x"
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
         EXPR_STMT
           RECORD_EXPR
             PATH
@@ -100,6 +120,35 @@ SOURCE_FILE
               R_CURLY "}"
           SEMICOLON ";"
         WHITESPACE "\n    "
+        EXPR_STMT
+          RECORD_EXPR
+            PATH
+              PATH_SEGMENT
+                NAME_REF
+                  IDENT "S"
+            WHITESPACE " "
+            RECORD_EXPR_FIELD_LIST
+              L_CURLY "{"
+              WHITESPACE " "
+              RECORD_EXPR_FIELD
+                NAME_REF
+                  IDENT "x"
+                COLON ":"
+                WHITESPACE " "
+                CALL_EXPR
+                  PATH_EXPR
+                    PATH
+                      PATH_SEGMENT
+                        COLON2 "::"
+                        NAME_REF
+                          IDENT "default"
+                  ARG_LIST
+                    L_PAREN "("
+                    R_PAREN ")"
+              WHITESPACE " "
+              R_CURLY "}"
+          SEMICOLON ";"
+        WHITESPACE "\n    "
         EXPR_STMT
           RECORD_EXPR
             PATH
diff --git a/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs b/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs
index 6285e55497722..86411fbb7dc05 100644
--- a/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs
+++ b/crates/parser/test_data/parser/inline/ok/0061_record_lit.rs
@@ -1,6 +1,8 @@
 fn foo() {
     S {};
+    S { x };
     S { x, y: 32, };
     S { x, y: 32, ..Default::default() };
+    S { x: ::default() };
     TupleStruct { 0: 1 };
 }

From f4f70c0e0da9783eb0b935e0c8698a9505c7b45e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= <lnicola@dend.ro>
Date: Wed, 10 Aug 2022 10:49:49 +0300
Subject: [PATCH 21/39] Remove incomplete 1.64 ABI

---
 .../proc-macro-srv/src/abis/abi_1_64/mod.rs   |  105 --
 .../abis/abi_1_64/proc_macro/bridge/buffer.rs |  156 ---
 .../abis/abi_1_64/proc_macro/bridge/client.rs |  529 --------
 .../abi_1_64/proc_macro/bridge/closure.rs     |   32 -
 .../abis/abi_1_64/proc_macro/bridge/handle.rs |   89 --
 .../abis/abi_1_64/proc_macro/bridge/mod.rs    |  493 --------
 .../abis/abi_1_64/proc_macro/bridge/rpc.rs    |  304 -----
 .../abi_1_64/proc_macro/bridge/scoped_cell.rs |   81 --
 .../proc_macro/bridge/selfless_reify.rs       |   84 --
 .../abis/abi_1_64/proc_macro/bridge/server.rs |  339 -----
 .../abis/abi_1_64/proc_macro/diagnostic.rs    |  166 ---
 .../src/abis/abi_1_64/proc_macro/mod.rs       | 1125 -----------------
 .../src/abis/abi_1_64/proc_macro/quote.rs     |  139 --
 .../src/abis/abi_1_64/ra_server.rs            |  791 ------------
 crates/proc-macro-srv/src/abis/mod.rs         |   11 +-
 15 files changed, 1 insertion(+), 4443 deletions(-)
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/mod.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs
 delete mode 100644 crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs

diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs b/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs
deleted file mode 100644
index 9d56f0eaf888f..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/mod.rs
+++ /dev/null
@@ -1,105 +0,0 @@
-//! Proc macro ABI.
-
-#[allow(dead_code)]
-#[doc(hidden)]
-mod proc_macro;
-
-#[allow(dead_code)]
-#[doc(hidden)]
-mod ra_server;
-
-use libloading::Library;
-use proc_macro_api::ProcMacroKind;
-
-use super::PanicMessage;
-
-pub use ra_server::TokenStream;
-
-pub(crate) struct Abi {
-    exported_macros: Vec<proc_macro::bridge::client::ProcMacro>,
-}
-
-impl From<proc_macro::bridge::PanicMessage> for PanicMessage {
-    fn from(p: proc_macro::bridge::PanicMessage) -> Self {
-        Self { message: p.as_str().map(|s| s.to_string()) }
-    }
-}
-
-impl Abi {
-    pub unsafe fn from_lib(lib: &Library, symbol_name: String) -> Result<Abi, libloading::Error> {
-        let macros: libloading::Symbol<'_, &&[proc_macro::bridge::client::ProcMacro]> =
-            lib.get(symbol_name.as_bytes())?;
-        Ok(Self { exported_macros: macros.to_vec() })
-    }
-
-    pub fn expand(
-        &self,
-        macro_name: &str,
-        macro_body: &tt::Subtree,
-        attributes: Option<&tt::Subtree>,
-    ) -> Result<tt::Subtree, PanicMessage> {
-        let parsed_body = TokenStream::with_subtree(macro_body.clone());
-
-        let parsed_attributes =
-            attributes.map_or(TokenStream::new(), |attr| TokenStream::with_subtree(attr.clone()));
-
-        for proc_macro in &self.exported_macros {
-            match proc_macro {
-                proc_macro::bridge::client::ProcMacro::CustomDerive {
-                    trait_name, client, ..
-                } if *trait_name == macro_name => {
-                    let res = client.run(
-                        &proc_macro::bridge::server::SameThread,
-                        ra_server::RustAnalyzer::default(),
-                        parsed_body,
-                        true,
-                    );
-                    return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
-                }
-                proc_macro::bridge::client::ProcMacro::Bang { name, client }
-                    if *name == macro_name =>
-                {
-                    let res = client.run(
-                        &proc_macro::bridge::server::SameThread,
-                        ra_server::RustAnalyzer::default(),
-                        parsed_body,
-                        true,
-                    );
-                    return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
-                }
-                proc_macro::bridge::client::ProcMacro::Attr { name, client }
-                    if *name == macro_name =>
-                {
-                    let res = client.run(
-                        &proc_macro::bridge::server::SameThread,
-                        ra_server::RustAnalyzer::default(),
-                        parsed_attributes,
-                        parsed_body,
-                        true,
-                    );
-                    return res.map(|it| it.into_subtree()).map_err(PanicMessage::from);
-                }
-                _ => continue,
-            }
-        }
-
-        Err(proc_macro::bridge::PanicMessage::String("Nothing to expand".to_string()).into())
-    }
-
-    pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
-        self.exported_macros
-            .iter()
-            .map(|proc_macro| match proc_macro {
-                proc_macro::bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
-                    (trait_name.to_string(), ProcMacroKind::CustomDerive)
-                }
-                proc_macro::bridge::client::ProcMacro::Bang { name, .. } => {
-                    (name.to_string(), ProcMacroKind::FuncLike)
-                }
-                proc_macro::bridge::client::ProcMacro::Attr { name, .. } => {
-                    (name.to_string(), ProcMacroKind::Attr)
-                }
-            })
-            .collect()
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs
deleted file mode 100644
index 48030f8d82dca..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/buffer.rs
+++ /dev/null
@@ -1,156 +0,0 @@
-//! Buffer management for same-process client<->server communication.
-
-use std::io::{self, Write};
-use std::mem;
-use std::ops::{Deref, DerefMut};
-use std::slice;
-
-#[repr(C)]
-pub struct Buffer {
-    data: *mut u8,
-    len: usize,
-    capacity: usize,
-    reserve: extern "C" fn(Buffer, usize) -> Buffer,
-    drop: extern "C" fn(Buffer),
-}
-
-unsafe impl Sync for Buffer {}
-unsafe impl Send for Buffer {}
-
-impl Default for Buffer {
-    #[inline]
-    fn default() -> Self {
-        Self::from(vec![])
-    }
-}
-
-impl Deref for Buffer {
-    type Target = [u8];
-    #[inline]
-    fn deref(&self) -> &[u8] {
-        unsafe { slice::from_raw_parts(self.data as *const u8, self.len) }
-    }
-}
-
-impl DerefMut for Buffer {
-    #[inline]
-    fn deref_mut(&mut self) -> &mut [u8] {
-        unsafe { slice::from_raw_parts_mut(self.data, self.len) }
-    }
-}
-
-impl Buffer {
-    #[inline]
-    pub(super) fn new() -> Self {
-        Self::default()
-    }
-
-    #[inline]
-    pub(super) fn clear(&mut self) {
-        self.len = 0;
-    }
-
-    #[inline]
-    pub(super) fn take(&mut self) -> Self {
-        mem::take(self)
-    }
-
-    // We have the array method separate from extending from a slice. This is
-    // because in the case of small arrays, codegen can be more efficient
-    // (avoiding a memmove call). With extend_from_slice, LLVM at least
-    // currently is not able to make that optimization.
-    #[inline]
-    pub(super) fn extend_from_array<const N: usize>(&mut self, xs: &[u8; N]) {
-        if xs.len() > (self.capacity - self.len) {
-            let b = self.take();
-            *self = (b.reserve)(b, xs.len());
-        }
-        unsafe {
-            xs.as_ptr().copy_to_nonoverlapping(self.data.add(self.len), xs.len());
-            self.len += xs.len();
-        }
-    }
-
-    #[inline]
-    pub(super) fn extend_from_slice(&mut self, xs: &[u8]) {
-        if xs.len() > (self.capacity - self.len) {
-            let b = self.take();
-            *self = (b.reserve)(b, xs.len());
-        }
-        unsafe {
-            xs.as_ptr().copy_to_nonoverlapping(self.data.add(self.len), xs.len());
-            self.len += xs.len();
-        }
-    }
-
-    #[inline]
-    pub(super) fn push(&mut self, v: u8) {
-        // The code here is taken from Vec::push, and we know that reserve()
-        // will panic if we're exceeding isize::MAX bytes and so there's no need
-        // to check for overflow.
-        if self.len == self.capacity {
-            let b = self.take();
-            *self = (b.reserve)(b, 1);
-        }
-        unsafe {
-            *self.data.add(self.len) = v;
-            self.len += 1;
-        }
-    }
-}
-
-impl Write for Buffer {
-    #[inline]
-    fn write(&mut self, xs: &[u8]) -> io::Result<usize> {
-        self.extend_from_slice(xs);
-        Ok(xs.len())
-    }
-
-    #[inline]
-    fn write_all(&mut self, xs: &[u8]) -> io::Result<()> {
-        self.extend_from_slice(xs);
-        Ok(())
-    }
-
-    #[inline]
-    fn flush(&mut self) -> io::Result<()> {
-        Ok(())
-    }
-}
-
-impl Drop for Buffer {
-    #[inline]
-    fn drop(&mut self) {
-        let b = self.take();
-        (b.drop)(b);
-    }
-}
-
-impl From<Vec<u8>> for Buffer {
-    fn from(mut v: Vec<u8>) -> Self {
-        let (data, len, capacity) = (v.as_mut_ptr(), v.len(), v.capacity());
-        mem::forget(v);
-
-        // This utility function is nested in here because it can *only*
-        // be safely called on `Buffer`s created by *this* `proc_macro`.
-        fn to_vec(b: Buffer) -> Vec<u8> {
-            unsafe {
-                let Buffer { data, len, capacity, .. } = b;
-                mem::forget(b);
-                Vec::from_raw_parts(data, len, capacity)
-            }
-        }
-
-        extern "C" fn reserve(b: Buffer, additional: usize) -> Buffer {
-            let mut v = to_vec(b);
-            v.reserve(additional);
-            Buffer::from(v)
-        }
-
-        extern "C" fn drop(b: Buffer) {
-            mem::drop(to_vec(b));
-        }
-
-        Buffer { data, len, capacity, reserve, drop }
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs
deleted file mode 100644
index 22bda8ba5a7cf..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/client.rs
+++ /dev/null
@@ -1,529 +0,0 @@
-//! Client-side types.
-
-use super::*;
-
-use std::marker::PhantomData;
-
-macro_rules! define_handles {
-    (
-        'owned: $($oty:ident,)*
-        'interned: $($ity:ident,)*
-    ) => {
-        #[repr(C)]
-        #[allow(non_snake_case)]
-        pub struct HandleCounters {
-            $($oty: AtomicUsize,)*
-            $($ity: AtomicUsize,)*
-        }
-
-        impl HandleCounters {
-            // FIXME(eddyb) use a reference to the `static COUNTERS`, instead of
-            // a wrapper `fn` pointer, once `const fn` can reference `static`s.
-            extern "C" fn get() -> &'static Self {
-                static COUNTERS: HandleCounters = HandleCounters {
-                    $($oty: AtomicUsize::new(1),)*
-                    $($ity: AtomicUsize::new(1),)*
-                };
-                &COUNTERS
-            }
-        }
-
-        // FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
-        #[repr(C)]
-        #[allow(non_snake_case)]
-        pub(super) struct HandleStore<S: server::Types> {
-            $($oty: handle::OwnedStore<S::$oty>,)*
-            $($ity: handle::InternedStore<S::$ity>,)*
-        }
-
-        impl<S: server::Types> HandleStore<S> {
-            pub(super) fn new(handle_counters: &'static HandleCounters) -> Self {
-                HandleStore {
-                    $($oty: handle::OwnedStore::new(&handle_counters.$oty),)*
-                    $($ity: handle::InternedStore::new(&handle_counters.$ity),)*
-                }
-            }
-        }
-
-        $(
-            #[repr(C)]
-            pub(crate) struct $oty {
-                handle: handle::Handle,
-                // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
-                // way of doing this, but that requires unstable features.
-                // rust-analyzer uses this code and avoids unstable features.
-                _marker: PhantomData<*mut ()>,
-            }
-
-            // Forward `Drop::drop` to the inherent `drop` method.
-            impl Drop for $oty {
-                fn drop(&mut self) {
-                    $oty {
-                        handle: self.handle,
-                        _marker: PhantomData,
-                    }.drop();
-                }
-            }
-
-            impl<S> Encode<S> for $oty {
-                fn encode(self, w: &mut Writer, s: &mut S) {
-                    let handle = self.handle;
-                    mem::forget(self);
-                    handle.encode(w, s);
-                }
-            }
-
-            impl<S: server::Types> DecodeMut<'_, '_, HandleStore<server::MarkedTypes<S>>>
-                for Marked<S::$oty, $oty>
-            {
-                fn decode(r: &mut Reader<'_>, s: &mut HandleStore<server::MarkedTypes<S>>) -> Self {
-                    s.$oty.take(handle::Handle::decode(r, &mut ()))
-                }
-            }
-
-            impl<S> Encode<S> for &$oty {
-                fn encode(self, w: &mut Writer, s: &mut S) {
-                    self.handle.encode(w, s);
-                }
-            }
-
-            impl<'s, S: server::Types> Decode<'_, 's, HandleStore<server::MarkedTypes<S>>>
-                for &'s Marked<S::$oty, $oty>
-            {
-                fn decode(r: &mut Reader<'_>, s: &'s HandleStore<server::MarkedTypes<S>>) -> Self {
-                    &s.$oty[handle::Handle::decode(r, &mut ())]
-                }
-            }
-
-            impl<S> Encode<S> for &mut $oty {
-                fn encode(self, w: &mut Writer, s: &mut S) {
-                    self.handle.encode(w, s);
-                }
-            }
-
-            impl<'s, S: server::Types> DecodeMut<'_, 's, HandleStore<server::MarkedTypes<S>>>
-                for &'s mut Marked<S::$oty, $oty>
-            {
-                fn decode(
-                    r: &mut Reader<'_>,
-                    s: &'s mut HandleStore<server::MarkedTypes<S>>
-                ) -> Self {
-                    &mut s.$oty[handle::Handle::decode(r, &mut ())]
-                }
-            }
-
-            impl<S: server::Types> Encode<HandleStore<server::MarkedTypes<S>>>
-                for Marked<S::$oty, $oty>
-            {
-                fn encode(self, w: &mut Writer, s: &mut HandleStore<server::MarkedTypes<S>>) {
-                    s.$oty.alloc(self).encode(w, s);
-                }
-            }
-
-            impl<S> DecodeMut<'_, '_, S> for $oty {
-                fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-                    $oty {
-                        handle: handle::Handle::decode(r, s),
-                        _marker: PhantomData,
-                    }
-                }
-            }
-        )*
-
-        $(
-            #[repr(C)]
-            #[derive(Copy, Clone, PartialEq, Eq, Hash)]
-            pub(crate) struct $ity {
-                handle: handle::Handle,
-                // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual
-                // way of doing this, but that requires unstable features.
-                // rust-analyzer uses this code and avoids unstable features.
-                _marker: PhantomData<*mut ()>,
-            }
-
-            impl<S> Encode<S> for $ity {
-                fn encode(self, w: &mut Writer, s: &mut S) {
-                    self.handle.encode(w, s);
-                }
-            }
-
-            impl<S: server::Types> DecodeMut<'_, '_, HandleStore<server::MarkedTypes<S>>>
-                for Marked<S::$ity, $ity>
-            {
-                fn decode(r: &mut Reader<'_>, s: &mut HandleStore<server::MarkedTypes<S>>) -> Self {
-                    s.$ity.copy(handle::Handle::decode(r, &mut ()))
-                }
-            }
-
-            impl<S: server::Types> Encode<HandleStore<server::MarkedTypes<S>>>
-                for Marked<S::$ity, $ity>
-            {
-                fn encode(self, w: &mut Writer, s: &mut HandleStore<server::MarkedTypes<S>>) {
-                    s.$ity.alloc(self).encode(w, s);
-                }
-            }
-
-            impl<S> DecodeMut<'_, '_, S> for $ity {
-                fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-                    $ity {
-                        handle: handle::Handle::decode(r, s),
-                        _marker: PhantomData,
-                    }
-                }
-            }
-        )*
-    }
-}
-define_handles! {
-    'owned:
-    FreeFunctions,
-    TokenStream,
-    Literal,
-    SourceFile,
-    MultiSpan,
-    Diagnostic,
-
-    'interned:
-    Ident,
-    Span,
-}
-
-// FIXME(eddyb) generate these impls by pattern-matching on the
-// names of methods - also could use the presence of `fn drop`
-// to distinguish between 'owned and 'interned, above.
-// Alternatively, special "modes" could be listed of types in with_api
-// instead of pattern matching on methods, here and in server decl.
-
-impl Clone for TokenStream {
-    fn clone(&self) -> Self {
-        self.clone()
-    }
-}
-
-impl Clone for Literal {
-    fn clone(&self) -> Self {
-        self.clone()
-    }
-}
-
-impl fmt::Debug for Literal {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Literal")
-            // format the kind without quotes, as in `kind: Float`
-            .field("kind", &format_args!("{}", &self.debug_kind()))
-            .field("symbol", &self.symbol())
-            // format `Some("...")` on one line even in {:#?} mode
-            .field("suffix", &format_args!("{:?}", &self.suffix()))
-            .field("span", &self.span())
-            .finish()
-    }
-}
-
-impl Clone for SourceFile {
-    fn clone(&self) -> Self {
-        self.clone()
-    }
-}
-
-impl Span {
-    pub(crate) fn def_site() -> Span {
-        Bridge::with(|bridge| bridge.globals.def_site)
-    }
-
-    pub(crate) fn call_site() -> Span {
-        Bridge::with(|bridge| bridge.globals.call_site)
-    }
-
-    pub(crate) fn mixed_site() -> Span {
-        Bridge::with(|bridge| bridge.globals.mixed_site)
-    }
-}
-
-impl fmt::Debug for Span {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.debug())
-    }
-}
-
-macro_rules! define_client_side {
-    ($($name:ident {
-        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
-    }),* $(,)?) => {
-        $(impl $name {
-            $(pub(crate) fn $method($($arg: $arg_ty),*) $(-> $ret_ty)* {
-                Bridge::with(|bridge| {
-                    let mut buf = bridge.cached_buffer.take();
-
-                    buf.clear();
-                    api_tags::Method::$name(api_tags::$name::$method).encode(&mut buf, &mut ());
-                    reverse_encode!(buf; $($arg),*);
-
-                    buf = bridge.dispatch.call(buf);
-
-                    let r = Result::<_, PanicMessage>::decode(&mut &buf[..], &mut ());
-
-                    bridge.cached_buffer = buf;
-
-                    r.unwrap_or_else(|e| panic::resume_unwind(e.into()))
-                })
-            })*
-        })*
-    }
-}
-with_api!(self, self, define_client_side);
-
-struct Bridge<'a> {
-    /// Reusable buffer (only `clear`-ed, never shrunk), primarily
-    /// used for making requests.
-    cached_buffer: Buffer,
-
-    /// Server-side function that the client uses to make requests.
-    dispatch: closure::Closure<'a, Buffer, Buffer>,
-
-    /// Provided globals for this macro expansion.
-    globals: ExpnGlobals<Span>,
-}
-
-enum BridgeState<'a> {
-    /// No server is currently connected to this client.
-    NotConnected,
-
-    /// A server is connected and available for requests.
-    Connected(Bridge<'a>),
-
-    /// Access to the bridge is being exclusively acquired
-    /// (e.g., during `BridgeState::with`).
-    InUse,
-}
-
-enum BridgeStateL {}
-
-impl<'a> scoped_cell::ApplyL<'a> for BridgeStateL {
-    type Out = BridgeState<'a>;
-}
-
-thread_local! {
-    static BRIDGE_STATE: scoped_cell::ScopedCell<BridgeStateL> =
-        scoped_cell::ScopedCell::new(BridgeState::NotConnected);
-}
-
-impl BridgeState<'_> {
-    /// Take exclusive control of the thread-local
-    /// `BridgeState`, and pass it to `f`, mutably.
-    /// The state will be restored after `f` exits, even
-    /// by panic, including modifications made to it by `f`.
-    ///
-    /// N.B., while `f` is running, the thread-local state
-    /// is `BridgeState::InUse`.
-    fn with<R>(f: impl FnOnce(&mut BridgeState<'_>) -> R) -> R {
-        BRIDGE_STATE.with(|state| {
-            state.replace(BridgeState::InUse, |mut state| {
-                // FIXME(#52812) pass `f` directly to `replace` when `RefMutL` is gone
-                f(&mut *state)
-            })
-        })
-    }
-}
-
-impl Bridge<'_> {
-    fn with<R>(f: impl FnOnce(&mut Bridge<'_>) -> R) -> R {
-        BridgeState::with(|state| match state {
-            BridgeState::NotConnected => {
-                panic!("procedural macro API is used outside of a procedural macro");
-            }
-            BridgeState::InUse => {
-                panic!("procedural macro API is used while it's already in use");
-            }
-            BridgeState::Connected(bridge) => f(bridge),
-        })
-    }
-}
-
-pub(crate) fn is_available() -> bool {
-    BridgeState::with(|state| match state {
-        BridgeState::Connected(_) | BridgeState::InUse => true,
-        BridgeState::NotConnected => false,
-    })
-}
-
-/// A client-side RPC entry-point, which may be using a different `proc_macro`
-/// from the one used by the server, but can be invoked compatibly.
-///
-/// Note that the (phantom) `I` ("input") and `O` ("output") type parameters
-/// decorate the `Client<I, O>` with the RPC "interface" of the entry-point, but
-/// do not themselves participate in ABI, at all, only facilitate type-checking.
-///
-/// E.g. `Client<TokenStream, TokenStream>` is the common proc macro interface,
-/// used for `#[proc_macro] fn foo(input: TokenStream) -> TokenStream`,
-/// indicating that the RPC input and output will be serialized token streams,
-/// and forcing the use of APIs that take/return `S::TokenStream`, server-side.
-#[repr(C)]
-pub struct Client<I, O> {
-    // FIXME(eddyb) use a reference to the `static COUNTERS`, instead of
-    // a wrapper `fn` pointer, once `const fn` can reference `static`s.
-    pub(super) get_handle_counters: extern "C" fn() -> &'static HandleCounters,
-
-    pub(super) run: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-
-    pub(super) _marker: PhantomData<fn(I) -> O>,
-}
-
-impl<I, O> Copy for Client<I, O> {}
-impl<I, O> Clone for Client<I, O> {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-
-fn maybe_install_panic_hook(force_show_panics: bool) {
-    // Hide the default panic output within `proc_macro` expansions.
-    // NB. the server can't do this because it may use a different libstd.
-    static HIDE_PANICS_DURING_EXPANSION: Once = Once::new();
-    HIDE_PANICS_DURING_EXPANSION.call_once(|| {
-        let prev = panic::take_hook();
-        panic::set_hook(Box::new(move |info| {
-            let show = BridgeState::with(|state| match state {
-                BridgeState::NotConnected => true,
-                BridgeState::Connected(_) | BridgeState::InUse => force_show_panics,
-            });
-            if show {
-                prev(info)
-            }
-        }));
-    });
-}
-
-/// Client-side helper for handling client panics, entering the bridge,
-/// deserializing input and serializing output.
-// FIXME(eddyb) maybe replace `Bridge::enter` with this?
-fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
-    config: BridgeConfig<'_>,
-    f: impl FnOnce(A) -> R,
-) -> Buffer {
-    let BridgeConfig { input: mut buf, dispatch, force_show_panics, .. } = config;
-
-    panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        maybe_install_panic_hook(force_show_panics);
-
-        let reader = &mut &buf[..];
-        let (globals, input) = <(ExpnGlobals<Span>, A)>::decode(reader, &mut ());
-
-        // Put the buffer we used for input back in the `Bridge` for requests.
-        let new_state =
-            BridgeState::Connected(Bridge { cached_buffer: buf.take(), dispatch, globals });
-
-        BRIDGE_STATE.with(|state| {
-            state.set(new_state, || {
-                let output = f(input);
-
-                // Take the `cached_buffer` back out, for the output value.
-                buf = Bridge::with(|bridge| bridge.cached_buffer.take());
-
-                // HACK(eddyb) Separate encoding a success value (`Ok(output)`)
-                // from encoding a panic (`Err(e: PanicMessage)`) to avoid
-                // having handles outside the `bridge.enter(|| ...)` scope, and
-                // to catch panics that could happen while encoding the success.
-                //
-                // Note that panics should be impossible beyond this point, but
-                // this is defensively trying to avoid any accidental panicking
-                // reaching the `extern "C"` (which should `abort` but might not
-                // at the moment, so this is also potentially preventing UB).
-                buf.clear();
-                Ok::<_, ()>(output).encode(&mut buf, &mut ());
-            })
-        })
-    }))
-    .map_err(PanicMessage::from)
-    .unwrap_or_else(|e| {
-        buf.clear();
-        Err::<(), _>(e).encode(&mut buf, &mut ());
-    });
-    buf
-}
-
-impl Client<super::super::TokenStream, super::super::TokenStream> {
-    pub const fn expand1(
-        f: impl Fn(super::super::TokenStream) -> super::super::TokenStream + Copy,
-    ) -> Self {
-        Client {
-            get_handle_counters: HandleCounters::get,
-            run: super::selfless_reify::reify_to_extern_c_fn_hrt_bridge(move |bridge| {
-                run_client(bridge, |input| f(super::super::TokenStream(input)).0)
-            }),
-            _marker: PhantomData,
-        }
-    }
-}
-
-impl Client<(super::super::TokenStream, super::super::TokenStream), super::super::TokenStream> {
-    pub const fn expand2(
-        f: impl Fn(super::super::TokenStream, super::super::TokenStream) -> super::super::TokenStream
-            + Copy,
-    ) -> Self {
-        Client {
-            get_handle_counters: HandleCounters::get,
-            run: super::selfless_reify::reify_to_extern_c_fn_hrt_bridge(move |bridge| {
-                run_client(bridge, |(input, input2)| {
-                    f(super::super::TokenStream(input), super::super::TokenStream(input2)).0
-                })
-            }),
-            _marker: PhantomData,
-        }
-    }
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub enum ProcMacro {
-    CustomDerive {
-        trait_name: &'static str,
-        attributes: &'static [&'static str],
-        client: Client<super::super::TokenStream, super::super::TokenStream>,
-    },
-
-    Attr {
-        name: &'static str,
-        client: Client<
-            (super::super::TokenStream, super::super::TokenStream),
-            super::super::TokenStream,
-        >,
-    },
-
-    Bang {
-        name: &'static str,
-        client: Client<super::super::TokenStream, super::super::TokenStream>,
-    },
-}
-
-impl ProcMacro {
-    pub fn name(&self) -> &'static str {
-        match self {
-            ProcMacro::CustomDerive { trait_name, .. } => trait_name,
-            ProcMacro::Attr { name, .. } => name,
-            ProcMacro::Bang { name, .. } => name,
-        }
-    }
-
-    pub const fn custom_derive(
-        trait_name: &'static str,
-        attributes: &'static [&'static str],
-        expand: impl Fn(super::super::TokenStream) -> super::super::TokenStream + Copy,
-    ) -> Self {
-        ProcMacro::CustomDerive { trait_name, attributes, client: Client::expand1(expand) }
-    }
-
-    pub const fn attr(
-        name: &'static str,
-        expand: impl Fn(super::super::TokenStream, super::super::TokenStream) -> super::super::TokenStream
-            + Copy,
-    ) -> Self {
-        ProcMacro::Attr { name, client: Client::expand2(expand) }
-    }
-
-    pub const fn bang(
-        name: &'static str,
-        expand: impl Fn(super::super::TokenStream) -> super::super::TokenStream + Copy,
-    ) -> Self {
-        ProcMacro::Bang { name, client: Client::expand1(expand) }
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs
deleted file mode 100644
index d371ae3cea098..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/closure.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-//! Closure type (equivalent to `&mut dyn FnMut(A) -> R`) that's `repr(C)`.
-
-use std::marker::PhantomData;
-
-#[repr(C)]
-pub struct Closure<'a, A, R> {
-    call: unsafe extern "C" fn(*mut Env, A) -> R,
-    env: *mut Env,
-    // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing
-    // this, but that requires unstable features. rust-analyzer uses this code
-    // and avoids unstable features.
-    //
-    // The `'a` lifetime parameter represents the lifetime of `Env`.
-    _marker: PhantomData<*mut &'a mut ()>,
-}
-
-struct Env;
-
-impl<'a, A, R, F: FnMut(A) -> R> From<&'a mut F> for Closure<'a, A, R> {
-    fn from(f: &'a mut F) -> Self {
-        unsafe extern "C" fn call<A, R, F: FnMut(A) -> R>(env: *mut Env, arg: A) -> R {
-            (*(env as *mut _ as *mut F))(arg)
-        }
-        Closure { call: call::<A, R, F>, env: f as *mut _ as *mut Env, _marker: PhantomData }
-    }
-}
-
-impl<'a, A, R> Closure<'a, A, R> {
-    pub fn call(&mut self, arg: A) -> R {
-        unsafe { (self.call)(self.env, arg) }
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs
deleted file mode 100644
index c219a9465d39f..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/handle.rs
+++ /dev/null
@@ -1,89 +0,0 @@
-//! Server-side handles and storage for per-handle data.
-
-use std::collections::{BTreeMap, HashMap};
-use std::hash::{BuildHasher, Hash};
-use std::num::NonZeroU32;
-use std::ops::{Index, IndexMut};
-use std::sync::atomic::{AtomicUsize, Ordering};
-
-pub(super) type Handle = NonZeroU32;
-
-/// A store that associates values of type `T` with numeric handles. A value can
-/// be looked up using its handle.
-pub(super) struct OwnedStore<T: 'static> {
-    counter: &'static AtomicUsize,
-    data: BTreeMap<Handle, T>,
-}
-
-impl<T> OwnedStore<T> {
-    pub(super) fn new(counter: &'static AtomicUsize) -> Self {
-        // Ensure the handle counter isn't 0, which would panic later,
-        // when `NonZeroU32::new` (aka `Handle::new`) is called in `alloc`.
-        assert_ne!(counter.load(Ordering::SeqCst), 0);
-
-        OwnedStore { counter, data: BTreeMap::new() }
-    }
-}
-
-impl<T> OwnedStore<T> {
-    pub(super) fn alloc(&mut self, x: T) -> Handle {
-        let counter = self.counter.fetch_add(1, Ordering::SeqCst);
-        let handle = Handle::new(counter as u32).expect("`proc_macro` handle counter overflowed");
-        assert!(self.data.insert(handle, x).is_none());
-        handle
-    }
-
-    pub(super) fn take(&mut self, h: Handle) -> T {
-        self.data.remove(&h).expect("use-after-free in `proc_macro` handle")
-    }
-}
-
-impl<T> Index<Handle> for OwnedStore<T> {
-    type Output = T;
-    fn index(&self, h: Handle) -> &T {
-        self.data.get(&h).expect("use-after-free in `proc_macro` handle")
-    }
-}
-
-impl<T> IndexMut<Handle> for OwnedStore<T> {
-    fn index_mut(&mut self, h: Handle) -> &mut T {
-        self.data.get_mut(&h).expect("use-after-free in `proc_macro` handle")
-    }
-}
-
-// HACK(eddyb) deterministic `std::collections::hash_map::RandomState` replacement
-// that doesn't require adding any dependencies to `proc_macro` (like `rustc-hash`).
-#[derive(Clone)]
-struct NonRandomState;
-
-impl BuildHasher for NonRandomState {
-    type Hasher = std::collections::hash_map::DefaultHasher;
-    #[inline]
-    fn build_hasher(&self) -> Self::Hasher {
-        Self::Hasher::new()
-    }
-}
-
-/// Like `OwnedStore`, but avoids storing any value more than once.
-pub(super) struct InternedStore<T: 'static> {
-    owned: OwnedStore<T>,
-    interner: HashMap<T, Handle, NonRandomState>,
-}
-
-impl<T: Copy + Eq + Hash> InternedStore<T> {
-    pub(super) fn new(counter: &'static AtomicUsize) -> Self {
-        InternedStore {
-            owned: OwnedStore::new(counter),
-            interner: HashMap::with_hasher(NonRandomState),
-        }
-    }
-
-    pub(super) fn alloc(&mut self, x: T) -> Handle {
-        let owned = &mut self.owned;
-        *self.interner.entry(x).or_insert_with(|| owned.alloc(x))
-    }
-
-    pub(super) fn copy(&mut self, h: Handle) -> T {
-        self.owned[h]
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs
deleted file mode 100644
index ffd440793231c..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/mod.rs
+++ /dev/null
@@ -1,493 +0,0 @@
-//! Internal interface for communicating between a `proc_macro` client
-//! (a proc macro crate) and a `proc_macro` server (a compiler front-end).
-//!
-//! Serialization (with C ABI buffers) and unique integer handles are employed
-//! to allow safely interfacing between two copies of `proc_macro` built
-//! (from the same source) by different compilers with potentially mismatching
-//! Rust ABIs (e.g., stage0/bin/rustc vs stage1/bin/rustc during bootstrap).
-
-#![deny(unsafe_code)]
-
-pub use super::{Delimiter, Level, LineColumn, Spacing};
-use std::fmt;
-use std::hash::Hash;
-use std::marker;
-use std::mem;
-use std::ops::Bound;
-use std::panic;
-use std::sync::atomic::AtomicUsize;
-use std::sync::Once;
-use std::thread;
-
-/// Higher-order macro describing the server RPC API, allowing automatic
-/// generation of type-safe Rust APIs, both client-side and server-side.
-///
-/// `with_api!(MySelf, my_self, my_macro)` expands to:
-/// ```rust,ignore (pseudo-code)
-/// my_macro! {
-///     // ...
-///     Literal {
-///         // ...
-///         fn character(ch: char) -> MySelf::Literal;
-///         // ...
-///         fn span(my_self: &MySelf::Literal) -> MySelf::Span;
-///         fn set_span(my_self: &mut MySelf::Literal, span: MySelf::Span);
-///     },
-///     // ...
-/// }
-/// ```
-///
-/// The first two arguments serve to customize the arguments names
-/// and argument/return types, to enable several different usecases:
-///
-/// If `my_self` is just `self`, then each `fn` signature can be used
-/// as-is for a method. If it's anything else (`self_` in practice),
-/// then the signatures don't have a special `self` argument, and
-/// can, therefore, have a different one introduced.
-///
-/// If `MySelf` is just `Self`, then the types are only valid inside
-/// a trait or a trait impl, where the trait has associated types
-/// for each of the API types. If non-associated types are desired,
-/// a module name (`self` in practice) can be used instead of `Self`.
-macro_rules! with_api {
-    ($S:ident, $self:ident, $m:ident) => {
-        $m! {
-            FreeFunctions {
-                fn drop($self: $S::FreeFunctions);
-                fn track_env_var(var: &str, value: Option<&str>);
-                fn track_path(path: &str);
-            },
-            TokenStream {
-                fn drop($self: $S::TokenStream);
-                fn clone($self: &$S::TokenStream) -> $S::TokenStream;
-                fn is_empty($self: &$S::TokenStream) -> bool;
-                fn expand_expr($self: &$S::TokenStream) -> Result<$S::TokenStream, ()>;
-                fn from_str(src: &str) -> $S::TokenStream;
-                fn to_string($self: &$S::TokenStream) -> String;
-                fn from_token_tree(
-                    tree: TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>,
-                ) -> $S::TokenStream;
-                fn concat_trees(
-                    base: Option<$S::TokenStream>,
-                    trees: Vec<TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>>,
-                ) -> $S::TokenStream;
-                fn concat_streams(
-                    base: Option<$S::TokenStream>,
-                    streams: Vec<$S::TokenStream>,
-                ) -> $S::TokenStream;
-                fn into_trees(
-                    $self: $S::TokenStream
-                ) -> Vec<TokenTree<$S::TokenStream, $S::Span, $S::Ident, $S::Literal>>;
-            },
-            Ident {
-                fn new(string: &str, span: $S::Span, is_raw: bool) -> $S::Ident;
-                fn span($self: $S::Ident) -> $S::Span;
-                fn with_span($self: $S::Ident, span: $S::Span) -> $S::Ident;
-            },
-            Literal {
-                fn drop($self: $S::Literal);
-                fn clone($self: &$S::Literal) -> $S::Literal;
-                fn from_str(s: &str) -> Result<$S::Literal, ()>;
-                fn to_string($self: &$S::Literal) -> String;
-                fn debug_kind($self: &$S::Literal) -> String;
-                fn symbol($self: &$S::Literal) -> String;
-                fn suffix($self: &$S::Literal) -> Option<String>;
-                fn integer(n: &str) -> $S::Literal;
-                fn typed_integer(n: &str, kind: &str) -> $S::Literal;
-                fn float(n: &str) -> $S::Literal;
-                fn f32(n: &str) -> $S::Literal;
-                fn f64(n: &str) -> $S::Literal;
-                fn string(string: &str) -> $S::Literal;
-                fn character(ch: char) -> $S::Literal;
-                fn byte_string(bytes: &[u8]) -> $S::Literal;
-                fn span($self: &$S::Literal) -> $S::Span;
-                fn set_span($self: &mut $S::Literal, span: $S::Span);
-                fn subspan(
-                    $self: &$S::Literal,
-                    start: Bound<usize>,
-                    end: Bound<usize>,
-                ) -> Option<$S::Span>;
-            },
-            SourceFile {
-                fn drop($self: $S::SourceFile);
-                fn clone($self: &$S::SourceFile) -> $S::SourceFile;
-                fn eq($self: &$S::SourceFile, other: &$S::SourceFile) -> bool;
-                fn path($self: &$S::SourceFile) -> String;
-                fn is_real($self: &$S::SourceFile) -> bool;
-            },
-            MultiSpan {
-                fn drop($self: $S::MultiSpan);
-                fn new() -> $S::MultiSpan;
-                fn push($self: &mut $S::MultiSpan, span: $S::Span);
-            },
-            Diagnostic {
-                fn drop($self: $S::Diagnostic);
-                fn new(level: Level, msg: &str, span: $S::MultiSpan) -> $S::Diagnostic;
-                fn sub(
-                    $self: &mut $S::Diagnostic,
-                    level: Level,
-                    msg: &str,
-                    span: $S::MultiSpan,
-                );
-                fn emit($self: $S::Diagnostic);
-            },
-            Span {
-                fn debug($self: $S::Span) -> String;
-                fn source_file($self: $S::Span) -> $S::SourceFile;
-                fn parent($self: $S::Span) -> Option<$S::Span>;
-                fn source($self: $S::Span) -> $S::Span;
-                fn start($self: $S::Span) -> LineColumn;
-                fn end($self: $S::Span) -> LineColumn;
-                fn before($self: $S::Span) -> $S::Span;
-                fn after($self: $S::Span) -> $S::Span;
-                fn join($self: $S::Span, other: $S::Span) -> Option<$S::Span>;
-                fn resolved_at($self: $S::Span, at: $S::Span) -> $S::Span;
-                fn source_text($self: $S::Span) -> Option<String>;
-                fn save_span($self: $S::Span) -> usize;
-                fn recover_proc_macro_span(id: usize) -> $S::Span;
-            },
-        }
-    };
-}
-
-// FIXME(eddyb) this calls `encode` for each argument, but in reverse,
-// to match the ordering in `reverse_decode`.
-macro_rules! reverse_encode {
-    ($writer:ident;) => {};
-    ($writer:ident; $first:ident $(, $rest:ident)*) => {
-        reverse_encode!($writer; $($rest),*);
-        $first.encode(&mut $writer, &mut ());
-    }
-}
-
-// FIXME(eddyb) this calls `decode` for each argument, but in reverse,
-// to avoid borrow conflicts from borrows started by `&mut` arguments.
-macro_rules! reverse_decode {
-    ($reader:ident, $s:ident;) => {};
-    ($reader:ident, $s:ident; $first:ident: $first_ty:ty $(, $rest:ident: $rest_ty:ty)*) => {
-        reverse_decode!($reader, $s; $($rest: $rest_ty),*);
-        let $first = <$first_ty>::decode(&mut $reader, $s);
-    }
-}
-
-#[allow(unsafe_code)]
-mod buffer;
-#[forbid(unsafe_code)]
-pub mod client;
-#[allow(unsafe_code)]
-mod closure;
-#[forbid(unsafe_code)]
-mod handle;
-#[macro_use]
-#[forbid(unsafe_code)]
-mod rpc;
-#[allow(unsafe_code)]
-mod scoped_cell;
-#[allow(unsafe_code)]
-mod selfless_reify;
-#[forbid(unsafe_code)]
-pub mod server;
-
-use buffer::Buffer;
-pub use rpc::PanicMessage;
-use rpc::{Decode, DecodeMut, Encode, Reader, Writer};
-
-/// Configuration for establishing an active connection between a server and a
-/// client.  The server creates the bridge config (`run_server` in `server.rs`),
-/// then passes it to the client through the function pointer in the `run` field
-/// of `client::Client`. The client constructs a local `Bridge` from the config
-/// in TLS during its execution (`Bridge::{enter, with}` in `client.rs`).
-#[repr(C)]
-pub struct BridgeConfig<'a> {
-    /// Buffer used to pass initial input to the client.
-    input: Buffer,
-
-    /// Server-side function that the client uses to make requests.
-    dispatch: closure::Closure<'a, Buffer, Buffer>,
-
-    /// If 'true', always invoke the default panic hook
-    force_show_panics: bool,
-
-    // Prevent Send and Sync impls. `!Send`/`!Sync` is the usual way of doing
-    // this, but that requires unstable features. rust-analyzer uses this code
-    // and avoids unstable features.
-    _marker: marker::PhantomData<*mut ()>,
-}
-
-#[forbid(unsafe_code)]
-#[allow(non_camel_case_types)]
-mod api_tags {
-    use super::rpc::{DecodeMut, Encode, Reader, Writer};
-
-    macro_rules! declare_tags {
-        ($($name:ident {
-            $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)*;)*
-        }),* $(,)?) => {
-            $(
-                pub(super) enum $name {
-                    $($method),*
-                }
-                rpc_encode_decode!(enum $name { $($method),* });
-            )*
-
-            pub(super) enum Method {
-                $($name($name)),*
-            }
-            rpc_encode_decode!(enum Method { $($name(m)),* });
-        }
-    }
-    with_api!(self, self, declare_tags);
-}
-
-/// Helper to wrap associated types to allow trait impl dispatch.
-/// That is, normally a pair of impls for `T::Foo` and `T::Bar`
-/// can overlap, but if the impls are, instead, on types like
-/// `Marked<T::Foo, Foo>` and `Marked<T::Bar, Bar>`, they can't.
-trait Mark {
-    type Unmarked;
-    fn mark(unmarked: Self::Unmarked) -> Self;
-}
-
-/// Unwrap types wrapped by `Mark::mark` (see `Mark` for details).
-trait Unmark {
-    type Unmarked;
-    fn unmark(self) -> Self::Unmarked;
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash)]
-struct Marked<T, M> {
-    value: T,
-    _marker: marker::PhantomData<M>,
-}
-
-impl<T, M> Mark for Marked<T, M> {
-    type Unmarked = T;
-    fn mark(unmarked: Self::Unmarked) -> Self {
-        Marked { value: unmarked, _marker: marker::PhantomData }
-    }
-}
-impl<T, M> Unmark for Marked<T, M> {
-    type Unmarked = T;
-    fn unmark(self) -> Self::Unmarked {
-        self.value
-    }
-}
-impl<'a, T, M> Unmark for &'a Marked<T, M> {
-    type Unmarked = &'a T;
-    fn unmark(self) -> Self::Unmarked {
-        &self.value
-    }
-}
-impl<'a, T, M> Unmark for &'a mut Marked<T, M> {
-    type Unmarked = &'a mut T;
-    fn unmark(self) -> Self::Unmarked {
-        &mut self.value
-    }
-}
-
-impl<T: Mark> Mark for Vec<T> {
-    type Unmarked = Vec<T::Unmarked>;
-    fn mark(unmarked: Self::Unmarked) -> Self {
-        // Should be a no-op due to std's in-place collect optimizations.
-        unmarked.into_iter().map(T::mark).collect()
-    }
-}
-impl<T: Unmark> Unmark for Vec<T> {
-    type Unmarked = Vec<T::Unmarked>;
-    fn unmark(self) -> Self::Unmarked {
-        // Should be a no-op due to std's in-place collect optimizations.
-        self.into_iter().map(T::unmark).collect()
-    }
-}
-
-macro_rules! mark_noop {
-    ($($ty:ty),* $(,)?) => {
-        $(
-            impl Mark for $ty {
-                type Unmarked = Self;
-                fn mark(unmarked: Self::Unmarked) -> Self {
-                    unmarked
-                }
-            }
-            impl Unmark for $ty {
-                type Unmarked = Self;
-                fn unmark(self) -> Self::Unmarked {
-                    self
-                }
-            }
-        )*
-    }
-}
-mark_noop! {
-    (),
-    bool,
-    char,
-    &'_ [u8],
-    &'_ str,
-    String,
-    u8,
-    usize,
-    Delimiter,
-    Level,
-    LineColumn,
-    Spacing,
-}
-
-rpc_encode_decode!(
-    enum Delimiter {
-        Parenthesis,
-        Brace,
-        Bracket,
-        None,
-    }
-);
-rpc_encode_decode!(
-    enum Level {
-        Error,
-        Warning,
-        Note,
-        Help,
-    }
-);
-rpc_encode_decode!(struct LineColumn { line, column });
-rpc_encode_decode!(
-    enum Spacing {
-        Alone,
-        Joint,
-    }
-);
-
-macro_rules! mark_compound {
-    (struct $name:ident <$($T:ident),+> { $($field:ident),* $(,)? }) => {
-        impl<$($T: Mark),+> Mark for $name <$($T),+> {
-            type Unmarked = $name <$($T::Unmarked),+>;
-            fn mark(unmarked: Self::Unmarked) -> Self {
-                $name {
-                    $($field: Mark::mark(unmarked.$field)),*
-                }
-            }
-        }
-        impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
-            type Unmarked = $name <$($T::Unmarked),+>;
-            fn unmark(self) -> Self::Unmarked {
-                $name {
-                    $($field: Unmark::unmark(self.$field)),*
-                }
-            }
-        }
-    };
-    (enum $name:ident <$($T:ident),+> { $($variant:ident $(($field:ident))?),* $(,)? }) => {
-        impl<$($T: Mark),+> Mark for $name <$($T),+> {
-            type Unmarked = $name <$($T::Unmarked),+>;
-            fn mark(unmarked: Self::Unmarked) -> Self {
-                match unmarked {
-                    $($name::$variant $(($field))? => {
-                        $name::$variant $((Mark::mark($field)))?
-                    })*
-                }
-            }
-        }
-        impl<$($T: Unmark),+> Unmark for $name <$($T),+> {
-            type Unmarked = $name <$($T::Unmarked),+>;
-            fn unmark(self) -> Self::Unmarked {
-                match self {
-                    $($name::$variant $(($field))? => {
-                        $name::$variant $((Unmark::unmark($field)))?
-                    })*
-                }
-            }
-        }
-    }
-}
-
-macro_rules! compound_traits {
-    ($($t:tt)*) => {
-        rpc_encode_decode!($($t)*);
-        mark_compound!($($t)*);
-    };
-}
-
-compound_traits!(
-    enum Bound<T> {
-        Included(x),
-        Excluded(x),
-        Unbounded,
-    }
-);
-
-compound_traits!(
-    enum Option<T> {
-        Some(t),
-        None,
-    }
-);
-
-compound_traits!(
-    enum Result<T, E> {
-        Ok(t),
-        Err(e),
-    }
-);
-
-#[derive(Copy, Clone)]
-pub struct DelimSpan<Span> {
-    pub open: Span,
-    pub close: Span,
-    pub entire: Span,
-}
-
-impl<Span: Copy> DelimSpan<Span> {
-    pub fn from_single(span: Span) -> Self {
-        DelimSpan { open: span, close: span, entire: span }
-    }
-}
-
-compound_traits!(struct DelimSpan<Span> { open, close, entire });
-
-#[derive(Clone)]
-pub struct Group<TokenStream, Span> {
-    pub delimiter: Delimiter,
-    pub stream: Option<TokenStream>,
-    pub span: DelimSpan<Span>,
-}
-
-compound_traits!(struct Group<TokenStream, Span> { delimiter, stream, span });
-
-#[derive(Clone)]
-pub struct Punct<Span> {
-    pub ch: u8,
-    pub joint: bool,
-    pub span: Span,
-}
-
-compound_traits!(struct Punct<Span> { ch, joint, span });
-
-#[derive(Clone)]
-pub enum TokenTree<TokenStream, Span, Ident, Literal> {
-    Group(Group<TokenStream, Span>),
-    Punct(Punct<Span>),
-    Ident(Ident),
-    Literal(Literal),
-}
-
-compound_traits!(
-    enum TokenTree<TokenStream, Span, Ident, Literal> {
-        Group(tt),
-        Punct(tt),
-        Ident(tt),
-        Literal(tt),
-    }
-);
-
-/// Globals provided alongside the initial inputs for a macro expansion.
-/// Provides values such as spans which are used frequently to avoid RPC.
-#[derive(Clone)]
-pub struct ExpnGlobals<Span> {
-    pub def_site: Span,
-    pub call_site: Span,
-    pub mixed_site: Span,
-}
-
-compound_traits!(
-    struct ExpnGlobals<Span> { def_site, call_site, mixed_site }
-);
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs
deleted file mode 100644
index e9d7a46c06f6d..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/rpc.rs
+++ /dev/null
@@ -1,304 +0,0 @@
-//! Serialization for client-server communication.
-
-use std::any::Any;
-use std::char;
-use std::io::Write;
-use std::num::NonZeroU32;
-use std::str;
-
-pub(super) type Writer = super::buffer::Buffer;
-
-pub(super) trait Encode<S>: Sized {
-    fn encode(self, w: &mut Writer, s: &mut S);
-}
-
-pub(super) type Reader<'a> = &'a [u8];
-
-pub(super) trait Decode<'a, 's, S>: Sized {
-    fn decode(r: &mut Reader<'a>, s: &'s S) -> Self;
-}
-
-pub(super) trait DecodeMut<'a, 's, S>: Sized {
-    fn decode(r: &mut Reader<'a>, s: &'s mut S) -> Self;
-}
-
-macro_rules! rpc_encode_decode {
-    (le $ty:ty) => {
-        impl<S> Encode<S> for $ty {
-            fn encode(self, w: &mut Writer, _: &mut S) {
-                w.extend_from_array(&self.to_le_bytes());
-            }
-        }
-
-        impl<S> DecodeMut<'_, '_, S> for $ty {
-            fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
-                const N: usize = ::std::mem::size_of::<$ty>();
-
-                let mut bytes = [0; N];
-                bytes.copy_from_slice(&r[..N]);
-                *r = &r[N..];
-
-                Self::from_le_bytes(bytes)
-            }
-        }
-    };
-    (struct $name:ident $(<$($T:ident),+>)? { $($field:ident),* $(,)? }) => {
-        impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
-            fn encode(self, w: &mut Writer, s: &mut S) {
-                $(self.$field.encode(w, s);)*
-            }
-        }
-
-        impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
-            for $name $(<$($T),+>)?
-        {
-            fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-                $name {
-                    $($field: DecodeMut::decode(r, s)),*
-                }
-            }
-        }
-    };
-    (enum $name:ident $(<$($T:ident),+>)? { $($variant:ident $(($field:ident))*),* $(,)? }) => {
-        impl<S, $($($T: Encode<S>),+)?> Encode<S> for $name $(<$($T),+>)? {
-            fn encode(self, w: &mut Writer, s: &mut S) {
-                // HACK(eddyb): `Tag` enum duplicated between the
-                // two impls as there's no other place to stash it.
-                #[allow(non_upper_case_globals)]
-                mod tag {
-                    #[repr(u8)] enum Tag { $($variant),* }
-
-                    $(pub const $variant: u8 = Tag::$variant as u8;)*
-                }
-
-                match self {
-                    $($name::$variant $(($field))* => {
-                        tag::$variant.encode(w, s);
-                        $($field.encode(w, s);)*
-                    })*
-                }
-            }
-        }
-
-        impl<'a, S, $($($T: for<'s> DecodeMut<'a, 's, S>),+)?> DecodeMut<'a, '_, S>
-            for $name $(<$($T),+>)?
-        {
-            fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-                // HACK(eddyb): `Tag` enum duplicated between the
-                // two impls as there's no other place to stash it.
-                #[allow(non_upper_case_globals)]
-                mod tag {
-                    #[repr(u8)] enum Tag { $($variant),* }
-
-                    $(pub const $variant: u8 = Tag::$variant as u8;)*
-                }
-
-                match u8::decode(r, s) {
-                    $(tag::$variant => {
-                        $(let $field = DecodeMut::decode(r, s);)*
-                        $name::$variant $(($field))*
-                    })*
-                    _ => unreachable!(),
-                }
-            }
-        }
-    }
-}
-
-impl<S> Encode<S> for () {
-    fn encode(self, _: &mut Writer, _: &mut S) {}
-}
-
-impl<S> DecodeMut<'_, '_, S> for () {
-    fn decode(_: &mut Reader<'_>, _: &mut S) -> Self {}
-}
-
-impl<S> Encode<S> for u8 {
-    fn encode(self, w: &mut Writer, _: &mut S) {
-        w.push(self);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for u8 {
-    fn decode(r: &mut Reader<'_>, _: &mut S) -> Self {
-        let x = r[0];
-        *r = &r[1..];
-        x
-    }
-}
-
-rpc_encode_decode!(le u32);
-rpc_encode_decode!(le usize);
-
-impl<S> Encode<S> for bool {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        (self as u8).encode(w, s);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for bool {
-    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-        match u8::decode(r, s) {
-            0 => false,
-            1 => true,
-            _ => unreachable!(),
-        }
-    }
-}
-
-impl<S> Encode<S> for char {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        (self as u32).encode(w, s);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for char {
-    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-        char::from_u32(u32::decode(r, s)).unwrap()
-    }
-}
-
-impl<S> Encode<S> for NonZeroU32 {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.get().encode(w, s);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for NonZeroU32 {
-    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-        Self::new(u32::decode(r, s)).unwrap()
-    }
-}
-
-impl<S, A: Encode<S>, B: Encode<S>> Encode<S> for (A, B) {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.0.encode(w, s);
-        self.1.encode(w, s);
-    }
-}
-
-impl<'a, S, A: for<'s> DecodeMut<'a, 's, S>, B: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S>
-    for (A, B)
-{
-    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-        (DecodeMut::decode(r, s), DecodeMut::decode(r, s))
-    }
-}
-
-impl<S> Encode<S> for &[u8] {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.len().encode(w, s);
-        w.write_all(self).unwrap();
-    }
-}
-
-impl<'a, S> DecodeMut<'a, '_, S> for &'a [u8] {
-    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-        let len = usize::decode(r, s);
-        let xs = &r[..len];
-        *r = &r[len..];
-        xs
-    }
-}
-
-impl<S> Encode<S> for &str {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.as_bytes().encode(w, s);
-    }
-}
-
-impl<'a, S> DecodeMut<'a, '_, S> for &'a str {
-    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-        str::from_utf8(<&[u8]>::decode(r, s)).unwrap()
-    }
-}
-
-impl<S> Encode<S> for String {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self[..].encode(w, s);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for String {
-    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-        <&str>::decode(r, s).to_string()
-    }
-}
-
-impl<S, T: Encode<S>> Encode<S> for Vec<T> {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.len().encode(w, s);
-        for x in self {
-            x.encode(w, s);
-        }
-    }
-}
-
-impl<'a, S, T: for<'s> DecodeMut<'a, 's, S>> DecodeMut<'a, '_, S> for Vec<T> {
-    fn decode(r: &mut Reader<'a>, s: &mut S) -> Self {
-        let len = usize::decode(r, s);
-        let mut vec = Vec::with_capacity(len);
-        for _ in 0..len {
-            vec.push(T::decode(r, s));
-        }
-        vec
-    }
-}
-
-/// Simplified version of panic payloads, ignoring
-/// types other than `&'static str` and `String`.
-pub enum PanicMessage {
-    StaticStr(&'static str),
-    String(String),
-    Unknown,
-}
-
-impl From<Box<dyn Any + Send>> for PanicMessage {
-    fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
-        if let Some(s) = payload.downcast_ref::<&'static str>() {
-            return PanicMessage::StaticStr(s);
-        }
-        if let Ok(s) = payload.downcast::<String>() {
-            return PanicMessage::String(*s);
-        }
-        PanicMessage::Unknown
-    }
-}
-
-impl Into<Box<dyn Any + Send>> for PanicMessage {
-    fn into(self) -> Box<dyn Any + Send> {
-        match self {
-            PanicMessage::StaticStr(s) => Box::new(s),
-            PanicMessage::String(s) => Box::new(s),
-            PanicMessage::Unknown => {
-                struct UnknownPanicMessage;
-                Box::new(UnknownPanicMessage)
-            }
-        }
-    }
-}
-
-impl PanicMessage {
-    pub fn as_str(&self) -> Option<&str> {
-        match self {
-            PanicMessage::StaticStr(s) => Some(s),
-            PanicMessage::String(s) => Some(s),
-            PanicMessage::Unknown => None,
-        }
-    }
-}
-
-impl<S> Encode<S> for PanicMessage {
-    fn encode(self, w: &mut Writer, s: &mut S) {
-        self.as_str().encode(w, s);
-    }
-}
-
-impl<S> DecodeMut<'_, '_, S> for PanicMessage {
-    fn decode(r: &mut Reader<'_>, s: &mut S) -> Self {
-        match Option::<String>::decode(r, s) {
-            Some(s) => PanicMessage::String(s),
-            None => PanicMessage::Unknown,
-        }
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs
deleted file mode 100644
index 2cde1f65adf9c..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/scoped_cell.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-//! `Cell` variant for (scoped) existential lifetimes.
-
-use std::cell::Cell;
-use std::mem;
-use std::ops::{Deref, DerefMut};
-
-/// Type lambda application, with a lifetime.
-#[allow(unused_lifetimes)]
-pub trait ApplyL<'a> {
-    type Out;
-}
-
-/// Type lambda taking a lifetime, i.e., `Lifetime -> Type`.
-pub trait LambdaL: for<'a> ApplyL<'a> {}
-
-impl<T: for<'a> ApplyL<'a>> LambdaL for T {}
-
-// HACK(eddyb) work around projection limitations with a newtype
-// FIXME(#52812) replace with `&'a mut <T as ApplyL<'b>>::Out`
-pub struct RefMutL<'a, 'b, T: LambdaL>(&'a mut <T as ApplyL<'b>>::Out);
-
-impl<'a, 'b, T: LambdaL> Deref for RefMutL<'a, 'b, T> {
-    type Target = <T as ApplyL<'b>>::Out;
-    fn deref(&self) -> &Self::Target {
-        self.0
-    }
-}
-
-impl<'a, 'b, T: LambdaL> DerefMut for RefMutL<'a, 'b, T> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        self.0
-    }
-}
-
-pub struct ScopedCell<T: LambdaL>(Cell<<T as ApplyL<'static>>::Out>);
-
-impl<T: LambdaL> ScopedCell<T> {
-    pub const fn new(value: <T as ApplyL<'static>>::Out) -> Self {
-        ScopedCell(Cell::new(value))
-    }
-
-    /// Sets the value in `self` to `replacement` while
-    /// running `f`, which gets the old value, mutably.
-    /// The old value will be restored after `f` exits, even
-    /// by panic, including modifications made to it by `f`.
-    pub fn replace<'a, R>(
-        &self,
-        replacement: <T as ApplyL<'a>>::Out,
-        f: impl for<'b, 'c> FnOnce(RefMutL<'b, 'c, T>) -> R,
-    ) -> R {
-        /// Wrapper that ensures that the cell always gets filled
-        /// (with the original state, optionally changed by `f`),
-        /// even if `f` had panicked.
-        struct PutBackOnDrop<'a, T: LambdaL> {
-            cell: &'a ScopedCell<T>,
-            value: Option<<T as ApplyL<'static>>::Out>,
-        }
-
-        impl<'a, T: LambdaL> Drop for PutBackOnDrop<'a, T> {
-            fn drop(&mut self) {
-                self.cell.0.set(self.value.take().unwrap());
-            }
-        }
-
-        let mut put_back_on_drop = PutBackOnDrop {
-            cell: self,
-            value: Some(self.0.replace(unsafe {
-                let erased = mem::transmute_copy(&replacement);
-                mem::forget(replacement);
-                erased
-            })),
-        };
-
-        f(RefMutL(put_back_on_drop.value.as_mut().unwrap()))
-    }
-
-    /// Sets the value in `self` to `value` while running `f`.
-    pub fn set<R>(&self, value: <T as ApplyL<'_>>::Out, f: impl FnOnce() -> R) -> R {
-        self.replace(value, |_| f())
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs
deleted file mode 100644
index 907ad256e4b43..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/selfless_reify.rs
+++ /dev/null
@@ -1,84 +0,0 @@
-//! Abstraction for creating `fn` pointers from any callable that *effectively*
-//! has the equivalent of implementing `Default`, even if the compiler neither
-//! provides `Default` nor allows reifying closures (i.e. creating `fn` pointers)
-//! other than those with absolutely no captures.
-//!
-//! More specifically, for a closure-like type to be "effectively `Default`":
-//! * it must be a ZST (zero-sized type): no information contained within, so
-//!   that `Default`'s return value (if it were implemented) is unambiguous
-//! * it must be `Copy`: no captured "unique ZST tokens" or any other similar
-//!   types that would make duplicating values at will unsound
-//!   * combined with the ZST requirement, this confers a kind of "telecopy"
-//!     ability: similar to `Copy`, but without keeping the value around, and
-//!     instead "reconstructing" it (a noop given it's a ZST) when needed
-//! * it must be *provably* inhabited: no captured uninhabited types or any
-//!   other types that cannot be constructed by the user of this abstraction
-//!   * the proof is a value of the closure-like type itself, in a sense the
-//!     "seed" for the "telecopy" process made possible by ZST + `Copy`
-//!   * this requirement is the only reason an abstraction limited to a specific
-//!     usecase is required: ZST + `Copy` can be checked with *at worst* a panic
-//!     at the "attempted `::default()` call" time, but that doesn't guarantee
-//!     that the value can be soundly created, and attempting to use the typical
-//!     "proof ZST token" approach leads yet again to having a ZST + `Copy` type
-//!     that is not proof of anything without a value (i.e. isomorphic to a
-//!     newtype of the type it's trying to prove the inhabitation of)
-//!
-//! A more flexible (and safer) solution to the general problem could exist once
-//! `const`-generic parameters can have type parameters in their types:
-//!
-//! ```rust,ignore (needs future const-generics)
-//! extern "C" fn ffi_wrapper<
-//!     A, R,
-//!     F: Fn(A) -> R,
-//!     const f: F, // <-- this `const`-generic is not yet allowed
-//! >(arg: A) -> R {
-//!     f(arg)
-//! }
-//! ```
-
-use std::mem;
-
-// FIXME(eddyb) this could be `trait` impls except for the `const fn` requirement.
-macro_rules! define_reify_functions {
-    ($(
-        fn $name:ident $(<$($param:ident),*>)?
-            for $(extern $abi:tt)? fn($($arg:ident: $arg_ty:ty),*) -> $ret_ty:ty;
-    )+) => {
-        $(pub const fn $name<
-            $($($param,)*)?
-            F: Fn($($arg_ty),*) -> $ret_ty + Copy
-        >(f: F) -> $(extern $abi)? fn($($arg_ty),*) -> $ret_ty {
-            // FIXME(eddyb) describe the `F` type (e.g. via `type_name::<F>`) once panic
-            // formatting becomes possible in `const fn`.
-            assert!(mem::size_of::<F>() == 0, "selfless_reify: closure must be zero-sized");
-
-            $(extern $abi)? fn wrapper<
-                $($($param,)*)?
-                F: Fn($($arg_ty),*) -> $ret_ty + Copy
-            >($($arg: $arg_ty),*) -> $ret_ty {
-                let f = unsafe {
-                    // SAFETY: `F` satisfies all criteria for "out of thin air"
-                    // reconstructability (see module-level doc comment).
-                    mem::MaybeUninit::<F>::uninit().assume_init()
-                };
-                f($($arg),*)
-            }
-            let _f_proof = f;
-            wrapper::<
-                $($($param,)*)?
-                F
-            >
-        })+
-    }
-}
-
-define_reify_functions! {
-    fn _reify_to_extern_c_fn_unary<A, R> for extern "C" fn(arg: A) -> R;
-
-    // HACK(eddyb) this abstraction is used with `for<'a> fn(BridgeConfig<'a>)
-    // -> T` but that doesn't work with just `reify_to_extern_c_fn_unary`
-    // because of the `fn` pointer type being "higher-ranked" (i.e. the
-    // `for<'a>` binder).
-    // FIXME(eddyb) try to remove the lifetime from `BridgeConfig`, that'd help.
-    fn reify_to_extern_c_fn_hrt_bridge<R> for extern "C" fn(bridge: super::BridgeConfig<'_>) -> R;
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs
deleted file mode 100644
index 6e7a8d8c10df1..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/bridge/server.rs
+++ /dev/null
@@ -1,339 +0,0 @@
-//! Server-side traits.
-
-use super::*;
-
-// FIXME(eddyb) generate the definition of `HandleStore` in `server.rs`.
-use super::client::HandleStore;
-
-pub trait Types {
-    type FreeFunctions: 'static;
-    type TokenStream: 'static + Clone;
-    type Ident: 'static + Copy + Eq + Hash;
-    type Literal: 'static + Clone;
-    type SourceFile: 'static + Clone;
-    type MultiSpan: 'static;
-    type Diagnostic: 'static;
-    type Span: 'static + Copy + Eq + Hash;
-}
-
-/// Declare an associated fn of one of the traits below, adding necessary
-/// default bodies.
-macro_rules! associated_fn {
-    (fn drop(&mut self, $arg:ident: $arg_ty:ty)) =>
-        (fn drop(&mut self, $arg: $arg_ty) { mem::drop($arg) });
-
-    (fn clone(&mut self, $arg:ident: $arg_ty:ty) -> $ret_ty:ty) =>
-        (fn clone(&mut self, $arg: $arg_ty) -> $ret_ty { $arg.clone() });
-
-    ($($item:tt)*) => ($($item)*;)
-}
-
-macro_rules! declare_server_traits {
-    ($($name:ident {
-        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
-    }),* $(,)?) => {
-        $(pub trait $name: Types {
-            $(associated_fn!(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)?);)*
-        })*
-
-        pub trait Server: Types $(+ $name)* {
-            fn globals(&mut self) -> ExpnGlobals<Self::Span>;
-        }
-    }
-}
-with_api!(Self, self_, declare_server_traits);
-
-pub(super) struct MarkedTypes<S: Types>(S);
-
-impl<S: Server> Server for MarkedTypes<S> {
-    fn globals(&mut self) -> ExpnGlobals<Self::Span> {
-        <_>::mark(Server::globals(&mut self.0))
-    }
-}
-
-macro_rules! define_mark_types_impls {
-    ($($name:ident {
-        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
-    }),* $(,)?) => {
-        impl<S: Types> Types for MarkedTypes<S> {
-            $(type $name = Marked<S::$name, client::$name>;)*
-        }
-
-        $(impl<S: $name> $name for MarkedTypes<S> {
-            $(fn $method(&mut self, $($arg: $arg_ty),*) $(-> $ret_ty)? {
-                <_>::mark($name::$method(&mut self.0, $($arg.unmark()),*))
-            })*
-        })*
-    }
-}
-with_api!(Self, self_, define_mark_types_impls);
-
-struct Dispatcher<S: Types> {
-    handle_store: HandleStore<S>,
-    server: S,
-}
-
-macro_rules! define_dispatcher_impl {
-    ($($name:ident {
-        $(fn $method:ident($($arg:ident: $arg_ty:ty),* $(,)?) $(-> $ret_ty:ty)?;)*
-    }),* $(,)?) => {
-        // FIXME(eddyb) `pub` only for `ExecutionStrategy` below.
-        pub trait DispatcherTrait {
-            // HACK(eddyb) these are here to allow `Self::$name` to work below.
-            $(type $name;)*
-            fn dispatch(&mut self, buf: Buffer) -> Buffer;
-        }
-
-        impl<S: Server> DispatcherTrait for Dispatcher<MarkedTypes<S>> {
-            $(type $name = <MarkedTypes<S> as Types>::$name;)*
-            fn dispatch(&mut self, mut buf: Buffer) -> Buffer {
-                let Dispatcher { handle_store, server } = self;
-
-                let mut reader = &buf[..];
-                match api_tags::Method::decode(&mut reader, &mut ()) {
-                    $(api_tags::Method::$name(m) => match m {
-                        $(api_tags::$name::$method => {
-                            let mut call_method = || {
-                                reverse_decode!(reader, handle_store; $($arg: $arg_ty),*);
-                                $name::$method(server, $($arg),*)
-                            };
-                            // HACK(eddyb) don't use `panic::catch_unwind` in a panic.
-                            // If client and server happen to use the same `libstd`,
-                            // `catch_unwind` asserts that the panic counter was 0,
-                            // even when the closure passed to it didn't panic.
-                            let r = if thread::panicking() {
-                                Ok(call_method())
-                            } else {
-                                panic::catch_unwind(panic::AssertUnwindSafe(call_method))
-                                    .map_err(PanicMessage::from)
-                            };
-
-                            buf.clear();
-                            r.encode(&mut buf, handle_store);
-                        })*
-                    }),*
-                }
-                buf
-            }
-        }
-    }
-}
-with_api!(Self, self_, define_dispatcher_impl);
-
-pub trait ExecutionStrategy {
-    fn run_bridge_and_client(
-        &self,
-        dispatcher: &mut impl DispatcherTrait,
-        input: Buffer,
-        run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-        force_show_panics: bool,
-    ) -> Buffer;
-}
-
-pub struct SameThread;
-
-impl ExecutionStrategy for SameThread {
-    fn run_bridge_and_client(
-        &self,
-        dispatcher: &mut impl DispatcherTrait,
-        input: Buffer,
-        run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-        force_show_panics: bool,
-    ) -> Buffer {
-        let mut dispatch = |buf| dispatcher.dispatch(buf);
-
-        run_client(BridgeConfig {
-            input,
-            dispatch: (&mut dispatch).into(),
-            force_show_panics,
-            _marker: marker::PhantomData,
-        })
-    }
-}
-
-// NOTE(eddyb) Two implementations are provided, the second one is a bit
-// faster but neither is anywhere near as fast as same-thread execution.
-
-pub struct CrossThread1;
-
-impl ExecutionStrategy for CrossThread1 {
-    fn run_bridge_and_client(
-        &self,
-        dispatcher: &mut impl DispatcherTrait,
-        input: Buffer,
-        run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-        force_show_panics: bool,
-    ) -> Buffer {
-        use std::sync::mpsc::channel;
-
-        let (req_tx, req_rx) = channel();
-        let (res_tx, res_rx) = channel();
-
-        let join_handle = thread::spawn(move || {
-            let mut dispatch = |buf| {
-                req_tx.send(buf).unwrap();
-                res_rx.recv().unwrap()
-            };
-
-            run_client(BridgeConfig {
-                input,
-                dispatch: (&mut dispatch).into(),
-                force_show_panics,
-                _marker: marker::PhantomData,
-            })
-        });
-
-        for b in req_rx {
-            res_tx.send(dispatcher.dispatch(b)).unwrap();
-        }
-
-        join_handle.join().unwrap()
-    }
-}
-
-pub struct CrossThread2;
-
-impl ExecutionStrategy for CrossThread2 {
-    fn run_bridge_and_client(
-        &self,
-        dispatcher: &mut impl DispatcherTrait,
-        input: Buffer,
-        run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-        force_show_panics: bool,
-    ) -> Buffer {
-        use std::sync::{Arc, Mutex};
-
-        enum State<T> {
-            Req(T),
-            Res(T),
-        }
-
-        let mut state = Arc::new(Mutex::new(State::Res(Buffer::new())));
-
-        let server_thread = thread::current();
-        let state2 = state.clone();
-        let join_handle = thread::spawn(move || {
-            let mut dispatch = |b| {
-                *state2.lock().unwrap() = State::Req(b);
-                server_thread.unpark();
-                loop {
-                    thread::park();
-                    if let State::Res(b) = &mut *state2.lock().unwrap() {
-                        break b.take();
-                    }
-                }
-            };
-
-            let r = run_client(BridgeConfig {
-                input,
-                dispatch: (&mut dispatch).into(),
-                force_show_panics,
-                _marker: marker::PhantomData,
-            });
-
-            // Wake up the server so it can exit the dispatch loop.
-            drop(state2);
-            server_thread.unpark();
-
-            r
-        });
-
-        // Check whether `state2` was dropped, to know when to stop.
-        while Arc::get_mut(&mut state).is_none() {
-            thread::park();
-            let mut b = match &mut *state.lock().unwrap() {
-                State::Req(b) => b.take(),
-                _ => continue,
-            };
-            b = dispatcher.dispatch(b.take());
-            *state.lock().unwrap() = State::Res(b);
-            join_handle.thread().unpark();
-        }
-
-        join_handle.join().unwrap()
-    }
-}
-
-fn run_server<
-    S: Server,
-    I: Encode<HandleStore<MarkedTypes<S>>>,
-    O: for<'a, 's> DecodeMut<'a, 's, HandleStore<MarkedTypes<S>>>,
->(
-    strategy: &impl ExecutionStrategy,
-    handle_counters: &'static client::HandleCounters,
-    server: S,
-    input: I,
-    run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer,
-    force_show_panics: bool,
-) -> Result<O, PanicMessage> {
-    let mut dispatcher =
-        Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) };
-
-    let globals = dispatcher.server.globals();
-
-    let mut buf = Buffer::new();
-    (globals, input).encode(&mut buf, &mut dispatcher.handle_store);
-
-    buf = strategy.run_bridge_and_client(&mut dispatcher, buf, run_client, force_show_panics);
-
-    Result::decode(&mut &buf[..], &mut dispatcher.handle_store)
-}
-
-impl client::Client<super::super::TokenStream, super::super::TokenStream> {
-    pub fn run<S>(
-        &self,
-        strategy: &impl ExecutionStrategy,
-        server: S,
-        input: S::TokenStream,
-        force_show_panics: bool,
-    ) -> Result<S::TokenStream, PanicMessage>
-    where
-        S: Server,
-        S::TokenStream: Default,
-    {
-        let client::Client { get_handle_counters, run, _marker } = *self;
-        run_server(
-            strategy,
-            get_handle_counters(),
-            server,
-            <MarkedTypes<S> as Types>::TokenStream::mark(input),
-            run,
-            force_show_panics,
-        )
-        .map(|s| <Option<<MarkedTypes<S> as Types>::TokenStream>>::unmark(s).unwrap_or_default())
-    }
-}
-
-impl
-    client::Client<
-        (super::super::TokenStream, super::super::TokenStream),
-        super::super::TokenStream,
-    >
-{
-    pub fn run<S>(
-        &self,
-        strategy: &impl ExecutionStrategy,
-        server: S,
-        input: S::TokenStream,
-        input2: S::TokenStream,
-        force_show_panics: bool,
-    ) -> Result<S::TokenStream, PanicMessage>
-    where
-        S: Server,
-        S::TokenStream: Default,
-    {
-        let client::Client { get_handle_counters, run, _marker } = *self;
-        run_server(
-            strategy,
-            get_handle_counters(),
-            server,
-            (
-                <MarkedTypes<S> as Types>::TokenStream::mark(input),
-                <MarkedTypes<S> as Types>::TokenStream::mark(input2),
-            ),
-            run,
-            force_show_panics,
-        )
-        .map(|s| <Option<<MarkedTypes<S> as Types>::TokenStream>>::unmark(s).unwrap_or_default())
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs
deleted file mode 100644
index 3fade2dc4f9cc..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/diagnostic.rs
+++ /dev/null
@@ -1,166 +0,0 @@
-//! lib-proc-macro diagnostic
-//!
-//! Copy from <https://github.com/rust-lang/rust/blob/e45d9973b2665897a768312e971b82cc62633103/src/libproc_macro/diagnostic.rs>
-//! augmented with removing unstable features
-
-use super::Span;
-
-/// An enum representing a diagnostic level.
-#[derive(Copy, Clone, Debug)]
-#[non_exhaustive]
-pub enum Level {
-    /// An error.
-    Error,
-    /// A warning.
-    Warning,
-    /// A note.
-    Note,
-    /// A help message.
-    Help,
-}
-
-/// Trait implemented by types that can be converted into a set of `Span`s.
-pub trait MultiSpan {
-    /// Converts `self` into a `Vec<Span>`.
-    fn into_spans(self) -> Vec<Span>;
-}
-
-impl MultiSpan for Span {
-    fn into_spans(self) -> Vec<Span> {
-        vec![self]
-    }
-}
-
-impl MultiSpan for Vec<Span> {
-    fn into_spans(self) -> Vec<Span> {
-        self
-    }
-}
-
-impl<'a> MultiSpan for &'a [Span] {
-    fn into_spans(self) -> Vec<Span> {
-        self.to_vec()
-    }
-}
-
-/// A structure representing a diagnostic message and associated children
-/// messages.
-#[derive(Clone, Debug)]
-pub struct Diagnostic {
-    level: Level,
-    message: String,
-    spans: Vec<Span>,
-    children: Vec<Diagnostic>,
-}
-
-macro_rules! diagnostic_child_methods {
-    ($spanned:ident, $regular:ident, $level:expr) => {
-        #[doc = concat!("Adds a new child diagnostics message to `self` with the [`",
-                        stringify!($level), "`] level, and the given `spans` and `message`.")]
-        pub fn $spanned<S, T>(mut self, spans: S, message: T) -> Diagnostic
-        where
-            S: MultiSpan,
-            T: Into<String>,
-        {
-            self.children.push(Diagnostic::spanned(spans, $level, message));
-            self
-        }
-
-        #[doc = concat!("Adds a new child diagnostic message to `self` with the [`",
-                        stringify!($level), "`] level, and the given `message`.")]
-        pub fn $regular<T: Into<String>>(mut self, message: T) -> Diagnostic {
-            self.children.push(Diagnostic::new($level, message));
-            self
-        }
-    };
-}
-
-/// Iterator over the children diagnostics of a `Diagnostic`.
-#[derive(Debug, Clone)]
-pub struct Children<'a>(std::slice::Iter<'a, Diagnostic>);
-
-impl<'a> Iterator for Children<'a> {
-    type Item = &'a Diagnostic;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        self.0.next()
-    }
-}
-
-impl Diagnostic {
-    /// Creates a new diagnostic with the given `level` and `message`.
-    pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
-        Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
-    }
-
-    /// Creates a new diagnostic with the given `level` and `message` pointing to
-    /// the given set of `spans`.
-    pub fn spanned<S, T>(spans: S, level: Level, message: T) -> Diagnostic
-    where
-        S: MultiSpan,
-        T: Into<String>,
-    {
-        Diagnostic { level, message: message.into(), spans: spans.into_spans(), children: vec![] }
-    }
-
-    diagnostic_child_methods!(span_error, error, Level::Error);
-    diagnostic_child_methods!(span_warning, warning, Level::Warning);
-    diagnostic_child_methods!(span_note, note, Level::Note);
-    diagnostic_child_methods!(span_help, help, Level::Help);
-
-    /// Returns the diagnostic `level` for `self`.
-    pub fn level(&self) -> Level {
-        self.level
-    }
-
-    /// Sets the level in `self` to `level`.
-    pub fn set_level(&mut self, level: Level) {
-        self.level = level;
-    }
-
-    /// Returns the message in `self`.
-    pub fn message(&self) -> &str {
-        &self.message
-    }
-
-    /// Sets the message in `self` to `message`.
-    pub fn set_message<T: Into<String>>(&mut self, message: T) {
-        self.message = message.into();
-    }
-
-    /// Returns the `Span`s in `self`.
-    pub fn spans(&self) -> &[Span] {
-        &self.spans
-    }
-
-    /// Sets the `Span`s in `self` to `spans`.
-    pub fn set_spans<S: MultiSpan>(&mut self, spans: S) {
-        self.spans = spans.into_spans();
-    }
-
-    /// Returns an iterator over the children diagnostics of `self`.
-    pub fn children(&self) -> Children<'_> {
-        Children(self.children.iter())
-    }
-
-    /// Emit the diagnostic.
-    pub fn emit(self) {
-        fn to_internal(spans: Vec<Span>) -> super::bridge::client::MultiSpan {
-            let mut multi_span = super::bridge::client::MultiSpan::new();
-            for span in spans {
-                multi_span.push(span.0);
-            }
-            multi_span
-        }
-
-        let mut diag = super::bridge::client::Diagnostic::new(
-            self.level,
-            &self.message[..],
-            to_internal(self.spans),
-        );
-        for c in self.children {
-            diag.sub(c.level, &c.message[..], to_internal(c.spans));
-        }
-        diag.emit();
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs
deleted file mode 100644
index 86a59b6455903..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/mod.rs
+++ /dev/null
@@ -1,1125 +0,0 @@
-//! A support library for macro authors when defining new macros.
-//!
-//! This library, provided by the standard distribution, provides the types
-//! consumed in the interfaces of procedurally defined macro definitions such as
-//! function-like macros `#[proc_macro]`, macro attributes `#[proc_macro_attribute]` and
-//! custom derive attributes`#[proc_macro_derive]`.
-//!
-//! See [the book] for more.
-//!
-//! [the book]: ../book/ch19-06-macros.html#procedural-macros-for-generating-code-from-attributes
-
-#[doc(hidden)]
-pub mod bridge;
-
-mod diagnostic;
-
-pub use diagnostic::{Diagnostic, Level, MultiSpan};
-
-use std::cmp::Ordering;
-use std::ops::RangeBounds;
-use std::path::PathBuf;
-use std::str::FromStr;
-use std::{error, fmt, iter, mem};
-
-/// Determines whether proc_macro has been made accessible to the currently
-/// running program.
-///
-/// The proc_macro crate is only intended for use inside the implementation of
-/// procedural macros. All the functions in this crate panic if invoked from
-/// outside of a procedural macro, such as from a build script or unit test or
-/// ordinary Rust binary.
-///
-/// With consideration for Rust libraries that are designed to support both
-/// macro and non-macro use cases, `proc_macro::is_available()` provides a
-/// non-panicking way to detect whether the infrastructure required to use the
-/// API of proc_macro is presently available. Returns true if invoked from
-/// inside of a procedural macro, false if invoked from any other binary.
-pub fn is_available() -> bool {
-    bridge::client::is_available()
-}
-
-/// The main type provided by this crate, representing an abstract stream of
-/// tokens, or, more specifically, a sequence of token trees.
-/// The type provide interfaces for iterating over those token trees and, conversely,
-/// collecting a number of token trees into one stream.
-///
-/// This is both the input and output of `#[proc_macro]`, `#[proc_macro_attribute]`
-/// and `#[proc_macro_derive]` definitions.
-#[derive(Clone)]
-pub struct TokenStream(Option<bridge::client::TokenStream>);
-
-/// Error returned from `TokenStream::from_str`.
-#[non_exhaustive]
-#[derive(Debug)]
-pub struct LexError;
-
-impl fmt::Display for LexError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("cannot parse string into token stream")
-    }
-}
-
-impl error::Error for LexError {}
-
-/// Error returned from `TokenStream::expand_expr`.
-#[non_exhaustive]
-#[derive(Debug)]
-pub struct ExpandError;
-
-impl fmt::Display for ExpandError {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("macro expansion failed")
-    }
-}
-
-impl error::Error for ExpandError {}
-
-impl TokenStream {
-    /// Returns an empty `TokenStream` containing no token trees.
-    pub fn new() -> TokenStream {
-        TokenStream(None)
-    }
-
-    /// Checks if this `TokenStream` is empty.
-    pub fn is_empty(&self) -> bool {
-        self.0.as_ref().map(|h| h.is_empty()).unwrap_or(true)
-    }
-
-    /// Parses this `TokenStream` as an expression and attempts to expand any
-    /// macros within it. Returns the expanded `TokenStream`.
-    ///
-    /// Currently only expressions expanding to literals will succeed, although
-    /// this may be relaxed in the future.
-    ///
-    /// NOTE: In error conditions, `expand_expr` may leave macros unexpanded,
-    /// report an error, failing compilation, and/or return an `Err(..)`. The
-    /// specific behavior for any error condition, and what conditions are
-    /// considered errors, is unspecified and may change in the future.
-    pub fn expand_expr(&self) -> Result<TokenStream, ExpandError> {
-        let stream = self.0.as_ref().ok_or(ExpandError)?;
-        match bridge::client::TokenStream::expand_expr(stream) {
-            Ok(stream) => Ok(TokenStream(Some(stream))),
-            Err(_) => Err(ExpandError),
-        }
-    }
-}
-
-/// Attempts to break the string into tokens and parse those tokens into a token stream.
-/// May fail for a number of reasons, for example, if the string contains unbalanced delimiters
-/// or characters not existing in the language.
-/// All tokens in the parsed stream get `Span::call_site()` spans.
-///
-/// NOTE: some errors may cause panics instead of returning `LexError`. We reserve the right to
-/// change these errors into `LexError`s later.
-impl FromStr for TokenStream {
-    type Err = LexError;
-
-    fn from_str(src: &str) -> Result<TokenStream, LexError> {
-        Ok(TokenStream(Some(bridge::client::TokenStream::from_str(src))))
-    }
-}
-
-/// Prints the token stream as a string that is supposed to be losslessly convertible back
-/// into the same token stream (modulo spans), except for possibly `TokenTree::Group`s
-/// with `Delimiter::None` delimiters and negative numeric literals.
-impl fmt::Display for TokenStream {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-/// Prints token in a form convenient for debugging.
-impl fmt::Debug for TokenStream {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str("TokenStream ")?;
-        f.debug_list().entries(self.clone()).finish()
-    }
-}
-
-impl Default for TokenStream {
-    fn default() -> Self {
-        TokenStream::new()
-    }
-}
-
-pub use quote::{quote, quote_span};
-
-fn tree_to_bridge_tree(
-    tree: TokenTree,
-) -> bridge::TokenTree<
-    bridge::client::TokenStream,
-    bridge::client::Span,
-    bridge::client::Ident,
-    bridge::client::Literal,
-> {
-    match tree {
-        TokenTree::Group(tt) => bridge::TokenTree::Group(tt.0),
-        TokenTree::Punct(tt) => bridge::TokenTree::Punct(tt.0),
-        TokenTree::Ident(tt) => bridge::TokenTree::Ident(tt.0),
-        TokenTree::Literal(tt) => bridge::TokenTree::Literal(tt.0),
-    }
-}
-
-/// Creates a token stream containing a single token tree.
-impl From<TokenTree> for TokenStream {
-    fn from(tree: TokenTree) -> TokenStream {
-        TokenStream(Some(bridge::client::TokenStream::from_token_tree(tree_to_bridge_tree(tree))))
-    }
-}
-
-/// Non-generic helper for implementing `FromIterator<TokenStream>` and
-/// `Extend<TokenStream>` with less monomorphization in calling crates.
-struct ConcatStreamsHelper {
-    streams: Vec<bridge::client::TokenStream>,
-}
-
-impl ConcatStreamsHelper {
-    fn new(capacity: usize) -> Self {
-        ConcatStreamsHelper { streams: Vec::with_capacity(capacity) }
-    }
-
-    fn push(&mut self, stream: TokenStream) {
-        if let Some(stream) = stream.0 {
-            self.streams.push(stream);
-        }
-    }
-
-    fn build(mut self) -> TokenStream {
-        if self.streams.len() <= 1 {
-            TokenStream(self.streams.pop())
-        } else {
-            TokenStream(Some(bridge::client::TokenStream::concat_streams(None, self.streams)))
-        }
-    }
-
-    fn append_to(mut self, stream: &mut TokenStream) {
-        if self.streams.is_empty() {
-            return;
-        }
-        let base = stream.0.take();
-        if base.is_none() && self.streams.len() == 1 {
-            stream.0 = self.streams.pop();
-        } else {
-            stream.0 = Some(bridge::client::TokenStream::concat_streams(base, self.streams));
-        }
-    }
-}
-
-/// Collects a number of token trees into a single stream.
-impl FromIterator<TokenTree> for TokenStream {
-    fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
-        trees.into_iter().map(TokenStream::from).collect()
-    }
-}
-
-/// A "flattening" operation on token streams, collects token trees
-/// from multiple token streams into a single stream.
-impl FromIterator<TokenStream> for TokenStream {
-    fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
-        let iter = streams.into_iter();
-        let mut builder = ConcatStreamsHelper::new(iter.size_hint().0);
-        iter.for_each(|stream| builder.push(stream));
-        builder.build()
-    }
-}
-
-impl Extend<TokenTree> for TokenStream {
-    fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
-        self.extend(trees.into_iter().map(TokenStream::from));
-    }
-}
-
-impl Extend<TokenStream> for TokenStream {
-    fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
-        // FIXME(eddyb) Use an optimized implementation if/when possible.
-        *self = iter::once(mem::replace(self, Self::new())).chain(streams).collect();
-    }
-}
-
-/// Public implementation details for the `TokenStream` type, such as iterators.
-pub mod token_stream {
-    use super::{bridge, Group, Ident, Literal, Punct, TokenStream, TokenTree};
-
-    /// An iterator over `TokenStream`'s `TokenTree`s.
-    /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,
-    /// and returns whole groups as token trees.
-    #[derive(Clone)]
-    pub struct IntoIter(
-        std::vec::IntoIter<
-            bridge::TokenTree<
-                bridge::client::TokenStream,
-                bridge::client::Span,
-                bridge::client::Ident,
-                bridge::client::Literal,
-            >,
-        >,
-    );
-
-    impl Iterator for IntoIter {
-        type Item = TokenTree;
-
-        fn next(&mut self) -> Option<TokenTree> {
-            self.0.next().map(|tree| match tree {
-                bridge::TokenTree::Group(tt) => TokenTree::Group(Group(tt)),
-                bridge::TokenTree::Punct(tt) => TokenTree::Punct(Punct(tt)),
-                bridge::TokenTree::Ident(tt) => TokenTree::Ident(Ident(tt)),
-                bridge::TokenTree::Literal(tt) => TokenTree::Literal(Literal(tt)),
-            })
-        }
-    }
-
-    impl IntoIterator for TokenStream {
-        type Item = TokenTree;
-        type IntoIter = IntoIter;
-
-        fn into_iter(self) -> IntoIter {
-            IntoIter(self.0.map(|v| v.into_trees()).unwrap_or_default().into_iter())
-        }
-    }
-}
-
-#[doc(hidden)]
-mod quote;
-
-/// A region of source code, along with macro expansion information.
-#[derive(Copy, Clone)]
-pub struct Span(bridge::client::Span);
-
-macro_rules! diagnostic_method {
-    ($name:ident, $level:expr) => {
-        /// Creates a new `Diagnostic` with the given `message` at the span
-        /// `self`.
-        pub fn $name<T: Into<String>>(self, message: T) -> Diagnostic {
-            Diagnostic::spanned(self, $level, message)
-        }
-    };
-}
-
-impl Span {
-    /// A span that resolves at the macro definition site.
-    pub fn def_site() -> Span {
-        Span(bridge::client::Span::def_site())
-    }
-
-    /// The span of the invocation of the current procedural macro.
-    /// Identifiers created with this span will be resolved as if they were written
-    /// directly at the macro call location (call-site hygiene) and other code
-    /// at the macro call site will be able to refer to them as well.
-    pub fn call_site() -> Span {
-        Span(bridge::client::Span::call_site())
-    }
-
-    /// A span that represents `macro_rules` hygiene, and sometimes resolves at the macro
-    /// definition site (local variables, labels, `$crate`) and sometimes at the macro
-    /// call site (everything else).
-    /// The span location is taken from the call-site.
-    pub fn mixed_site() -> Span {
-        Span(bridge::client::Span::mixed_site())
-    }
-
-    /// The original source file into which this span points.
-    pub fn source_file(&self) -> SourceFile {
-        SourceFile(self.0.source_file())
-    }
-
-    /// The `Span` for the tokens in the previous macro expansion from which
-    /// `self` was generated from, if any.
-    pub fn parent(&self) -> Option<Span> {
-        self.0.parent().map(Span)
-    }
-
-    /// The span for the origin source code that `self` was generated from. If
-    /// this `Span` wasn't generated from other macro expansions then the return
-    /// value is the same as `*self`.
-    pub fn source(&self) -> Span {
-        Span(self.0.source())
-    }
-
-    /// Gets the starting line/column in the source file for this span.
-    pub fn start(&self) -> LineColumn {
-        self.0.start().add_1_to_column()
-    }
-
-    /// Gets the ending line/column in the source file for this span.
-    pub fn end(&self) -> LineColumn {
-        self.0.end().add_1_to_column()
-    }
-
-    /// Creates an empty span pointing to directly before this span.
-    pub fn before(&self) -> Span {
-        Span(self.0.before())
-    }
-
-    /// Creates an empty span pointing to directly after this span.
-    pub fn after(&self) -> Span {
-        Span(self.0.after())
-    }
-
-    /// Creates a new span encompassing `self` and `other`.
-    ///
-    /// Returns `None` if `self` and `other` are from different files.
-    pub fn join(&self, other: Span) -> Option<Span> {
-        self.0.join(other.0).map(Span)
-    }
-
-    /// Creates a new span with the same line/column information as `self` but
-    /// that resolves symbols as though it were at `other`.
-    pub fn resolved_at(&self, other: Span) -> Span {
-        Span(self.0.resolved_at(other.0))
-    }
-
-    /// Creates a new span with the same name resolution behavior as `self` but
-    /// with the line/column information of `other`.
-    pub fn located_at(&self, other: Span) -> Span {
-        other.resolved_at(*self)
-    }
-
-    /// Compares to spans to see if they're equal.
-    pub fn eq(&self, other: &Span) -> bool {
-        self.0 == other.0
-    }
-
-    /// Returns the source text behind a span. This preserves the original source
-    /// code, including spaces and comments. It only returns a result if the span
-    /// corresponds to real source code.
-    ///
-    /// Note: The observable result of a macro should only rely on the tokens and
-    /// not on this source text. The result of this function is a best effort to
-    /// be used for diagnostics only.
-    pub fn source_text(&self) -> Option<String> {
-        self.0.source_text()
-    }
-
-    // Used by the implementation of `Span::quote`
-    #[doc(hidden)]
-    pub fn save_span(&self) -> usize {
-        self.0.save_span()
-    }
-
-    // Used by the implementation of `Span::quote`
-    #[doc(hidden)]
-    pub fn recover_proc_macro_span(id: usize) -> Span {
-        Span(bridge::client::Span::recover_proc_macro_span(id))
-    }
-
-    diagnostic_method!(error, Level::Error);
-    diagnostic_method!(warning, Level::Warning);
-    diagnostic_method!(note, Level::Note);
-    diagnostic_method!(help, Level::Help);
-}
-
-/// Prints a span in a form convenient for debugging.
-impl fmt::Debug for Span {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-/// A line-column pair representing the start or end of a `Span`.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub struct LineColumn {
-    /// The 1-indexed line in the source file on which the span starts or ends (inclusive).
-    pub line: usize,
-    /// The 1-indexed column (number of bytes in UTF-8 encoding) in the source
-    /// file on which the span starts or ends (inclusive).
-    pub column: usize,
-}
-
-impl LineColumn {
-    fn add_1_to_column(self) -> Self {
-        LineColumn { line: self.line, column: self.column + 1 }
-    }
-}
-
-impl Ord for LineColumn {
-    fn cmp(&self, other: &Self) -> Ordering {
-        self.line.cmp(&other.line).then(self.column.cmp(&other.column))
-    }
-}
-
-impl PartialOrd for LineColumn {
-    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
-        Some(self.cmp(other))
-    }
-}
-
-/// The source file of a given `Span`.
-#[derive(Clone)]
-pub struct SourceFile(bridge::client::SourceFile);
-
-impl SourceFile {
-    /// Gets the path to this source file.
-    ///
-    /// ### Note
-    /// If the code span associated with this `SourceFile` was generated by an external macro, this
-    /// macro, this might not be an actual path on the filesystem. Use [`is_real`] to check.
-    ///
-    /// Also note that even if `is_real` returns `true`, if `--remap-path-prefix` was passed on
-    /// the command line, the path as given might not actually be valid.
-    ///
-    /// [`is_real`]: Self::is_real
-    pub fn path(&self) -> PathBuf {
-        PathBuf::from(self.0.path())
-    }
-
-    /// Returns `true` if this source file is a real source file, and not generated by an external
-    /// macro's expansion.
-    pub fn is_real(&self) -> bool {
-        // This is a hack until intercrate spans are implemented and we can have real source files
-        // for spans generated in external macros.
-        // https://github.com/rust-lang/rust/pull/43604#issuecomment-333334368
-        self.0.is_real()
-    }
-}
-
-impl fmt::Debug for SourceFile {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("SourceFile")
-            .field("path", &self.path())
-            .field("is_real", &self.is_real())
-            .finish()
-    }
-}
-
-impl PartialEq for SourceFile {
-    fn eq(&self, other: &Self) -> bool {
-        self.0.eq(&other.0)
-    }
-}
-
-impl Eq for SourceFile {}
-
-/// A single token or a delimited sequence of token trees (e.g., `[1, (), ..]`).
-#[derive(Clone)]
-pub enum TokenTree {
-    /// A token stream surrounded by bracket delimiters.
-    Group(Group),
-    /// An identifier.
-    Ident(Ident),
-    /// A single punctuation character (`+`, `,`, `$`, etc.).
-    Punct(Punct),
-    /// A literal character (`'a'`), string (`"hello"`), number (`2.3`), etc.
-    Literal(Literal),
-}
-
-impl TokenTree {
-    /// Returns the span of this tree, delegating to the `span` method of
-    /// the contained token or a delimited stream.
-    pub fn span(&self) -> Span {
-        match *self {
-            TokenTree::Group(ref t) => t.span(),
-            TokenTree::Ident(ref t) => t.span(),
-            TokenTree::Punct(ref t) => t.span(),
-            TokenTree::Literal(ref t) => t.span(),
-        }
-    }
-
-    /// Configures the span for *only this token*.
-    ///
-    /// Note that if this token is a `Group` then this method will not configure
-    /// the span of each of the internal tokens, this will simply delegate to
-    /// the `set_span` method of each variant.
-    pub fn set_span(&mut self, span: Span) {
-        match *self {
-            TokenTree::Group(ref mut t) => t.set_span(span),
-            TokenTree::Ident(ref mut t) => t.set_span(span),
-            TokenTree::Punct(ref mut t) => t.set_span(span),
-            TokenTree::Literal(ref mut t) => t.set_span(span),
-        }
-    }
-}
-
-/// Prints token tree in a form convenient for debugging.
-impl fmt::Debug for TokenTree {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        // Each of these has the name in the struct type in the derived debug,
-        // so don't bother with an extra layer of indirection
-        match *self {
-            TokenTree::Group(ref tt) => tt.fmt(f),
-            TokenTree::Ident(ref tt) => tt.fmt(f),
-            TokenTree::Punct(ref tt) => tt.fmt(f),
-            TokenTree::Literal(ref tt) => tt.fmt(f),
-        }
-    }
-}
-
-impl From<Group> for TokenTree {
-    fn from(g: Group) -> TokenTree {
-        TokenTree::Group(g)
-    }
-}
-
-impl From<Ident> for TokenTree {
-    fn from(g: Ident) -> TokenTree {
-        TokenTree::Ident(g)
-    }
-}
-
-impl From<Punct> for TokenTree {
-    fn from(g: Punct) -> TokenTree {
-        TokenTree::Punct(g)
-    }
-}
-
-impl From<Literal> for TokenTree {
-    fn from(g: Literal) -> TokenTree {
-        TokenTree::Literal(g)
-    }
-}
-
-/// Prints the token tree as a string that is supposed to be losslessly convertible back
-/// into the same token tree (modulo spans), except for possibly `TokenTree::Group`s
-/// with `Delimiter::None` delimiters and negative numeric literals.
-impl fmt::Display for TokenTree {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-/// A delimited token stream.
-///
-/// A `Group` internally contains a `TokenStream` which is surrounded by `Delimiter`s.
-#[derive(Clone)]
-pub struct Group(bridge::Group<bridge::client::TokenStream, bridge::client::Span>);
-
-/// Describes how a sequence of token trees is delimited.
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum Delimiter {
-    /// `( ... )`
-    Parenthesis,
-    /// `{ ... }`
-    Brace,
-    /// `[ ... ]`
-    Bracket,
-    /// `Ø ... Ø`
-    /// An invisible delimiter, that may, for example, appear around tokens coming from a
-    /// "macro variable" `$var`. It is important to preserve operator priorities in cases like
-    /// `$var * 3` where `$var` is `1 + 2`.
-    /// Invisible delimiters might not survive roundtrip of a token stream through a string.
-    None,
-}
-
-impl Group {
-    /// Creates a new `Group` with the given delimiter and token stream.
-    ///
-    /// This constructor will set the span for this group to
-    /// `Span::call_site()`. To change the span you can use the `set_span`
-    /// method below.
-    pub fn new(delimiter: Delimiter, stream: TokenStream) -> Group {
-        Group(bridge::Group {
-            delimiter,
-            stream: stream.0,
-            span: bridge::DelimSpan::from_single(Span::call_site().0),
-        })
-    }
-
-    /// Returns the delimiter of this `Group`
-    pub fn delimiter(&self) -> Delimiter {
-        self.0.delimiter
-    }
-
-    /// Returns the `TokenStream` of tokens that are delimited in this `Group`.
-    ///
-    /// Note that the returned token stream does not include the delimiter
-    /// returned above.
-    pub fn stream(&self) -> TokenStream {
-        TokenStream(self.0.stream.clone())
-    }
-
-    /// Returns the span for the delimiters of this token stream, spanning the
-    /// entire `Group`.
-    ///
-    /// ```text
-    /// pub fn span(&self) -> Span {
-    ///            ^^^^^^^
-    /// ```
-    pub fn span(&self) -> Span {
-        Span(self.0.span.entire)
-    }
-
-    /// Returns the span pointing to the opening delimiter of this group.
-    ///
-    /// ```text
-    /// pub fn span_open(&self) -> Span {
-    ///                 ^
-    /// ```
-    pub fn span_open(&self) -> Span {
-        Span(self.0.span.open)
-    }
-
-    /// Returns the span pointing to the closing delimiter of this group.
-    ///
-    /// ```text
-    /// pub fn span_close(&self) -> Span {
-    ///                        ^
-    /// ```
-    pub fn span_close(&self) -> Span {
-        Span(self.0.span.close)
-    }
-
-    /// Configures the span for this `Group`'s delimiters, but not its internal
-    /// tokens.
-    ///
-    /// This method will **not** set the span of all the internal tokens spanned
-    /// by this group, but rather it will only set the span of the delimiter
-    /// tokens at the level of the `Group`.
-    pub fn set_span(&mut self, span: Span) {
-        self.0.span = bridge::DelimSpan::from_single(span.0);
-    }
-}
-
-/// Prints the group as a string that should be losslessly convertible back
-/// into the same group (modulo spans), except for possibly `TokenTree::Group`s
-/// with `Delimiter::None` delimiters.
-impl fmt::Display for Group {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-impl fmt::Debug for Group {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Group")
-            .field("delimiter", &self.delimiter())
-            .field("stream", &self.stream())
-            .field("span", &self.span())
-            .finish()
-    }
-}
-
-/// A `Punct` is a single punctuation character such as `+`, `-` or `#`.
-///
-/// Multi-character operators like `+=` are represented as two instances of `Punct` with different
-/// forms of `Spacing` returned.
-#[derive(Clone)]
-pub struct Punct(bridge::Punct<bridge::client::Span>);
-
-/// Describes whether a `Punct` is followed immediately by another `Punct` ([`Spacing::Joint`]) or
-/// by a different token or whitespace ([`Spacing::Alone`]).
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-pub enum Spacing {
-    /// A `Punct` is not immediately followed by another `Punct`.
-    /// E.g. `+` is `Alone` in `+ =`, `+ident` and `+()`.
-    Alone,
-    /// A `Punct` is immediately followed by another `Punct`.
-    /// E.g. `+` is `Joint` in `+=` and `++`.
-    ///
-    /// Additionally, single quote `'` can join with identifiers to form lifetimes: `'ident`.
-    Joint,
-}
-
-impl Punct {
-    /// Creates a new `Punct` from the given character and spacing.
-    /// The `ch` argument must be a valid punctuation character permitted by the language,
-    /// otherwise the function will panic.
-    ///
-    /// The returned `Punct` will have the default span of `Span::call_site()`
-    /// which can be further configured with the `set_span` method below.
-    pub fn new(ch: char, spacing: Spacing) -> Punct {
-        const LEGAL_CHARS: &[char] = &[
-            '=', '<', '>', '!', '~', '+', '-', '*', '/', '%', '^', '&', '|', '@', '.', ',', ';',
-            ':', '#', '$', '?', '\'',
-        ];
-        if !LEGAL_CHARS.contains(&ch) {
-            panic!("unsupported character `{:?}`", ch);
-        }
-        Punct(bridge::Punct {
-            ch: ch as u8,
-            joint: spacing == Spacing::Joint,
-            span: Span::call_site().0,
-        })
-    }
-
-    /// Returns the value of this punctuation character as `char`.
-    pub fn as_char(&self) -> char {
-        self.0.ch as char
-    }
-
-    /// Returns the spacing of this punctuation character, indicating whether it's immediately
-    /// followed by another `Punct` in the token stream, so they can potentially be combined into
-    /// a multi-character operator (`Joint`), or it's followed by some other token or whitespace
-    /// (`Alone`) so the operator has certainly ended.
-    pub fn spacing(&self) -> Spacing {
-        if self.0.joint {
-            Spacing::Joint
-        } else {
-            Spacing::Alone
-        }
-    }
-
-    /// Returns the span for this punctuation character.
-    pub fn span(&self) -> Span {
-        Span(self.0.span)
-    }
-
-    /// Configure the span for this punctuation character.
-    pub fn set_span(&mut self, span: Span) {
-        self.0.span = span.0;
-    }
-}
-
-/// Prints the punctuation character as a string that should be losslessly convertible
-/// back into the same character.
-impl fmt::Display for Punct {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-impl fmt::Debug for Punct {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Punct")
-            .field("ch", &self.as_char())
-            .field("spacing", &self.spacing())
-            .field("span", &self.span())
-            .finish()
-    }
-}
-
-impl PartialEq<char> for Punct {
-    fn eq(&self, rhs: &char) -> bool {
-        self.as_char() == *rhs
-    }
-}
-
-impl PartialEq<Punct> for char {
-    fn eq(&self, rhs: &Punct) -> bool {
-        *self == rhs.as_char()
-    }
-}
-
-/// An identifier (`ident`).
-#[derive(Clone)]
-pub struct Ident(bridge::client::Ident);
-
-impl Ident {
-    /// Creates a new `Ident` with the given `string` as well as the specified
-    /// `span`.
-    /// The `string` argument must be a valid identifier permitted by the
-    /// language (including keywords, e.g. `self` or `fn`). Otherwise, the function will panic.
-    ///
-    /// Note that `span`, currently in rustc, configures the hygiene information
-    /// for this identifier.
-    ///
-    /// As of this time `Span::call_site()` explicitly opts-in to "call-site" hygiene
-    /// meaning that identifiers created with this span will be resolved as if they were written
-    /// directly at the location of the macro call, and other code at the macro call site will be
-    /// able to refer to them as well.
-    ///
-    /// Later spans like `Span::def_site()` will allow to opt-in to "definition-site" hygiene
-    /// meaning that identifiers created with this span will be resolved at the location of the
-    /// macro definition and other code at the macro call site will not be able to refer to them.
-    ///
-    /// Due to the current importance of hygiene this constructor, unlike other
-    /// tokens, requires a `Span` to be specified at construction.
-    pub fn new(string: &str, span: Span) -> Ident {
-        Ident(bridge::client::Ident::new(string, span.0, false))
-    }
-
-    /// Same as `Ident::new`, but creates a raw identifier (`r#ident`).
-    /// The `string` argument be a valid identifier permitted by the language
-    /// (including keywords, e.g. `fn`). Keywords which are usable in path segments
-    /// (e.g. `self`, `super`) are not supported, and will cause a panic.
-    pub fn new_raw(string: &str, span: Span) -> Ident {
-        Ident(bridge::client::Ident::new(string, span.0, true))
-    }
-
-    /// Returns the span of this `Ident`, encompassing the entire string returned
-    /// by [`to_string`](Self::to_string).
-    pub fn span(&self) -> Span {
-        Span(self.0.span())
-    }
-
-    /// Configures the span of this `Ident`, possibly changing its hygiene context.
-    pub fn set_span(&mut self, span: Span) {
-        self.0 = self.0.with_span(span.0);
-    }
-}
-
-/// Prints the identifier as a string that should be losslessly convertible
-/// back into the same identifier.
-impl fmt::Display for Ident {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-impl fmt::Debug for Ident {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("Ident")
-            .field("ident", &self.to_string())
-            .field("span", &self.span())
-            .finish()
-    }
-}
-
-/// A literal string (`"hello"`), byte string (`b"hello"`),
-/// character (`'a'`), byte character (`b'a'`), an integer or floating point number
-/// with or without a suffix (`1`, `1u8`, `2.3`, `2.3f32`).
-/// Boolean literals like `true` and `false` do not belong here, they are `Ident`s.
-#[derive(Clone)]
-pub struct Literal(bridge::client::Literal);
-
-macro_rules! suffixed_int_literals {
-    ($($name:ident => $kind:ident,)*) => ($(
-        /// Creates a new suffixed integer literal with the specified value.
-        ///
-        /// This function will create an integer like `1u32` where the integer
-        /// value specified is the first part of the token and the integral is
-        /// also suffixed at the end.
-        /// Literals created from negative numbers might not survive round-trips through
-        /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-        ///
-        /// Literals created through this method have the `Span::call_site()`
-        /// span by default, which can be configured with the `set_span` method
-        /// below.
-        pub fn $name(n: $kind) -> Literal {
-            Literal(bridge::client::Literal::typed_integer(&n.to_string(), stringify!($kind)))
-        }
-    )*)
-}
-
-macro_rules! unsuffixed_int_literals {
-    ($($name:ident => $kind:ident,)*) => ($(
-        /// Creates a new unsuffixed integer literal with the specified value.
-        ///
-        /// This function will create an integer like `1` where the integer
-        /// value specified is the first part of the token. No suffix is
-        /// specified on this token, meaning that invocations like
-        /// `Literal::i8_unsuffixed(1)` are equivalent to
-        /// `Literal::u32_unsuffixed(1)`.
-        /// Literals created from negative numbers might not survive rountrips through
-        /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-        ///
-        /// Literals created through this method have the `Span::call_site()`
-        /// span by default, which can be configured with the `set_span` method
-        /// below.
-        pub fn $name(n: $kind) -> Literal {
-            Literal(bridge::client::Literal::integer(&n.to_string()))
-        }
-    )*)
-}
-
-impl Literal {
-    suffixed_int_literals! {
-        u8_suffixed => u8,
-        u16_suffixed => u16,
-        u32_suffixed => u32,
-        u64_suffixed => u64,
-        u128_suffixed => u128,
-        usize_suffixed => usize,
-        i8_suffixed => i8,
-        i16_suffixed => i16,
-        i32_suffixed => i32,
-        i64_suffixed => i64,
-        i128_suffixed => i128,
-        isize_suffixed => isize,
-    }
-
-    unsuffixed_int_literals! {
-        u8_unsuffixed => u8,
-        u16_unsuffixed => u16,
-        u32_unsuffixed => u32,
-        u64_unsuffixed => u64,
-        u128_unsuffixed => u128,
-        usize_unsuffixed => usize,
-        i8_unsuffixed => i8,
-        i16_unsuffixed => i16,
-        i32_unsuffixed => i32,
-        i64_unsuffixed => i64,
-        i128_unsuffixed => i128,
-        isize_unsuffixed => isize,
-    }
-
-    /// Creates a new unsuffixed floating-point literal.
-    ///
-    /// This constructor is similar to those like `Literal::i8_unsuffixed` where
-    /// the float's value is emitted directly into the token but no suffix is
-    /// used, so it may be inferred to be a `f64` later in the compiler.
-    /// Literals created from negative numbers might not survive rountrips through
-    /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-    ///
-    /// # Panics
-    ///
-    /// This function requires that the specified float is finite, for
-    /// example if it is infinity or NaN this function will panic.
-    pub fn f32_unsuffixed(n: f32) -> Literal {
-        if !n.is_finite() {
-            panic!("Invalid float literal {n}");
-        }
-        let mut repr = n.to_string();
-        if !repr.contains('.') {
-            repr.push_str(".0");
-        }
-        Literal(bridge::client::Literal::float(&repr))
-    }
-
-    /// Creates a new suffixed floating-point literal.
-    ///
-    /// This constructor will create a literal like `1.0f32` where the value
-    /// specified is the preceding part of the token and `f32` is the suffix of
-    /// the token. This token will always be inferred to be an `f32` in the
-    /// compiler.
-    /// Literals created from negative numbers might not survive rountrips through
-    /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-    ///
-    /// # Panics
-    ///
-    /// This function requires that the specified float is finite, for
-    /// example if it is infinity or NaN this function will panic.
-    pub fn f32_suffixed(n: f32) -> Literal {
-        if !n.is_finite() {
-            panic!("Invalid float literal {n}");
-        }
-        Literal(bridge::client::Literal::f32(&n.to_string()))
-    }
-
-    /// Creates a new unsuffixed floating-point literal.
-    ///
-    /// This constructor is similar to those like `Literal::i8_unsuffixed` where
-    /// the float's value is emitted directly into the token but no suffix is
-    /// used, so it may be inferred to be a `f64` later in the compiler.
-    /// Literals created from negative numbers might not survive rountrips through
-    /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-    ///
-    /// # Panics
-    ///
-    /// This function requires that the specified float is finite, for
-    /// example if it is infinity or NaN this function will panic.
-    pub fn f64_unsuffixed(n: f64) -> Literal {
-        if !n.is_finite() {
-            panic!("Invalid float literal {n}");
-        }
-        let mut repr = n.to_string();
-        if !repr.contains('.') {
-            repr.push_str(".0");
-        }
-        Literal(bridge::client::Literal::float(&repr))
-    }
-
-    /// Creates a new suffixed floating-point literal.
-    ///
-    /// This constructor will create a literal like `1.0f64` where the value
-    /// specified is the preceding part of the token and `f64` is the suffix of
-    /// the token. This token will always be inferred to be an `f64` in the
-    /// compiler.
-    /// Literals created from negative numbers might not survive rountrips through
-    /// `TokenStream` or strings and may be broken into two tokens (`-` and positive literal).
-    ///
-    /// # Panics
-    ///
-    /// This function requires that the specified float is finite, for
-    /// example if it is infinity or NaN this function will panic.
-    pub fn f64_suffixed(n: f64) -> Literal {
-        if !n.is_finite() {
-            panic!("Invalid float literal {n}");
-        }
-        Literal(bridge::client::Literal::f64(&n.to_string()))
-    }
-
-    /// String literal.
-    pub fn string(string: &str) -> Literal {
-        Literal(bridge::client::Literal::string(string))
-    }
-
-    /// Character literal.
-    pub fn character(ch: char) -> Literal {
-        Literal(bridge::client::Literal::character(ch))
-    }
-
-    /// Byte string literal.
-    pub fn byte_string(bytes: &[u8]) -> Literal {
-        Literal(bridge::client::Literal::byte_string(bytes))
-    }
-
-    /// Returns the span encompassing this literal.
-    pub fn span(&self) -> Span {
-        Span(self.0.span())
-    }
-
-    /// Configures the span associated for this literal.
-    pub fn set_span(&mut self, span: Span) {
-        self.0.set_span(span.0);
-    }
-
-    /// Returns a `Span` that is a subset of `self.span()` containing only the
-    /// source bytes in range `range`. Returns `None` if the would-be trimmed
-    /// span is outside the bounds of `self`.
-    // FIXME(SergioBenitez): check that the byte range starts and ends at a
-    // UTF-8 boundary of the source. otherwise, it's likely that a panic will
-    // occur elsewhere when the source text is printed.
-    // FIXME(SergioBenitez): there is no way for the user to know what
-    // `self.span()` actually maps to, so this method can currently only be
-    // called blindly. For example, `to_string()` for the character 'c' returns
-    // "'\u{63}'"; there is no way for the user to know whether the source text
-    // was 'c' or whether it was '\u{63}'.
-    pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
-        self.0.subspan(range.start_bound().cloned(), range.end_bound().cloned()).map(Span)
-    }
-}
-
-/// Parse a single literal from its stringified representation.
-///
-/// In order to parse successfully, the input string must not contain anything
-/// but the literal token. Specifically, it must not contain whitespace or
-/// comments in addition to the literal.
-///
-/// The resulting literal token will have a `Span::call_site()` span.
-///
-/// NOTE: some errors may cause panics instead of returning `LexError`. We
-/// reserve the right to change these errors into `LexError`s later.
-impl FromStr for Literal {
-    type Err = LexError;
-
-    fn from_str(src: &str) -> Result<Self, LexError> {
-        match bridge::client::Literal::from_str(src) {
-            Ok(literal) => Ok(Literal(literal)),
-            Err(()) => Err(LexError),
-        }
-    }
-}
-
-/// Prints the literal as a string that should be losslessly convertible
-/// back into the same literal (except for possible rounding for floating point literals).
-impl fmt::Display for Literal {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&self.to_string())
-    }
-}
-
-impl fmt::Debug for Literal {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0.fmt(f)
-    }
-}
-
-/// Tracked access to environment variables.
-pub mod tracked_env {
-    use std::env::{self, VarError};
-    use std::ffi::OsStr;
-
-    /// Retrieve an environment variable and add it to build dependency info.
-    /// Build system executing the compiler will know that the variable was accessed during
-    /// compilation, and will be able to rerun the build when the value of that variable changes.
-    /// Besides the dependency tracking this function should be equivalent to `env::var` from the
-    /// standard library, except that the argument must be UTF-8.
-    pub fn var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
-        let key: &str = key.as_ref();
-        let value = env::var(key);
-        super::bridge::client::FreeFunctions::track_env_var(key, value.as_deref().ok());
-        value
-    }
-}
-
-/// Tracked access to additional files.
-pub mod tracked_path {
-
-    /// Track a file explicitly.
-    ///
-    /// Commonly used for tracking asset preprocessing.
-    pub fn path<P: AsRef<str>>(path: P) {
-        let path: &str = path.as_ref();
-        super::bridge::client::FreeFunctions::track_path(path);
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs b/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs
deleted file mode 100644
index 39309faa41213..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/proc_macro/quote.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-//! # Quasiquoter
-//! This file contains the implementation internals of the quasiquoter provided by `quote!`.
-
-//! This quasiquoter uses macros 2.0 hygiene to reliably access
-//! items from `proc_macro`, to build a `proc_macro::TokenStream`.
-
-use super::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
-
-macro_rules! quote_tt {
-    (($($t:tt)*)) => { Group::new(Delimiter::Parenthesis, quote!($($t)*)) };
-    ([$($t:tt)*]) => { Group::new(Delimiter::Bracket, quote!($($t)*)) };
-    ({$($t:tt)*}) => { Group::new(Delimiter::Brace, quote!($($t)*)) };
-    (,) => { Punct::new(',', Spacing::Alone) };
-    (.) => { Punct::new('.', Spacing::Alone) };
-    (;) => { Punct::new(';', Spacing::Alone) };
-    (!) => { Punct::new('!', Spacing::Alone) };
-    (<) => { Punct::new('<', Spacing::Alone) };
-    (>) => { Punct::new('>', Spacing::Alone) };
-    (&) => { Punct::new('&', Spacing::Alone) };
-    (=) => { Punct::new('=', Spacing::Alone) };
-    ($i:ident) => { Ident::new(stringify!($i), Span::def_site()) };
-}
-
-macro_rules! quote_ts {
-    ((@ $($t:tt)*)) => { $($t)* };
-    (::) => {
-        [
-            TokenTree::from(Punct::new(':', Spacing::Joint)),
-            TokenTree::from(Punct::new(':', Spacing::Alone)),
-        ].iter()
-            .cloned()
-            .map(|mut x| {
-                x.set_span(Span::def_site());
-                x
-            })
-            .collect::<TokenStream>()
-    };
-    ($t:tt) => { TokenTree::from(quote_tt!($t)) };
-}
-
-/// Simpler version of the real `quote!` macro, implemented solely
-/// through `macro_rules`, for bootstrapping the real implementation
-/// (see the `quote` function), which does not have access to the
-/// real `quote!` macro due to the `proc_macro` crate not being
-/// able to depend on itself.
-///
-/// Note: supported tokens are a subset of the real `quote!`, but
-/// unquoting is different: instead of `$x`, this uses `(@ expr)`.
-macro_rules! quote {
-    () => { TokenStream::new() };
-    ($($t:tt)*) => {
-        [
-            $(TokenStream::from(quote_ts!($t)),)*
-        ].iter().cloned().collect::<TokenStream>()
-    };
-}
-
-/// Quote a `TokenStream` into a `TokenStream`.
-/// This is the actual implementation of the `quote!()` proc macro.
-///
-/// It is loaded by the compiler in `register_builtin_macros`.
-pub fn quote(stream: TokenStream) -> TokenStream {
-    if stream.is_empty() {
-        return quote!(super::TokenStream::new());
-    }
-    let proc_macro_crate = quote!(crate);
-    let mut after_dollar = false;
-    let tokens = stream
-        .into_iter()
-        .filter_map(|tree| {
-            if after_dollar {
-                after_dollar = false;
-                match tree {
-                    TokenTree::Ident(_) => {
-                        return Some(quote!(Into::<super::TokenStream>::into(
-                        Clone::clone(&(@ tree))),));
-                    }
-                    TokenTree::Punct(ref tt) if tt.as_char() == '$' => {}
-                    _ => panic!("`$` must be followed by an ident or `$` in `quote!`"),
-                }
-            } else if let TokenTree::Punct(ref tt) = tree {
-                if tt.as_char() == '$' {
-                    after_dollar = true;
-                    return None;
-                }
-            }
-
-            Some(quote!(super::TokenStream::from((@ match tree {
-                TokenTree::Punct(tt) => quote!(super::TokenTree::Punct(super::Punct::new(
-                    (@ TokenTree::from(Literal::character(tt.as_char()))),
-                    (@ match tt.spacing() {
-                        Spacing::Alone => quote!(super::Spacing::Alone),
-                        Spacing::Joint => quote!(super::Spacing::Joint),
-                    }),
-                ))),
-                TokenTree::Group(tt) => quote!(super::TokenTree::Group(super::Group::new(
-                    (@ match tt.delimiter() {
-                        Delimiter::Parenthesis => quote!(super::Delimiter::Parenthesis),
-                        Delimiter::Brace => quote!(super::Delimiter::Brace),
-                        Delimiter::Bracket => quote!(super::Delimiter::Bracket),
-                        Delimiter::None => quote!(super::Delimiter::None),
-                    }),
-                    (@ quote(tt.stream())),
-                ))),
-                TokenTree::Ident(tt) => quote!(super::TokenTree::Ident(super::Ident::new(
-                    (@ TokenTree::from(Literal::string(&tt.to_string()))),
-                    (@ quote_span(proc_macro_crate.clone(), tt.span())),
-                ))),
-                TokenTree::Literal(tt) => quote!(super::TokenTree::Literal({
-                    let mut iter = (@ TokenTree::from(Literal::string(&tt.to_string())))
-                        .parse::<super::TokenStream>()
-                        .unwrap()
-                        .into_iter();
-                    if let (Some(super::TokenTree::Literal(mut lit)), None) =
-                        (iter.next(), iter.next())
-                    {
-                        lit.set_span((@ quote_span(proc_macro_crate.clone(), tt.span())));
-                        lit
-                    } else {
-                        unreachable!()
-                    }
-                }))
-            })),))
-        })
-        .collect::<TokenStream>();
-
-    if after_dollar {
-        panic!("unexpected trailing `$` in `quote!`");
-    }
-
-    quote!([(@ tokens)].iter().cloned().collect::<super::TokenStream>())
-}
-
-/// Quote a `Span` into a `TokenStream`.
-/// This is needed to implement a custom quoter.
-pub fn quote_span(proc_macro_crate: TokenStream, span: Span) -> TokenStream {
-    let id = span.save_span();
-    quote!((@ proc_macro_crate ) ::Span::recover_proc_macro_span((@ TokenTree::from(Literal::usize_unsuffixed(id)))))
-}
diff --git a/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs
deleted file mode 100644
index d8aa1ec429a7d..0000000000000
--- a/crates/proc-macro-srv/src/abis/abi_1_64/ra_server.rs
+++ /dev/null
@@ -1,791 +0,0 @@
-//! Rustc proc-macro server implementation with tt
-//!
-//! Based on idea from <https://github.com/fedochet/rust-proc-macro-expander>
-//! The lib-proc-macro server backend is `TokenStream`-agnostic, such that
-//! we could provide any TokenStream implementation.
-//! The original idea from fedochet is using proc-macro2 as backend,
-//! we use tt instead for better integration with RA.
-//!
-//! FIXME: No span and source file information is implemented yet
-
-use super::proc_macro::bridge::{self, server};
-
-use std::collections::HashMap;
-use std::hash::Hash;
-use std::ops::Bound;
-use std::{ascii, vec::IntoIter};
-
-type Group = tt::Subtree;
-type TokenTree = tt::TokenTree;
-type Punct = tt::Punct;
-type Spacing = tt::Spacing;
-type Literal = tt::Literal;
-type Span = tt::TokenId;
-
-#[derive(Debug, Default, Clone)]
-pub struct TokenStream {
-    pub token_trees: Vec<TokenTree>,
-}
-
-impl TokenStream {
-    pub fn new() -> Self {
-        TokenStream::default()
-    }
-
-    pub fn with_subtree(subtree: tt::Subtree) -> Self {
-        if subtree.delimiter.is_some() {
-            TokenStream { token_trees: vec![TokenTree::Subtree(subtree)] }
-        } else {
-            TokenStream { token_trees: subtree.token_trees }
-        }
-    }
-
-    pub fn into_subtree(self) -> tt::Subtree {
-        tt::Subtree { delimiter: None, token_trees: self.token_trees }
-    }
-
-    pub fn is_empty(&self) -> bool {
-        self.token_trees.is_empty()
-    }
-}
-
-/// Creates a token stream containing a single token tree.
-impl From<TokenTree> for TokenStream {
-    fn from(tree: TokenTree) -> TokenStream {
-        TokenStream { token_trees: vec![tree] }
-    }
-}
-
-/// Collects a number of token trees into a single stream.
-impl FromIterator<TokenTree> for TokenStream {
-    fn from_iter<I: IntoIterator<Item = TokenTree>>(trees: I) -> Self {
-        trees.into_iter().map(TokenStream::from).collect()
-    }
-}
-
-/// A "flattening" operation on token streams, collects token trees
-/// from multiple token streams into a single stream.
-impl FromIterator<TokenStream> for TokenStream {
-    fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
-        let mut builder = TokenStreamBuilder::new();
-        streams.into_iter().for_each(|stream| builder.push(stream));
-        builder.build()
-    }
-}
-
-impl Extend<TokenTree> for TokenStream {
-    fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, trees: I) {
-        self.extend(trees.into_iter().map(TokenStream::from));
-    }
-}
-
-impl Extend<TokenStream> for TokenStream {
-    fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
-        for item in streams {
-            for tkn in item {
-                match tkn {
-                    tt::TokenTree::Subtree(subtree) if subtree.delimiter.is_none() => {
-                        self.token_trees.extend(subtree.token_trees);
-                    }
-                    _ => {
-                        self.token_trees.push(tkn);
-                    }
-                }
-            }
-        }
-    }
-}
-
-#[derive(Clone)]
-pub struct SourceFile {
-    // FIXME stub
-}
-
-type Level = super::proc_macro::Level;
-type LineColumn = super::proc_macro::LineColumn;
-
-/// A structure representing a diagnostic message and associated children
-/// messages.
-#[derive(Clone, Debug)]
-pub struct Diagnostic {
-    level: Level,
-    message: String,
-    spans: Vec<Span>,
-    children: Vec<Diagnostic>,
-}
-
-impl Diagnostic {
-    /// Creates a new diagnostic with the given `level` and `message`.
-    pub fn new<T: Into<String>>(level: Level, message: T) -> Diagnostic {
-        Diagnostic { level, message: message.into(), spans: vec![], children: vec![] }
-    }
-}
-
-// Rustc Server Ident has to be `Copyable`
-// We use a stub here for bypassing
-#[derive(Hash, Eq, PartialEq, Copy, Clone)]
-pub struct IdentId(u32);
-
-#[derive(Clone, Hash, Eq, PartialEq)]
-struct IdentData(tt::Ident);
-
-#[derive(Default)]
-struct IdentInterner {
-    idents: HashMap<IdentData, u32>,
-    ident_data: Vec<IdentData>,
-}
-
-impl IdentInterner {
-    fn intern(&mut self, data: &IdentData) -> u32 {
-        if let Some(index) = self.idents.get(data) {
-            return *index;
-        }
-
-        let index = self.idents.len() as u32;
-        self.ident_data.push(data.clone());
-        self.idents.insert(data.clone(), index);
-        index
-    }
-
-    fn get(&self, index: u32) -> &IdentData {
-        &self.ident_data[index as usize]
-    }
-
-    #[allow(unused)]
-    fn get_mut(&mut self, index: u32) -> &mut IdentData {
-        self.ident_data.get_mut(index as usize).expect("Should be consistent")
-    }
-}
-
-pub struct TokenStreamBuilder {
-    acc: TokenStream,
-}
-
-/// Public implementation details for the `TokenStream` type, such as iterators.
-pub mod token_stream {
-    use std::str::FromStr;
-
-    use super::{TokenStream, TokenTree};
-
-    /// An iterator over `TokenStream`'s `TokenTree`s.
-    /// The iteration is "shallow", e.g., the iterator doesn't recurse into delimited groups,
-    /// and returns whole groups as token trees.
-    impl IntoIterator for TokenStream {
-        type Item = TokenTree;
-        type IntoIter = super::IntoIter<TokenTree>;
-
-        fn into_iter(self) -> Self::IntoIter {
-            self.token_trees.into_iter()
-        }
-    }
-
-    type LexError = String;
-
-    /// Attempts to break the string into tokens and parse those tokens into a token stream.
-    /// May fail for a number of reasons, for example, if the string contains unbalanced delimiters
-    /// or characters not existing in the language.
-    /// All tokens in the parsed stream get `Span::call_site()` spans.
-    ///
-    /// NOTE: some errors may cause panics instead of returning `LexError`. We reserve the right to
-    /// change these errors into `LexError`s later.
-    impl FromStr for TokenStream {
-        type Err = LexError;
-
-        fn from_str(src: &str) -> Result<TokenStream, LexError> {
-            let (subtree, _token_map) =
-                mbe::parse_to_token_tree(src).ok_or("Failed to parse from mbe")?;
-
-            let subtree = subtree_replace_token_ids_with_unspecified(subtree);
-            Ok(TokenStream::with_subtree(subtree))
-        }
-    }
-
-    impl ToString for TokenStream {
-        fn to_string(&self) -> String {
-            tt::pretty(&self.token_trees)
-        }
-    }
-
-    fn subtree_replace_token_ids_with_unspecified(subtree: tt::Subtree) -> tt::Subtree {
-        tt::Subtree {
-            delimiter: subtree
-                .delimiter
-                .map(|d| tt::Delimiter { id: tt::TokenId::unspecified(), ..d }),
-            token_trees: subtree
-                .token_trees
-                .into_iter()
-                .map(token_tree_replace_token_ids_with_unspecified)
-                .collect(),
-        }
-    }
-
-    fn token_tree_replace_token_ids_with_unspecified(tt: tt::TokenTree) -> tt::TokenTree {
-        match tt {
-            tt::TokenTree::Leaf(leaf) => {
-                tt::TokenTree::Leaf(leaf_replace_token_ids_with_unspecified(leaf))
-            }
-            tt::TokenTree::Subtree(subtree) => {
-                tt::TokenTree::Subtree(subtree_replace_token_ids_with_unspecified(subtree))
-            }
-        }
-    }
-
-    fn leaf_replace_token_ids_with_unspecified(leaf: tt::Leaf) -> tt::Leaf {
-        match leaf {
-            tt::Leaf::Literal(lit) => {
-                tt::Leaf::Literal(tt::Literal { id: tt::TokenId::unspecified(), ..lit })
-            }
-            tt::Leaf::Punct(punct) => {
-                tt::Leaf::Punct(tt::Punct { id: tt::TokenId::unspecified(), ..punct })
-            }
-            tt::Leaf::Ident(ident) => {
-                tt::Leaf::Ident(tt::Ident { id: tt::TokenId::unspecified(), ..ident })
-            }
-        }
-    }
-}
-
-impl TokenStreamBuilder {
-    fn new() -> TokenStreamBuilder {
-        TokenStreamBuilder { acc: TokenStream::new() }
-    }
-
-    fn push(&mut self, stream: TokenStream) {
-        self.acc.extend(stream.into_iter())
-    }
-
-    fn build(self) -> TokenStream {
-        self.acc
-    }
-}
-
-pub struct FreeFunctions;
-
-#[derive(Clone)]
-pub struct TokenStreamIter {
-    trees: IntoIter<TokenTree>,
-}
-
-#[derive(Default)]
-pub struct RustAnalyzer {
-    ident_interner: IdentInterner,
-    // FIXME: store span information here.
-}
-
-impl server::Types for RustAnalyzer {
-    type FreeFunctions = FreeFunctions;
-    type TokenStream = TokenStream;
-    type Ident = IdentId;
-    type Literal = Literal;
-    type SourceFile = SourceFile;
-    type Diagnostic = Diagnostic;
-    type Span = Span;
-    type MultiSpan = Vec<Span>;
-}
-
-impl server::FreeFunctions for RustAnalyzer {
-    fn track_env_var(&mut self, _var: &str, _value: Option<&str>) {
-        // FIXME: track env var accesses
-        // https://github.com/rust-lang/rust/pull/71858
-    }
-    fn track_path(&mut self, _path: &str) {}
-}
-
-impl server::TokenStream for RustAnalyzer {
-    fn is_empty(&mut self, stream: &Self::TokenStream) -> bool {
-        stream.is_empty()
-    }
-    fn from_str(&mut self, src: &str) -> Self::TokenStream {
-        use std::str::FromStr;
-
-        Self::TokenStream::from_str(src).expect("cannot parse string")
-    }
-    fn to_string(&mut self, stream: &Self::TokenStream) -> String {
-        stream.to_string()
-    }
-    fn from_token_tree(
-        &mut self,
-        tree: bridge::TokenTree<Self::TokenStream, Self::Span, Self::Ident, Self::Literal>,
-    ) -> Self::TokenStream {
-        match tree {
-            bridge::TokenTree::Group(group) => {
-                let group = Group {
-                    delimiter: delim_to_internal(group.delimiter),
-                    token_trees: match group.stream {
-                        Some(stream) => stream.into_iter().collect(),
-                        None => Vec::new(),
-                    },
-                };
-                let tree = TokenTree::from(group);
-                Self::TokenStream::from_iter(vec![tree])
-            }
-
-            bridge::TokenTree::Ident(IdentId(index)) => {
-                let IdentData(ident) = self.ident_interner.get(index).clone();
-                let ident: tt::Ident = ident;
-                let leaf = tt::Leaf::from(ident);
-                let tree = TokenTree::from(leaf);
-                Self::TokenStream::from_iter(vec![tree])
-            }
-
-            bridge::TokenTree::Literal(literal) => {
-                let leaf = tt::Leaf::from(literal);
-                let tree = TokenTree::from(leaf);
-                Self::TokenStream::from_iter(vec![tree])
-            }
-
-            bridge::TokenTree::Punct(p) => {
-                let punct = tt::Punct {
-                    char: p.ch as char,
-                    spacing: if p.joint { Spacing::Joint } else { Spacing::Alone },
-                    id: p.span,
-                };
-                let leaf = tt::Leaf::from(punct);
-                let tree = TokenTree::from(leaf);
-                Self::TokenStream::from_iter(vec![tree])
-            }
-        }
-    }
-
-    fn expand_expr(&mut self, self_: &Self::TokenStream) -> Result<Self::TokenStream, ()> {
-        Ok(self_.clone())
-    }
-
-    fn concat_trees(
-        &mut self,
-        base: Option<Self::TokenStream>,
-        trees: Vec<bridge::TokenTree<Self::TokenStream, Self::Span, Self::Ident, Self::Literal>>,
-    ) -> Self::TokenStream {
-        let mut builder = TokenStreamBuilder::new();
-        if let Some(base) = base {
-            builder.push(base);
-        }
-        for tree in trees {
-            builder.push(self.from_token_tree(tree));
-        }
-        builder.build()
-    }
-
-    fn concat_streams(
-        &mut self,
-        base: Option<Self::TokenStream>,
-        streams: Vec<Self::TokenStream>,
-    ) -> Self::TokenStream {
-        let mut builder = TokenStreamBuilder::new();
-        if let Some(base) = base {
-            builder.push(base);
-        }
-        for stream in streams {
-            builder.push(stream);
-        }
-        builder.build()
-    }
-
-    fn into_trees(
-        &mut self,
-        stream: Self::TokenStream,
-    ) -> Vec<bridge::TokenTree<Self::TokenStream, Self::Span, Self::Ident, Self::Literal>> {
-        stream
-            .into_iter()
-            .map(|tree| match tree {
-                tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
-                    bridge::TokenTree::Ident(IdentId(self.ident_interner.intern(&IdentData(ident))))
-                }
-                tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => bridge::TokenTree::Literal(lit),
-                tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) => {
-                    bridge::TokenTree::Punct(bridge::Punct {
-                        ch: punct.char as u8,
-                        joint: punct.spacing == Spacing::Joint,
-                        span: punct.id,
-                    })
-                }
-                tt::TokenTree::Subtree(subtree) => bridge::TokenTree::Group(bridge::Group {
-                    delimiter: delim_to_external(subtree.delimiter),
-                    stream: if subtree.token_trees.is_empty() {
-                        None
-                    } else {
-                        Some(subtree.token_trees.into_iter().collect())
-                    },
-                    span: bridge::DelimSpan::from_single(
-                        subtree.delimiter.map_or(Span::unspecified(), |del| del.id),
-                    ),
-                }),
-            })
-            .collect()
-    }
-}
-
-fn delim_to_internal(d: bridge::Delimiter) -> Option<tt::Delimiter> {
-    let kind = match d {
-        bridge::Delimiter::Parenthesis => tt::DelimiterKind::Parenthesis,
-        bridge::Delimiter::Brace => tt::DelimiterKind::Brace,
-        bridge::Delimiter::Bracket => tt::DelimiterKind::Bracket,
-        bridge::Delimiter::None => return None,
-    };
-    Some(tt::Delimiter { id: tt::TokenId::unspecified(), kind })
-}
-
-fn delim_to_external(d: Option<tt::Delimiter>) -> bridge::Delimiter {
-    match d.map(|it| it.kind) {
-        Some(tt::DelimiterKind::Parenthesis) => bridge::Delimiter::Parenthesis,
-        Some(tt::DelimiterKind::Brace) => bridge::Delimiter::Brace,
-        Some(tt::DelimiterKind::Bracket) => bridge::Delimiter::Bracket,
-        None => bridge::Delimiter::None,
-    }
-}
-
-fn spacing_to_internal(spacing: bridge::Spacing) -> Spacing {
-    match spacing {
-        bridge::Spacing::Alone => Spacing::Alone,
-        bridge::Spacing::Joint => Spacing::Joint,
-    }
-}
-
-fn spacing_to_external(spacing: Spacing) -> bridge::Spacing {
-    match spacing {
-        Spacing::Alone => bridge::Spacing::Alone,
-        Spacing::Joint => bridge::Spacing::Joint,
-    }
-}
-
-impl server::Ident for RustAnalyzer {
-    fn new(&mut self, string: &str, span: Self::Span, _is_raw: bool) -> Self::Ident {
-        IdentId(self.ident_interner.intern(&IdentData(tt::Ident { text: string.into(), id: span })))
-    }
-
-    fn span(&mut self, ident: Self::Ident) -> Self::Span {
-        self.ident_interner.get(ident.0).0.id
-    }
-    fn with_span(&mut self, ident: Self::Ident, span: Self::Span) -> Self::Ident {
-        let data = self.ident_interner.get(ident.0);
-        let new = IdentData(tt::Ident { id: span, ..data.0.clone() });
-        IdentId(self.ident_interner.intern(&new))
-    }
-}
-
-impl server::Literal for RustAnalyzer {
-    fn debug_kind(&mut self, _literal: &Self::Literal) -> String {
-        // r-a: debug_kind and suffix are unsupported; corresponding client code has been changed to not call these.
-        // They must still be present to be ABI-compatible and work with upstream proc_macro.
-        "".to_owned()
-    }
-    fn from_str(&mut self, s: &str) -> Result<Self::Literal, ()> {
-        Ok(Literal { text: s.into(), id: tt::TokenId::unspecified() })
-    }
-    fn symbol(&mut self, literal: &Self::Literal) -> String {
-        literal.text.to_string()
-    }
-    fn suffix(&mut self, _literal: &Self::Literal) -> Option<String> {
-        None
-    }
-
-    fn to_string(&mut self, literal: &Self::Literal) -> String {
-        literal.to_string()
-    }
-
-    fn integer(&mut self, n: &str) -> Self::Literal {
-        let n = match n.parse::<i128>() {
-            Ok(n) => n.to_string(),
-            Err(_) => n.parse::<u128>().unwrap().to_string(),
-        };
-        Literal { text: n.into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn typed_integer(&mut self, n: &str, kind: &str) -> Self::Literal {
-        macro_rules! def_suffixed_integer {
-            ($kind:ident, $($ty:ty),*) => {
-                match $kind {
-                    $(
-                        stringify!($ty) => {
-                            let n: $ty = n.parse().unwrap();
-                            format!(concat!("{}", stringify!($ty)), n)
-                        }
-                    )*
-                    _ => unimplemented!("unknown args for typed_integer: n {}, kind {}", n, $kind),
-                }
-            }
-        }
-
-        let text = def_suffixed_integer! {kind, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize};
-
-        Literal { text: text.into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn float(&mut self, n: &str) -> Self::Literal {
-        let n: f64 = n.parse().unwrap();
-        let mut text = f64::to_string(&n);
-        if !text.contains('.') {
-            text += ".0"
-        }
-        Literal { text: text.into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn f32(&mut self, n: &str) -> Self::Literal {
-        let n: f32 = n.parse().unwrap();
-        let text = format!("{}f32", n);
-        Literal { text: text.into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn f64(&mut self, n: &str) -> Self::Literal {
-        let n: f64 = n.parse().unwrap();
-        let text = format!("{}f64", n);
-        Literal { text: text.into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn string(&mut self, string: &str) -> Self::Literal {
-        let mut escaped = String::new();
-        for ch in string.chars() {
-            escaped.extend(ch.escape_debug());
-        }
-        Literal { text: format!("\"{}\"", escaped).into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn character(&mut self, ch: char) -> Self::Literal {
-        Literal { text: format!("'{}'", ch).into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn byte_string(&mut self, bytes: &[u8]) -> Self::Literal {
-        let string = bytes
-            .iter()
-            .cloned()
-            .flat_map(ascii::escape_default)
-            .map(Into::<char>::into)
-            .collect::<String>();
-
-        Literal { text: format!("b\"{}\"", string).into(), id: tt::TokenId::unspecified() }
-    }
-
-    fn span(&mut self, literal: &Self::Literal) -> Self::Span {
-        literal.id
-    }
-
-    fn set_span(&mut self, literal: &mut Self::Literal, span: Self::Span) {
-        literal.id = span;
-    }
-
-    fn subspan(
-        &mut self,
-        _literal: &Self::Literal,
-        _start: Bound<usize>,
-        _end: Bound<usize>,
-    ) -> Option<Self::Span> {
-        // FIXME handle span
-        None
-    }
-}
-
-impl server::SourceFile for RustAnalyzer {
-    // FIXME these are all stubs
-    fn eq(&mut self, _file1: &Self::SourceFile, _file2: &Self::SourceFile) -> bool {
-        true
-    }
-    fn path(&mut self, _file: &Self::SourceFile) -> String {
-        String::new()
-    }
-    fn is_real(&mut self, _file: &Self::SourceFile) -> bool {
-        true
-    }
-}
-
-impl server::Diagnostic for RustAnalyzer {
-    fn new(&mut self, level: Level, msg: &str, spans: Self::MultiSpan) -> Self::Diagnostic {
-        let mut diag = Diagnostic::new(level, msg);
-        diag.spans = spans;
-        diag
-    }
-
-    fn sub(
-        &mut self,
-        _diag: &mut Self::Diagnostic,
-        _level: Level,
-        _msg: &str,
-        _spans: Self::MultiSpan,
-    ) {
-        // FIXME handle diagnostic
-        //
-    }
-
-    fn emit(&mut self, _diag: Self::Diagnostic) {
-        // FIXME handle diagnostic
-        // diag.emit()
-    }
-}
-
-impl server::Span for RustAnalyzer {
-    fn debug(&mut self, span: Self::Span) -> String {
-        format!("{:?}", span.0)
-    }
-    fn source_file(&mut self, _span: Self::Span) -> Self::SourceFile {
-        SourceFile {}
-    }
-    fn save_span(&mut self, _span: Self::Span) -> usize {
-        // FIXME stub
-        0
-    }
-    fn recover_proc_macro_span(&mut self, _id: usize) -> Self::Span {
-        // FIXME stub
-        tt::TokenId::unspecified()
-    }
-    /// Recent feature, not yet in the proc_macro
-    ///
-    /// See PR:
-    /// https://github.com/rust-lang/rust/pull/55780
-    fn source_text(&mut self, _span: Self::Span) -> Option<String> {
-        None
-    }
-
-    fn parent(&mut self, _span: Self::Span) -> Option<Self::Span> {
-        // FIXME handle span
-        None
-    }
-    fn source(&mut self, span: Self::Span) -> Self::Span {
-        // FIXME handle span
-        span
-    }
-    fn start(&mut self, _span: Self::Span) -> LineColumn {
-        // FIXME handle span
-        LineColumn { line: 0, column: 0 }
-    }
-    fn end(&mut self, _span: Self::Span) -> LineColumn {
-        // FIXME handle span
-        LineColumn { line: 0, column: 0 }
-    }
-    fn join(&mut self, first: Self::Span, _second: Self::Span) -> Option<Self::Span> {
-        // Just return the first span again, because some macros will unwrap the result.
-        Some(first)
-    }
-    fn resolved_at(&mut self, _span: Self::Span, _at: Self::Span) -> Self::Span {
-        // FIXME handle span
-        tt::TokenId::unspecified()
-    }
-
-    fn after(&mut self, _self_: Self::Span) -> Self::Span {
-        tt::TokenId::unspecified()
-    }
-
-    fn before(&mut self, _self_: Self::Span) -> Self::Span {
-        tt::TokenId::unspecified()
-    }
-}
-
-impl server::MultiSpan for RustAnalyzer {
-    fn new(&mut self) -> Self::MultiSpan {
-        // FIXME handle span
-        vec![]
-    }
-
-    fn push(&mut self, other: &mut Self::MultiSpan, span: Self::Span) {
-        //TODP
-        other.push(span)
-    }
-}
-
-impl server::Server for RustAnalyzer {
-    fn globals(&mut self) -> bridge::ExpnGlobals<Self::Span> {
-        bridge::ExpnGlobals {
-            def_site: Span::unspecified(),
-            call_site: Span::unspecified(),
-            mixed_site: Span::unspecified(),
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::super::proc_macro::bridge::server::Literal;
-    use super::*;
-
-    #[test]
-    fn test_ra_server_literals() {
-        let mut srv = RustAnalyzer { ident_interner: IdentInterner::default() };
-        assert_eq!(srv.integer("1234").text, "1234");
-
-        assert_eq!(srv.typed_integer("12", "u8").text, "12u8");
-        assert_eq!(srv.typed_integer("255", "u16").text, "255u16");
-        assert_eq!(srv.typed_integer("1234", "u32").text, "1234u32");
-        assert_eq!(srv.typed_integer("15846685", "u64").text, "15846685u64");
-        assert_eq!(srv.typed_integer("15846685258", "u128").text, "15846685258u128");
-        assert_eq!(srv.typed_integer("156788984", "usize").text, "156788984usize");
-        assert_eq!(srv.typed_integer("127", "i8").text, "127i8");
-        assert_eq!(srv.typed_integer("255", "i16").text, "255i16");
-        assert_eq!(srv.typed_integer("1234", "i32").text, "1234i32");
-        assert_eq!(srv.typed_integer("15846685", "i64").text, "15846685i64");
-        assert_eq!(srv.typed_integer("15846685258", "i128").text, "15846685258i128");
-        assert_eq!(srv.float("0").text, "0.0");
-        assert_eq!(srv.float("15684.5867").text, "15684.5867");
-        assert_eq!(srv.f32("15684.58").text, "15684.58f32");
-        assert_eq!(srv.f64("15684.58").text, "15684.58f64");
-
-        assert_eq!(srv.string("hello_world").text, "\"hello_world\"");
-        assert_eq!(srv.character('c').text, "'c'");
-        assert_eq!(srv.byte_string(b"1234586\x88").text, "b\"1234586\\x88\"");
-
-        // u128::max
-        assert_eq!(
-            srv.integer("340282366920938463463374607431768211455").text,
-            "340282366920938463463374607431768211455"
-        );
-        // i128::min
-        assert_eq!(
-            srv.integer("-170141183460469231731687303715884105728").text,
-            "-170141183460469231731687303715884105728"
-        );
-    }
-
-    #[test]
-    fn test_ra_server_to_string() {
-        let s = TokenStream {
-            token_trees: vec![
-                tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
-                    text: "struct".into(),
-                    id: tt::TokenId::unspecified(),
-                })),
-                tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
-                    text: "T".into(),
-                    id: tt::TokenId::unspecified(),
-                })),
-                tt::TokenTree::Subtree(tt::Subtree {
-                    delimiter: Some(tt::Delimiter {
-                        id: tt::TokenId::unspecified(),
-                        kind: tt::DelimiterKind::Brace,
-                    }),
-                    token_trees: vec![],
-                }),
-            ],
-        };
-
-        assert_eq!(s.to_string(), "struct T {}");
-    }
-
-    #[test]
-    fn test_ra_server_from_str() {
-        use std::str::FromStr;
-        let subtree_paren_a = tt::TokenTree::Subtree(tt::Subtree {
-            delimiter: Some(tt::Delimiter {
-                id: tt::TokenId::unspecified(),
-                kind: tt::DelimiterKind::Parenthesis,
-            }),
-            token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
-                text: "a".into(),
-                id: tt::TokenId::unspecified(),
-            }))],
-        });
-
-        let t1 = TokenStream::from_str("(a)").unwrap();
-        assert_eq!(t1.token_trees.len(), 1);
-        assert_eq!(t1.token_trees[0], subtree_paren_a);
-
-        let t2 = TokenStream::from_str("(a);").unwrap();
-        assert_eq!(t2.token_trees.len(), 2);
-        assert_eq!(t2.token_trees[0], subtree_paren_a);
-
-        let underscore = TokenStream::from_str("_").unwrap();
-        assert_eq!(
-            underscore.token_trees[0],
-            tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
-                text: "_".into(),
-                id: tt::TokenId::unspecified(),
-            }))
-        );
-    }
-}
diff --git a/crates/proc-macro-srv/src/abis/mod.rs b/crates/proc-macro-srv/src/abis/mod.rs
index 705d09ea9458b..f7d3a30919e1c 100644
--- a/crates/proc-macro-srv/src/abis/mod.rs
+++ b/crates/proc-macro-srv/src/abis/mod.rs
@@ -25,7 +25,6 @@
 
 mod abi_1_58;
 mod abi_1_63;
-mod abi_1_64;
 #[cfg(feature = "sysroot-abi")]
 mod abi_sysroot;
 
@@ -34,12 +33,11 @@ include!(concat!(env!("OUT_DIR"), "/rustc_version.rs"));
 
 // Used by `test/utils.rs`
 #[cfg(test)]
-pub(crate) use abi_1_64::TokenStream as TestTokenStream;
+pub(crate) use abi_1_63::TokenStream as TestTokenStream;
 
 use super::dylib::LoadProcMacroDylibError;
 pub(crate) use abi_1_58::Abi as Abi_1_58;
 pub(crate) use abi_1_63::Abi as Abi_1_63;
-pub(crate) use abi_1_64::Abi as Abi_1_64;
 #[cfg(feature = "sysroot-abi")]
 pub(crate) use abi_sysroot::Abi as Abi_Sysroot;
 use libloading::Library;
@@ -58,7 +56,6 @@ impl PanicMessage {
 pub(crate) enum Abi {
     Abi1_58(Abi_1_58),
     Abi1_63(Abi_1_63),
-    Abi1_64(Abi_1_64),
     #[cfg(feature = "sysroot-abi")]
     AbiSysroot(Abi_Sysroot),
 }
@@ -120,10 +117,6 @@ impl Abi {
                 let inner = unsafe { Abi_1_63::from_lib(lib, symbol_name) }?;
                 Ok(Abi::Abi1_63(inner))
             }
-            (1, 64..) => {
-                let inner = unsafe { Abi_1_64::from_lib(lib, symbol_name) }?;
-                Ok(Abi::Abi1_64(inner))
-            }
             _ => Err(LoadProcMacroDylibError::UnsupportedABI),
         }
     }
@@ -137,7 +130,6 @@ impl Abi {
         match self {
             Self::Abi1_58(abi) => abi.expand(macro_name, macro_body, attributes),
             Self::Abi1_63(abi) => abi.expand(macro_name, macro_body, attributes),
-            Self::Abi1_64(abi) => abi.expand(macro_name, macro_body, attributes),
             #[cfg(feature = "sysroot-abi")]
             Self::AbiSysroot(abi) => abi.expand(macro_name, macro_body, attributes),
         }
@@ -147,7 +139,6 @@ impl Abi {
         match self {
             Self::Abi1_58(abi) => abi.list_macros(),
             Self::Abi1_63(abi) => abi.list_macros(),
-            Self::Abi1_64(abi) => abi.list_macros(),
             #[cfg(feature = "sysroot-abi")]
             Self::AbiSysroot(abi) => abi.list_macros(),
         }

From 25d4fbe9dae2b875ebfa81a28e10796475def74b Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Wed, 10 Aug 2022 10:23:46 +0200
Subject: [PATCH 22/39] Re-try build script building with --keep-going

---
 crates/project-model/src/build_scripts.rs | 33 ++++++++++++++++-------
 1 file changed, 23 insertions(+), 10 deletions(-)

diff --git a/crates/project-model/src/build_scripts.rs b/crates/project-model/src/build_scripts.rs
index 4b00479a4c9c2..84e772d1684a1 100644
--- a/crates/project-model/src/build_scripts.rs
+++ b/crates/project-model/src/build_scripts.rs
@@ -39,7 +39,7 @@ pub(crate) struct BuildScriptOutput {
 }
 
 impl WorkspaceBuildScripts {
-    fn build_command(config: &CargoConfig, toolchain: &Option<Version>) -> Command {
+    fn build_command(config: &CargoConfig) -> Command {
         if let Some([program, args @ ..]) = config.run_build_script_command.as_deref() {
             let mut cmd = Command::new(program);
             cmd.args(args);
@@ -71,26 +71,39 @@ impl WorkspaceBuildScripts {
             }
         }
 
+        cmd
+    }
+
+    pub(crate) fn run(
+        config: &CargoConfig,
+        workspace: &CargoWorkspace,
+        progress: &dyn Fn(String),
+        toolchain: &Option<Version>,
+    ) -> io::Result<WorkspaceBuildScripts> {
         const RUST_1_62: Version = Version::new(1, 62, 0);
 
-        match toolchain {
-            Some(v) if v >= &RUST_1_62 => {
+        match Self::run_(Self::build_command(config), config, workspace, progress) {
+            Ok(WorkspaceBuildScripts { error: Some(error), .. })
+                if toolchain.as_ref().map_or(false, |it| *it >= RUST_1_62) =>
+            {
+                // building build scripts failed, attempt to build with --keep-going so
+                // that we potentially get more build data
+                let mut cmd = Self::build_command(config);
                 cmd.args(&["-Z", "unstable-options", "--keep-going"]).env("RUSTC_BOOTSTRAP", "1");
+                let mut res = Self::run_(cmd, config, workspace, progress)?;
+                res.error = Some(error);
+                Ok(res)
             }
-            _ => (),
+            res => res,
         }
-
-        cmd
     }
 
-    pub(crate) fn run(
+    fn run_(
+        mut cmd: Command,
         config: &CargoConfig,
         workspace: &CargoWorkspace,
         progress: &dyn Fn(String),
-        toolchain: &Option<Version>,
     ) -> io::Result<WorkspaceBuildScripts> {
-        let mut cmd = Self::build_command(config, toolchain);
-
         if config.wrap_rustc_in_build_scripts {
             // Setup RUSTC_WRAPPER to point to `rust-analyzer` binary itself. We use
             // that to compile only proc macros and build scripts during the initial

From 23e17cd5819a21731122b4dc4975170e0efc4ca2 Mon Sep 17 00:00:00 2001
From: Edwin Cheng <edwin0cheng@gmail.com>
Date: Wed, 10 Aug 2022 16:28:56 +0800
Subject: [PATCH 23/39] Improve insert whitespace in mbe

---
 crates/hir-expand/src/builtin_fn_macro.rs |  8 ++++++--
 crates/mbe/src/syntax_bridge.rs           | 11 +----------
 2 files changed, 7 insertions(+), 12 deletions(-)

diff --git a/crates/hir-expand/src/builtin_fn_macro.rs b/crates/hir-expand/src/builtin_fn_macro.rs
index c21b35cdc0917..8befa7f7da727 100644
--- a/crates/hir-expand/src/builtin_fn_macro.rs
+++ b/crates/hir-expand/src/builtin_fn_macro.rs
@@ -251,9 +251,13 @@ fn format_args_expand(
     }
     for arg in &mut args {
         // Remove `key =`.
-        if matches!(arg.token_trees.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' && p.spacing != tt::Spacing::Joint)
+        if matches!(arg.token_trees.get(1), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=')
         {
-            arg.token_trees.drain(..2);
+            // but not with `==`
+            if !matches!(arg.token_trees.get(2), Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p))) if p.char == '=' )
+            {
+                arg.token_trees.drain(..2);
+            }
         }
     }
     let _format_string = args.remove(0);
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index aca6ecd424e40..e4c56565b92d4 100644
--- a/crates/mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
@@ -228,16 +228,7 @@ fn convert_tokens<C: TokenConvertor>(conv: &mut C) -> tt::Subtree {
             }
 
             let spacing = match conv.peek().map(|next| next.kind(conv)) {
-                Some(kind)
-                    if !kind.is_trivia()
-                        && kind.is_punct()
-                        && kind != T!['[']
-                        && kind != T!['{']
-                        && kind != T!['(']
-                        && kind != UNDERSCORE =>
-                {
-                    tt::Spacing::Joint
-                }
+                Some(kind) if !kind.is_trivia() => tt::Spacing::Joint,
                 _ => tt::Spacing::Alone,
             };
             let char = match token.to_char(conv) {

From c47914c6cfbce6e99bdeb5b8183b9655673b1110 Mon Sep 17 00:00:00 2001
From: Edwin Cheng <edwin0cheng@gmail.com>
Date: Wed, 10 Aug 2022 16:29:23 +0800
Subject: [PATCH 24/39] Fixes tests

---
 crates/hir-def/src/macro_expansion_tests/mbe.rs    | 12 ++++++------
 .../src/macro_expansion_tests/mbe/regression.rs    |  4 ++--
 .../src/macro_expansion_tests/mbe/tt_conversion.rs |  2 +-
 .../src/macro_expansion_tests/proc_macros.rs       |  2 +-
 crates/hir-expand/src/fixup.rs                     | 14 +++++++-------
 .../src/handlers/add_missing_impl_members.rs       |  2 +-
 crates/proc-macro-srv/src/tests/mod.rs             |  6 +++---
 7 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/crates/hir-def/src/macro_expansion_tests/mbe.rs b/crates/hir-def/src/macro_expansion_tests/mbe.rs
index 30d39d52f385e..457e43925c635 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe.rs
@@ -885,7 +885,7 @@ macro_rules! m {
     ($t:ty) => ( fn bar() -> $ t {} )
 }
 
-fn bar() -> & 'a Baz<u8> {}
+fn bar() -> &'a Baz<u8> {}
 
 fn bar() -> extern "Rust"fn() -> Ret {}
 "#]],
@@ -1578,7 +1578,7 @@ macro_rules !register_methods {
             ($$($val: expr), *) = > {
                 struct Foo;
                 impl Foo {
-                    $(fn $method()-> & 'static[u32] {
+                    $(fn $method()-> &'static[u32] {
                         &[$$($$val), *]
                     }
                     )*
@@ -1591,10 +1591,10 @@ macro_rules !implement_methods {
     ($($val: expr), *) = > {
         struct Foo;
         impl Foo {
-            fn alpha()-> & 'static[u32] {
+            fn alpha()-> &'static[u32] {
                 &[$($val), *]
             }
-            fn beta()-> & 'static[u32] {
+            fn beta()-> &'static[u32] {
                 &[$($val), *]
             }
         }
@@ -1602,10 +1602,10 @@ macro_rules !implement_methods {
 }
 struct Foo;
 impl Foo {
-    fn alpha() -> & 'static[u32] {
+    fn alpha() -> &'static[u32] {
         &[1, 2, 3]
     }
-    fn beta() -> & 'static[u32] {
+    fn beta() -> &'static[u32] {
         &[1, 2, 3]
     }
 }
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
index 2dff4adf2ee80..d2505e7cafe53 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/regression.rs
@@ -166,7 +166,7 @@ macro_rules! int_base {
     }
 }
 #[stable(feature = "rust1", since = "1.0.0")] impl fmt::Binary for isize {
-    fn fmt(&self , f: &mut fmt::Formatter< '_>) -> fmt::Result {
+    fn fmt(&self , f: &mut fmt::Formatter<'_>) -> fmt::Result {
         Binary.fmt_int(*self as usize, f)
     }
 }
@@ -724,7 +724,7 @@ macro_rules! delegate_impl {
         }
     }
 }
-impl <> Data for & 'amut G where G: Data {}
+impl <> Data for &'amut G where G: Data {}
 "##]],
     );
 }
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs b/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
index 0710b1ac3d696..b8d2ca687c9e0 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/tt_conversion.rs
@@ -78,7 +78,7 @@ m!(static bar: &'static str = "hello";);
 macro_rules! m {
     ($($t:tt)*) => { $($t)*}
 }
-static bar: & 'static str = "hello";
+static bar: &'static str = "hello";
 "#]],
     );
 }
diff --git a/crates/hir-def/src/macro_expansion_tests/proc_macros.rs b/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
index 72c44a0fbcb21..029821e5e87f6 100644
--- a/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
+++ b/crates/hir-def/src/macro_expansion_tests/proc_macros.rs
@@ -87,7 +87,7 @@ fn foo() { bar.; blub }
 fn foo() { bar.; blub }
 
 fn foo() {
-    bar. ;
+    bar.;
     blub
 }"##]],
     );
diff --git a/crates/hir-expand/src/fixup.rs b/crates/hir-expand/src/fixup.rs
index 46257b6bc4dce..893e6fe4b8240 100644
--- a/crates/hir-expand/src/fixup.rs
+++ b/crates/hir-expand/src/fixup.rs
@@ -468,7 +468,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-fn foo () {a . __ra_fixup}
+fn foo () {a .__ra_fixup}
 "#]],
         )
     }
@@ -478,11 +478,11 @@ fn foo () {a . __ra_fixup}
         check(
             r#"
 fn foo() {
-    a. ;
+    a.;
 }
 "#,
             expect![[r#"
-fn foo () {a . __ra_fixup ;}
+fn foo () {a .__ra_fixup ;}
 "#]],
         )
     }
@@ -492,12 +492,12 @@ fn foo () {a . __ra_fixup ;}
         check(
             r#"
 fn foo() {
-    a. ;
+    a.;
     bar();
 }
 "#,
             expect![[r#"
-fn foo () {a . __ra_fixup ; bar () ;}
+fn foo () {a .__ra_fixup ; bar () ;}
 "#]],
         )
     }
@@ -525,7 +525,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-fn foo () {let x = a . __ra_fixup ;}
+fn foo () {let x = a .__ra_fixup ;}
 "#]],
         )
     }
@@ -541,7 +541,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-fn foo () {a . b ; bar () ;}
+fn foo () {a .b ; bar () ;}
 "#]],
         )
     }
diff --git a/crates/ide-assists/src/handlers/add_missing_impl_members.rs b/crates/ide-assists/src/handlers/add_missing_impl_members.rs
index c808c010c672e..62cf5ab4f37a1 100644
--- a/crates/ide-assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/ide-assists/src/handlers/add_missing_impl_members.rs
@@ -944,7 +944,7 @@ foo!();
 struct Foo(usize);
 
 impl FooB for Foo {
-    $0fn foo< 'lt>(& 'lt self){}
+    $0fn foo<'lt>(&'lt self){}
 }
 "#,
         )
diff --git a/crates/proc-macro-srv/src/tests/mod.rs b/crates/proc-macro-srv/src/tests/mod.rs
index 07222907f0880..6339d56d01791 100644
--- a/crates/proc-macro-srv/src/tests/mod.rs
+++ b/crates/proc-macro-srv/src/tests/mod.rs
@@ -19,7 +19,7 @@ fn test_derive_error() {
         expect![[r##"
             SUBTREE $
               IDENT   compile_error 4294967295
-              PUNCH   ! [alone] 4294967295
+              PUNCH   ! [joint] 4294967295
               SUBTREE () 4294967295
                 LITERAL "#[derive(DeriveError)] struct S ;" 4294967295
               PUNCH   ; [alone] 4294967295"##]],
@@ -109,7 +109,7 @@ fn test_fn_like_macro_clone_literals() {
               PUNCH   , [alone] 4294967295
               LITERAL 2_u32 4294967295
               PUNCH   , [alone] 4294967295
-              PUNCH   - [alone] 4294967295
+              PUNCH   - [joint] 4294967295
               LITERAL 4i64 4294967295
               PUNCH   , [alone] 4294967295
               LITERAL 3.14f32 4294967295
@@ -130,7 +130,7 @@ fn test_attr_macro() {
         expect![[r##"
             SUBTREE $
               IDENT   compile_error 4294967295
-              PUNCH   ! [alone] 4294967295
+              PUNCH   ! [joint] 4294967295
               SUBTREE () 4294967295
                 LITERAL "#[attr_error(some arguments)] mod m {}" 4294967295
               PUNCH   ; [alone] 4294967295"##]],

From ffc6b42901fc1f64c812df571110e665de75da45 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida <low.ryoshida@gmail.com>
Date: Wed, 10 Aug 2022 19:17:13 +0900
Subject: [PATCH 25/39] fix: infer byte string pattern as `&[u8]` when matched
 against slices

---
 crates/hir-ty/src/infer/pat.rs      | 33 ++++++++++++++++++---
 crates/hir-ty/src/tests/patterns.rs | 45 +++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+), 4 deletions(-)

diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs
index 5e7320a5dd305..53259d66dec64 100644
--- a/crates/hir-ty/src/infer/pat.rs
+++ b/crates/hir-ty/src/infer/pat.rs
@@ -14,8 +14,9 @@ use crate::{
     consteval::intern_const_scalar,
     infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
     lower::lower_to_chalk_mutability,
-    static_lifetime, ConcreteConst, ConstValue, Interner, Substitution, Ty, TyBuilder, TyExt,
-    TyKind,
+    primitive::UintTy,
+    static_lifetime, ConcreteConst, ConstValue, Interner, Scalar, Substitution, Ty, TyBuilder,
+    TyExt, TyKind,
 };
 
 use super::PatLike;
@@ -294,7 +295,29 @@ impl<'a> InferenceContext<'a> {
                 let start_ty = self.infer_expr(*start, &Expectation::has_type(expected.clone()));
                 self.infer_expr(*end, &Expectation::has_type(start_ty))
             }
-            Pat::Lit(expr) => self.infer_expr(*expr, &Expectation::has_type(expected.clone())),
+            &Pat::Lit(expr) => {
+                // FIXME: using `Option` here is a workaround until we can use if-let chains in stable.
+                let mut pat_ty = None;
+
+                // Like slice patterns, byte string patterns can denote both `&[u8; N]` and `&[u8]`.
+                if let Expr::Literal(Literal::ByteString(_)) = self.body[expr] {
+                    if let Some((inner, ..)) = expected.as_reference() {
+                        let inner = self.resolve_ty_shallow(inner);
+                        if matches!(inner.kind(Interner), TyKind::Slice(_)) {
+                            let elem_ty = TyKind::Scalar(Scalar::Uint(UintTy::U8)).intern(Interner);
+                            let slice_ty = TyKind::Slice(elem_ty).intern(Interner);
+                            let ty = TyKind::Ref(Mutability::Not, static_lifetime(), slice_ty)
+                                .intern(Interner);
+                            self.write_expr_ty(expr, ty.clone());
+                            pat_ty = Some(ty);
+                        }
+                    }
+                }
+
+                pat_ty.unwrap_or_else(|| {
+                    self.infer_expr(expr, &Expectation::has_type(expected.clone()))
+                })
+            }
             Pat::Box { inner } => match self.resolve_boxed_box() {
                 Some(box_adt) => {
                     let (inner_ty, alloc_ty) = match expected.as_adt() {
@@ -343,7 +366,9 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
         // FIXME: ConstBlock/Path/Lit might actually evaluate to ref, but inference is unimplemented.
         Pat::Path(..) => true,
         Pat::ConstBlock(..) => true,
-        Pat::Lit(expr) => !matches!(body[*expr], Expr::Literal(Literal::String(..))),
+        Pat::Lit(expr) => {
+            !matches!(body[*expr], Expr::Literal(Literal::String(..) | Literal::ByteString(..)))
+        }
         Pat::Bind {
             mode: BindingAnnotation::Mutable | BindingAnnotation::Unannotated,
             subpat: Some(subpat),
diff --git a/crates/hir-ty/src/tests/patterns.rs b/crates/hir-ty/src/tests/patterns.rs
index 399553356b041..94efe7bc11a8b 100644
--- a/crates/hir-ty/src/tests/patterns.rs
+++ b/crates/hir-ty/src/tests/patterns.rs
@@ -315,6 +315,51 @@ fn infer_pattern_match_string_literal() {
     );
 }
 
+#[test]
+fn infer_pattern_match_byte_string_literal() {
+    check_infer_with_mismatches(
+        r#"
+        //- minicore: index
+        struct S;
+        impl<T, const N: usize> core::ops::Index<S> for [T; N] {
+            type Output = [u8];
+            fn index(&self, index: core::ops::RangeFull) -> &Self::Output {
+                loop {}
+            }
+        }
+        fn test(v: [u8; 3]) {
+            if let b"foo" = &v[S] {}
+            if let b"foo" = &v {}
+        }
+        "#,
+        expect![[r#"
+            105..109 'self': &[T; N]
+            111..116 'index': {unknown}
+            157..180 '{     ...     }': &[u8]
+            167..174 'loop {}': !
+            172..174 '{}': ()
+            191..192 'v': [u8; 3]
+            203..261 '{     ...v {} }': ()
+            209..233 'if let...[S] {}': ()
+            212..230 'let b"... &v[S]': bool
+            216..222 'b"foo"': &[u8]
+            216..222 'b"foo"': &[u8]
+            225..230 '&v[S]': &[u8]
+            226..227 'v': [u8; 3]
+            226..230 'v[S]': [u8]
+            228..229 'S': S
+            231..233 '{}': ()
+            238..259 'if let... &v {}': ()
+            241..256 'let b"foo" = &v': bool
+            245..251 'b"foo"': &[u8; 3]
+            245..251 'b"foo"': &[u8; 3]
+            254..256 '&v': &[u8; 3]
+            255..256 'v': [u8; 3]
+            257..259 '{}': ()
+        "#]],
+    );
+}
+
 #[test]
 fn infer_pattern_match_or() {
     check_infer_with_mismatches(

From 53ec791dc6b22e581f9e5aabeda5edfc806564cb Mon Sep 17 00:00:00 2001
From: Ryo Yoshida <low.ryoshida@gmail.com>
Date: Mon, 1 Aug 2022 14:20:05 +0900
Subject: [PATCH 26/39] Add `UnescapedName` and make `Name` hold escaped name

---
 crates/hir-expand/src/name.rs | 54 +++++++++++++++++++++++++++++++++--
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index 47d191822d841..18b0793f10ec1 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -7,6 +7,10 @@ use syntax::{ast, SmolStr, SyntaxKind};
 /// `Name` is a wrapper around string, which is used in hir for both references
 /// and declarations. In theory, names should also carry hygiene info, but we are
 /// not there yet!
+///
+/// Note that `Name` holds and prints escaped name i.e. prefixed with "r#" when it
+/// is a raw identifier. Use [`unescaped()`][Name::unescaped] when you need the
+/// name without "r#".
 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub struct Name(Repr);
 
@@ -14,6 +18,10 @@ pub struct Name(Repr);
 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub struct EscapedName<'a>(&'a Name);
 
+/// Wrapper of `Name` to print the name without "r#" even when it is a raw identifier.
+#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub struct UnescapedName<'a>(&'a Name);
+
 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 enum Repr {
     Text(SmolStr),
@@ -49,6 +57,35 @@ impl<'a> fmt::Display for EscapedName<'a> {
     }
 }
 
+impl<'a> fmt::Display for UnescapedName<'a> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match &self.0 .0 {
+            Repr::Text(text) => {
+                let text = text.strip_prefix("r#").unwrap_or(text);
+                fmt::Display::fmt(&text, f)
+            }
+            Repr::TupleField(idx) => fmt::Display::fmt(&idx, f),
+        }
+    }
+}
+
+impl<'a> UnescapedName<'a> {
+    /// Returns the textual representation of this name as a [`SmolStr`]. Prefer using this over
+    /// [`ToString::to_string`] if possible as this conversion is cheaper in the general case.
+    pub fn to_smol_str(&self) -> SmolStr {
+        match &self.0 .0 {
+            Repr::Text(it) => {
+                if let Some(stripped) = it.strip_prefix("r#") {
+                    SmolStr::new(stripped)
+                } else {
+                    it.clone()
+                }
+            }
+            Repr::TupleField(it) => SmolStr::new(&it.to_string()),
+        }
+    }
+}
+
 impl<'a> EscapedName<'a> {
     pub fn is_escaped(&self) -> bool {
         match &self.0 .0 {
@@ -97,9 +134,11 @@ impl Name {
 
     /// Resolve a name from the text of token.
     fn resolve(raw_text: &str) -> Name {
+        // When `raw_text` starts with "r#" but the name does not coincide with any
+        // keyword, we never need the prefix so we strip it.
         match raw_text.strip_prefix("r#") {
-            Some(text) => Name::new_text(SmolStr::new(text)),
-            None => Name::new_text(raw_text.into()),
+            Some(text) if !is_raw_identifier(text) => Name::new_text(SmolStr::new(text)),
+            _ => Name::new_text(raw_text.into()),
         }
     }
 
@@ -145,6 +184,17 @@ impl Name {
     pub fn escaped(&self) -> EscapedName<'_> {
         EscapedName(self)
     }
+
+    pub fn unescaped(&self) -> UnescapedName<'_> {
+        UnescapedName(self)
+    }
+
+    pub fn is_escaped(&self) -> bool {
+        match &self.0 {
+            Repr::Text(it) => it.starts_with("r#"),
+            Repr::TupleField(_) => false,
+        }
+    }
 }
 
 pub trait AsName {

From 4322cf7f5b4cc31ae88320add185184f5d58abb7 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida <low.ryoshida@gmail.com>
Date: Mon, 1 Aug 2022 15:19:49 +0900
Subject: [PATCH 27/39] Remove `EscapedName`

---
 crates/hir-expand/src/mod_path.rs             |  4 +-
 crates/hir-expand/src/name.rs                 | 48 -------------------
 .../src/completions/item_list/trait_impl.rs   |  3 +-
 crates/ide-completion/src/render.rs           |  8 ++--
 crates/ide-completion/src/render/const_.rs    |  2 +-
 crates/ide-completion/src/render/function.rs  |  6 +--
 crates/ide-completion/src/render/macro_.rs    |  2 +-
 crates/ide-completion/src/render/pattern.rs   |  8 ++--
 .../ide-completion/src/render/type_alias.rs   |  4 +-
 .../src/render/union_literal.rs               | 10 ++--
 crates/ide-completion/src/render/variant.rs   |  4 +-
 11 files changed, 26 insertions(+), 73 deletions(-)

diff --git a/crates/hir-expand/src/mod_path.rs b/crates/hir-expand/src/mod_path.rs
index fea09521e87cb..ed9d90298871c 100644
--- a/crates/hir-expand/src/mod_path.rs
+++ b/crates/hir-expand/src/mod_path.rs
@@ -134,9 +134,9 @@ impl ModPath {
             }
             first_segment = false;
             if escaped {
-                segment.escaped().fmt(f)?
-            } else {
                 segment.fmt(f)?
+            } else {
+                segment.unescaped().fmt(f)?
             };
         }
         Ok(())
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index 18b0793f10ec1..87c663eec8e81 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -14,10 +14,6 @@ use syntax::{ast, SmolStr, SyntaxKind};
 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub struct Name(Repr);
 
-/// `EscapedName` will add a prefix "r#" to the wrapped `Name` when it is a raw identifier
-#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
-pub struct EscapedName<'a>(&'a Name);
-
 /// Wrapper of `Name` to print the name without "r#" even when it is a raw identifier.
 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub struct UnescapedName<'a>(&'a Name);
@@ -42,21 +38,6 @@ fn is_raw_identifier(name: &str) -> bool {
     is_keyword && !matches!(name, "self" | "crate" | "super" | "Self")
 }
 
-impl<'a> fmt::Display for EscapedName<'a> {
-    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        match &self.0 .0 {
-            Repr::Text(text) => {
-                if is_raw_identifier(text) {
-                    write!(f, "r#{}", &text)
-                } else {
-                    fmt::Display::fmt(&text, f)
-                }
-            }
-            Repr::TupleField(idx) => fmt::Display::fmt(&idx, f),
-        }
-    }
-}
-
 impl<'a> fmt::Display for UnescapedName<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match &self.0 .0 {
@@ -86,31 +67,6 @@ impl<'a> UnescapedName<'a> {
     }
 }
 
-impl<'a> EscapedName<'a> {
-    pub fn is_escaped(&self) -> bool {
-        match &self.0 .0 {
-            Repr::Text(it) => is_raw_identifier(&it),
-            Repr::TupleField(_) => false,
-        }
-    }
-
-    /// Returns the textual representation of this name as a [`SmolStr`].
-    /// Prefer using this over [`ToString::to_string`] if possible as this conversion is cheaper in
-    /// the general case.
-    pub fn to_smol_str(&self) -> SmolStr {
-        match &self.0 .0 {
-            Repr::Text(it) => {
-                if is_raw_identifier(&it) {
-                    SmolStr::from_iter(["r#", &it])
-                } else {
-                    it.clone()
-                }
-            }
-            Repr::TupleField(it) => SmolStr::new(&it.to_string()),
-        }
-    }
-}
-
 impl Name {
     /// Note: this is private to make creating name from random string hard.
     /// Hopefully, this should allow us to integrate hygiene cleaner in the
@@ -181,10 +137,6 @@ impl Name {
         }
     }
 
-    pub fn escaped(&self) -> EscapedName<'_> {
-        EscapedName(self)
-    }
-
     pub fn unescaped(&self) -> UnescapedName<'_> {
         UnescapedName(self)
     }
diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs
index e9256803cc4f7..785db6fde1d5a 100644
--- a/crates/ide-completion/src/completions/item_list/trait_impl.rs
+++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs
@@ -233,7 +233,8 @@ fn add_type_alias_impl(
     type_alias: hir::TypeAlias,
 ) {
     let alias_name = type_alias.name(ctx.db);
-    let (alias_name, escaped_name) = (alias_name.to_smol_str(), alias_name.escaped().to_smol_str());
+    let (alias_name, escaped_name) =
+        (alias_name.unescaped().to_smol_str(), alias_name.to_smol_str());
 
     let label = format!("type {} =", alias_name);
     let replacement = format!("type {} = ", escaped_name);
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs
index 946134b0ff95d..6c466777a1026 100644
--- a/crates/ide-completion/src/render.rs
+++ b/crates/ide-completion/src/render.rs
@@ -117,7 +117,7 @@ pub(crate) fn render_field(
 ) -> CompletionItem {
     let is_deprecated = ctx.is_deprecated(field);
     let name = field.name(ctx.db());
-    let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+    let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
     let mut item = CompletionItem::new(
         SymbolKind::Field,
         ctx.source_range(),
@@ -283,8 +283,8 @@ fn render_resolution_path(
 
     let name = local_name.to_smol_str();
     let mut item = render_resolution_simple_(ctx, &local_name, import_to_add, resolution);
-    if local_name.escaped().is_escaped() {
-        item.insert_text(local_name.escaped().to_smol_str());
+    if local_name.is_escaped() {
+        item.insert_text(local_name.to_smol_str());
     }
     // Add `<>` for generic types
     let type_path_no_ty_args = matches!(
@@ -306,7 +306,7 @@ fn render_resolution_path(
                 item.lookup_by(name.clone())
                     .label(SmolStr::from_iter([&name, "<…>"]))
                     .trigger_call_info()
-                    .insert_snippet(cap, format!("{}<$0>", local_name.escaped()));
+                    .insert_snippet(cap, format!("{}<$0>", local_name));
             }
         }
     }
diff --git a/crates/ide-completion/src/render/const_.rs b/crates/ide-completion/src/render/const_.rs
index a810eef18dd1f..93ea825e00427 100644
--- a/crates/ide-completion/src/render/const_.rs
+++ b/crates/ide-completion/src/render/const_.rs
@@ -13,7 +13,7 @@ pub(crate) fn render_const(ctx: RenderContext<'_>, const_: hir::Const) -> Option
 fn render(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem> {
     let db = ctx.db();
     let name = const_.name(db)?;
-    let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+    let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
     let detail = const_.display(db).to_string();
 
     let mut item = CompletionItem::new(SymbolKind::Const, ctx.source_range(), name.clone());
diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs
index 4b5535718c5df..2a90703b09ece 100644
--- a/crates/ide-completion/src/render/function.rs
+++ b/crates/ide-completion/src/render/function.rs
@@ -52,10 +52,10 @@ fn render(
 
     let (call, escaped_call) = match &func_kind {
         FuncKind::Method(_, Some(receiver)) => (
-            format!("{}.{}", receiver, &name).into(),
-            format!("{}.{}", receiver.escaped(), name.escaped()).into(),
+            format!("{}.{}", receiver.unescaped(), name.unescaped()).into(),
+            format!("{}.{}", receiver, name).into(),
         ),
-        _ => (name.to_smol_str(), name.escaped().to_smol_str()),
+        _ => (name.unescaped().to_smol_str(), name.to_smol_str()),
     };
     let mut item = CompletionItem::new(
         if func.self_param(db).is_some() {
diff --git a/crates/ide-completion/src/render/macro_.rs b/crates/ide-completion/src/render/macro_.rs
index ca2269f1398f0..eabd0bd17d65f 100644
--- a/crates/ide-completion/src/render/macro_.rs
+++ b/crates/ide-completion/src/render/macro_.rs
@@ -46,7 +46,7 @@ fn render(
         ctx.source_range()
     };
 
-    let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+    let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
     let docs = ctx.docs(macro_);
     let docs_str = docs.as_ref().map(Documentation::as_str).unwrap_or_default();
     let is_fn_like = macro_.is_fn_like(completion.db);
diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs
index 34a384f2f7ae8..4f4c064027068 100644
--- a/crates/ide-completion/src/render/pattern.rs
+++ b/crates/ide-completion/src/render/pattern.rs
@@ -31,7 +31,7 @@ pub(crate) fn render_struct_pat(
     }
 
     let name = local_name.unwrap_or_else(|| strukt.name(ctx.db()));
-    let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
+    let (name, escaped_name) = (name.unescaped().to_smol_str(), name.to_smol_str());
     let kind = strukt.kind(ctx.db());
     let label = format_literal_label(name.as_str(), kind);
     let pat = render_pat(&ctx, pattern_ctx, &escaped_name, kind, &visible_fields, fields_omitted)?;
@@ -56,7 +56,7 @@ pub(crate) fn render_variant_pat(
         Some(path) => (path.to_string().into(), path.escaped().to_string().into()),
         None => {
             let name = local_name.unwrap_or_else(|| variant.name(ctx.db()));
-            (name.to_smol_str(), name.escaped().to_smol_str())
+            (name.unescaped().to_smol_str(), name.to_smol_str())
         }
     };
 
@@ -146,7 +146,7 @@ fn render_record_as_pat(
             format!(
                 "{name} {{ {}{} }}",
                 fields.enumerate().format_with(", ", |(idx, field), f| {
-                    f(&format_args!("{}${}", field.name(db).escaped(), idx + 1))
+                    f(&format_args!("{}${}", field.name(db), idx + 1))
                 }),
                 if fields_omitted { ", .." } else { "" },
                 name = name
@@ -155,7 +155,7 @@ fn render_record_as_pat(
         None => {
             format!(
                 "{name} {{ {}{} }}",
-                fields.map(|field| field.name(db).escaped().to_smol_str()).format(", "),
+                fields.map(|field| field.name(db).to_smol_str()).format(", "),
                 if fields_omitted { ", .." } else { "" },
                 name = name
             )
diff --git a/crates/ide-completion/src/render/type_alias.rs b/crates/ide-completion/src/render/type_alias.rs
index f1b23c76e7b43..de919429f2f95 100644
--- a/crates/ide-completion/src/render/type_alias.rs
+++ b/crates/ide-completion/src/render/type_alias.rs
@@ -32,11 +32,11 @@ fn render(
     let name = type_alias.name(db);
     let (name, escaped_name) = if with_eq {
         (
+            SmolStr::from_iter([&name.unescaped().to_smol_str(), " = "]),
             SmolStr::from_iter([&name.to_smol_str(), " = "]),
-            SmolStr::from_iter([&name.escaped().to_smol_str(), " = "]),
         )
     } else {
-        (name.to_smol_str(), name.escaped().to_smol_str())
+        (name.unescaped().to_smol_str(), name.to_smol_str())
     };
     let detail = type_alias.display(db).to_string();
 
diff --git a/crates/ide-completion/src/render/union_literal.rs b/crates/ide-completion/src/render/union_literal.rs
index 9c9540a9bd963..b04c8e3bf9d10 100644
--- a/crates/ide-completion/src/render/union_literal.rs
+++ b/crates/ide-completion/src/render/union_literal.rs
@@ -22,7 +22,7 @@ pub(crate) fn render_union_literal(
 
     let (qualified_name, escaped_qualified_name) = match path {
         Some(p) => (p.to_string(), p.escaped().to_string()),
-        None => (name.to_string(), name.escaped().to_string()),
+        None => (name.unescaped().to_string(), name.to_string()),
     };
 
     let mut item = CompletionItem::new(
@@ -42,15 +42,15 @@ pub(crate) fn render_union_literal(
         format!(
             "{} {{ ${{1|{}|}}: ${{2:()}} }}$0",
             escaped_qualified_name,
-            fields.iter().map(|field| field.name(ctx.db()).escaped().to_smol_str()).format(",")
+            fields.iter().map(|field| field.name(ctx.db()).to_smol_str()).format(",")
         )
     } else {
         format!(
             "{} {{ {} }}",
             escaped_qualified_name,
-            fields.iter().format_with(", ", |field, f| {
-                f(&format_args!("{}: ()", field.name(ctx.db()).escaped()))
-            })
+            fields
+                .iter()
+                .format_with(", ", |field, f| { f(&format_args!("{}: ()", field.name(ctx.db()))) })
         )
     };
 
diff --git a/crates/ide-completion/src/render/variant.rs b/crates/ide-completion/src/render/variant.rs
index 003a0c11ed2f8..664845330eb8f 100644
--- a/crates/ide-completion/src/render/variant.rs
+++ b/crates/ide-completion/src/render/variant.rs
@@ -24,9 +24,9 @@ pub(crate) fn render_record_lit(
 ) -> RenderedLiteral {
     let completions = fields.iter().enumerate().format_with(", ", |(idx, field), f| {
         if snippet_cap.is_some() {
-            f(&format_args!("{}: ${{{}:()}}", field.name(db).escaped(), idx + 1))
+            f(&format_args!("{}: ${{{}:()}}", field.name(db), idx + 1))
         } else {
-            f(&format_args!("{}: ()", field.name(db).escaped()))
+            f(&format_args!("{}: ()", field.name(db)))
         }
     });
 

From 8fe73a224005a153c89a40243e71a021e9304958 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida <low.ryoshida@gmail.com>
Date: Mon, 1 Aug 2022 15:20:14 +0900
Subject: [PATCH 28/39] Make tests pass

---
 crates/hir-def/src/nameres/mod_resolution.rs       | 2 ++
 crates/hir-def/src/nameres/tests/mod_resolution.rs | 4 ++--
 crates/ide-completion/src/render.rs                | 3 ++-
 crates/ide-completion/src/render/function.rs       | 2 +-
 4 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/crates/hir-def/src/nameres/mod_resolution.rs b/crates/hir-def/src/nameres/mod_resolution.rs
index 52a620fe22f6e..99f7f1b549e2c 100644
--- a/crates/hir-def/src/nameres/mod_resolution.rs
+++ b/crates/hir-def/src/nameres/mod_resolution.rs
@@ -73,10 +73,12 @@ impl ModDir {
                 candidate_files.push(self.dir_path.join_attr(attr_path, self.root_non_dir_owner))
             }
             None if file_id.is_include_macro(db.upcast()) => {
+                let name = name.unescaped();
                 candidate_files.push(format!("{}.rs", name));
                 candidate_files.push(format!("{}/mod.rs", name));
             }
             None => {
+                let name = name.unescaped();
                 candidate_files.push(format!("{}{}.rs", self.dir_path.0, name));
                 candidate_files.push(format!("{}{}/mod.rs", self.dir_path.0, name));
             }
diff --git a/crates/hir-def/src/nameres/tests/mod_resolution.rs b/crates/hir-def/src/nameres/tests/mod_resolution.rs
index 79a74873b4a47..3fa585574deec 100644
--- a/crates/hir-def/src/nameres/tests/mod_resolution.rs
+++ b/crates/hir-def/src/nameres/tests/mod_resolution.rs
@@ -132,9 +132,9 @@ pub struct Bar;
         expect![[r#"
             crate
             Bar: t v
-            async: t
+            r#async: t
 
-            crate::async
+            crate::r#async
             Bar: t v
         "#]],
     );
diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs
index 6c466777a1026..693007ca3071a 100644
--- a/crates/ide-completion/src/render.rs
+++ b/crates/ide-completion/src/render.rs
@@ -342,7 +342,8 @@ fn render_resolution_simple_(
     let ctx = ctx.import_to_add(import_to_add);
     let kind = res_to_kind(resolution);
 
-    let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.to_smol_str());
+    let mut item =
+        CompletionItem::new(kind, ctx.source_range(), local_name.unescaped().to_smol_str());
     item.set_relevance(ctx.completion_relevance())
         .set_documentation(scope_def_docs(db, resolution))
         .set_deprecated(scope_def_is_deprecated(&ctx, resolution));
diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs
index 2a90703b09ece..9cf64691298eb 100644
--- a/crates/ide-completion/src/render/function.rs
+++ b/crates/ide-completion/src/render/function.rs
@@ -96,7 +96,7 @@ fn render(
     item.set_documentation(ctx.docs(func))
         .set_deprecated(ctx.is_deprecated(func) || ctx.is_deprecated_assoc_item(func))
         .detail(detail(db, func))
-        .lookup_by(name.to_smol_str());
+        .lookup_by(name.unescaped().to_smol_str());
 
     match ctx.completion.config.snippet_cap {
         Some(cap) => {

From 018266a7ff6d06747e798afdf84faadb7567d179 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida <low.ryoshida@gmail.com>
Date: Thu, 11 Aug 2022 02:17:15 +0900
Subject: [PATCH 29/39] Make `ModPath` display escaped path

---
 crates/hir-expand/src/mod_path.rs                 | 12 ++++++------
 crates/ide-completion/src/render/literal.rs       |  2 +-
 crates/ide-completion/src/render/pattern.rs       |  2 +-
 crates/ide-completion/src/render/union_literal.rs |  2 +-
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/crates/hir-expand/src/mod_path.rs b/crates/hir-expand/src/mod_path.rs
index ed9d90298871c..d0f73ec8208c6 100644
--- a/crates/hir-expand/src/mod_path.rs
+++ b/crates/hir-expand/src/mod_path.rs
@@ -22,7 +22,7 @@ pub struct ModPath {
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct EscapedModPath<'a>(&'a ModPath);
+pub struct UnescapedModPath<'a>(&'a ModPath);
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum PathKind {
@@ -102,8 +102,8 @@ impl ModPath {
         }
     }
 
-    pub fn escaped(&self) -> EscapedModPath<'_> {
-        EscapedModPath(self)
+    pub fn unescaped(&self) -> UnescapedModPath<'_> {
+        UnescapedModPath(self)
     }
 
     fn _fmt(&self, f: &mut fmt::Formatter<'_>, escaped: bool) -> fmt::Result {
@@ -145,13 +145,13 @@ impl ModPath {
 
 impl Display for ModPath {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self._fmt(f, false)
+        self._fmt(f, true)
     }
 }
 
-impl<'a> Display for EscapedModPath<'a> {
+impl<'a> Display for UnescapedModPath<'a> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        self.0._fmt(f, true)
+        self.0._fmt(f, false)
     }
 }
 
diff --git a/crates/ide-completion/src/render/literal.rs b/crates/ide-completion/src/render/literal.rs
index 91a253f8fc8c1..707dea206be57 100644
--- a/crates/ide-completion/src/render/literal.rs
+++ b/crates/ide-completion/src/render/literal.rs
@@ -73,7 +73,7 @@ fn render(
         None => (name.clone().into(), name.into(), false),
     };
     let (qualified_name, escaped_qualified_name) =
-        (qualified_name.to_string(), qualified_name.escaped().to_string());
+        (qualified_name.unescaped().to_string(), qualified_name.to_string());
     let snippet_cap = ctx.snippet_cap();
 
     let mut rendered = match kind {
diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs
index 4f4c064027068..1c1299e33b670 100644
--- a/crates/ide-completion/src/render/pattern.rs
+++ b/crates/ide-completion/src/render/pattern.rs
@@ -53,7 +53,7 @@ pub(crate) fn render_variant_pat(
     let (visible_fields, fields_omitted) = visible_fields(ctx.completion, &fields, variant)?;
 
     let (name, escaped_name) = match path {
-        Some(path) => (path.to_string().into(), path.escaped().to_string().into()),
+        Some(path) => (path.unescaped().to_string().into(), path.to_string().into()),
         None => {
             let name = local_name.unwrap_or_else(|| variant.name(ctx.db()));
             (name.unescaped().to_smol_str(), name.to_smol_str())
diff --git a/crates/ide-completion/src/render/union_literal.rs b/crates/ide-completion/src/render/union_literal.rs
index b04c8e3bf9d10..bb32330f276de 100644
--- a/crates/ide-completion/src/render/union_literal.rs
+++ b/crates/ide-completion/src/render/union_literal.rs
@@ -21,7 +21,7 @@ pub(crate) fn render_union_literal(
     let name = local_name.unwrap_or_else(|| un.name(ctx.db()));
 
     let (qualified_name, escaped_qualified_name) = match path {
-        Some(p) => (p.to_string(), p.escaped().to_string()),
+        Some(p) => (p.unescaped().to_string(), p.to_string()),
         None => (name.unescaped().to_string(), name.to_string()),
     };
 

From ba6db3e9b054902549a0cf487cd7f69db2654aa1 Mon Sep 17 00:00:00 2001
From: Ryo Yoshida <low.ryoshida@gmail.com>
Date: Sat, 30 Jul 2022 22:28:34 +0900
Subject: [PATCH 30/39] Add test for runnables with raw identifiers

---
 crates/ide/src/runnables.rs | 186 ++++++++++++++++++++++++++++++++++++
 1 file changed, 186 insertions(+)

diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index b0853b10fde2f..0181c6b8e456a 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -2225,4 +2225,190 @@ macro_rules! foo {
             "#]],
         );
     }
+
+    #[test]
+    fn test_paths_with_raw_ident() {
+        check(
+            r#"
+//- /lib.rs
+$0
+mod r#mod {
+    #[test]
+    fn r#fn() {}
+
+    /// ```
+    /// ```
+    fn r#for() {}
+
+    /// ```
+    /// ```
+    struct r#struct<r#type>(r#type);
+
+    /// ```
+    /// ```
+    impl<r#type> r#struct<r#type> {
+        /// ```
+        /// ```
+        fn r#fn() {}
+    }
+
+    enum r#enum {}
+    impl r#struct<r#enum> {
+        /// ```
+        /// ```
+        fn r#fn() {}
+    }
+
+    trait r#trait {}
+
+    /// ```
+    /// ```
+    impl<T> r#trait for r#struct<T> {}
+}
+"#,
+            &[TestMod, Test, DocTest, DocTest, DocTest, DocTest, DocTest, DocTest],
+            expect![[r#"
+                [
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 1..461,
+                            focus_range: 5..10,
+                            name: "r#mod",
+                            kind: Module,
+                            description: "mod r#mod",
+                        },
+                        kind: TestMod {
+                            path: "r#mod",
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 17..41,
+                            focus_range: 32..36,
+                            name: "r#fn",
+                            kind: Function,
+                        },
+                        kind: Test {
+                            test_id: Path(
+                                "r#mod::r#fn",
+                            ),
+                            attr: TestAttr {
+                                ignore: false,
+                            },
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 47..84,
+                            name: "r#for",
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#mod::r#for",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 90..146,
+                            name: "r#struct",
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#mod::r#struct",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 152..266,
+                            focus_range: 189..205,
+                            name: "impl",
+                            kind: Impl,
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#struct<r#type>",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 216..260,
+                            name: "r#fn",
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#mod::r#struct<r#type>::r#fn",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 323..367,
+                            name: "r#fn",
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#mod::r#struct<r#enum>::r#fn",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                    Runnable {
+                        use_name_in_title: false,
+                        nav: NavigationTarget {
+                            file_id: FileId(
+                                0,
+                            ),
+                            full_range: 401..459,
+                            focus_range: 445..456,
+                            name: "impl",
+                            kind: Impl,
+                        },
+                        kind: DocTest {
+                            test_id: Path(
+                                "r#struct<T>",
+                            ),
+                        },
+                        cfg: None,
+                    },
+                ]
+            "#]],
+        )
+    }
 }

From 1bb58205f0b09ccdb1a8915cfdede35bd2c09da4 Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Thu, 11 Aug 2022 10:41:30 +0200
Subject: [PATCH 31/39] Fix panic in no_such_field when using tuple fields on
 record structs

---
 crates/hir/src/source_analyzer.rs              |  1 +
 .../src/handlers/no_such_field.rs              | 18 ++++++++++++++++--
 2 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index f5e2e44307090..ae2896e193299 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -368,6 +368,7 @@ impl SourceAnalyzer {
         let local = if field.name_ref().is_some() {
             None
         } else {
+            // Shorthand syntax, resolve to the local
             let path = ModPath::from_segments(PathKind::Plain, once(local_name.clone()));
             match self.resolver.resolve_path_in_value_ns_fully(db.upcast(), &path) {
                 Some(ValueNs::LocalBinding(pat_id)) => {
diff --git a/crates/ide-diagnostics/src/handlers/no_such_field.rs b/crates/ide-diagnostics/src/handlers/no_such_field.rs
index e032c578f0282..a80299106bd36 100644
--- a/crates/ide-diagnostics/src/handlers/no_such_field.rs
+++ b/crates/ide-diagnostics/src/handlers/no_such_field.rs
@@ -68,7 +68,7 @@ fn missing_record_expr_field_fixes(
     }
     let new_field = make::record_field(
         None,
-        make::name(&record_expr_field.field_name()?.text()),
+        make::name(&record_expr_field.field_name()?.ident_token()?.text()),
         make::ty(&new_field_type.display_source_code(sema.db, module.into()).ok()?),
     );
 
@@ -109,7 +109,7 @@ fn missing_record_expr_field_fixes(
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::{check_diagnostics, check_fix};
+    use crate::tests::{check_diagnostics, check_fix, check_no_fix};
 
     #[test]
     fn no_such_field_diagnostics() {
@@ -277,6 +277,20 @@ struct Foo {
     bar: i32,
     pub(crate) baz: bool
 }
+"#,
+        )
+    }
+
+    #[test]
+    fn test_tuple_field_on_record_struct() {
+        check_no_fix(
+            r#"
+struct Struct {}
+fn main() {
+    Struct {
+        0$0: 0
+    }
+}
 "#,
         )
     }

From 1ce978370bd190d952d0d31bb09d934895278238 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= <lnicola@dend.ro>
Date: Fri, 12 Aug 2022 18:19:48 +0300
Subject: [PATCH 32/39] Use Node 16 in CI workflows

---
 .github/workflows/ci.yaml      | 2 +-
 .github/workflows/release.yaml | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 0c81ff0789fbb..a70252fa65a5d 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -101,7 +101,7 @@ jobs:
     - name: Install Nodejs
       uses: actions/setup-node@v1
       with:
-        node-version: 14.x
+        node-version: 16.x
 
     - name: Install xvfb
       if: matrix.os == 'ubuntu-latest'
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index ca8eb1309de3d..d5d8df2345fa9 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -68,7 +68,7 @@ jobs:
       - name: Install Node.js
         uses: actions/setup-node@v1
         with:
-          node-version: 14.x
+          node-version: 16.x
 
       - name: Update apt repositories
         if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf'
@@ -133,7 +133,7 @@ jobs:
     container:
       image: rust:alpine
       volumes:
-        - /usr/local/cargo/registry
+        - /usr/local/cargo/registry:/usr/local/cargo/registry
 
     steps:
       - name: Install dependencies
@@ -176,7 +176,7 @@ jobs:
       - name: Install Nodejs
         uses: actions/setup-node@v1
         with:
-          node-version: 14.x
+          node-version: 16.x
 
       - run: echo "TAG=$(date --iso -u)" >> $GITHUB_ENV
         if: github.ref == 'refs/heads/release'

From 19da03291d5253f658e29dbe916e41b4c0cfefee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= <lnicola@dend.ro>
Date: Fri, 12 Aug 2022 18:22:14 +0300
Subject: [PATCH 33/39] Upgrade npm lockfile

---
 editors/code/package-lock.json | 3974 +++++++++++++++++++++++++++++++-
 1 file changed, 3962 insertions(+), 12 deletions(-)

diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index 0436681b1a0a9..3ff4b6897a16b 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -1,8 +1,3956 @@
 {
     "name": "rust-analyzer",
     "version": "0.5.0-dev",
-    "lockfileVersion": 1,
+    "lockfileVersion": 2,
     "requires": true,
+    "packages": {
+        "": {
+            "name": "rust-analyzer",
+            "version": "0.5.0-dev",
+            "license": "MIT OR Apache-2.0",
+            "dependencies": {
+                "d3": "^7.6.1",
+                "d3-graphviz": "^4.1.1",
+                "vscode-languageclient": "^8.0.0-next.14"
+            },
+            "devDependencies": {
+                "@types/node": "~16.11.7",
+                "@types/vscode": "~1.66.0",
+                "@typescript-eslint/eslint-plugin": "^5.30.5",
+                "@typescript-eslint/parser": "^5.30.5",
+                "@vscode/test-electron": "^2.1.5",
+                "cross-env": "^7.0.3",
+                "esbuild": "^0.14.48",
+                "eslint": "^8.19.0",
+                "eslint-config-prettier": "^8.5.0",
+                "ovsx": "^0.5.1",
+                "prettier": "^2.7.1",
+                "tslib": "^2.4.0",
+                "typescript": "^4.7.4",
+                "vsce": "^2.9.2"
+            },
+            "engines": {
+                "vscode": "^1.66.0"
+            }
+        },
+        "node_modules/@eslint/eslintrc": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
+            "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==",
+            "dev": true,
+            "dependencies": {
+                "ajv": "^6.12.4",
+                "debug": "^4.3.2",
+                "espree": "^9.3.2",
+                "globals": "^13.15.0",
+                "ignore": "^5.2.0",
+                "import-fresh": "^3.2.1",
+                "js-yaml": "^4.1.0",
+                "minimatch": "^3.1.2",
+                "strip-json-comments": "^3.1.1"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            }
+        },
+        "node_modules/@hpcc-js/wasm": {
+            "version": "1.12.8",
+            "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-1.12.8.tgz",
+            "integrity": "sha512-n4q9ARKco2hpCLsuVaW6Az3cDVaua7B3DSONHkc49WtEzgY/btvcDG5Zr1P6PZDv0sQ7oPnAi9Y+W2DI++MgcQ==",
+            "dependencies": {
+                "yargs": "^17.3.1"
+            },
+            "bin": {
+                "dot-wasm": "bin/cli.js"
+            }
+        },
+        "node_modules/@humanwhocodes/config-array": {
+            "version": "0.9.5",
+            "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
+            "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+            "dev": true,
+            "dependencies": {
+                "@humanwhocodes/object-schema": "^1.2.1",
+                "debug": "^4.1.1",
+                "minimatch": "^3.0.4"
+            },
+            "engines": {
+                "node": ">=10.10.0"
+            }
+        },
+        "node_modules/@humanwhocodes/object-schema": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+            "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+            "dev": true
+        },
+        "node_modules/@nodelib/fs.scandir": {
+            "version": "2.1.5",
+            "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+            "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+            "dev": true,
+            "dependencies": {
+                "@nodelib/fs.stat": "2.0.5",
+                "run-parallel": "^1.1.9"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/@nodelib/fs.stat": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+            "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+            "dev": true,
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/@nodelib/fs.walk": {
+            "version": "1.2.8",
+            "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+            "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+            "dev": true,
+            "dependencies": {
+                "@nodelib/fs.scandir": "2.1.5",
+                "fastq": "^1.6.0"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/@tootallnate/once": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
+            "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+            "dev": true,
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/@types/json-schema": {
+            "version": "7.0.11",
+            "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+            "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+            "dev": true
+        },
+        "node_modules/@types/node": {
+            "version": "16.11.43",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.43.tgz",
+            "integrity": "sha512-GqWykok+3uocgfAJM8imbozrqLnPyTrpFlrryURQlw1EesPUCx5XxTiucWDSFF9/NUEXDuD4bnvHm8xfVGWTpQ==",
+            "dev": true
+        },
+        "node_modules/@types/vscode": {
+            "version": "1.66.0",
+            "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.66.0.tgz",
+            "integrity": "sha512-ZfJck4M7nrGasfs4A4YbUoxis3Vu24cETw3DERsNYtDZmYSYtk6ljKexKFKhImO/ZmY6ZMsmegu2FPkXoUFImA==",
+            "dev": true
+        },
+        "node_modules/@typescript-eslint/eslint-plugin": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.5.tgz",
+            "integrity": "sha512-lftkqRoBvc28VFXEoRgyZuztyVUQ04JvUnATSPtIRFAccbXTWL6DEtXGYMcbg998kXw1NLUJm7rTQ9eUt+q6Ig==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/scope-manager": "5.30.5",
+                "@typescript-eslint/type-utils": "5.30.5",
+                "@typescript-eslint/utils": "5.30.5",
+                "debug": "^4.3.4",
+                "functional-red-black-tree": "^1.0.1",
+                "ignore": "^5.2.0",
+                "regexpp": "^3.2.0",
+                "semver": "^7.3.7",
+                "tsutils": "^3.21.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "@typescript-eslint/parser": "^5.0.0",
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/parser": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.5.tgz",
+            "integrity": "sha512-zj251pcPXI8GO9NDKWWmygP6+UjwWmrdf9qMW/L/uQJBM/0XbU2inxe5io/234y/RCvwpKEYjZ6c1YrXERkK4Q==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/scope-manager": "5.30.5",
+                "@typescript-eslint/types": "5.30.5",
+                "@typescript-eslint/typescript-estree": "5.30.5",
+                "debug": "^4.3.4"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/scope-manager": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.5.tgz",
+            "integrity": "sha512-NJ6F+YHHFT/30isRe2UTmIGGAiXKckCyMnIV58cE3JkHmaD6e5zyEYm5hBDv0Wbin+IC0T1FWJpD3YqHUG/Ydg==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/types": "5.30.5",
+                "@typescript-eslint/visitor-keys": "5.30.5"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            }
+        },
+        "node_modules/@typescript-eslint/type-utils": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.5.tgz",
+            "integrity": "sha512-k9+ejlv1GgwN1nN7XjVtyCgE0BTzhzT1YsQF0rv4Vfj2U9xnslBgMYYvcEYAFVdvhuEscELJsB7lDkN7WusErw==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/utils": "5.30.5",
+                "debug": "^4.3.4",
+                "tsutils": "^3.21.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "eslint": "*"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/types": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.5.tgz",
+            "integrity": "sha512-kZ80w/M2AvsbRvOr3PjaNh6qEW1LFqs2pLdo2s5R38B2HYXG8Z0PP48/4+j1QHJFL3ssHIbJ4odPRS8PlHrFfw==",
+            "dev": true,
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            }
+        },
+        "node_modules/@typescript-eslint/typescript-estree": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.5.tgz",
+            "integrity": "sha512-qGTc7QZC801kbYjAr4AgdOfnokpwStqyhSbiQvqGBLixniAKyH+ib2qXIVo4P9NgGzwyfD9I0nlJN7D91E1VpQ==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/types": "5.30.5",
+                "@typescript-eslint/visitor-keys": "5.30.5",
+                "debug": "^4.3.4",
+                "globby": "^11.1.0",
+                "is-glob": "^4.0.3",
+                "semver": "^7.3.7",
+                "tsutils": "^3.21.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependenciesMeta": {
+                "typescript": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/@typescript-eslint/utils": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.5.tgz",
+            "integrity": "sha512-o4SSUH9IkuA7AYIfAvatldovurqTAHrfzPApOZvdUq01hHojZojCFXx06D/aFpKCgWbMPRdJBWAC3sWp3itwTA==",
+            "dev": true,
+            "dependencies": {
+                "@types/json-schema": "^7.0.9",
+                "@typescript-eslint/scope-manager": "5.30.5",
+                "@typescript-eslint/types": "5.30.5",
+                "@typescript-eslint/typescript-estree": "5.30.5",
+                "eslint-scope": "^5.1.1",
+                "eslint-utils": "^3.0.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            }
+        },
+        "node_modules/@typescript-eslint/visitor-keys": {
+            "version": "5.30.5",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz",
+            "integrity": "sha512-D+xtGo9HUMELzWIUqcQc0p2PO4NyvTrgIOK/VnSH083+8sq0tiLozNRKuLarwHYGRuA6TVBQSuuLwJUDWd3aaA==",
+            "dev": true,
+            "dependencies": {
+                "@typescript-eslint/types": "5.30.5",
+                "eslint-visitor-keys": "^3.3.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            }
+        },
+        "node_modules/@vscode/test-electron": {
+            "version": "2.1.5",
+            "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.1.5.tgz",
+            "integrity": "sha512-O/ioqFpV+RvKbRykX2ItYPnbcZ4Hk5V0rY4uhQjQTLhGL9WZUvS7exzuYQCCI+ilSqJpctvxq2llTfGXf9UnnA==",
+            "dev": true,
+            "dependencies": {
+                "http-proxy-agent": "^4.0.1",
+                "https-proxy-agent": "^5.0.0",
+                "rimraf": "^3.0.2",
+                "unzipper": "^0.10.11"
+            },
+            "engines": {
+                "node": ">=8.9.3"
+            }
+        },
+        "node_modules/acorn": {
+            "version": "8.7.1",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
+            "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+            "dev": true,
+            "bin": {
+                "acorn": "bin/acorn"
+            },
+            "engines": {
+                "node": ">=0.4.0"
+            }
+        },
+        "node_modules/acorn-jsx": {
+            "version": "5.3.2",
+            "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+            "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+            "dev": true,
+            "peerDependencies": {
+                "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+            }
+        },
+        "node_modules/agent-base": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+            "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+            "dev": true,
+            "dependencies": {
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6.0.0"
+            }
+        },
+        "node_modules/ajv": {
+            "version": "6.12.6",
+            "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+            "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+            "dev": true,
+            "dependencies": {
+                "fast-deep-equal": "^3.1.1",
+                "fast-json-stable-stringify": "^2.0.0",
+                "json-schema-traverse": "^0.4.1",
+                "uri-js": "^4.2.2"
+            },
+            "funding": {
+                "type": "github",
+                "url": "https://github.com/sponsors/epoberezkin"
+            }
+        },
+        "node_modules/ansi-regex": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/ansi-styles": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+            "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+            "dependencies": {
+                "color-convert": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+            }
+        },
+        "node_modules/argparse": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+            "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+            "dev": true
+        },
+        "node_modules/array-union": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+            "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/azure-devops-node-api": {
+            "version": "11.2.0",
+            "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-11.2.0.tgz",
+            "integrity": "sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA==",
+            "dev": true,
+            "dependencies": {
+                "tunnel": "0.0.6",
+                "typed-rest-client": "^1.8.4"
+            }
+        },
+        "node_modules/balanced-match": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+        },
+        "node_modules/base64-js": {
+            "version": "1.5.1",
+            "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+            "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ]
+        },
+        "node_modules/big-integer": {
+            "version": "1.6.51",
+            "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
+            "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/binary": {
+            "version": "0.3.0",
+            "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
+            "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==",
+            "dev": true,
+            "dependencies": {
+                "buffers": "~0.1.1",
+                "chainsaw": "~0.1.0"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/bl": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+            "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+            "dev": true,
+            "dependencies": {
+                "buffer": "^5.5.0",
+                "inherits": "^2.0.4",
+                "readable-stream": "^3.4.0"
+            }
+        },
+        "node_modules/bl/node_modules/readable-stream": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+            "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+            "dev": true,
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/bluebird": {
+            "version": "3.4.7",
+            "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
+            "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==",
+            "dev": true
+        },
+        "node_modules/boolbase": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+            "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+            "dev": true
+        },
+        "node_modules/brace-expansion": {
+            "version": "1.1.11",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+            "dependencies": {
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
+            }
+        },
+        "node_modules/braces": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+            "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+            "dev": true,
+            "dependencies": {
+                "fill-range": "^7.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/buffer": {
+            "version": "5.7.1",
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+            "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "dependencies": {
+                "base64-js": "^1.3.1",
+                "ieee754": "^1.1.13"
+            }
+        },
+        "node_modules/buffer-crc32": {
+            "version": "0.2.13",
+            "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+            "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+            "dev": true,
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/buffer-indexof-polyfill": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
+            "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/buffers": {
+            "version": "0.1.1",
+            "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz",
+            "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.2.0"
+            }
+        },
+        "node_modules/call-bind": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+            "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+            "dev": true,
+            "dependencies": {
+                "function-bind": "^1.1.1",
+                "get-intrinsic": "^1.0.2"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/callsites": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+            "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/chainsaw": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
+            "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==",
+            "dev": true,
+            "dependencies": {
+                "traverse": ">=0.3.0 <0.4"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/chalk": {
+            "version": "4.1.2",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+            "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+            "dev": true,
+            "dependencies": {
+                "ansi-styles": "^4.1.0",
+                "supports-color": "^7.1.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/chalk?sponsor=1"
+            }
+        },
+        "node_modules/cheerio": {
+            "version": "1.0.0-rc.12",
+            "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
+            "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
+            "dev": true,
+            "dependencies": {
+                "cheerio-select": "^2.1.0",
+                "dom-serializer": "^2.0.0",
+                "domhandler": "^5.0.3",
+                "domutils": "^3.0.1",
+                "htmlparser2": "^8.0.1",
+                "parse5": "^7.0.0",
+                "parse5-htmlparser2-tree-adapter": "^7.0.0"
+            },
+            "engines": {
+                "node": ">= 6"
+            },
+            "funding": {
+                "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+            }
+        },
+        "node_modules/cheerio-select": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+            "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+            "dev": true,
+            "dependencies": {
+                "boolbase": "^1.0.0",
+                "css-select": "^5.1.0",
+                "css-what": "^6.1.0",
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.3",
+                "domutils": "^3.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
+        "node_modules/chownr": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+            "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
+            "dev": true
+        },
+        "node_modules/ci-info": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+            "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+            "dev": true
+        },
+        "node_modules/cliui": {
+            "version": "7.0.4",
+            "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+            "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+            "dependencies": {
+                "string-width": "^4.2.0",
+                "strip-ansi": "^6.0.0",
+                "wrap-ansi": "^7.0.0"
+            }
+        },
+        "node_modules/color-convert": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+            "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+            "dependencies": {
+                "color-name": "~1.1.4"
+            },
+            "engines": {
+                "node": ">=7.0.0"
+            }
+        },
+        "node_modules/color-name": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+        },
+        "node_modules/commander": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+            "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+            "engines": {
+                "node": ">= 10"
+            }
+        },
+        "node_modules/concat-map": {
+            "version": "0.0.1",
+            "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+            "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+        },
+        "node_modules/core-util-is": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+            "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+            "dev": true
+        },
+        "node_modules/cross-env": {
+            "version": "7.0.3",
+            "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+            "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+            "dev": true,
+            "dependencies": {
+                "cross-spawn": "^7.0.1"
+            },
+            "bin": {
+                "cross-env": "src/bin/cross-env.js",
+                "cross-env-shell": "src/bin/cross-env-shell.js"
+            },
+            "engines": {
+                "node": ">=10.14",
+                "npm": ">=6",
+                "yarn": ">=1"
+            }
+        },
+        "node_modules/cross-spawn": {
+            "version": "7.0.3",
+            "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+            "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+            "dev": true,
+            "dependencies": {
+                "path-key": "^3.1.0",
+                "shebang-command": "^2.0.0",
+                "which": "^2.0.1"
+            },
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/css-select": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+            "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+            "dev": true,
+            "dependencies": {
+                "boolbase": "^1.0.0",
+                "css-what": "^6.1.0",
+                "domhandler": "^5.0.2",
+                "domutils": "^3.0.1",
+                "nth-check": "^2.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
+        "node_modules/css-what": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+            "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+            "dev": true,
+            "engines": {
+                "node": ">= 6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/fb55"
+            }
+        },
+        "node_modules/d3": {
+            "version": "7.6.1",
+            "resolved": "https://registry.npmjs.org/d3/-/d3-7.6.1.tgz",
+            "integrity": "sha512-txMTdIHFbcpLx+8a0IFhZsbp+PfBBPt8yfbmukZTQFroKuFqIwqswF0qE5JXWefylaAVpSXFoKm3yP+jpNLFLw==",
+            "dependencies": {
+                "d3-array": "3",
+                "d3-axis": "3",
+                "d3-brush": "3",
+                "d3-chord": "3",
+                "d3-color": "3",
+                "d3-contour": "4",
+                "d3-delaunay": "6",
+                "d3-dispatch": "3",
+                "d3-drag": "3",
+                "d3-dsv": "3",
+                "d3-ease": "3",
+                "d3-fetch": "3",
+                "d3-force": "3",
+                "d3-format": "3",
+                "d3-geo": "3",
+                "d3-hierarchy": "3",
+                "d3-interpolate": "3",
+                "d3-path": "3",
+                "d3-polygon": "3",
+                "d3-quadtree": "3",
+                "d3-random": "3",
+                "d3-scale": "4",
+                "d3-scale-chromatic": "3",
+                "d3-selection": "3",
+                "d3-shape": "3",
+                "d3-time": "3",
+                "d3-time-format": "4",
+                "d3-timer": "3",
+                "d3-transition": "3",
+                "d3-zoom": "3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-array": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.0.tgz",
+            "integrity": "sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g==",
+            "dependencies": {
+                "internmap": "1 - 2"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-axis": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",
+            "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-brush": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
+            "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
+            "dependencies": {
+                "d3-dispatch": "1 - 3",
+                "d3-drag": "2 - 3",
+                "d3-interpolate": "1 - 3",
+                "d3-selection": "3",
+                "d3-transition": "3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-brush/node_modules/d3-selection": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+            "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-chord": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",
+            "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
+            "dependencies": {
+                "d3-path": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-color": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
+            "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-contour": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.0.tgz",
+            "integrity": "sha512-7aQo0QHUTu/Ko3cP9YK9yUTxtoDEiDGwnBHyLxG5M4vqlBkO/uixMRele3nfsfj6UXOcuReVpVXzAboGraYIJw==",
+            "dependencies": {
+                "d3-array": "^3.2.0"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-delaunay": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.2.tgz",
+            "integrity": "sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==",
+            "dependencies": {
+                "delaunator": "5"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-dispatch": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
+            "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-drag": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
+            "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
+            "dependencies": {
+                "d3-dispatch": "1 - 3",
+                "d3-selection": "3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-drag/node_modules/d3-selection": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+            "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-dsv": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
+            "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
+            "dependencies": {
+                "commander": "7",
+                "iconv-lite": "0.6",
+                "rw": "1"
+            },
+            "bin": {
+                "csv2json": "bin/dsv2json.js",
+                "csv2tsv": "bin/dsv2dsv.js",
+                "dsv2dsv": "bin/dsv2dsv.js",
+                "dsv2json": "bin/dsv2json.js",
+                "json2csv": "bin/json2dsv.js",
+                "json2dsv": "bin/json2dsv.js",
+                "json2tsv": "bin/json2dsv.js",
+                "tsv2csv": "bin/dsv2dsv.js",
+                "tsv2json": "bin/dsv2json.js"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-ease": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
+            "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-fetch": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",
+            "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
+            "dependencies": {
+                "d3-dsv": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-force": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
+            "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
+            "dependencies": {
+                "d3-dispatch": "1 - 3",
+                "d3-quadtree": "1 - 3",
+                "d3-timer": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-format": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
+            "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-geo": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.0.1.tgz",
+            "integrity": "sha512-Wt23xBych5tSy9IYAM1FR2rWIBFWa52B/oF/GYe5zbdHrg08FU8+BuI6X4PvTwPDdqdAdq04fuWJpELtsaEjeA==",
+            "dependencies": {
+                "d3-array": "2.5.0 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-graphviz": {
+            "version": "4.1.1",
+            "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-4.1.1.tgz",
+            "integrity": "sha512-s0IVbKf8rs4eJI2xo5Umr7nXDX/LEZw/x2WtKxmlyQxR0qUY49UiLhBNOX7VDHZywMle43NKEXnU6fn22fpJvQ==",
+            "dependencies": {
+                "@hpcc-js/wasm": "1.12.8",
+                "d3-dispatch": "^2.0.0",
+                "d3-format": "^2.0.0",
+                "d3-interpolate": "^2.0.1",
+                "d3-path": "^2.0.0",
+                "d3-timer": "^2.0.0",
+                "d3-transition": "^2.0.0",
+                "d3-zoom": "^2.0.0"
+            },
+            "peerDependencies": {
+                "d3-selection": "^2.0.0"
+            }
+        },
+        "node_modules/d3-graphviz/node_modules/d3-color": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
+            "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-dispatch": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz",
+            "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-drag": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz",
+            "integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==",
+            "dependencies": {
+                "d3-dispatch": "1 - 2",
+                "d3-selection": "2"
+            }
+        },
+        "node_modules/d3-graphviz/node_modules/d3-ease": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz",
+            "integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-format": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz",
+            "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-interpolate": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
+            "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
+            "dependencies": {
+                "d3-color": "1 - 2"
+            }
+        },
+        "node_modules/d3-graphviz/node_modules/d3-path": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz",
+            "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-timer": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz",
+            "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA=="
+        },
+        "node_modules/d3-graphviz/node_modules/d3-transition": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz",
+            "integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==",
+            "dependencies": {
+                "d3-color": "1 - 2",
+                "d3-dispatch": "1 - 2",
+                "d3-ease": "1 - 2",
+                "d3-interpolate": "1 - 2",
+                "d3-timer": "1 - 2"
+            },
+            "peerDependencies": {
+                "d3-selection": "2"
+            }
+        },
+        "node_modules/d3-graphviz/node_modules/d3-zoom": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz",
+            "integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==",
+            "dependencies": {
+                "d3-dispatch": "1 - 2",
+                "d3-drag": "2",
+                "d3-interpolate": "1 - 2",
+                "d3-selection": "2",
+                "d3-transition": "2"
+            }
+        },
+        "node_modules/d3-hierarchy": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
+            "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-interpolate": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
+            "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+            "dependencies": {
+                "d3-color": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-path": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.0.1.tgz",
+            "integrity": "sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-polygon": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",
+            "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-quadtree": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
+            "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-random": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
+            "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-scale": {
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+            "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+            "dependencies": {
+                "d3-array": "2.10.0 - 3",
+                "d3-format": "1 - 3",
+                "d3-interpolate": "1.2.0 - 3",
+                "d3-time": "2.1.1 - 3",
+                "d3-time-format": "2 - 4"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-scale-chromatic": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
+            "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
+            "dependencies": {
+                "d3-color": "1 - 3",
+                "d3-interpolate": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-selection": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz",
+            "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA=="
+        },
+        "node_modules/d3-shape": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.1.0.tgz",
+            "integrity": "sha512-tGDh1Muf8kWjEDT/LswZJ8WF85yDZLvVJpYU9Nq+8+yW1Z5enxrmXOhTArlkaElU+CTn0OTVNli+/i+HP45QEQ==",
+            "dependencies": {
+                "d3-path": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-time": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.0.0.tgz",
+            "integrity": "sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ==",
+            "dependencies": {
+                "d3-array": "2 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-time-format": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+            "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+            "dependencies": {
+                "d3-time": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-timer": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+            "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3-transition": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
+            "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
+            "dependencies": {
+                "d3-color": "1 - 3",
+                "d3-dispatch": "1 - 3",
+                "d3-ease": "1 - 3",
+                "d3-interpolate": "1 - 3",
+                "d3-timer": "1 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "peerDependencies": {
+                "d3-selection": "2 - 3"
+            }
+        },
+        "node_modules/d3-zoom": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
+            "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
+            "dependencies": {
+                "d3-dispatch": "1 - 3",
+                "d3-drag": "2 - 3",
+                "d3-interpolate": "1 - 3",
+                "d3-selection": "2 - 3",
+                "d3-transition": "2 - 3"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/d3/node_modules/d3-selection": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+            "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/debug": {
+            "version": "4.3.4",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+            "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+            "dev": true,
+            "dependencies": {
+                "ms": "2.1.2"
+            },
+            "engines": {
+                "node": ">=6.0"
+            },
+            "peerDependenciesMeta": {
+                "supports-color": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/decompress-response": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+            "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+            "dev": true,
+            "dependencies": {
+                "mimic-response": "^3.1.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/deep-extend": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+            "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/deep-is": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+            "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+            "dev": true
+        },
+        "node_modules/delaunator": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz",
+            "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==",
+            "dependencies": {
+                "robust-predicates": "^3.0.0"
+            }
+        },
+        "node_modules/detect-libc": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
+            "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/dir-glob": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+            "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+            "dev": true,
+            "dependencies": {
+                "path-type": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/doctrine": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+            "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+            "dev": true,
+            "dependencies": {
+                "esutils": "^2.0.2"
+            },
+            "engines": {
+                "node": ">=6.0.0"
+            }
+        },
+        "node_modules/dom-serializer": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+            "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+            "dev": true,
+            "dependencies": {
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.2",
+                "entities": "^4.2.0"
+            },
+            "funding": {
+                "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+            }
+        },
+        "node_modules/domelementtype": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+            "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/fb55"
+                }
+            ]
+        },
+        "node_modules/domhandler": {
+            "version": "5.0.3",
+            "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+            "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+            "dev": true,
+            "dependencies": {
+                "domelementtype": "^2.3.0"
+            },
+            "engines": {
+                "node": ">= 4"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/domhandler?sponsor=1"
+            }
+        },
+        "node_modules/domutils": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
+            "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+            "dev": true,
+            "dependencies": {
+                "dom-serializer": "^2.0.0",
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.1"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/domutils?sponsor=1"
+            }
+        },
+        "node_modules/duplexer2": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+            "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==",
+            "dev": true,
+            "dependencies": {
+                "readable-stream": "^2.0.2"
+            }
+        },
+        "node_modules/emoji-regex": {
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+        },
+        "node_modules/end-of-stream": {
+            "version": "1.4.4",
+            "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+            "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+            "dev": true,
+            "dependencies": {
+                "once": "^1.4.0"
+            }
+        },
+        "node_modules/entities": {
+            "version": "4.3.1",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz",
+            "integrity": "sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.12"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
+        "node_modules/esbuild": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.48.tgz",
+            "integrity": "sha512-w6N1Yn5MtqK2U1/WZTX9ZqUVb8IOLZkZ5AdHkT6x3cHDMVsYWC7WPdiLmx19w3i4Rwzy5LqsEMtVihG3e4rFzA==",
+            "dev": true,
+            "hasInstallScript": true,
+            "bin": {
+                "esbuild": "bin/esbuild"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "optionalDependencies": {
+                "esbuild-android-64": "0.14.48",
+                "esbuild-android-arm64": "0.14.48",
+                "esbuild-darwin-64": "0.14.48",
+                "esbuild-darwin-arm64": "0.14.48",
+                "esbuild-freebsd-64": "0.14.48",
+                "esbuild-freebsd-arm64": "0.14.48",
+                "esbuild-linux-32": "0.14.48",
+                "esbuild-linux-64": "0.14.48",
+                "esbuild-linux-arm": "0.14.48",
+                "esbuild-linux-arm64": "0.14.48",
+                "esbuild-linux-mips64le": "0.14.48",
+                "esbuild-linux-ppc64le": "0.14.48",
+                "esbuild-linux-riscv64": "0.14.48",
+                "esbuild-linux-s390x": "0.14.48",
+                "esbuild-netbsd-64": "0.14.48",
+                "esbuild-openbsd-64": "0.14.48",
+                "esbuild-sunos-64": "0.14.48",
+                "esbuild-windows-32": "0.14.48",
+                "esbuild-windows-64": "0.14.48",
+                "esbuild-windows-arm64": "0.14.48"
+            }
+        },
+        "node_modules/esbuild-android-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.48.tgz",
+            "integrity": "sha512-3aMjboap/kqwCUpGWIjsk20TtxVoKck8/4Tu19rubh7t5Ra0Yrpg30Mt1QXXlipOazrEceGeWurXKeFJgkPOUg==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "android"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-android-arm64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.48.tgz",
+            "integrity": "sha512-vptI3K0wGALiDq+EvRuZotZrJqkYkN5282iAfcffjI5lmGG9G1ta/CIVauhY42MBXwEgDJkweiDcDMRLzBZC4g==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "android"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-darwin-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.48.tgz",
+            "integrity": "sha512-gGQZa4+hab2Va/Zww94YbshLuWteyKGD3+EsVon8EWTWhnHFRm5N9NbALNbwi/7hQ/hM1Zm4FuHg+k6BLsl5UA==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "darwin"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-darwin-arm64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.48.tgz",
+            "integrity": "sha512-bFjnNEXjhZT+IZ8RvRGNJthLWNHV5JkCtuOFOnjvo5pC0sk2/QVk0Qc06g2PV3J0TcU6kaPC3RN9yy9w2PSLEA==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "darwin"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-freebsd-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.48.tgz",
+            "integrity": "sha512-1NOlwRxmOsnPcWOGTB10JKAkYSb2nue0oM1AfHWunW/mv3wERfJmnYlGzL3UAOIUXZqW8GeA2mv+QGwq7DToqA==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "freebsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-freebsd-arm64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.48.tgz",
+            "integrity": "sha512-gXqKdO8wabVcYtluAbikDH2jhXp+Klq5oCD5qbVyUG6tFiGhrC9oczKq3vIrrtwcxDQqK6+HDYK8Zrd4bCA9Gw==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "freebsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-32": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.48.tgz",
+            "integrity": "sha512-ghGyDfS289z/LReZQUuuKq9KlTiTspxL8SITBFQFAFRA/IkIvDpnZnCAKTCjGXAmUqroMQfKJXMxyjJA69c/nQ==",
+            "cpu": [
+                "ia32"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.48.tgz",
+            "integrity": "sha512-vni3p/gppLMVZLghI7oMqbOZdGmLbbKR23XFARKnszCIBpEMEDxOMNIKPmMItQrmH/iJrL1z8Jt2nynY0bE1ug==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-arm": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.48.tgz",
+            "integrity": "sha512-+VfSV7Akh1XUiDNXgqgY1cUP1i2vjI+BmlyXRfVz5AfV3jbpde8JTs5Q9sYgaoq5cWfuKfoZB/QkGOI+QcL1Tw==",
+            "cpu": [
+                "arm"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-arm64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.48.tgz",
+            "integrity": "sha512-3CFsOlpoxlKPRevEHq8aAntgYGYkE1N9yRYAcPyng/p4Wyx0tPR5SBYsxLKcgPB9mR8chHEhtWYz6EZ+H199Zw==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-mips64le": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.48.tgz",
+            "integrity": "sha512-cs0uOiRlPp6ymknDnjajCgvDMSsLw5mST2UXh+ZIrXTj2Ifyf2aAP3Iw4DiqgnyYLV2O/v/yWBJx+WfmKEpNLA==",
+            "cpu": [
+                "mips64el"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-ppc64le": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.48.tgz",
+            "integrity": "sha512-+2F0vJMkuI0Wie/wcSPDCqXvSFEELH7Jubxb7mpWrA/4NpT+/byjxDz0gG6R1WJoeDefcrMfpBx4GFNN1JQorQ==",
+            "cpu": [
+                "ppc64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-riscv64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.48.tgz",
+            "integrity": "sha512-BmaK/GfEE+5F2/QDrIXteFGKnVHGxlnK9MjdVKMTfvtmudjY3k2t8NtlY4qemKSizc+QwyombGWTBDc76rxePA==",
+            "cpu": [
+                "riscv64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-linux-s390x": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.48.tgz",
+            "integrity": "sha512-tndw/0B9jiCL+KWKo0TSMaUm5UWBLsfCKVdbfMlb3d5LeV9WbijZ8Ordia8SAYv38VSJWOEt6eDCdOx8LqkC4g==",
+            "cpu": [
+                "s390x"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "linux"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-netbsd-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.48.tgz",
+            "integrity": "sha512-V9hgXfwf/T901Lr1wkOfoevtyNkrxmMcRHyticybBUHookznipMOHoF41Al68QBsqBxnITCEpjjd4yAos7z9Tw==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "netbsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-openbsd-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.48.tgz",
+            "integrity": "sha512-+IHf4JcbnnBl4T52egorXMatil/za0awqzg2Vy6FBgPcBpisDWT2sVz/tNdrK9kAqj+GZG/jZdrOkj7wsrNTKA==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "openbsd"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-sunos-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.48.tgz",
+            "integrity": "sha512-77m8bsr5wOpOWbGi9KSqDphcq6dFeJyun8TA+12JW/GAjyfTwVtOnN8DOt6DSPUfEV+ltVMNqtXUeTeMAxl5KA==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "sunos"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-windows-32": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.48.tgz",
+            "integrity": "sha512-EPgRuTPP8vK9maxpTGDe5lSoIBHGKO/AuxDncg5O3NkrPeLNdvvK8oywB0zGaAZXxYWfNNSHskvvDgmfVTguhg==",
+            "cpu": [
+                "ia32"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "win32"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-windows-64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.48.tgz",
+            "integrity": "sha512-YmpXjdT1q0b8ictSdGwH3M8VCoqPpK1/UArze3X199w6u8hUx3V8BhAi1WjbsfDYRBanVVtduAhh2sirImtAvA==",
+            "cpu": [
+                "x64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "win32"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/esbuild-windows-arm64": {
+            "version": "0.14.48",
+            "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.48.tgz",
+            "integrity": "sha512-HHaOMCsCXp0rz5BT2crTka6MPWVno121NKApsGs/OIW5QC0ggC69YMGs1aJct9/9FSUF4A1xNE/cLvgB5svR4g==",
+            "cpu": [
+                "arm64"
+            ],
+            "dev": true,
+            "optional": true,
+            "os": [
+                "win32"
+            ],
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/escalade": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+            "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/escape-string-regexp": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+            "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+            "dev": true,
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/eslint": {
+            "version": "8.19.0",
+            "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.19.0.tgz",
+            "integrity": "sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw==",
+            "dev": true,
+            "dependencies": {
+                "@eslint/eslintrc": "^1.3.0",
+                "@humanwhocodes/config-array": "^0.9.2",
+                "ajv": "^6.10.0",
+                "chalk": "^4.0.0",
+                "cross-spawn": "^7.0.2",
+                "debug": "^4.3.2",
+                "doctrine": "^3.0.0",
+                "escape-string-regexp": "^4.0.0",
+                "eslint-scope": "^7.1.1",
+                "eslint-utils": "^3.0.0",
+                "eslint-visitor-keys": "^3.3.0",
+                "espree": "^9.3.2",
+                "esquery": "^1.4.0",
+                "esutils": "^2.0.2",
+                "fast-deep-equal": "^3.1.3",
+                "file-entry-cache": "^6.0.1",
+                "functional-red-black-tree": "^1.0.1",
+                "glob-parent": "^6.0.1",
+                "globals": "^13.15.0",
+                "ignore": "^5.2.0",
+                "import-fresh": "^3.0.0",
+                "imurmurhash": "^0.1.4",
+                "is-glob": "^4.0.0",
+                "js-yaml": "^4.1.0",
+                "json-stable-stringify-without-jsonify": "^1.0.1",
+                "levn": "^0.4.1",
+                "lodash.merge": "^4.6.2",
+                "minimatch": "^3.1.2",
+                "natural-compare": "^1.4.0",
+                "optionator": "^0.9.1",
+                "regexpp": "^3.2.0",
+                "strip-ansi": "^6.0.1",
+                "strip-json-comments": "^3.1.0",
+                "text-table": "^0.2.0",
+                "v8-compile-cache": "^2.0.3"
+            },
+            "bin": {
+                "eslint": "bin/eslint.js"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://opencollective.com/eslint"
+            }
+        },
+        "node_modules/eslint-config-prettier": {
+            "version": "8.5.0",
+            "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
+            "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
+            "dev": true,
+            "bin": {
+                "eslint-config-prettier": "bin/cli.js"
+            },
+            "peerDependencies": {
+                "eslint": ">=7.0.0"
+            }
+        },
+        "node_modules/eslint-scope": {
+            "version": "5.1.1",
+            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+            "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+            "dev": true,
+            "dependencies": {
+                "esrecurse": "^4.3.0",
+                "estraverse": "^4.1.1"
+            },
+            "engines": {
+                "node": ">=8.0.0"
+            }
+        },
+        "node_modules/eslint-utils": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+            "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+            "dev": true,
+            "dependencies": {
+                "eslint-visitor-keys": "^2.0.0"
+            },
+            "engines": {
+                "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/mysticatea"
+            },
+            "peerDependencies": {
+                "eslint": ">=5"
+            }
+        },
+        "node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+            "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+            "dev": true,
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/eslint-visitor-keys": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz",
+            "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==",
+            "dev": true,
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            }
+        },
+        "node_modules/eslint/node_modules/eslint-scope": {
+            "version": "7.1.1",
+            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
+            "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
+            "dev": true,
+            "dependencies": {
+                "esrecurse": "^4.3.0",
+                "estraverse": "^5.2.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            }
+        },
+        "node_modules/eslint/node_modules/estraverse": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+            "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/espree": {
+            "version": "9.3.2",
+            "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
+            "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+            "dev": true,
+            "dependencies": {
+                "acorn": "^8.7.1",
+                "acorn-jsx": "^5.3.2",
+                "eslint-visitor-keys": "^3.3.0"
+            },
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            }
+        },
+        "node_modules/esquery": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz",
+            "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==",
+            "dev": true,
+            "dependencies": {
+                "estraverse": "^5.1.0"
+            },
+            "engines": {
+                "node": ">=0.10"
+            }
+        },
+        "node_modules/esquery/node_modules/estraverse": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+            "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/esrecurse": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+            "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+            "dev": true,
+            "dependencies": {
+                "estraverse": "^5.2.0"
+            },
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/esrecurse/node_modules/estraverse": {
+            "version": "5.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+            "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/estraverse": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+            "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/esutils": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+            "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/expand-template": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+            "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/fast-deep-equal": {
+            "version": "3.1.3",
+            "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+            "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+            "dev": true
+        },
+        "node_modules/fast-glob": {
+            "version": "3.2.11",
+            "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
+            "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==",
+            "dev": true,
+            "dependencies": {
+                "@nodelib/fs.stat": "^2.0.2",
+                "@nodelib/fs.walk": "^1.2.3",
+                "glob-parent": "^5.1.2",
+                "merge2": "^1.3.0",
+                "micromatch": "^4.0.4"
+            },
+            "engines": {
+                "node": ">=8.6.0"
+            }
+        },
+        "node_modules/fast-glob/node_modules/glob-parent": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+            "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+            "dev": true,
+            "dependencies": {
+                "is-glob": "^4.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/fast-json-stable-stringify": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+            "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+            "dev": true
+        },
+        "node_modules/fast-levenshtein": {
+            "version": "2.0.6",
+            "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+            "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+            "dev": true
+        },
+        "node_modules/fastq": {
+            "version": "1.13.0",
+            "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz",
+            "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==",
+            "dev": true,
+            "dependencies": {
+                "reusify": "^1.0.4"
+            }
+        },
+        "node_modules/fd-slicer": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+            "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+            "dev": true,
+            "dependencies": {
+                "pend": "~1.2.0"
+            }
+        },
+        "node_modules/file-entry-cache": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+            "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+            "dev": true,
+            "dependencies": {
+                "flat-cache": "^3.0.4"
+            },
+            "engines": {
+                "node": "^10.12.0 || >=12.0.0"
+            }
+        },
+        "node_modules/fill-range": {
+            "version": "7.0.1",
+            "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+            "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+            "dev": true,
+            "dependencies": {
+                "to-regex-range": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/flat-cache": {
+            "version": "3.0.4",
+            "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+            "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+            "dev": true,
+            "dependencies": {
+                "flatted": "^3.1.0",
+                "rimraf": "^3.0.2"
+            },
+            "engines": {
+                "node": "^10.12.0 || >=12.0.0"
+            }
+        },
+        "node_modules/flatted": {
+            "version": "3.2.6",
+            "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz",
+            "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==",
+            "dev": true
+        },
+        "node_modules/follow-redirects": {
+            "version": "1.15.1",
+            "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz",
+            "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "individual",
+                    "url": "https://github.com/sponsors/RubenVerborgh"
+                }
+            ],
+            "engines": {
+                "node": ">=4.0"
+            },
+            "peerDependenciesMeta": {
+                "debug": {
+                    "optional": true
+                }
+            }
+        },
+        "node_modules/fs-constants": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+            "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+            "dev": true
+        },
+        "node_modules/fs.realpath": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+            "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+            "dev": true
+        },
+        "node_modules/fstream": {
+            "version": "1.0.12",
+            "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
+            "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+            "dev": true,
+            "dependencies": {
+                "graceful-fs": "^4.1.2",
+                "inherits": "~2.0.0",
+                "mkdirp": ">=0.5 0",
+                "rimraf": "2"
+            },
+            "engines": {
+                "node": ">=0.6"
+            }
+        },
+        "node_modules/fstream/node_modules/rimraf": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+            "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            }
+        },
+        "node_modules/function-bind": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+            "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+            "dev": true
+        },
+        "node_modules/functional-red-black-tree": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+            "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
+            "dev": true
+        },
+        "node_modules/get-caller-file": {
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+            "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+            "engines": {
+                "node": "6.* || 8.* || >= 10.*"
+            }
+        },
+        "node_modules/get-intrinsic": {
+            "version": "1.1.2",
+            "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+            "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
+            "dev": true,
+            "dependencies": {
+                "function-bind": "^1.1.1",
+                "has": "^1.0.3",
+                "has-symbols": "^1.0.3"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/github-from-package": {
+            "version": "0.0.0",
+            "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+            "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
+            "dev": true
+        },
+        "node_modules/glob": {
+            "version": "7.2.3",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+            "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+            "dev": true,
+            "dependencies": {
+                "fs.realpath": "^1.0.0",
+                "inflight": "^1.0.4",
+                "inherits": "2",
+                "minimatch": "^3.1.1",
+                "once": "^1.3.0",
+                "path-is-absolute": "^1.0.0"
+            },
+            "engines": {
+                "node": "*"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/glob-parent": {
+            "version": "6.0.2",
+            "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+            "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+            "dev": true,
+            "dependencies": {
+                "is-glob": "^4.0.3"
+            },
+            "engines": {
+                "node": ">=10.13.0"
+            }
+        },
+        "node_modules/globals": {
+            "version": "13.16.0",
+            "resolved": "https://registry.npmjs.org/globals/-/globals-13.16.0.tgz",
+            "integrity": "sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q==",
+            "dev": true,
+            "dependencies": {
+                "type-fest": "^0.20.2"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/globby": {
+            "version": "11.1.0",
+            "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+            "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+            "dev": true,
+            "dependencies": {
+                "array-union": "^2.1.0",
+                "dir-glob": "^3.0.1",
+                "fast-glob": "^3.2.9",
+                "ignore": "^5.2.0",
+                "merge2": "^1.4.1",
+                "slash": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/graceful-fs": {
+            "version": "4.2.10",
+            "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+            "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+            "dev": true
+        },
+        "node_modules/has": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+            "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+            "dev": true,
+            "dependencies": {
+                "function-bind": "^1.1.1"
+            },
+            "engines": {
+                "node": ">= 0.4.0"
+            }
+        },
+        "node_modules/has-flag": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+            "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/has-symbols": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+            "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/hosted-git-info": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
+            "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
+            "dev": true,
+            "dependencies": {
+                "lru-cache": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/htmlparser2": {
+            "version": "8.0.1",
+            "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
+            "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
+            "dev": true,
+            "funding": [
+                "https://github.com/fb55/htmlparser2?sponsor=1",
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/fb55"
+                }
+            ],
+            "dependencies": {
+                "domelementtype": "^2.3.0",
+                "domhandler": "^5.0.2",
+                "domutils": "^3.0.1",
+                "entities": "^4.3.0"
+            }
+        },
+        "node_modules/http-proxy-agent": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
+            "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+            "dev": true,
+            "dependencies": {
+                "@tootallnate/once": "1",
+                "agent-base": "6",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/https-proxy-agent": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+            "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+            "dev": true,
+            "dependencies": {
+                "agent-base": "6",
+                "debug": "4"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/iconv-lite": {
+            "version": "0.6.3",
+            "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+            "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+            "dependencies": {
+                "safer-buffer": ">= 2.1.2 < 3.0.0"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/ieee754": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+            "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ]
+        },
+        "node_modules/ignore": {
+            "version": "5.2.0",
+            "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
+            "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+            "dev": true,
+            "engines": {
+                "node": ">= 4"
+            }
+        },
+        "node_modules/import-fresh": {
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+            "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+            "dev": true,
+            "dependencies": {
+                "parent-module": "^1.0.0",
+                "resolve-from": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/imurmurhash": {
+            "version": "0.1.4",
+            "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+            "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.8.19"
+            }
+        },
+        "node_modules/inflight": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+            "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+            "dev": true,
+            "dependencies": {
+                "once": "^1.3.0",
+                "wrappy": "1"
+            }
+        },
+        "node_modules/inherits": {
+            "version": "2.0.4",
+            "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+            "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+            "dev": true
+        },
+        "node_modules/ini": {
+            "version": "1.3.8",
+            "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+            "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+            "dev": true
+        },
+        "node_modules/internmap": {
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
+            "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/is-ci": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+            "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+            "dev": true,
+            "dependencies": {
+                "ci-info": "^2.0.0"
+            },
+            "bin": {
+                "is-ci": "bin.js"
+            }
+        },
+        "node_modules/is-extglob": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+            "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-fullwidth-code-point": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+            "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/is-glob": {
+            "version": "4.0.3",
+            "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+            "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+            "dev": true,
+            "dependencies": {
+                "is-extglob": "^2.1.1"
+            },
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/is-number": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+            "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.12.0"
+            }
+        },
+        "node_modules/isarray": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+            "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+            "dev": true
+        },
+        "node_modules/isexe": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+            "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+            "dev": true
+        },
+        "node_modules/js-yaml": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+            "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+            "dev": true,
+            "dependencies": {
+                "argparse": "^2.0.1"
+            },
+            "bin": {
+                "js-yaml": "bin/js-yaml.js"
+            }
+        },
+        "node_modules/json-schema-traverse": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+            "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+            "dev": true
+        },
+        "node_modules/json-stable-stringify-without-jsonify": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+            "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+            "dev": true
+        },
+        "node_modules/keytar": {
+            "version": "7.9.0",
+            "resolved": "https://registry.npmjs.org/keytar/-/keytar-7.9.0.tgz",
+            "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==",
+            "dev": true,
+            "hasInstallScript": true,
+            "dependencies": {
+                "node-addon-api": "^4.3.0",
+                "prebuild-install": "^7.0.1"
+            }
+        },
+        "node_modules/leven": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+            "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/levn": {
+            "version": "0.4.1",
+            "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+            "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+            "dev": true,
+            "dependencies": {
+                "prelude-ls": "^1.2.1",
+                "type-check": "~0.4.0"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/linkify-it": {
+            "version": "3.0.3",
+            "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
+            "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
+            "dev": true,
+            "dependencies": {
+                "uc.micro": "^1.0.1"
+            }
+        },
+        "node_modules/listenercount": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz",
+            "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==",
+            "dev": true
+        },
+        "node_modules/lodash.merge": {
+            "version": "4.6.2",
+            "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+            "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+            "dev": true
+        },
+        "node_modules/lru-cache": {
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+            "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+            "dependencies": {
+                "yallist": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/markdown-it": {
+            "version": "12.3.2",
+            "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz",
+            "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==",
+            "dev": true,
+            "dependencies": {
+                "argparse": "^2.0.1",
+                "entities": "~2.1.0",
+                "linkify-it": "^3.0.1",
+                "mdurl": "^1.0.1",
+                "uc.micro": "^1.0.5"
+            },
+            "bin": {
+                "markdown-it": "bin/markdown-it.js"
+            }
+        },
+        "node_modules/markdown-it/node_modules/entities": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+            "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==",
+            "dev": true,
+            "funding": {
+                "url": "https://github.com/fb55/entities?sponsor=1"
+            }
+        },
+        "node_modules/mdurl": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+            "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==",
+            "dev": true
+        },
+        "node_modules/merge2": {
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+            "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+            "dev": true,
+            "engines": {
+                "node": ">= 8"
+            }
+        },
+        "node_modules/micromatch": {
+            "version": "4.0.5",
+            "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+            "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+            "dev": true,
+            "dependencies": {
+                "braces": "^3.0.2",
+                "picomatch": "^2.3.1"
+            },
+            "engines": {
+                "node": ">=8.6"
+            }
+        },
+        "node_modules/mime": {
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+            "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+            "dev": true,
+            "bin": {
+                "mime": "cli.js"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/mimic-response": {
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+            "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/minimatch": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+            "dependencies": {
+                "brace-expansion": "^1.1.7"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/minimist": {
+            "version": "1.2.6",
+            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
+            "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
+            "dev": true
+        },
+        "node_modules/mkdirp": {
+            "version": "0.5.6",
+            "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+            "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+            "dev": true,
+            "dependencies": {
+                "minimist": "^1.2.6"
+            },
+            "bin": {
+                "mkdirp": "bin/cmd.js"
+            }
+        },
+        "node_modules/mkdirp-classic": {
+            "version": "0.5.3",
+            "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+            "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
+            "dev": true
+        },
+        "node_modules/ms": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+            "dev": true
+        },
+        "node_modules/mute-stream": {
+            "version": "0.0.8",
+            "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+            "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+            "dev": true
+        },
+        "node_modules/napi-build-utils": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+            "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
+            "dev": true
+        },
+        "node_modules/natural-compare": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+            "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+            "dev": true
+        },
+        "node_modules/node-abi": {
+            "version": "3.22.0",
+            "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.22.0.tgz",
+            "integrity": "sha512-u4uAs/4Zzmp/jjsD9cyFYDXeISfUWaAVWshPmDZOFOv4Xl4SbzTXm53I04C2uRueYJ+0t5PEtLH/owbn2Npf/w==",
+            "dev": true,
+            "dependencies": {
+                "semver": "^7.3.5"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/node-addon-api": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
+            "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",
+            "dev": true
+        },
+        "node_modules/nth-check": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+            "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+            "dev": true,
+            "dependencies": {
+                "boolbase": "^1.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/nth-check?sponsor=1"
+            }
+        },
+        "node_modules/object-inspect": {
+            "version": "1.12.2",
+            "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
+            "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+            "dev": true,
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/once": {
+            "version": "1.4.0",
+            "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+            "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+            "dev": true,
+            "dependencies": {
+                "wrappy": "1"
+            }
+        },
+        "node_modules/optionator": {
+            "version": "0.9.1",
+            "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+            "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+            "dev": true,
+            "dependencies": {
+                "deep-is": "^0.1.3",
+                "fast-levenshtein": "^2.0.6",
+                "levn": "^0.4.1",
+                "prelude-ls": "^1.2.1",
+                "type-check": "^0.4.0",
+                "word-wrap": "^1.2.3"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/ovsx": {
+            "version": "0.5.1",
+            "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.5.1.tgz",
+            "integrity": "sha512-3OWq0l7DuVHi2bd2aQe5+QVQlFIqvrcw3/2vGXL404L6Tr+R4QHtzfnYYghv8CCa85xJHjU0RhcaC7pyXkAUbg==",
+            "dev": true,
+            "dependencies": {
+                "commander": "^6.1.0",
+                "follow-redirects": "^1.14.6",
+                "is-ci": "^2.0.0",
+                "leven": "^3.1.0",
+                "tmp": "^0.2.1",
+                "vsce": "^2.6.3"
+            },
+            "bin": {
+                "ovsx": "lib/ovsx"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/ovsx/node_modules/commander": {
+            "version": "6.2.1",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+            "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+            "dev": true,
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/parent-module": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+            "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+            "dev": true,
+            "dependencies": {
+                "callsites": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/parse-semver": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
+            "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==",
+            "dev": true,
+            "dependencies": {
+                "semver": "^5.1.0"
+            }
+        },
+        "node_modules/parse-semver/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/parse5": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz",
+            "integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==",
+            "dev": true,
+            "dependencies": {
+                "entities": "^4.3.0"
+            },
+            "funding": {
+                "url": "https://github.com/inikulin/parse5?sponsor=1"
+            }
+        },
+        "node_modules/parse5-htmlparser2-tree-adapter": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
+            "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
+            "dev": true,
+            "dependencies": {
+                "domhandler": "^5.0.2",
+                "parse5": "^7.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/inikulin/parse5?sponsor=1"
+            }
+        },
+        "node_modules/path-is-absolute": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+            "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/path-key": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+            "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/path-type": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+            "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/pend": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+            "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+            "dev": true
+        },
+        "node_modules/picomatch": {
+            "version": "2.3.1",
+            "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+            "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+            "dev": true,
+            "engines": {
+                "node": ">=8.6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/jonschlinkert"
+            }
+        },
+        "node_modules/prebuild-install": {
+            "version": "7.1.1",
+            "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
+            "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
+            "dev": true,
+            "dependencies": {
+                "detect-libc": "^2.0.0",
+                "expand-template": "^2.0.3",
+                "github-from-package": "0.0.0",
+                "minimist": "^1.2.3",
+                "mkdirp-classic": "^0.5.3",
+                "napi-build-utils": "^1.0.1",
+                "node-abi": "^3.3.0",
+                "pump": "^3.0.0",
+                "rc": "^1.2.7",
+                "simple-get": "^4.0.0",
+                "tar-fs": "^2.0.0",
+                "tunnel-agent": "^0.6.0"
+            },
+            "bin": {
+                "prebuild-install": "bin.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/prelude-ls": {
+            "version": "1.2.1",
+            "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+            "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+            "dev": true,
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/prettier": {
+            "version": "2.7.1",
+            "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
+            "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
+            "dev": true,
+            "bin": {
+                "prettier": "bin-prettier.js"
+            },
+            "engines": {
+                "node": ">=10.13.0"
+            },
+            "funding": {
+                "url": "https://github.com/prettier/prettier?sponsor=1"
+            }
+        },
+        "node_modules/process-nextick-args": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+            "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+            "dev": true
+        },
+        "node_modules/pump": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+            "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+            "dev": true,
+            "dependencies": {
+                "end-of-stream": "^1.1.0",
+                "once": "^1.3.1"
+            }
+        },
+        "node_modules/punycode": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+            "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+            "dev": true,
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/qs": {
+            "version": "6.11.0",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
+            "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
+            "dev": true,
+            "dependencies": {
+                "side-channel": "^1.0.4"
+            },
+            "engines": {
+                "node": ">=0.6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/queue-microtask": {
+            "version": "1.2.3",
+            "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+            "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ]
+        },
+        "node_modules/rc": {
+            "version": "1.2.8",
+            "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+            "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+            "dev": true,
+            "dependencies": {
+                "deep-extend": "^0.6.0",
+                "ini": "~1.3.0",
+                "minimist": "^1.2.0",
+                "strip-json-comments": "~2.0.1"
+            },
+            "bin": {
+                "rc": "cli.js"
+            }
+        },
+        "node_modules/rc/node_modules/strip-json-comments": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+            "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/read": {
+            "version": "1.0.7",
+            "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+            "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==",
+            "dev": true,
+            "dependencies": {
+                "mute-stream": "~0.0.4"
+            },
+            "engines": {
+                "node": ">=0.8"
+            }
+        },
+        "node_modules/readable-stream": {
+            "version": "2.3.7",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+            "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+            "dev": true,
+            "dependencies": {
+                "core-util-is": "~1.0.0",
+                "inherits": "~2.0.3",
+                "isarray": "~1.0.0",
+                "process-nextick-args": "~2.0.0",
+                "safe-buffer": "~5.1.1",
+                "string_decoder": "~1.1.1",
+                "util-deprecate": "~1.0.1"
+            }
+        },
+        "node_modules/regexpp": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
+            "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/mysticatea"
+            }
+        },
+        "node_modules/require-directory": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+            "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/resolve-from": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+            "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/reusify": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+            "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+            "dev": true,
+            "engines": {
+                "iojs": ">=1.0.0",
+                "node": ">=0.10.0"
+            }
+        },
+        "node_modules/rimraf": {
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+            "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+            "dev": true,
+            "dependencies": {
+                "glob": "^7.1.3"
+            },
+            "bin": {
+                "rimraf": "bin.js"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
+            }
+        },
+        "node_modules/robust-predicates": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz",
+            "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g=="
+        },
+        "node_modules/run-parallel": {
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+            "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "dependencies": {
+                "queue-microtask": "^1.2.2"
+            }
+        },
+        "node_modules/rw": {
+            "version": "1.3.3",
+            "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+            "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="
+        },
+        "node_modules/safe-buffer": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+            "dev": true
+        },
+        "node_modules/safer-buffer": {
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+            "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+        },
+        "node_modules/sax": {
+            "version": "1.2.4",
+            "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+            "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+            "dev": true
+        },
+        "node_modules/semver": {
+            "version": "7.3.7",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
+            "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
+            "dependencies": {
+                "lru-cache": "^6.0.0"
+            },
+            "bin": {
+                "semver": "bin/semver.js"
+            },
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/setimmediate": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+            "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+            "dev": true
+        },
+        "node_modules/shebang-command": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+            "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+            "dev": true,
+            "dependencies": {
+                "shebang-regex": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/shebang-regex": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+            "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/side-channel": {
+            "version": "1.0.4",
+            "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+            "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+            "dev": true,
+            "dependencies": {
+                "call-bind": "^1.0.0",
+                "get-intrinsic": "^1.0.2",
+                "object-inspect": "^1.9.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/simple-concat": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+            "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ]
+        },
+        "node_modules/simple-get": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
+            "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "dependencies": {
+                "decompress-response": "^6.0.0",
+                "once": "^1.3.1",
+                "simple-concat": "^1.0.0"
+            }
+        },
+        "node_modules/slash": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+            "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/string_decoder": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+            "dev": true,
+            "dependencies": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
+        "node_modules/string-width": {
+            "version": "4.2.3",
+            "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+            "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+            "dependencies": {
+                "emoji-regex": "^8.0.0",
+                "is-fullwidth-code-point": "^3.0.0",
+                "strip-ansi": "^6.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/strip-ansi": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+            "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+            "dependencies": {
+                "ansi-regex": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/strip-json-comments": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+            "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+            "dev": true,
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/supports-color": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+            "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+            "dev": true,
+            "dependencies": {
+                "has-flag": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/tar-fs": {
+            "version": "2.1.1",
+            "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+            "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+            "dev": true,
+            "dependencies": {
+                "chownr": "^1.1.1",
+                "mkdirp-classic": "^0.5.2",
+                "pump": "^3.0.0",
+                "tar-stream": "^2.1.4"
+            }
+        },
+        "node_modules/tar-stream": {
+            "version": "2.2.0",
+            "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+            "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+            "dev": true,
+            "dependencies": {
+                "bl": "^4.0.3",
+                "end-of-stream": "^1.4.1",
+                "fs-constants": "^1.0.0",
+                "inherits": "^2.0.3",
+                "readable-stream": "^3.1.1"
+            },
+            "engines": {
+                "node": ">=6"
+            }
+        },
+        "node_modules/tar-stream/node_modules/readable-stream": {
+            "version": "3.6.0",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+            "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+            "dev": true,
+            "dependencies": {
+                "inherits": "^2.0.3",
+                "string_decoder": "^1.1.1",
+                "util-deprecate": "^1.0.1"
+            },
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/text-table": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+            "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+            "dev": true
+        },
+        "node_modules/tmp": {
+            "version": "0.2.1",
+            "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+            "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+            "dev": true,
+            "dependencies": {
+                "rimraf": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=8.17.0"
+            }
+        },
+        "node_modules/to-regex-range": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+            "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+            "dev": true,
+            "dependencies": {
+                "is-number": "^7.0.0"
+            },
+            "engines": {
+                "node": ">=8.0"
+            }
+        },
+        "node_modules/traverse": {
+            "version": "0.3.9",
+            "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz",
+            "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==",
+            "dev": true,
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/tslib": {
+            "version": "2.4.0",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
+            "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
+            "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": ">= 6"
+            },
+            "peerDependencies": {
+                "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/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": {
+            "version": "0.0.6",
+            "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+            "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.6.11 <=0.7.0 || >=0.7.3"
+            }
+        },
+        "node_modules/tunnel-agent": {
+            "version": "0.6.0",
+            "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+            "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+            "dev": true,
+            "dependencies": {
+                "safe-buffer": "^5.0.1"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/type-check": {
+            "version": "0.4.0",
+            "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+            "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+            "dev": true,
+            "dependencies": {
+                "prelude-ls": "^1.2.1"
+            },
+            "engines": {
+                "node": ">= 0.8.0"
+            }
+        },
+        "node_modules/type-fest": {
+            "version": "0.20.2",
+            "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+            "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+            "dev": true,
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/typed-rest-client": {
+            "version": "1.8.9",
+            "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.9.tgz",
+            "integrity": "sha512-uSmjE38B80wjL85UFX3sTYEUlvZ1JgCRhsWj/fJ4rZ0FqDUFoIuodtiVeE+cUqiVTOKPdKrp/sdftD15MDek6g==",
+            "dev": true,
+            "dependencies": {
+                "qs": "^6.9.1",
+                "tunnel": "0.0.6",
+                "underscore": "^1.12.1"
+            }
+        },
+        "node_modules/typescript": {
+            "version": "4.7.4",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
+            "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
+            "dev": true,
+            "bin": {
+                "tsc": "bin/tsc",
+                "tsserver": "bin/tsserver"
+            },
+            "engines": {
+                "node": ">=4.2.0"
+            }
+        },
+        "node_modules/uc.micro": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+            "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+            "dev": true
+        },
+        "node_modules/underscore": {
+            "version": "1.13.4",
+            "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.4.tgz",
+            "integrity": "sha512-BQFnUDuAQ4Yf/cYY5LNrK9NCJFKriaRbD9uR1fTeXnBeoa97W0i41qkZfGO9pSo8I5KzjAcSY2XYtdf0oKd7KQ==",
+            "dev": true
+        },
+        "node_modules/unzipper": {
+            "version": "0.10.11",
+            "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz",
+            "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==",
+            "dev": true,
+            "dependencies": {
+                "big-integer": "^1.6.17",
+                "binary": "~0.3.0",
+                "bluebird": "~3.4.1",
+                "buffer-indexof-polyfill": "~1.0.0",
+                "duplexer2": "~0.1.4",
+                "fstream": "^1.0.12",
+                "graceful-fs": "^4.2.2",
+                "listenercount": "~1.0.1",
+                "readable-stream": "~2.3.6",
+                "setimmediate": "~1.0.4"
+            }
+        },
+        "node_modules/uri-js": {
+            "version": "4.4.1",
+            "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+            "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+            "dev": true,
+            "dependencies": {
+                "punycode": "^2.1.0"
+            }
+        },
+        "node_modules/url-join": {
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+            "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
+            "dev": true
+        },
+        "node_modules/util-deprecate": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+            "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+            "dev": true
+        },
+        "node_modules/v8-compile-cache": {
+            "version": "2.3.0",
+            "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
+            "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
+            "dev": true
+        },
+        "node_modules/vsce": {
+            "version": "2.9.2",
+            "resolved": "https://registry.npmjs.org/vsce/-/vsce-2.9.2.tgz",
+            "integrity": "sha512-xyLqL4U82BilUX1t6Ym2opQEa2tLGWYjbgB7+ETeNVXlIJz5sWBJjQJSYJVFOKJSpiOtQclolu88cj7oY6vvPQ==",
+            "dev": true,
+            "dependencies": {
+                "azure-devops-node-api": "^11.0.1",
+                "chalk": "^2.4.2",
+                "cheerio": "^1.0.0-rc.9",
+                "commander": "^6.1.0",
+                "glob": "^7.0.6",
+                "hosted-git-info": "^4.0.2",
+                "keytar": "^7.7.0",
+                "leven": "^3.1.0",
+                "markdown-it": "^12.3.2",
+                "mime": "^1.3.4",
+                "minimatch": "^3.0.3",
+                "parse-semver": "^1.1.1",
+                "read": "^1.0.7",
+                "semver": "^5.1.0",
+                "tmp": "^0.2.1",
+                "typed-rest-client": "^1.8.4",
+                "url-join": "^4.0.1",
+                "xml2js": "^0.4.23",
+                "yauzl": "^2.3.1",
+                "yazl": "^2.2.2"
+            },
+            "bin": {
+                "vsce": "vsce"
+            },
+            "engines": {
+                "node": ">= 14"
+            }
+        },
+        "node_modules/vsce/node_modules/ansi-styles": {
+            "version": "3.2.1",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+            "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+            "dev": true,
+            "dependencies": {
+                "color-convert": "^1.9.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/vsce/node_modules/chalk": {
+            "version": "2.4.2",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+            "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+            "dev": true,
+            "dependencies": {
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/vsce/node_modules/color-convert": {
+            "version": "1.9.3",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+            "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+            "dev": true,
+            "dependencies": {
+                "color-name": "1.1.3"
+            }
+        },
+        "node_modules/vsce/node_modules/color-name": {
+            "version": "1.1.3",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+            "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+            "dev": true
+        },
+        "node_modules/vsce/node_modules/commander": {
+            "version": "6.2.1",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+            "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+            "dev": true,
+            "engines": {
+                "node": ">= 6"
+            }
+        },
+        "node_modules/vsce/node_modules/escape-string-regexp": {
+            "version": "1.0.5",
+            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+            "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+            "dev": true,
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
+        "node_modules/vsce/node_modules/has-flag": {
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+            "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+            "dev": true,
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/vsce/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/vsce/node_modules/supports-color": {
+            "version": "5.5.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+            "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+            "dev": true,
+            "dependencies": {
+                "has-flag": "^3.0.0"
+            },
+            "engines": {
+                "node": ">=4"
+            }
+        },
+        "node_modules/vscode-jsonrpc": {
+            "version": "8.0.0-next.7",
+            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.0.0-next.7.tgz",
+            "integrity": "sha512-JX/F31LEsims0dAlOTKFE4E+AJMiJvdRSRViifFJSqSN7EzeYyWlfuDchF7g91oRNPZOIWfibTkDf3/UMsQGzQ==",
+            "engines": {
+                "node": ">=14.0.0"
+            }
+        },
+        "node_modules/vscode-languageclient": {
+            "version": "8.0.0-next.14",
+            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-8.0.0-next.14.tgz",
+            "integrity": "sha512-NqjkOuDTMu8uo+PhoMsV72VO9Gd3wBi/ZpOrkRUOrWKQo7yUdiIw183g8wjH8BImgbK9ZP51HM7TI0ZhCnI1Mw==",
+            "dependencies": {
+                "minimatch": "^3.0.4",
+                "semver": "^7.3.5",
+                "vscode-languageserver-protocol": "3.17.0-next.16"
+            },
+            "engines": {
+                "vscode": "^1.66.0"
+            }
+        },
+        "node_modules/vscode-languageserver-protocol": {
+            "version": "3.17.0-next.16",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.0-next.16.tgz",
+            "integrity": "sha512-tx4DnXw9u3N7vw+bx6n2NKp6FoxoNwiP/biH83AS30I2AnTGyLd7afSeH6Oewn2E8jvB7K15bs12sMppkKOVeQ==",
+            "dependencies": {
+                "vscode-jsonrpc": "8.0.0-next.7",
+                "vscode-languageserver-types": "3.17.0-next.9"
+            }
+        },
+        "node_modules/vscode-languageserver-types": {
+            "version": "3.17.0-next.9",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.0-next.9.tgz",
+            "integrity": "sha512-9/PeDNPYduaoXRUzYpqmu4ZV9L01HGo0wH9FUt+sSHR7IXwA7xoXBfNUlv8gB9H0D2WwEmMomSy1NmhjKQyn3A=="
+        },
+        "node_modules/which": {
+            "version": "2.0.2",
+            "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+            "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+            "dev": true,
+            "dependencies": {
+                "isexe": "^2.0.0"
+            },
+            "bin": {
+                "node-which": "bin/node-which"
+            },
+            "engines": {
+                "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",
+            "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+            "dependencies": {
+                "ansi-styles": "^4.0.0",
+                "string-width": "^4.1.0",
+                "strip-ansi": "^6.0.0"
+            },
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+            }
+        },
+        "node_modules/wrappy": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+            "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+            "dev": true
+        },
+        "node_modules/xml2js": {
+            "version": "0.4.23",
+            "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
+            "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+            "dev": true,
+            "dependencies": {
+                "sax": ">=0.6.0",
+                "xmlbuilder": "~11.0.0"
+            },
+            "engines": {
+                "node": ">=4.0.0"
+            }
+        },
+        "node_modules/xmlbuilder": {
+            "version": "11.0.1",
+            "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+            "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
+            "dev": true,
+            "engines": {
+                "node": ">=4.0"
+            }
+        },
+        "node_modules/y18n": {
+            "version": "5.0.8",
+            "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+            "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+            "engines": {
+                "node": ">=10"
+            }
+        },
+        "node_modules/yallist": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+        },
+        "node_modules/yargs": {
+            "version": "17.5.1",
+            "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz",
+            "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==",
+            "dependencies": {
+                "cliui": "^7.0.2",
+                "escalade": "^3.1.1",
+                "get-caller-file": "^2.0.5",
+                "require-directory": "^2.1.1",
+                "string-width": "^4.2.3",
+                "y18n": "^5.0.5",
+                "yargs-parser": "^21.0.0"
+            },
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/yargs-parser": {
+            "version": "21.0.1",
+            "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz",
+            "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==",
+            "engines": {
+                "node": ">=12"
+            }
+        },
+        "node_modules/yauzl": {
+            "version": "2.10.0",
+            "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+            "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+            "dev": true,
+            "dependencies": {
+                "buffer-crc32": "~0.2.3",
+                "fd-slicer": "~1.1.0"
+            }
+        },
+        "node_modules/yazl": {
+            "version": "2.5.1",
+            "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
+            "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
+            "dev": true,
+            "dependencies": {
+                "buffer-crc32": "~0.2.3"
+            }
+        }
+    },
     "dependencies": {
         "@eslint/eslintrc": {
             "version": "1.3.0",
@@ -213,7 +4161,8 @@
             "version": "5.3.2",
             "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
             "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-            "dev": true
+            "dev": true,
+            "requires": {}
         },
         "agent-base": {
             "version": "6.0.2",
@@ -1278,7 +5227,8 @@
             "version": "8.5.0",
             "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
             "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
-            "dev": true
+            "dev": true,
+            "requires": {}
         },
         "eslint-scope": {
             "version": "5.1.1",
@@ -2348,6 +6298,15 @@
             "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
             "dev": true
         },
+        "string_decoder": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+            "dev": true,
+            "requires": {
+                "safe-buffer": "~5.1.0"
+            }
+        },
         "string-width": {
             "version": "4.2.3",
             "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
@@ -2358,15 +6317,6 @@
                 "strip-ansi": "^6.0.1"
             }
         },
-        "string_decoder": {
-            "version": "1.1.1",
-            "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-            "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-            "dev": true,
-            "requires": {
-                "safe-buffer": "~5.1.0"
-            }
-        },
         "strip-ansi": {
             "version": "6.0.1",
             "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",

From fd58459373c285df53e6254782e83d70440f192e Mon Sep 17 00:00:00 2001
From: shoffmeister <stefan.hoffmeister@econos.de>
Date: Thu, 11 Aug 2022 13:36:41 +0200
Subject: [PATCH 34/39] Take into account renamed extension id when launching

Signed-off-by: Stefan Hoffmeister <stefan.hoffmeister@econos.de>
---
 .vscode/launch.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.vscode/launch.json b/.vscode/launch.json
index 021b8f048cf2c..1e21214ffc4bc 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -78,7 +78,7 @@
       "request": "launch",
       "runtimeExecutable": "${execPath}",
       "args": [
-        "--disable-extension", "matklad.rust-analyzer",
+        "--disable-extension", "rust-lang.rust-analyzer",
         "--extensionDevelopmentPath=${workspaceFolder}/editors/code"
       ],
       "outFiles": [

From 72ae308c73a2d9d71715ec35ba1f644989338761 Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Sat, 13 Aug 2022 12:13:48 +0200
Subject: [PATCH 35/39] Do not unconditionally succeed RUSTC_WRAPPER checks
 when run by build scripts

rust-analyzer's RUSTC_WRAPPER unconditionally succeeds `cargo check`
invocations tripping up build scripts using `cargo check` to probe for
successful compilations. To prevent this from happening the RUSTC_WRAPPER
now checks if it's run from a build script by looking for the
`CARGO_CFG_TARGET_ARCH` env var that cargo sets only when running build
scripts.
---
 crates/rust-analyzer/src/bin/rustc_wrapper.rs | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/crates/rust-analyzer/src/bin/rustc_wrapper.rs b/crates/rust-analyzer/src/bin/rustc_wrapper.rs
index 2f6d4706d879e..38e9c7dd7e11c 100644
--- a/crates/rust-analyzer/src/bin/rustc_wrapper.rs
+++ b/crates/rust-analyzer/src/bin/rustc_wrapper.rs
@@ -17,6 +17,11 @@ pub(crate) fn run_rustc_skipping_cargo_checking(
     rustc_executable: OsString,
     args: Vec<OsString>,
 ) -> io::Result<ExitCode> {
+    // `CARGO_CFG_TARGET_ARCH` is only set by cargo when executing build scripts
+    // We don't want to exit out checks unconditionally with success if a build
+    // script tries to invoke checks themselves
+    // See https://github.com/rust-lang/rust-analyzer/issues/12973 for context
+    let not_invoked_by_build_script = std::env::var_os("CARGO_CFG_TARGET_ARCH").is_none();
     let is_cargo_check = args.iter().any(|arg| {
         let arg = arg.to_string_lossy();
         // `cargo check` invokes `rustc` with `--emit=metadata` argument.
@@ -29,7 +34,7 @@ pub(crate) fn run_rustc_skipping_cargo_checking(
         //            The default output filename is CRATE_NAME.rmeta.
         arg.starts_with("--emit=") && arg.contains("metadata") && !arg.contains("link")
     });
-    if is_cargo_check {
+    if not_invoked_by_build_script && is_cargo_check {
         return Ok(ExitCode(Some(0)));
     }
     run_rustc(rustc_executable, args)

From 038c36a1f5195d96d9247529d9cc1e14f00c8c17 Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Sat, 13 Aug 2022 20:03:06 +0200
Subject: [PATCH 36/39] Simplify `GlobalState::handle_event`

---
 crates/rust-analyzer/src/main_loop.rs | 381 +++++++++++++-------------
 1 file changed, 192 insertions(+), 189 deletions(-)

diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index b504c24878266..92b6be22e7626 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -9,6 +9,7 @@ use std::{
 
 use always_assert::always;
 use crossbeam_channel::{select, Receiver};
+use flycheck::FlycheckHandle;
 use ide_db::base_db::{SourceDatabase, SourceDatabaseExt, VfsPath};
 use itertools::Itertools;
 use lsp_server::{Connection, Notification, Request};
@@ -205,81 +206,14 @@ impl GlobalState {
                 }
                 lsp_server::Message::Response(resp) => self.complete_request(resp),
             },
-            Event::Task(mut task) => {
+            Event::Task(task) => {
                 let _p = profile::span("GlobalState::handle_event/task");
                 let mut prime_caches_progress = Vec::new();
-                loop {
-                    match task {
-                        Task::Response(response) => self.respond(response),
-                        Task::Retry(req) => self.on_request(req),
-                        Task::Diagnostics(diagnostics_per_file) => {
-                            for (file_id, diagnostics) in diagnostics_per_file {
-                                self.diagnostics.set_native_diagnostics(file_id, diagnostics)
-                            }
-                        }
-                        Task::PrimeCaches(progress) => match progress {
-                            PrimeCachesProgress::Begin => prime_caches_progress.push(progress),
-                            PrimeCachesProgress::Report(_) => {
-                                match prime_caches_progress.last_mut() {
-                                    Some(last @ PrimeCachesProgress::Report(_)) => {
-                                        // Coalesce subsequent update events.
-                                        *last = progress;
-                                    }
-                                    _ => prime_caches_progress.push(progress),
-                                }
-                            }
-                            PrimeCachesProgress::End { .. } => prime_caches_progress.push(progress),
-                        },
-                        Task::FetchWorkspace(progress) => {
-                            let (state, msg) = match progress {
-                                ProjectWorkspaceProgress::Begin => (Progress::Begin, None),
-                                ProjectWorkspaceProgress::Report(msg) => {
-                                    (Progress::Report, Some(msg))
-                                }
-                                ProjectWorkspaceProgress::End(workspaces) => {
-                                    self.fetch_workspaces_queue.op_completed(workspaces);
-
-                                    let old = Arc::clone(&self.workspaces);
-                                    self.switch_workspaces("fetched workspace".to_string());
-                                    let workspaces_updated = !Arc::ptr_eq(&old, &self.workspaces);
-
-                                    if self.config.run_build_scripts() && workspaces_updated {
-                                        self.fetch_build_data_queue
-                                            .request_op(format!("workspace updated"));
-                                    }
-
-                                    (Progress::End, None)
-                                }
-                            };
 
-                            self.report_progress("Fetching", state, msg, None);
-                        }
-                        Task::FetchBuildData(progress) => {
-                            let (state, msg) = match progress {
-                                BuildDataProgress::Begin => (Some(Progress::Begin), None),
-                                BuildDataProgress::Report(msg) => {
-                                    (Some(Progress::Report), Some(msg))
-                                }
-                                BuildDataProgress::End(build_data_result) => {
-                                    self.fetch_build_data_queue.op_completed(build_data_result);
-
-                                    self.switch_workspaces("fetched build data".to_string());
-
-                                    (Some(Progress::End), None)
-                                }
-                            };
-
-                            if let Some(state) = state {
-                                self.report_progress("Loading", state, msg, None);
-                            }
-                        }
-                    }
-
-                    // Coalesce multiple task events into one loop turn
-                    task = match self.task_pool.receiver.try_recv() {
-                        Ok(task) => task,
-                        Err(_) => break,
-                    };
+                self.handle_task(&mut prime_caches_progress, task);
+                // Coalesce multiple task events into one loop turn
+                while let Ok(task) = self.task_pool.receiver.try_recv() {
+                    self.handle_task(&mut prime_caches_progress, task);
                 }
 
                 for progress in prime_caches_progress {
@@ -326,119 +260,20 @@ impl GlobalState {
                     self.report_progress("Indexing", state, message, Some(fraction));
                 }
             }
-            Event::Vfs(mut task) => {
+            Event::Vfs(message) => {
                 let _p = profile::span("GlobalState::handle_event/vfs");
-                loop {
-                    match task {
-                        vfs::loader::Message::Loaded { files } => {
-                            let vfs = &mut self.vfs.write().0;
-                            for (path, contents) in files {
-                                let path = VfsPath::from(path);
-                                if !self.mem_docs.contains(&path) {
-                                    vfs.set_file_contents(path, contents);
-                                }
-                            }
-                        }
-                        vfs::loader::Message::Progress { n_total, n_done, config_version } => {
-                            always!(config_version <= self.vfs_config_version);
-
-                            self.vfs_progress_config_version = config_version;
-                            self.vfs_progress_n_total = n_total;
-                            self.vfs_progress_n_done = n_done;
-
-                            let state = if n_done == 0 {
-                                Progress::Begin
-                            } else if n_done < n_total {
-                                Progress::Report
-                            } else {
-                                assert_eq!(n_done, n_total);
-                                Progress::End
-                            };
-                            self.report_progress(
-                                "Roots Scanned",
-                                state,
-                                Some(format!("{}/{}", n_done, n_total)),
-                                Some(Progress::fraction(n_done, n_total)),
-                            )
-                        }
-                    }
-                    // Coalesce many VFS event into a single loop turn
-                    task = match self.loader.receiver.try_recv() {
-                        Ok(task) => task,
-                        Err(_) => break,
-                    }
+                self.handle_vfs_msg(message);
+                // Coalesce many VFS event into a single loop turn
+                while let Ok(message) = self.loader.receiver.try_recv() {
+                    self.handle_vfs_msg(message);
                 }
             }
-            Event::Flycheck(mut task) => {
+            Event::Flycheck(message) => {
                 let _p = profile::span("GlobalState::handle_event/flycheck");
-                loop {
-                    match task {
-                        flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => {
-                            let snap = self.snapshot();
-                            let diagnostics =
-                                crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
-                                    &self.config.diagnostics_map(),
-                                    &diagnostic,
-                                    &workspace_root,
-                                    &snap,
-                                );
-                            for diag in diagnostics {
-                                match url_to_file_id(&self.vfs.read().0, &diag.url) {
-                                    Ok(file_id) => self.diagnostics.add_check_diagnostic(
-                                        id,
-                                        file_id,
-                                        diag.diagnostic,
-                                        diag.fix,
-                                    ),
-                                    Err(err) => {
-                                        tracing::error!(
-                                            "File with cargo diagnostic not found in VFS: {}",
-                                            err
-                                        );
-                                    }
-                                };
-                            }
-                        }
-
-                        flycheck::Message::Progress { id, progress } => {
-                            let (state, message) = match progress {
-                                flycheck::Progress::DidStart => {
-                                    self.diagnostics.clear_check(id);
-                                    (Progress::Begin, None)
-                                }
-                                flycheck::Progress::DidCheckCrate(target) => {
-                                    (Progress::Report, Some(target))
-                                }
-                                flycheck::Progress::DidCancel => (Progress::End, None),
-                                flycheck::Progress::DidFinish(result) => {
-                                    if let Err(err) = result {
-                                        self.show_and_log_error(
-                                            "cargo check failed".to_string(),
-                                            Some(err.to_string()),
-                                        );
-                                    }
-                                    (Progress::End, None)
-                                }
-                            };
-
-                            // When we're running multiple flychecks, we have to include a disambiguator in
-                            // the title, or the editor complains. Note that this is a user-facing string.
-                            let title = if self.flycheck.len() == 1 {
-                                match self.config.flycheck() {
-                                    Some(config) => format!("{}", config),
-                                    None => "cargo check".to_string(),
-                                }
-                            } else {
-                                format!("cargo check (#{})", id + 1)
-                            };
-                            self.report_progress(&title, state, message, None);
-                        }
-                    }
-                    // Coalesce many flycheck updates into a single loop turn
-                    task = match self.flycheck_receiver.try_recv() {
-                        Ok(task) => task,
-                        Err(_) => break,
-                    }
+                self.handle_flycheck_msg(message);
+                // Coalesce many flycheck updates into a single loop turn
+                while let Ok(message) = self.flycheck_receiver.try_recv() {
+                    self.handle_flycheck_msg(message);
                 }
             }
         }
@@ -447,13 +282,13 @@ impl GlobalState {
         let memdocs_added_or_removed = self.mem_docs.take_changes();
 
         if self.is_quiescent() {
-            if !was_quiescent
-                && !self.fetch_workspaces_queue.op_requested()
-                && !self.fetch_build_data_queue.op_requested()
-            {
-                for flycheck in &self.flycheck {
-                    flycheck.update();
-                }
+            let became_quiescent = !(was_quiescent
+                || self.fetch_workspaces_queue.op_requested()
+                || self.fetch_build_data_queue.op_requested());
+
+            if became_quiescent {
+                // Project has loaded properly, kick off initial flycheck
+                self.flycheck.iter().for_each(FlycheckHandle::update);
                 if self.config.prefill_caches() {
                     self.prime_caches_queue.request_op("became quiescent".to_string());
                 }
@@ -495,8 +330,9 @@ impl GlobalState {
                 let url = file_id_to_url(&self.vfs.read().0, file_id);
                 let mut diagnostics =
                     self.diagnostics.diagnostics_for(file_id).cloned().collect::<Vec<_>>();
-                // https://github.com/rust-lang/rust-analyzer/issues/11404
                 for d in &mut diagnostics {
+                    // https://github.com/rust-lang/rust-analyzer/issues/11404
+                    // FIXME: We should move this workaround into the client code
                     if d.message.is_empty() {
                         d.message = " ".to_string();
                     }
@@ -575,11 +411,171 @@ impl GlobalState {
         Ok(())
     }
 
+    fn handle_task(&mut self, prime_caches_progress: &mut Vec<PrimeCachesProgress>, task: Task) {
+        match task {
+            Task::Response(response) => self.respond(response),
+            Task::Retry(req) => self.on_request(req),
+            Task::Diagnostics(diagnostics_per_file) => {
+                for (file_id, diagnostics) in diagnostics_per_file {
+                    self.diagnostics.set_native_diagnostics(file_id, diagnostics)
+                }
+            }
+            Task::PrimeCaches(progress) => match progress {
+                PrimeCachesProgress::Begin => prime_caches_progress.push(progress),
+                PrimeCachesProgress::Report(_) => {
+                    match prime_caches_progress.last_mut() {
+                        Some(last @ PrimeCachesProgress::Report(_)) => {
+                            // Coalesce subsequent update events.
+                            *last = progress;
+                        }
+                        _ => prime_caches_progress.push(progress),
+                    }
+                }
+                PrimeCachesProgress::End { .. } => prime_caches_progress.push(progress),
+            },
+            Task::FetchWorkspace(progress) => {
+                let (state, msg) = match progress {
+                    ProjectWorkspaceProgress::Begin => (Progress::Begin, None),
+                    ProjectWorkspaceProgress::Report(msg) => (Progress::Report, Some(msg)),
+                    ProjectWorkspaceProgress::End(workspaces) => {
+                        self.fetch_workspaces_queue.op_completed(workspaces);
+
+                        let old = Arc::clone(&self.workspaces);
+                        self.switch_workspaces("fetched workspace".to_string());
+                        let workspaces_updated = !Arc::ptr_eq(&old, &self.workspaces);
+
+                        if self.config.run_build_scripts() && workspaces_updated {
+                            self.fetch_build_data_queue.request_op(format!("workspace updated"));
+                        }
+
+                        (Progress::End, None)
+                    }
+                };
+
+                self.report_progress("Fetching", state, msg, None);
+            }
+            Task::FetchBuildData(progress) => {
+                let (state, msg) = match progress {
+                    BuildDataProgress::Begin => (Some(Progress::Begin), None),
+                    BuildDataProgress::Report(msg) => (Some(Progress::Report), Some(msg)),
+                    BuildDataProgress::End(build_data_result) => {
+                        self.fetch_build_data_queue.op_completed(build_data_result);
+
+                        self.switch_workspaces("fetched build data".to_string());
+
+                        (Some(Progress::End), None)
+                    }
+                };
+
+                if let Some(state) = state {
+                    self.report_progress("Loading", state, msg, None);
+                }
+            }
+        }
+    }
+
+    fn handle_vfs_msg(&mut self, message: vfs::loader::Message) {
+        match message {
+            vfs::loader::Message::Loaded { files } => {
+                let vfs = &mut self.vfs.write().0;
+                for (path, contents) in files {
+                    let path = VfsPath::from(path);
+                    if !self.mem_docs.contains(&path) {
+                        vfs.set_file_contents(path, contents);
+                    }
+                }
+            }
+            vfs::loader::Message::Progress { n_total, n_done, config_version } => {
+                always!(config_version <= self.vfs_config_version);
+
+                self.vfs_progress_config_version = config_version;
+                self.vfs_progress_n_total = n_total;
+                self.vfs_progress_n_done = n_done;
+
+                let state = if n_done == 0 {
+                    Progress::Begin
+                } else if n_done < n_total {
+                    Progress::Report
+                } else {
+                    assert_eq!(n_done, n_total);
+                    Progress::End
+                };
+                self.report_progress(
+                    "Roots Scanned",
+                    state,
+                    Some(format!("{}/{}", n_done, n_total)),
+                    Some(Progress::fraction(n_done, n_total)),
+                )
+            }
+        }
+    }
+
+    fn handle_flycheck_msg(&mut self, message: flycheck::Message) {
+        match message {
+            flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => {
+                let snap = self.snapshot();
+                let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
+                    &self.config.diagnostics_map(),
+                    &diagnostic,
+                    &workspace_root,
+                    &snap,
+                );
+                for diag in diagnostics {
+                    match url_to_file_id(&self.vfs.read().0, &diag.url) {
+                        Ok(file_id) => self.diagnostics.add_check_diagnostic(
+                            id,
+                            file_id,
+                            diag.diagnostic,
+                            diag.fix,
+                        ),
+                        Err(err) => {
+                            tracing::error!("File with cargo diagnostic not found in VFS: {}", err);
+                        }
+                    };
+                }
+            }
+
+            flycheck::Message::Progress { id, progress } => {
+                let (state, message) = match progress {
+                    flycheck::Progress::DidStart => {
+                        self.diagnostics.clear_check(id);
+                        (Progress::Begin, None)
+                    }
+                    flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)),
+                    flycheck::Progress::DidCancel => (Progress::End, None),
+                    flycheck::Progress::DidFinish(result) => {
+                        if let Err(err) = result {
+                            self.show_and_log_error(
+                                "cargo check failed".to_string(),
+                                Some(err.to_string()),
+                            );
+                        }
+                        (Progress::End, None)
+                    }
+                };
+
+                // When we're running multiple flychecks, we have to include a disambiguator in
+                // the title, or the editor complains. Note that this is a user-facing string.
+                let title = if self.flycheck.len() == 1 {
+                    match self.config.flycheck() {
+                        Some(config) => format!("{}", config),
+                        None => "cargo check".to_string(),
+                    }
+                } else {
+                    format!("cargo check (#{})", id + 1)
+                };
+                self.report_progress(&title, state, message, None);
+            }
+        }
+    }
+
+    /// Registers and handles a request. This should only be called once per incoming request.
     fn on_new_request(&mut self, request_received: Instant, req: Request) {
         self.register_request(&req, request_received);
         self.on_request(req);
     }
 
+    /// Handles a request.
     fn on_request(&mut self, req: Request) {
         if self.shutdown_requested {
             self.respond(lsp_server::Response::new_err(
@@ -670,6 +666,7 @@ impl GlobalState {
             .finish();
     }
 
+    /// Handles an incoming notification.
     fn on_notification(&mut self, not: Notification) -> Result<()> {
         NotificationDispatcher { not: Some(not), global_state: self }
             .on::<lsp_types::notification::Cancel>(|this, params| {
@@ -743,6 +740,8 @@ impl GlobalState {
                 let mut updated = false;
                 if let Ok(vfs_path) = from_proto::vfs_path(&params.text_document.uri) {
                     let (vfs, _) = &*this.vfs.read();
+
+                    // Trigger flychecks for all workspaces that depend on the saved file
                     if let Some(file_id) = vfs.file_id(&vfs_path) {
                         let analysis = this.analysis_host.analysis();
                         // Crates containing or depending on the saved file
@@ -800,6 +799,8 @@ impl GlobalState {
                             }
                         }
                     }
+
+                    // Re-fetch workspaces if a workspace related file has changed
                     if let Some(abs_path) = vfs_path.as_path() {
                         if reload::should_refresh_for_change(&abs_path, ChangeKind::Modify) {
                             this.fetch_workspaces_queue
@@ -807,6 +808,8 @@ impl GlobalState {
                         }
                     }
                 }
+
+                // No specific flycheck was triggered, so let's trigger all of them.
                 if !updated {
                     for flycheck in &this.flycheck {
                         flycheck.update();

From ec8256dd8027bbe5493698e4b9125f1f0cf8c646 Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Sat, 13 Aug 2022 20:18:21 +0200
Subject: [PATCH 37/39] Move VSCode diagnostics workaroudn into client code

---
 crates/rust-analyzer/src/handlers.rs  |  3 +--
 crates/rust-analyzer/src/main_loop.rs | 22 ++++------------------
 editors/code/src/client.ts            |  9 +++++++++
 3 files changed, 14 insertions(+), 20 deletions(-)

diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 47daa732d5d32..943d043bc1995 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -1320,8 +1320,7 @@ pub(crate) fn publish_diagnostics(
                 .unwrap(),
             }),
             source: Some("rust-analyzer".to_string()),
-            // https://github.com/rust-lang/rust-analyzer/issues/11404
-            message: if !d.message.is_empty() { d.message } else { " ".to_string() },
+            message: d.message,
             related_information: None,
             tags: if d.unused { Some(vec![DiagnosticTag::UNNECESSARY]) } else { None },
             data: None,
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 92b6be22e7626..77419998249f4 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -327,29 +327,15 @@ impl GlobalState {
                     continue;
                 }
 
-                let url = file_id_to_url(&self.vfs.read().0, file_id);
-                let mut diagnostics =
+                let uri = file_id_to_url(&self.vfs.read().0, file_id);
+                let diagnostics =
                     self.diagnostics.diagnostics_for(file_id).cloned().collect::<Vec<_>>();
-                for d in &mut diagnostics {
-                    // https://github.com/rust-lang/rust-analyzer/issues/11404
-                    // FIXME: We should move this workaround into the client code
-                    if d.message.is_empty() {
-                        d.message = " ".to_string();
-                    }
-                    if let Some(rds) = d.related_information.as_mut() {
-                        for rd in rds {
-                            if rd.message.is_empty() {
-                                rd.message = " ".to_string();
-                            }
-                        }
-                    }
-                }
-                let version = from_proto::vfs_path(&url)
+                let version = from_proto::vfs_path(&uri)
                     .map(|path| self.mem_docs.get(&path).map(|it| it.version))
                     .unwrap_or_default();
 
                 self.send_notification::<lsp_types::notification::PublishDiagnostics>(
-                    lsp_types::PublishDiagnosticsParams { uri: url, diagnostics, version },
+                    lsp_types::PublishDiagnosticsParams { uri, diagnostics, version },
                 );
             }
         }
diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 8a2dea6b35b76..40ba17844bee0 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -105,6 +105,15 @@ export async function createClient(
         traceOutputChannel: traceOutputChannel(),
         outputChannel: outputChannel(),
         middleware: {
+            async handleDiagnostics(uri, diagnostics, next) {
+                // Workaround for https://github.com/microsoft/vscode/issues/155531
+                for (const diagnostic of diagnostics) {
+                    if (!diagnostic.message) {
+                        diagnostic.message = " ";
+                    }
+                }
+                next(uri, diagnostics);
+            },
             async provideHover(
                 document: vscode.TextDocument,
                 position: vscode.Position,

From 614969baa770360b711881a3d9776d60937c98db Mon Sep 17 00:00:00 2001
From: Lukas Wirth <lukastw97@gmail.com>
Date: Sat, 13 Aug 2022 20:49:00 +0200
Subject: [PATCH 38/39] Pad empty diagnostic messages in relatedInformation as
 well

---
 editors/code/src/client.ts | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts
index 40ba17844bee0..27ab31db8db4f 100644
--- a/editors/code/src/client.ts
+++ b/editors/code/src/client.ts
@@ -111,6 +111,13 @@ export async function createClient(
                     if (!diagnostic.message) {
                         diagnostic.message = " ";
                     }
+                    if (diagnostic.relatedInformation) {
+                        for (const relatedInformation of diagnostic.relatedInformation) {
+                            if (!relatedInformation.message) {
+                                relatedInformation.message = " ";
+                            }
+                        }
+                    }
                 }
                 next(uri, diagnostics);
             },

From c61237b2b293d6f62270f6047ca11306f6871c39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lauren=C8=9Biu=20Nicola?= <lnicola@dend.ro>
Date: Sun, 14 Aug 2022 20:52:43 +0300
Subject: [PATCH 39/39] Remove redundant --pre-release flag from publish

---
 .github/workflows/release.yaml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index d5d8df2345fa9..3c36c4fb84a2b 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -253,9 +253,9 @@ jobs:
       - name: Publish Extension (Code Marketplace, nightly)
         if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
         working-directory: ./editors/code
-        run: npx vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix --pre-release
+        run: npx vsce publish --pat ${{ secrets.MARKETPLACE_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix
 
       - name: Publish Extension (OpenVSX, nightly)
         if: github.ref != 'refs/heads/release' && (github.repository == 'rust-analyzer/rust-analyzer' || github.repository == 'rust-lang/rust-analyzer')
         working-directory: ./editors/code
-        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix --pre-release
+        run: npx ovsx publish --pat ${{ secrets.OPENVSX_TOKEN }} --packagePath ../../dist/rust-analyzer-*.vsix