11//! Flycheck provides the functionality needed to run `cargo check` to provide
22//! LSP diagnostics based on the output of the command.
33
4- use std:: { fmt, io, mem , process:: Command , time:: Duration } ;
4+ use std:: { fmt, io, process:: Command , time:: Duration } ;
55
66use cargo_metadata:: PackageId ;
77use crossbeam_channel:: { select_biased, unbounded, Receiver , Sender } ;
8+ use ide_db:: FxHashSet ;
89use paths:: { AbsPath , AbsPathBuf , Utf8PathBuf } ;
910use rustc_hash:: FxHashMap ;
1011use serde:: Deserialize as _;
@@ -231,13 +232,7 @@ struct FlycheckActor {
231232 command_handle : Option < CommandHandle < CargoCheckMessage > > ,
232233 /// The receiver side of the channel mentioned above.
233234 command_receiver : Option < Receiver < CargoCheckMessage > > ,
234- package_status : FxHashMap < Arc < PackageId > , DiagnosticReceived > ,
235- }
236-
237- #[ derive( PartialEq , Eq , Copy , Clone , Debug ) ]
238- enum DiagnosticReceived {
239- Yes ,
240- No ,
235+ diagnostics_cleared_for : FxHashSet < Arc < PackageId > > ,
241236}
242237
243238#[ allow( clippy:: large_enum_variant) ]
@@ -267,7 +262,7 @@ impl FlycheckActor {
267262 manifest_path,
268263 command_handle : None ,
269264 command_receiver : None ,
270- package_status : FxHashMap :: default ( ) ,
265+ diagnostics_cleared_for : Default :: default ( ) ,
271266 }
272267 }
273268
@@ -344,16 +339,16 @@ impl FlycheckActor {
344339 error
345340 ) ;
346341 }
347- if self . package_status . is_empty ( ) {
342+ if self . diagnostics_cleared_for . is_empty ( ) {
348343 tracing:: trace!( flycheck_id = self . id, "clearing diagnostics" ) ;
349344 // We finished without receiving any diagnostics.
350- // That means all of them are stale.
345+ // Clear everything for good measure
351346 self . send ( FlycheckMessage :: ClearDiagnostics {
352347 id : self . id ,
353348 package_id : None ,
354349 } ) ;
355350 } else {
356- self . send_clear_diagnostics ( ) ;
351+ self . diagnostics_cleared_for . clear ( ) ;
357352 }
358353
359354 self . report_progress ( Progress :: DidFinish ( res) ) ;
@@ -367,9 +362,18 @@ impl FlycheckActor {
367362 "artifact received"
368363 ) ;
369364 self . report_progress ( Progress :: DidCheckCrate ( msg. target . name ) ) ;
370- self . package_status
371- . entry ( Arc :: new ( msg. package_id ) )
372- . or_insert ( DiagnosticReceived :: No ) ;
365+ let package_id = Arc :: new ( msg. package_id ) ;
366+ if self . diagnostics_cleared_for . insert ( package_id. clone ( ) ) {
367+ tracing:: trace!(
368+ flycheck_id = self . id,
369+ package_id = package_id. repr,
370+ "clearing diagnostics"
371+ ) ;
372+ self . send ( FlycheckMessage :: ClearDiagnostics {
373+ id : self . id ,
374+ package_id : Some ( package_id) ,
375+ } ) ;
376+ }
373377 }
374378 CargoCheckMessage :: Diagnostic { diagnostic, package_id } => {
375379 tracing:: trace!(
@@ -379,10 +383,7 @@ impl FlycheckActor {
379383 "diagnostic received"
380384 ) ;
381385 if let Some ( package_id) = & package_id {
382- if let None | Some ( DiagnosticReceived :: No ) = self
383- . package_status
384- . insert ( package_id. clone ( ) , DiagnosticReceived :: Yes )
385- {
386+ if self . diagnostics_cleared_for . insert ( package_id. clone ( ) ) {
386387 tracing:: trace!(
387388 flycheck_id = self . id,
388389 package_id = package_id. repr,
@@ -417,23 +418,7 @@ impl FlycheckActor {
417418 command_handle. cancel ( ) ;
418419 self . command_receiver . take ( ) ;
419420 self . report_progress ( Progress :: DidCancel ) ;
420- self . send_clear_diagnostics ( ) ;
421- }
422- }
423-
424- fn send_clear_diagnostics ( & mut self ) {
425- for ( package_id, status) in mem:: take ( & mut self . package_status ) {
426- if let DiagnosticReceived :: No = status {
427- tracing:: trace!(
428- flycheck_id = self . id,
429- package_id = package_id. repr,
430- "clearing diagnostics"
431- ) ;
432- self . send ( FlycheckMessage :: ClearDiagnostics {
433- id : self . id ,
434- package_id : Some ( package_id) ,
435- } ) ;
436- }
421+ self . diagnostics_cleared_for . clear ( ) ;
437422 }
438423 }
439424
0 commit comments