Skip to content

Commit dd673ee

Browse files
committed
Auto merge of #14025 - Veykril:changekind-fix, r=jonas-schievink
fix: Fix process-changes not deduplicating changes correctly probably fixes #12873 (will close it with this nevertheless as its not really reproducible)
2 parents 6fd5769 + d712e52 commit dd673ee

File tree

4 files changed

+30
-15
lines changed

4 files changed

+30
-15
lines changed

crates/proc-macro-api/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ impl ProcMacroServer {
121121
}
122122

123123
pub fn load_dylib(&self, dylib: MacroDylib) -> Result<Vec<ProcMacro>, ServerError> {
124-
let _p = profile::span("ProcMacroClient::by_dylib_path");
124+
let _p = profile::span("ProcMacroClient::load_dylib");
125125
let macros =
126126
self.process.lock().unwrap_or_else(|e| e.into_inner()).find_proc_macros(&dylib.path)?;
127127

crates/rust-analyzer/src/global_state.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//!
44
//! Each tick provides an immutable snapshot of the state as `WorldSnapshot`.
55
6-
use std::{sync::Arc, time::Instant};
6+
use std::{mem, sync::Arc, time::Instant};
77

88
use crossbeam_channel::{unbounded, Receiver, Sender};
99
use flycheck::FlycheckHandle;
@@ -197,37 +197,51 @@ impl GlobalState {
197197
// We need to fix up the changed events a bit, if we have a create or modify for a file
198198
// id that is followed by a delete we actually no longer observe the file text from the
199199
// create or modify which may cause problems later on
200+
let mut collapsed_create_delete = false;
200201
changed_files.dedup_by(|a, b| {
201202
use vfs::ChangeKind::*;
202203

204+
let has_collapsed_create_delete = mem::replace(&mut collapsed_create_delete, false);
205+
203206
if a.file_id != b.file_id {
204207
return false;
205208
}
206209

207-
match (a.change_kind, b.change_kind) {
210+
// true => delete the second element (a), we swap them here as they are inverted by dedup_by
211+
match (b.change_kind, a.change_kind) {
208212
// duplicate can be merged
209213
(Create, Create) | (Modify, Modify) | (Delete, Delete) => true,
210214
// just leave the create, modify is irrelevant
211-
(Create, Modify) => {
212-
std::mem::swap(a, b);
215+
(Create, Modify) => true,
216+
// modify becomes irrelevant if the file is deleted
217+
(Modify, Delete) => {
218+
mem::swap(a, b);
219+
true
220+
}
221+
// Remove the create message, and in the following loop, also remove the delete
222+
(Create, Delete) => {
223+
collapsed_create_delete = true;
224+
b.change_kind = Delete;
225+
true
226+
}
227+
// trailing delete from earlier
228+
(Delete, Create | Modify) if has_collapsed_create_delete => {
229+
b.change_kind = Create;
213230
true
214231
}
215-
// modify becomes irrelevant if the file is deleted
216-
(Modify, Delete) => true,
217-
// we should fully remove this occurrence,
218-
// but leaving just a delete works as well
219-
(Create, Delete) => true,
220232
// this is equivalent to a modify
221233
(Delete, Create) => {
222-
a.change_kind = Modify;
234+
b.change_kind = Modify;
223235
true
224236
}
225237
// can't really occur
226238
(Modify, Create) => false,
227239
(Delete, Modify) => false,
228240
}
229241
});
230-
242+
if collapsed_create_delete {
243+
changed_files.pop();
244+
}
231245
for file in &changed_files {
232246
if let Some(path) = vfs.file_path(file.file_id).as_path() {
233247
let path = path.to_path_buf();

crates/rust-analyzer/src/reload.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ impl GlobalState {
362362
let loader = &mut self.loader;
363363
let mem_docs = &self.mem_docs;
364364
let mut load = move |path: &AbsPath| {
365-
let _p = profile::span("GlobalState::load");
365+
let _p = profile::span("switch_workspaces::load");
366366
let vfs_path = vfs::VfsPath::from(path.to_path_buf());
367367
if !mem_docs.contains(&vfs_path) {
368368
let contents = loader.handle.load_sync(path);
@@ -584,10 +584,10 @@ pub(crate) fn load_proc_macro(
584584
path: &AbsPath,
585585
dummy_replace: &[Box<str>],
586586
) -> ProcMacroLoadResult {
587+
let server = server.map_err(ToOwned::to_owned)?;
587588
let res: Result<Vec<_>, String> = (|| {
588589
let dylib = MacroDylib::new(path.to_path_buf())
589590
.map_err(|io| format!("Proc-macro dylib loading failed: {io}"))?;
590-
let server = server.map_err(ToOwned::to_owned)?;
591591
let vec = server.load_dylib(dylib).map_err(|e| format!("{e}"))?;
592592
if vec.is_empty() {
593593
return Err("proc macro library returned no proc macros".to_string());

crates/vfs/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ pub struct Vfs {
7575
}
7676

7777
/// Changed file in the [`Vfs`].
78+
#[derive(Debug)]
7879
pub struct ChangedFile {
7980
/// Id of the changed file
8081
pub file_id: FileId,
@@ -161,9 +162,9 @@ impl Vfs {
161162
let file_id = self.alloc_file_id(path);
162163
let change_kind = match (&self.get(file_id), &contents) {
163164
(None, None) => return false,
165+
(Some(old), Some(new)) if old == new => return false,
164166
(None, Some(_)) => ChangeKind::Create,
165167
(Some(_), None) => ChangeKind::Delete,
166-
(Some(old), Some(new)) if old == new => return false,
167168
(Some(_), Some(_)) => ChangeKind::Modify,
168169
};
169170

0 commit comments

Comments
 (0)