Unnamed repository; edit this file 'description' to name the repository.
add `FlycheckStatus` to global state
| -rw-r--r-- | crates/rust-analyzer/src/global_state.rs | 21 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 20 |
2 files changed, 34 insertions, 7 deletions
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 0c2e60fcc9..1216de2de4 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -87,7 +87,7 @@ pub(crate) struct GlobalState { pub(crate) flycheck_sender: Sender<flycheck::Message>, pub(crate) flycheck_receiver: Receiver<flycheck::Message>, pub(crate) last_flycheck_error: Option<String>, - pub(crate) diagnostics_received: FxHashMap<usize, bool>, + pub(crate) flycheck_status: FxHashMap<usize, FlycheckStatus>, // Test explorer pub(crate) test_run_session: Option<Vec<flycheck::CargoTestHandle>>, @@ -166,6 +166,14 @@ pub(crate) struct GlobalStateSnapshot { pub(crate) flycheck: Arc<[FlycheckHandle]>, } +#[derive(Debug, Clone)] +pub(crate) enum FlycheckStatus { + Unknown, + Started, + DiagnosticReceived, + Finished, +} + impl std::panic::UnwindSafe for GlobalStateSnapshot {} impl GlobalState { @@ -225,7 +233,7 @@ impl GlobalState { flycheck_sender, flycheck_receiver, last_flycheck_error: None, - diagnostics_received: FxHashMap::default(), + flycheck_status: FxHashMap::default(), test_run_session: None, test_run_sender, @@ -513,3 +521,12 @@ pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> anyhow::Result<FileId let res = vfs.file_id(&path).ok_or_else(|| anyhow::format_err!("file not found: {path}"))?; Ok(res) } + +impl FlycheckStatus { + pub(crate) fn should_clear_old_diagnostics(&self) -> bool { + match self { + FlycheckStatus::Unknown | FlycheckStatus::Started => false, + FlycheckStatus::DiagnosticReceived | FlycheckStatus::Finished => true, + } + } +} diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index a94ca871bd..efedea77fe 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -19,7 +19,7 @@ use crate::{ config::Config, diagnostics::fetch_native_diagnostics, dispatch::{NotificationDispatcher, RequestDispatcher}, - global_state::{file_id_to_url, url_to_file_id, GlobalState}, + global_state::{file_id_to_url, url_to_file_id, FlycheckStatus, GlobalState}, hack_recover_crate_name, lsp::{ from_proto, to_proto, @@ -804,10 +804,13 @@ impl GlobalState { fn handle_flycheck_msg(&mut self, message: flycheck::Message) { match message { flycheck::Message::AddDiagnostic { id, workspace_root, diagnostic } => { - if !self.diagnostics_received.get(&id).copied().unwrap_or_default() { + let flycheck_status = + self.flycheck_status.entry(id).or_insert(FlycheckStatus::Unknown); + + if !flycheck_status.should_clear_old_diagnostics() { self.diagnostics.clear_check(id); - self.diagnostics_received.insert(id, true); } + *flycheck_status = FlycheckStatus::DiagnosticReceived; let snap = self.snapshot(); let diagnostics = crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( &self.config.diagnostics_map(), @@ -836,25 +839,32 @@ impl GlobalState { flycheck::Message::Progress { id, progress } => { let (state, message) = match progress { flycheck::Progress::DidStart => { - self.diagnostics_received.insert(id, false); + self.flycheck_status.insert(id, FlycheckStatus::Started); (Progress::Begin, None) } flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)), flycheck::Progress::DidCancel => { self.last_flycheck_error = None; + // We do not clear + self.flycheck_status.insert(id, FlycheckStatus::Finished); (Progress::End, None) } flycheck::Progress::DidFailToRestart(err) => { self.last_flycheck_error = Some(format!("cargo check failed to start: {err}")); + self.flycheck_status.insert(id, FlycheckStatus::Finished); return; } flycheck::Progress::DidFinish(result) => { self.last_flycheck_error = result.err().map(|err| format!("cargo check failed to start: {err}")); - if !self.diagnostics_received.get(&id).copied().unwrap_or_default() { + let flycheck_status = + self.flycheck_status.entry(id).or_insert(FlycheckStatus::Unknown); + + if !flycheck_status.should_clear_old_diagnostics() { self.diagnostics.clear_check(id); } + *flycheck_status = FlycheckStatus::Finished; (Progress::End, None) } }; |