Auto merge of #16153 - Veykril:err-msg, r=Veykril

fix: Notify user that linkedProjects is set when failing to discover projects

Fixes https://github.com/rust-lang/rust-analyzer/issues/15171
This commit is contained in:
bors 2024-01-02 14:42:03 +00:00
commit 1a0b772a43
3 changed files with 38 additions and 16 deletions

View File

@ -7,7 +7,11 @@
//! configure the server itself, feature flags are passed into analysis, and //! configure the server itself, feature flags are passed into analysis, and
//! tweak things like automatic insertion of `()` in completions. //! 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 cfg::{CfgAtom, CfgDiff};
use flycheck::FlycheckConfig; use flycheck::FlycheckConfig;
@ -920,7 +924,19 @@ impl Config {
pub fn has_linked_projects(&self) -> bool { pub fn has_linked_projects(&self) -> bool {
!self.data.linkedProjects.is_empty() !self.data.linkedProjects.is_empty()
} }
pub fn linked_projects(&self) -> Vec<LinkedProject> { pub fn linked_manifests(&self) -> impl Iterator<Item = &Path> + '_ {
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<LinkedProject> {
match self.data.linkedProjects.as_slice() { match self.data.linkedProjects.as_slice() {
[] => { [] => {
let exclude_dirs: Vec<_> = let exclude_dirs: Vec<_> =
@ -955,15 +971,6 @@ impl Config {
} }
} }
pub fn add_linked_projects(&mut self, linked_projects: Vec<ProjectJsonData>) {
let mut linked_projects = linked_projects
.into_iter()
.map(ManifestOrProjectJson::ProjectJson)
.collect::<Vec<ManifestOrProjectJson>>();
self.data.linkedProjects.append(&mut linked_projects);
}
pub fn did_save_text_document_dynamic_registration(&self) -> bool { pub fn did_save_text_document_dynamic_registration(&self) -> bool {
let caps = try_or_def!(self.caps.text_document.as_ref()?.synchronization.clone()?); let caps = try_or_def!(self.caps.text_document.as_ref()?.synchronization.clone()?);
caps.did_save == Some(true) && caps.dynamic_registration == Some(true) caps.did_save == Some(true) && caps.dynamic_registration == Some(true)

View File

@ -801,7 +801,7 @@ pub(crate) fn handle_runnables(
} }
} }
None => { None => {
if !snap.config.linked_projects().is_empty() { if !snap.config.linked_or_discovered_projects().is_empty() {
res.push(lsp_ext::Runnable { res.push(lsp_ext::Runnable {
label: "cargo check --workspace".to_string(), label: "cargo check --workspace".to_string(),
location: None, location: None,

View File

@ -80,7 +80,8 @@ impl GlobalState {
&self.config.lru_query_capacities().cloned().unwrap_or_default(), &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) self.fetch_workspaces_queue.request_op("linked projects changed".to_string(), false)
} else if self.config.flycheck() != old_config.flycheck() { } else if self.config.flycheck() != old_config.flycheck() {
self.reload_flycheck(); self.reload_flycheck();
@ -128,7 +129,7 @@ impl GlobalState {
status.health = lsp_ext::Health::Warning; 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"); 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.detached_files().is_empty()
&& self.config.notifications().cargo_toml_not_found && self.config.notifications().cargo_toml_not_found
{ {
@ -174,7 +175,21 @@ impl GlobalState {
if let Err(_) = self.fetch_workspace_error() { if let Err(_) = self.fetch_workspace_error() {
status.health = lsp_ext::Health::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() { if !message.is_empty() {
@ -187,7 +202,7 @@ impl GlobalState {
tracing::info!(%cause, "will fetch workspaces"); tracing::info!(%cause, "will fetch workspaces");
self.task_pool.handle.spawn_with_sender(ThreadIntent::Worker, { 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 detached_files = self.config.detached_files().to_vec();
let cargo_config = self.config.cargo(); let cargo_config = self.config.cargo();