diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 43a0bf8ec05..6b15f6ecd62 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -111,12 +111,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { impl GlobalState { fn run(mut self, inbox: Receiver) -> Result<()> { - if self.config.linked_projects().is_empty() - && self.config.detached_files().is_empty() - && self.config.notifications().cargo_toml_not_found - { - self.show_and_log_error("rust-analyzer failed to discover workspace".to_string(), None); - }; + self.update_status_or_notify(); if self.config.did_save_text_document_dynamic_registration() { let save_registration_options = lsp_types::TextDocumentSaveRegistrationOptions { @@ -394,18 +389,7 @@ fn handle_event(&mut self, event: Event) -> Result<()> { }); } - let status = self.current_status(); - if self.last_reported_status.as_ref() != Some(&status) { - self.last_reported_status = Some(status.clone()); - - if self.config.server_status_notification() { - self.send_notification::(status); - } else { - if let (lsp_ext::Health::Error, Some(message)) = (status.health, &status.message) { - self.show_message(lsp_types::MessageType::ERROR, message.clone()); - } - } - } + self.update_status_or_notify(); let loop_duration = loop_start.elapsed(); if loop_duration > Duration::from_millis(100) && was_quiescent { @@ -415,6 +399,20 @@ fn handle_event(&mut self, event: Event) -> Result<()> { Ok(()) } + fn update_status_or_notify(&mut self) { + let status = self.current_status(); + if self.last_reported_status.as_ref() != Some(&status) { + self.last_reported_status = Some(status.clone()); + + if self.config.server_status_notification() { + self.send_notification::(status); + } else if let (lsp_ext::Health::Error, Some(message)) = (status.health, &status.message) + { + self.show_and_log_error(message.clone(), None); + } + } + } + fn handle_task(&mut self, prime_caches_progress: &mut Vec, task: Task) { match task { Task::Response(response) => self.respond(response), @@ -445,6 +443,9 @@ fn handle_task(&mut self, prime_caches_progress: &mut Vec, ProjectWorkspaceProgress::Report(msg) => (Progress::Report, Some(msg)), ProjectWorkspaceProgress::End(workspaces) => { self.fetch_workspaces_queue.op_completed(Some(workspaces)); + if let Err(e) = self.fetch_workspace_error() { + tracing::error!("FetchWorkspaceError:\n{e}") + } let old = Arc::clone(&self.workspaces); self.switch_workspaces("fetched workspace".to_string()); @@ -466,6 +467,9 @@ fn handle_task(&mut self, prime_caches_progress: &mut Vec, BuildDataProgress::Report(msg) => (Some(Progress::Report), Some(msg)), BuildDataProgress::End(build_data_result) => { self.fetch_build_data_queue.op_completed(build_data_result); + if let Err(e) = self.fetch_build_data_error() { + tracing::error!("FetchBuildDataError:\n{e}") + } self.switch_workspaces("fetched build data".to_string()); @@ -491,6 +495,7 @@ fn handle_vfs_msg(&mut self, message: vfs::loader::Message) { } } } + vfs::loader::Message::Progress { n_total: 0, .. } => {} vfs::loader::Message::Progress { n_total, n_done, config_version } => { always!(config_version <= self.vfs_config_version); @@ -554,7 +559,10 @@ fn handle_flycheck_msg(&mut self, message: flycheck::Message) { flycheck::Progress::DidCheckCrate(target) => (Progress::Report, Some(target)), flycheck::Progress::DidCancel => (Progress::End, None), flycheck::Progress::DidFailToRestart(err) => { - self.show_and_log_error("cargo check failed".to_string(), Some(err)); + self.show_and_log_error( + "cargo check failed to start".to_string(), + Some(err), + ); return; } flycheck::Progress::DidFinish(result) => { diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 2dfbb2ffb97..4695e874161 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -108,9 +108,9 @@ pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams { status.message = Some("Workspace reload required".to_string()) } - if let Err(error) = self.fetch_workspace_error() { + if let Err(_) = self.fetch_workspace_error() { status.health = lsp_ext::Health::Error; - status.message = Some(error) + status.message = Some("Failed to load workspaces".to_string()) } if self.config.linked_projects().is_empty() @@ -118,8 +118,9 @@ pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams { && self.config.notifications().cargo_toml_not_found { status.health = lsp_ext::Health::Warning; - status.message = Some("Workspace reload required".to_string()) + status.message = Some("Failed to discover workspace".to_string()) } + status } @@ -201,10 +202,7 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) { let _p = profile::span("GlobalState::switch_workspaces"); tracing::info!(%cause, "will switch workspaces"); - if let Err(error_message) = self.fetch_workspace_error() { - if !self.config.server_status_notification() { - self.show_and_log_error(error_message, None); - } + if let Err(_) = self.fetch_workspace_error() { if !self.workspaces.is_empty() { // It only makes sense to switch to a partially broken workspace // if we don't have any workspace at all yet. @@ -212,10 +210,6 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) { } } - if let Err(error) = self.fetch_build_data_error() { - self.show_and_log_error("failed to run build scripts".to_string(), Some(error)); - } - let Some(workspaces) = self.fetch_workspaces_queue.last_op_result() else { return; }; let workspaces = workspaces.iter().filter_map(|res| res.as_ref().ok().cloned()).collect::>(); @@ -394,7 +388,7 @@ pub(crate) fn switch_workspaces(&mut self, cause: Cause) { tracing::info!("did switch workspaces"); } - fn fetch_workspace_error(&self) -> Result<(), String> { + pub(super) fn fetch_workspace_error(&self) -> Result<(), String> { let mut buf = String::new(); let Some(last_op_result) = self.fetch_workspaces_queue.last_op_result() else { return Ok(()) }; @@ -415,7 +409,7 @@ fn fetch_workspace_error(&self) -> Result<(), String> { Err(buf) } - fn fetch_build_data_error(&self) -> Result<(), String> { + pub(super) fn fetch_build_data_error(&self) -> Result<(), String> { let mut buf = String::new(); for ws in &self.fetch_build_data_queue.last_op_result().1 {