about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-08-19 17:30:25 +0000
committerbors <bors@rust-lang.org>2024-08-19 17:30:25 +0000
commitdf6ce9607ca80cd2068393b0cb2178ae1c39c677 (patch)
treee8e62d472f470bfee8c5216170075d79be04e4ef
parentf9c0c8a7794b9a9679a82e95a8af67ba62948582 (diff)
parentf25cb8073c2a10648fff0a267e3c41817a81b1a0 (diff)
downloadrust-df6ce9607ca80cd2068393b0cb2178ae1c39c677.tar.gz
rust-df6ce9607ca80cd2068393b0cb2178ae1c39c677.zip
Auto merge of #17886 - Wilfred:prime_caches_quiescent, r=Veykril
internal: ServerStatusParams should consider 'prime caches' in quiescent status

Priming caches is a performance win, but it takes a lock on the salsa database and prevents rust-analyzer from responding to e.g. go-to-def requests.

This causes confusion for users, who see the spinner next to rust-analyzer in the VS Code footer stop, so they start attempting to navigate their code.

Instead, set the `quiescent` status in LSP to false during cache priming, so the VS Code spinner persists until we can respond to any LSP request.
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
index 510dc22603c..884a8e83472 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -61,6 +61,10 @@ pub(crate) enum ProcMacroProgress {
 }
 
 impl GlobalState {
+    /// Is the server quiescent?
+    ///
+    /// This indicates that we've fully loaded the projects and
+    /// are ready to do semantic work.
     pub(crate) fn is_quiescent(&self) -> bool {
         self.vfs_done
             && self.last_reported_status.is_some()
@@ -71,6 +75,15 @@ impl GlobalState {
             && self.vfs_progress_config_version >= self.vfs_config_version
     }
 
+    /// Is the server ready to respond to analysis dependent LSP requests?
+    ///
+    /// Unlike `is_quiescent`, this returns false when we're indexing
+    /// the project, because we're holding the salsa lock and cannot
+    /// respond to LSP requests that depend on salsa data.
+    fn is_fully_ready(&self) -> bool {
+        self.is_quiescent() && !self.prime_caches_queue.op_in_progress()
+    }
+
     pub(crate) fn update_configuration(&mut self, config: Config) {
         let _p = tracing::info_span!("GlobalState::update_configuration").entered();
         let old_config = mem::replace(&mut self.config, Arc::new(config));
@@ -102,13 +115,15 @@ impl GlobalState {
     }
 
     pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams {
-        let quiescent = self.is_quiescent();
-        let mut status =
-            lsp_ext::ServerStatusParams { health: lsp_ext::Health::Ok, quiescent, message: None };
+        let mut status = lsp_ext::ServerStatusParams {
+            health: lsp_ext::Health::Ok,
+            quiescent: self.is_fully_ready(),
+            message: None,
+        };
         let mut message = String::new();
 
         if !self.config.cargo_autoreload(None)
-            && quiescent
+            && self.is_quiescent()
             && self.fetch_workspaces_queue.op_requested()
             && self.config.discover_workspace_config().is_none()
         {