Skip to content

Commit 9e34e64

Browse files
committed
Auto merge of rust-lang#16319 - Veykril:no-double-load, r=Veykril
fix: Differentiate between vfs config load and file changed events Kind of fixes rust-lang/rust-analyzer#14730 in a pretty bad way. We need to rethink the vfs-notify layer entirely. For a decent fix.
2 parents e3575a8 + e1c6748 commit 9e34e64

File tree

8 files changed

+26
-16
lines changed

8 files changed

+26
-16
lines changed

crates/load-cargo/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ fn load_crate_graph(
322322
break;
323323
}
324324
}
325-
vfs::loader::Message::Loaded { files } => {
325+
vfs::loader::Message::Loaded { files } | vfs::loader::Message::Changed { files } => {
326326
for (path, contents) in files {
327327
vfs.set_file_contents(path.into(), contents);
328328
}

crates/project-model/src/workspace.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1398,7 +1398,7 @@ fn sysroot_to_crate_graph(
13981398
let public_deps = SysrootPublicDeps {
13991399
deps: sysroot
14001400
.public_deps()
1401-
.map(|(name, idx, prelude)| (name, sysroot_crates[&idx], prelude))
1401+
.filter_map(|(name, idx, prelude)| Some((name, *sysroot_crates.get(&idx)?, prelude)))
14021402
.collect::<Vec<_>>(),
14031403
};
14041404

crates/rust-analyzer/src/global_state.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ impl GlobalState {
218218
let _p = profile::span("GlobalState::process_changes");
219219

220220
let mut file_changes = FxHashMap::<_, (bool, ChangedFile)>::default();
221-
let (change, modified_files, workspace_structure_change) = {
221+
let (change, modified_rust_files, workspace_structure_change) = {
222222
let mut change = Change::new();
223223
let mut guard = self.vfs.write();
224224
let changed_files = guard.0.take_changes();
@@ -254,8 +254,8 @@ impl GlobalState {
254254
*change = Create(new);
255255
*just_created = true;
256256
}
257-
// shouldn't occur, but collapse into `Modify`
258-
(Modify(prev), _, Create(new)) => *prev = new,
257+
// shouldn't occur, but keep the Create
258+
(prev @ Modify(_), _, new @ Create(_)) => *prev = new,
259259
}
260260
}
261261
Entry::Vacant(v) => {
@@ -276,7 +276,7 @@ impl GlobalState {
276276
// A file was added or deleted
277277
let mut has_structure_changes = false;
278278
let mut bytes = vec![];
279-
let mut modified_files = vec![];
279+
let mut modified_rust_files = vec![];
280280
for file in changed_files {
281281
let vfs_path = &vfs.file_path(file.file_id);
282282
if let Some(path) = vfs_path.as_path() {
@@ -288,8 +288,8 @@ impl GlobalState {
288288
has_structure_changes = true;
289289
workspace_structure_change =
290290
Some((path, self.crate_graph_file_dependencies.contains(vfs_path)));
291-
} else {
292-
modified_files.push(file.file_id);
291+
} else if path.extension() == Some("rs".as_ref()) {
292+
modified_rust_files.push(file.file_id);
293293
}
294294
}
295295

@@ -324,7 +324,7 @@ impl GlobalState {
324324
let roots = self.source_root_config.partition(vfs);
325325
change.set_roots(roots);
326326
}
327-
(change, modified_files, workspace_structure_change)
327+
(change, modified_rust_files, workspace_structure_change)
328328
};
329329

330330
self.analysis_host.apply_change(change);
@@ -339,7 +339,7 @@ impl GlobalState {
339339
force_crate_graph_reload,
340340
);
341341
}
342-
self.proc_macro_changed = modified_files.into_iter().any(|file_id| {
342+
self.proc_macro_changed = modified_rust_files.into_iter().any(|file_id| {
343343
let crates = raw_database.relevant_crates(file_id);
344344
let crate_graph = raw_database.crate_graph();
345345

crates/rust-analyzer/src/handlers/notification.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,10 @@ pub(crate) fn handle_did_change_text_document(
101101
params.content_changes,
102102
)
103103
.into_bytes();
104-
*data = new_contents.clone();
105-
state.vfs.write().0.set_file_contents(path, Some(new_contents));
104+
if *data != new_contents {
105+
*data = new_contents.clone();
106+
state.vfs.write().0.set_file_contents(path, Some(new_contents));
107+
}
106108
}
107109
Ok(())
108110
}

crates/rust-analyzer/src/main_loop.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -571,15 +571,18 @@ impl GlobalState {
571571
}
572572

573573
fn handle_vfs_msg(&mut self, message: vfs::loader::Message) {
574+
let is_changed = matches!(message, vfs::loader::Message::Changed { .. });
574575
match message {
575-
vfs::loader::Message::Loaded { files } => {
576+
vfs::loader::Message::Changed { files } | vfs::loader::Message::Loaded { files } => {
576577
let vfs = &mut self.vfs.write().0;
577578
for (path, contents) in files {
578579
let path = VfsPath::from(path);
579580
// if the file is in mem docs, it's managed by the client via notifications
580581
// so only set it if its not in there
581582
if !self.mem_docs.contains(&path) {
582-
vfs.set_file_contents(path, contents);
583+
if is_changed || vfs.file_id(&path).is_none() {
584+
vfs.set_file_contents(path, contents);
585+
}
583586
}
584587
}
585588
}

crates/rust-analyzer/tests/slow-tests/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ fn main() {
835835
#[cfg(any(feature = "sysroot-abi", rust_analyzer))]
836836
fn resolve_proc_macro() {
837837
use expect_test::expect;
838-
if skip_slow_tests() || true {
838+
if skip_slow_tests() {
839839
return;
840840
}
841841

crates/vfs-notify/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ impl NotifyActor {
160160
Some((path, contents))
161161
})
162162
.collect();
163-
self.send(loader::Message::Loaded { files });
163+
self.send(loader::Message::Changed { files });
164164
}
165165
}
166166
}

crates/vfs/src/loader.rs

+5
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ pub enum Message {
5151
Progress { n_total: usize, n_done: usize, config_version: u32 },
5252
/// The handle loaded the following files' content.
5353
Loaded { files: Vec<(AbsPathBuf, Option<Vec<u8>>)> },
54+
/// The handle loaded the following files' content.
55+
Changed { files: Vec<(AbsPathBuf, Option<Vec<u8>>)> },
5456
}
5557

5658
/// Type that will receive [`Messages`](Message) from a [`Handle`].
@@ -199,6 +201,9 @@ impl fmt::Debug for Message {
199201
Message::Loaded { files } => {
200202
f.debug_struct("Loaded").field("n_files", &files.len()).finish()
201203
}
204+
Message::Changed { files } => {
205+
f.debug_struct("Changed").field("n_files", &files.len()).finish()
206+
}
202207
Message::Progress { n_total, n_done, config_version } => f
203208
.debug_struct("Progress")
204209
.field("n_total", n_total)

0 commit comments

Comments
 (0)