about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-01-09 10:30:16 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-01-09 10:30:16 +0100
commite1c67485bf02bdaa1234df174a48aba402a2d707 (patch)
treec4ab857197b0eb742864fd035ab971ab68b9d28b
parentf5f7ddae23f9a959e684fefd3f1b78c93f89968e (diff)
downloadrust-e1c67485bf02bdaa1234df174a48aba402a2d707.tar.gz
rust-e1c67485bf02bdaa1234df174a48aba402a2d707.zip
fix: Differentiate between vfs config load and file changed events
-rw-r--r--crates/load-cargo/src/lib.rs2
-rw-r--r--crates/project-model/src/workspace.rs2
-rw-r--r--crates/rust-analyzer/src/global_state.rs16
-rw-r--r--crates/rust-analyzer/src/handlers/notification.rs6
-rw-r--r--crates/rust-analyzer/src/main_loop.rs7
-rw-r--r--crates/rust-analyzer/tests/slow-tests/main.rs2
-rw-r--r--crates/vfs-notify/src/lib.rs2
-rw-r--r--crates/vfs/src/loader.rs5
8 files changed, 26 insertions, 16 deletions
diff --git a/crates/load-cargo/src/lib.rs b/crates/load-cargo/src/lib.rs
index ee0b9e6d504..e6ddfd580c3 100644
--- a/crates/load-cargo/src/lib.rs
+++ b/crates/load-cargo/src/lib.rs
@@ -322,7 +322,7 @@ fn load_crate_graph(
                     break;
                 }
             }
