about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-05-26 15:21:00 +0200
committerLukas Wirth <lukastw97@gmail.com>2023-05-26 15:26:03 +0200
commita2b59b110fc417ec90b7f24882a416dd8a8fe618 (patch)
treeb3fa7b73bb01d1a547874ffb3c0e0440a71b3bc6
parent79fe11ced3283b88c4a24da972e1649eb16a9f1b (diff)
downloadrust-a2b59b110fc417ec90b7f24882a416dd8a8fe618.tar.gz
rust-a2b59b110fc417ec90b7f24882a416dd8a8fe618.zip
Report config errors via status
-rw-r--r--crates/rust-analyzer/src/config.rs10
-rw-r--r--crates/rust-analyzer/src/global_state.rs4
-rw-r--r--crates/rust-analyzer/src/handlers/notification.rs8
-rw-r--r--crates/rust-analyzer/src/main_loop.rs6
-rw-r--r--crates/rust-analyzer/src/reload.rs5
5 files changed, 19 insertions, 14 deletions
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index e73a2d5c770..05567f8f579 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -720,11 +720,11 @@ pub struct ClientCommandsConfig {
 }
 
 #[derive(Debug)]
-pub struct ConfigUpdateError {
+pub struct ConfigError {
     errors: Vec<(String, serde_json::Error)>,
 }
 
-impl fmt::Display for ConfigUpdateError {
+impl fmt::Display for ConfigError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let errors = self.errors.iter().format_with("\n", |(key, e), f| {
             f(key)?;
@@ -733,7 +733,7 @@ impl fmt::Display for ConfigUpdateError {
         });
         write!(
             f,
-            "rust-analyzer found {} invalid config value{}:\n{}",
+            "invalid config value{}:\n{}",
             self.errors.len(),
             if self.errors.len() == 1 { "" } else { "s" },
             errors
@@ -777,7 +777,7 @@ impl Config {
         self.workspace_roots.extend(paths);
     }
 
-    pub fn update(&mut self, mut json: serde_json::Value) -> Result<(), ConfigUpdateError> {
+    pub fn update(&mut self, mut json: serde_json::Value) -> Result<(), ConfigError> {
         tracing::info!("updating config from JSON: {:#}", json);
         if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) {
             return Ok(());
@@ -824,7 +824,7 @@ impl Config {
         if errors.is_empty() {
             Ok(())
         } else {
-            Err(ConfigUpdateError { errors })
+            Err(ConfigError { errors })
         }
     }
 
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index defb3e1461f..d68e51240b7 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -19,7 +19,7 @@ use triomphe::Arc;
 use vfs::AnchoredPathBuf;
 
 use crate::{
-    config::Config,
+    config::{Config, ConfigError},
     diagnostics::{CheckFixes, DiagnosticCollection},
     from_proto,
     line_index::{LineEndings, LineIndex},
@@ -56,6 +56,7 @@ pub(crate) struct GlobalState {
     pub(crate) task_pool: Handle<TaskPool<Task>, Receiver<Task>>,
 
     pub(crate) config: Arc<Config>,
+    pub(crate) config_errors: Option<ConfigError>,
     pub(crate) analysis_host: AnalysisHost,
     pub(crate) diagnostics: DiagnosticCollection,
     pub(crate) mem_docs: MemDocs,
@@ -168,6 +169,7 @@ impl GlobalState {
             shutdown_requested: false,
             last_reported_status: None,
             source_root_config: SourceRootConfig::default(),
+            config_errors: Default::default(),
 
             proc_macro_changed: false,
             // FIXME: use `Arc::from_iter` when it becomes available
diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs
index ca9ea77f305..481004988d3 100644
--- a/crates/rust-analyzer/src/handlers/notification.rs
+++ b/crates/rust-analyzer/src/handlers/notification.rs
@@ -169,13 +169,7 @@ pub(crate) fn handle_did_change_configuration(
                         // Note that json can be null according to the spec if the client can't
                         // provide a configuration. This is handled in Config::update below.
                         let mut config = Config::clone(&*this.config);
-                        if let Err(error) = config.update(json.take()) {
-                            this.show_message(
-                                lsp_types::MessageType::WARNING,
-                                error.to_string(),
-                                false,
-                            );
-                        }
+                        config.update(json.take());
                         this.update_configuration(config);
                     }
                 }
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index b3522394cd6..49595a45ea9 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -419,7 +419,11 @@ impl GlobalState {
 
             if self.config.server_status_notification() {
                 self.send_notification::<lsp_ext::ServerStatusNotification>(status);
-            } else if let (health, Some(message)) = (status.health, &status.message) {
+            } else if let (
+                health @ (lsp_ext::Health::Warning | lsp_ext::Health::Error),
+                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());
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index 4c76392a0e7..5300349e7d2 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -27,6 +27,7 @@ use ide_db::{
 use itertools::Itertools;
 use proc_macro_api::{MacroDylib, ProcMacroServer};
 use project_model::{PackageRoot, ProjectWorkspace, WorkspaceBuildScripts};
+use stdx::format_to;
 use syntax::SmolStr;
 use triomphe::Arc;
 use vfs::{file_set::FileSetConfig, AbsPath, AbsPathBuf, ChangeKind};
@@ -134,6 +135,10 @@ impl GlobalState {
             message.push_str("Failed to discover workspace.\n");
             message.push_str("Consider adding the `Cargo.toml` of the workspace to the [`linkedProjects`](https://rust-analyzer.github.io/manual.html#rust-analyzer.linkedProjects) setting.\n\n");
         }
+        if let Some(err) = &self.config_errors {
+            status.health = lsp_ext::Health::Warning;
+            format_to!(message, "{err}\n");
+        }
 
         for ws in self.workspaces.iter() {
             let (ProjectWorkspace::Cargo { sysroot, .. }