about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs39
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs43
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs4
3 files changed, 51 insertions, 35 deletions
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
index 0e859f32751..9fb43286579 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/flycheck.rs
@@ -34,6 +34,14 @@ pub(crate) struct CargoOptions {
     pub(crate) target_dir: Option<Utf8PathBuf>,
 }
 
+#[derive(Clone)]
+pub(crate) enum Target {
+    Bin(String),
+    Example(String),
+    Benchmark(String),
+    Test(String),
+}
+
 impl CargoOptions {
     pub(crate) fn apply_on_command(&self, cmd: &mut Command) {
         for target in &self.target_triples {
@@ -118,12 +126,12 @@ impl FlycheckHandle {
     }
 
     /// Schedule a re-start of the cargo check worker to do a workspace wide check.
-    pub(crate) fn restart_workspace(&self, saved_file: Option<AbsPathBuf>, target: Option<String>) {
-        self.sender.send(StateChange::Restart { package: None, saved_file, target }).unwrap();
+    pub(crate) fn restart_workspace(&self, saved_file: Option<AbsPathBuf>) {
+        self.sender.send(StateChange::Restart { package: None, saved_file, target: None }).unwrap();
     }
 
     /// Schedule a re-start of the cargo check worker to do a package wide check.
-    pub(crate) fn restart_for_package(&self, package: String, target: Option<String>) {
+    pub(crate) fn restart_for_package(&self, package: String, target: Option<Target>) {
         self.sender
             .send(StateChange::Restart { package: Some(package), saved_file: None, target })
             .unwrap();
@@ -183,7 +191,7 @@ pub(crate) enum Progress {
 }
 
 enum StateChange {
-    Restart { package: Option<String>, saved_file: Option<AbsPathBuf>, target: Option<String> },
+    Restart { package: Option<String>, saved_file: Option<AbsPathBuf>, target: Option<Target> },
     Cancel,
 }
 
@@ -281,14 +289,12 @@ impl FlycheckActor {
                         }
                     }
 
-                    let command = match self.check_command(
-                        package.as_deref(),
-                        saved_file.as_deref(),
-                        target.as_deref(),
-                    ) {
-                        Some(c) => c,
-                        None => continue,
+                    let Some(command) =
+                        self.check_command(package.as_deref(), saved_file.as_deref(), target)
+                    else {
+                        continue;
                     };
+
                     let formatted_command = format!("{command:?}");
 
                     tracing::debug!(?command, "will restart flycheck");
@@ -384,7 +390,7 @@ impl FlycheckActor {
         &self,
         package: Option<&str>,
         saved_file: Option<&AbsPath>,
-        bin_target: Option<&str>,
+        target: Option<Target>,
     ) -> Option<Command> {
         match &self.config {
             FlycheckConfig::CargoCommand { command, options, ansi_color_output } => {
@@ -400,8 +406,13 @@ impl FlycheckActor {
                     None => cmd.arg("--workspace"),
                 };
 
-                if let Some(tgt) = bin_target {
-                    cmd.arg("--bin").arg(tgt);
+                if let Some(tgt) = target {
+                    match tgt {
+                        Target::Bin(tgt) => cmd.arg("--bin").arg(tgt),
+                        Target::Example(tgt) => cmd.arg("--example").arg(tgt),
+                        Target::Test(tgt) => cmd.arg("--test").arg(tgt),
+                        Target::Benchmark(tgt) => cmd.arg("--bench").arg(tgt),
+                    };
                 }
 
                 cmd.arg(if *ansi_color_output {
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
index fb7caf652d0..f99319271ba 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/notification.rs
@@ -15,6 +15,7 @@ use vfs::{AbsPathBuf, ChangeKind, VfsPath};
 
 use crate::{
     config::{Config, ConfigChange},
+    flycheck::Target,
     global_state::{FetchWorkspaceRequest, GlobalState},
     lsp::{from_proto, utils::apply_document_changes},
     lsp_ext::{self, RunFlycheckParams},
@@ -186,7 +187,7 @@ pub(crate) fn handle_did_save_text_document(
     } else if state.config.check_on_save() {
         // No specific flycheck was triggered, so let's trigger all of them.
         for flycheck in state.flycheck.iter() {
-            flycheck.restart_workspace(None, None);
+            flycheck.restart_workspace(None);
         }
     }
     Ok(())
@@ -289,18 +290,25 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
         let mut updated = false;
         let task = move || -> std::result::Result<(), ide::Cancelled> {
             // Is the target binary? If so we let flycheck run only for the workspace that contains the crate.
-            let target_is_bin = TargetSpec::for_file(&world, file_id)?.and_then(|x| {
-                if x.target_kind() == project_model::TargetKind::Bin {
-                    return match x {
-                        TargetSpec::Cargo(c) => Some(c.target),
-                        TargetSpec::ProjectJson(p) => Some(p.label),
-                    };
-                }
+            let target = TargetSpec::for_file(&world, file_id)?.and_then(|x| {
+                let tgt_kind = x.target_kind();
+                let tgt_name = match x {
+                    TargetSpec::Cargo(c) => c.target,
+                    TargetSpec::ProjectJson(p) => p.label,
+                };
+
+                let tgt = match tgt_kind {
+                    project_model::TargetKind::Bin => Target::Bin(tgt_name),
+                    project_model::TargetKind::Example => Target::Example(tgt_name),
+                    project_model::TargetKind::Test => Target::Test(tgt_name),
+                    project_model::TargetKind::Bench => Target::Benchmark(tgt_name),
+                    _ => return None,
+                };
 
-                None
+                Some(tgt)
             });
 
-            let crate_ids = if target_is_bin.is_some() {
+            let crate_ids = if target.is_some() {
                 // Trigger flychecks for the only workspace which the binary crate belongs to
                 world.analysis.crates_for(file_id)?.into_iter().unique().collect::<Vec<_>>()
             } else {
@@ -364,12 +372,11 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
                 for (id, package) in workspace_ids.clone() {
                     if id == flycheck.id() {
                         updated = true;
-                        match package.filter(|_| !world.config.flycheck_workspace()) {
-                            Some(package) => {
-                                flycheck.restart_for_package(package, target_is_bin.clone())
-                            }
-                            None => flycheck
-                                .restart_workspace(saved_file.clone(), target_is_bin.clone()),
+                        match package
+                            .filter(|_| !world.config.flycheck_workspace() || target.is_some())
+                        {
+                            Some(package) => flycheck.restart_for_package(package, target.clone()),
+                            None => flycheck.restart_workspace(saved_file.clone()),
                         }
                         continue;
                     }
@@ -378,7 +385,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
             // No specific flycheck was triggered, so let's trigger all of them.
             if !updated {
                 for flycheck in world.flycheck.iter() {
-                    flycheck.restart_workspace(saved_file.clone(), None);
+                    flycheck.restart_workspace(saved_file.clone());
                 }
             }
             Ok(())
@@ -420,7 +427,7 @@ pub(crate) fn handle_run_flycheck(
     }
     // No specific flycheck was triggered, so let's trigger all of them.
     for flycheck in state.flycheck.iter() {
-        flycheck.restart_workspace(None, None);
+        flycheck.restart_workspace(None);
     }
     Ok(())
 }
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 79a209f8bfe..1d4ee71e5c1 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
@@ -406,9 +406,7 @@ impl GlobalState {
             if became_quiescent {
                 if self.config.check_on_save() {
                     // Project has loaded properly, kick off initial flycheck
-                    self.flycheck
-                        .iter()
-                        .for_each(|flycheck| flycheck.restart_workspace(None, None));
+                    self.flycheck.iter().for_each(|flycheck| flycheck.restart_workspace(None));
                 }
                 if self.config.prefill_caches() {
                     self.prime_caches_queue.request_op("became quiescent".to_owned(), ());