From a40e05dd5d8b2c5f74c61cd08efed9dc83124657 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 15 Jul 2020 14:37:44 +0200 Subject: [PATCH] Don't drop flycheck messages during restart closes #5386 --- crates/rust-analyzer/src/global_state.rs | 7 +++++- crates/rust-analyzer/src/main_loop.rs | 8 +++--- crates/rust-analyzer/src/reload.rs | 32 +++++++++++------------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 9a9a6547a97..94973b90a49 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -63,7 +63,9 @@ pub(crate) struct GlobalState { req_queue: ReqQueue, pub(crate) task_pool: Handle, Receiver>, pub(crate) loader: Handle, Receiver>, - pub(crate) flycheck: Option>>, + pub(crate) flycheck: Option, + pub(crate) flycheck_sender: Sender, + pub(crate) flycheck_receiver: Receiver, pub(crate) config: Config, pub(crate) analysis_host: AnalysisHost, pub(crate) diagnostics: DiagnosticCollection, @@ -103,12 +105,15 @@ pub(crate) fn new(sender: Sender, config: Config) -> Global }; let analysis_host = AnalysisHost::new(config.lru_capacity); + let (flycheck_sender, flycheck_receiver) = unbounded(); GlobalState { sender, req_queue: ReqQueue::default(), task_pool, loader, flycheck: None, + flycheck_sender, + flycheck_receiver, config, analysis_host, diagnostics: Default::default(), diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 5afcc2d87ac..a41f7f56466 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -5,7 +5,7 @@ time::{Duration, Instant}, }; -use crossbeam_channel::{never, select, Receiver}; +use crossbeam_channel::{select, Receiver}; use lsp_server::{Connection, Notification, Request, Response}; use lsp_types::notification::Notification as _; use ra_db::VfsPath; @@ -108,7 +108,7 @@ fn next_event(&self, inbox: &Receiver) -> Option { recv(self.loader.receiver) -> task => Some(Event::Vfs(task.unwrap())), - recv(self.flycheck.as_ref().map_or(&never(), |it| &it.receiver)) -> task => + recv(self.flycheck_receiver) -> task => Some(Event::Flycheck(task.unwrap())), } } @@ -292,7 +292,7 @@ fn handle_event(&mut self, event: Event) -> Result<()> { let state_changed = self.process_changes(); if prev_status == Status::Loading && self.status == Status::Ready { if let Some(flycheck) = &self.flycheck { - flycheck.handle.update(); + flycheck.update(); } } @@ -441,7 +441,7 @@ fn on_notification(&mut self, not: Notification) -> Result<()> { })? .on::(|this, params| { if let Some(flycheck) = &this.flycheck { - flycheck.handle.update(); + flycheck.update(); } if let Ok(abs_path) = from_proto::abs_path(¶ms.text_document.uri) { this.maybe_refresh(&[(abs_path, ChangeKind::Modify)]); diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index ab1b18ea97a..3f4dbdd8c3a 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -1,20 +1,19 @@ //! Project loading & configuration updates use std::{mem, sync::Arc}; -use crossbeam_channel::unbounded; use flycheck::FlycheckHandle; use ra_db::{CrateGraph, SourceRoot, VfsPath}; use ra_ide::AnalysisChange; +use ra_prof::profile; use ra_project_model::{PackageRoot, ProcMacroClient, ProjectWorkspace}; use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind}; use crate::{ config::{Config, FilesWatcher, LinkedProject}, - global_state::{GlobalState, Handle, Status}, + global_state::{GlobalState, Status}, lsp_ext, main_loop::Task, }; -use ra_prof::profile; impl GlobalState { pub(crate) fn update_configuration(&mut self, config: Config) { @@ -231,21 +230,20 @@ fn reload_flycheck(&mut self) { } }; - // FIXME: Figure out the multi-workspace situation - self.flycheck = self.workspaces.iter().find_map(move |w| match w { - ProjectWorkspace::Cargo { cargo, .. } => { - let (sender, receiver) = unbounded(); - let sender = Box::new(move |msg| sender.send(msg).unwrap()); + let sender = self.flycheck_sender.clone(); + let sender = Box::new(move |msg| sender.send(msg).unwrap()); + self.flycheck = self + .workspaces + .iter() + // FIXME: Figure out the multi-workspace situation + .find_map(|w| match w { + ProjectWorkspace::Cargo { cargo, sysroot: _ } => Some(cargo), + ProjectWorkspace::Json { .. } => None, + }) + .map(move |cargo| { let cargo_project_root = cargo.workspace_root().to_path_buf(); - let handle = - FlycheckHandle::spawn(sender, config.clone(), cargo_project_root.into()); - Some(Handle { handle, receiver }) - } - ProjectWorkspace::Json { .. } => { - log::warn!("Cargo check watching only supported for cargo workspaces, disabling"); - None - } - }) + FlycheckHandle::spawn(sender, config.clone(), cargo_project_root.into()) + }) } }