@@ -20,6 +20,7 @@ use crate::{
20
20
lsp_ext:: { self , RunFlycheckParams } ,
21
21
mem_docs:: DocumentData ,
22
22
reload,
23
+ target_spec:: TargetSpec ,
23
24
} ;
24
25
25
26
pub ( crate ) fn handle_cancel ( state : & mut GlobalState , params : CancelParams ) -> anyhow:: Result < ( ) > {
@@ -185,7 +186,7 @@ pub(crate) fn handle_did_save_text_document(
185
186
} else if state. config . check_on_save ( ) {
186
187
// No specific flycheck was triggered, so let's trigger all of them.
187
188
for flycheck in state. flycheck . iter ( ) {
188
- flycheck. restart_workspace ( None ) ;
189
+ flycheck. restart_workspace ( None , None ) ;
189
190
}
190
191
}
191
192
Ok ( ( ) )
@@ -287,16 +288,33 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
287
288
let world = state. snapshot ( ) ;
288
289
let mut updated = false ;
289
290
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
+ } ;
300
318
301
319
let crate_root_paths: Vec < _ > = crate_ids
302
320
. iter ( )
@@ -347,8 +365,11 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
347
365
if id == flycheck. id ( ) {
348
366
updated = true ;
349
367
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 ( ) ) ,
352
373
}
353
374
continue ;
354
375
}
@@ -357,7 +378,7 @@ fn run_flycheck(state: &mut GlobalState, vfs_path: VfsPath) -> bool {
357
378
// No specific flycheck was triggered, so let's trigger all of them.
358
379
if !updated {
359
380
for flycheck in world. flycheck . iter ( ) {
360
- flycheck. restart_workspace ( saved_file. clone ( ) ) ;
381
+ flycheck. restart_workspace ( saved_file. clone ( ) , None ) ;
361
382
}
362
383
}
363
384
Ok ( ( ) )
@@ -399,7 +420,7 @@ pub(crate) fn handle_run_flycheck(
399
420
}
400
421
// No specific flycheck was triggered, so let's trigger all of them.
401
422
for flycheck in state. flycheck . iter ( ) {
402
- flycheck. restart_workspace ( None ) ;
423
+ flycheck. restart_workspace ( None , None ) ;
403
424
}
404
425
Ok ( ( ) )
405
426
}
0 commit comments