aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ide/src/prime_caches.rs1
-rw-r--r--crates/rust-analyzer/src/main_loop.rs30
2 files changed, 11 insertions, 20 deletions
diff --git a/crates/ide/src/prime_caches.rs b/crates/ide/src/prime_caches.rs
index 03597f507..d912a01b8 100644
--- a/crates/ide/src/prime_caches.rs
+++ b/crates/ide/src/prime_caches.rs
@@ -27,6 +27,7 @@ pub(crate) fn prime_caches(db: &RootDatabase, cb: &(dyn Fn(PrimeCachesProgress)
27 let topo = &graph.crates_in_topological_order(); 27 let topo = &graph.crates_in_topological_order();
28 28
29 cb(PrimeCachesProgress::Started); 29 cb(PrimeCachesProgress::Started);
30 // Take care to emit the finish signal even when the computation is canceled.
30 let _d = stdx::defer(|| cb(PrimeCachesProgress::Finished)); 31 let _d = stdx::defer(|| cb(PrimeCachesProgress::Finished));
31 32
32 // FIXME: This would be easy to parallelize, since it's in the ideal ordering for that. 33 // FIXME: This would be easy to parallelize, since it's in the ideal ordering for that.
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index a3e974e92..ce7ece559 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -8,8 +8,7 @@ use std::{
8 8
9use always_assert::always; 9use always_assert::always;
10use crossbeam_channel::{select, Receiver}; 10use crossbeam_channel::{select, Receiver};
11use ide::PrimeCachesProgress; 11use ide::{FileId, PrimeCachesProgress};
12use ide::{Canceled, FileId};
13use ide_db::base_db::VfsPath; 12use ide_db::base_db::VfsPath;
14use lsp_server::{Connection, Notification, Request, Response}; 13use lsp_server::{Connection, Notification, Request, Response};
15use lsp_types::notification::Notification as _; 14use lsp_types::notification::Notification as _;
@@ -278,8 +277,6 @@ impl GlobalState {
278 }; 277 };
279 } 278 }
280 279
281 let mut finished = false;
282
283 for progress in prime_caches_progress { 280 for progress in prime_caches_progress {
284 let (state, message, fraction); 281 let (state, message, fraction);
285 match progress { 282 match progress {
@@ -297,18 +294,13 @@ impl GlobalState {
297 state = Progress::End; 294 state = Progress::End;
298 message = None; 295 message = None;
299 fraction = 1.0; 296 fraction = 1.0;
300 finished = true; 297
298 self.prime_caches_queue.op_completed(());
301 } 299 }
302 }; 300 };
303 301
304 self.report_progress("Indexing", state, message, Some(fraction)); 302 self.report_progress("Indexing", state, message, Some(fraction));
305 } 303 }
306
307 // If the task is cancelled we may observe two `PrimeCachesProgress::Finished` so we
308 // have to make sure to only call `op_completed()` once.
309 if finished {
310 self.prime_caches_queue.op_completed(());
311 }
312 } 304 }
313 Event::Vfs(mut task) => { 305 Event::Vfs(mut task) => {
314 let _p = profile::span("GlobalState::handle_event/vfs"); 306 let _p = profile::span("GlobalState::handle_event/vfs");
@@ -730,15 +722,13 @@ impl GlobalState {
730 self.task_pool.handle.spawn_with_sender({ 722 self.task_pool.handle.spawn_with_sender({
731 let snap = self.snapshot(); 723 let snap = self.snapshot();
732 move |sender| { 724 move |sender| {
733 snap.analysis 725 let cb = |progress| {
734 .prime_caches(|progress| { 726 sender.send(Task::PrimeCaches(progress)).unwrap();
735 sender.send(Task::PrimeCaches(progress)).unwrap(); 727 };
736 }) 728 match snap.analysis.prime_caches(cb) {
737 .unwrap_or_else(|_: Canceled| { 729 Ok(()) => (),
738 // Pretend that we're done, so that the progress bar is removed. Otherwise 730 Err(_canceled) => (),
739 // the editor may complain about it already existing. 731 }
740 sender.send(Task::PrimeCaches(PrimeCachesProgress::Finished)).unwrap()
741 });
742 } 732 }
743 }); 733 });
744 } 734 }