From 8136e739f536d28308831f86cc779c3d618a6c65 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Mon, 18 Dec 2023 15:38:21 +0100 Subject: [PATCH] fix: Notify user that linkedProjects is set when failing to discover projects --- crates/rust-analyzer/src/config.rs | 29 ++++++++++++-------- crates/rust-analyzer/src/handlers/request.rs | 2 +- crates/rust-analyzer/src/reload.rs | 23 +++++++++++++--- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 258f7410639..f88c009e5ba 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -7,7 +7,11 @@ //! configure the server itself, feature flags are passed into analysis, and //! tweak things like automatic insertion of `()` in completions. -use std::{fmt, iter, ops::Not, path::PathBuf}; +use std::{ + fmt, iter, + ops::Not, + path::{Path, PathBuf}, +}; use cfg::{CfgAtom, CfgDiff}; use flycheck::FlycheckConfig; @@ -917,7 +921,19 @@ impl Config { pub fn has_linked_projects(&self) -> bool { !self.data.linkedProjects.is_empty() } - pub fn linked_projects(&self) -> Vec { + pub fn linked_manifests(&self) -> impl Iterator + '_ { + self.data.linkedProjects.iter().filter_map(|it| match it { + ManifestOrProjectJson::Manifest(p) => Some(&**p), + ManifestOrProjectJson::ProjectJson(_) => None, + }) + } + pub fn has_linked_project_jsons(&self) -> bool { + self.data + .linkedProjects + .iter() + .any(|it| matches!(it, ManifestOrProjectJson::ProjectJson(_))) + } + pub fn linked_or_discovered_projects(&self) -> Vec { match self.data.linkedProjects.as_slice() { [] => { let exclude_dirs: Vec<_> = @@ -952,15 +968,6 @@ impl Config { } } - pub fn add_linked_projects(&mut self, linked_projects: Vec) { - let mut linked_projects = linked_projects - .into_iter() - .map(ManifestOrProjectJson::ProjectJson) - .collect::>(); - - self.data.linkedProjects.append(&mut linked_projects); - } - pub fn did_save_text_document_dynamic_registration(&self) -> bool { let caps = try_or_def!(self.caps.text_document.as_ref()?.synchronization.clone()?); caps.did_save == Some(true) && caps.dynamic_registration == Some(true) diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index 6b7bc944d52..f1317ce2b40 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -801,7 +801,7 @@ pub(crate) fn handle_runnables( } } None => { - if !snap.config.linked_projects().is_empty() { + if !snap.config.linked_or_discovered_projects().is_empty() { res.push(lsp_ext::Runnable { label: "cargo check --workspace".to_string(), location: None, diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index cc7cb276ad0..91dc6c2e4b4 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -80,7 +80,8 @@ impl GlobalState { &self.config.lru_query_capacities().cloned().unwrap_or_default(), ); } - if self.config.linked_projects() != old_config.linked_projects() { + if self.config.linked_or_discovered_projects() != old_config.linked_or_discovered_projects() + { self.fetch_workspaces_queue.request_op("linked projects changed".to_string(), false) } else if self.config.flycheck() != old_config.flycheck() { self.reload_flycheck(); @@ -128,7 +129,7 @@ impl GlobalState { status.health = lsp_ext::Health::Warning; message.push_str("Auto-reloading is disabled and the workspace has changed, a manual workspace reload is required.\n\n"); } - if self.config.linked_projects().is_empty() + if self.config.linked_or_discovered_projects().is_empty() && self.config.detached_files().is_empty() && self.config.notifications().cargo_toml_not_found { @@ -174,7 +175,21 @@ impl GlobalState { if let Err(_) = self.fetch_workspace_error() { status.health = lsp_ext::Health::Error; - message.push_str("Failed to load workspaces.\n\n"); + message.push_str("Failed to load workspaces."); + + if self.config.has_linked_projects() { + message.push_str( + "`rust-analyzer.linkedProjects` have been specified, which may be incorrect. Specified project paths:\n", + ); + message.push_str(&format!( + " {}", + self.config.linked_manifests().map(|it| it.display()).format("\n ") + )); + if self.config.has_linked_project_jsons() { + message.push_str("\nAdditionally, one or more project jsons are specified") + } + } + message.push_str("\n\n"); } if !message.is_empty() { @@ -187,7 +202,7 @@ impl GlobalState { tracing::info!(%cause, "will fetch workspaces"); self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, { - let linked_projects = self.config.linked_projects(); + let linked_projects = self.config.linked_or_discovered_projects(); let detached_files = self.config.detached_files().to_vec(); let cargo_config = self.config.cargo();