Skip to content

Commit ffc3bfe

Browse files
committed
Run flycheck only on crate if target is binary.
1 parent b02c214 commit ffc3bfe

File tree

3 files changed

+58
-27
lines changed

3 files changed

+58
-27
lines changed

crates/rust-analyzer/src/flycheck.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,14 @@ impl FlycheckHandle {
118118
}
119119

120120
/// Schedule a re-start of the cargo check worker to do a workspace wide check.
121-
pub(crate) fn restart_workspace(&self, saved_file: Option<AbsPathBuf>) {
122-
self.sender.send(StateChange::Restart { package: None, saved_file }).unwrap();
121+
pub(crate) fn restart_workspace(&self, saved_file: Option<AbsPathBuf>, target: Option<String>) {
122+
self.sender.send(StateChange::Restart { package: None, saved_file, target }).unwrap();
123123
}
124124

125125
/// Schedule a re-start of the cargo check worker to do a package wide check.
126-
pub(crate) fn restart_for_package(&self, package: String) {
126+
pub(crate) fn restart_for_package(&self, package: String, target: Option<String>) {
127127
self.sender
128-
.send(StateChange::Restart { package: Some(package), saved_file: None })
128+
.send(StateChange::Restart { package: Some(package), saved_file: None, target })
129129
.unwrap();
130130
}
131131

@@ -183,7 +183,7 @@ pub(crate) enum Progress {
183183
}
184184

185185
enum StateChange {
186-
Restart { package: Option<String>, saved_file: Option<AbsPathBuf> },
186+
Restart { package: Option<String>, saved_file: Option<AbsPathBuf>, target: Option<String> },
187187
Cancel,
188188
}
189189

@@ -271,7 +271,7 @@ impl FlycheckActor {
271271
tracing::debug!(flycheck_id = self.id, "flycheck cancelled");
272272
self.cancel_check_process();
273273
}
274-
Event::RequestStateChange(StateChange::Restart { package, saved_file }) => {
274+
Event::RequestStateChange(StateChange::Restart { package, saved_file, target }) => {
275275
// Cancel the previously spawned process
276276
self.cancel_check_process();
277277
while let Ok(restart) = inbox.recv_timeout(Duration::from_millis(50)) {
@@ -281,11 +281,14 @@ impl FlycheckActor {
281281
}
282282
}
283283

284-
let command =
285-
match self.check_command(package.as_deref(), saved_file.as_deref()) {
286-
Some(c) => c,
287-
None => continue,
288-
};
284+
let command = match self.check_command(
285+
package.as_deref(),
286+
saved_file.as_deref(),
287+
target.as_deref(),
288+
) {
289+
Some(c) => c,
290+
None => continue,
291+
};
289292
let formatted_command = format!("{command:?}");
290293

291294
tracing::debug!(?command, "will restart flycheck");
@@ -381,6 +384,7 @@ impl FlycheckActor {
381384
&self,
382385
package: Option<&str>,
383386
saved_file: Option<&AbsPath>,
387+
bin_target: Option<&str>,
384388
) -> Option<Command> {
385389
match &self.config {
386390
FlycheckConfig::CargoCommand { command, options, ansi_color_output } => {
@@ -396,6 +400,10 @@ impl FlycheckActor {
396400
None => cmd.arg("--workspace"),
397401
};
398402

403+
if let Some(tgt) = bin_target {
404+
cmd.arg("--bin").arg(tgt);
405+
}
406+
399407
cmd.arg(if *ansi_color_output {
400408
"--message-format=json-diagnostic-rendered-ansi"
401409
} else {

crates/rust-analyzer/src/handlers/notification.rs

+36-15
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::{
2020
lsp_ext::{self, RunFlycheckParams},
2121
mem_docs::DocumentData,
2222
reload,
23+
target_spec::TargetSpec,
2324
};
2425

2526
pub(crate) fn handle_cancel(state: &mut GlobalState, params: CancelParams) -> anyhow::Result<()> {
@@ -185,7 +186,7 @@ pub(crate) fn handle_did_save_text_document(
185186
} else if state.config.check_on_save() {
186187
// No specific flycheck was triggered, so let's trigger all of them.
187188
for flycheck in state.flycheck.iter() {
188-
flycheck.restart_workspace(None);
189+
flycheck.restart_workspace(None, None);
189190
}
190191
}
191192
Ok(())
@@ -287,16 +288,33 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
287288
let world = state.snapshot();
288289
let mut updated = false;
289290
let task = move || -> std::result::Result<(), ide::Cancelled> {
290-
// Trigger flychecks for all workspaces that depend on the saved file
291-
// Crates containing or depending on the saved file
292-
let crate_ids: Vec<_> = world
293-
.analysis
294-
.crates_for(file_id)?
295-
.into_iter()
296-
.flat_map(|id| world.analysis.transitive_rev_deps(id))
297-
.flatten()
298-
.unique()
299-
.collect();
291+
// Is the target binary? If so we let flycheck run only for the workspace that contains the crate.
292+
let target_is_bin = TargetSpec::for_file(&world, file_id)?.and_then(|x| {
293+
if x.target_kind() == project_model::TargetKind::Bin {
294+
return match x {
295+
TargetSpec::Cargo(c) => Some(c.target),
296+
TargetSpec::ProjectJson(p) => Some(p.label),
297+
};
298+
}
299+
300+
None
301+
});
302+
303+
let crate_ids = if target_is_bin.is_some() {
304+
// Trigger flychecks for the only workspace which the binary crate belongs to
305+
world.analysis.crates_for(file_id)?.into_iter().unique().collect::<Vec<_>>()
306+
} else {
307+
// Trigger flychecks for all workspaces that depend on the saved file
308+
// Crates containing or depending on the saved file
309+
world
310+
.analysis
311+
.crates_for(file_id)?
312+
.into_iter()
313+
.flat_map(|id| world.analysis.transitive_rev_deps(id))
314+
.flatten()
315+
.unique()
316+
.collect::<Vec<_>>()
317+
};
300318

301319
let crate_root_paths: Vec<_> = crate_ids
302320
.iter()
@@ -347,8 +365,11 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
347365
if id == flycheck.id() {
348366
updated = true;
349367
match package.filter(|_| !world.config.flycheck_workspace()) {
350-
Some(package) => flycheck.restart_for_package(package),
351-
None => flycheck.restart_workspace(saved_file.clone()),
368+
Some(package) => {
369+
flycheck.restart_for_package(package, target_is_bin.clone())
370+
}
371+
None => flycheck
372+
.restart_workspace(saved_file.clone(), target_is_bin.clone()),
352373
}
353374
continue;
354375
}
@@ -357,7 +378,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
357378
// No specific flycheck was triggered, so let's trigger all of them.
358379
if !updated {
359380
for flycheck in world.flycheck.iter() {
360-
flycheck.restart_workspace(saved_file.clone());
381+
flycheck.restart_workspace(saved_file.clone(), None);
361382
}
362383
}
363384
Ok(())
@@ -399,7 +420,7 @@ pub(crate) fn handle_run_flycheck(
399420
}
400421
// No specific flycheck was triggered, so let's trigger all of them.
401422
for flycheck in state.flycheck.iter() {
402-
flycheck.restart_workspace(None);
423+
flycheck.restart_workspace(None, None);
403424
}
404425
Ok(())
405426
}

crates/rust-analyzer/src/main_loop.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,9 @@ impl GlobalState {
406406
if became_quiescent {
407407
if self.config.check_on_save() {
408408
// Project has loaded properly, kick off initial flycheck
409-
self.flycheck.iter().for_each(|flycheck| flycheck.restart_workspace(None));
409+
self.flycheck
410+
.iter()
411+
.for_each(|flycheck| flycheck.restart_workspace(None, None));
410412
}
411413
if self.config.prefill_caches() {
412414
self.prime_caches_queue.request_op("became quiescent".to_owned(), ());

0 commit comments

Comments
 (0)