-            vfs::loader::Message::Loaded { files } => {
+            vfs::loader::Message::Loaded { files } | vfs::loader::Message::Changed { files } => {
                 for (path, contents) in files {
                     vfs.set_file_contents(path.into(), contents);
                 }
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index 00cc7c30ee3..c04eddc56fb 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -1398,7 +1398,7 @@ fn sysroot_to_crate_graph(
     let public_deps = SysrootPublicDeps {
         deps: sysroot
             .public_deps()
-            .map(|(name, idx, prelude)| (name, sysroot_crates[&idx], prelude))
+            .filter_map(|(name, idx, prelude)| Some((name, *sysroot_crates.get(&idx)?, prelude)))
             .collect::<Vec<_>>(),
     };
 
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index da132f93968..c4a29e0cbb0 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -218,7 +218,7 @@ impl GlobalState {
         let _p = profile::span("GlobalState::process_changes");
 
         let mut file_changes = FxHashMap::<_, (bool, ChangedFile)>::default();
-        let (change, modified_files, workspace_structure_change) = {
+        let (change, modified_rust_files, workspace_structure_change) = {
             let mut change = Change::new();
             let mut guard = self.vfs.write();
             let changed_files = guard.0.take_changes();
@@ -254,8 +254,8 @@ impl GlobalState {
                                 *change = Create(new);
                                 *just_created = true;
                             }
-                            // shouldn't occur, but collapse into `Modify`
-                            (Modify(prev), _, Create(new)) => *prev = new,
+                            // shouldn't occur, but keep the Create
+                            (prev @ Modify(_), _, new @ Create(_)) => *prev = new,
                         }
                     }
                     Entry::Vacant(v) => {
@@ -276,7 +276,7 @@ impl GlobalState {
             // A file was added or deleted
             let mut has_structure_changes = false;
             let mut bytes = vec![];
-            let mut modified_files = vec![];
+            let mut modified_rust_files = vec![];
             for file in changed_files {
                 let vfs_path = &vfs.file_path(file.file_id);
                 if let Some(path) = vfs_path.as_path() {
@@ -288,8 +288,8 @@ impl GlobalState {
                         has_structure_changes = true;
                         workspace_structure_change =
                             Some((path, self.crate_graph_file_dependencies.contains(vfs_path)));
-                    } else {
-                        modified_files.push(file.file_id);
+                    } else if path.extension() == Some("rs".as_ref()) {
+                        modified_rust_files.push(file.file_id);
                     }
                 }
 
@@ -324,7 +324,7 @@ impl GlobalState {
                 let roots = self.source_root_config.partition(vfs);
                 change.set_roots(roots);
             }
-            (change, modified_files, workspace_structure_change)
+            (change, modified_rust_files, workspace_structure_change)
         };
 
         self.analysis_host.apply_change(change);
@@ -339,7 +339,7 @@ impl GlobalState {
                     force_crate_graph_reload,
                 );
             }
-            self.proc_macro_changed = modified_files.into_iter().any(|file_id| {
+            self.proc_macro_changed = modified_rust_files.into_iter().any(|file_id| {
                 let crates = raw_database.relevant_crates(file_id);
                 let crate_graph = raw_database.crate_graph();
 
diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs
index c0d35498c66..ce69d612255 100644
--- a/crates/rust-analyzer/src/handlers/notification.rs
+++ b/crates/rust-analyzer/src/handlers/notification.rs
@@ -101,8 +101,10 @@ pub(crate) fn handle_did_change_text_document(
             params.content_changes,
         )
         .into_bytes();
-        *data = new_contents.clone();
-        state.vfs.write().0.set_file_contents(path, Some(new_contents));
+        if *data != new_contents {
+            *data = new_contents.clone();
+            state.vfs.write().0.set_file_contents(path, Some(new_contents));
+        }
     }
     Ok(())
 }
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index 356c332f90d..ca7893faf5d 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -571,15 +571,18 @@ impl GlobalState {
     }
 
     fn handle_vfs_msg(&mut self, message: vfs::loader::Message) {
+        let is_changed = matches!(message, vfs::loader::Message::Changed { .. });
         match message {
-            vfs::loader::Message::Loaded { files } => {
+            vfs::loader::Message::Changed { files } | vfs::loader::Message::Loaded { files } => {
                 let vfs = &mut self.vfs.write().0;
                 for (path, contents) in files {
                     let path = VfsPath::from(path);
                     // if the file is in mem docs, it's managed by the client via notifications
                     // so only set it if its not in there
                     if !self.mem_docs.contains(&path) {
-                        vfs.set_file_contents(path, contents);
+                        if is_changed || vfs.file_id(&path).is_none() {
+                            vfs.set_file_contents(path, contents);
+                        }
                     }
                 }
             }
diff --git a/crates/rust-analyzer/tests/slow-tests/main.rs b/crates/rust-analyzer/tests/slow-tests/main.rs
index f76ff7db38c..78411e2d58d 100644
--- a/crates/rust-analyzer/tests/slow-tests/main.rs
+++ b/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -835,7 +835,7 @@ fn main() {
 #[cfg(any(feature = "sysroot-abi", rust_analyzer))]
 fn resolve_proc_macro() {
     use expect_test::expect;
-    if skip_slow_tests() || true {
+    if skip_slow_tests() {
         return;
     }
 
diff --git a/crates/vfs-notify/src/lib.rs b/crates/vfs-notify/src/lib.rs
index 03065043714..19b34ffe6b9 100644
--- a/crates/vfs-notify/src/lib.rs
+++ b/crates/vfs-notify/src/lib.rs
@@ -160,7 +160,7 @@ impl NotifyActor {
                                 Some((path, contents))
                             })
                             .collect();
-                        self.send(loader::Message::Loaded { files });
+                        self.send(loader::Message::Changed { files });
                     }
                 }
             }
diff --git a/crates/vfs/src/loader.rs b/crates/vfs/src/loader.rs
index e2d74782ae5..89a544c81d8 100644
--- a/crates/vfs/src/loader.rs
+++ b/crates/vfs/src/loader.rs
@@ -51,6 +51,8 @@ pub enum Message {
     Progress { n_total: usize, n_done: usize, config_version: u32 },
     /// The handle loaded the following files' content.
     Loaded { files: Vec<(AbsPathBuf, Option<Vec<u8>>)> },
+    /// The handle loaded the following files' content.
+    Changed { files: Vec<(AbsPathBuf, Option<Vec<u8>>)> },
 }
 
 /// Type that will receive [`Messages`](Message) from a [`Handle`].
@@ -199,6 +201,9 @@ impl fmt::Debug for Message {
             Message::Loaded { files } => {
                 f.debug_struct("Loaded").field("n_files", &files.len()).finish()
             }
+            Message::Changed { files } => {
+                f.debug_struct("Changed").field("n_files", &files.len()).finish()
+            }
             Message::Progress { n_total, n_done, config_version } => f
                 .debug_struct("Progress")
                 .field("n_total", n_total)