Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 2d8a494

Browse files
committed
Wait with change processing until the vfs is done
1 parent 07e6f9d commit 2d8a494

File tree

5 files changed

+34
-30
lines changed

5 files changed

+34
-30
lines changed

src/tools/rust-analyzer/crates/rust-analyzer/src/global_state.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use crate::{
3333
lsp_ext,
3434
main_loop::Task,
3535
mem_docs::MemDocs,
36-
op_queue::OpQueue,
36+
op_queue::{Cause, OpQueue},
3737
reload,
3838
target_spec::{CargoTargetSpec, ProjectJsonTargetSpec, TargetSpec},
3939
task_pool::{TaskPool, TaskQueue},
@@ -108,8 +108,8 @@ pub(crate) struct GlobalState {
108108
pub(crate) vfs: Arc<RwLock<(vfs::Vfs, IntMap<FileId, LineEndings>)>>,
109109
pub(crate) vfs_config_version: u32,
110110
pub(crate) vfs_progress_config_version: u32,
111-
pub(crate) vfs_progress_n_total: usize,
112-
pub(crate) vfs_progress_n_done: usize,
111+
pub(crate) vfs_done: bool,
112+
pub(crate) wants_to_switch: Option<Cause>,
113113

114114
/// `workspaces` field stores the data we actually use, while the `OpQueue`
115115
/// stores the result of the last fetch.
@@ -252,8 +252,8 @@ impl GlobalState {
252252
vfs: Arc::new(RwLock::new((vfs::Vfs::default(), IntMap::default()))),
253253
vfs_config_version: 0,
254254
vfs_progress_config_version: 0,
255-
vfs_progress_n_total: 0,
256-
vfs_progress_n_done: 0,
255+
vfs_done: true,
256+
wants_to_switch: None,
257257

258258
workspaces: Arc::from(Vec::new()),
259259
crate_graph_file_dependencies: FxHashSet::default(),

src/tools/rust-analyzer/crates/rust-analyzer/src/main_loop.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -375,9 +375,14 @@ impl GlobalState {
375375
}
376376
}
377377
let event_handling_duration = loop_start.elapsed();
378-
379-
let state_changed = self.process_changes();
380-
let memdocs_added_or_removed = self.mem_docs.take_changes();
378+
let (state_changed, memdocs_added_or_removed) = if self.vfs_done {
379+
if let Some(cause) = self.wants_to_switch.take() {
380+
self.switch_workspaces(cause);
381+
}
382+
(self.process_changes(), self.mem_docs.take_changes())
383+
} else {
384+
(false, false)
385+
};
381386

382387
if self.is_quiescent() {
383388
let became_quiescent = !was_quiescent;
@@ -672,7 +677,7 @@ impl GlobalState {
672677
if let Err(e) = self.fetch_workspace_error() {
673678
error!("FetchWorkspaceError:\n{e}");
674679
}
675-
self.switch_workspaces("fetched workspace".to_owned());
680+
self.wants_to_switch = Some("fetched workspace".to_owned());
676681
(Progress::End, None)
677682
}
678683
};
@@ -718,8 +723,9 @@ impl GlobalState {
718723
error!("FetchBuildDataError:\n{e}");
719724
}
720725

721-
self.switch_workspaces("fetched build data".to_owned());
722-
726+
if self.wants_to_switch.is_none() {
727+
self.wants_to_switch = Some("fetched build data".to_owned());
728+
}
723729
(Some(Progress::End), None)
724730
}
725731
};
@@ -779,8 +785,7 @@ impl GlobalState {
779785
};
780786

781787
self.vfs_progress_config_version = config_version;
782-
self.vfs_progress_n_total = n_total;
783-
self.vfs_progress_n_done = n_done;
788+
self.vfs_done = state == Progress::End;
784789

