@@ -20,6 +20,7 @@ use crate::{
2020 lsp_ext:: { self , RunFlycheckParams } ,
2121 mem_docs:: DocumentData ,
2222 reload,
23+ target_spec:: TargetSpec ,
2324} ;
2425
2526pub ( 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}
0 commit comments