about summary refs log tree commit diff
path: root/src/tools/rust-analyzer
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-06-06 10:37:46 +0200
committerLukas Wirth <lukastw97@gmail.com>2024-06-06 10:40:41 +0200
commitd726854555b44046b0b3028fad2f3bb4c76477aa (patch)
treefe9c91cd9f4a1e8496c078a0558aee669012069d /src/tools/rust-analyzer
parent003106cf6bbc20efbbc4ebfe73cae25659004675 (diff)
downloadrust-d726854555b44046b0b3028fad2f3bb4c76477aa.tar.gz
rust-d726854555b44046b0b3028fad2f3bb4c76477aa.zip
Fix file loading of r-a toml files
Diffstat (limited to 'src/tools/rust-analyzer')
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs24
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs61
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs42
3 files changed, 37 insertions, 90 deletions
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index 2baac886250..1ae454ace35 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -902,10 +902,10 @@ impl Config {
 
 #[derive(Default, Debug)]
 pub struct ConfigChange {
-    user_config_change: Option<String>,
-    root_ratoml_change: Option<String>,
+    user_config_change: Option<Arc<str>>,
+    root_ratoml_change: Option<Arc<str>>,
     client_config_change: Option<serde_json::Value>,
-    ratoml_file_change: Option<FxHashMap<SourceRootId, (VfsPath, Option<String>)>>,
+    ratoml_file_change: Option<FxHashMap<SourceRootId, (VfsPath, Option<Arc<str>>)>>,
     source_map_change: Option<Arc<FxHashMap<SourceRootId, SourceRootId>>>,
 }
 
@@ -914,19 +914,19 @@ impl ConfigChange {
         &mut self,
         source_root: SourceRootId,
         vfs_path: VfsPath,
-        content: Option<String>,
-    ) -> Option<(VfsPath, Option<String>)> {
+        content: Option<Arc<str>>,
+    ) -> Option<(VfsPath, Option<Arc<str>>)> {
         self.ratoml_file_change
             .get_or_insert_with(Default::default)
             .insert(source_root, (vfs_path, content))
     }
 
-    pub fn change_user_config(&mut self, content: Option<String>) {
+    pub fn change_user_config(&mut self, content: Option<Arc<str>>) {
         assert!(self.user_config_change.is_none()); // Otherwise it is a double write.
         self.user_config_change = content;
     }
 
-    pub fn change_root_ratoml(&mut self, content: Option<String>) {
+    pub fn change_root_ratoml(&mut self, content: Option<Arc<str>>) {
         assert!(self.user_config_change.is_none()); // Otherwise it is a double write.
         self.root_ratoml_change = content;
     }
@@ -1206,8 +1206,7 @@ impl Config {
             client_config: (FullConfigInput::default(), ConfigErrors(vec![])),
             user_config: None,
             ratoml_files: FxHashMap::default(),
-            default_config: DEFAULT_CONFIG_DATA
-                .get_or_init(|| Box::leak(Box::new(DefaultConfigData::default()))),
+            default_config: DEFAULT_CONFIG_DATA.get_or_init(|| Box::leak(Box::default())),
             source_root_parent_map: Arc::new(FxHashMap::default()),
             user_config_path,
             root_ratoml: None,
@@ -3548,7 +3547,8 @@ mod tests {
                 [cargo.sysroot]
                 non-table = "expected"
             }
-            .to_string(),
+            .to_string()
+            .into(),
         ));
 
         let (config, e, _) = config.apply_change(change);
@@ -3582,9 +3582,9 @@ mod tests {
                 be = "be"
                 valid = "valid"
             }
-            .to_string(),
+            .to_string()
+            .into(),
         ));
