about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/Cargo.lock20
-rw-r--r--src/tools/rust-analyzer/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/flycheck/Cargo.toml31
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/project_json.rs247
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs (renamed from src/tools/rust-analyzer/crates/flycheck/src/command.rs)4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs16
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs13
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs (renamed from src/tools/rust-analyzer/crates/flycheck/src/project_json.rs)23
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs (renamed from src/tools/rust-analyzer/crates/flycheck/src/lib.rs)85
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs20
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs9
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs57
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs10
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs (renamed from src/tools/rust-analyzer/crates/flycheck/src/test_runner.rs)12
16 files changed, 252 insertions, 303 deletions
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 8fee2b64fd3..b6bf516af15 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -424,23 +424,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "flycheck"
-version = "0.0.0"
-dependencies = [
- "cargo_metadata",
- "crossbeam-channel",
- "paths",
- "process-wrap",
- "project-model",
- "rustc-hash",
- "serde",
- "serde_json",
- "stdx",
- "toolchain",
- "tracing",
-]
-
-[[package]]
 name = "form_urlencoded"
 version = "1.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1650,12 +1633,12 @@ version = "0.0.0"
 dependencies = [
  "always-assert",
  "anyhow",
+ "cargo_metadata",
  "cfg",
  "crossbeam-channel",
  "dirs",
  "dissimilar",
  "expect-test",
- "flycheck",
  "hir",
  "hir-def",
  "hir-ty",
@@ -1676,6 +1659,7 @@ dependencies = [
  "parser",
  "paths",
  "proc-macro-api",
+ "process-wrap",
  "profile",
  "project-model",
  "rayon",
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index 4e834840698..b2cf3451467 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -52,7 +52,6 @@ debug = 2
 # local crates
 base-db = { path = "./crates/base-db", version = "0.0.0" }
 cfg = { path = "./crates/cfg", version = "0.0.0", features = ["tt"] }
-flycheck = { path = "./crates/flycheck", version = "0.0.0" }
 hir = { path = "./crates/hir", version = "0.0.0" }
 hir-def = { path = "./crates/hir-def", version = "0.0.0" }
 hir-expand = { path = "./crates/hir-expand", version = "0.0.0" }
diff --git a/src/tools/rust-analyzer/crates/flycheck/Cargo.toml b/src/tools/rust-analyzer/crates/flycheck/Cargo.toml
deleted file mode 100644
index a7f6e296d3b..00000000000
--- a/src/tools/rust-analyzer/crates/flycheck/Cargo.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-[package]
-name = "flycheck"
-version = "0.0.0"
-repository.workspace = true
-description = "Functionality needed for rust-analyzer to run `cargo` commands in a background thread."
-
-authors.workspace = true
-edition.workspace = true
-license.workspace = true
-rust-version.workspace = true
-
-[lib]
-doctest = false
-
-[dependencies]
-cargo_metadata.workspace = true
-crossbeam-channel.workspace = true
-tracing.workspace = true
-rustc-hash.workspace = true
-serde_json.workspace = true
-serde.workspace = true
-process-wrap.workspace = true
-
-# local deps
-paths.workspace = true
-stdx.workspace = true
-toolchain.workspace = true
-project-model.workspace = true
-
-[lints]
-workspace = true
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
index 1fb9cec8e26..7dea0c38398 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
@@ -74,106 +74,6 @@ pub struct ProjectJson {
     runnables: Vec<Runnable>,
 }
 
-/// A crate points to the root module of a crate and lists the dependencies of the crate. This is
-/// useful in creating the crate graph.
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct Crate {
-    pub(crate) display_name: Option<CrateDisplayName>,
-    pub root_module: AbsPathBuf,
-    pub(crate) edition: Edition,
-    pub(crate) version: Option<String>,
-    pub(crate) deps: Vec<Dep>,
-    pub(crate) cfg: Vec<CfgAtom>,
-    pub(crate) target: Option<String>,
-    pub(crate) env: FxHashMap<String, String>,
-    pub(crate) proc_macro_dylib_path: Option<AbsPathBuf>,
-    pub(crate) is_workspace_member: bool,
-    pub(crate) include: Vec<AbsPathBuf>,
-    pub(crate) exclude: Vec<AbsPathBuf>,
-    pub(crate) is_proc_macro: bool,
-    pub(crate) repository: Option<String>,
-    pub build: Option<Build>,
-}
-
-/// Additional, build-specific data about a crate.
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub struct Build {
-    /// The name associated with this crate.
-    ///
-    /// This is determined by the build system that produced
-    /// the `rust-project.json` in question. For instance, if buck were used,
-    /// the label might be something like `//ide/rust/rust-analyzer:rust-analyzer`.
-    ///
-    /// Do not attempt to parse the contents of this string; it is a build system-specific
-    /// identifier similar to [`Crate::display_name`].
-    pub label: String,
-    /// Path corresponding to the build system-specific file defining the crate.
-    ///
-    /// It is roughly analogous to [`ManifestPath`], but it should *not* be used with
-    /// [`crate::ProjectManifest::from_manifest_file`], as the build file may not be
-    /// be in the `rust-project.json`.
-    pub build_file: Utf8PathBuf,
-    /// The kind of target.
-    ///
-    /// Examples (non-exhaustively) include [`TargetKind::Bin`], [`TargetKind::Lib`],
-    /// and [`TargetKind::Test`]. This information is used to determine what sort
-    /// of runnable codelens to provide, if any.
-    pub target_kind: TargetKind,
-}
-
-/// A template-like structure for describing runnables.
-///
-/// These are used for running and debugging binaries and tests without encoding
-/// build system-specific knowledge into rust-analyzer.
-///
-/// # Example
-///
-/// Below is an example of a test runnable. `{label}` and `{test_id}`
-/// are explained in [`Runnable::args`]'s documentation.
-///
-/// ```json
-/// {
-///     "program": "buck",
-///     "args": [
-///         "test",
-///          "{label}",
-///          "--",
-///          "{test_id}",
-///          "--print-passing-details"
-///     ],
-///     "cwd": "/home/user/repo-root/",
-///     "kind": "testOne"
-/// }
-/// ```
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct Runnable {
-    /// The program invoked by the runnable.
-    ///
-    /// For example, this might be `cargo`, `buck`, or `bazel`.
-    pub program: String,
-    /// The arguments passed to [`Runnable::program`].
-    ///
-    /// The args can contain two template strings: `{label}` and `{test_id}`.
-    /// rust-analyzer will find and replace `{label}` with [`Build::label`] and
-    /// `{test_id}` with the test name.
-    pub args: Vec<String>,
-    /// The current working directory of the runnable.
-    pub cwd: Utf8PathBuf,
-    pub kind: RunnableKind,
-}
-
-/// The kind of runnable.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum RunnableKind {
-    Check,
-
-    /// Can run a binary.
-    Run,
-
-    /// Run a single test.
-    TestOne,
-}
-
 impl ProjectJson {
     /// Create a new ProjectJson instance.
     ///
@@ -302,6 +202,106 @@ impl ProjectJson {
     }
 }
 
+/// A crate points to the root module of a crate and lists the dependencies of the crate. This is
+/// useful in creating the crate graph.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Crate {
+    pub(crate) display_name: Option<CrateDisplayName>,
+    pub root_module: AbsPathBuf,
+    pub(crate) edition: Edition,
+    pub(crate) version: Option<String>,
+    pub(crate) deps: Vec<Dep>,
+    pub(crate) cfg: Vec<CfgAtom>,
+    pub(crate) target: Option<String>,
+    pub(crate) env: FxHashMap<String, String>,
+    pub(crate) proc_macro_dylib_path: Option<AbsPathBuf>,
+    pub(crate) is_workspace_member: bool,
+    pub(crate) include: Vec<AbsPathBuf>,
+    pub(crate) exclude: Vec<AbsPathBuf>,
+    pub(crate) is_proc_macro: bool,
+    pub(crate) repository: Option<String>,
+    pub build: Option<Build>,
+}
+
+/// Additional, build-specific data about a crate.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct Build {
+    /// The name associated with this crate.
+    ///
+    /// This is determined by the build system that produced
+    /// the `rust-project.json` in question. For instance, if buck were used,
+    /// the label might be something like `//ide/rust/rust-analyzer:rust-analyzer`.
+    ///
+    /// Do not attempt to parse the contents of this string; it is a build system-specific
+    /// identifier similar to [`Crate::display_name`].
+    pub label: String,
+    /// Path corresponding to the build system-specific file defining the crate.
+    ///
+    /// It is roughly analogous to [`ManifestPath`], but it should *not* be used with
+    /// [`crate::ProjectManifest::from_manifest_file`], as the build file may not be
+    /// be in the `rust-project.json`.
+    pub build_file: Utf8PathBuf,
+    /// The kind of target.
+    ///
+    /// Examples (non-exhaustively) include [`TargetKind::Bin`], [`TargetKind::Lib`],
+    /// and [`TargetKind::Test`]. This information is used to determine what sort
+    /// of runnable codelens to provide, if any.
+    pub target_kind: TargetKind,
+}
+
+/// A template-like structure for describing runnables.
+///
+/// These are used for running and debugging binaries and tests without encoding
+/// build system-specific knowledge into rust-analyzer.
+///
+/// # Example
+///
+/// Below is an example of a test runnable. `{label}` and `{test_id}`
+/// are explained in [`Runnable::args`]'s documentation.
+///
+/// ```json
+/// {
+///     "program": "buck",
+///     "args": [
+///         "test",
+///          "{label}",
+///          "--",
+///          "{test_id}",
+///          "--print-passing-details"
+///     ],
+///     "cwd": "/home/user/repo-root/",
+///     "kind": "testOne"
+/// }
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Runnable {
+    /// The program invoked by the runnable.
+    ///
+    /// For example, this might be `cargo`, `buck`, or `bazel`.
+    pub program: String,
+    /// The arguments passed to [`Runnable::program`].
+    ///
+    /// The args can contain two template strings: `{label}` and `{test_id}`.
+    /// rust-analyzer will find and replace `{label}` with [`Build::label`] and
+    /// `{test_id}` with the test name.
+    pub args: Vec<String>,
+    /// The current working directory of the runnable.
+    pub cwd: Utf8PathBuf,
+    pub kind: RunnableKind,
+}
+
+/// The kind of runnable.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum RunnableKind {
+    Check,
+
+    /// Can run a binary.
+    Run,
+
+    /// Run a single test.
+    TestOne,
+}
+
 #[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
 pub struct ProjectJsonData {
     sysroot: Option<Utf8PathBuf>,
@@ -407,6 +407,29 @@ pub enum TargetKindData {
     Lib,
     Test,
 }
+/// Identifies a crate by position in the crates array.
+///
+/// This will differ from `CrateId` when multiple `ProjectJson`
+/// workspaces are loaded.
+#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
+#[serde(transparent)]
+pub struct CrateArrayIdx(pub usize);
+
+#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
+pub(crate) struct Dep {
+    /// Identifies a crate by position in the crates array.
+    #[serde(rename = "crate")]
+    pub(crate) krate: CrateArrayIdx,
+    #[serde(serialize_with = "serialize_crate_name")]
+    #[serde(deserialize_with = "deserialize_crate_name")]
+    pub(crate) name: CrateName,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
+struct CrateSource {
+    include_dirs: Vec<Utf8PathBuf>,
+    exclude_dirs: Vec<Utf8PathBuf>,
+}
 
 impl From<TargetKindData> for TargetKind {
     fn from(data: TargetKindData) -> Self {
@@ -445,30 +468,6 @@ impl From<RunnableKindData> for RunnableKind {
     }
 }
 
-/// Identifies a crate by position in the crates array.
-///
-/// This will differ from `CrateId` when multiple `ProjectJson`
-/// workspaces are loaded.
-#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
-#[serde(transparent)]
-pub struct CrateArrayIdx(pub usize);
-
-#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
-pub(crate) struct Dep {
-    /// Identifies a crate by position in the crates array.
-    #[serde(rename = "crate")]
-    pub(crate) krate: CrateArrayIdx,
-    #[serde(serialize_with = "serialize_crate_name")]
-    #[serde(deserialize_with = "deserialize_crate_name")]
-    pub(crate) name: CrateName,
-}
-
-#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
-struct CrateSource {
-    include_dirs: Vec<Utf8PathBuf>,
-    exclude_dirs: Vec<Utf8PathBuf>,
-}
-
 fn deserialize_crate_name<'de, D>(de: D) -> std::result::Result<CrateName, D::Error>
 where
     D: de::Deserializer<'de>,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
index 6aa2789c5eb..f0878b25dd3 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
@@ -47,9 +47,10 @@ always-assert = "0.2.0"
 walkdir = "2.3.2"
 semver.workspace = true
 memchr = "2.7.1"
+cargo_metadata.workspace = true
+process-wrap.workspace = true
 
 cfg.workspace = true
-flycheck.workspace = true
 hir-def.workspace = true
 hir-ty.workspace = true
 hir.workspace = true
diff --git a/src/tools/rust-analyzer/crates/flycheck/src/command.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs
index 38c7c81f57a..f1009eb4660 100644
--- a/src/tools/rust-analyzer/crates/flycheck/src/command.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/command.rs
@@ -1,5 +1,5 @@
-//! Utilities for running a cargo command like `cargo check` or `cargo test` in a separate thread and
-//! parse its stdout/stderr.
+//! Utilities for running a cargo command like `cargo check` or `cargo test` in a separate thread
+//! and parse its stdout/stderr.
 
 use std::{
     ffi::OsString,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index 54573344245..486046c47c7 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -7,7 +7,6 @@ use std::{fmt, iter, ops::Not, sync::OnceLock};
 
 use cfg::{CfgAtom, CfgDiff};
 use dirs::config_dir;
-use flycheck::{CargoOptions, FlycheckConfig};
 use hir::Symbol;
 use ide::{
     AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode,
@@ -37,6 +36,7 @@ use vfs::{AbsPath, AbsPathBuf, VfsPath};
 use crate::{
     capabilities::ClientCapabilities,
     diagnostics::DiagnosticsMapConfig,
+    flycheck::{CargoOptions, FlycheckConfig},
     lsp_ext::{WorkspaceSymbolSearchKind, WorkspaceSymbolSearchScope},
 };
 
@@ -1899,7 +1899,7 @@ impl Config {
         *self.check_workspace(None)
     }
 
-    pub fn cargo_test_options(&self) -> CargoOptions {
+    pub(crate) fn cargo_test_options(&self) -> CargoOptions {
         CargoOptions {
             target_triples: self.cargo_target(None).clone().into_iter().collect(),
             all_targets: false,
@@ -1915,7 +1915,7 @@ impl Config {
         }
     }
 
-    pub fn flycheck(&self) -> FlycheckConfig {
+    pub(crate) fn flycheck(&self) -> FlycheckConfig {
         match &self.check_overrideCommand(None) {
             Some(args) if !args.is_empty() => {
                 let mut args = args.clone();
@@ -1925,16 +1925,18 @@ impl Config {
                     args,
                     extra_env: self.check_extra_env(),
                     invocation_strategy: match self.check_invocationStrategy(None) {
-                        InvocationStrategy::Once => flycheck::InvocationStrategy::Once,
+                        InvocationStrategy::Once => crate::flycheck::InvocationStrategy::Once,
                         InvocationStrategy::PerWorkspace => {
-                            flycheck::InvocationStrategy::PerWorkspace
+                            crate::flycheck::InvocationStrategy::PerWorkspace
                         }
                     },
                     invocation_location: match self.check_invocationLocation(None) {
                         InvocationLocation::Root => {
-                            flycheck::InvocationLocation::Root(self.root_path.clone())
+                            crate::flycheck::InvocationLocation::Root(self.root_path.clone())
+                        }
+                        InvocationLocation::Workspace => {
+                            crate::flycheck::InvocationLocation::Workspace
                         }
-                        InvocationLocation::Workspace => flycheck::InvocationLocation::Workspace,
                     },
                 }
             }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
index defa464f2ba..208a70bc02a 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/diagnostics/to_proto.rs
@@ -1,7 +1,7 @@
 //! This module provides the functionality needed to convert diagnostics from
 //! `cargo check` json format to the LSP diagnostic format.
 
-use flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan};
+use crate::flycheck::{Applicability, DiagnosticLevel, DiagnosticSpan};
 use itertools::Itertools;
 use rustc_hash::FxHashMap;
 use stdx::format_to;
@@ -17,8 +17,8 @@ use super::{DiagnosticsMapConfig, Fix};
 /// Determines the LSP severity from a diagnostic
 fn diagnostic_severity(
     config: &DiagnosticsMapConfig,
-    level: flycheck::DiagnosticLevel,
-    code: Option<flycheck::DiagnosticCode>,
+    level: crate::flycheck::DiagnosticLevel,
+    code: Option<crate::flycheck::DiagnosticCode>,
 ) -> Option<lsp_types::DiagnosticSeverity> {
     let res = match level {
         DiagnosticLevel::Ice => lsp_types::DiagnosticSeverity::ERROR,
@@ -181,7 +181,7 @@ enum MappedRustChildDiagnostic {
 fn map_rust_child_diagnostic(
     config: &DiagnosticsMapConfig,
     workspace_root: &AbsPath,
-    rd: &flycheck::Diagnostic,
+    rd: &crate::flycheck::Diagnostic,
     snap: &GlobalStateSnapshot,
 ) -> MappedRustChildDiagnostic {
     let spans: Vec<&DiagnosticSpan> = rd.spans.iter().filter(|s| s.is_primary).collect();
@@ -284,7 +284,7 @@ pub(crate) struct MappedRustDiagnostic {
 /// If the diagnostic has no primary span this will return `None`
 pub(crate) fn map_rust_diagnostic_to_lsp(
     config: &DiagnosticsMapConfig,
-    rd: &flycheck::Diagnostic,
+    rd: &crate::flycheck::Diagnostic,
     workspace_root: &AbsPath,
     snap: &GlobalStateSnapshot,
 ) -> Vec<MappedRustDiagnostic> {
@@ -537,7 +537,8 @@ mod tests {
     }
 
     fn check_with_config(config: DiagnosticsMapConfig, diagnostics_json: &str, expect: ExpectFile) {
-        let diagnostic: flycheck::Diagnostic = serde_json::from_str(diagnostics_json).unwrap();
+        let diagnostic: crate::flycheck::Diagnostic =
+            serde_json::from_str(diagnostics_json).unwrap();
         let workspace_root: &AbsPath = Utf8Path::new("/test/").try_into().unwrap();
         let (sender, _) = crossbeam_channel::unbounded();
         let state = GlobalState::new(
diff --git a/src/tools/rust-analyzer/crates/flycheck/src/project_json.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs
index b6e4495bc6d..7e9162eee6e 100644
--- a/src/tools/rust-analyzer/crates/flycheck/src/project_json.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/discover.rs
@@ -1,4 +1,5 @@
-//! A `cargo-metadata`-equivalent for non-Cargo build systems.
+//! Infrastructure for lazy project discovery. Currently only support rust-project.json discovery
+//! via a custom discover command.
 use std::{io, process::Command};
 
 use crossbeam_channel::Sender;
@@ -9,19 +10,19 @@ use serde_json::Value;
 
 use crate::command::{CommandHandle, ParseFromLine};
 
-pub const ARG_PLACEHOLDER: &str = "{arg}";
+pub(crate) const ARG_PLACEHOLDER: &str = "{arg}";
 
 /// A command wrapper for getting a `rust-project.json`.
 ///
-/// This is analogous to `cargo-metadata`, but for non-Cargo build systems.
-pub struct Discover {
+/// This is analogous to discovering a cargo project + running `cargo-metadata` on it, but for non-Cargo build systems.
+pub(crate) struct DiscoverCommand {
     command: Vec<String>,
     sender: Sender<DiscoverProjectMessage>,
 }
 
 #[derive(PartialEq, Clone, Debug, Serialize)]
 #[serde(rename_all = "camelCase")]
-pub enum DiscoverArgument {
+pub(crate) enum DiscoverArgument {
     Path(#[serde(serialize_with = "serialize_abs_pathbuf")] AbsPathBuf),
     Buildfile(#[serde(serialize_with = "serialize_abs_pathbuf")] AbsPathBuf),
 }
@@ -34,14 +35,14 @@ where
     se.serialize_str(path.as_str())
 }
 
-impl Discover {
-    /// Create a new [Discover].
-    pub fn new(sender: Sender<DiscoverProjectMessage>, command: Vec<String>) -> Self {
+impl DiscoverCommand {
+    /// Create a new [DiscoverCommand].
+    pub(crate) fn new(sender: Sender<DiscoverProjectMessage>, command: Vec<String>) -> Self {
         Self { sender, command }
     }
 
     /// Spawn the command inside [Discover] and report progress, if any.
-    pub fn spawn(&self, discover_arg: DiscoverArgument) -> io::Result<DiscoverHandle> {
+    pub(crate) fn spawn(&self, discover_arg: DiscoverArgument) -> io::Result<DiscoverHandle> {
         let command = &self.command[0];
         let args = &self.command[1..];
 
@@ -65,7 +66,7 @@ impl Discover {
 
 /// A handle to a spawned [Discover].
 #[derive(Debug)]
-pub struct DiscoverHandle {
+pub(crate) struct DiscoverHandle {
     _handle: CommandHandle<DiscoverProjectMessage>,
 }
 
@@ -81,7 +82,7 @@ enum DiscoverProjectData {
 }
 
 #[derive(Debug, PartialEq, Clone)]
-pub enum DiscoverProjectMessage {
+pub(crate) enum DiscoverProjectMessage {
     Finished { project: ProjectJsonData, buildfile: AbsPathBuf },
     Error { error: String, source: Option<String> },
     Progress { message: String },
diff --git a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
index 3dd2a91d8fd..c2b943d1d6f 100644
--- a/src/tools/rust-analyzer/crates/flycheck/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
@@ -1,11 +1,6 @@
-//! Flycheck provides the functionality needed to run `cargo check` or
-//! another compatible command (f.x. clippy) in a background thread and provide
+//! Flycheck provides the functionality needed to run `cargo check` to provide
 //! LSP diagnostics based on the output of the command.
 
-// FIXME: This crate now handles running `cargo test` needed in the test explorer in
-// addition to `cargo check`. Either split it into 3 crates (one for test, one for check
-// and one common utilities) or change its name and docs to reflect the current state.
-
 use std::{fmt, io, process::Command, time::Duration};
 
 use crossbeam_channel::{never, select, unbounded, Receiver, Sender};
@@ -13,47 +8,41 @@ use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
 use rustc_hash::FxHashMap;
 use serde::Deserialize;
 
-pub use cargo_metadata::diagnostic::{
+pub(crate) use cargo_metadata::diagnostic::{
     Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan,
-    DiagnosticSpanMacroExpansion,
 };
 use toolchain::Tool;
 
-mod command;
-pub mod project_json;
-mod test_runner;
-
-use command::{CommandHandle, ParseFromLine};
-pub use test_runner::{CargoTestHandle, CargoTestMessage, TestState, TestTarget};
+use crate::command::{CommandHandle, ParseFromLine};
 
 #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
-pub enum InvocationStrategy {
+pub(crate) enum InvocationStrategy {
     Once,
     #[default]
     PerWorkspace,
 }
 
 #[derive(Clone, Debug, Default, PartialEq, Eq)]
-pub enum InvocationLocation {
+pub(crate) enum InvocationLocation {
     Root(AbsPathBuf),
     #[default]
     Workspace,
 }
 
 #[derive(Clone, Debug, PartialEq, Eq)]
-pub struct CargoOptions {
-    pub target_triples: Vec<String>,
-    pub all_targets: bool,
-    pub no_default_features: bool,
-    pub all_features: bool,
-    pub features: Vec<String>,
-    pub extra_args: Vec<String>,
-    pub extra_env: FxHashMap<String, String>,
-    pub target_dir: Option<Utf8PathBuf>,
+pub(crate) struct CargoOptions {
+    pub(crate) target_triples: Vec<String>,
+    pub(crate) all_targets: bool,
+    pub(crate) no_default_features: bool,
+    pub(crate) all_features: bool,
+    pub(crate) features: Vec<String>,
+    pub(crate) extra_args: Vec<String>,
+    pub(crate) extra_env: FxHashMap<String, String>,
+    pub(crate) target_dir: Option<Utf8PathBuf>,
 }
 
 impl CargoOptions {
-    fn apply_on_command(&self, cmd: &mut Command) {
+    pub(crate) fn apply_on_command(&self, cmd: &mut Command) {
         for target in &self.target_triples {
             cmd.args(["--target", target.as_str()]);
         }
@@ -79,7 +68,7 @@ impl CargoOptions {
 }
 
 #[derive(Clone, Debug, PartialEq, Eq)]
-pub enum FlycheckConfig {
+pub(crate) enum FlycheckConfig {
     CargoCommand {
         command: String,
         options: CargoOptions,
@@ -110,7 +99,7 @@ impl fmt::Display for FlycheckConfig {
 /// diagnostics based on the output.
 /// The spawned thread is shut down when this struct is dropped.
 #[derive(Debug)]
-pub struct FlycheckHandle {
+pub(crate) struct FlycheckHandle {
     // XXX: drop order is significant
     sender: Sender<StateChange>,
     _thread: stdx::thread::JoinHandle,
@@ -118,9 +107,9 @@ pub struct FlycheckHandle {
 }
 
 impl FlycheckHandle {
-    pub fn spawn(
+    pub(crate) fn spawn(
         id: usize,
-        sender: Box<dyn Fn(Message) + Send>,
+        sender: Box<dyn Fn(FlycheckMessage) + Send>,
         config: FlycheckConfig,
         sysroot_root: Option<AbsPathBuf>,
         workspace_root: AbsPathBuf,
@@ -137,28 +126,28 @@ impl FlycheckHandle {
     }
 
     /// Schedule a re-start of the cargo check worker to do a workspace wide check.
-    pub fn restart_workspace(&self, saved_file: Option<AbsPathBuf>) {
+    pub(crate) fn restart_workspace(&self, saved_file: Option<AbsPathBuf>) {
         self.sender.send(StateChange::Restart { package: None, saved_file }).unwrap();
     }
 
     /// Schedule a re-start of the cargo check worker to do a package wide check.
-    pub fn restart_for_package(&self, package: String) {
+    pub(crate) fn restart_for_package(&self, package: String) {
         self.sender
             .send(StateChange::Restart { package: Some(package), saved_file: None })
             .unwrap();
     }
 
     /// Stop this cargo check worker.
-    pub fn cancel(&self) {
+    pub(crate) fn cancel(&self) {
         self.sender.send(StateChange::Cancel).unwrap();
     }
 
-    pub fn id(&self) -> usize {
+    pub(crate) fn id(&self) -> usize {
         self.id
     }
 }
 
-pub enum Message {
+pub(crate) enum FlycheckMessage {
     /// Request adding a diagnostic with fixes included to a file
     AddDiagnostic { id: usize, workspace_root: AbsPathBuf, diagnostic: Diagnostic },
 
@@ -173,19 +162,19 @@ pub enum Message {
     },
 }
 
-impl fmt::Debug for Message {
+impl fmt::Debug for FlycheckMessage {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
-            Message::AddDiagnostic { id, workspace_root, diagnostic } => f
+            FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => f
                 .debug_struct("AddDiagnostic")
                 .field("id", id)
                 .field("workspace_root", workspace_root)
                 .field("diagnostic_code", &diagnostic.code.as_ref().map(|it| &it.code))
                 .finish(),
-            Message::ClearDiagnostics { id } => {
+            FlycheckMessage::ClearDiagnostics { id } => {
                 f.debug_struct("ClearDiagnostics").field("id", id).finish()
             }
-            Message::Progress { id, progress } => {
+            FlycheckMessage::Progress { id, progress } => {
                 f.debug_struct("Progress").field("id", id).field("progress", progress).finish()
             }
         }
@@ -193,7 +182,7 @@ impl fmt::Debug for Message {
 }
 
 #[derive(Debug)]
-pub enum Progress {
+pub(crate) enum Progress {
     DidStart,
     DidCheckCrate(String),
     DidFinish(io::Result<()>),
@@ -210,7 +199,7 @@ enum StateChange {
 struct FlycheckActor {
     /// The workspace id of this flycheck instance.
     id: usize,
-    sender: Box<dyn Fn(Message) + Send>,
+    sender: Box<dyn Fn(FlycheckMessage) + Send>,
     config: FlycheckConfig,
     manifest_path: Option<AbsPathBuf>,
     /// Either the workspace root of the workspace we are flychecking,
@@ -241,12 +230,12 @@ enum FlycheckStatus {
     Finished,
 }
 
-pub const SAVED_FILE_PLACEHOLDER: &str = "$saved_file";
+pub(crate) const SAVED_FILE_PLACEHOLDER: &str = "$saved_file";
 
 impl FlycheckActor {
     fn new(
         id: usize,
-        sender: Box<dyn Fn(Message) + Send>,
+        sender: Box<dyn Fn(FlycheckMessage) + Send>,
         config: FlycheckConfig,
         sysroot_root: Option<AbsPathBuf>,
         workspace_root: AbsPathBuf,
@@ -267,7 +256,7 @@ impl FlycheckActor {
     }
 
     fn report_progress(&self, progress: Progress) {
-        self.send(Message::Progress { id: self.id, progress });
+        self.send(FlycheckMessage::Progress { id: self.id, progress });
     }
 
     fn next_event(&self, inbox: &Receiver<StateChange>) -> Option<Event> {
@@ -340,7 +329,7 @@ impl FlycheckActor {
                         );
                     }
                     if self.status == FlycheckStatus::Started {
-                        self.send(Message::ClearDiagnostics { id: self.id });
+                        self.send(FlycheckMessage::ClearDiagnostics { id: self.id });
                     }
                     self.report_progress(Progress::DidFinish(res));
                     self.status = FlycheckStatus::Finished;
@@ -362,9 +351,9 @@ impl FlycheckActor {
                             "diagnostic received"
                         );
                         if self.status == FlycheckStatus::Started {
-                            self.send(Message::ClearDiagnostics { id: self.id });
+                            self.send(FlycheckMessage::ClearDiagnostics { id: self.id });
                         }
-                        self.send(Message::AddDiagnostic {
+                        self.send(FlycheckMessage::AddDiagnostic {
                             id: self.id,
                             workspace_root: self.root.clone(),
                             diagnostic: msg,
@@ -489,7 +478,7 @@ impl FlycheckActor {
         Some(cmd)
     }
 
-    fn send(&self, check_task: Message) {
+    fn send(&self, check_task: FlycheckMessage) {
         (self.sender)(check_task);
     }
 }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
index 9d064ed1226..df809c07235 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
@@ -6,7 +6,6 @@
 use std::{ops::Not as _, time::Instant};
 
 use crossbeam_channel::{unbounded, Receiver, Sender};
-use flycheck::{project_json, FlycheckHandle};
 use hir::ChangeWithProcMacros;
 use ide::{Analysis, AnalysisHost, Cancellable, FileId, SourceRootId};
 use ide_db::base_db::{CrateId, ProcMacroPaths, SourceDatabase, SourceRootDatabase};
@@ -28,6 +27,8 @@ use vfs::{AbsPathBuf, AnchoredPathBuf, ChangeKind, Vfs, VfsPath};
 use crate::{
     config::{Config, ConfigChange, ConfigErrors, RatomlFileKind},
     diagnostics::{CheckFixes, DiagnosticCollection},
+    discover,
+    flycheck::{FlycheckHandle, FlycheckMessage},
     line_index::{LineEndings, LineIndex},
     lsp::{from_proto, to_proto::url_from_abs_path},
     lsp_ext,
@@ -37,6 +38,7 @@ use crate::{
     reload,
     target_spec::{CargoTargetSpec, ProjectJsonTargetSpec, TargetSpec},
     task_pool::{TaskPool, TaskQueue},
+    test_runner::{CargoTestHandle, CargoTestMessage},
 };
 
 pub(crate) struct FetchWorkspaceRequest {
@@ -88,20 +90,20 @@ pub(crate) struct GlobalState {
 
     // Flycheck
     pub(crate) flycheck: Arc<[FlycheckHandle]>,
-    pub(crate) flycheck_sender: Sender<flycheck::Message>,
-    pub(crate) flycheck_receiver: Receiver<flycheck::Message>,
+    pub(crate) flycheck_sender: Sender<FlycheckMessage>,
+    pub(crate) flycheck_receiver: Receiver<FlycheckMessage>,
     pub(crate) last_flycheck_error: Option<String>,
 
     // Test explorer
-    pub(crate) test_run_session: Option<Vec<flycheck::CargoTestHandle>>,
-    pub(crate) test_run_sender: Sender<flycheck::CargoTestMessage>,
-    pub(crate) test_run_receiver: Receiver<flycheck::CargoTestMessage>,
+    pub(crate) test_run_session: Option<Vec<CargoTestHandle>>,
+    pub(crate) test_run_sender: Sender<CargoTestMessage>,
+    pub(crate) test_run_receiver: Receiver<CargoTestMessage>,
     pub(crate) test_run_remaining_jobs: usize,
 
     // Project loading
-    pub(crate) discover_handle: Option<project_json::DiscoverHandle>,
-    pub(crate) discover_sender: Sender<project_json::DiscoverProjectMessage>,
-    pub(crate) discover_receiver: Receiver<project_json::DiscoverProjectMessage>,
+    pub(crate) discover_handle: Option<discover::DiscoverHandle>,
+    pub(crate) discover_sender: Sender<discover::DiscoverProjectMessage>,
+    pub(crate) discover_receiver: Receiver<discover::DiscoverProjectMessage>,
 
     // VFS
     pub(crate) loader: Handle<Box<dyn vfs::loader::Handle>, Receiver<vfs::loader::Message>>,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
index fc3a02ab184..a77d31167a7 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
@@ -51,6 +51,7 @@ use crate::{
         FetchDependencyListResult, PositionOrRange, ViewCrateGraphParams, WorkspaceSymbolParams,
     },
     target_spec::{CargoTargetSpec, TargetSpec},
+    test_runner::{CargoTestHandle, TestTarget},
 };
 
 pub(crate) fn handle_workspace_reload(state: &mut GlobalState, _: ()) -> anyhow::Result<()> {
@@ -246,15 +247,15 @@ pub(crate) fn handle_run_test(
         if let ProjectWorkspaceKind::Cargo { cargo, .. } = &ws.kind {
             let test_target = if let Some(namespace_root) = namespace_root {
                 if let Some(package_name) = find_package_name(namespace_root, cargo) {
-                    flycheck::TestTarget::Package(package_name)
+                    TestTarget::Package(package_name)
                 } else {
-                    flycheck::TestTarget::Workspace
+                    TestTarget::Workspace
                 }
             } else {
-                flycheck::TestTarget::Workspace
+                TestTarget::Workspace
             };
 
-            let handle = flycheck::CargoTestHandle::new(
+            let handle = CargoTestHandle::new(
                 test_path,
                 state.config.cargo_test_options(),
                 cargo.workspace_root(),
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs
index 174979edede..56eb420770e 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lib.rs
@@ -12,9 +12,12 @@
 pub mod cli;
 
 mod capabilities;
+mod command;
 mod diagnostics;
 mod diff;
+mod discover;
 mod dispatch;
+mod flycheck;
 mod hack_recover_crate_name;
 mod line_index;
 mod main_loop;
@@ -23,6 +26,7 @@ mod op_queue;
 mod reload;
 mod target_spec;
 mod task_pool;
+mod test_runner;
 mod version;
 
 mod handlers {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
index 54f718479f0..85e7d81fce3 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs
@@ -9,7 +9,6 @@ use std::{
 
 use always_assert::always;
 use crossbeam_channel::{select, Receiver};
-use flycheck::project_json;
 use ide_db::base_db::{SourceDatabase, SourceRootDatabase, VfsPath};
 use lsp_server::{Connection, Notification, Request};
 use lsp_types::{notification::Notification as _, TextDocumentIdentifier};
@@ -20,7 +19,9 @@ use vfs::{loader::LoadingProgress, AbsPathBuf, FileId};
 use crate::{
     config::Config,
     diagnostics::{fetch_native_diagnostics, DiagnosticsGeneration, NativeDiagnosticsFetchKind},
+    discover::{DiscoverArgument, DiscoverCommand, DiscoverProjectMessage},
     dispatch::{NotificationDispatcher, RequestDispatcher},
+    flycheck::{self, FlycheckMessage},
     global_state::{file_id_to_url, url_to_file_id, FetchWorkspaceRequest, GlobalState},
     hack_recover_crate_name,
     lsp::{
@@ -29,6 +30,7 @@ use crate::{
     },
     lsp_ext,
     reload::{BuildDataProgress, ProcMacroProgress, ProjectWorkspaceProgress},
+    test_runner::{CargoTestMessage, TestState},
 };
 
 pub fn main_loop(config: Config, connection: Connection) -> anyhow::Result<()> {
@@ -61,9 +63,9 @@ enum Event {
     Task(Task),
     QueuedTask(QueuedTask),
     Vfs(vfs::loader::Message),
-    Flycheck(flycheck::Message),
-    TestResult(flycheck::CargoTestMessage),
-    DiscoverProject(project_json::DiscoverProjectMessage),
+    Flycheck(FlycheckMessage),
+    TestResult(CargoTestMessage),
+    DiscoverProject(DiscoverProjectMessage),
 }
 
 impl fmt::Display for Event {
@@ -689,8 +691,7 @@ impl GlobalState {
                         // `self.report_progress` is called later
                         let title = &cfg.progress_label.clone();
                         let command = cfg.command.clone();
-                        let discover =
-                            project_json::Discover::new(self.discover_sender.clone(), command);
+                        let discover = DiscoverCommand::new(self.discover_sender.clone(), command);
 
                         self.report_progress(title, Progress::Begin, None, None, None);
                         self.discover_workspace_queue
@@ -698,12 +699,8 @@ impl GlobalState {
                         let _ = self.discover_workspace_queue.should_start_op();
 
                         let arg = match arg {
-                            DiscoverProjectParam::Buildfile(it) => {
-                                project_json::DiscoverArgument::Buildfile(it)
-                            }
-                            DiscoverProjectParam::Path(it) => {
-                                project_json::DiscoverArgument::Path(it)
-                            }
+                            DiscoverProjectParam::Buildfile(it) => DiscoverArgument::Buildfile(it),
+                            DiscoverProjectParam::Path(it) => DiscoverArgument::Path(it),
                         };
 
                         let handle = discover.spawn(arg).unwrap();
@@ -852,14 +849,14 @@ impl GlobalState {
         }
     }
 
-    fn handle_discover_msg(&mut self, message: project_json::DiscoverProjectMessage) {
+    fn handle_discover_msg(&mut self, message: DiscoverProjectMessage) {
         let title = self
             .config
             .discover_workspace_config()
             .map(|cfg| cfg.progress_label.clone())
             .expect("No title could be found; this is a bug");
         match message {
-            project_json::DiscoverProjectMessage::Finished { project, buildfile } => {
+            DiscoverProjectMessage::Finished { project, buildfile } => {
                 self.report_progress(&title, Progress::End, None, None, None);
                 self.discover_workspace_queue.op_completed(());
 
@@ -867,10 +864,10 @@ impl GlobalState {
                 config.add_linked_projects(project, buildfile);
                 self.update_configuration(config);
             }
-            project_json::DiscoverProjectMessage::Progress { message } => {
+            DiscoverProjectMessage::Progress { message } => {
                 self.report_progress(&title, Progress::Report, Some(message), None, None)
             }
-            project_json::DiscoverProjectMessage::Error { error, source } => {
+            DiscoverProjectMessage::Error { error, source } => {
                 let message = format!("Project discovery failed: {error}");
                 self.discover_workspace_queue.op_completed(());
                 self.show_and_log_error(message.clone(), source);
@@ -879,16 +876,14 @@ impl GlobalState {
         }
     }
 
-    fn handle_cargo_test_msg(&mut self, message: flycheck::CargoTestMessage) {
+    fn handle_cargo_test_msg(&mut self, message: CargoTestMessage) {
         match message {
-            flycheck::CargoTestMessage::Test { name, state } => {
+            CargoTestMessage::Test { name, state } => {
                 let state = match state {
-                    flycheck::TestState::Started => lsp_ext::TestState::Started,
-                    flycheck::TestState::Ignored => lsp_ext::TestState::Skipped,
-                    flycheck::TestState::Ok => lsp_ext::TestState::Passed,
-                    flycheck::TestState::Failed { stdout } => {
-                        lsp_ext::TestState::Failed { message: stdout }
-                    }
+                    TestState::Started => lsp_ext::TestState::Started,
+                    TestState::Ignored => lsp_ext::TestState::Skipped,
+                    TestState::Ok => lsp_ext::TestState::Passed,
+                    TestState::Failed { stdout } => lsp_ext::TestState::Failed { message: stdout },
                 };
                 let Some(test_id) = hack_recover_crate_name::lookup_name(name) else {
                     return;
@@ -897,23 +892,23 @@ impl GlobalState {
                     lsp_ext::ChangeTestStateParams { test_id, state },
                 );
             }
-            flycheck::CargoTestMessage::Suite => (),
-            flycheck::CargoTestMessage::Finished => {
+            CargoTestMessage::Suite => (),
+            CargoTestMessage::Finished => {
                 self.test_run_remaining_jobs = self.test_run_remaining_jobs.saturating_sub(1);
                 if self.test_run_remaining_jobs == 0 {
                     self.send_notification::<lsp_ext::EndRunTest>(());
                     self.test_run_session = None;
                 }
             }
-            flycheck::CargoTestMessage::Custom { text } => {
+            CargoTestMessage::Custom { text } => {
                 self.send_notification::<lsp_ext::AppendOutputToRunTest>(text);
             }
         }
     }
 
-    fn handle_flycheck_msg(&mut self, message: flycheck::Message) {
+    fn handle_flycheck_msg(&mut self, message: FlycheckMessage) {
         match message {
-            flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => {
+            FlycheckMessage::AddDiagnostic { id, workspace_root, diagnostic } => {
                 let snap = self.snapshot();
                 let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp(
                     &self.config.diagnostics_map(),
@@ -939,9 +934,9 @@ impl GlobalState {
                 }
             }
 
-            flycheck::Message::ClearDiagnostics { id } => self.diagnostics.clear_check(id),
+            FlycheckMessage::ClearDiagnostics { id } => self.diagnostics.clear_check(id),
 
-            flycheck::Message::Progress { id, progress } => {
+            FlycheckMessage::Progress { id, progress } => {
                 let (state, message) = match progress {
                     flycheck::Progress::DidStart => (Progress::Begin, None),
                     flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)),
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
index 39301f42884..e432f5d5cff 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -15,7 +15,6 @@
 // FIXME: This is a mess that needs some untangling work
 use std::{iter, mem};
 
-use flycheck::{FlycheckConfig, FlycheckHandle};
 use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros, ProcMacrosBuilder};
 use ide_db::{
     base_db::{salsa::Durability, CrateGraph, ProcMacroPaths, Version},
@@ -32,6 +31,7 @@ use vfs::{AbsPath, AbsPathBuf, ChangeKind};
 
 use crate::{
     config::{Config, FilesWatcher, LinkedProject},
+    flycheck::{FlycheckConfig, FlycheckHandle},
     global_state::{FetchWorkspaceRequest, GlobalState},
     lsp_ext,
     main_loop::{DiscoverProjectParam, Task},
@@ -749,12 +749,14 @@ impl GlobalState {
         let config = self.config.flycheck();
         let sender = self.flycheck_sender.clone();
         let invocation_strategy = match config {
-            FlycheckConfig::CargoCommand { .. } => flycheck::InvocationStrategy::PerWorkspace,
+            FlycheckConfig::CargoCommand { .. } => {
+                crate::flycheck::InvocationStrategy::PerWorkspace
+            }
             FlycheckConfig::CustomCommand { invocation_strategy, .. } => invocation_strategy,
         };
 
         self.flycheck = match invocation_strategy {
-            flycheck::InvocationStrategy::Once => vec![FlycheckHandle::spawn(
+            crate::flycheck::InvocationStrategy::Once => vec![FlycheckHandle::spawn(
                 0,
                 Box::new(move |msg| sender.send(msg).unwrap()),
                 config,
@@ -762,7 +764,7 @@ impl GlobalState {
                 self.config.root_path().clone(),
                 None,
             )],
-            flycheck::InvocationStrategy::PerWorkspace => {
+            crate::flycheck::InvocationStrategy::PerWorkspace => {
                 self.workspaces
                     .iter()
                     .enumerate()
diff --git a/src/tools/rust-analyzer/crates/flycheck/src/test_runner.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs
index 74ebca34103..293cff47433 100644
--- a/src/tools/rust-analyzer/crates/flycheck/src/test_runner.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/test_runner.rs
@@ -10,12 +10,12 @@ use toolchain::Tool;
 
 use crate::{
     command::{CommandHandle, ParseFromLine},
-    CargoOptions,
+    flycheck::CargoOptions,
 };
 
 #[derive(Debug, Deserialize)]
 #[serde(tag = "event", rename_all = "camelCase")]
-pub enum TestState {
+pub(crate) enum TestState {
     Started,
     Ok,
     Ignored,
@@ -24,7 +24,7 @@ pub enum TestState {
 
 #[derive(Debug, Deserialize)]
 #[serde(tag = "type", rename_all = "camelCase")]
-pub enum CargoTestMessage {
+pub(crate) enum CargoTestMessage {
     Test {
         name: String,
         #[serde(flatten)]
@@ -54,7 +54,7 @@ impl ParseFromLine for CargoTestMessage {
 }
 
 #[derive(Debug)]
-pub struct CargoTestHandle {
+pub(crate) struct CargoTestHandle {
     _handle: CommandHandle<CargoTestMessage>,
 }
 
@@ -64,13 +64,13 @@ pub struct CargoTestHandle {
 // cargo test --package my-package --no-fail-fast -- module::func -Z unstable-options --format=json
 
 #[derive(Debug)]
-pub enum TestTarget {
+pub(crate) enum TestTarget {
     Workspace,
     Package(String),
 }
 
 impl CargoTestHandle {
-    pub fn new(
+    pub(crate) fn new(
         path: Option<&str>,
         options: CargoOptions,
         root: &AbsPath,