785790
let mut message = format!("{n_done}/{n_total}");
786791
if let Some(dir) = dir {

src/tools/rust-analyzer/crates/rust-analyzer/src/reload.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ pub(crate) enum ProcMacroProgress {
6262

6363
impl GlobalState {
6464
pub(crate) fn is_quiescent(&self) -> bool {
65-
!(self.last_reported_status.is_none()
66-
|| self.fetch_workspaces_queue.op_in_progress()
67-
|| self.fetch_build_data_queue.op_in_progress()
68-
|| self.fetch_proc_macros_queue.op_in_progress()
69-
|| self.discover_workspace_queue.op_in_progress()
70-
|| self.vfs_progress_config_version < self.vfs_config_version
71-
|| self.vfs_progress_n_done < self.vfs_progress_n_total)
65+
self.vfs_done
66+
&& self.last_reported_status.is_some()
67+
&& !self.fetch_workspaces_queue.op_in_progress()
68+
&& !self.fetch_build_data_queue.op_in_progress()
69+
&& !self.fetch_proc_macros_queue.op_in_progress()
70+
&& !self.discover_workspace_queue.op_in_progress()
71+
&& self.vfs_progress_config_version >= self.vfs_config_version
7272
}
7373

7474
pub(crate) fn update_configuration(&mut self, config: Config) {
@@ -102,15 +102,13 @@ impl GlobalState {
102102
}
103103

104104
pub(crate) fn current_status(&self) -> lsp_ext::ServerStatusParams {
105-
let mut status = lsp_ext::ServerStatusParams {
106-
health: lsp_ext::Health::Ok,
107-
quiescent: self.is_quiescent(),
108-
message: None,
109-
};
105+
let quiescent = self.is_quiescent();
106+
let mut status =
107+
lsp_ext::ServerStatusParams { health: lsp_ext::Health::Ok, quiescent, message: None };
110108
let mut message = String::new();
111109

112110
if !self.config.cargo_autoreload(None)
113-
&& self.is_quiescent()
111+
&& quiescent
114112
&& self.fetch_workspaces_queue.op_requested()
115113
&& self.config.discover_workspace_config().is_none()
116114
{
@@ -242,7 +240,7 @@ impl GlobalState {
242240
let discover_command = self.config.discover_workspace_config().cloned();
243241
let is_quiescent = !(self.discover_workspace_queue.op_in_progress()
244242
|| self.vfs_progress_config_version < self.vfs_config_version
245-
|| self.vfs_progress_n_done < self.vfs_progress_n_total);
243+
|| !self.vfs_done);
246244

247245
move |sender| {
248246
let progress = {

src/tools/rust-analyzer/crates/vfs-notify/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ type NotifyEvent = notify::Result<notify::Event>;
6161

6262
struct NotifyActor {
6363
sender: loader::Sender,
64+
// FIXME: Consider hashset
6465
watched_entries: Vec<loader::Entry>,
6566
// Drop order is significant.
6667
watcher: Option<(RecommendedWatcher, Receiver<NotifyEvent>)>,

src/tools/rust-analyzer/crates/vfs/src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ impl Vfs {
201201
pub fn set_file_contents(&mut self, path: VfsPath, contents: Option<Vec<u8>>) -> bool {
202202
let _p = span!(Level::INFO, "Vfs::set_file_contents").entered();
203203
let file_id = self.alloc_file_id(path);
204-
let state = self.get(file_id);
205-
let change_kind = match (state, contents) {
204+
let state: FileState = self.get(file_id);
205+
let change = match (state, contents) {
206206
(FileState::Deleted, None) => return false,
207207
(FileState::Deleted, Some(v)) => {
208208
let hash = hash_once::<FxHasher>(&*v);
@@ -225,7 +225,7 @@ impl Vfs {
225225
};
226226
};
227227

228-
let changed_file = ChangedFile { file_id, change: change_kind };
228+
let changed_file = ChangedFile { file_id, change };
229229
match self.changes.entry(file_id) {
230230
// two changes to the same file in one cycle, merge them appropriately
231231
Entry::Occupied(mut o) => {

0 commit comments

Comments
 (0)