-
         let (_, e, _) = config.apply_change(change);
         expect_test::expect![[r#"
             ConfigErrors(
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
index 354f955efce..a3e61447b1d 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs
@@ -25,7 +25,7 @@ use project_model::{
 use rustc_hash::{FxHashMap, FxHashSet};
 use tracing::{span, Level};
 use triomphe::Arc;
-use vfs::{AnchoredPathBuf, Vfs, VfsPath};
+use vfs::{AnchoredPathBuf, ChangeKind, Vfs};
 
 use crate::{
     config::{Config, ConfigChange, ConfigErrors},
@@ -262,19 +262,9 @@ impl GlobalState {
         // that can be used by the config module because config talks
         // in `SourceRootId`s instead of `FileId`s and `FileId` -> `SourceRootId`
         // mapping is not ready until `AnalysisHost::apply_changes` has been called.
-        let mut modified_ratoml_files: FxHashMap<FileId, vfs::VfsPath> = FxHashMap::default();
-        let mut ratoml_text_map: FxHashMap<FileId, (vfs::VfsPath, Option<String>)> =
+        let mut modified_ratoml_files: FxHashMap<FileId, (ChangeKind, vfs::VfsPath)> =
             FxHashMap::default();
 
-        let mut user_config_file: Option<Option<String>> = None;
-        let mut root_path_ratoml: Option<Option<String>> = None;
-
-        let root_vfs_path = {
-            let mut root_vfs_path = self.config.root_path().to_path_buf();
-            root_vfs_path.push("rust-analyzer.toml");
-            VfsPath::new_real_path(root_vfs_path.to_string())
-        };
-
         let (change, modified_rust_files, workspace_structure_change) = {
             let mut change = ChangeWithProcMacros::new();
             let mut guard = self.vfs.write();
@@ -296,7 +286,7 @@ impl GlobalState {
                 let vfs_path = vfs.file_path(file.file_id);
                 if let Some(("rust-analyzer", Some("toml"))) = vfs_path.name_and_extension() {
                     // Remember ids to use them after `apply_changes`
-                    modified_ratoml_files.insert(file.file_id, vfs_path.clone());
+                    modified_ratoml_files.insert(file.file_id, (file.kind(), vfs_path.clone()));
                 }
 
                 if let Some(path) = vfs_path.as_path() {
@@ -344,17 +334,7 @@ impl GlobalState {
                         Some(text)
                     }
                 };
-
-                change.change_file(file_id, text.clone());
-                if let Some(vfs_path) = modified_ratoml_files.get(&file_id) {
-                    if vfs_path == self.config.user_config_path() {
-                        user_config_file = Some(text);
-                    } else if vfs_path == &root_vfs_path {
-                        root_path_ratoml = Some(text);
-                    } else {
-                        ratoml_text_map.insert(file_id, (vfs_path.clone(), text));
-                    }
-                }
+                change.change_file(file_id, text);
             });
             if has_structure_changes {
                 let roots = self.source_root_config.partition(vfs);
@@ -365,22 +345,35 @@ impl GlobalState {
 
         let _p = span!(Level::INFO, "GlobalState::process_changes/apply_change").entered();
         self.analysis_host.apply_change(change);
-        if !(ratoml_text_map.is_empty() && user_config_file.is_none() && root_path_ratoml.is_none())
-        {
+        if !modified_ratoml_files.is_empty() {
             let config_change = {
+                let user_config_path = self.config.user_config_path();
+                let root_ratoml_path = self.config.root_ratoml_path();
                 let mut change = ConfigChange::default();
                 let db = self.analysis_host.raw_database();
 
-                for (file_id, (vfs_path, text)) in ratoml_text_map {
+                for (file_id, (_change_kind, vfs_path)) in modified_ratoml_files {
+                    if vfs_path == *user_config_path {
+                        change.change_user_config(Some(db.file_text(file_id)));
+                        continue;
+                    }
+
+                    if vfs_path == *root_ratoml_path {
+                        change.change_root_ratoml(Some(db.file_text(file_id)));
+                        continue;
+                    }
+
                     // If change has been made to a ratoml file that
                     // belongs to a non-local source root, we will ignore it.
                     // As it doesn't make sense a users to use external config files.
                     let sr_id = db.file_source_root(file_id);
                     let sr = db.source_root(sr_id);
                     if !sr.is_library {
-                        if let Some((old_path, old_text)) =
-                            change.change_ratoml(sr_id, vfs_path.clone(), text)
-                        {
+                        if let Some((old_path, old_text)) = change.change_ratoml(
+                            sr_id,
+                            vfs_path.clone(),
+                            Some(db.file_text(file_id)),
+                        ) {
                             // SourceRoot has more than 1 RATOML files. In this case lexicographically smaller wins.
                             if old_path < vfs_path {
                                 span!(Level::ERROR, "Two `rust-analyzer.toml` files were found inside the same crate. {vfs_path} has no effect.");
@@ -394,14 +387,6 @@ impl GlobalState {
                     }
                 }
 
-                if let Some(Some(txt)) = user_config_file {
-                    change.change_user_config(Some(txt));
-                }
-
-                if let Some(Some(txt)) = root_path_ratoml {
-                    change.change_root_ratoml(Some(txt));
-                }
-
                 change
             };
 
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 36f9504e7d5..899c3cfeebb 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs
@@ -13,7 +13,7 @@
 //! project is currently loading and we don't have a full project model, we
 //! still want to respond to various  requests.
 // FIXME: This is a mess that needs some untangling work
-use std::{iter, mem, ops::Not as _};
+use std::{iter, mem};
 
 use flycheck::{FlycheckConfig, FlycheckHandle};
 use hir::{db::DefDatabase, ChangeWithProcMacros, ProcMacros};
@@ -28,12 +28,11 @@ use lsp_types::FileSystemWatcher;
 use proc_macro_api::ProcMacroServer;
 use project_model::{ManifestPath, ProjectWorkspace, ProjectWorkspaceKind, WorkspaceBuildScripts};
 use stdx::{format_to, thread::ThreadIntent};
-use tracing::error;
 use triomphe::Arc;
 use vfs::{AbsPath, AbsPathBuf, ChangeKind};
 
 use crate::{
-    config::{Config, ConfigChange, FilesWatcher, LinkedProject},
+    config::{Config, FilesWatcher, LinkedProject},
     global_state::GlobalState,
     lsp_ext,
     main_loop::Task,
@@ -573,43 +572,6 @@ impl GlobalState {
         self.source_root_config = project_folders.source_root_config;
         self.local_roots_parent_map = Arc::new(self.source_root_config.source_root_parent_map());
 
-        let user_config_path = self.config.user_config_path();
-        let root_ratoml_path = self.config.root_ratoml_path();
-
-        {
-            let vfs = &mut self.vfs.write().0;
-            let loader = &mut self.loader;
-
-            if vfs.file_id(user_config_path).is_none() {
-                if let Some(user_cfg_abs) = user_config_path.as_path() {
-                    let contents = loader.handle.load_sync(user_cfg_abs);
-                    vfs.set_file_contents(user_config_path.clone(), contents);
-                } else {
-                    error!("Non-abs virtual path for user config.");
-                }
-            }
-
-            if vfs.file_id(root_ratoml_path).is_none() {
-                // FIXME @alibektas : Sometimes root_path_ratoml collide with a regular ratoml.
-                // Although this shouldn't be a problem because everything is mapped to a `FileId`.
-                // We may want to further think about this.
-                if let Some(root_ratoml_abs) = root_ratoml_path.as_path() {
-                    let contents = loader.handle.load_sync(root_ratoml_abs);
-                    vfs.set_file_contents(root_ratoml_path.clone(), contents);
-                } else {
-                    error!("Non-abs virtual path for user config.");
-                }
-            }
-        }
-
-        let mut config_change = ConfigChange::default();
-        config_change.change_source_root_parent_map(self.local_roots_parent_map.clone());
-
-        let (config, e, _) = self.config.apply_change(config_change);
-        self.config_errors = e.is_empty().not().then_some(e);
-
-        self.config = Arc::new(config);
-
         self.recreate_crate_graph(cause);
 
         tracing::info!("did switch workspaces");