diff options
Diffstat (limited to 'src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs')
-rw-r--r-- | src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs | 82 |
1 files changed, 51 insertions, 31 deletions
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs index d1e38b33c..67a54cde6 100644 --- a/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs +++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs @@ -111,12 +111,7 @@ impl fmt::Debug for Event { impl GlobalState { fn run(mut self, inbox: Receiver<lsp_server::Message>) -> 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 { @@ -323,17 +318,6 @@ impl GlobalState { if let Some(diagnostic_changes) = self.diagnostics.take_changes() { for file_id in diagnostic_changes { - let db = self.analysis_host.raw_database(); - let source_root = db.file_source_root(file_id); - if db.source_root(source_root).is_library { - // Only publish diagnostics for files in the workspace, not from crates.io deps - // or the sysroot. - // While theoretically these should never have errors, we have quite a few false - // positives particularly in the stdlib, and those diagnostics would stay around - // forever if we emitted them here. - continue; - } - let uri = file_id_to_url(&self.vfs.read().0, file_id); let mut diagnostics = self.diagnostics.diagnostics_for(file_id).cloned().collect::<Vec<_>>(); @@ -405,25 +389,38 @@ impl GlobalState { }); } + self.update_status_or_notify(); + + let loop_duration = loop_start.elapsed(); + if loop_duration > Duration::from_millis(100) && was_quiescent { + tracing::warn!("overly long loop turn: {:?}", loop_duration); + self.poke_rust_analyzer_developer(format!("overly long loop turn: {loop_duration:?}")); + } + 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 let (lsp_ext::Health::Error, Some(message)) = (status.health, &status.message) { - self.show_message(lsp_types::MessageType::ERROR, message.clone()); - } - if self.config.server_status_notification() { self.send_notification::<lsp_ext::ServerStatusNotification>(status); + } else if let (health, Some(message)) = (status.health, &status.message) { + let open_log_button = tracing::enabled!(tracing::Level::ERROR) + && (self.fetch_build_data_error().is_err() + || self.fetch_workspace_error().is_err()); + self.show_message( + match health { + lsp_ext::Health::Ok => lsp_types::MessageType::INFO, + lsp_ext::Health::Warning => lsp_types::MessageType::WARNING, + lsp_ext::Health::Error => lsp_types::MessageType::ERROR, + }, + message.clone(), + open_log_button, + ); } } - - let loop_duration = loop_start.elapsed(); - if loop_duration > Duration::from_millis(100) && was_quiescent { - tracing::warn!("overly long loop turn: {:?}", loop_duration); - self.poke_rust_analyzer_developer(format!("overly long loop turn: {loop_duration:?}")); - } - Ok(()) } fn handle_task(&mut self, prime_caches_progress: &mut Vec<PrimeCachesProgress>, task: Task) { @@ -456,6 +453,9 @@ impl GlobalState { 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()); @@ -477,6 +477,9 @@ impl GlobalState { 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()); @@ -509,6 +512,7 @@ impl GlobalState { self.vfs_progress_n_total = n_total; self.vfs_progress_n_done = n_done; + // if n_total != 0 { let state = if n_done == 0 { Progress::Begin } else if n_done < n_total { @@ -523,7 +527,8 @@ impl GlobalState { Some(format!("{n_done}/{n_total}")), Some(Progress::fraction(n_done, n_total)), None, - ) + ); + // } } } } @@ -565,7 +570,10 @@ impl GlobalState { 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) => { @@ -634,6 +642,7 @@ impl GlobalState { .on::<lsp_ext::AnalyzerStatus>(handlers::handle_analyzer_status) .on::<lsp_ext::SyntaxTree>(handlers::handle_syntax_tree) .on::<lsp_ext::ViewHir>(handlers::handle_view_hir) + .on::<lsp_ext::ViewMir>(handlers::handle_view_mir) .on::<lsp_ext::ViewFileText>(handlers::handle_view_file_text) .on::<lsp_ext::ViewCrateGraph>(handlers::handle_view_crate_graph) .on::<lsp_ext::ViewItemTree>(handlers::handle_view_item_tree) @@ -654,7 +663,7 @@ impl GlobalState { .on::<lsp_types::request::GotoDeclaration>(handlers::handle_goto_declaration) .on::<lsp_types::request::GotoImplementation>(handlers::handle_goto_implementation) .on::<lsp_types::request::GotoTypeDefinition>(handlers::handle_goto_type_definition) - .on::<lsp_types::request::InlayHintRequest>(handlers::handle_inlay_hints) + .on_no_retry::<lsp_types::request::InlayHintRequest>(handlers::handle_inlay_hints) .on::<lsp_types::request::InlayHintResolveRequest>(handlers::handle_inlay_hints_resolve) .on::<lsp_types::request::Completion>(handlers::handle_completion) .on::<lsp_types::request::ResolveCompletionItem>(handlers::handle_completion_resolve) @@ -920,6 +929,7 @@ impl GlobalState { this.show_message( lsp_types::MessageType::WARNING, error.to_string(), + false, ); } this.update_configuration(config); @@ -971,10 +981,20 @@ impl GlobalState { } fn update_diagnostics(&mut self) { + let db = self.analysis_host.raw_database(); let subscriptions = self .mem_docs .iter() .map(|path| self.vfs.read().0.file_id(path).unwrap()) + .filter(|&file_id| { + let source_root = db.file_source_root(file_id); + // Only publish diagnostics for files in the workspace, not from crates.io deps + // or the sysroot. + // While theoretically these should never have errors, we have quite a few false + // positives particularly in the stdlib, and those diagnostics would stay around + // forever if we emitted them here. + !db.source_root(source_root).is_library + }) .collect::<Vec<_>>(); tracing::trace!("updating notifications for {:?}", subscriptions); |