@@ -421,11 +421,17 @@ struct FlycheckActor {
421421 diagnostics_received : DiagnosticsReceived ,
422422}
423423
424- #[ derive( PartialEq ) ]
424+ #[ derive( PartialEq , Debug ) ]
425425enum DiagnosticsReceived {
426- Yes ,
427- No ,
428- YesAndClearedForAll ,
426+ /// We started a flycheck, but we haven't seen any diagnostics yet.
427+ NotYet ,
428+ /// We received a non-zero number of diagnostics from rustc or clippy (via
429+ /// cargo or custom check command). This means there were errors or
430+ /// warnings.
431+ AtLeastOne ,
432+ /// We received a non-zero number of diagnostics, and the scope is
433+ /// workspace, so we've discarded the previous workspace diagnostics.
434+ AtLeastOneAndClearedWorkspace ,
429435}
430436
431437#[ allow( clippy:: large_enum_variant) ]
@@ -522,7 +528,7 @@ impl FlycheckActor {
522528 command_handle : None ,
523529 command_receiver : None ,
524530 diagnostics_cleared_for : Default :: default ( ) ,
525- diagnostics_received : DiagnosticsReceived :: No ,
531+ diagnostics_received : DiagnosticsReceived :: NotYet ,
526532 }
527533 }
528534
@@ -641,7 +647,7 @@ impl FlycheckActor {
641647 error
642648 ) ;
643649 }
644- if self . diagnostics_received == DiagnosticsReceived :: No {
650+ if self . diagnostics_received == DiagnosticsReceived :: NotYet {
645651 tracing:: trace!( flycheck_id = self . id, "clearing diagnostics" ) ;
646652 // We finished without receiving any diagnostics.
647653 // Clear everything for good measure
@@ -735,41 +741,70 @@ impl FlycheckActor {
735741 flycheck_id = self . id,
736742 message = diagnostic. message,
737743 package_id = package_id. as_ref( ) . map( |it| it. as_str( ) ) ,
744+ scope = ?self . scope,
738745 "diagnostic received"
739746 ) ;
740- if self . diagnostics_received == DiagnosticsReceived :: No {
741- self . diagnostics_received = DiagnosticsReceived :: Yes ;
742- }
743- if let Some ( package_id) = & package_id {
744- if self . diagnostics_cleared_for . insert ( package_id. clone ( ) ) {
745- tracing:: trace!(
746- flycheck_id = self . id,
747- package_id = package_id. as_str( ) ,
748- "clearing diagnostics"
749- ) ;
750- self . send ( FlycheckMessage :: ClearDiagnostics {
747+
748+ match & self . scope {
749+ FlycheckScope :: Workspace => {
750+ if self . diagnostics_received == DiagnosticsReceived :: NotYet {
751+ self . send ( FlycheckMessage :: ClearDiagnostics {
752+ id : self . id ,
753+ kind : ClearDiagnosticsKind :: All ( ClearScope :: Workspace ) ,
754+ } ) ;
755+
756+ self . diagnostics_received =
757+ DiagnosticsReceived :: AtLeastOneAndClearedWorkspace ;
758+ }
759+
760+ if let Some ( package_id) = package_id {
761+ tracing:: warn!(
762+ "Ignoring package label {:?} and applying diagnostics to the whole workspace" ,
763+ package_id
764+ ) ;
765+ }
766+
767+ self . send ( FlycheckMessage :: AddDiagnostic {
751768 id : self . id ,
752- kind : ClearDiagnosticsKind :: All ( ClearScope :: Package (
753- package_id. clone ( ) ,
754- ) ) ,
769+ generation : self . generation ,
770+ package_id : None ,
771+ workspace_root : self . root . clone ( ) ,
772+ diagnostic,
773+ } ) ;
774+ }
775+ FlycheckScope :: Package { package : flycheck_package, .. } => {
776+ if self . diagnostics_received == DiagnosticsReceived :: NotYet {
777+ self . diagnostics_received = DiagnosticsReceived :: AtLeastOne ;
778+ }
779+
780+ // If the package has been set in the diagnostic JSON, respect that. Otherwise, use the
781+ // package that the current flycheck is scoped to. This is useful when a project is
782+ // directly using rustc for its checks (e.g. custom check commands in rust-project.json).
783+ let package_id = package_id. unwrap_or ( flycheck_package. clone ( ) ) ;
784+
785+ if self . diagnostics_cleared_for . insert ( package_id. clone ( ) ) {
786+ tracing:: trace!(
787+ flycheck_id = self . id,
788+ package_id = package_id. as_str( ) ,
789+ "clearing diagnostics"
790+ ) ;
791+ self . send ( FlycheckMessage :: ClearDiagnostics {
792+ id : self . id ,
793+ kind : ClearDiagnosticsKind :: All ( ClearScope :: Package (
794+ package_id. clone ( ) ,
795+ ) ) ,
796+ } ) ;
797+ }
798+
799+ self . send ( FlycheckMessage :: AddDiagnostic {
800+ id : self . id ,
801+ generation : self . generation ,
802+ package_id : Some ( package_id) ,
803+ workspace_root : self . root . clone ( ) ,
804+ diagnostic,
755805 } ) ;
756806 }
757- } else if self . diagnostics_received
758- != DiagnosticsReceived :: YesAndClearedForAll
759- {
760- self . diagnostics_received = DiagnosticsReceived :: YesAndClearedForAll ;
761- self . send ( FlycheckMessage :: ClearDiagnostics {
762- id : self . id ,
763- kind : ClearDiagnosticsKind :: All ( ClearScope :: Workspace ) ,
764- } ) ;
765807 }
766- self . send ( FlycheckMessage :: AddDiagnostic {
767- id : self . id ,
768- generation : self . generation ,
769- package_id,
770- workspace_root : self . root . clone ( ) ,
771- diagnostic,
772- } ) ;
773808 }
774809 } ,
775810 }
@@ -793,7 +828,7 @@ impl FlycheckActor {
793828
794829 fn clear_diagnostics_state ( & mut self ) {
795830 self . diagnostics_cleared_for . clear ( ) ;
796- self . diagnostics_received = DiagnosticsReceived :: No ;
831+ self . diagnostics_received = DiagnosticsReceived :: NotYet ;
797832 }
798833
799834 fn explicit_check_command (
0 commit comments